LCOV - code coverage report
Current view: top level - EnergyPlus - FanCoilUnits.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 1830 2864 63.9 %
Date: 2023-01-17 19:17:23 Functions: 24 33 72.7 %

          Line data    Source code
       1             : // EnergyPlus, Copyright (c) 1996-2023, The Board of Trustees of the University of Illinois,
       2             : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3             : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4             : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5             : // contributors. All rights reserved.
       6             : //
       7             : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8             : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9             : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10             : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11             : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12             : //
      13             : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14             : // provided that the following conditions are met:
      15             : //
      16             : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17             : //     conditions and the following disclaimer.
      18             : //
      19             : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20             : //     conditions and the following disclaimer in the documentation and/or other materials
      21             : //     provided with the distribution.
      22             : //
      23             : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24             : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25             : //     used to endorse or promote products derived from this software without specific prior
      26             : //     written permission.
      27             : //
      28             : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29             : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30             : //     reference solely to the software portion of its product, Licensee must refer to the
      31             : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32             : //     obtained under this License and may not use a different name for the software. Except as
      33             : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34             : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35             : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36             : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37             : //
      38             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39             : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40             : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41             : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42             : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43             : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45             : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46             : // POSSIBILITY OF SUCH DAMAGE.
      47             : 
      48             : // C++ Headers
      49             : #include <cmath>
      50             : 
      51             : // ObjexxFCL Headers
      52             : #include <ObjexxFCL/Array.functions.hh>
      53             : #include <ObjexxFCL/Fmath.hh>
      54             : 
      55             : // EnergyPlus Headers
      56             : #include <EnergyPlus/Autosizing/All_Simple_Sizing.hh>
      57             : #include <EnergyPlus/Autosizing/CoolingAirFlowSizing.hh>
      58             : #include <EnergyPlus/Autosizing/CoolingCapacitySizing.hh>
      59             : #include <EnergyPlus/Autosizing/HeatingAirFlowSizing.hh>
      60             : #include <EnergyPlus/Autosizing/HeatingCapacitySizing.hh>
      61             : #include <EnergyPlus/Autosizing/SystemAirFlowSizing.hh>
      62             : #include <EnergyPlus/BranchNodeConnections.hh>
      63             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      64             : #include <EnergyPlus/DataAirSystems.hh>
      65             : #include <EnergyPlus/DataEnvironment.hh>
      66             : #include <EnergyPlus/DataHVACGlobals.hh>
      67             : #include <EnergyPlus/DataHeatBalFanSys.hh>
      68             : #include <EnergyPlus/DataHeatBalance.hh>
      69             : #include <EnergyPlus/DataLoopNode.hh>
      70             : #include <EnergyPlus/DataPrecisionGlobals.hh>
      71             : #include <EnergyPlus/DataSizing.hh>
      72             : #include <EnergyPlus/DataZoneEnergyDemands.hh>
      73             : #include <EnergyPlus/DataZoneEquipment.hh>
      74             : #include <EnergyPlus/FanCoilUnits.hh>
      75             : #include <EnergyPlus/Fans.hh>
      76             : #include <EnergyPlus/FluidProperties.hh>
      77             : #include <EnergyPlus/GeneralRoutines.hh>
      78             : #include <EnergyPlus/HVACFan.hh>
      79             : #include <EnergyPlus/HVACHXAssistedCoolingCoil.hh>
      80             : #include <EnergyPlus/HeatingCoils.hh>
      81             : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      82             : #include <EnergyPlus/MixedAir.hh>
      83             : #include <EnergyPlus/NodeInputManager.hh>
      84             : #include <EnergyPlus/OutputProcessor.hh>
      85             : #include <EnergyPlus/Plant/DataPlant.hh>
      86             : #include <EnergyPlus/PlantUtilities.hh>
      87             : #include <EnergyPlus/Psychrometrics.hh>
      88             : #include <EnergyPlus/ReportCoilSelection.hh>
      89             : #include <EnergyPlus/SZVAVModel.hh>
      90             : #include <EnergyPlus/ScheduleManager.hh>
      91             : #include <EnergyPlus/SingleDuct.hh>
      92             : #include <EnergyPlus/UtilityRoutines.hh>
      93             : #include <EnergyPlus/WaterCoils.hh>
      94             : #include <EnergyPlus/ZoneEquipmentManager.hh>
      95             : #include <EnergyPlus/ZonePlenum.hh>
      96             : 
      97             : namespace EnergyPlus {
      98             : 
      99             : namespace FanCoilUnits {
     100             : 
     101             :     // Module containing the routines dealing with 2 and 4 pipe fan coil units
     102             : 
     103             :     // MODULE INFORMATION:
     104             :     //       AUTHOR         Fred Buhl
     105             :     //       DATE WRITTEN   March 2000
     106             :     //       MODIFIED       October 2003 (FSEC added cooling coil type)
     107             :     //                      June 2010    Arnaud Flament LBNL added 3-speed and variables-speed fan capacity control;
     108             :     //                                   outside air schedule; and removed coil water inlet node inputs
     109             :     //                      Sept 2010    Brent Griffith, plant upgrades for water coils, fluid properties
     110             :     //       RE-ENGINEERED  na
     111             : 
     112             :     // PURPOSE OF THIS MODULE:
     113             :     // To encapsulate the data and algorithms needed to simulate 2 and 4 pipe
     114             :     // fan coil units.
     115             : 
     116             :     // METHODOLOGY EMPLOYED:
     117             :     // Units are modeled as a collection of components: outside air mixer,
     118             :     // fan, heating coil and/or cooling coil plus an integrated control
     119             :     // algorithm that adjusts the hot or cold water flow to meet the zone
     120             :     // load. Or varies the air flow rate to meet the zone load. Or both.
     121             : 
     122             :     // REFERENCES: none
     123             : 
     124             :     // OTHER NOTES: none
     125             : 
     126             :     // USE STATEMENTS:
     127             :     // Use statements for data only modules
     128             :     // Using/Aliasing
     129             :     using namespace DataLoopNode;
     130             :     using namespace DataSizing;
     131             :     using DataHVACGlobals::ATMixer_InletSide;
     132             :     using DataHVACGlobals::ATMixer_SupplySide;
     133             :     using DataHVACGlobals::ATMixerExists;
     134             :     using DataHVACGlobals::cATMixerTypes;
     135             :     using DataHVACGlobals::cFanTypes;
     136             :     using DataHVACGlobals::ContFanCycCoil;
     137             :     using DataHVACGlobals::CycFanCycCoil;
     138             :     using DataHVACGlobals::SmallAirVolFlow;
     139             :     using DataHVACGlobals::SmallLoad;
     140             :     using DataHVACGlobals::SmallMassFlow;
     141             :     using namespace ScheduleManager;
     142             : 
     143      514191 :     void SimFanCoilUnit(EnergyPlusData &state,
     144             :                         std::string_view CompName,     // name of the fan coil unit
     145             :                         int const ControlledZoneNum,   // number of zone being served
     146             :                         bool const FirstHVACIteration, // TRUE if 1st HVAC simulation of system timestep
     147             :                         Real64 &PowerMet,              // Sensible power supplied (W)
     148             :                         Real64 &LatOutputProvided,     // Latent add/removal supplied by window AC (kg/s), dehumid = negative
     149             :                         int &CompIndex)
     150             :     {
     151             : 
     152             :         // SUBROUTINE INFORMATION:
     153             :         //       AUTHOR         Fred Buhl
     154             :         //       DATE WRITTEN   March 2000
     155             :         //       MODIFIED       Don Shirey, Aug 2009 (LatOutputProvided)
     156             :         //       RE-ENGINEERED  na
     157             : 
     158             :         // PURPOSE OF THIS SUBROUTINE:
     159             :         // Manages the simulation of a fan coil unit. Called from SimZone Equipment
     160             : 
     161             :         // Using/Aliasing
     162             : 
     163             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     164             :         int FanCoilNum; // index of fan coil unit being simulated
     165             : 
     166             :         // First time SimFanCoilUnit is called, get the input for all the fan coil units
     167      514191 :         if (state.dataFanCoilUnits->GetFanCoilInputFlag) {
     168          19 :             GetFanCoilUnits(state);
     169          19 :             state.dataFanCoilUnits->GetFanCoilInputFlag = false;
     170             :         }
     171             : 
     172             :         // Find the correct Fan Coil Equipment
     173      514191 :         if (CompIndex == 0) {
     174          81 :             FanCoilNum = UtilityRoutines::FindItemInList(CompName, state.dataFanCoilUnits->FanCoil);
     175          81 :             if (FanCoilNum == 0) {
     176           0 :                 ShowFatalError(state, "SimFanCoil: Unit not found=" + std::string{CompName});
     177             :             }
     178          81 :             CompIndex = FanCoilNum;
     179             :         } else {
     180      514110 :             FanCoilNum = CompIndex;
     181      514110 :             if (FanCoilNum > state.dataFanCoilUnits->NumFanCoils || FanCoilNum < 1) {
     182           0 :                 ShowFatalError(state,
     183           0 :                                format("SimFanCoil:  Invalid CompIndex passed={}, Number of Units={}, Entered Unit name={}",
     184             :                                       FanCoilNum,
     185           0 :                                       state.dataFanCoilUnits->NumFanCoils,
     186           0 :                                       CompName));
     187             :             }
     188      514110 :             if (state.dataFanCoilUnits->CheckEquipName(FanCoilNum)) {
     189          81 :                 if (CompName != state.dataFanCoilUnits->FanCoil(FanCoilNum).Name) {
     190           0 :                     ShowFatalError(state,
     191           0 :                                    format("SimFanCoil: Invalid CompIndex passed={}, Unit name={}, stored Unit Name for that index={}",
     192             :                                           FanCoilNum,
     193             :                                           CompName,
     194           0 :                                           state.dataFanCoilUnits->FanCoil(FanCoilNum).Name));
     195             :                 }
     196          81 :                 state.dataFanCoilUnits->CheckEquipName(FanCoilNum) = false;
     197             :             }
     198             :         }
     199             : 
     200      514191 :         state.dataSize->ZoneEqFanCoil = true;
     201             : 
     202             :         // Initialize the fan coil unit
     203      514191 :         InitFanCoilUnits(state, FanCoilNum, ControlledZoneNum);
     204             : 
     205             :         // Select the correct unit type
     206      514191 :         if (state.dataFanCoilUnits->FanCoil(FanCoilNum).UnitType_Num == FanCoilUnit_4Pipe) {
     207      514191 :             Sim4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, PowerMet, LatOutputProvided);
     208             :         }
     209             : 
     210             :         // Report the result of the simulation
     211      514191 :         ReportFanCoilUnit(state, FanCoilNum);
     212             : 
     213      514191 :         state.dataSize->ZoneEqFanCoil = false;
     214      514191 :     }
     215             : 
     216          19 :     void GetFanCoilUnits(EnergyPlusData &state)
     217             :     {
     218             : 
     219             :         // SUBROUTINE INFORMATION:
     220             :         //       AUTHOR         Fred Buhl
     221             :         //       DATE WRITTEN   March 2000
     222             :         //       MODIFIED       Bereket Nigusse, FSEC, April 2011: eliminated input node names
     223             :         //                                                         added OA Mixer object type
     224             :         //                                                         and fan object type
     225             :         //                      Chandan Sharma, FSEC, July 2012: Added zone sys avail managers
     226             :         //       RE-ENGINEERED  na
     227             : 
     228             :         // PURPOSE OF THIS SUBROUTINE:
     229             :         // Obtains input data for fan coil units and stores it in fan coil data structures
     230             : 
     231             :         // METHODOLOGY EMPLOYED:
     232             :         // Uses "Get" routines to read in data.
     233             : 
     234             :         // Using/Aliasing
     235             :         using BranchNodeConnections::SetUpCompSets;
     236             :         using BranchNodeConnections::TestCompSet;
     237             :         using Fans::GetFanDesignVolumeFlowRate;
     238             :         using Fans::GetFanType;
     239             : 
     240             :         using NodeInputManager::GetOnlySingleNode;
     241             :         using WaterCoils::GetCoilWaterInletNode;
     242          19 :         auto &GetHXCoilWaterInletNode(HVACHXAssistedCoolingCoil::GetCoilWaterInletNode);
     243          19 :         auto &GetHeatingCoilCapacity(HeatingCoils::GetCoilCapacity);
     244             :         using DataHVACGlobals::FanType_SimpleConstVolume;
     245             :         using DataHVACGlobals::FanType_SimpleOnOff;
     246             :         using DataHVACGlobals::FanType_SimpleVAV;
     247             :         using HVACHXAssistedCoolingCoil::GetHXCoilTypeAndName;
     248             :         using MixedAir::GetOAMixerIndex;
     249             :         using MixedAir::GetOAMixerNodeNumbers;
     250             :         using SingleDuct::GetATMixer;
     251             : 
     252             :         // Locals
     253             :         // SUBROUTINE ARGUMENT DEFINITIONS:
     254             :         static constexpr std::string_view RoutineName("GetFanCoilUnits: "); // include trailing blank space
     255             : 
     256             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     257             :         int FanCoilIndex;                // loop index
     258             :         int FanCoilNum;                  // current fan coil number
     259             :         int NumAlphas;                   // Number of Alphas for each GetObjectItem call
     260             :         int NumNumbers;                  // Number of Numbers for each GetObjectItem call
     261          38 :         Array1D_int OANodeNums(4);       // Node numbers of Outdoor air mixer (OA, EA, RA, MA)
     262             :         int IOStatus;                    // Used in GetObjectItem
     263             :         bool IsNotOK;                    // Flag to verify name
     264          38 :         std::string CurrentModuleObject; // Object type for getting and error messages
     265          38 :         Array1D_string Alphas;           // Alpha input items for object
     266          38 :         Array1D_string cAlphaFields;     // Alpha field names
     267          38 :         Array1D_string cNumericFields;   // Numeric field names
     268          38 :         Array1D<Real64> Numbers;         // Numeric input items for object
     269          38 :         Array1D_bool lAlphaBlanks;       // Logical array, alpha field input BLANK = .TRUE.
     270          38 :         Array1D_bool lNumericBlanks;     // Logical array, numeric field input BLANK = .TRUE.
     271             :         int NodeNum;                     // index to loop counter
     272          38 :         std::string ATMixerName;
     273             : 
     274          19 :         auto &FanCoil(state.dataFanCoilUnits->FanCoil);
     275          19 :         auto &ErrorsFound(state.dataFanCoilUnits->ErrorsFound);
     276          19 :         auto errFlag(state.dataFanCoilUnits->errFlag);
     277             : 
     278             :         // find the number of each type of fan coil unit
     279             : 
     280          19 :         CurrentModuleObject = state.dataFanCoilUnits->cMO_FanCoil;
     281          19 :         state.dataFanCoilUnits->Num4PipeFanCoils = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
     282          19 :         state.dataFanCoilUnits->NumFanCoils = state.dataFanCoilUnits->Num4PipeFanCoils;
     283             :         // allocate the data structures
     284          19 :         state.dataFanCoilUnits->FanCoil.allocate(state.dataFanCoilUnits->NumFanCoils);
     285          19 :         state.dataFanCoilUnits->FanCoilNumericFields.allocate(state.dataFanCoilUnits->NumFanCoils);
     286          19 :         state.dataFanCoilUnits->CheckEquipName.dimension(state.dataFanCoilUnits->NumFanCoils, true);
     287             : 
     288          38 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
     289          19 :             state, CurrentModuleObject, state.dataFanCoilUnits->TotalArgs, NumAlphas, NumNumbers);
     290          19 :         Alphas.allocate(NumAlphas);
     291          19 :         cAlphaFields.allocate(NumAlphas);
     292          19 :         cNumericFields.allocate(NumNumbers);
     293          19 :         Numbers.dimension(NumNumbers, 0.0);
     294          19 :         lAlphaBlanks.dimension(NumAlphas, true);
     295          19 :         lNumericBlanks.dimension(NumNumbers, true);
     296             : 
     297             :         // loop over 4 pipe fan coil units; get and load the input data
     298         100 :         for (FanCoilIndex = 1; FanCoilIndex <= state.dataFanCoilUnits->Num4PipeFanCoils; ++FanCoilIndex) {
     299             : 
     300          81 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     301             :                                                                      CurrentModuleObject,
     302             :                                                                      FanCoilIndex,
     303             :                                                                      Alphas,
     304             :                                                                      NumAlphas,
     305             :                                                                      Numbers,
     306             :                                                                      NumNumbers,
     307             :                                                                      IOStatus,
     308             :                                                                      lNumericBlanks,
     309             :                                                                      lAlphaBlanks,
     310             :                                                                      cAlphaFields,
     311             :                                                                      cNumericFields);
     312             : 
     313          81 :             FanCoilNum = FanCoilIndex;
     314             : 
     315          81 :             state.dataFanCoilUnits->FanCoilNumericFields(FanCoilNum).FieldNames.allocate(NumNumbers);
     316          81 :             state.dataFanCoilUnits->FanCoilNumericFields(FanCoilNum).FieldNames = "";
     317          81 :             state.dataFanCoilUnits->FanCoilNumericFields(FanCoilNum).FieldNames = cNumericFields;
     318             : 
     319          81 :             UtilityRoutines::IsNameEmpty(state, Alphas(1), CurrentModuleObject, ErrorsFound);
     320          81 :             FanCoil(FanCoilNum).Name = Alphas(1);
     321          81 :             FanCoil(FanCoilNum).UnitType = CurrentModuleObject;
     322          81 :             FanCoil(FanCoilNum).UnitType_Num = FanCoilUnit_4Pipe;
     323          81 :             FanCoil(FanCoilNum).Sched = Alphas(2);
     324          81 :             if (lAlphaBlanks(2)) {
     325           0 :                 FanCoil(FanCoilNum).SchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
     326             :             } else {
     327          81 :                 FanCoil(FanCoilNum).SchedPtr = GetScheduleIndex(state, Alphas(2)); // convert schedule name to pointer
     328          81 :                 if (FanCoil(FanCoilNum).SchedPtr == 0) {
     329           0 :                     ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", invalid");
     330           0 :                     ShowContinueError(state, "invalid-not found: " + cAlphaFields(2) + "=\"" + Alphas(2) + "\".");
     331           0 :                     ErrorsFound = true;
     332             :                 }
     333             :             }
     334             : 
     335         213 :             if (UtilityRoutines::SameString(Alphas(3), "ConstantFanVariableFlow") || UtilityRoutines::SameString(Alphas(3), "CyclingFan") ||
     336          93 :                 UtilityRoutines::SameString(Alphas(3), "VariableFanVariableFlow") ||
     337         177 :                 UtilityRoutines::SameString(Alphas(3), "VariableFanConstantFlow") || UtilityRoutines::SameString(Alphas(3), "MultiSpeedFan") ||
     338          84 :                 UtilityRoutines::SameString(Alphas(3), "ASHRAE90VariableFan")) {
     339          81 :                 FanCoil(FanCoilNum).CapCtrlMeth = Alphas(3);
     340          81 :                 if (UtilityRoutines::SameString(Alphas(3), "ConstantFanVariableFlow")) FanCoil(FanCoilNum).CapCtrlMeth_Num = CCM::ConsFanVarFlow;
     341          81 :                 if (UtilityRoutines::SameString(Alphas(3), "CyclingFan")) FanCoil(FanCoilNum).CapCtrlMeth_Num = CCM::CycFan;
     342          81 :                 if (UtilityRoutines::SameString(Alphas(3), "VariableFanVariableFlow")) FanCoil(FanCoilNum).CapCtrlMeth_Num = CCM::VarFanVarFlow;
     343             :                 ;
     344          81 :                 if (UtilityRoutines::SameString(Alphas(3), "VariableFanConstantFlow")) FanCoil(FanCoilNum).CapCtrlMeth_Num = CCM::VarFanConsFlow;
     345          81 :                 if (UtilityRoutines::SameString(Alphas(3), "MultiSpeedFan")) FanCoil(FanCoilNum).CapCtrlMeth_Num = CCM::MultiSpeedFan;
     346          81 :                 if (UtilityRoutines::SameString(Alphas(3), "ASHRAE90VariableFan")) {
     347           3 :                     FanCoil(FanCoilNum).CapCtrlMeth_Num = CCM::ASHRAE;
     348           3 :                     FanCoil(FanCoilNum).DesZoneCoolingLoad = AutoSize;
     349           3 :                     FanCoil(FanCoilNum).DesZoneHeatingLoad = AutoSize;
     350           3 :                     FanCoil(FanCoilNum).FanOpMode = ContFanCycCoil;
     351             :                 }
     352             :             } else {
     353           0 :                 ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + FanCoil(FanCoilNum).Name + "\", invalid");
     354           0 :                 ShowContinueError(state, "illegal value: " + cAlphaFields(3) + "=\"" + Alphas(3) + "\".");
     355           0 :                 ErrorsFound = true;
     356             :             }
     357             : 
     358          81 :             FanCoil(FanCoilNum).SchedOutAir = Alphas(4);
     359          81 :             FanCoil(FanCoilNum).SchedOutAirPtr = GetScheduleIndex(state, Alphas(4)); // convert schedule name to pointer
     360          81 :             if (FanCoil(FanCoilNum).SchedOutAirPtr == 0 && (!lAlphaBlanks(4))) {
     361           0 :                 ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + FanCoil(FanCoilNum).Name + "\", invalid");
     362           0 :                 ShowContinueError(state, "illegal value: " + cAlphaFields(4) + "=\"" + Alphas(4) + "\".");
     363           0 :                 ErrorsFound = true;
     364             :             }
     365          81 :             FanCoil(FanCoilNum).MaxAirVolFlow = Numbers(1);
     366          81 :             FanCoil(FanCoilNum).LowSpeedRatio = Numbers(2);
     367          81 :             FanCoil(FanCoilNum).MedSpeedRatio = Numbers(3);
     368             :             // check if low speed ratio < medium speed ratio, if not : warning & set to default values
     369          81 :             if (FanCoil(FanCoilNum).LowSpeedRatio > FanCoil(FanCoilNum).MedSpeedRatio) {
     370           0 :                 ShowWarningError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + FanCoil(FanCoilNum).Name + "\",");
     371           0 :                 ShowContinueError(state, "... " + cNumericFields(2) + " is greater than the medium speed supply air flow ratio.");
     372           0 :                 ShowContinueError(state, format("... Fan Coil Unit low speed supply air flow ratio = {:.5T} ", FanCoil(FanCoilNum).LowSpeedRatio));
     373           0 :                 ShowContinueError(state, format("... Fan Coit Unit medium speed supply air flow ratio = {:.5T} ", FanCoil(FanCoilNum).MedSpeedRatio));
     374           0 :                 ShowContinueError(state,
     375             :                                   "... Fan Coil Unit low speed supply air flow ratio and medium speed supply air flow ratio set to default values");
     376           0 :                 FanCoil(FanCoilNum).LowSpeedRatio = 1.0 / 3.0;
     377           0 :                 FanCoil(FanCoilNum).MedSpeedRatio = 2.0 / 3.0;
     378             :             }
     379             : 
     380          81 :             FanCoil(FanCoilNum).OutAirVolFlow = Numbers(4);
     381             : 
     382          81 :             FanCoil(FanCoilNum).AirInNode = GetOnlySingleNode(state,
     383          81 :                                                               Alphas(5),
     384             :                                                               ErrorsFound,
     385             :                                                               DataLoopNode::ConnectionObjectType::ZoneHVACFourPipeFanCoil,
     386          81 :                                                               Alphas(1),
     387             :                                                               DataLoopNode::NodeFluidType::Air,
     388             :                                                               DataLoopNode::ConnectionType::Inlet,
     389             :                                                               NodeInputManager::CompFluidStream::Primary,
     390          81 :                                                               ObjectIsParent); // air input node
     391             : 
     392          81 :             FanCoil(FanCoilNum).AirOutNode = GetOnlySingleNode(state,
     393          81 :                                                                Alphas(6),
     394             :                                                                ErrorsFound,
     395             :                                                                DataLoopNode::ConnectionObjectType::ZoneHVACFourPipeFanCoil,
     396          81 :                                                                Alphas(1),
     397             :                                                                DataLoopNode::NodeFluidType::Air,
     398             :                                                                DataLoopNode::ConnectionType::Outlet,
     399             :                                                                NodeInputManager::CompFluidStream::Primary,
     400          81 :                                                                ObjectIsParent); // air outlet node
     401             : 
     402          81 :             FanCoil(FanCoilNum).OAMixType = Alphas(7);
     403          81 :             FanCoil(FanCoilNum).OAMixName = Alphas(8);
     404             :             // check to see if local OA mixer specified
     405          81 :             if (!lAlphaBlanks(8)) {
     406          71 :                 errFlag = false;
     407          71 :                 ValidateComponent(state, FanCoil(FanCoilNum).OAMixType, FanCoil(FanCoilNum).OAMixName, errFlag, CurrentModuleObject);
     408          71 :                 if (errFlag) {
     409           0 :                     ShowContinueError(state, "specified in " + CurrentModuleObject + " = \"" + FanCoil(FanCoilNum).Name + "\".");
     410           0 :                     ErrorsFound = true;
     411             :                 } else {
     412             :                     // Get outdoor air mixer node numbers
     413          71 :                     OANodeNums = GetOAMixerNodeNumbers(state, FanCoil(FanCoilNum).OAMixName, errFlag);
     414          71 :                     if (errFlag) {
     415           0 :                         ShowContinueError(state, "that was specified in " + CurrentModuleObject + " = " + FanCoil(FanCoilNum).Name);
     416           0 :                         ShowContinueError(state, "..OutdoorAir:Mixer is required. Enter an OutdoorAir:Mixer object with this name.");
     417           0 :                         ErrorsFound = true;
     418             :                     } else {
     419          71 :                         FanCoil(FanCoilNum).OutsideAirNode = OANodeNums(1);
     420          71 :                         FanCoil(FanCoilNum).AirReliefNode = OANodeNums(2);
     421          71 :                         FanCoil(FanCoilNum).MixedAirNode = OANodeNums(4);
     422             :                     }
     423             :                 }
     424             :             }
     425             : 
     426          81 :             FanCoil(FanCoilNum).CCoilName = Alphas(12);
     427          81 :             FanCoil(FanCoilNum).MaxColdWaterVolFlow = Numbers(5);
     428          81 :             FanCoil(FanCoilNum).MinColdWaterVolFlow = Numbers(6);
     429          81 :             FanCoil(FanCoilNum).ColdControlOffset = Numbers(7);
     430          81 :             FanCoil(FanCoilNum).HCoilName = Alphas(14);
     431          81 :             FanCoil(FanCoilNum).HCoilType = Alphas(13);
     432          81 :             FanCoil(FanCoilNum).MaxHotWaterVolFlow = Numbers(8);
     433          81 :             FanCoil(FanCoilNum).MinHotWaterVolFlow = Numbers(9);
     434          81 :             FanCoil(FanCoilNum).HotControlOffset = Numbers(10);
     435             : 
     436         162 :             if (UtilityRoutines::SameString(Alphas(11), "Coil:Cooling:Water") ||
     437         162 :                 UtilityRoutines::SameString(Alphas(11), "Coil:Cooling:Water:DetailedGeometry") ||
     438          81 :                 UtilityRoutines::SameString(Alphas(11), "CoilSystem:Cooling:Water:HeatExchangerAssisted")) {
     439          81 :                 FanCoil(FanCoilNum).CCoilType = Alphas(11);
     440          81 :                 if (UtilityRoutines::SameString(Alphas(11), "Coil:Cooling:Water")) {
     441          81 :                     FanCoil(FanCoilNum).CCoilType_Num = CCoil::Water;
     442          81 :                     FanCoil(FanCoilNum).CCoilPlantName = FanCoil(FanCoilNum).CCoilName;
     443          81 :                     FanCoil(FanCoilNum).CCoilPlantType = DataPlant::PlantEquipmentType::CoilWaterCooling;
     444             :                 }
     445          81 :                 if (UtilityRoutines::SameString(Alphas(11), "Coil:Cooling:Water:DetailedGeometry")) {
     446           0 :                     FanCoil(FanCoilNum).CCoilType_Num = CCoil::Detailed;
     447           0 :                     FanCoil(FanCoilNum).CCoilPlantName = FanCoil(FanCoilNum).CCoilName;
     448           0 :                     FanCoil(FanCoilNum).CCoilPlantType = DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling;
     449             :                 }
     450          81 :                 if (UtilityRoutines::SameString(Alphas(11), "CoilSystem:Cooling:Water:HeatExchangerAssisted")) {
     451           0 :                     FanCoil(FanCoilNum).CCoilType_Num = CCoil::HXAssist;
     452           0 :                     std::string CCoilType;
     453           0 :                     GetHXCoilTypeAndName(state,
     454           0 :                                          FanCoil(FanCoilNum).CCoilType,
     455           0 :                                          FanCoil(FanCoilNum).CCoilName,
     456             :                                          ErrorsFound,
     457             :                                          CCoilType,
     458           0 :                                          FanCoil(FanCoilNum).CCoilPlantName);
     459           0 :                     if (UtilityRoutines::SameString(CCoilType, "Coil:Cooling:Water")) {
     460           0 :                         FanCoil(FanCoilNum).CCoilPlantType = DataPlant::PlantEquipmentType::CoilWaterCooling;
     461           0 :                     } else if (UtilityRoutines::SameString(CCoilType, "Coil:Cooling:Water:DetailedGeometry")) {
     462           0 :                         FanCoil(FanCoilNum).CCoilPlantType = DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling;
     463             :                     } else {
     464           0 :                         ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + FanCoil(FanCoilNum).Name + "\", invalid");
     465           0 :                         ShowContinueError(state, "For: " + cAlphaFields(11) + "=\"" + Alphas(11) + "\".");
     466           0 :                         ShowContinueError(state, format("Invalid Coil Type={}, Name={}", CCoilType, FanCoil(FanCoilNum).CCoilPlantName));
     467           0 :                         ShowContinueError(state, "must be \"Coil:Cooling:Water\" or \"Coil:Cooling:Water:DetailedGeometry\"");
     468           0 :                         ErrorsFound = true;
     469             :                     }
     470             :                 }
     471          81 :                 IsNotOK = false;
     472          81 :                 ValidateComponent(state, FanCoil(FanCoilNum).CCoilType, FanCoil(FanCoilNum).CCoilName, IsNotOK, FanCoil(FanCoilNum).UnitType);
     473          81 :                 if (IsNotOK) {
     474           0 :                     ShowContinueError(state, "...specified in " + CurrentModuleObject + "=\"" + FanCoil(FanCoilNum).Name + "\".");
     475           0 :                     ErrorsFound = true;
     476             :                 } else {
     477          81 :                     if (FanCoil(FanCoilNum).CCoilType_Num != CCoil::HXAssist) {
     478             :                         // mine the cold water node from the coil object
     479          81 :                         FanCoil(FanCoilNum).CoolCoilFluidInletNode =
     480          81 :                             GetCoilWaterInletNode(state, FanCoil(FanCoilNum).CCoilType, FanCoil(FanCoilNum).CCoilName, IsNotOK);
     481          81 :                         FanCoil(FanCoilNum).CoolCoilInletNodeNum =
     482          81 :                             WaterCoils::GetCoilInletNode(state, FanCoil(FanCoilNum).CCoilType, FanCoil(FanCoilNum).CCoilName, IsNotOK);
     483          81 :                         FanCoil(FanCoilNum).CoolCoilOutletNodeNum =
     484          81 :                             WaterCoils::GetCoilOutletNode(state, FanCoil(FanCoilNum).CCoilType, FanCoil(FanCoilNum).CCoilName, IsNotOK);
     485             :                     } else {
     486           0 :                         FanCoil(FanCoilNum).CoolCoilFluidInletNode =
     487           0 :                             GetHXCoilWaterInletNode(state, FanCoil(FanCoilNum).CCoilType, FanCoil(FanCoilNum).CCoilName, IsNotOK);
     488           0 :                         FanCoil(FanCoilNum).CoolCoilInletNodeNum =
     489           0 :                             HVACHXAssistedCoolingCoil::GetCoilInletNode(state, FanCoil(FanCoilNum).CCoilType, FanCoil(FanCoilNum).CCoilName, IsNotOK);
     490           0 :                         FanCoil(FanCoilNum).CoolCoilOutletNodeNum = HVACHXAssistedCoolingCoil::GetCoilOutletNode(
     491           0 :                             state, FanCoil(FanCoilNum).CCoilType, FanCoil(FanCoilNum).CCoilName, IsNotOK);
     492             :                     }
     493             :                     // Other error checks should trap before it gets to this point in the code, but including just in case.
     494          81 :                     if (IsNotOK) {
     495           0 :                         ShowContinueError(state, "...specified in " + CurrentModuleObject + "=\"" + FanCoil(FanCoilNum).Name + "\".");
     496           0 :                         ErrorsFound = true;
     497             :                     }
     498             :                 }
     499             :             } else {
     500           0 :                 ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + FanCoil(FanCoilNum).Name + "\", invalid");
     501           0 :                 ShowContinueError(state, "illegal value: " + cAlphaFields(11) + "=\"" + Alphas(11) + "\".");
     502           0 :                 ErrorsFound = true;
     503             :             }
     504             : 
     505          81 :             if (UtilityRoutines::SameString(Alphas(13), "Coil:Heating:Water")) {
     506          80 :                 FanCoil(FanCoilNum).HCoilType_Num = HCoil::Water;
     507          80 :                 FanCoil(FanCoilNum).HCoilPlantTypeOf = DataPlant::PlantEquipmentType::CoilWaterSimpleHeating;
     508          80 :                 IsNotOK = false;
     509          80 :                 ValidateComponent(state, FanCoil(FanCoilNum).HCoilType, FanCoil(FanCoilNum).HCoilName, IsNotOK, CurrentModuleObject);
     510          80 :                 if (IsNotOK) {
     511           0 :                     ShowContinueError(state, "...specified in " + CurrentModuleObject + "=\"" + FanCoil(FanCoilNum).Name + "\".");
     512           0 :                     ErrorsFound = true;
     513             :                 } else {
     514             :                     // mine the hot water node from the coil object
     515          80 :                     FanCoil(FanCoilNum).HeatCoilFluidInletNode =
     516          80 :                         GetCoilWaterInletNode(state, FanCoil(FanCoilNum).HCoilType, FanCoil(FanCoilNum).HCoilName, IsNotOK);
     517          80 :                     FanCoil(FanCoilNum).HeatCoilInletNodeNum =
     518          80 :                         WaterCoils::GetCoilInletNode(state, FanCoil(FanCoilNum).HCoilType, FanCoil(FanCoilNum).HCoilName, IsNotOK);
     519          80 :                     FanCoil(FanCoilNum).HeatCoilOutletNodeNum =
     520          80 :                         WaterCoils::GetCoilOutletNode(state, FanCoil(FanCoilNum).HCoilType, FanCoil(FanCoilNum).HCoilName, IsNotOK);
     521          80 :                     if (IsNotOK) {
     522           0 :                         ShowContinueError(state, "...specified in " + CurrentModuleObject + "=\"" + FanCoil(FanCoilNum).Name + "\".");
     523           0 :                         ErrorsFound = true;
     524             :                     }
     525             :                 }
     526           1 :             } else if (UtilityRoutines::SameString(Alphas(13), "Coil:Heating:Electric")) {
     527           1 :                 FanCoil(FanCoilNum).HCoilType_Num = HCoil::Electric;
     528           1 :                 IsNotOK = false;
     529           1 :                 ValidateComponent(state, FanCoil(FanCoilNum).HCoilType, FanCoil(FanCoilNum).HCoilName, IsNotOK, CurrentModuleObject);
     530           1 :                 if (IsNotOK) {
     531           0 :                     ShowContinueError(state, "...specified in " + CurrentModuleObject + "=\"" + FanCoil(FanCoilNum).Name + "\".");
     532           0 :                     ErrorsFound = true;
     533             :                 } else {
     534           1 :                     FanCoil(FanCoilNum).DesignHeatingCapacity =
     535           1 :                         GetHeatingCoilCapacity(state, FanCoil(FanCoilNum).HCoilType, FanCoil(FanCoilNum).HCoilName, errFlag);
     536           1 :                     FanCoil(FanCoilNum).HeatCoilInletNodeNum =
     537           1 :                         HeatingCoils::GetCoilInletNode(state, FanCoil(FanCoilNum).HCoilType, FanCoil(FanCoilNum).HCoilName, errFlag);
     538           1 :                     FanCoil(FanCoilNum).HeatCoilOutletNodeNum =
     539           1 :                         HeatingCoils::GetCoilOutletNode(state, FanCoil(FanCoilNum).HCoilType, FanCoil(FanCoilNum).HCoilName, errFlag);
     540           1 :                     if (errFlag) {
     541           0 :                         ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + FanCoil(FanCoilNum).Name);
     542           0 :                         ErrorsFound = true;
     543             :                     }
     544             :                 }
     545             :             } else {
     546           0 :                 ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + FanCoil(FanCoilNum).Name + "\", invalid");
     547           0 :                 ShowContinueError(state, "illegal value: " + cAlphaFields(13) + "=\"" + Alphas(13) + "\".");
     548           0 :                 ErrorsFound = true;
     549             :             }
     550             : 
     551          81 :             FanCoil(FanCoilNum).FanType = Alphas(9);
     552          81 :             FanCoil(FanCoilNum).FanName = Alphas(10);
     553             : 
     554          81 :             if (!lAlphaBlanks(15)) {
     555           0 :                 FanCoil(FanCoilNum).AvailManagerListName = Alphas(15);
     556             :             }
     557             : 
     558          81 :             FanCoil(FanCoilNum).HVACSizingIndex = 0;
     559          81 :             if (!lAlphaBlanks(16)) {
     560           3 :                 FanCoil(FanCoilNum).HVACSizingIndex = UtilityRoutines::FindItemInList(Alphas(16), state.dataSize->ZoneHVACSizing);
     561           3 :                 if (FanCoil(FanCoilNum).HVACSizingIndex == 0) {
     562           0 :                     ShowSevereError(state, cAlphaFields(16) + " = " + Alphas(16) + " not found.");
     563           0 :                     ShowContinueError(state, "Occurs in " + state.dataFanCoilUnits->cMO_FanCoil + " = " + FanCoil(FanCoilNum).Name);
     564           0 :                     ErrorsFound = true;
     565             :                 }
     566             :             }
     567             : 
     568          81 :             errFlag = false;
     569          81 :             ValidateComponent(state, FanCoil(FanCoilNum).FanType, FanCoil(FanCoilNum).FanName, errFlag, CurrentModuleObject);
     570          81 :             if (errFlag) {
     571           0 :                 ShowContinueError(state, "specified in " + CurrentModuleObject + " = \"" + FanCoil(FanCoilNum).Name + "\".");
     572           0 :                 ErrorsFound = true;
     573             :             } else {
     574          81 :                 if (!UtilityRoutines::SameString(FanCoil(FanCoilNum).FanType, "Fan:SystemModel")) {
     575         189 :                     GetFanType(
     576         189 :                         state, FanCoil(FanCoilNum).FanName, FanCoil(FanCoilNum).FanType_Num, errFlag, CurrentModuleObject, FanCoil(FanCoilNum).Name);
     577             :                     // need to grab fan index here
     578             :                     // Fans::GetFanIndex(state, FanCoil(FanCoilNum).FanName, FanCoil(FanCoilNum).FanIndex, errFlag, FanCoil(FanCoilNum).FanType);
     579          63 :                     FanCoil(FanCoilNum).fanAvailSchIndex =
     580          63 :                         Fans::GetFanAvailSchPtr(state, FanCoil(FanCoilNum).FanType, FanCoil(FanCoilNum).FanName, errFlag);
     581          63 :                     if (errFlag) {
     582           0 :                         ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + FanCoil(FanCoilNum).Name);
     583           0 :                         ErrorsFound = true;
     584           0 :                         errFlag = false;
     585             :                     }
     586          63 :                     switch (FanCoil(FanCoilNum).FanType_Num) {
     587          63 :                     case FanType_SimpleConstVolume:
     588             :                     case FanType_SimpleVAV:
     589             :                     case FanType_SimpleOnOff: {
     590             :                         // Get fan air volume flow rate
     591          63 :                         FanCoil(FanCoilNum).FanAirVolFlow =
     592         126 :                             GetFanDesignVolumeFlowRate(state, FanCoil(FanCoilNum).FanType, FanCoil(FanCoilNum).FanName, IsNotOK);
     593             :                         // Check that the fan volumetric flow rate is greater than or equal to the FCU volumetric flow rate
     594          63 :                         if (FanCoil(FanCoilNum).MaxAirVolFlow > FanCoil(FanCoilNum).FanAirVolFlow && FanCoil(FanCoilNum).FanAirVolFlow != AutoSize) {
     595           0 :                             ShowWarningError(state, std::string{RoutineName} + FanCoil(FanCoilNum).UnitType + ": " + FanCoil(FanCoilNum).Name);
     596           0 :                             ShowContinueError(state, "... " + cNumericFields(1) + " is greater than the maximum fan flow rate.");
     597           0 :                             ShowContinueError(state, format("... Fan Coil Unit flow = {:.5T} m3/s.", FanCoil(FanCoilNum).MaxAirVolFlow));
     598           0 :                             ShowContinueError(state, "... Fan = " + cFanTypes(FanCoil(FanCoilNum).FanType_Num) + ": " + FanCoil(FanCoilNum).FanName);
     599           0 :                             ShowContinueError(state, format("... Fan flow = {:.5T} m3/s.", FanCoil(FanCoilNum).FanAirVolFlow));
     600           0 :                             ShowContinueError(state, "... Fan Coil Unit flow rate reduced to match the fan flow rate and the simulation continues.");
     601           0 :                             FanCoil(FanCoilNum).MaxAirVolFlow = FanCoil(FanCoilNum).FanAirVolFlow;
     602             :                         }
     603             : 
     604             :                         // Check that the fan type match with the capacity control method selected
     605         218 :                         if ((FanCoil(FanCoilNum).CapCtrlMeth_Num == CCM::ConsFanVarFlow && (FanCoil(FanCoilNum).FanType_Num == FanType_SimpleVAV)) ||
     606         160 :                             (FanCoil(FanCoilNum).CapCtrlMeth_Num == CCM::CycFan && FanCoil(FanCoilNum).FanType_Num != FanType_SimpleOnOff) ||
     607         189 :                             (FanCoil(FanCoilNum).CapCtrlMeth_Num == CCM::VarFanVarFlow && FanCoil(FanCoilNum).FanType_Num != FanType_SimpleVAV) ||
     608          63 :                             (FanCoil(FanCoilNum).CapCtrlMeth_Num == CCM::VarFanConsFlow && FanCoil(FanCoilNum).FanType_Num != FanType_SimpleVAV)) {
     609           0 :                             ShowSevereError(state, std::string{RoutineName} + FanCoil(FanCoilNum).UnitType + ": " + FanCoil(FanCoilNum).Name);
     610           0 :                             ShowContinueError(state,
     611           0 :                                               "...the fan type of the object : " + FanCoil(FanCoilNum).FanName +
     612           0 :                                                   " does not match with the capacity control method selected : " + FanCoil(FanCoilNum).CapCtrlMeth +
     613             :                                                   " please see I/O reference");
     614           0 :                             ShowContinueError(state, "...for ConstantFanVariableFlow a Fan:OnOff or Fan:ConstantVolume is valid.");
     615           0 :                             ShowContinueError(state, "...for CyclingFan a Fan:OnOff is valid.");
     616           0 :                             ShowContinueError(state, "...for VariableFanVariableFlow or VariableFanConstantFlow a Fan:VariableVolume is valid.");
     617           0 :                             ErrorsFound = true;
     618             :                         }
     619          63 :                     } break;
     620           0 :                     default: {
     621           0 :                         ShowSevereError(state, CurrentModuleObject + " = \"" + Alphas(1) + "\"");
     622           0 :                         ShowContinueError(state, "Fan Type must be Fan:OnOff, Fan:ConstantVolume or Fan:VariableVolume.");
     623           0 :                         ErrorsFound = true;
     624           0 :                     } break;
     625             :                     }
     626          18 :                 } else if (UtilityRoutines::SameString(FanCoil(FanCoilNum).FanType, "Fan:SystemModel")) {
     627          18 :                     FanCoil(FanCoilNum).FanType_Num = DataHVACGlobals::FanType_SystemModelObject;
     628          18 :                     state.dataHVACFan->fanObjs.emplace_back(new HVACFan::FanSystem(state, FanCoil(FanCoilNum).FanName)); // call constructor
     629          18 :                     FanCoil(FanCoilNum).FanIndex = HVACFan::getFanObjectVectorIndex(state, FanCoil(FanCoilNum).FanName); // zero-based
     630          18 :                     FanCoil(FanCoilNum).fanAvailSchIndex = state.dataHVACFan->fanObjs[FanCoil(FanCoilNum).FanIndex]->availSchedIndex;
     631          18 :                     FanCoil(FanCoilNum).FanAirVolFlow = state.dataHVACFan->fanObjs[FanCoil(FanCoilNum).FanIndex]->designAirVolFlowRate;
     632             :                     // Check that the fan volumetric flow rate is greater than or equal to the FCU volumetric flow rate
     633          18 :                     if (FanCoil(FanCoilNum).MaxAirVolFlow > FanCoil(FanCoilNum).FanAirVolFlow && FanCoil(FanCoilNum).FanAirVolFlow != AutoSize) {
     634           0 :                         ShowWarningError(state, std::string{RoutineName} + FanCoil(FanCoilNum).UnitType + ": " + FanCoil(FanCoilNum).Name);
     635           0 :                         ShowContinueError(state, "... " + cNumericFields(1) + " is greater than the maximum fan flow rate.");
     636           0 :                         ShowContinueError(state, format("... Fan Coil Unit flow = {:.5T} m3/s.", FanCoil(FanCoilNum).MaxAirVolFlow));
     637           0 :                         ShowContinueError(state, "... Fan = " + cFanTypes(FanCoil(FanCoilNum).FanType_Num) + ": " + FanCoil(FanCoilNum).FanName);
     638           0 :                         ShowContinueError(state, format("... Fan flow = {:.5T} m3/s.", FanCoil(FanCoilNum).FanAirVolFlow));
     639           0 :                         ShowContinueError(state, "... Fan Coil Unit flow rate reduced to match the fan flow rate and the simulation continues.");
     640           0 :                         FanCoil(FanCoilNum).MaxAirVolFlow = FanCoil(FanCoilNum).FanAirVolFlow;
     641             :                     }
     642             : 
     643             :                     // check that for VariableFanVariableFlow or VariableFanConstantFlow that the fan speed control is continuous
     644          36 :                     if (FanCoil(FanCoilNum).CapCtrlMeth_Num == CCM::VarFanVarFlow || FanCoil(FanCoilNum).CapCtrlMeth_Num == CCM::VarFanConsFlow ||
     645          18 :                         FanCoil(FanCoilNum).CapCtrlMeth_Num == CCM::ASHRAE) { // then expect continuous speed control fan
     646           3 :                         if (state.dataHVACFan->fanObjs[FanCoil(FanCoilNum).FanIndex]->speedControl !=
     647             :                             HVACFan::FanSystem::SpeedControlMethod::Continuous) {
     648           0 :                             ShowSevereError(state, std::string{RoutineName} + FanCoil(FanCoilNum).UnitType + ": " + FanCoil(FanCoilNum).Name);
     649           0 :                             ShowContinueError(state,
     650           0 :                                               "...the fan type of the object : " + FanCoil(FanCoilNum).FanName +
     651           0 :                                                   " does not match with the capacity control method selected : " + FanCoil(FanCoilNum).CapCtrlMeth +
     652             :                                                   " please see I/O reference");
     653           0 :                             ShowContinueError(
     654             :                                 state,
     655             :                                 "...for VariableFanVariableFlow or VariableFanConstantFlow a Fan:SystemModel should have Continuous speed control.");
     656           0 :                             ErrorsFound = true;
     657             :                         }
     658             :                     }
     659             :                 }
     660             :             }
     661             : 
     662             :             // check low speed fan ratio when using ASHRAE90.1 capacity control method
     663          81 :             if (FanCoil(FanCoilNum).CapCtrlMeth_Num == CCM::ASHRAE) {
     664           3 :                 if (FanCoil(FanCoilNum).LowSpeedRatio > 0.5) {
     665           0 :                     ShowWarningError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + FanCoil(FanCoilNum).Name + "\",");
     666           0 :                     ShowContinueError(state, "... " + cNumericFields(2) + " is greater than the 50% of the supply air flow ratio.");
     667           0 :                     ShowContinueError(state,
     668           0 :                                       format("... Fan Coil Unit low speed supply air flow ratio = {:.5T} ", FanCoil(FanCoilNum).LowSpeedRatio));
     669           3 :                 } else if (FanCoil(FanCoilNum).LowSpeedRatio == 0.0) {
     670           0 :                     ShowWarningError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + FanCoil(FanCoilNum).Name + "\",");
     671           0 :                     ShowContinueError(state, "... " + cNumericFields(2) + " is equal to 0.");
     672           0 :                     ShowContinueError(state, "... Fan Coil Unit low speed supply air flow ratio should be greater than 0 to comply with ASHRAE90.1.");
     673           0 :                     ShowContinueError(state, "... Fan Coil Unit low speed supply air flow ratio set to 0.5");
     674           0 :                     FanCoil(FanCoilNum).LowSpeedRatio = 0.5;
     675             :                 }
     676             :             }
     677             : 
     678             :             // Set defaults for convergence tolerance
     679          81 :             if (FanCoil(FanCoilNum).ColdControlOffset <= 0.0) {
     680           0 :                 FanCoil(FanCoilNum).ColdControlOffset = 0.001;
     681             :             }
     682          81 :             if (FanCoil(FanCoilNum).HotControlOffset <= 0.0) {
     683           0 :                 FanCoil(FanCoilNum).HotControlOffset = 0.001;
     684             :             }
     685             : 
     686             :             // check for inlet side air mixer
     687         567 :             GetATMixer(state,
     688          81 :                        FanCoil(FanCoilNum).Name,
     689             :                        ATMixerName,
     690          81 :                        state.dataFanCoilUnits->ATMixerNum,
     691          81 :                        state.dataFanCoilUnits->ATMixerType,
     692          81 :                        state.dataFanCoilUnits->ATMixerPriNode,
     693          81 :                        state.dataFanCoilUnits->ATMixerSecNode,
     694          81 :                        state.dataFanCoilUnits->ATMixerOutNode,
     695          81 :                        FanCoil(FanCoilNum).AirOutNode);
     696          81 :             FanCoil(FanCoilNum).ControlZoneNum =
     697          81 :                 DataZoneEquipment::GetZoneEquipControlledZoneNum(state, DataZoneEquipment::ZoneEquip::FanCoil4Pipe, FanCoil(FanCoilNum).Name);
     698          81 :             if (FanCoil(FanCoilNum).ControlZoneNum == 0) {
     699           0 :                 ErrorsFound = true;
     700             :             }
     701          81 :             if (state.dataFanCoilUnits->ATMixerType == ATMixer_InletSide) {
     702             :                 // save the air terminal mixer data in the fan coil data array
     703           5 :                 FanCoil(FanCoilNum).ATMixerExists = true;
     704           5 :                 FanCoil(FanCoilNum).ATMixerIndex = state.dataFanCoilUnits->ATMixerNum;
     705           5 :                 FanCoil(FanCoilNum).ATMixerName = ATMixerName;
     706           5 :                 FanCoil(FanCoilNum).ATMixerType = ATMixer_InletSide;
     707           5 :                 FanCoil(FanCoilNum).ATMixerPriNode = state.dataFanCoilUnits->ATMixerPriNode;
     708           5 :                 FanCoil(FanCoilNum).ATMixerSecNode = state.dataFanCoilUnits->ATMixerSecNode;
     709           5 :                 FanCoil(FanCoilNum).ATMixerOutNode = state.dataFanCoilUnits->ATMixerOutNode;
     710             :                 // check that fan coil doesn' have local outside air
     711           5 :                 if (!lAlphaBlanks(8)) {
     712           0 :                     ShowSevereError(state,
     713           0 :                                     CurrentModuleObject + " = \"" + FanCoil(FanCoilNum).Name +
     714             :                                         "\". Fan coil unit has local as well as central outdoor air specified");
     715             :                 }
     716             :                 // check that the air teminal mixer out node is the fan coil inlet node
     717           5 :                 if (FanCoil(FanCoilNum).AirInNode != state.dataFanCoilUnits->ATMixerOutNode) {
     718           0 :                     ShowSevereError(state,
     719           0 :                                     CurrentModuleObject + " = \"" + FanCoil(FanCoilNum).Name +
     720             :                                         "\". Fan coil unit air inlet node name must be the same as an air terminal mixer outlet node name.");
     721           0 :                     ShowContinueError(state, "..Air terminal mixer outlet node name is specified in AirTerminal:SingleDuct:InletSideMixer object.");
     722           0 :                     ShowContinueError(state, "..Fan coil unit air inlet node name = " + state.dataLoopNodes->NodeID(FanCoil(FanCoilNum).AirInNode));
     723           0 :                     ErrorsFound = true;
     724             :                 }
     725             :                 // check for supply side air terminal mixer
     726          76 :             } else if (state.dataFanCoilUnits->ATMixerType == ATMixer_SupplySide) {
     727             :                 // save the air terminal mixer data in the fan coil data array
     728           5 :                 FanCoil(FanCoilNum).ATMixerExists = true;
     729           5 :                 FanCoil(FanCoilNum).ATMixerIndex = state.dataFanCoilUnits->ATMixerNum;
     730           5 :                 FanCoil(FanCoilNum).ATMixerName = ATMixerName;
     731           5 :                 FanCoil(FanCoilNum).ATMixerType = ATMixer_SupplySide;
     732           5 :                 FanCoil(FanCoilNum).ATMixerPriNode = state.dataFanCoilUnits->ATMixerPriNode;
     733           5 :                 FanCoil(FanCoilNum).ATMixerSecNode = state.dataFanCoilUnits->ATMixerSecNode;
     734           5 :                 FanCoil(FanCoilNum).ATMixerOutNode = state.dataFanCoilUnits->ATMixerOutNode;
     735             :                 // check that fan coil doesn' have local outside air
     736           5 :                 if (!lAlphaBlanks(8)) {
     737           0 :                     ShowSevereError(state,
     738           0 :                                     CurrentModuleObject + " = \"" + FanCoil(FanCoilNum).Name +
     739             :                                         "\". Fan coil unit has local as well as central outdoor air specified");
     740             :                 }
     741             :                 // check that the air teminal mixer secondary air inlet node is the fan coil outlet node
     742           5 :                 if (FanCoil(FanCoilNum).AirOutNode != state.dataFanCoilUnits->ATMixerSecNode) {
     743           0 :                     ShowSevereError(
     744             :                         state,
     745           0 :                         CurrentModuleObject + " = \"" + FanCoil(FanCoilNum).Name +
     746             :                             "\". Fan coil unit air outlet node name must be the same as the air terminal mixer secondary air inlet node name.");
     747           0 :                     ShowContinueError(
     748             :                         state, "..Air terminal mixer secondary inlet node name is specified in AirTerminal:SingleDuct:SupplySideMixer object.");
     749           0 :                     ShowContinueError(state, "..Fan coil unit air outlet node name = " + state.dataLoopNodes->NodeID(FanCoil(FanCoilNum).AirOutNode));
     750           0 :                     ErrorsFound = true;
     751             :                 }
     752           5 :                 bool ZoneNodeNotFound = true;
     753           5 :                 for (NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(FanCoil(FanCoilNum).ControlZoneNum).NumExhaustNodes; ++NodeNum) {
     754          10 :                     if (FanCoil(FanCoilNum).AirInNode ==
     755           5 :                         state.dataZoneEquip->ZoneEquipConfig(FanCoil(FanCoilNum).ControlZoneNum).ExhaustNode(NodeNum)) {
     756           5 :                         ZoneNodeNotFound = false;
     757           5 :                         break;
     758             :                     }
     759             :                 }
     760           5 :                 if (ZoneNodeNotFound) {
     761           0 :                     bool InletNodeFound = false;
     762           0 :                     if (FanCoil(FanCoilNum).ControlZoneNum > 0) {
     763           0 :                         InletNodeFound =
     764           0 :                             ZonePlenum::ValidateInducedNode(state,
     765           0 :                                                             FanCoil(FanCoilNum).AirInNode,
     766           0 :                                                             state.dataZoneEquip->ZoneEquipConfig(FanCoil(FanCoilNum).ControlZoneNum).NumReturnNodes,
     767           0 :                                                             state.dataZoneEquip->ZoneEquipConfig(FanCoil(FanCoilNum).ControlZoneNum).ReturnNode);
     768             :                     }
     769           0 :                     if (!InletNodeFound) {
     770           0 :                         ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + FanCoil(FanCoilNum).Name + "\"");
     771           0 :                         ShowContinueError(state,
     772             :                                           "..FanCoil inlet node name must be the same as either a zone exhaust node name or an induced "
     773             :                                           "air node in ZonePlenum.");
     774           0 :                         ShowContinueError(state, "..Zone exhaust node name is specified in ZoneHVAC:EquipmentConnections object.");
     775           0 :                         ShowContinueError(state, "..Induced Air Outlet Node name is specified in AirLoopHVAC:ReturnPlenum object.");
     776           0 :                         ShowContinueError(state, "..FanCoil inlet node name = " + state.dataLoopNodes->NodeID(FanCoil(FanCoilNum).AirInNode));
     777           0 :                         ErrorsFound = true;
     778             :                     }
     779             :                 }
     780             :                 // no air terminal mixer; do the normal connectivity checks
     781             :             } else {
     782             :                 // check that the fan coil inlet node is the same as one of the zone exhaust nodes
     783          71 :                 state.dataFanCoilUnits->ZoneExNodeNotFound = true;
     784          71 :                 for (NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(FanCoil(FanCoilNum).ControlZoneNum).NumExhaustNodes; ++NodeNum) {
     785         142 :                     if (FanCoil(FanCoilNum).AirInNode ==
     786          71 :                         state.dataZoneEquip->ZoneEquipConfig(FanCoil(FanCoilNum).ControlZoneNum).ExhaustNode(NodeNum)) {
     787          71 :                         state.dataFanCoilUnits->ZoneExNodeNotFound = false;
     788          71 :                         break;
     789             :                     }
     790             :                 }
     791          71 :                 if (state.dataFanCoilUnits->ZoneExNodeNotFound) {
     792           0 :                     bool InletNodeFound = false;
     793           0 :                     InletNodeFound =
     794           0 :                         ZonePlenum::ValidateInducedNode(state,
     795           0 :                                                         FanCoil(FanCoilNum).AirInNode,
     796           0 :                                                         state.dataZoneEquip->ZoneEquipConfig(FanCoil(FanCoilNum).ControlZoneNum).NumReturnNodes,
     797           0 :                                                         state.dataZoneEquip->ZoneEquipConfig(FanCoil(FanCoilNum).ControlZoneNum).ReturnNode);
     798             : 
     799           0 :                     if (!InletNodeFound) {
     800           0 :                         ShowSevereError(state,
     801           0 :                                         CurrentModuleObject + " = \"" + FanCoil(FanCoilNum).Name +
     802             :                                             "\". Fan coil unit air inlet node name must be the same either as a zone exhaust node name or an induce "
     803             :                                             "air node in ZoePlenum.");
     804           0 :                         ShowContinueError(state, "..Zone exhaust node name is specified in ZoneHVAC:EquipmentConnections object.");
     805           0 :                         ShowContinueError(state, "..Induced Air Outlet Node name is specified in AirLoopHVAC:ReturnPlenum object.");
     806           0 :                         ShowContinueError(state,
     807           0 :                                           "..Fan coil unit air inlet node name = " + state.dataLoopNodes->NodeID(FanCoil(FanCoilNum).AirInNode));
     808           0 :                         ErrorsFound = true;
     809             :                     }
     810             :                 }
     811             :                 // check that the fan coil outlet node is the same as one of the zone inlet nodes
     812          71 :                 state.dataFanCoilUnits->ZoneInNodeNotFound = true;
     813          71 :                 if (FanCoil(FanCoilNum).ControlZoneNum > 0) {
     814          71 :                     FanCoil(FanCoilNum).NodeNumOfControlledZone = state.dataZoneEquip->ZoneEquipConfig(FanCoil(FanCoilNum).ControlZoneNum).ZoneNode;
     815          71 :                     state.dataFanCoilUnits->ZoneInNodeNotFound = false;
     816             :                 }
     817             : 
     818          71 :                 if (state.dataFanCoilUnits->ZoneInNodeNotFound) {
     819           0 :                     ShowSevereError(state,
     820           0 :                                     CurrentModuleObject + " = \"" + FanCoil(FanCoilNum).Name +
     821             :                                         "\". Fan coil unit air outlet node name must be the same as a zone inlet node name.");
     822           0 :                     ShowContinueError(state, "..Zone inlet node name is specified in ZoneHVAC:EquipmentConnections object.");
     823           0 :                     ShowContinueError(state, "..Fan coil unit air outlet node name = " + state.dataLoopNodes->NodeID(FanCoil(FanCoilNum).AirOutNode));
     824             : 
     825           0 :                     ErrorsFound = true;
     826             :                 }
     827             :             }
     828          81 :             if (FanCoil(FanCoilNum).CapCtrlMeth == "MULTISPEEDFAN") {
     829           3 :                 if (!lAlphaBlanks(17)) {
     830           2 :                     FanCoil(FanCoilNum).FanOpModeSchedPtr = GetScheduleIndex(state, Alphas(17));
     831           4 :                     if (FanCoil(FanCoilNum).FanType_Num != FanType_SimpleOnOff &&
     832           2 :                         FanCoil(FanCoilNum).FanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
     833           0 :                         ShowSevereError(state, CurrentModuleObject + " = " + FanCoil(FanCoilNum).Name);
     834           0 :                         ShowContinueError(state, "For " + cAlphaFields(17) + " = " + Alphas(17));
     835           0 :                         ShowContinueError(state, "Illegal " + cAlphaFields(9) + " = " + Alphas(9));
     836           0 :                         ShowContinueError(state, "...fan operating schedule is allowed for on off or system model fan type only )");
     837           0 :                         ErrorsFound = true;
     838             :                     } else {
     839           2 :                         if (FanCoil(FanCoilNum).FanOpModeSchedPtr == 0) {
     840           0 :                             ShowSevereError(state, CurrentModuleObject + " = " + FanCoil(FanCoilNum).Name);
     841           0 :                             ShowContinueError(state, "Illegal " + cAlphaFields(17) + " = " + Alphas(17));
     842           0 :                             ErrorsFound = true;
     843             :                         }
     844             :                     }
     845             :                 } else {
     846           2 :                     if (FanCoil(FanCoilNum).FanType_Num == FanType_SimpleOnOff ||
     847           1 :                         FanCoil(FanCoilNum).FanType_Num == DataHVACGlobals::FanType_SystemModelObject) {
     848           1 :                         FanCoil(FanCoilNum).FanOpMode = CycFanCycCoil;
     849             :                     }
     850             :                 }
     851             :             }
     852             : 
     853          81 :             if (!lNumericBlanks(11)) {
     854           0 :                 FanCoil(FanCoilNum).DesignMinOutletTemp = Numbers(11);
     855           0 :                 if (lNumericBlanks(12)) {
     856           0 :                     ShowWarningError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + FanCoil(FanCoilNum).Name + "\",");
     857           0 :                     ShowContinueError(state, "... " + cNumericFields(11) + " and " + cNumericFields(12) + " must be used in unison.");
     858           0 :                     ErrorsFound = true;
     859             :                 }
     860             :             }
     861             : 
     862          81 :             if (!lNumericBlanks(12)) {
     863           0 :                 FanCoil(FanCoilNum).DesignMaxOutletTemp = Numbers(12);
     864           0 :                 if (FanCoil(FanCoilNum).DesignMinOutletTemp != AutoSize && FanCoil(FanCoilNum).DesignMaxOutletTemp != AutoSize) {
     865           0 :                     if (FanCoil(FanCoilNum).DesignMaxOutletTemp < FanCoil(FanCoilNum).DesignMinOutletTemp) {
     866           0 :                         ShowWarningError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + FanCoil(FanCoilNum).Name + "\",");
     867           0 :                         ShowContinueError(state, "... " + cNumericFields(11) + " is greater than " + cNumericFields(12) + ".");
     868           0 :                         ShowContinueError(state, format("... {} = {:.2T} [C].", cNumericFields(11), FanCoil(FanCoilNum).DesignMinOutletTemp));
     869           0 :                         ShowContinueError(state, format("... {} = {:.2T} [C].", cNumericFields(12), FanCoil(FanCoilNum).DesignMaxOutletTemp));
     870           0 :                         ErrorsFound = true;
     871             :                     }
     872             :                 }
     873           0 :                 if (lNumericBlanks(11)) {
     874           0 :                     ShowWarningError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + FanCoil(FanCoilNum).Name + "\",");
     875           0 :                     ShowContinueError(state, "... " + cNumericFields(11) + " and " + cNumericFields(12) + " must be used in unison.");
     876           0 :                     ErrorsFound = true;
     877             :                 }
     878             :             }
     879             : 
     880          81 :             if (FanCoil(FanCoilNum).DesignMinOutletTemp > 0.0 && FanCoil(FanCoilNum).DesignMaxOutletTemp > 0.0) {
     881           0 :                 FanCoil(FanCoilNum).ASHRAETempControl = true;
     882          81 :             } else if (FanCoil(FanCoilNum).DesignMinOutletTemp == AutoSize || FanCoil(FanCoilNum).DesignMaxOutletTemp == AutoSize) {
     883           0 :                 FanCoil(FanCoilNum).ASHRAETempControl = true;
     884             :             }
     885             : 
     886             :             // Set up component set for supply fan
     887          81 :             if (FanCoil(FanCoilNum).OutsideAirNode > 0) {
     888         355 :                 SetUpCompSets(state,
     889          71 :                               FanCoil(FanCoilNum).UnitType,
     890          71 :                               FanCoil(FanCoilNum).Name,
     891          71 :                               FanCoil(FanCoilNum).FanType,
     892          71 :                               FanCoil(FanCoilNum).FanName,
     893          71 :                               state.dataLoopNodes->NodeID(FanCoil(FanCoilNum).MixedAirNode),
     894          71 :                               "UNDEFINED");
     895             :             } else {
     896          50 :                 SetUpCompSets(state,
     897          10 :                               FanCoil(FanCoilNum).UnitType,
     898          10 :                               FanCoil(FanCoilNum).Name,
     899          10 :                               FanCoil(FanCoilNum).FanType,
     900          10 :                               FanCoil(FanCoilNum).FanName,
     901          10 :                               state.dataLoopNodes->NodeID(FanCoil(FanCoilNum).AirInNode),
     902          10 :                               "UNDEFINED");
     903             :             }
     904             :             // Set up component set for cooling coil
     905         324 :             SetUpCompSets(state,
     906          81 :                           FanCoil(FanCoilNum).UnitType,
     907          81 :                           FanCoil(FanCoilNum).Name,
     908          81 :                           FanCoil(FanCoilNum).CCoilType,
     909          81 :                           FanCoil(FanCoilNum).CCoilName,
     910             :                           "UNDEFINED",
     911          81 :                           "UNDEFINED");
     912             : 
     913             :             // Set up component set for heating coil
     914         405 :             SetUpCompSets(state,
     915          81 :                           FanCoil(FanCoilNum).UnitType,
     916          81 :                           FanCoil(FanCoilNum).Name,
     917          81 :                           FanCoil(FanCoilNum).HCoilType,
     918          81 :                           FanCoil(FanCoilNum).HCoilName,
     919             :                           "UNDEFINED",
     920         162 :                           state.dataLoopNodes->NodeID(FanCoil(FanCoilNum).AirOutNode));
     921             : 
     922             :             // Set up component set for OA mixer - use OA node and Mixed air node
     923          81 :             if (FanCoil(FanCoilNum).OutsideAirNode > 0) {
     924         426 :                 SetUpCompSets(state,
     925          71 :                               FanCoil(FanCoilNum).UnitType,
     926          71 :                               FanCoil(FanCoilNum).Name,
     927          71 :                               FanCoil(FanCoilNum).OAMixType,
     928          71 :                               FanCoil(FanCoilNum).OAMixName,
     929          71 :                               state.dataLoopNodes->NodeID(FanCoil(FanCoilNum).OutsideAirNode),
     930          71 :                               state.dataLoopNodes->NodeID(FanCoil(FanCoilNum).MixedAirNode));
     931             :             }
     932             :         }
     933             : 
     934          19 :         Alphas.deallocate();
     935          19 :         cAlphaFields.deallocate();
     936          19 :         cNumericFields.deallocate();
     937          19 :         Numbers.deallocate();
     938          19 :         lAlphaBlanks.deallocate();
     939          19 :         lNumericBlanks.deallocate();
     940             : 
     941          19 :         if (ErrorsFound) {
     942           0 :             ShowFatalError(state, std::string{RoutineName} + "Errors found in input. Preceding condition(s) cause termination.");
     943             :         }
     944             : 
     945         100 :         for (FanCoilNum = 1; FanCoilNum <= state.dataFanCoilUnits->NumFanCoils; ++FanCoilNum) {
     946             :             // Setup Report variables for the Fan Coils
     947             :             // CurrentModuleObject='ZoneHVAC:FourPipeFanCoil'
     948         324 :             SetupOutputVariable(state,
     949             :                                 "Fan Coil Heating Rate",
     950             :                                 OutputProcessor::Unit::W,
     951          81 :                                 FanCoil(FanCoilNum).HeatPower,
     952             :                                 OutputProcessor::SOVTimeStepType::System,
     953             :                                 OutputProcessor::SOVStoreType::Average,
     954         162 :                                 FanCoil(FanCoilNum).Name);
     955         324 :             SetupOutputVariable(state,
     956             :                                 "Fan Coil Heating Energy",
     957             :                                 OutputProcessor::Unit::J,
     958          81 :                                 FanCoil(FanCoilNum).HeatEnergy,
     959             :                                 OutputProcessor::SOVTimeStepType::System,
     960             :                                 OutputProcessor::SOVStoreType::Summed,
     961         162 :                                 FanCoil(FanCoilNum).Name);
     962         324 :             SetupOutputVariable(state,
     963             :                                 "Fan Coil Total Cooling Rate",
     964             :                                 OutputProcessor::Unit::W,
     965          81 :                                 FanCoil(FanCoilNum).TotCoolPower,
     966             :                                 OutputProcessor::SOVTimeStepType::System,
     967             :                                 OutputProcessor::SOVStoreType::Average,
     968         162 :                                 FanCoil(FanCoilNum).Name);
     969         324 :             SetupOutputVariable(state,
     970             :                                 "Fan Coil Total Cooling Energy",
     971             :                                 OutputProcessor::Unit::J,
     972          81 :                                 FanCoil(FanCoilNum).TotCoolEnergy,
     973             :                                 OutputProcessor::SOVTimeStepType::System,
     974             :                                 OutputProcessor::SOVStoreType::Summed,
     975         162 :                                 FanCoil(FanCoilNum).Name);
     976         324 :             SetupOutputVariable(state,
     977             :                                 "Fan Coil Sensible Cooling Rate",
     978             :                                 OutputProcessor::Unit::W,
     979          81 :                                 FanCoil(FanCoilNum).SensCoolPower,
     980             :                                 OutputProcessor::SOVTimeStepType::System,
     981             :                                 OutputProcessor::SOVStoreType::Average,
     982         162 :                                 FanCoil(FanCoilNum).Name);
     983         324 :             SetupOutputVariable(state,
     984             :                                 "Fan Coil Sensible Cooling Energy",
     985             :                                 OutputProcessor::Unit::J,
     986          81 :                                 FanCoil(FanCoilNum).SensCoolEnergy,
     987             :                                 OutputProcessor::SOVTimeStepType::System,
     988             :                                 OutputProcessor::SOVStoreType::Summed,
     989         162 :                                 FanCoil(FanCoilNum).Name);
     990         324 :             SetupOutputVariable(state,
     991             :                                 "Fan Coil Fan Electricity Rate",
     992             :                                 OutputProcessor::Unit::W,
     993          81 :                                 FanCoil(FanCoilNum).ElecPower,
     994             :                                 OutputProcessor::SOVTimeStepType::System,
     995             :                                 OutputProcessor::SOVStoreType::Average,
     996         162 :                                 FanCoil(FanCoilNum).Name);
     997         324 :             SetupOutputVariable(state,
     998             :                                 "Fan Coil Fan Electricity Energy",
     999             :                                 OutputProcessor::Unit::J,
    1000          81 :                                 FanCoil(FanCoilNum).ElecEnergy,
    1001             :                                 OutputProcessor::SOVTimeStepType::System,
    1002             :                                 OutputProcessor::SOVStoreType::Summed,
    1003         162 :                                 FanCoil(FanCoilNum).Name);
    1004          81 :             if (FanCoil(FanCoilNum).CapCtrlMeth_Num == CCM::CycFan || FanCoil(FanCoilNum).CapCtrlMeth_Num == CCM::MultiSpeedFan) {
    1005         168 :                 SetupOutputVariable(state,
    1006             :                                     "Fan Coil Runtime Fraction",
    1007             :                                     OutputProcessor::Unit::None,
    1008          42 :                                     FanCoil(FanCoilNum).PLR,
    1009             :                                     OutputProcessor::SOVTimeStepType::System,
    1010             :                                     OutputProcessor::SOVStoreType::Average,
    1011          84 :                                     FanCoil(FanCoilNum).Name);
    1012         168 :                 SetupOutputVariable(state,
    1013             :                                     "Fan Coil Fan Speed Level",
    1014             :                                     OutputProcessor::Unit::None,
    1015          42 :                                     FanCoil(FanCoilNum).SpeedFanSel,
    1016             :                                     OutputProcessor::SOVTimeStepType::System,
    1017             :                                     OutputProcessor::SOVStoreType::Average,
    1018          84 :                                     FanCoil(FanCoilNum).Name);
    1019          42 :                 if (FanCoil(FanCoilNum).CapCtrlMeth_Num == CCM::MultiSpeedFan) {
    1020          12 :                     SetupOutputVariable(state,
    1021             :                                         "Fan Coil Speed Ratio",
    1022             :                                         OutputProcessor::Unit::None,
    1023           3 :                                         FanCoil(FanCoilNum).SpeedRatio,
    1024             :                                         OutputProcessor::SOVTimeStepType::System,
    1025             :                                         OutputProcessor::SOVStoreType::Average,
    1026           6 :                                         FanCoil(FanCoilNum).Name);
    1027          12 :                     SetupOutputVariable(state,
    1028             :                                         "Fan Coil Part Load Ratio",
    1029             :                                         OutputProcessor::Unit::None,
    1030           3 :                                         FanCoil(FanCoilNum).PLR,
    1031             :                                         OutputProcessor::SOVTimeStepType::System,
    1032             :                                         OutputProcessor::SOVStoreType::Average,
    1033           6 :                                         FanCoil(FanCoilNum).Name);
    1034             :                 }
    1035             :             }
    1036          81 :             if (FanCoil(FanCoilNum).CapCtrlMeth_Num == CCM::VarFanVarFlow || FanCoil(FanCoilNum).CapCtrlMeth_Num == CCM::VarFanConsFlow) {
    1037           0 :                 SetupOutputVariable(state,
    1038             :                                     "Fan Coil Part Load Ratio",
    1039             :                                     OutputProcessor::Unit::None,
    1040           0 :                                     FanCoil(FanCoilNum).PLR,
    1041             :                                     OutputProcessor::SOVTimeStepType::System,
    1042             :                                     OutputProcessor::SOVStoreType::Average,
    1043           0 :                                     FanCoil(FanCoilNum).Name);
    1044             :             }
    1045         324 :             SetupOutputVariable(state,
    1046             :                                 "Fan Coil Availability Status",
    1047             :                                 OutputProcessor::Unit::None,
    1048          81 :                                 FanCoil(FanCoilNum).AvailStatus,
    1049             :                                 OutputProcessor::SOVTimeStepType::System,
    1050             :                                 OutputProcessor::SOVStoreType::Average,
    1051         162 :                                 FanCoil(FanCoilNum).Name);
    1052             :         }
    1053             : 
    1054         100 :         for (FanCoilNum = 1; FanCoilNum <= state.dataFanCoilUnits->NumFanCoils; ++FanCoilNum) {
    1055          81 :             if (FanCoil(FanCoilNum).FanType_Num == DataHVACGlobals::FanType_SystemModelObject) {
    1056          90 :                 state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(state,
    1057          18 :                                                                                          FanCoil(FanCoilNum).CCoilName,
    1058          18 :                                                                                          FanCoil(FanCoilNum).CCoilType,
    1059          18 :                                                                                          FanCoil(FanCoilNum).FanName,
    1060             :                                                                                          DataAirSystems::ObjectVectorOOFanSystemModel,
    1061          18 :                                                                                          FanCoil(FanCoilNum).FanIndex);
    1062          90 :                 state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(state,
    1063          18 :                                                                                          FanCoil(FanCoilNum).HCoilName,
    1064          18 :                                                                                          FanCoil(FanCoilNum).HCoilType,
    1065          18 :                                                                                          FanCoil(FanCoilNum).FanName,
    1066             :                                                                                          DataAirSystems::ObjectVectorOOFanSystemModel,
    1067          18 :                                                                                          FanCoil(FanCoilNum).FanIndex);
    1068             :             } else {
    1069         315 :                 state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(state,
    1070          63 :                                                                                          FanCoil(FanCoilNum).CCoilName,
    1071          63 :                                                                                          FanCoil(FanCoilNum).CCoilType,
    1072          63 :                                                                                          FanCoil(FanCoilNum).FanName,
    1073             :                                                                                          DataAirSystems::StructArrayLegacyFanModels,
    1074          63 :                                                                                          FanCoil(FanCoilNum).FanIndex);
    1075         315 :                 state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(state,
    1076          63 :                                                                                          FanCoil(FanCoilNum).HCoilName,
    1077          63 :                                                                                          FanCoil(FanCoilNum).HCoilType,
    1078          63 :                                                                                          FanCoil(FanCoilNum).FanName,
    1079             :                                                                                          DataAirSystems::StructArrayLegacyFanModels,
    1080          63 :                                                                                          FanCoil(FanCoilNum).FanIndex);
    1081             :             }
    1082             :         }
    1083          19 :     }
    1084             : 
    1085      514191 :     void InitFanCoilUnits(EnergyPlusData &state,
    1086             :                           int const FanCoilNum,       // number of the current fan coil unit being simulated
    1087             :                           int const ControlledZoneNum // number of zone being served
    1088             :     )
    1089             :     {
    1090             : 
    1091             :         // SUBROUTINE INFORMATION:
    1092             :         //       AUTHOR         Fred Buhl
    1093             :         //       DATE WRITTEN   March 2000
    1094             :         //       MODIFIED       July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
    1095             :         //       RE-ENGINEERED  na
    1096             : 
    1097             :         // PURPOSE OF THIS SUBROUTINE:
    1098             :         // This subroutine is for initializations of the Fan Coil Components.
    1099             : 
    1100             :         // METHODOLOGY EMPLOYED:
    1101             :         // Uses the status flags to trigger initializations.
    1102             : 
    1103             :         // Using/Aliasing
    1104      514191 :         auto &ZoneComp = state.dataHVACGlobal->ZoneComp;
    1105             :         using DataZoneEquipment::CheckZoneEquipmentList;
    1106             :         using FluidProperties::GetDensityGlycol;
    1107             :         using PlantUtilities::InitComponentNodes;
    1108             :         using PlantUtilities::ScanPlantLoopsForObject;
    1109             :         using Psychrometrics::PsyRhoAirFnPbTdbW;
    1110             : 
    1111             :         // SUBROUTINE PARAMETER DEFINITIONS:
    1112             :         static constexpr std::string_view RoutineName("InitFanCoilUnits");
    1113             : 
    1114             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1115             :         int InNode;         // inlet node number in fan coil loop
    1116             :         int OutNode;        // outlet node number in fan coil loop
    1117             :         int InletNode;      // inlet node number for fan coil FanCoilNum
    1118             :         int HotConNode;     // hot water control node number in fan coil loop
    1119             :         int ColdConNode;    // hot water control node number in fan coil loop
    1120             :         int OutsideAirNode; // outside air node number in fan coil loop
    1121             :         int AirRelNode;     // relief air node number in fan coil loop
    1122             :         Real64 RhoAir;      // air density at InNode
    1123             :         int Loop;
    1124             :         Real64 rho;
    1125             :         bool errFlag;
    1126             : 
    1127      514191 :         auto &FanCoil(state.dataFanCoilUnits->FanCoil);
    1128             : 
    1129             :         // Do the one time initializations
    1130      514191 :         if (state.dataFanCoilUnits->InitFanCoilUnitsOneTimeFlag) {
    1131             : 
    1132          19 :             state.dataFanCoilUnits->MyEnvrnFlag.allocate(state.dataFanCoilUnits->NumFanCoils);
    1133          19 :             state.dataFanCoilUnits->MySizeFlag.allocate(state.dataFanCoilUnits->NumFanCoils);
    1134          19 :             state.dataFanCoilUnits->MyPlantScanFlag.allocate(state.dataFanCoilUnits->NumFanCoils);
    1135          19 :             state.dataFanCoilUnits->MyZoneEqFlag.allocate(state.dataFanCoilUnits->NumFanCoils);
    1136          19 :             state.dataFanCoilUnits->MyEnvrnFlag = true;
    1137          19 :             state.dataFanCoilUnits->MySizeFlag = true;
    1138          19 :             state.dataFanCoilUnits->MyPlantScanFlag = true;
    1139          19 :             state.dataFanCoilUnits->MyZoneEqFlag = true;
    1140          19 :             state.dataFanCoilUnits->InitFanCoilUnitsOneTimeFlag = false;
    1141             :         }
    1142             : 
    1143      514191 :         if (allocated(ZoneComp)) {
    1144      514191 :             if (state.dataFanCoilUnits->MyZoneEqFlag(FanCoilNum)) { // initialize the name of each availability manager list and zone number
    1145         162 :                 ZoneComp(DataZoneEquipment::ZoneEquip::FanCoil4Pipe).ZoneCompAvailMgrs(FanCoilNum).AvailManagerListName =
    1146         162 :                     FanCoil(FanCoilNum).AvailManagerListName;
    1147          81 :                 ZoneComp(DataZoneEquipment::ZoneEquip::FanCoil4Pipe).ZoneCompAvailMgrs(FanCoilNum).ZoneNum = ControlledZoneNum;
    1148          81 :                 state.dataFanCoilUnits->MyZoneEqFlag(FanCoilNum) = false;
    1149             :             }
    1150      514191 :             FanCoil(FanCoilNum).AvailStatus = ZoneComp(DataZoneEquipment::ZoneEquip::FanCoil4Pipe).ZoneCompAvailMgrs(FanCoilNum).AvailStatus;
    1151             :         }
    1152             : 
    1153      514191 :         if (state.dataFanCoilUnits->MyPlantScanFlag(FanCoilNum) && allocated(state.dataPlnt->PlantLoop)) {
    1154          81 :             errFlag = false;
    1155          81 :             if (FanCoil(FanCoilNum).HCoilType_Num == HCoil::Water) {
    1156         320 :                 ScanPlantLoopsForObject(state,
    1157          80 :                                         FanCoil(FanCoilNum).HCoilName,
    1158          80 :                                         FanCoil(FanCoilNum).HCoilPlantTypeOf,
    1159          80 :                                         FanCoil(FanCoilNum).HeatCoilPlantLoc,
    1160             :                                         errFlag,
    1161             :                                         _,
    1162             :                                         _,
    1163             :                                         _,
    1164             :                                         _,
    1165             :                                         _);
    1166             : 
    1167          80 :                 if (errFlag) {
    1168           0 :                     ShowContinueError(state, "Reference Unit=\"" + FanCoil(FanCoilNum).Name + "\", type=" + FanCoil(FanCoilNum).UnitType);
    1169           0 :                     ShowFatalError(state, "InitFanCoilUnits: Program terminated for previous conditions.");
    1170             :                 }
    1171             : 
    1172          80 :                 FanCoil(FanCoilNum).HeatCoilFluidOutletNodeNum =
    1173          80 :                     DataPlant::CompData::getPlantComponent(state, FanCoil(FanCoilNum).HeatCoilPlantLoc).NodeNumOut;
    1174             : 
    1175           1 :             } else if (FanCoil(FanCoilNum).HCoilType_Num == HCoil::Electric) {
    1176             :                 // do nothing, valid type
    1177             :             } else {
    1178           0 :                 ShowFatalError(state, "InitFanCoilUnits: FanCoil=" + FanCoil(FanCoilNum).Name + ", invalid heating coil type. Program terminated.");
    1179             :             }
    1180             : 
    1181          81 :             if ((FanCoil(FanCoilNum).CCoilPlantType == DataPlant::PlantEquipmentType::CoilWaterCooling) ||
    1182           0 :                 (FanCoil(FanCoilNum).CCoilPlantType == DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling)) {
    1183         324 :                 ScanPlantLoopsForObject(state,
    1184          81 :                                         FanCoil(FanCoilNum).CCoilPlantName,
    1185          81 :                                         FanCoil(FanCoilNum).CCoilPlantType,
    1186          81 :                                         FanCoil(FanCoilNum).CoolCoilPlantLoc,
    1187             :                                         errFlag,
    1188             :                                         _,
    1189             :                                         _,
    1190             :                                         _,
    1191             :                                         _,
    1192             :                                         _);
    1193          81 :                 if (errFlag) {
    1194           0 :                     ShowContinueError(state, "Reference Unit=\"" + FanCoil(FanCoilNum).Name + "\", type=" + FanCoil(FanCoilNum).UnitType);
    1195           0 :                     ShowFatalError(state, "InitFanCoilUnits: Program terminated for previous conditions.");
    1196             :                 }
    1197          81 :                 FanCoil(FanCoilNum).CoolCoilFluidOutletNodeNum =
    1198          81 :                     DataPlant::CompData::getPlantComponent(state, FanCoil(FanCoilNum).CoolCoilPlantLoc).NodeNumOut;
    1199             :             } else {
    1200           0 :                 ShowFatalError(state, "InitFanCoilUnits: FanCoil=" + FanCoil(FanCoilNum).Name + ", invalid cooling coil type. Program terminated.");
    1201             :             }
    1202             : 
    1203          81 :             state.dataFanCoilUnits->MyPlantScanFlag(FanCoilNum) = false;
    1204             :         }
    1205             : 
    1206      514191 :         if (!state.dataFanCoilUnits->InitFanCoilUnitsCheckInZoneEquipmentListFlag && state.dataZoneEquip->ZoneEquipInputsFilled) {
    1207          19 :             state.dataFanCoilUnits->InitFanCoilUnitsCheckInZoneEquipmentListFlag = true;
    1208         100 :             for (Loop = 1; Loop <= state.dataFanCoilUnits->NumFanCoils; ++Loop) {
    1209          81 :                 if (CheckZoneEquipmentList(state, FanCoil(Loop).UnitType, FanCoil(Loop).Name)) continue;
    1210           0 :                 ShowSevereError(state,
    1211           0 :                                 "InitFanCoil: FanCoil Unit=[" + FanCoil(Loop).UnitType + ',' + FanCoil(Loop).Name +
    1212             :                                     "] is not on any ZoneHVAC:EquipmentList.  It will not be simulated.");
    1213             :             }
    1214             :         }
    1215             : 
    1216      514272 :         if (!state.dataGlobal->SysSizingCalc && state.dataFanCoilUnits->MySizeFlag(FanCoilNum) &&
    1217          81 :             !state.dataFanCoilUnits->MyPlantScanFlag(FanCoilNum)) {
    1218             : 
    1219          81 :             SizeFanCoilUnit(state, FanCoilNum, ControlledZoneNum);
    1220             : 
    1221          81 :             state.dataFanCoilUnits->MySizeFlag(FanCoilNum) = false;
    1222             :         }
    1223             : 
    1224             :         // Do the Begin Environment initializations
    1225      514671 :         if (state.dataGlobal->BeginEnvrnFlag && state.dataFanCoilUnits->MyEnvrnFlag(FanCoilNum) &&
    1226         480 :             !state.dataFanCoilUnits->MyPlantScanFlag(FanCoilNum)) {
    1227         480 :             InNode = FanCoil(FanCoilNum).AirInNode;
    1228         480 :             OutNode = FanCoil(FanCoilNum).AirOutNode;
    1229         480 :             OutsideAirNode = FanCoil(FanCoilNum).OutsideAirNode;
    1230         480 :             RhoAir = state.dataEnvrn->StdRhoAir;
    1231         480 :             HotConNode = FanCoil(FanCoilNum).HeatCoilFluidInletNode;
    1232         480 :             ColdConNode = FanCoil(FanCoilNum).CoolCoilFluidInletNode;
    1233             :             // set the mass flow rates from the input volume flow rates
    1234         480 :             FanCoil(FanCoilNum).MaxAirMassFlow = RhoAir * FanCoil(FanCoilNum).MaxAirVolFlow;
    1235         480 :             FanCoil(FanCoilNum).OutAirMassFlow = RhoAir * FanCoil(FanCoilNum).OutAirVolFlow;
    1236             : 
    1237         480 :             if (FanCoil(FanCoilNum).HCoilType_Num == HCoil::Water) {
    1238         948 :                 rho = GetDensityGlycol(state,
    1239         474 :                                        state.dataPlnt->PlantLoop(FanCoil(FanCoilNum).HeatCoilPlantLoc.loopNum).FluidName,
    1240             :                                        DataGlobalConstants::HWInitConvTemp,
    1241         474 :                                        state.dataPlnt->PlantLoop(FanCoil(FanCoilNum).HeatCoilPlantLoc.loopNum).FluidIndex,
    1242             :                                        RoutineName);
    1243         474 :                 FanCoil(FanCoilNum).MaxHeatCoilFluidFlow = rho * FanCoil(FanCoilNum).MaxHotWaterVolFlow;
    1244         474 :                 FanCoil(FanCoilNum).MinHotWaterFlow = rho * FanCoil(FanCoilNum).MinHotWaterVolFlow;
    1245             :             }
    1246             : 
    1247         960 :             rho = GetDensityGlycol(state,
    1248         480 :                                    state.dataPlnt->PlantLoop(FanCoil(FanCoilNum).CoolCoilPlantLoc.loopNum).FluidName,
    1249             :                                    DataGlobalConstants::CWInitConvTemp,
    1250         480 :                                    state.dataPlnt->PlantLoop(FanCoil(FanCoilNum).CoolCoilPlantLoc.loopNum).FluidIndex,
    1251             :                                    RoutineName);
    1252         480 :             FanCoil(FanCoilNum).MaxCoolCoilFluidFlow = rho * FanCoil(FanCoilNum).MaxColdWaterVolFlow;
    1253         480 :             FanCoil(FanCoilNum).MinColdWaterFlow = rho * FanCoil(FanCoilNum).MinColdWaterVolFlow;
    1254             : 
    1255             :             // set the node max and min mass flow rates
    1256         480 :             if (FanCoil(FanCoilNum).HCoilType_Num == HCoil::Water) {
    1257        1896 :                 InitComponentNodes(state,
    1258         474 :                                    FanCoil(FanCoilNum).MinHotWaterFlow,
    1259         474 :                                    FanCoil(FanCoilNum).MaxHeatCoilFluidFlow,
    1260         474 :                                    FanCoil(FanCoilNum).HeatCoilFluidInletNode,
    1261         474 :                                    FanCoil(FanCoilNum).HeatCoilFluidOutletNodeNum);
    1262             :             }
    1263             : 
    1264        1920 :             InitComponentNodes(state,
    1265         480 :                                FanCoil(FanCoilNum).MinColdWaterFlow,
    1266         480 :                                FanCoil(FanCoilNum).MaxCoolCoilFluidFlow,
    1267         480 :                                FanCoil(FanCoilNum).CoolCoilFluidInletNode,
    1268         480 :                                FanCoil(FanCoilNum).CoolCoilFluidOutletNodeNum);
    1269             :             //  Node(HotConNode)%MassFlowRateMax = FanCoil(FanCoilNum)%MaxHeatCoilFluidFlow
    1270             :             //  Node(HotConNode)%MassFlowRateMin = FanCoil(FanCoilNum)%MinHotWaterFlow
    1271             :             //  Node(ColdConNode)%MassFlowRateMax = FanCoil(FanCoilNum)%MaxCoolCoilFluidFlow
    1272             :             //  Node(ColdConNode)%MassFlowRateMin = FanCoil(FanCoilNum)%MinColdWaterFlow
    1273             : 
    1274         480 :             if (FanCoil(FanCoilNum).OutsideAirNode > 0) {
    1275         420 :                 state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMax = FanCoil(FanCoilNum).OutAirMassFlow;
    1276         420 :                 state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMin = 0.0;
    1277             :             }
    1278         480 :             state.dataLoopNodes->Node(OutNode).MassFlowRateMax = FanCoil(FanCoilNum).MaxAirMassFlow;
    1279         480 :             state.dataLoopNodes->Node(OutNode).MassFlowRateMin = 0.0;
    1280         480 :             state.dataLoopNodes->Node(InNode).MassFlowRateMax = FanCoil(FanCoilNum).MaxAirMassFlow;
    1281         480 :             state.dataLoopNodes->Node(InNode).MassFlowRateMin = 0.0;
    1282         480 :             state.dataFanCoilUnits->MyEnvrnFlag(FanCoilNum) = false;
    1283             :         } // end one time inits
    1284             : 
    1285      514191 :         if (!state.dataGlobal->BeginEnvrnFlag) {
    1286      510925 :             state.dataFanCoilUnits->MyEnvrnFlag(FanCoilNum) = true;
    1287             :         }
    1288             : 
    1289             :         // These initializations are done every iteration
    1290      514191 :         InletNode = FanCoil(FanCoilNum).AirInNode;
    1291      514191 :         OutsideAirNode = FanCoil(FanCoilNum).OutsideAirNode;
    1292      514191 :         AirRelNode = FanCoil(FanCoilNum).AirReliefNode;
    1293      514191 :         FanCoil(FanCoilNum).SpeedRatio = 0.0;
    1294      514191 :         if (FanCoil(FanCoilNum).FanOpModeSchedPtr > 0) {
    1295        8250 :             if (GetCurrentScheduleValue(state, FanCoil(FanCoilNum).FanOpModeSchedPtr) == 0.0) {
    1296          14 :                 FanCoil(FanCoilNum).FanOpMode = CycFanCycCoil;
    1297             :             } else {
    1298        8236 :                 FanCoil(FanCoilNum).FanOpMode = ContFanCycCoil;
    1299             :             }
    1300             :         }
    1301             :         // Set the inlet node mass flow rate
    1302     1542069 :         if (((GetCurrentScheduleValue(state, FanCoil(FanCoilNum).SchedPtr) > 0.0 &&
    1303      514191 :               GetCurrentScheduleValue(state, FanCoil(FanCoilNum).fanAvailSchIndex) > 0.0) ||
    1304     1028382 :              state.dataHVACGlobal->ZoneCompTurnFansOn) &&
    1305      513687 :             !state.dataHVACGlobal->ZoneCompTurnFansOff) {
    1306      511019 :             state.dataLoopNodes->Node(InletNode).MassFlowRate = FanCoil(FanCoilNum).MaxAirMassFlow;
    1307      511019 :             state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = state.dataLoopNodes->Node(InletNode).MassFlowRate;
    1308      511019 :             state.dataLoopNodes->Node(InletNode).MassFlowRateMinAvail = 0.0;
    1309             : 
    1310      511019 :             if (OutsideAirNode > 0) {
    1311      474379 :                 state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate = FanCoil(FanCoilNum).OutAirMassFlow;
    1312      474379 :                 state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMaxAvail = FanCoil(FanCoilNum).OutAirMassFlow;
    1313      474379 :                 state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMinAvail = FanCoil(FanCoilNum).OutAirMassFlow;
    1314      474379 :                 state.dataLoopNodes->Node(AirRelNode).MassFlowRate = FanCoil(FanCoilNum).OutAirMassFlow;
    1315      474379 :                 state.dataLoopNodes->Node(AirRelNode).MassFlowRateMaxAvail = FanCoil(FanCoilNum).OutAirMassFlow;
    1316      474379 :                 state.dataLoopNodes->Node(AirRelNode).MassFlowRateMinAvail = FanCoil(FanCoilNum).OutAirMassFlow;
    1317             :             }
    1318             : 
    1319             :         } else {
    1320        3172 :             state.dataLoopNodes->Node(InletNode).MassFlowRate = 0.0;
    1321        3172 :             state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = 0.0;
    1322        3172 :             state.dataLoopNodes->Node(InletNode).MassFlowRateMinAvail = 0.0;
    1323        3172 :             if (OutsideAirNode > 0) {
    1324        3032 :                 state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate = 0.0;
    1325        3032 :                 state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMaxAvail = 0.0;
    1326        3032 :                 state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMinAvail = 0.0;
    1327        3032 :                 state.dataLoopNodes->Node(AirRelNode).MassFlowRate = 0.0;
    1328        3032 :                 state.dataLoopNodes->Node(AirRelNode).MassFlowRateMaxAvail = 0.0;
    1329        3032 :                 state.dataLoopNodes->Node(AirRelNode).MassFlowRateMinAvail = 0.0;
    1330             :             }
    1331             :         }
    1332      514191 :     }
    1333             : 
    1334          81 :     void SizeFanCoilUnit(EnergyPlusData &state,
    1335             :                          int const FanCoilNum,
    1336             :                          int const ControlledZoneNum // index into ZoneEquipConfig array
    1337             :     )
    1338             :     {
    1339             : 
    1340             :         // SUBROUTINE INFORMATION:
    1341             :         //       AUTHOR         Fred Buhl
    1342             :         //       DATE WRITTEN   January 2002
    1343             :         //       MODIFIED       August 2013 Daeho Kang, add component sizing table entries
    1344             :         //                      July 2014, B. Nigusse, added scalable sizing
    1345             :         //       RE-ENGINEERED  na
    1346             : 
    1347             :         // PURPOSE OF THIS SUBROUTINE:
    1348             :         // This subroutine is for sizing Fan Coil Unit components for which flow rates have not been
    1349             :         // specified in the input.
    1350             : 
    1351             :         // METHODOLOGY EMPLOYED:
    1352             :         // Obtains flow rates from the zone or system sizing arrays and plant sizing data.
    1353             : 
    1354             :         // Using/Aliasing
    1355             :         using namespace DataSizing;
    1356             :         using DataHVACGlobals::CoolingAirflowSizing;
    1357             :         using DataHVACGlobals::CoolingCapacitySizing;
    1358             :         using DataHVACGlobals::HeatingAirflowSizing;
    1359             :         using DataHVACGlobals::HeatingCapacitySizing;
    1360             :         using Fans::GetFanDesignVolumeFlowRate;
    1361             :         using FluidProperties::GetDensityGlycol;
    1362             :         using FluidProperties::GetSpecificHeatGlycol;
    1363             : 
    1364             :         using HVACHXAssistedCoolingCoil::GetHXCoilType;
    1365             :         using HVACHXAssistedCoolingCoil::GetHXDXCoilName;
    1366             :         using PlantUtilities::MyPlantSizingIndex;
    1367             :         using Psychrometrics::PsyCpAirFnW;
    1368             :         using Psychrometrics::PsyHFnTdbW;
    1369             :         using WaterCoils::GetCoilWaterInletNode;
    1370             :         using WaterCoils::GetCoilWaterOutletNode;
    1371             :         using WaterCoils::GetWaterCoilIndex;
    1372             :         using WaterCoils::SetCoilDesFlow;
    1373             : 
    1374             :         // SUBROUTINE PARAMETER DEFINITIONS:
    1375             :         static constexpr std::string_view RoutineName("SizeFanCoilUnit: "); // include trailing blank space
    1376             :         static constexpr std::string_view RoutineNameNoSpace("SizeFanCoilUnit");
    1377             : 
    1378             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1379             :         int PltSizHeatNum;  // index of plant sizing object for 1st heating loop
    1380             :         int PltSizCoolNum;  // index of plant sizing object for 1st cooling loop
    1381             :         bool ErrorsFound;   // TRUE if errors foind during sizing
    1382             :         Real64 DesCoilLoad; // coil load used for sizing [W]
    1383         162 :         std::string CoolingCoilName;
    1384         162 :         std::string CoolingCoilType;
    1385             :         Real64 rho;
    1386             :         Real64 Cp;
    1387             :         int zoneHVACIndex;              // index of zoneHVAC equipment sizing specification
    1388             :         bool IsAutoSize;                // Indicator to autosize for reporting
    1389             :         Real64 MaxAirVolFlowDes;        // Autosized max air flow for reporting
    1390             :         Real64 MaxAirVolFlowUser;       // Hardsized max air flow for reporting
    1391             :         Real64 OutAirVolFlowDes;        // Autosized outdoor air flow for reporting
    1392             :         Real64 OutAirVolFlowUser;       // Hardsized outdoor air flow for reporting
    1393             :         Real64 MaxHotWaterVolFlowDes;   // Autosized hot water flow for reporting
    1394             :         Real64 MaxHotWaterVolFlowUser;  // Hardsized hot water flow for reporting
    1395             :         Real64 MaxColdWaterVolFlowDes;  // Autosized cold water flow for reporting
    1396             :         Real64 MaxColdWaterVolFlowUser; // Hardsized cold water flow for reporting
    1397             :         Real64 CoolingAirVolFlowDes;    // cooling supply air flow rate
    1398             :         Real64 HeatingAirVolFlowDes;    // heating supply air flow rate
    1399         162 :         std::string CompName;           // component name
    1400         162 :         std::string CompType;           // component type
    1401         162 :         std::string SizingString;       // input field sizing description (e.g., Nominal Capacity)
    1402             :         Real64 TempSize;                // autosized value of coil input field
    1403          81 :         int FieldNum = 1;               // IDD numeric field number where input field description is found
    1404             :         int SizingMethod; // Integer representation of sizing method name (e.g., CoolingAirflowSizing, HeatingAirflowSizing, CoolingCapacitySizing,
    1405             :                           // HeatingCapacitySizing, etc.)
    1406             :         bool PrintFlag;   // TRUE when sizing information is reported in the eio file
    1407          81 :         int SAFMethod(0); // supply air flow rate sizing method (SupplyAirFlowRate, FlowPerFloorArea, FractionOfAutosizedCoolingAirflow,
    1408             :                           // FractionOfAutosizedHeatingAirflow ...)
    1409          81 :         int CapSizingMethod(0);    // capacity sizing methods (HeatingDesignCapacity, CapacityPerFloorArea, FractionOfAutosizedCoolingCapacity, and
    1410             :                                    // FractionOfAutosizedHeatingCapacity )
    1411             :         bool SizingDesRunThisZone; // test for zone sizing
    1412          81 :         bool DoWaterCoilSizing = false; // if TRUE do water coil sizing calculation
    1413             :         Real64 WaterCoilSizDeltaT;      // water coil deltaT for design water flow rate autosizing
    1414             :         int CoilNum;                    // index of water coil object
    1415             : 
    1416          81 :         PltSizCoolNum = 0;
    1417          81 :         PltSizHeatNum = 0;
    1418          81 :         ErrorsFound = false;
    1419          81 :         IsAutoSize = false;
    1420          81 :         MaxAirVolFlowDes = 0.0;
    1421          81 :         MaxAirVolFlowUser = 0.0;
    1422          81 :         OutAirVolFlowDes = 0.0;
    1423          81 :         OutAirVolFlowUser = 0.0;
    1424          81 :         MaxHotWaterVolFlowDes = 0.0;
    1425          81 :         MaxHotWaterVolFlowUser = 0.0;
    1426          81 :         MaxColdWaterVolFlowDes = 0.0;
    1427          81 :         MaxColdWaterVolFlowUser = 0.0;
    1428             : 
    1429          81 :         CoolingAirVolFlowDes = 0.0;
    1430          81 :         HeatingAirVolFlowDes = 0.0;
    1431          81 :         state.dataSize->ZoneHeatingOnlyFan = false;
    1432          81 :         state.dataSize->ZoneCoolingOnlyFan = false;
    1433          81 :         state.dataSize->DataScalableSizingON = false;
    1434          81 :         state.dataSize->DataScalableCapSizingON = false;
    1435             : 
    1436          81 :         state.dataSize->DataFracOfAutosizedCoolingAirflow = 1.0;
    1437          81 :         state.dataSize->DataFracOfAutosizedHeatingAirflow = 1.0;
    1438          81 :         state.dataSize->DataFracOfAutosizedCoolingCapacity = 1.0;
    1439          81 :         state.dataSize->DataFracOfAutosizedHeatingCapacity = 1.0;
    1440             : 
    1441          81 :         auto &FanCoil(state.dataFanCoilUnits->FanCoil);
    1442             : 
    1443          81 :         CompType = FanCoil(FanCoilNum).UnitType;
    1444          81 :         CompName = FanCoil(FanCoilNum).Name;
    1445          81 :         state.dataSize->DataZoneNumber = FanCoil(FanCoilNum).ControlZoneNum;
    1446          81 :         if (FanCoil(FanCoilNum).FanType_Num == DataHVACGlobals::FanType_SystemModelObject) {
    1447          18 :             state.dataSize->DataFanEnumType = DataAirSystems::ObjectVectorOOFanSystemModel;
    1448             :         } else {
    1449          63 :             state.dataSize->DataFanEnumType = DataAirSystems::StructArrayLegacyFanModels;
    1450             :         }
    1451          81 :         state.dataSize->DataFanIndex = FanCoil(FanCoilNum).FanIndex;
    1452             :         // fan coil unit is always blow thru
    1453          81 :         state.dataSize->DataFanPlacement = DataSizing::ZoneFanPlacement::BlowThru;
    1454             : 
    1455          81 :         auto &ZoneEqSizing(state.dataSize->ZoneEqSizing);
    1456             : 
    1457          81 :         if (state.dataSize->CurZoneEqNum > 0) {
    1458             : 
    1459          81 :             if (FanCoil(FanCoilNum).HVACSizingIndex > 0) {
    1460             : 
    1461             :                 // initialize OA flow for sizing other inputs (e.g., inlet temp, capacity, etc.)
    1462           3 :                 if (FanCoil(FanCoilNum).OutAirVolFlow == AutoSize) {
    1463           3 :                     ZoneEqSizing(state.dataSize->CurZoneEqNum).OAVolFlow = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA;
    1464             :                 } else {
    1465           0 :                     ZoneEqSizing(state.dataSize->CurZoneEqNum).OAVolFlow = FanCoil(FanCoilNum).OutAirVolFlow;
    1466             :                 }
    1467           3 :                 if (FanCoil(FanCoilNum).ATMixerExists) {                        // set up ATMixer conditions for scalable capacity sizing
    1468           0 :                     ZoneEqSizing(state.dataSize->CurZoneEqNum).OAVolFlow = 0.0; // Equipment OA flow should always be 0 when ATMixer is used
    1469           0 :                     SingleDuct::setATMixerSizingProperties(state, FanCoil(FanCoilNum).ATMixerIndex, ControlledZoneNum, state.dataSize->CurZoneEqNum);
    1470             :                 }
    1471             : 
    1472           3 :                 zoneHVACIndex = FanCoil(FanCoilNum).HVACSizingIndex;
    1473           3 :                 FieldNum = 1;
    1474           3 :                 PrintFlag = true;
    1475           3 :                 SizingString = state.dataFanCoilUnits->FanCoilNumericFields(FanCoilNum).FieldNames(FieldNum) + " [m3/s]";
    1476           3 :                 if (state.dataGlobal->isEpJSON) SizingString = "maximum_supply_air_flow_rate [m3/s]";
    1477           3 :                 if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).CoolingSAFMethod > 0) {
    1478           3 :                     SizingMethod = CoolingAirflowSizing;
    1479           3 :                     SAFMethod = state.dataSize->ZoneHVACSizing(zoneHVACIndex).CoolingSAFMethod;
    1480           3 :                     ZoneEqSizing(state.dataSize->CurZoneEqNum).SizingMethod(SizingMethod) = SAFMethod;
    1481           3 :                     if (SAFMethod == SupplyAirFlowRate || SAFMethod == FlowPerFloorArea || SAFMethod == FractionOfAutosizedCoolingAirflow) {
    1482           3 :                         if (SAFMethod == SupplyAirFlowRate) {
    1483           1 :                             if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow > 0.0) {
    1484           0 :                                 ZoneEqSizing(state.dataSize->CurZoneEqNum).AirVolFlow =
    1485           0 :                                     state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
    1486           0 :                                 ZoneEqSizing(state.dataSize->CurZoneEqNum).SystemAirFlow = true;
    1487             :                             }
    1488           1 :                             TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
    1489           2 :                         } else if (SAFMethod == FlowPerFloorArea) {
    1490           1 :                             ZoneEqSizing(state.dataSize->CurZoneEqNum).SystemAirFlow = true;
    1491           2 :                             ZoneEqSizing(state.dataSize->CurZoneEqNum).AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow *
    1492           1 :                                                                                     state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
    1493           1 :                             TempSize = ZoneEqSizing(state.dataSize->CurZoneEqNum).AirVolFlow;
    1494           1 :                             state.dataSize->DataScalableSizingON = true;
    1495           1 :                         } else if (SAFMethod == FractionOfAutosizedCoolingAirflow) {
    1496           1 :                             state.dataSize->DataFracOfAutosizedCoolingAirflow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
    1497           1 :                             TempSize = AutoSize;
    1498           1 :                             state.dataSize->DataScalableSizingON = true;
    1499             :                         } else {
    1500           0 :                             TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
    1501             :                         }
    1502           6 :                         CoolingAirFlowSizer sizingCoolingAirFlow;
    1503           3 :                         sizingCoolingAirFlow.overrideSizingString(SizingString);
    1504             :                         // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
    1505           3 :                         sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    1506           6 :                         CoolingAirVolFlowDes = sizingCoolingAirFlow.size(state, TempSize, ErrorsFound);
    1507             : 
    1508           0 :                     } else if (SAFMethod == FlowPerCoolingCapacity) {
    1509           0 :                         SizingMethod = CoolingCapacitySizing;
    1510           0 :                         TempSize = AutoSize;
    1511           0 :                         PrintFlag = false;
    1512           0 :                         CoolingCapacitySizer sizerCoolingCapacity;
    1513           0 :                         sizerCoolingCapacity.overrideSizingString(SizingString);
    1514           0 :                         sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    1515           0 :                         state.dataSize->DataAutosizedCoolingCapacity = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
    1516           0 :                         if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).CoolingCapMethod == FractionOfAutosizedCoolingCapacity) {
    1517           0 :                             state.dataSize->DataFracOfAutosizedCoolingCapacity = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity;
    1518             :                         }
    1519           0 :                         state.dataSize->DataFlowPerCoolingCapacity = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
    1520           0 :                         PrintFlag = true;
    1521           0 :                         TempSize = AutoSize;
    1522           0 :                         state.dataSize->DataScalableSizingON = true;
    1523           0 :                         CoolingAirFlowSizer sizingCoolingAirFlow;
    1524           0 :                         sizingCoolingAirFlow.overrideSizingString(SizingString);
    1525             :                         // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
    1526           0 :                         sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    1527           0 :                         CoolingAirVolFlowDes = sizingCoolingAirFlow.size(state, TempSize, ErrorsFound);
    1528             :                     }
    1529           0 :                 } else if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).HeatingSAFMethod > 0) {
    1530             :                     // now do heating supply air flow rate sizing
    1531           0 :                     SizingMethod = HeatingAirflowSizing;
    1532           0 :                     SAFMethod = state.dataSize->ZoneHVACSizing(zoneHVACIndex).HeatingSAFMethod;
    1533           0 :                     ZoneEqSizing(state.dataSize->CurZoneEqNum).SizingMethod(SizingMethod) = SAFMethod;
    1534           0 :                     if (SAFMethod == SupplyAirFlowRate || SAFMethod == FlowPerFloorArea || SAFMethod == FractionOfAutosizedHeatingAirflow) {
    1535           0 :                         if (SAFMethod == SupplyAirFlowRate) {
    1536           0 :                             if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow > 0.0) {
    1537           0 :                                 ZoneEqSizing(state.dataSize->CurZoneEqNum).AirVolFlow =
    1538           0 :                                     state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow;
    1539           0 :                                 ZoneEqSizing(state.dataSize->CurZoneEqNum).SystemAirFlow = true;
    1540             :                             }
    1541           0 :                             TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow;
    1542           0 :                         } else if (SAFMethod == FlowPerFloorArea) {
    1543           0 :                             ZoneEqSizing(state.dataSize->CurZoneEqNum).SystemAirFlow = true;
    1544           0 :                             ZoneEqSizing(state.dataSize->CurZoneEqNum).AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow *
    1545           0 :                                                                                     state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
    1546           0 :                             TempSize = ZoneEqSizing(state.dataSize->CurZoneEqNum).AirVolFlow;
    1547           0 :                             state.dataSize->DataScalableSizingON = true;
    1548           0 :                         } else if (SAFMethod == FractionOfAutosizedHeatingAirflow) {
    1549           0 :                             state.dataSize->DataFracOfAutosizedHeatingAirflow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow;
    1550           0 :                             TempSize = AutoSize;
    1551           0 :                             state.dataSize->DataScalableSizingON = true;
    1552             :                         } else {
    1553           0 :                             TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow;
    1554             :                         }
    1555           0 :                         bool errorsFound = false;
    1556           0 :                         HeatingAirFlowSizer sizingHeatingAirFlow;
    1557           0 :                         sizingHeatingAirFlow.overrideSizingString(SizingString);
    1558             :                         // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
    1559           0 :                         sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    1560           0 :                         HeatingAirVolFlowDes = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
    1561           0 :                     } else if (SAFMethod == FlowPerHeatingCapacity) {
    1562           0 :                         SizingMethod = HeatingCapacitySizing;
    1563           0 :                         TempSize = AutoSize;
    1564           0 :                         PrintFlag = false;
    1565           0 :                         state.dataSize->DataScalableSizingON = true;
    1566             :                         // initialize OA flow for sizing capacity
    1567           0 :                         if (FanCoil(FanCoilNum).OutAirVolFlow == AutoSize) {
    1568           0 :                             ZoneEqSizing(state.dataSize->CurZoneEqNum).OAVolFlow =
    1569           0 :                                 state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA;
    1570             :                         } else {
    1571           0 :                             ZoneEqSizing(state.dataSize->CurZoneEqNum).OAVolFlow = FanCoil(FanCoilNum).OutAirVolFlow;
    1572             :                         }
    1573           0 :                         bool errorsFound = false;
    1574           0 :                         HeatingCapacitySizer sizerHeatingCapacity;
    1575           0 :                         sizerHeatingCapacity.overrideSizingString(SizingString);
    1576           0 :                         sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    1577           0 :                         TempSize = sizerHeatingCapacity.size(state, TempSize, errorsFound);
    1578           0 :                         if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).HeatingCapMethod == FractionOfAutosizedHeatingCapacity) {
    1579           0 :                             state.dataSize->DataFracOfAutosizedHeatingCapacity = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity;
    1580             :                         }
    1581           0 :                         state.dataSize->DataAutosizedHeatingCapacity = TempSize;
    1582           0 :                         state.dataSize->DataFlowPerHeatingCapacity = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow;
    1583           0 :                         SizingMethod = HeatingAirflowSizing;
    1584           0 :                         PrintFlag = true;
    1585           0 :                         TempSize = AutoSize;
    1586           0 :                         errorsFound = false;
    1587           0 :                         HeatingAirFlowSizer sizingHeatingAirFlow;
    1588           0 :                         sizingHeatingAirFlow.overrideSizingString(SizingString);
    1589             :                         // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
    1590           0 :                         sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    1591           0 :                         HeatingAirVolFlowDes = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
    1592             :                     }
    1593             :                 }
    1594             : 
    1595           5 :                 if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow == AutoSize ||
    1596           2 :                     state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow == AutoSize) {
    1597           1 :                     IsAutoSize = true;
    1598           1 :                     FanCoil(FanCoilNum).MaxAirVolFlow = AutoSize;
    1599           1 :                     MaxAirVolFlowDes = max(CoolingAirVolFlowDes, HeatingAirVolFlowDes);
    1600             :                 } else {
    1601           2 :                     FanCoil(FanCoilNum).MaxAirVolFlow = max(CoolingAirVolFlowDes, HeatingAirVolFlowDes);
    1602           2 :                     MaxAirVolFlowDes = 0.0;
    1603             :                 }
    1604             :             } else {
    1605             :                 // SizingString = "Supply Air Maximum Flow Rate [m3/s]";
    1606          78 :                 TempSize = FanCoil(FanCoilNum).MaxAirVolFlow;
    1607          78 :                 PrintFlag = true;
    1608          78 :                 if (FanCoil(FanCoilNum).MaxAirVolFlow == AutoSize) {
    1609          78 :                     IsAutoSize = true;
    1610         156 :                     SystemAirFlowSizer sizerSystemAirFlow;
    1611             :                     // sizerSystemAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
    1612          78 :                     sizerSystemAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    1613          78 :                     MaxAirVolFlowDes = sizerSystemAirFlow.size(state, TempSize, ErrorsFound);
    1614             :                 } else {
    1615           0 :                     MaxAirVolFlowDes = 0.0;
    1616             :                 }
    1617             :             }
    1618             :         }
    1619             : 
    1620          81 :         if (state.dataSize->CurZoneEqNum > 0) {
    1621             : 
    1622          81 :             if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) {
    1623             : 
    1624             :             } else {
    1625          81 :                 if (MaxAirVolFlowDes < SmallAirVolFlow) {
    1626           2 :                     MaxAirVolFlowDes = 0.0;
    1627             :                 }
    1628             : 
    1629             :                 //     If fan is autosized, get fan volumetric flow rate
    1630          81 :                 if (FanCoil(FanCoilNum).FanAirVolFlow == AutoSize) {
    1631          81 :                     if (FanCoil(FanCoilNum).FanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
    1632          63 :                         Fans::SimulateFanComponents(state, FanCoil(FanCoilNum).FanName, true, FanCoil(FanCoilNum).FanIndex);
    1633          63 :                         FanCoil(FanCoilNum).FanAirVolFlow =
    1634         126 :                             GetFanDesignVolumeFlowRate(state, cFanTypes(FanCoil(FanCoilNum).FanType_Num), FanCoil(FanCoilNum).FanName, ErrorsFound);
    1635             :                     } else {
    1636          18 :                         state.dataHVACFan->fanObjs[FanCoil(FanCoilNum).FanIndex]->simulate(state, _, _, _, _);
    1637          18 :                         FanCoil(FanCoilNum).FanAirVolFlow = state.dataHVACFan->fanObjs[FanCoil(FanCoilNum).FanIndex]->designAirVolFlowRate;
    1638             :                     }
    1639             :                 }
    1640             :                 //     Check that the fan volumetric flow rate is greater than or equal to the FCU volumetric flow rate
    1641          81 :                 if (MaxAirVolFlowDes > FanCoil(FanCoilNum).FanAirVolFlow) {
    1642           0 :                     ShowWarningError(state, std::string{RoutineName} + FanCoil(FanCoilNum).UnitType + ": " + FanCoil(FanCoilNum).Name);
    1643           0 :                     ShowContinueError(state, "... Maximum supply air flow rate is greater than the maximum fan flow rate.");
    1644           0 :                     ShowContinueError(state, format("... Fan Coil Unit flow = {:.5T} [m3/s].", MaxAirVolFlowDes));
    1645           0 :                     ShowContinueError(state, "... Fan = " + cFanTypes(FanCoil(FanCoilNum).FanType_Num) + ": " + FanCoil(FanCoilNum).FanName);
    1646           0 :                     ShowContinueError(state, format("... Fan flow = {:.5T} [m3/s].", FanCoil(FanCoilNum).FanAirVolFlow));
    1647           0 :                     ShowContinueError(state, "... Fan Coil Unit flow rate reduced to match the fan flow rate and the simulation continues.");
    1648           0 :                     MaxAirVolFlowDes = FanCoil(FanCoilNum).FanAirVolFlow;
    1649             :                 }
    1650             : 
    1651          81 :                 if (IsAutoSize) {
    1652          79 :                     FanCoil(FanCoilNum).MaxAirVolFlow = MaxAirVolFlowDes;
    1653             :                 } else { // Hard size with sizing data
    1654           2 :                     if (FanCoil(FanCoilNum).MaxAirVolFlow > 0.0 && MaxAirVolFlowDes > 0.0) {
    1655           0 :                         MaxAirVolFlowUser = FanCoil(FanCoilNum).MaxAirVolFlow;
    1656           0 :                         if (state.dataGlobal->DisplayExtraWarnings) {
    1657           0 :                             if ((std::abs(MaxAirVolFlowDes - MaxAirVolFlowUser) / MaxAirVolFlowUser) > state.dataSize->AutoVsHardSizingThreshold) {
    1658           0 :                                 ShowMessage(state,
    1659           0 :                                             "SizeFanCoilUnit: Potential issue with equipment sizing for " + FanCoil(FanCoilNum).UnitType + ' ' +
    1660           0 :                                                 FanCoil(FanCoilNum).Name);
    1661           0 :                                 ShowContinueError(state, format("User-Specified Supply Air Maximum Flow Rate of {:.5R} [m3/s]", MaxAirVolFlowUser));
    1662           0 :                                 ShowContinueError(state,
    1663           0 :                                                   format("differs from Design Size Supply Air Maximum Flow Rate of {:.5R} [m3/s]", MaxAirVolFlowDes));
    1664           0 :                                 ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    1665           0 :                                 ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    1666             :                             }
    1667             :                         }
    1668             :                     }
    1669             :                 }
    1670             :             }
    1671           0 :         } else if (FanCoil(FanCoilNum).FanAirVolFlow == AutoSize) {
    1672           0 :             if (FanCoil(FanCoilNum).FanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
    1673           0 :                 Fans::SimulateFanComponents(state, FanCoil(FanCoilNum).FanName, true, FanCoil(FanCoilNum).FanIndex);
    1674           0 :                 FanCoil(FanCoilNum).FanAirVolFlow =
    1675           0 :                     GetFanDesignVolumeFlowRate(state, cFanTypes(FanCoil(FanCoilNum).FanType_Num), FanCoil(FanCoilNum).FanName, ErrorsFound);
    1676             :             } else {
    1677           0 :                 state.dataHVACFan->fanObjs[FanCoil(FanCoilNum).FanIndex]->simulate(state, _, _, _, _);
    1678           0 :                 FanCoil(FanCoilNum).FanAirVolFlow = state.dataHVACFan->fanObjs[FanCoil(FanCoilNum).FanIndex]->designAirVolFlowRate;
    1679             :             }
    1680             :             //   Check that the fan volumetric flow rate is greater than or equal to the FCU volumetric flow rate
    1681           0 :             if (FanCoil(FanCoilNum).MaxAirVolFlow > FanCoil(FanCoilNum).FanAirVolFlow) {
    1682           0 :                 ShowWarningError(state, std::string{RoutineName} + FanCoil(FanCoilNum).UnitType + ": " + FanCoil(FanCoilNum).Name);
    1683           0 :                 ShowContinueError(state, "... Maximum supply air flow rate is greater than the maximum fan flow rate.");
    1684           0 :                 ShowContinueError(state, format("... Fan Coil Unit flow = {:.5T} m3/s.", FanCoil(FanCoilNum).MaxAirVolFlow));
    1685           0 :                 ShowContinueError(state, "... Fan = " + cFanTypes(FanCoil(FanCoilNum).FanType_Num) + ": " + FanCoil(FanCoilNum).FanName);
    1686           0 :                 ShowContinueError(state, format("... Fan flow = {:.5T} m3/s.", FanCoil(FanCoilNum).FanAirVolFlow));
    1687           0 :                 ShowContinueError(state, "... Fan Coil Unit flow rate reduced to match the fan flow rate and the simulation continues.");
    1688           0 :                 FanCoil(FanCoilNum).MaxAirVolFlow = FanCoil(FanCoilNum).FanAirVolFlow;
    1689             :             }
    1690             :         }
    1691             : 
    1692          81 :         IsAutoSize = false;
    1693          81 :         if (FanCoil(FanCoilNum).OutAirVolFlow == AutoSize) {
    1694          23 :             IsAutoSize = true;
    1695             :         }
    1696             : 
    1697          81 :         if (state.dataSize->CurZoneEqNum > 0) {
    1698          81 :             if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) {
    1699           0 :                 if (FanCoil(FanCoilNum).OutAirVolFlow > 0.0) {
    1700           0 :                     BaseSizer::reportSizerOutput(state,
    1701           0 :                                                  FanCoil(FanCoilNum).UnitType,
    1702           0 :                                                  FanCoil(FanCoilNum).Name,
    1703             :                                                  "User-Specified Maximum Outdoor Air Flow Rate [m3/s]",
    1704           0 :                                                  FanCoil(FanCoilNum).OutAirVolFlow);
    1705             :                 }
    1706             :             } else {
    1707          81 :                 CheckZoneSizing(state, FanCoil(FanCoilNum).UnitType, FanCoil(FanCoilNum).Name);
    1708          81 :                 OutAirVolFlowDes = min(state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA, FanCoil(FanCoilNum).MaxAirVolFlow);
    1709          81 :                 if (OutAirVolFlowDes < SmallAirVolFlow) {
    1710           2 :                     OutAirVolFlowDes = 0.0;
    1711             :                 }
    1712          81 :                 if (IsAutoSize) {
    1713          23 :                     FanCoil(FanCoilNum).OutAirVolFlow = OutAirVolFlowDes;
    1714          69 :                     BaseSizer::reportSizerOutput(state,
    1715          23 :                                                  FanCoil(FanCoilNum).UnitType,
    1716          23 :                                                  FanCoil(FanCoilNum).Name,
    1717             :                                                  "Design Size Maximum Outdoor Air Flow Rate [m3/s]",
    1718          23 :                                                  OutAirVolFlowDes);
    1719             :                 } else {
    1720          58 :                     if (FanCoil(FanCoilNum).OutAirVolFlow > 0.0 && OutAirVolFlowDes > 0.0) {
    1721           0 :                         OutAirVolFlowUser = FanCoil(FanCoilNum).OutAirVolFlow;
    1722           0 :                         BaseSizer::reportSizerOutput(state,
    1723           0 :                                                      FanCoil(FanCoilNum).UnitType,
    1724           0 :                                                      FanCoil(FanCoilNum).Name,
    1725             :                                                      "Design Size Maximum Outdoor Air Flow Rate [m3/s]",
    1726             :                                                      OutAirVolFlowDes,
    1727             :                                                      "User-Specified Maximum Outdoor Air Flow Rate [m3/s]",
    1728           0 :                                                      OutAirVolFlowUser);
    1729           0 :                         if (state.dataGlobal->DisplayExtraWarnings) {
    1730           0 :                             if ((std::abs(OutAirVolFlowDes - OutAirVolFlowUser) / OutAirVolFlowUser) > state.dataSize->AutoVsHardSizingThreshold) {
    1731           0 :                                 ShowMessage(state,
    1732           0 :                                             "SizeFanCoilUnit: Potential issue with equipment sizing for " + FanCoil(FanCoilNum).UnitType + ' ' +
    1733           0 :                                                 FanCoil(FanCoilNum).Name);
    1734           0 :                                 ShowContinueError(state, format("User-Specified Maximum Outdoor Air Flow Rate of {:.5R} [m3/s]", OutAirVolFlowUser));
    1735           0 :                                 ShowContinueError(
    1736           0 :                                     state, format("differs from Design Size Maximum Outdoor Air Flow Rate of {:.5R} [m3/s]", OutAirVolFlowDes));
    1737           0 :                                 ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    1738           0 :                                 ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    1739             :                             }
    1740             :                         }
    1741             :                     }
    1742             :                 }
    1743             :             }
    1744          81 :             ZoneEqSizing(state.dataSize->CurZoneEqNum).OAVolFlow = FanCoil(FanCoilNum).OutAirVolFlow; // sets OA frac in sizing
    1745             : 
    1746          81 :             if (FanCoil(FanCoilNum).ATMixerExists) {                        // set up ATMixer conditions for use in component sizing
    1747          10 :                 ZoneEqSizing(state.dataSize->CurZoneEqNum).OAVolFlow = 0.0; // Equipment OA flow should always be 0 when ATMixer is used
    1748          10 :                 SingleDuct::setATMixerSizingProperties(state, FanCoil(FanCoilNum).ATMixerIndex, ControlledZoneNum, state.dataSize->CurZoneEqNum);
    1749             :             }
    1750             :         }
    1751             : 
    1752          81 :         if (FanCoil(FanCoilNum).HCoilType_Num == HCoil::Water) {
    1753             : 
    1754          80 :             IsAutoSize = false;
    1755          80 :             if (FanCoil(FanCoilNum).MaxHotWaterVolFlow == AutoSize) {
    1756          80 :                 IsAutoSize = true;
    1757             :             }
    1758             : 
    1759          80 :             if (state.dataSize->CurZoneEqNum > 0) {
    1760          80 :                 if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) {
    1761           0 :                     if (FanCoil(FanCoilNum).MaxHotWaterVolFlow > 0.0) {
    1762           0 :                         BaseSizer::reportSizerOutput(state,
    1763           0 :                                                      FanCoil(FanCoilNum).UnitType,
    1764           0 :                                                      FanCoil(FanCoilNum).Name,
    1765             :                                                      "User-Specified Maximum Hot Water Flow [m3/s]",
    1766           0 :                                                      FanCoil(FanCoilNum).MaxHotWaterVolFlow);
    1767             :                     }
    1768             :                 } else {
    1769          80 :                     state.dataFanCoilUnits->CoilWaterInletNode =
    1770         160 :                         WaterCoils::GetCoilWaterInletNode(state, "Coil:Heating:Water", FanCoil(FanCoilNum).HCoilName, ErrorsFound);
    1771          80 :                     state.dataFanCoilUnits->CoilWaterOutletNode =
    1772         160 :                         WaterCoils::GetCoilWaterOutletNode(state, "Coil:Heating:Water", FanCoil(FanCoilNum).HCoilName, ErrorsFound);
    1773          80 :                     if (IsAutoSize) {
    1774         320 :                         PltSizHeatNum = MyPlantSizingIndex(state,
    1775             :                                                            "Coil:Heating:Water",
    1776          80 :                                                            FanCoil(FanCoilNum).HCoilName,
    1777          80 :                                                            state.dataFanCoilUnits->CoilWaterInletNode,
    1778          80 :                                                            state.dataFanCoilUnits->CoilWaterOutletNode,
    1779             :                                                            ErrorsFound);
    1780          80 :                         CoilNum = WaterCoils::GetWaterCoilIndex(state, "COIL:HEATING:WATER", FanCoil(FanCoilNum).HCoilName, ErrorsFound);
    1781          80 :                         if (state.dataWaterCoils->WaterCoil(CoilNum).UseDesignWaterDeltaTemp) {
    1782           0 :                             WaterCoilSizDeltaT = state.dataWaterCoils->WaterCoil(CoilNum).DesignWaterDeltaTemp;
    1783           0 :                             DoWaterCoilSizing = true;
    1784             :                         } else {
    1785          80 :                             if (PltSizHeatNum > 0) {
    1786          80 :                                 WaterCoilSizDeltaT = state.dataSize->PlantSizData(PltSizHeatNum).DeltaT;
    1787          80 :                                 DoWaterCoilSizing = true;
    1788             :                             } else {
    1789           0 :                                 DoWaterCoilSizing = false;
    1790             :                                 // If there is no heating Plant Sizing object and autosizing was requested, issue fatal error message
    1791           0 :                                 ShowSevereError(state, "Autosizing of water coil requires a heating loop Sizing:Plant object");
    1792           0 :                                 ShowContinueError(state, "Occurs in " + FanCoil(FanCoilNum).UnitType + " Object=" + FanCoil(FanCoilNum).Name);
    1793           0 :                                 ErrorsFound = true;
    1794             :                             }
    1795             :                         }
    1796          80 :                         if (DoWaterCoilSizing) {
    1797          80 :                             SizingMethod = HeatingCapacitySizing;
    1798          80 :                             if (state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatMassFlow > 0.0) {
    1799          80 :                                 state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatOAFlowFrac = min(
    1800          80 :                                     FanCoil(FanCoilNum).OutAirVolFlow / state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatMassFlow,
    1801             :                                     1.0);
    1802             :                             } else {
    1803           0 :                                 state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatOAFlowFrac = 0.0;
    1804             :                             }
    1805          80 :                             if (FanCoil(FanCoilNum).HVACSizingIndex > 0) {
    1806           3 :                                 zoneHVACIndex = FanCoil(FanCoilNum).HVACSizingIndex;
    1807           3 :                                 CapSizingMethod = state.dataSize->ZoneHVACSizing(zoneHVACIndex).HeatingCapMethod;
    1808           3 :                                 ZoneEqSizing(state.dataSize->CurZoneEqNum).SizingMethod(SizingMethod) = CapSizingMethod;
    1809           3 :                                 if (CapSizingMethod == HeatingDesignCapacity || CapSizingMethod == CapacityPerFloorArea ||
    1810             :                                     CapSizingMethod == FractionOfAutosizedHeatingCapacity) {
    1811           3 :                                     if (CapSizingMethod == HeatingDesignCapacity) {
    1812           0 :                                         if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity > 0.0) {
    1813           0 :                                             ZoneEqSizing(state.dataSize->CurZoneEqNum).HeatingCapacity = true;
    1814           0 :                                             ZoneEqSizing(state.dataSize->CurZoneEqNum).DesHeatingLoad =
    1815           0 :                                                 state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity;
    1816             :                                         }
    1817           0 :                                         TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity;
    1818           3 :                                     } else if (CapSizingMethod == CapacityPerFloorArea) {
    1819           2 :                                         if (state.dataSize->ZoneSizingRunDone) {
    1820           2 :                                             PrintFlag = false;
    1821           2 :                                             TempSize = AutoSize;
    1822           2 :                                             state.dataSize->DataFlowUsedForSizing =
    1823           2 :                                                 state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatVolFlow;
    1824           2 :                                             bool errorsFound = false;
    1825           4 :                                             HeatingCapacitySizer sizerHeatingCapacity;
    1826           2 :                                             sizerHeatingCapacity.overrideSizingString(SizingString);
    1827           2 :                                             sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    1828           2 :                                             ZoneEqSizing(state.dataSize->CurZoneEqNum).DesHeatingLoad =
    1829           2 :                                                 sizerHeatingCapacity.size(state, TempSize, errorsFound);
    1830           2 :                                             ZoneEqSizing(state.dataSize->CurZoneEqNum).HeatingCapacity = true;
    1831             :                                         }
    1832           4 :                                         TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity *
    1833           2 :                                                    state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
    1834           2 :                                         state.dataSize->DataScalableCapSizingON = true;
    1835           1 :                                     } else if (CapSizingMethod == FractionOfAutosizedHeatingCapacity) {
    1836           1 :                                         CheckZoneSizing(state, CompType, CompName);
    1837           1 :                                         PrintFlag = false;
    1838           1 :                                         TempSize = AutoSize;
    1839           1 :                                         state.dataSize->DataFlowUsedForSizing =
    1840           1 :                                             state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatVolFlow;
    1841           1 :                                         bool errorsFound = false;
    1842           2 :                                         HeatingCapacitySizer sizerHeatingCapacity;
    1843           1 :                                         sizerHeatingCapacity.overrideSizingString(SizingString);
    1844           1 :                                         sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    1845           1 :                                         ZoneEqSizing(state.dataSize->CurZoneEqNum).DesHeatingLoad =
    1846           1 :                                             sizerHeatingCapacity.size(state, TempSize, errorsFound);
    1847           1 :                                         ZoneEqSizing(state.dataSize->CurZoneEqNum).HeatingCapacity = true;
    1848           2 :                                         TempSize = ZoneEqSizing(state.dataSize->CurZoneEqNum).DesHeatingLoad *
    1849           1 :                                                    state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity;
    1850           1 :                                         state.dataSize->DataScalableCapSizingON = true;
    1851             :                                     }
    1852             :                                 }
    1853           3 :                                 SizingString = "Heating Design Capacity [W]";
    1854           3 :                                 PrintFlag = false;
    1855           3 :                                 bool errorsFound = false;
    1856           6 :                                 HeatingCapacitySizer sizerHeatingCapacity;
    1857           3 :                                 sizerHeatingCapacity.overrideSizingString(SizingString);
    1858           3 :                                 sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    1859           3 :                                 DesCoilLoad = sizerHeatingCapacity.size(state, TempSize, errorsFound);
    1860           3 :                                 state.dataSize->DataScalableCapSizingON = false;
    1861           3 :                                 state.dataSize->DataFlowUsedForSizing = 0.0;
    1862             : 
    1863             :                             } else {
    1864          77 :                                 SizingString = "Heating Design Capacity [W]";
    1865          77 :                                 PrintFlag = false;
    1866          77 :                                 TempSize = AutoSize;
    1867          77 :                                 bool errorsFound = false;
    1868         154 :                                 HeatingCapacitySizer sizerHeatingCapacity;
    1869          77 :                                 sizerHeatingCapacity.overrideSizingString(SizingString);
    1870          77 :                                 sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    1871          77 :                                 DesCoilLoad = sizerHeatingCapacity.size(state, TempSize, errorsFound);
    1872             :                             }
    1873          80 :                             FanCoil(FanCoilNum).DesHeatingLoad = DesCoilLoad;
    1874          80 :                             if (DesCoilLoad >= SmallLoad) {
    1875         160 :                                 rho = GetDensityGlycol(state,
    1876          80 :                                                        state.dataPlnt->PlantLoop(FanCoil(FanCoilNum).HeatCoilPlantLoc.loopNum).FluidName,
    1877             :                                                        DataGlobalConstants::HWInitConvTemp,
    1878          80 :                                                        state.dataPlnt->PlantLoop(FanCoil(FanCoilNum).HeatCoilPlantLoc.loopNum).FluidIndex,
    1879             :                                                        RoutineNameNoSpace);
    1880         160 :                                 Cp = GetSpecificHeatGlycol(state,
    1881          80 :                                                            state.dataPlnt->PlantLoop(FanCoil(FanCoilNum).HeatCoilPlantLoc.loopNum).FluidName,
    1882             :                                                            DataGlobalConstants::HWInitConvTemp,
    1883          80 :                                                            state.dataPlnt->PlantLoop(FanCoil(FanCoilNum).HeatCoilPlantLoc.loopNum).FluidIndex,
    1884             :                                                            RoutineNameNoSpace);
    1885             : 
    1886          80 :                                 MaxHotWaterVolFlowDes = DesCoilLoad / (WaterCoilSizDeltaT * Cp * rho);
    1887             :                             } else {
    1888           0 :                                 MaxHotWaterVolFlowDes = 0.0;
    1889             :                             }
    1890             :                         }
    1891             :                     }
    1892             :                 }
    1893             : 
    1894          80 :                 if (IsAutoSize) {
    1895          80 :                     FanCoil(FanCoilNum).MaxHotWaterVolFlow = MaxHotWaterVolFlowDes;
    1896         240 :                     BaseSizer::reportSizerOutput(state,
    1897          80 :                                                  FanCoil(FanCoilNum).UnitType,
    1898          80 :                                                  FanCoil(FanCoilNum).Name,
    1899             :                                                  "Design Size Maximum Hot Water Flow [m3/s]",
    1900          80 :                                                  MaxHotWaterVolFlowDes);
    1901             :                 } else { // Hard size with sizing data
    1902           0 :                     if (FanCoil(FanCoilNum).MaxHotWaterVolFlow > 0.0 && MaxHotWaterVolFlowDes > 0.0) {
    1903           0 :                         MaxHotWaterVolFlowDes = FanCoil(FanCoilNum).MaxHotWaterVolFlow;
    1904           0 :                         BaseSizer::reportSizerOutput(state,
    1905           0 :                                                      FanCoil(FanCoilNum).UnitType,
    1906           0 :                                                      FanCoil(FanCoilNum).Name,
    1907             :                                                      "Design Size Maximum Hot Water Flow [m3/s]",
    1908             :                                                      MaxHotWaterVolFlowDes,
    1909             :                                                      "User-Specified Maximum Hot Water Flow [m3/s]",
    1910           0 :                                                      MaxHotWaterVolFlowUser);
    1911           0 :                         if (state.dataGlobal->DisplayExtraWarnings) {
    1912           0 :                             if ((std::abs(MaxHotWaterVolFlowDes - MaxHotWaterVolFlowUser) / MaxHotWaterVolFlowUser) >
    1913           0 :                                 state.dataSize->AutoVsHardSizingThreshold) {
    1914           0 :                                 ShowMessage(state,
    1915           0 :                                             "SizeFanCoilUnit: Potential issue with equipment sizing for " + FanCoil(FanCoilNum).UnitType + ' ' +
    1916           0 :                                                 FanCoil(FanCoilNum).Name);
    1917           0 :                                 ShowContinueError(state, format("User-Specified Maximum Hot Water Flow of {:.5R} [m3/s]", MaxHotWaterVolFlowUser));
    1918           0 :                                 ShowContinueError(state,
    1919           0 :                                                   format("differs from Design Size Maximum Hot Water Flow of {:.5R} [m3/s]", MaxHotWaterVolFlowDes));
    1920           0 :                                 ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    1921           0 :                                 ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    1922             :                             }
    1923             :                         }
    1924             :                     }
    1925             :                 }
    1926             :             }
    1927           1 :         } else if (FanCoil(FanCoilNum).HCoilType_Num == HCoil::Electric) {
    1928           1 :             if (FanCoil(FanCoilNum).DesignHeatingCapacity == AutoSize) {
    1929           1 :                 CompName = FanCoil(FanCoilNum).HCoilName;
    1930           1 :                 CompType = FanCoil(FanCoilNum).HCoilType;
    1931           1 :                 SizingMethod = HeatingCapacitySizing;
    1932           1 :                 PrintFlag = false;
    1933           1 :                 TempSize = FanCoil(FanCoilNum).DesignHeatingCapacity;
    1934           1 :                 SizingString = "Nominal Heating Capacity [W]";
    1935           1 :                 bool errorsFound = false;
    1936           2 :                 HeatingCapacitySizer sizerHeatingCapacity;
    1937           1 :                 sizerHeatingCapacity.overrideSizingString(SizingString);
    1938           1 :                 sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    1939           1 :                 FanCoil(FanCoilNum).DesignHeatingCapacity = sizerHeatingCapacity.size(state, TempSize, errorsFound);
    1940           1 :                 FanCoil(FanCoilNum).DesHeatingLoad = FanCoil(FanCoilNum).DesignHeatingCapacity;
    1941             :             }
    1942             :         }
    1943             : 
    1944          81 :         IsAutoSize = false;
    1945          81 :         if (FanCoil(FanCoilNum).MaxColdWaterVolFlow == AutoSize) {
    1946          81 :             IsAutoSize = true;
    1947             :         }
    1948          81 :         if (state.dataSize->CurZoneEqNum > 0) {
    1949          81 :             if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) {
    1950           0 :                 if (FanCoil(FanCoilNum).MaxColdWaterVolFlow > 0.0) {
    1951           0 :                     BaseSizer::reportSizerOutput(state,
    1952           0 :                                                  FanCoil(FanCoilNum).UnitType,
    1953           0 :                                                  FanCoil(FanCoilNum).Name,
    1954             :                                                  "User-Specified Maximum Cold Water Flow [m3/s]",
    1955           0 :                                                  FanCoil(FanCoilNum).MaxColdWaterVolFlow);
    1956             :                 }
    1957             :             } else {
    1958          81 :                 if (UtilityRoutines::SameString(FanCoil(FanCoilNum).CCoilType, "CoilSystem:Cooling:Water:HeatExchangerAssisted")) {
    1959           0 :                     CoolingCoilName = GetHXDXCoilName(state, FanCoil(FanCoilNum).CCoilType, FanCoil(FanCoilNum).CCoilName, ErrorsFound);
    1960           0 :                     CoolingCoilType = GetHXCoilType(state, FanCoil(FanCoilNum).CCoilType, FanCoil(FanCoilNum).CCoilName, ErrorsFound);
    1961             :                 } else {
    1962          81 :                     CoolingCoilName = FanCoil(FanCoilNum).CCoilName;
    1963          81 :                     CoolingCoilType = FanCoil(FanCoilNum).CCoilType;
    1964             :                 }
    1965          81 :                 state.dataFanCoilUnits->CoilWaterInletNode = WaterCoils::GetCoilWaterInletNode(state, CoolingCoilType, CoolingCoilName, ErrorsFound);
    1966          81 :                 state.dataFanCoilUnits->CoilWaterOutletNode =
    1967          81 :                     WaterCoils::GetCoilWaterOutletNode(state, CoolingCoilType, CoolingCoilName, ErrorsFound);
    1968          81 :                 if (IsAutoSize) {
    1969         243 :                     PltSizCoolNum = MyPlantSizingIndex(state,
    1970             :                                                        CoolingCoilType,
    1971             :                                                        CoolingCoilName,
    1972          81 :                                                        state.dataFanCoilUnits->CoilWaterInletNode,
    1973          81 :                                                        state.dataFanCoilUnits->CoilWaterOutletNode,
    1974             :                                                        ErrorsFound);
    1975          81 :                     CoilNum = WaterCoils::GetWaterCoilIndex(state, CoolingCoilType, CoolingCoilName, ErrorsFound);
    1976          81 :                     if (state.dataWaterCoils->WaterCoil(CoilNum).UseDesignWaterDeltaTemp) {
    1977           0 :                         WaterCoilSizDeltaT = state.dataWaterCoils->WaterCoil(CoilNum).DesignWaterDeltaTemp;
    1978           0 :                         DoWaterCoilSizing = true;
    1979             :                     } else {
    1980          81 :                         if (PltSizCoolNum > 0) {
    1981          81 :                             WaterCoilSizDeltaT = state.dataSize->PlantSizData(PltSizCoolNum).DeltaT;
    1982          81 :                             DoWaterCoilSizing = true;
    1983             :                         } else {
    1984           0 :                             DoWaterCoilSizing = false;
    1985             :                             // If there is no cooling Plant Sizing object and autosizing was requested, issue fatal error message
    1986           0 :                             ShowSevereError(state, "Autosizing of water coil requires a cooling loop Sizing:Plant object");
    1987           0 :                             ShowContinueError(state, "Occurs in " + FanCoil(FanCoilNum).UnitType + " Object=" + FanCoil(FanCoilNum).Name);
    1988           0 :                             ErrorsFound = true;
    1989             :                         }
    1990             :                     }
    1991             : 
    1992          81 :                     if (DoWaterCoilSizing) {
    1993          81 :                         SizingMethod = CoolingCapacitySizing;
    1994          81 :                         if (state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolMassFlow > 0.0) {
    1995          81 :                             state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolOAFlowFrac =
    1996          81 :                                 min(FanCoil(FanCoilNum).OutAirVolFlow / state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolMassFlow,
    1997             :                                     1.0);
    1998             :                         } else {
    1999           0 :                             state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolOAFlowFrac = 0.0;
    2000             :                         }
    2001          81 :                         if (FanCoil(FanCoilNum).HVACSizingIndex > 0) {
    2002           3 :                             zoneHVACIndex = FanCoil(FanCoilNum).HVACSizingIndex;
    2003           3 :                             CapSizingMethod = state.dataSize->ZoneHVACSizing(zoneHVACIndex).CoolingCapMethod;
    2004           3 :                             ZoneEqSizing(state.dataSize->CurZoneEqNum).SizingMethod(SizingMethod) = CapSizingMethod;
    2005           3 :                             if (CapSizingMethod == CoolingDesignCapacity || CapSizingMethod == CapacityPerFloorArea ||
    2006             :                                 CapSizingMethod == FractionOfAutosizedCoolingCapacity) {
    2007           3 :                                 if (CapSizingMethod == CoolingDesignCapacity) {
    2008           1 :                                     if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity > 0.0) {
    2009           0 :                                         ZoneEqSizing(state.dataSize->CurZoneEqNum).CoolingCapacity = true;
    2010           0 :                                         ZoneEqSizing(state.dataSize->CurZoneEqNum).DesCoolingLoad =
    2011           0 :                                             state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity;
    2012             :                                     } else {
    2013           1 :                                         state.dataSize->DataFlowUsedForSizing =
    2014           1 :                                             state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolVolFlow;
    2015             :                                     }
    2016           1 :                                     TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity;
    2017           2 :                                 } else if (CapSizingMethod == CapacityPerFloorArea) {
    2018           1 :                                     if (state.dataSize->ZoneSizingRunDone) {
    2019           1 :                                         CheckZoneSizing(state, CompType, CompName);
    2020           1 :                                         PrintFlag = false;
    2021           1 :                                         TempSize = AutoSize;
    2022           1 :                                         state.dataSize->DataFlowUsedForSizing =
    2023           1 :                                             state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolVolFlow;
    2024           2 :                                         CoolingCapacitySizer sizerCoolingCapacity;
    2025           1 :                                         sizerCoolingCapacity.overrideSizingString(SizingString);
    2026           1 :                                         sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    2027           1 :                                         ZoneEqSizing(state.dataSize->CurZoneEqNum).DesCoolingLoad =
    2028           1 :                                             sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
    2029           1 :                                         ZoneEqSizing(state.dataSize->CurZoneEqNum).CoolingCapacity = true;
    2030             :                                     }
    2031           2 :                                     TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity *
    2032           1 :                                                state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
    2033           1 :                                     state.dataSize->DataScalableCapSizingON = true;
    2034           1 :                                 } else if (CapSizingMethod == FractionOfAutosizedCoolingCapacity) {
    2035           1 :                                     PrintFlag = false;
    2036           1 :                                     TempSize = AutoSize;
    2037           1 :                                     state.dataSize->DataFlowUsedForSizing =
    2038           1 :                                         state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolVolFlow;
    2039           2 :                                     CoolingCapacitySizer sizerCoolingCapacity2;
    2040           1 :                                     sizerCoolingCapacity2.overrideSizingString(SizingString);
    2041           1 :                                     sizerCoolingCapacity2.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    2042           1 :                                     ZoneEqSizing(state.dataSize->CurZoneEqNum).DesCoolingLoad =
    2043           1 :                                         sizerCoolingCapacity2.size(state, TempSize, ErrorsFound);
    2044           1 :                                     ZoneEqSizing(state.dataSize->CurZoneEqNum).CoolingCapacity = true;
    2045           2 :                                     TempSize = ZoneEqSizing(state.dataSize->CurZoneEqNum).DesCoolingLoad *
    2046           1 :                                                state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity;
    2047           1 :                                     state.dataSize->DataScalableCapSizingON = true;
    2048             :                                 }
    2049             :                             }
    2050           3 :                             SizingString = "Cooling Design Capacity [W]";
    2051           3 :                             PrintFlag = false;
    2052           6 :                             CoolingCapacitySizer sizerCoolingCapacity3;
    2053           3 :                             sizerCoolingCapacity3.overrideSizingString(SizingString);
    2054           3 :                             sizerCoolingCapacity3.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    2055           3 :                             DesCoilLoad = sizerCoolingCapacity3.size(state, TempSize, ErrorsFound);
    2056           3 :                             state.dataSize->DataScalableCapSizingON = false;
    2057           3 :                             state.dataSize->DataFlowUsedForSizing = 0.0;
    2058             :                         } else {
    2059          78 :                             SizingString = "Cooling Design Capacity [W]";
    2060          78 :                             PrintFlag = false;
    2061          78 :                             TempSize = AutoSize;
    2062          78 :                             state.dataSize->DataFlowUsedForSizing = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolVolFlow;
    2063         156 :                             CoolingCapacitySizer sizerCoolingCapacity;
    2064          78 :                             sizerCoolingCapacity.overrideSizingString(SizingString);
    2065          78 :                             sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    2066          78 :                             DesCoilLoad = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
    2067             :                         }
    2068          81 :                         FanCoil(FanCoilNum).DesCoolingLoad = DesCoilLoad;
    2069          81 :                         if (DesCoilLoad >= SmallLoad) {
    2070         162 :                             rho = GetDensityGlycol(state,
    2071          81 :                                                    state.dataPlnt->PlantLoop(FanCoil(FanCoilNum).CoolCoilPlantLoc.loopNum).FluidName,
    2072             :                                                    5.,
    2073          81 :                                                    state.dataPlnt->PlantLoop(FanCoil(FanCoilNum).CoolCoilPlantLoc.loopNum).FluidIndex,
    2074             :                                                    RoutineNameNoSpace);
    2075         162 :                             Cp = GetSpecificHeatGlycol(state,
    2076          81 :                                                        state.dataPlnt->PlantLoop(FanCoil(FanCoilNum).CoolCoilPlantLoc.loopNum).FluidName,
    2077             :                                                        5.,
    2078          81 :                                                        state.dataPlnt->PlantLoop(FanCoil(FanCoilNum).CoolCoilPlantLoc.loopNum).FluidIndex,
    2079             :                                                        RoutineNameNoSpace);
    2080          81 :                             MaxColdWaterVolFlowDes = DesCoilLoad / (WaterCoilSizDeltaT * Cp * rho);
    2081             :                         } else {
    2082           0 :                             MaxColdWaterVolFlowDes = 0.0;
    2083             :                         }
    2084             :                     }
    2085             :                 }
    2086          81 :                 if (IsAutoSize) {
    2087          81 :                     FanCoil(FanCoilNum).MaxColdWaterVolFlow = MaxColdWaterVolFlowDes;
    2088         243 :                     BaseSizer::reportSizerOutput(state,
    2089          81 :                                                  FanCoil(FanCoilNum).UnitType,
    2090          81 :                                                  FanCoil(FanCoilNum).Name,
    2091             :                                                  "Design Size Maximum Cold Water Flow [m3/s]",
    2092          81 :                                                  MaxColdWaterVolFlowDes);
    2093             :                 } else { // Hard size with sizing data
    2094           0 :                     if (FanCoil(FanCoilNum).MaxColdWaterVolFlow > 0.0 && MaxColdWaterVolFlowDes > 0.0) {
    2095           0 :                         MaxColdWaterVolFlowUser = FanCoil(FanCoilNum).MaxColdWaterVolFlow;
    2096           0 :                         BaseSizer::reportSizerOutput(state,
    2097           0 :                                                      FanCoil(FanCoilNum).UnitType,
    2098           0 :                                                      FanCoil(FanCoilNum).Name,
    2099             :                                                      "Design Size Maximum Cold Water Flow [m3/s]",
    2100             :                                                      MaxColdWaterVolFlowDes,
    2101             :                                                      "User-Specified Maximum Cold Water Flow [m3/s]",
    2102           0 :                                                      MaxColdWaterVolFlowUser);
    2103           0 :                         if (state.dataGlobal->DisplayExtraWarnings) {
    2104           0 :                             if ((std::abs(MaxColdWaterVolFlowDes - MaxColdWaterVolFlowUser) / MaxColdWaterVolFlowUser) >
    2105           0 :                                 state.dataSize->AutoVsHardSizingThreshold) {
    2106           0 :                                 ShowMessage(state,
    2107           0 :                                             "SizeFanCoilUnit: Potential issue with equipment sizing for " + FanCoil(FanCoilNum).UnitType + ' ' +
    2108           0 :                                                 FanCoil(FanCoilNum).Name);
    2109           0 :                                 ShowContinueError(state, format("User-Specified Maximum Cold Water Flow of {:.5R}[m3/s]", MaxColdWaterVolFlowUser));
    2110           0 :                                 ShowContinueError(state,
    2111           0 :                                                   format("differs from Design Size Maximum Cold Water Flow of {:.5R}[m3/s]", MaxColdWaterVolFlowDes));
    2112           0 :                                 ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    2113           0 :                                 ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    2114             :                             }
    2115             :                         }
    2116             :                     }
    2117             :                 }
    2118             :             }
    2119             : 
    2120          81 :             if (FanCoil(FanCoilNum).CapCtrlMeth_Num == CCM::ASHRAE && !FanCoil(FanCoilNum).ASHRAETempControl) {
    2121             : 
    2122           3 :                 CompType = FanCoil(FanCoilNum).UnitType;
    2123           3 :                 CompName = FanCoil(FanCoilNum).Name;
    2124           3 :                 PrintFlag = true;
    2125             : 
    2126           6 :                 ZoneCoolingLoadSizer sizerZoneCoolingLoad;
    2127           3 :                 sizerZoneCoolingLoad.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    2128           3 :                 FanCoil(FanCoilNum).DesZoneCoolingLoad = sizerZoneCoolingLoad.size(state, FanCoil(FanCoilNum).DesZoneCoolingLoad, ErrorsFound);
    2129           3 :                 FanCoil(FanCoilNum).DesZoneCoolingLoad *= -1.0;
    2130             : 
    2131           6 :                 ZoneHeatingLoadSizer sizerZoneHeatingLoad;
    2132           3 :                 sizerZoneHeatingLoad.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    2133           3 :                 FanCoil(FanCoilNum).DesZoneHeatingLoad = sizerZoneHeatingLoad.size(state, FanCoil(FanCoilNum).DesZoneHeatingLoad, ErrorsFound);
    2134             : 
    2135           3 :                 FanCoil(FanCoilNum).DSOAPtr = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneDesignSpecOAIndex;
    2136             : 
    2137          78 :             } else if (FanCoil(FanCoilNum).CapCtrlMeth_Num == CCM::ASHRAE && FanCoil(FanCoilNum).ASHRAETempControl) {
    2138             : 
    2139           0 :                 CompType = FanCoil(FanCoilNum).UnitType;
    2140           0 :                 CompName = FanCoil(FanCoilNum).Name;
    2141           0 :                 Real64 capacityMultiplier = 0.6; // 60% of design zone load for water coils
    2142           0 :                 state.dataSize->DataCapacityUsedForSizing = FanCoil(FanCoilNum).DesCoolingLoad * capacityMultiplier;
    2143           0 :                 CheckThisZoneForSizing(state, state.dataSize->CurZoneEqNum, SizingDesRunThisZone);
    2144           0 :                 if (SizingDesRunThisZone) {
    2145           0 :                     state.dataSize->DataCapacityUsedForSizing =
    2146           0 :                         state.dataSize->FinalZoneSizing(FanCoil(FanCoilNum).ControlZoneNum).DesCoolLoad * capacityMultiplier;
    2147             :                 } else {
    2148           0 :                     state.dataSize->DataCapacityUsedForSizing = FanCoil(FanCoilNum).DesCoolingLoad * capacityMultiplier;
    2149             :                 }
    2150           0 :                 state.dataSize->DataFlowUsedForSizing = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolVolFlow;
    2151           0 :                 PrintFlag = true;
    2152           0 :                 ASHRAEMinSATCoolingSizer sizerASHRAEMinSATCooling;
    2153           0 :                 sizerASHRAEMinSATCooling.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    2154           0 :                 FanCoil(FanCoilNum).DesignMinOutletTemp = sizerASHRAEMinSATCooling.size(state, FanCoil(FanCoilNum).DesignMinOutletTemp, ErrorsFound);
    2155             : 
    2156           0 :                 if (SizingDesRunThisZone) {
    2157           0 :                     state.dataSize->DataCapacityUsedForSizing =
    2158           0 :                         state.dataSize->FinalZoneSizing(FanCoil(FanCoilNum).ControlZoneNum).DesHeatLoad * capacityMultiplier;
    2159             :                 } else {
    2160           0 :                     state.dataSize->DataCapacityUsedForSizing = FanCoil(FanCoilNum).DesHeatingLoad * capacityMultiplier;
    2161             :                 }
    2162           0 :                 state.dataSize->DataFlowUsedForSizing = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatVolFlow;
    2163           0 :                 ASHRAEMaxSATHeatingSizer sizerASHRAEMaxSATHeating;
    2164           0 :                 sizerASHRAEMaxSATHeating.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    2165           0 :                 FanCoil(FanCoilNum).DesignMaxOutletTemp = sizerASHRAEMaxSATHeating.size(state, FanCoil(FanCoilNum).DesignMaxOutletTemp, ErrorsFound);
    2166             : 
    2167           0 :                 state.dataSize->DataCapacityUsedForSizing = 0.0; // reset so other routines don't use this inadvertently
    2168           0 :                 state.dataSize->DataFlowUsedForSizing = 0.0;
    2169             : 
    2170           0 :                 SizingDesRunThisZone = false;
    2171           0 :                 CheckThisZoneForSizing(state, state.dataSize->CurZoneEqNum, SizingDesRunThisZone);
    2172             : 
    2173           0 :                 if (SizingDesRunThisZone) {
    2174             : 
    2175           0 :                     FanCoil(FanCoilNum).DesZoneCoolingLoad =
    2176           0 :                         -1.0 * (FanCoil(FanCoilNum).DesCoolingLoad / state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).CoolSizingFactor);
    2177           0 :                     FanCoil(FanCoilNum).DesZoneHeatingLoad =
    2178           0 :                         FanCoil(FanCoilNum).DesHeatingLoad / state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).HeatSizingFactor;
    2179           0 :                     FanCoil(FanCoilNum).DSOAPtr = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneDesignSpecOAIndex;
    2180             : 
    2181             :                 } else {
    2182             : 
    2183           0 :                     FanCoil(FanCoilNum).DesZoneCoolingLoad = -1.0 * FanCoil(FanCoilNum).DesCoolingLoad;
    2184           0 :                     FanCoil(FanCoilNum).DesZoneHeatingLoad = FanCoil(FanCoilNum).DesHeatingLoad;
    2185             :                 }
    2186             :             }
    2187             : 
    2188             :         } // if ( CurZoneEqNum > 0 )
    2189             : 
    2190             :         // set the design air flow rates for the heating and cooling coils
    2191          81 :         if (UtilityRoutines::SameString(FanCoil(FanCoilNum).CCoilType, "CoilSystem:Cooling:Water:HeatExchangerAssisted")) {
    2192           0 :             CoolingCoilName = GetHXDXCoilName(state, FanCoil(FanCoilNum).CCoilType, FanCoil(FanCoilNum).CCoilName, ErrorsFound);
    2193           0 :             CoolingCoilType = GetHXCoilType(state, FanCoil(FanCoilNum).CCoilType, FanCoil(FanCoilNum).CCoilName, ErrorsFound);
    2194             :         } else {
    2195          81 :             CoolingCoilName = FanCoil(FanCoilNum).CCoilName;
    2196          81 :             CoolingCoilType = FanCoil(FanCoilNum).CCoilType;
    2197             :         }
    2198          81 :         if (state.dataSize->ZoneSizingRunDone) {
    2199          81 :             WaterCoils::SetCoilDesFlow(
    2200          81 :                 state, CoolingCoilType, CoolingCoilName, state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolVolFlow, ErrorsFound);
    2201         243 :             WaterCoils::SetCoilDesFlow(state,
    2202          81 :                                        FanCoil(FanCoilNum).HCoilType,
    2203          81 :                                        FanCoil(FanCoilNum).HCoilName,
    2204          81 :                                        state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatVolFlow,
    2205             :                                        ErrorsFound);
    2206             :         } else {
    2207           0 :             WaterCoils::SetCoilDesFlow(state, CoolingCoilType, CoolingCoilName, FanCoil(FanCoilNum).MaxAirVolFlow, ErrorsFound);
    2208           0 :             WaterCoils::SetCoilDesFlow(
    2209           0 :                 state, FanCoil(FanCoilNum).HCoilType, FanCoil(FanCoilNum).HCoilName, FanCoil(FanCoilNum).MaxAirVolFlow, ErrorsFound);
    2210             :         }
    2211          81 :         if (state.dataSize->CurZoneEqNum > 0) {
    2212          81 :             ZoneEqSizing(state.dataSize->CurZoneEqNum).MaxHWVolFlow = FanCoil(FanCoilNum).MaxHotWaterVolFlow;
    2213          81 :             ZoneEqSizing(state.dataSize->CurZoneEqNum).MaxCWVolFlow = FanCoil(FanCoilNum).MaxColdWaterVolFlow;
    2214          81 :             ZoneEqSizing(state.dataSize->CurZoneEqNum).AirVolFlow = FanCoil(FanCoilNum).MaxAirVolFlow;
    2215          81 :             ZoneEqSizing(state.dataSize->CurZoneEqNum).DesCoolingLoad = FanCoil(FanCoilNum).DesCoolingLoad;
    2216          81 :             ZoneEqSizing(state.dataSize->CurZoneEqNum).DesHeatingLoad = FanCoil(FanCoilNum).DesHeatingLoad;
    2217          81 :             ZoneEqSizing(state.dataSize->CurZoneEqNum).DesignSizeFromParent = true;
    2218             :         }
    2219             : 
    2220          81 :         if (ErrorsFound) {
    2221           0 :             ShowFatalError(state, "Preceding sizing errors cause program termination");
    2222             :         }
    2223          81 :     }
    2224             : 
    2225      514191 :     void Sim4PipeFanCoil(EnergyPlusData &state,
    2226             :                          int &FanCoilNum,               // number of the current fan coil unit being simulated
    2227             :                          int const ControlledZoneNum,   // index into ZoneEqupConfig
    2228             :                          bool const FirstHVACIteration, // TRUE if 1st HVAC simulation of system timestep
    2229             :                          Real64 &PowerMet,              // Sensible power supplied (W)
    2230             :                          Real64 &LatOutputProvided      // Latent power supplied (kg/s), negative = dehumidification
    2231             :     )
    2232             :     {
    2233             : 
    2234             :         // SUBROUTINE INFORMATION:
    2235             :         //       AUTHOR         Fred Buhl
    2236             :         //       DATE WRITTEN   March 2000
    2237             :         //       MODIFIED       Don Shirey, Aug 2009 (LatOutputProvided)
    2238             :         //       MODIFIED       Arnaud Flament June 2010 (added airflow capacity control methods)
    2239             :         //       MODIFIED      R. Raustad, FSEC, Feb 2016 (added ASHRAE 90.1 SZVAV system control)
    2240             : 
    2241             :         // PURPOSE OF THIS SUBROUTINE:
    2242             :         // Simulate a 4 pipe fan coil unit; adjust its output to match the
    2243             :         // remaining zone load.
    2244             : 
    2245             :         // METHODOLOGY EMPLOYED:
    2246             :         // If unit is on, calls ControlCompOutput to obtain the desired unit output
    2247             : 
    2248             :         // REFERENCES:
    2249             :         // SZVAV sysetm control:
    2250             :         // ASHRAE 90.1 2010 Section 6.4.3.10 - Single Zone Variable-Air-volume Controls (described in Trane newsletter entitled Understanding
    2251             :         // Single-Zone VAV Systems) Trane Engineers Newsletter -
    2252             :         // https://www.trane.com/content/dam/Trane/Commercial/global/products-systems/education-training/engineers-newsletters/airside-design/admapn047en_0413.pdf
    2253             :         //
    2254             : 
    2255             :         // Using/Aliasing
    2256             :         using namespace DataZoneEnergyDemands;
    2257             : 
    2258             :         using PlantUtilities::SetComponentFlowRate;
    2259             :         using Psychrometrics::PsyHFnTdbW;
    2260             :         using Psychrometrics::PsyRhoAirFnPbTdbW;
    2261             :         using namespace DataPlant;
    2262             :         using namespace DataLoopNode;
    2263             : 
    2264      514191 :         int constexpr MaxIterCycl(100);
    2265             : 
    2266             :         Real64 QZnReq;        // heating or cooling needed by zone [watts]
    2267             :         Real64 QUnitOut;      // heating or sens. cooling provided by fan coil unit [watts]
    2268             :         Real64 QUnitOutMax;   // heating or sens. cooling provided by fan coil unit (running during an entire timestep)
    2269             :         Real64 PLR;           // Part Load Ratio, fraction of time step fancoil is on
    2270             :         bool UnitOn;          // TRUE if unit is on
    2271             :         int ControlNode;      // the hot water or cold water inlet node
    2272             :         Real64 ControlOffset; // tolerance for output control
    2273             :         Real64 MaxWaterFlow;  // maximum water flow for heating or cooling [kg/sec]
    2274             :         Real64 MinWaterFlow;  // minimum water flow for heating or cooling [kg/sec]
    2275             :         Real64 PLRMin;        // minimum PLR used for tighter control of air and water flow rate
    2276             :         Real64 PLRMax;        // maximum PLR used for tighter control of air and water flow rate
    2277             :         int OutletNode;       // unit air outlet node
    2278             :         int InletNode;        // unit air inlet node
    2279             :         Real64 QTotUnitOut;   // total unit output [watts]
    2280             :         Real64 AirMassFlow;   // air mass flow rate [kg/sec]
    2281             :         Real64 QUnitOutNoHC;  // unit output with no active heating or cooling [W]
    2282             :         Real64 QUnitOutMaxC;  // unit output with full active cooling [W]
    2283             :         Real64 QUnitOutMaxH;  // unit output with full active heating [W]
    2284             :         Real64 QCoilHeatSP;   // coil load to the heating setpoint [W]
    2285             :         Real64 QCoilCoolSP;   // coil load to the cooling setpoint [W]
    2286             :         Real64 LatentOutput;  // Latent (moisture) add/removal rate, negative is dehumidification [kg/s]
    2287             :         Real64 SpecHumOut;    // Specific humidity ratio of outlet air (kg moisture / kg moist air)
    2288             :         Real64 SpecHumIn;     // Specific humidity ratio of inlet air (kg moisture / kg moist air)
    2289             :         Real64 Error;         // Error between QZnReq and QUnitOut
    2290             :         Real64 AbsError;      // Absolute error between QZnReq and QUnitOut [W]   !FB
    2291             :         int Iter;             // iteration counter
    2292             :         Real64 Relax;
    2293             :         Real64 DelPLR;
    2294             :         Real64 mdot;
    2295             :         // Real64 Low_mdot;
    2296             :         Real64 QSensUnitOutNoATM;     // unit output not including air added by supply side air terminal mixer
    2297             :         int SolFlag;                  // return flag from RegulaFalsi for sensible load
    2298             :         Real64 ElectricHeaterControl; // 1 or 0, enables or disables heating coil
    2299             :         Real64 OAVolumeFlowRate;      // OA volume flow rate based on design specifications object [m3/s]
    2300             :         Real64 OAMassFlow;            // OA mass flow rate based on design specifications object [kg/s]
    2301             :         Real64 RhoAir;                // density of air [kg/m3]
    2302             :         Real64 MinSAMassFlowRate;     // minimum supply air mass flow rate [kg/s]
    2303             :         Real64 MaxSAMassFlowRate;     // maximum supply air mass flow rate [kg/s]
    2304             :         // Real64 FCOutletTempOn;        // ASHRAE outlet air temperature when coil is on [C]
    2305             :         Real64 HWFlow;       // hot water mass flow rate solution [kg/s]
    2306             :         Real64 MdotLockH;    // saved value of locked chilled water mass flow rate [kg/s]
    2307             :         Real64 MdotLockC;    // saved value of locked hot water mass flow rate [kg/s]
    2308             :         Real64 CWFlow;       // cold water mass flow rate solution [kg/s]
    2309             :         Real64 CWFlowBypass; // cold water bypassed mass flow rate [kg/s]
    2310             :         Real64 HWFlowBypass; // hot water bypassed mass flow rate [kg/s]
    2311             :         bool ColdFlowLocked; // if true cold water flow is locked
    2312             :         bool HotFlowLocked;  // if true Hot water flow is locked
    2313             : 
    2314      514191 :         auto &Node(state.dataLoopNodes->Node);
    2315             : 
    2316             :         // initialize local variables
    2317      514191 :         UnitOn = true;
    2318      514191 :         ControlNode = 0;
    2319      514191 :         QUnitOut = 0.0;
    2320      514191 :         QUnitOutMax = 0.0;
    2321      514191 :         PLR = 0.0;
    2322      514191 :         LatentOutput = 0.0;
    2323      514191 :         QUnitOutNoHC = 0.0;
    2324      514191 :         QCoilHeatSP = 0.0;
    2325      514191 :         QCoilCoolSP = 0.0;
    2326      514191 :         QZnReq = 0.0;
    2327      514191 :         ControlOffset = 0.0;
    2328      514191 :         MaxWaterFlow = 0.0;
    2329      514191 :         MinWaterFlow = 0.0;
    2330      514191 :         OutletNode = state.dataFanCoilUnits->FanCoil(FanCoilNum).AirOutNode;
    2331      514191 :         InletNode = state.dataFanCoilUnits->FanCoil(FanCoilNum).AirInNode;
    2332      514191 :         AirMassFlow = Node(InletNode).MassFlowRate;
    2333      514191 :         Error = 1.0;
    2334      514191 :         AbsError = 2.0 * SmallLoad;
    2335      514191 :         Iter = 0;
    2336      514191 :         Relax = 1.0;
    2337      514191 :         ElectricHeaterControl = 0.0;
    2338      514191 :         HWFlow = 0.0;
    2339      514191 :         HWFlowBypass = 0.0;
    2340      514191 :         MdotLockH = 0.0;
    2341      514191 :         MdotLockC = 0.0;
    2342      514191 :         ColdFlowLocked = false;
    2343      514191 :         HotFlowLocked = false;
    2344             : 
    2345      514191 :         auto &FanCoil(state.dataFanCoilUnits->FanCoil);
    2346             : 
    2347             :         // select capacity control method
    2348      514191 :         switch (FanCoil(FanCoilNum).CapCtrlMeth_Num) {
    2349      280714 :         case CCM::ConsFanVarFlow: {
    2350             : 
    2351      280714 :             if (AirMassFlow < SmallMassFlow) UnitOn = false;
    2352             :             // zero the hot & cold water flows
    2353             : 
    2354             :             // set water coil flow rate to 0 to calculate coil off capacity (only valid while flow is unlocked)
    2355      280714 :             mdot = 0.0;
    2356      842142 :             SetComponentFlowRate(state,
    2357             :                                  mdot,
    2358      280714 :                                  FanCoil(FanCoilNum).CoolCoilFluidInletNode,
    2359      280714 :                                  FanCoil(FanCoilNum).CoolCoilFluidOutletNodeNum,
    2360      280714 :                                  FanCoil(FanCoilNum).CoolCoilPlantLoc);
    2361      561428 :             if (state.dataPlnt->PlantLoop(FanCoil(FanCoilNum).CoolCoilPlantLoc.loopNum)
    2362      280714 :                     .LoopSide(FanCoil(FanCoilNum).CoolCoilPlantLoc.loopSideNum)
    2363      280714 :                     .FlowLock == DataPlant::FlowLock::Locked) {
    2364         216 :                 ColdFlowLocked = true; // check for flow lock
    2365             :             }
    2366      280714 :             if (FanCoil(FanCoilNum).HCoilType_Num == HCoil::Water) {
    2367      280714 :                 mdot = 0.0;
    2368      842142 :                 SetComponentFlowRate(state,
    2369             :                                      mdot,
    2370      280714 :                                      FanCoil(FanCoilNum).HeatCoilFluidInletNode,
    2371      280714 :                                      FanCoil(FanCoilNum).HeatCoilFluidOutletNodeNum,
    2372      280714 :                                      FanCoil(FanCoilNum).HeatCoilPlantLoc);
    2373      561428 :                 if (state.dataPlnt->PlantLoop(FanCoil(FanCoilNum).HeatCoilPlantLoc.loopNum)
    2374      280714 :                         .LoopSide(FanCoil(FanCoilNum).HeatCoilPlantLoc.loopSideNum)
    2375      280714 :                         .FlowLock == DataPlant::FlowLock::Locked) {
    2376         216 :                     HotFlowLocked = true; // save locked flow
    2377             :                 }
    2378             :             }
    2379             :             // obtain unit output with no active heating/cooling
    2380      280714 :             Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOutNoHC, 0.0);
    2381             : 
    2382      280714 :             if (ColdFlowLocked || HotFlowLocked) {
    2383         216 :                 QUnitOutNoHC = FanCoil(FanCoilNum).QUnitOutNoHC;
    2384             :             } else { // continue to update QUnitOutNoHC while flow is unlocked
    2385      280498 :                 FanCoil(FanCoilNum).QUnitOutNoHC = QUnitOutNoHC;
    2386             :             }
    2387             : 
    2388             :             // then calculate the loads at the coils
    2389      280714 :             QCoilHeatSP = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlledZoneNum).RemainingOutputReqToHeatSP - QUnitOutNoHC;
    2390      280714 :             QCoilCoolSP = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlledZoneNum).RemainingOutputReqToCoolSP - QUnitOutNoHC;
    2391             : 
    2392             :             // if cooling
    2393      432128 :             if (UnitOn && QCoilCoolSP < (-1.0 * SmallLoad) &&
    2394      151414 :                 state.dataHeatBalFanSys->TempControlType(ControlledZoneNum) != DataHVACGlobals::ThermostatType::SingleHeating) {
    2395      151072 :                 ControlNode = FanCoil(FanCoilNum).CoolCoilFluidInletNode;
    2396      151072 :                 ControlOffset = FanCoil(FanCoilNum).ColdControlOffset;
    2397      151072 :                 MaxWaterFlow = FanCoil(FanCoilNum).MaxCoolCoilFluidFlow;
    2398      151072 :                 MinWaterFlow = FanCoil(FanCoilNum).MinColdWaterFlow;
    2399             :                 // On the first HVAC iteration the system values are given to the controller, but after that
    2400             :                 // the demand limits are in place and there needs to be feedback to the Zone Equipment
    2401      151072 :                 if (!FirstHVACIteration) {
    2402       90516 :                     MaxWaterFlow = Node(ControlNode).MassFlowRateMaxAvail;
    2403       90516 :                     MinWaterFlow = Node(ControlNode).MassFlowRateMinAvail;
    2404             :                 }
    2405             :                 // get full load result
    2406      151072 :                 mdot = MaxWaterFlow;
    2407      453216 :                 SetComponentFlowRate(state,
    2408             :                                      mdot,
    2409      151072 :                                      FanCoil(FanCoilNum).CoolCoilFluidInletNode,
    2410      151072 :                                      FanCoil(FanCoilNum).CoolCoilFluidOutletNodeNum,
    2411      151072 :                                      FanCoil(FanCoilNum).CoolCoilPlantLoc);
    2412      151072 :                 Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOutMaxC);
    2413      151072 :                 if (!ColdFlowLocked) {
    2414      151010 :                     FanCoil(FanCoilNum).QUnitOutMaxC = QUnitOutMaxC;
    2415             :                 } else {
    2416          62 :                     QUnitOutMaxC = FanCoil(FanCoilNum).QUnitOutMaxC;
    2417          62 :                     MdotLockC = mdot; // save locked flow
    2418             :                 }
    2419      151072 :                 QZnReq = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlledZoneNum).RemainingOutputReqToCoolSP;
    2420      151072 :                 if (QUnitOutMaxC < QZnReq) {
    2421             :                     // more cooling than required, find reduced water flow rate to meet the load
    2422             :                     // solve for the cold water flow rate with no limit set by flow rate lockdown
    2423     3319552 :                     auto f = [&state, FanCoilNum, FirstHVACIteration, ControlledZoneNum, QZnReq](Real64 const CWFlow) {
    2424     1659776 :                         return CalcFanCoilCWLoadResidual(state, CWFlow, FanCoilNum, FirstHVACIteration, ControlledZoneNum, QZnReq);
    2425     1809546 :                     };
    2426      149770 :                     General::SolveRoot(state, 0.001, MaxIterCycl, SolFlag, CWFlow, f, 0.0, MaxWaterFlow);
    2427      149770 :                     if (SolFlag == -1) {
    2428             :                         // tighten limits on water flow rate to see if this allows convergence
    2429           0 :                         state.dataFanCoilUnits->CoolingLoad = true;
    2430           0 :                         state.dataFanCoilUnits->HeatingLoad = false;
    2431           0 :                         TightenWaterFlowLimits(state,
    2432             :                                                FanCoilNum,
    2433           0 :                                                state.dataFanCoilUnits->CoolingLoad,
    2434           0 :                                                state.dataFanCoilUnits->HeatingLoad,
    2435           0 :                                                FanCoil(FanCoilNum).CoolCoilFluidInletNode,
    2436             :                                                ControlledZoneNum,
    2437             :                                                FirstHVACIteration,
    2438             :                                                QZnReq,
    2439             :                                                MinWaterFlow,
    2440             :                                                MaxWaterFlow);
    2441           0 :                         General::SolveRoot(state, 0.001, MaxIterCycl, SolFlag, CWFlow, f, MinWaterFlow, MaxWaterFlow);
    2442           0 :                         if (SolFlag == -1) {
    2443           0 :                             ++FanCoil(FanCoilNum).ConvgErrCountC;
    2444           0 :                             if (FanCoil(FanCoilNum).ConvgErrCountC < 2) {
    2445           0 :                                 ShowWarningError(state, "Cold Water control failed in fan coil unit " + FanCoil(FanCoilNum).Name);
    2446           0 :                                 ShowContinueError(state, "  Iteration limit exceeded in calculating water flow rate ");
    2447           0 :                                 Node(FanCoil(FanCoilNum).CoolCoilFluidInletNode).MassFlowRate = CWFlow;
    2448           0 :                                 Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut);
    2449           0 :                                 ShowContinueErrorTimeStamp(state, format("Load Request = {}, Final Capacity = {}", QZnReq, QUnitOut));
    2450           0 :                                 ShowContinueErrorTimeStamp(
    2451             :                                     state,
    2452           0 :                                     format("Min water flow used during iterations = {}, Max water flow used during iterations = {}",
    2453             :                                            MinWaterFlow,
    2454           0 :                                            MaxWaterFlow));
    2455           0 :                                 ShowContinueErrorTimeStamp(state, format("Water flow rate on last iteration = {}", CWFlow));
    2456           0 :                                 ShowContinueErrorTimeStamp(state, "..Water flow rate set to last iteration value ");
    2457             :                             } else {
    2458           0 :                                 ShowRecurringWarningErrorAtEnd(state,
    2459           0 :                                                                "Cold water flow Iteration limit exceeded in fan coil unit " +
    2460           0 :                                                                    FanCoil(FanCoilNum).Name,
    2461           0 :                                                                FanCoil(FanCoilNum).MaxIterIndexC);
    2462             :                             }
    2463           0 :                         } else if (SolFlag == -2) {
    2464           0 :                             ++FanCoil(FanCoilNum).LimitErrCountC;
    2465           0 :                             if (FanCoil(FanCoilNum).LimitErrCountC < 2) {
    2466           0 :                                 ShowWarningError(state, "Cold Water control failed in fan coil unit " + FanCoil(FanCoilNum).Name);
    2467           0 :                                 ShowContinueError(state, "  Bad cold water mass flow limits");
    2468           0 :                                 ShowContinueErrorTimeStamp(state, "..Water flow rate set to lower limit ");
    2469             :                             } else {
    2470           0 :                                 ShowRecurringWarningErrorAtEnd(state,
    2471           0 :                                                                "Cold Water control failed in fan coil unit " + FanCoil(FanCoilNum).Name,
    2472           0 :                                                                FanCoil(FanCoilNum).BadMassFlowLimIndexC);
    2473             :                             }
    2474             :                         }
    2475      149770 :                     } else if (SolFlag == -2) {
    2476           0 :                         ++FanCoil(FanCoilNum).LimitErrCountC;
    2477           0 :                         if (FanCoil(FanCoilNum).LimitErrCountC < 2) {
    2478           0 :                             ShowWarningError(state, "Cold Water control failed in fan coil unit " + FanCoil(FanCoilNum).Name);
    2479           0 :                             ShowContinueError(state, "  Bad cold water mass flow limits");
    2480           0 :                             ShowContinueErrorTimeStamp(state, "..Water flow rate set to lower limit ");
    2481             :                         } else {
    2482           0 :                             ShowRecurringWarningErrorAtEnd(state,
    2483           0 :                                                            "Cold Water control failed in fan coil unit " + FanCoil(FanCoilNum).Name,
    2484           0 :                                                            FanCoil(FanCoilNum).BadMassFlowLimIndexC);
    2485             :                         }
    2486             :                     }
    2487             :                 } else {
    2488             :                     // demand greater than capacity
    2489        1302 :                     CWFlow = MaxWaterFlow;
    2490             :                 }
    2491      151072 :                 if (!ColdFlowLocked) {
    2492      151010 :                     mdot = CWFlow; // not flowlocked - set flow to CWFlow
    2493      453030 :                     SetComponentFlowRate(state,
    2494             :                                          mdot,
    2495      151010 :                                          FanCoil(FanCoilNum).CoolCoilFluidInletNode,
    2496      151010 :                                          FanCoil(FanCoilNum).CoolCoilFluidOutletNodeNum,
    2497      151010 :                                          FanCoil(FanCoilNum).CoolCoilPlantLoc);
    2498      151010 :                     Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut); // get QUnitOut
    2499             :                 } else {
    2500             :                     // flow lock on
    2501          62 :                     if (MdotLockC > CWFlow) { // if mdot > CWFlow, bypass extra flow
    2502          31 :                         Calc4PipeFanCoil(state,
    2503             :                                          FanCoilNum,
    2504             :                                          ControlledZoneNum,
    2505             :                                          FirstHVACIteration,
    2506             :                                          QUnitOut); // get QUnitOut with CWFlow; rest will be bypassed
    2507          31 :                         Node(FanCoil(FanCoilNum).CoolCoilFluidInletNode).MassFlowRate =
    2508             :                             MdotLockC; // reset flow to locked value. Since lock is on, must do this by hand
    2509          31 :                         Node(FanCoil(FanCoilNum).CoolCoilFluidOutletNodeNum).MassFlowRate = MdotLockC;
    2510             :                         // Keep soln flow rate but reset outlet water temperature - i.e. bypass extra water
    2511          31 :                         CWFlowBypass = MdotLockC - CWFlow;
    2512             :                         // change water outlet temperature and enthalpy
    2513          31 :                         Node(FanCoil(FanCoilNum).CoolCoilFluidOutletNodeNum).Temp =
    2514          62 :                             (CWFlowBypass * Node(FanCoil(FanCoilNum).CoolCoilFluidInletNode).Temp +
    2515          62 :                              CWFlow * Node(FanCoil(FanCoilNum).CoolCoilFluidOutletNodeNum).Temp) /
    2516             :                             MdotLockC;
    2517          31 :                         Node(FanCoil(FanCoilNum).CoolCoilFluidOutletNodeNum).Enthalpy =
    2518          62 :                             (CWFlowBypass * Node(FanCoil(FanCoilNum).CoolCoilFluidInletNode).Enthalpy +
    2519          62 :                              CWFlow * Node(FanCoil(FanCoilNum).CoolCoilFluidOutletNodeNum).Enthalpy) /
    2520             :                             MdotLockC;
    2521             :                     } else {
    2522             :                         // if MdotLockC <= CWFlow use MdotLockC as is
    2523          31 :                         Node(FanCoil(FanCoilNum).CoolCoilFluidInletNode).MassFlowRate =
    2524             :                             MdotLockC; // reset flow to locked value. Since lock is on, must do this by hand
    2525          31 :                         Node(FanCoil(FanCoilNum).CoolCoilFluidOutletNodeNum).MassFlowRate = MdotLockC;
    2526          31 :                         Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut);
    2527             :                     }
    2528             :                 }
    2529      151072 :                 QUnitOut = calcZoneSensibleOutput(AirMassFlow, Node(OutletNode).Temp, Node(InletNode).Temp, Node(InletNode).HumRat);
    2530             : 
    2531             :                 // if heating
    2532      246352 :             } else if (UnitOn && QCoilHeatSP > SmallLoad &&
    2533      116710 :                        state.dataHeatBalFanSys->TempControlType(ControlledZoneNum) != DataHVACGlobals::ThermostatType::SingleCooling) {
    2534             :                 // get full load result
    2535      113859 :                 if (FanCoil(FanCoilNum).HCoilType_Num == HCoil::Water) { // if HW Coil
    2536      113859 :                     ControlNode = FanCoil(FanCoilNum).HeatCoilFluidInletNode;
    2537      113859 :                     ControlOffset = FanCoil(FanCoilNum).HotControlOffset;
    2538      113859 :                     MaxWaterFlow = FanCoil(FanCoilNum).MaxHeatCoilFluidFlow;
    2539      113859 :                     MinWaterFlow = FanCoil(FanCoilNum).MinHotWaterFlow;
    2540             :                     // On the first HVAC iteration the system values are given to the controller, but after that
    2541             :                     // the demand limits are in place and there needs to be feedback to the Zone Equipment
    2542      113859 :                     if (!FirstHVACIteration) {
    2543       56921 :                         MaxWaterFlow = Node(ControlNode).MassFlowRateMaxAvail;
    2544       56921 :                         MinWaterFlow = Node(ControlNode).MassFlowRateMinAvail;
    2545             :                     }
    2546      113859 :                     mdot = MaxWaterFlow;
    2547      341577 :                     SetComponentFlowRate(state,
    2548             :                                          mdot,
    2549      113859 :                                          FanCoil(FanCoilNum).HeatCoilFluidInletNode,
    2550      113859 :                                          FanCoil(FanCoilNum).HeatCoilFluidOutletNodeNum,
    2551      113859 :                                          FanCoil(FanCoilNum).HeatCoilPlantLoc);
    2552      113859 :                     Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOutMaxH);
    2553      113859 :                     if (!HotFlowLocked) {
    2554      113823 :                         FanCoil(FanCoilNum).QUnitOutMaxH = QUnitOutMaxH;
    2555             :                     } else {
    2556          36 :                         QUnitOutMaxH = FanCoil(FanCoilNum).QUnitOutMaxH;
    2557          36 :                         MdotLockH = mdot; // save locked flow
    2558             :                     }
    2559             :                 } else {
    2560             :                     // not HW coil
    2561           0 :                     Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOutMaxH, 1.0);
    2562             :                 }
    2563      113859 :                 QZnReq = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlledZoneNum).RemainingOutputReqToHeatSP;
    2564      113859 :                 if (QUnitOutMaxH > QZnReq) {
    2565             :                     // more heating than required, find reduced water flow rate to meet the load
    2566      113275 :                     if (FanCoil(FanCoilNum).HCoilType_Num == HCoil::Water) {
    2567             :                         // solve for the hot water flow rate with no limit set by flow rate lockdown
    2568     9327966 :                         auto f = [&state, FirstHVACIteration, FanCoilNum, ControlledZoneNum, QZnReq](Real64 HWFlow) {
    2569             :                             // To calculate the part-load ratio for the FCU with electric heating coil
    2570             :                             Real64 QUnitOut; // delivered capacity [W]
    2571     4145968 :                             state.dataLoopNodes->Node(state.dataFanCoilUnits->FanCoil(FanCoilNum).HeatCoilFluidInletNode).MassFlowRate = HWFlow;
    2572     3109476 :                             Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut, 1.0);
    2573             :                             // Calculate residual based on output magnitude
    2574     1036492 :                             if (std::abs(QZnReq) <= 100.0) {
    2575         924 :                                 return (QUnitOut - QZnReq) / 100.0;
    2576             :                             } else {
    2577     3108090 :                                 return (QUnitOut - QZnReq) / QZnReq;
    2578             :                             }
    2579      113275 :                         };
    2580      113275 :                         General::SolveRoot(state, 0.001, MaxIterCycl, SolFlag, HWFlow, f, 0.0, MaxWaterFlow);
    2581      113275 :                         if (SolFlag == -1) {
    2582             :                             // tighten limits on water flow rate to see if this allows convergence
    2583           0 :                             state.dataFanCoilUnits->CoolingLoad = false;
    2584           0 :                             state.dataFanCoilUnits->HeatingLoad = true;
    2585           0 :                             TightenWaterFlowLimits(state,
    2586             :                                                    FanCoilNum,
    2587           0 :                                                    state.dataFanCoilUnits->CoolingLoad,
    2588           0 :                                                    state.dataFanCoilUnits->HeatingLoad,
    2589           0 :                                                    FanCoil(FanCoilNum).HeatCoilFluidInletNode,
    2590             :                                                    ControlledZoneNum,
    2591             :                                                    FirstHVACIteration,
    2592             :                                                    QZnReq,
    2593             :                                                    MinWaterFlow,
    2594             :                                                    MaxWaterFlow);
    2595           0 :                             General::SolveRoot(state, 0.001, MaxIterCycl, SolFlag, HWFlow, f, MinWaterFlow, MaxWaterFlow);
    2596           0 :                             if (SolFlag == -1) {
    2597           0 :                                 ++FanCoil(FanCoilNum).ConvgErrCountH;
    2598           0 :                                 if (FanCoil(FanCoilNum).ConvgErrCountH < 2) {
    2599           0 :                                     ShowWarningError(state, "Hot Water control failed in fan coil unit " + FanCoil(FanCoilNum).Name);
    2600           0 :                                     ShowContinueError(state, "  Iteration limit exceeded in calculating water flow rate ");
    2601           0 :                                     Node(FanCoil(FanCoilNum).HeatCoilFluidInletNode).MassFlowRate = HWFlow;
    2602           0 :                                     Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut);
    2603           0 :                                     ShowContinueErrorTimeStamp(state, format("Load Request = {}, Final Capacity = {}", QZnReq, QUnitOut));
    2604           0 :                                     ShowContinueErrorTimeStamp(
    2605             :                                         state,
    2606           0 :                                         format("Min water flow used during iterations = {}, Max water flow used during iterations = {}",
    2607             :                                                MinWaterFlow,
    2608           0 :                                                MaxWaterFlow));
    2609           0 :                                     ShowContinueErrorTimeStamp(state, format("Water flow rate on last iteration = {}", HWFlow));
    2610           0 :                                     ShowContinueErrorTimeStamp(state, "..Water flow rate set to last iteration value ");
    2611             :                                 } else {
    2612           0 :                                     ShowRecurringWarningErrorAtEnd(state,
    2613           0 :                                                                    "Hot water flow Iteration limit exceeded in fan coil unit " +
    2614           0 :                                                                        FanCoil(FanCoilNum).Name,
    2615           0 :                                                                    FanCoil(FanCoilNum).MaxIterIndexH);
    2616             :                                 }
    2617           0 :                             } else if (SolFlag == -2) {
    2618           0 :                                 ++FanCoil(FanCoilNum).LimitErrCountH;
    2619           0 :                                 if (FanCoil(FanCoilNum).LimitErrCountH < 2) {
    2620           0 :                                     ShowWarningError(state, "Hot Water control failed in fan coil unit " + FanCoil(FanCoilNum).Name);
    2621           0 :                                     ShowContinueError(state, "  Bad hot water mass flow limits");
    2622           0 :                                     ShowContinueErrorTimeStamp(state, "..Water flow rate set to lower limit ");
    2623             :                                 } else {
    2624           0 :                                     ShowRecurringWarningErrorAtEnd(state,
    2625           0 :                                                                    "Hot Water control failed in fan coil unit " + FanCoil(FanCoilNum).Name,
    2626           0 :                                                                    FanCoil(FanCoilNum).BadMassFlowLimIndexH);
    2627             :                                 }
    2628             :                             }
    2629      113275 :                         } else if (SolFlag == -2) {
    2630           0 :                             ++FanCoil(FanCoilNum).LimitErrCountH;
    2631           0 :                             if (FanCoil(FanCoilNum).LimitErrCountH < 2) {
    2632           0 :                                 ShowWarningError(state, "Hot Water control failed in fan coil unit " + FanCoil(FanCoilNum).Name);
    2633           0 :                                 ShowContinueError(state, "  Bad hot water mass flow limits");
    2634           0 :                                 ShowContinueErrorTimeStamp(state, "..Water flow rate set to lower limit ");
    2635             :                             } else {
    2636           0 :                                 ShowRecurringWarningErrorAtEnd(state,
    2637           0 :                                                                "Hot Water control failed in fan coil unit " + FanCoil(FanCoilNum).Name,
    2638           0 :                                                                FanCoil(FanCoilNum).BadMassFlowLimIndexH);
    2639             :                             }
    2640             :                         }
    2641             :                     } else {
    2642           0 :                         auto f = [&state, FirstHVACIteration, FanCoilNum, ControlledZoneNum, QZnReq](Real64 const PartLoadRatio) {
    2643           0 :                             return CalcFanCoilLoadResidual(state, FanCoilNum, FirstHVACIteration, ControlledZoneNum, QZnReq, PartLoadRatio);
    2644           0 :                         };
    2645           0 :                         General::SolveRoot(state, 0.001, MaxIterCycl, SolFlag, PLR, f, 0.0, 1.0);
    2646             :                     }
    2647             :                 } else {
    2648             :                     // demand greater than capacity
    2649         584 :                     if (FanCoil(FanCoilNum).HCoilType_Num == HCoil::Water) {
    2650         584 :                         HWFlow = MaxWaterFlow;
    2651             :                     } else {
    2652           0 :                         Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut, 1.0);
    2653             :                     }
    2654             :                 }
    2655      113859 :                 if (FanCoil(FanCoilNum).HCoilType_Num == HCoil::Water) {
    2656      113859 :                     if (!HotFlowLocked) {
    2657      113823 :                         mdot = HWFlow; // not flowlocked - set flow to HWFlow
    2658      341469 :                         SetComponentFlowRate(state,
    2659             :                                              mdot,
    2660      113823 :                                              FanCoil(FanCoilNum).HeatCoilFluidInletNode,
    2661      113823 :                                              FanCoil(FanCoilNum).HeatCoilFluidOutletNodeNum,
    2662      113823 :                                              FanCoil(FanCoilNum).HeatCoilPlantLoc);
    2663      113823 :                         Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut); // get QUnitOut
    2664             :                     } else {
    2665             :                         // flow lock on
    2666          36 :                         if (MdotLockH > HWFlow) { // if mdot > HWFlow, bypass extra flow
    2667          19 :                             Calc4PipeFanCoil(state,
    2668             :                                              FanCoilNum,
    2669             :                                              ControlledZoneNum,
    2670             :                                              FirstHVACIteration,
    2671             :                                              QUnitOut); // get QUnitOut with HWFlow; rest will be bypassed
    2672          19 :                             Node(FanCoil(FanCoilNum).HeatCoilFluidInletNode).MassFlowRate =
    2673             :                                 MdotLockH; // reset flow to locked value. Since lock is on, must do this by hand
    2674          19 :                             Node(FanCoil(FanCoilNum).HeatCoilFluidOutletNodeNum).MassFlowRate = MdotLockH;
    2675             :                             // Keep soln flow rate but reset outlet water temperature - i.e. bypass extra water
    2676          19 :                             HWFlowBypass = MdotLockH - HWFlow;
    2677             :                             // change outlet water temperature and enthalpy
    2678          19 :                             Node(FanCoil(FanCoilNum).HeatCoilFluidOutletNodeNum).Temp =
    2679          38 :                                 (HWFlowBypass * Node(FanCoil(FanCoilNum).HeatCoilFluidInletNode).Temp +
    2680          38 :                                  HWFlow * Node(FanCoil(FanCoilNum).HeatCoilFluidOutletNodeNum).Temp) /
    2681             :                                 MdotLockH;
    2682          19 :                             Node(FanCoil(FanCoilNum).HeatCoilFluidOutletNodeNum).Enthalpy =
    2683          38 :                                 (HWFlowBypass * Node(FanCoil(FanCoilNum).HeatCoilFluidInletNode).Enthalpy +
    2684          38 :                                  HWFlow * Node(FanCoil(FanCoilNum).HeatCoilFluidOutletNodeNum).Enthalpy) /
    2685             :                                 MdotLockH;
    2686             :                         } else {
    2687             :                             // if MdotLockH <= HWFlow use MdotLockH as is
    2688          17 :                             Node(FanCoil(FanCoilNum).HeatCoilFluidInletNode).MassFlowRate =
    2689             :                                 MdotLockH; // reset flow to locked value. Since lock is on, must do this by hand
    2690          17 :                             Node(FanCoil(FanCoilNum).HeatCoilFluidOutletNodeNum).MassFlowRate = MdotLockH;
    2691          17 :                             Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut);
    2692             :                         }
    2693             :                     }
    2694             :                 }
    2695      113859 :                 QUnitOut = calcZoneSensibleOutput(AirMassFlow, Node(OutletNode).Temp, Node(InletNode).Temp, Node(InletNode).HumRat);
    2696             :             } else {
    2697             :                 // no action
    2698       15783 :                 QUnitOut = QUnitOutNoHC;
    2699             :             }
    2700             : 
    2701             :             // CR9155 Remove specific humidity calculations
    2702      280714 :             SpecHumOut = Node(OutletNode).HumRat;
    2703      280714 :             SpecHumIn = Node(InletNode).HumRat;
    2704      280714 :             LatentOutput = AirMassFlow * (SpecHumOut - SpecHumIn); // Latent rate (kg/s), dehumid = negative
    2705      280714 :             QTotUnitOut = AirMassFlow * (Node(OutletNode).Enthalpy - Node(InletNode).Enthalpy);
    2706             :             // report variables
    2707      280714 :             FanCoil(FanCoilNum).HeatPower = max(0.0, QUnitOut);
    2708      280714 :             FanCoil(FanCoilNum).SensCoolPower = std::abs(min(DataPrecisionGlobals::constant_zero, QUnitOut));
    2709      280714 :             FanCoil(FanCoilNum).TotCoolPower = std::abs(min(DataPrecisionGlobals::constant_zero, QTotUnitOut));
    2710      280714 :             if (FanCoil(FanCoilNum).FanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
    2711      235012 :                 FanCoil(FanCoilNum).ElecPower = Fans::GetFanPower(state, FanCoil(FanCoilNum).FanIndex);
    2712             :             } else {
    2713       45702 :                 FanCoil(FanCoilNum).ElecPower = state.dataHVACFan->fanObjs[FanCoil(FanCoilNum).FanIndex]->fanPower();
    2714             :             }
    2715             : 
    2716      280714 :             PowerMet = QUnitOut;
    2717      280714 :             LatOutputProvided = LatentOutput;
    2718             : 
    2719             :             // cycling fan constant water flow AND VarFanVarFlow
    2720      280714 :         } break;
    2721      203855 :         case CCM::CycFan:
    2722             :         case CCM::VarFanVarFlow: {
    2723             : 
    2724      203855 :             if (state.dataZoneEnergyDemand->CurDeadBandOrSetback(ControlledZoneNum) || AirMassFlow < SmallMassFlow) UnitOn = false;
    2725             : 
    2726             :             // zero the hot & cold water flows
    2727      203855 :             mdot = 0.0;
    2728      611565 :             SetComponentFlowRate(state,
    2729             :                                  mdot,
    2730      203855 :                                  FanCoil(FanCoilNum).CoolCoilFluidInletNode,
    2731      203855 :                                  FanCoil(FanCoilNum).CoolCoilFluidOutletNodeNum,
    2732      203855 :                                  FanCoil(FanCoilNum).CoolCoilPlantLoc);
    2733      407710 :             if (state.dataPlnt->PlantLoop(FanCoil(FanCoilNum).CoolCoilPlantLoc.loopNum)
    2734      203855 :                     .LoopSide(FanCoil(FanCoilNum).CoolCoilPlantLoc.loopSideNum)
    2735      203855 :                     .FlowLock == DataPlant::FlowLock::Locked) {
    2736         156 :                 ColdFlowLocked = true; // check for flow lock
    2737             :             }
    2738      203855 :             if (FanCoil(FanCoilNum).HCoilType_Num == HCoil::Water) {
    2739      203855 :                 mdot = 0.0;
    2740      611565 :                 SetComponentFlowRate(state,
    2741             :                                      mdot,
    2742      203855 :                                      FanCoil(FanCoilNum).HeatCoilFluidInletNode,
    2743      203855 :                                      FanCoil(FanCoilNum).HeatCoilFluidOutletNodeNum,
    2744      203855 :                                      FanCoil(FanCoilNum).HeatCoilPlantLoc);
    2745      407710 :                 if (state.dataPlnt->PlantLoop(FanCoil(FanCoilNum).HeatCoilPlantLoc.loopNum)
    2746      203855 :                         .LoopSide(FanCoil(FanCoilNum).HeatCoilPlantLoc.loopSideNum)
    2747      203855 :                         .FlowLock == DataPlant::FlowLock::Locked) {
    2748         156 :                     HotFlowLocked = true; // save locked flow
    2749             :                 }
    2750             :             }
    2751             : 
    2752             :             // obtain unit output with no active heating/cooling
    2753      203855 :             Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOutNoHC, 0.0);
    2754             : 
    2755             :             // get the loads at the coil
    2756      203855 :             QCoilHeatSP = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlledZoneNum).RemainingOutputReqToHeatSP - QUnitOutNoHC;
    2757      203855 :             QCoilCoolSP = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlledZoneNum).RemainingOutputReqToCoolSP - QUnitOutNoHC;
    2758             : 
    2759             :             // speed fan selection only for multispeed cycling fan
    2760      203855 :             if (UnitOn && (FanCoil(FanCoilNum).CapCtrlMeth_Num == CCM::CycFan)) {
    2761      166228 :                 QZnReq = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlledZoneNum).RemainingOutputRequired;
    2762             : 
    2763             :                 // set water side mass flow rate
    2764      166228 :                 if (QCoilCoolSP < 0) {
    2765       91973 :                     Node(FanCoil(FanCoilNum).CoolCoilFluidInletNode).MassFlowRate = FanCoil(FanCoilNum).MaxCoolCoilFluidFlow;
    2766       74255 :                 } else if (QCoilHeatSP > 0 && FanCoil(FanCoilNum).HCoilType_Num != HCoil::Electric) {
    2767       74255 :                     Node(FanCoil(FanCoilNum).HeatCoilFluidInletNode).MassFlowRate = FanCoil(FanCoilNum).MaxHeatCoilFluidFlow;
    2768             :                 }
    2769             : 
    2770      166228 :                 Node(InletNode).MassFlowRateMax = FanCoil(FanCoilNum).LowSpeedRatio * FanCoil(FanCoilNum).MaxAirMassFlow;
    2771      166228 :                 FanCoil(FanCoilNum).SpeedFanSel = 1;
    2772      166228 :                 FanCoil(FanCoilNum).SpeedFanRatSel = FanCoil(FanCoilNum).LowSpeedRatio;
    2773      166228 :                 Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOutMax);
    2774      166228 :                 if (std::abs(QUnitOutMax) < std::abs(QZnReq)) {
    2775      120733 :                     Node(InletNode).MassFlowRateMax = FanCoil(FanCoilNum).MedSpeedRatio * FanCoil(FanCoilNum).MaxAirMassFlow;
    2776      120733 :                     FanCoil(FanCoilNum).SpeedFanSel = 2;
    2777      120733 :                     FanCoil(FanCoilNum).SpeedFanRatSel = FanCoil(FanCoilNum).MedSpeedRatio;
    2778      120733 :                     Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOutMax);
    2779             :                 }
    2780      166228 :                 if (std::abs(QUnitOutMax) < std::abs(QZnReq)) {
    2781       71800 :                     FanCoil(FanCoilNum).SpeedFanSel = 3;
    2782       71800 :                     FanCoil(FanCoilNum).SpeedFanRatSel = 1.0;
    2783       71800 :                     Node(InletNode).MassFlowRateMax = FanCoil(FanCoilNum).MaxAirMassFlow;
    2784             :                 }
    2785             :             } else {
    2786       37627 :                 FanCoil(FanCoilNum).SpeedFanSel = 0;
    2787             :             }
    2788             : 
    2789             :             // meet the coil load adjusted for fan operation
    2790      295092 :             if (UnitOn && QCoilCoolSP < (-1.0 * SmallLoad) &&
    2791       91237 :                 state.dataHeatBalFanSys->TempControlType(ControlledZoneNum) != DataHVACGlobals::ThermostatType::SingleHeating) {
    2792             :                 // cooling coil action, maximum cold water flow
    2793       91237 :                 mdot = FanCoil(FanCoilNum).MaxCoolCoilFluidFlow;
    2794      273711 :                 SetComponentFlowRate(state,
    2795             :                                      mdot,
    2796       91237 :                                      FanCoil(FanCoilNum).CoolCoilFluidInletNode,
    2797       91237 :                                      FanCoil(FanCoilNum).CoolCoilFluidOutletNodeNum,
    2798       91237 :                                      FanCoil(FanCoilNum).CoolCoilPlantLoc);
    2799             : 
    2800       91237 :                 QZnReq = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlledZoneNum).RemainingOutputReqToCoolSP;
    2801       91237 :                 ControlOffset = FanCoil(FanCoilNum).ColdControlOffset;
    2802             : 
    2803             :                 // get the maximum output of the fcu
    2804       91237 :                 Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOutMax); // call without PLR means PLR = 1
    2805             : 
    2806       91237 :                 if (QUnitOutMax < QZnReq) {
    2807             :                     // more cooling than required, find reduced air and water flow rate to meet the load
    2808             :                     // solve for the cold water flow rate with no limit set by flow rate lockdown
    2809     1402012 :                     auto f = [&state, FanCoilNum, FirstHVACIteration, ControlledZoneNum, &FanCoil, QZnReq](Real64 const PLR) {
    2810      701006 :                         return CalcFanCoilPLRResidual(
    2811      701006 :                             state, PLR, FanCoilNum, FirstHVACIteration, ControlledZoneNum, FanCoil(FanCoilNum).CoolCoilFluidInletNode, QZnReq);
    2812      425466 :                     };
    2813       74963 :                     General::SolveRoot(state, 0.001, MaxIterCycl, SolFlag, PLR, f, 0.0, 1.0);
    2814       74963 :                     if (SolFlag == -1) {
    2815             :                         // tighten limits on water flow rate to see if this allows convergence
    2816           0 :                         state.dataFanCoilUnits->CoolingLoad = true;
    2817           0 :                         state.dataFanCoilUnits->HeatingLoad = false;
    2818           0 :                         TightenAirAndWaterFlowLimits(state,
    2819             :                                                      FanCoilNum,
    2820           0 :                                                      state.dataFanCoilUnits->CoolingLoad,
    2821           0 :                                                      state.dataFanCoilUnits->HeatingLoad,
    2822           0 :                                                      FanCoil(FanCoilNum).CoolCoilFluidInletNode,
    2823             :                                                      ControlledZoneNum,
    2824             :                                                      FirstHVACIteration,
    2825             :                                                      QZnReq,
    2826             :                                                      PLRMin,
    2827             :                                                      PLRMax);
    2828           0 :                         General::SolveRoot(state, 0.001, MaxIterCycl, SolFlag, PLR, f, PLRMin, PLRMax);
    2829           0 :                         if (SolFlag == -1) {
    2830           0 :                             ++FanCoil(FanCoilNum).ConvgErrCountC;
    2831           0 :                             if (FanCoil(FanCoilNum).ConvgErrCountC < 2) {
    2832           0 :                                 ShowWarningError(state, "Part-load ratio cooling control failed in fan coil unit " + FanCoil(FanCoilNum).Name);
    2833           0 :                                 ShowContinueError(state, "  Iteration limit exceeded in calculating FCU part-load ratio ");
    2834           0 :                                 Node(FanCoil(FanCoilNum).CoolCoilFluidInletNode).MassFlowRate = PLR * FanCoil(FanCoilNum).MaxCoolCoilFluidFlow;
    2835           0 :                                 Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut, PLR);
    2836           0 :                                 ShowContinueErrorTimeStamp(state, format("Load Request = {}, Final Capacity = {}", QZnReq, QUnitOut));
    2837           0 :                                 ShowContinueErrorTimeStamp(
    2838             :                                     state,
    2839           0 :                                     format("Min part-load used during iterations = {}, Max part-load used during iterations = {}", PLRMin, PLRMax));
    2840           0 :                                 ShowContinueErrorTimeStamp(state, format("Part-load ratio on last iteration = {}", PLR));
    2841           0 :                                 ShowContinueErrorTimeStamp(state, "..Part-load ratio set to last iteration value ");
    2842             :                             } else {
    2843           0 :                                 ShowRecurringWarningErrorAtEnd(state,
    2844           0 :                                                                "Part-load ratio cooling iteration limit exceeded in fan coil unit " +
    2845           0 :                                                                    FanCoil(FanCoilNum).Name,
    2846           0 :                                                                FanCoil(FanCoilNum).MaxIterIndexC);
    2847             :                             }
    2848           0 :                         } else if (SolFlag == -2) {
    2849           0 :                             ++FanCoil(FanCoilNum).LimitErrCountC;
    2850           0 :                             if (FanCoil(FanCoilNum).LimitErrCountC < 2) {
    2851           0 :                                 ShowWarningError(state, "Part-load ratio cooling control failed in fan coil unit " + FanCoil(FanCoilNum).Name);
    2852           0 :                                 ShowContinueError(state, "  Bad part-load ratio limits");
    2853           0 :                                 ShowContinueErrorTimeStamp(state, format("..Part-load ratio set to {}", PLRMin));
    2854             :                             } else {
    2855           0 :                                 ShowRecurringWarningErrorAtEnd(state,
    2856           0 :                                                                "Part-load ratio cooling control failed in fan coil unit " + FanCoil(FanCoilNum).Name,
    2857           0 :                                                                FanCoil(FanCoilNum).BadMassFlowLimIndexC);
    2858             :                             }
    2859             :                         }
    2860       74963 :                     } else if (SolFlag == -2) {
    2861           0 :                         ++FanCoil(FanCoilNum).LimitErrCountC;
    2862           0 :                         if (FanCoil(FanCoilNum).LimitErrCountC < 2) {
    2863           0 :                             ShowWarningError(state, "Part-load ratio control failed in fan coil unit " + FanCoil(FanCoilNum).Name);
    2864           0 :                             ShowContinueError(state, "  Bad part-load ratio limits");
    2865           0 :                             ShowContinueErrorTimeStamp(state, "..Part-load ratio set to 0");
    2866             :                         } else {
    2867           0 :                             ShowRecurringWarningErrorAtEnd(state,
    2868           0 :                                                            "Part-load ratio control failed in fan coil unit " + FanCoil(FanCoilNum).Name,
    2869           0 :                                                            FanCoil(FanCoilNum).BadMassFlowLimIndexC);
    2870             :                         }
    2871             :                     }
    2872       74963 :                     mdot = PLR * FanCoil(FanCoilNum).MaxCoolCoilFluidFlow;
    2873      224889 :                     SetComponentFlowRate(state,
    2874             :                                          mdot,
    2875       74963 :                                          FanCoil(FanCoilNum).CoolCoilFluidInletNode,
    2876       74963 :                                          FanCoil(FanCoilNum).CoolCoilFluidOutletNodeNum,
    2877       74963 :                                          FanCoil(FanCoilNum).CoolCoilPlantLoc);
    2878             :                 } else {
    2879       16274 :                     PLR = 1.0;
    2880       16274 :                     mdot = PLR * FanCoil(FanCoilNum).MaxCoolCoilFluidFlow;
    2881       48822 :                     SetComponentFlowRate(state,
    2882             :                                          mdot,
    2883       16274 :                                          FanCoil(FanCoilNum).CoolCoilFluidInletNode,
    2884       16274 :                                          FanCoil(FanCoilNum).CoolCoilFluidOutletNodeNum,
    2885       16274 :                                          FanCoil(FanCoilNum).CoolCoilPlantLoc);
    2886             :                 }
    2887             : 
    2888             :                 // at the end calculate output
    2889       91237 :                 Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut, PLR);
    2890             : 
    2891      186873 :             } else if (UnitOn && QCoilHeatSP > SmallLoad &&
    2892       74255 :                        state.dataHeatBalFanSys->TempControlType(ControlledZoneNum) != DataHVACGlobals::ThermostatType::SingleCooling) {
    2893             :                 // heating coil action, maximun hot water flow
    2894             : 
    2895       74255 :                 if (FanCoil(FanCoilNum).HCoilType_Num == HCoil::Water) {
    2896       74255 :                     mdot = FanCoil(FanCoilNum).MaxHeatCoilFluidFlow;
    2897      222765 :                     SetComponentFlowRate(state,
    2898             :                                          mdot,
    2899       74255 :                                          FanCoil(FanCoilNum).HeatCoilFluidInletNode,
    2900       74255 :                                          FanCoil(FanCoilNum).HeatCoilFluidOutletNodeNum,
    2901       74255 :                                          FanCoil(FanCoilNum).HeatCoilPlantLoc);
    2902             :                 }
    2903             : 
    2904       74255 :                 QZnReq = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlledZoneNum).RemainingOutputReqToHeatSP;
    2905       74255 :                 ControlOffset = FanCoil(FanCoilNum).HotControlOffset;
    2906             : 
    2907             :                 // get the maximum output of the fcu
    2908       74255 :                 Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOutMax);
    2909             :                 // calculate the PLR, if load greater than output, PLR = 1 (output = max)
    2910       74255 :                 if (QUnitOutMax > QZnReq) {
    2911             :                     // more heating than required, find reduced water flow rate to meet the load
    2912       70799 :                     if (FanCoil(FanCoilNum).HCoilType_Num == HCoil::Water) {
    2913             :                         // solve for the hot water flow rate with no limit set by flow rate lockdown
    2914     1291508 :                         auto f = [&state, FanCoilNum, FirstHVACIteration, ControlledZoneNum, &FanCoil, QZnReq](Real64 const PLR) {
    2915      645754 :                             return CalcFanCoilPLRResidual(
    2916      645754 :                                 state, PLR, FanCoilNum, FirstHVACIteration, ControlledZoneNum, FanCoil(FanCoilNum).HeatCoilFluidInletNode, QZnReq);
    2917      393676 :                         };
    2918       70799 :                         General::SolveRoot(state, 0.001, MaxIterCycl, SolFlag, PLR, f, 0.0, 1.0);
    2919       70799 :                         if (SolFlag == -1) {
    2920             :                             // tighten limits on water flow rate to see if this allows convergence
    2921           0 :                             state.dataFanCoilUnits->CoolingLoad = false;
    2922           0 :                             state.dataFanCoilUnits->HeatingLoad = true;
    2923           0 :                             TightenAirAndWaterFlowLimits(state,
    2924             :                                                          FanCoilNum,
    2925           0 :                                                          state.dataFanCoilUnits->CoolingLoad,
    2926           0 :                                                          state.dataFanCoilUnits->HeatingLoad,
    2927           0 :                                                          FanCoil(FanCoilNum).HeatCoilFluidInletNode,
    2928             :                                                          ControlledZoneNum,
    2929             :                                                          FirstHVACIteration,
    2930             :                                                          QZnReq,
    2931             :                                                          PLRMin,
    2932             :                                                          PLRMax);
    2933           0 :                             General::SolveRoot(state, 0.001, MaxIterCycl, SolFlag, PLR, f, PLRMin, PLRMax);
    2934           0 :                             if (SolFlag == -1) {
    2935           0 :                                 ++FanCoil(FanCoilNum).ConvgErrCountH;
    2936           0 :                                 if (FanCoil(FanCoilNum).ConvgErrCountH < 2) {
    2937           0 :                                     ShowWarningError(state, "Part-load ratio heating control failed in fan coil unit " + FanCoil(FanCoilNum).Name);
    2938           0 :                                     ShowContinueError(state, "  Iteration limit exceeded in calculating FCU part-load ratio ");
    2939           0 :                                     Node(FanCoil(FanCoilNum).HeatCoilFluidInletNode).MassFlowRate = PLR * FanCoil(FanCoilNum).MaxHeatCoilFluidFlow;
    2940           0 :                                     Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut, PLR);
    2941           0 :                                     ShowContinueErrorTimeStamp(state, format("Load Request = {}, Final Capacity = {}", QZnReq, QUnitOut));
    2942           0 :                                     ShowContinueErrorTimeStamp(
    2943             :                                         state,
    2944           0 :                                         format("Min part-load ratio used during iterations = {}, Max part-load used during iterations = {}",
    2945             :                                                PLRMin,
    2946           0 :                                                PLRMax));
    2947           0 :                                     ShowContinueErrorTimeStamp(state, format("Part-load ratio on last iteration = {}", PLR));
    2948           0 :                                     ShowContinueErrorTimeStamp(state, "..Part-load ratio set to last iteration value ");
    2949             :                                 } else {
    2950           0 :                                     ShowRecurringWarningErrorAtEnd(state,
    2951           0 :                                                                    "Part-load ratio heating iteration limit exceeded in fan coil unit " +
    2952           0 :                                                                        FanCoil(FanCoilNum).Name,
    2953           0 :                                                                    FanCoil(FanCoilNum).MaxIterIndexH);
    2954             :                                 }
    2955           0 :                             } else if (SolFlag == -2) {
    2956           0 :                                 ++FanCoil(FanCoilNum).LimitErrCountH;
    2957           0 :                                 if (FanCoil(FanCoilNum).LimitErrCountH < 2) {
    2958           0 :                                     ShowWarningError(state, "Part-load ratio heating control failed in fan coil unit " + FanCoil(FanCoilNum).Name);
    2959           0 :                                     ShowContinueError(state, "  Bad hot part-load ratio limits");
    2960           0 :                                     ShowContinueErrorTimeStamp(state, format("..Part-load ratio set to {}", PLRMin));
    2961             :                                 } else {
    2962           0 :                                     ShowRecurringWarningErrorAtEnd(state,
    2963           0 :                                                                    "Part-load ratio heating control failed in fan coil unit " +
    2964           0 :                                                                        FanCoil(FanCoilNum).Name,
    2965           0 :                                                                    FanCoil(FanCoilNum).BadMassFlowLimIndexH);
    2966             :                                 }
    2967             :                             }
    2968       70799 :                         } else if (SolFlag == -2) {
    2969           0 :                             ++FanCoil(FanCoilNum).LimitErrCountH;
    2970           0 :                             if (FanCoil(FanCoilNum).LimitErrCountH < 2) {
    2971           0 :                                 ShowWarningError(state, "Part-load ratio heating control failed in fan coil unit " + FanCoil(FanCoilNum).Name);
    2972           0 :                                 ShowContinueError(state, "  Bad part-load ratio limits");
    2973           0 :                                 ShowContinueErrorTimeStamp(state, "..Part-load ratio set to 0");
    2974             :                             } else {
    2975           0 :                                 ShowRecurringWarningErrorAtEnd(state,
    2976           0 :                                                                "Part-load ratio heating control failed in fan coil unit " + FanCoil(FanCoilNum).Name,
    2977           0 :                                                                FanCoil(FanCoilNum).BadMassFlowLimIndexH);
    2978             :                             }
    2979             :                         }
    2980       70799 :                         HWFlow = PLR * FanCoil(FanCoilNum).MaxHeatCoilFluidFlow;
    2981      212397 :                         SetComponentFlowRate(state,
    2982             :                                              HWFlow,
    2983       70799 :                                              FanCoil(FanCoilNum).HeatCoilFluidInletNode,
    2984       70799 :                                              FanCoil(FanCoilNum).HeatCoilFluidOutletNodeNum,
    2985       70799 :                                              FanCoil(FanCoilNum).HeatCoilPlantLoc);
    2986             : 
    2987             :                     } else {
    2988           0 :                         auto f = [&state, FirstHVACIteration, FanCoilNum, ControlledZoneNum, QZnReq](Real64 const PartLoadRatio) {
    2989           0 :                             return CalcFanCoilLoadResidual(state, FanCoilNum, FirstHVACIteration, ControlledZoneNum, QZnReq, PartLoadRatio);
    2990           0 :                         };
    2991           0 :                         General::SolveRoot(state, 0.001, MaxIterCycl, SolFlag, PLR, f, 0.0, 1.0);
    2992             :                     }
    2993             :                 } else {
    2994        3456 :                     PLR = 1.0;
    2995        3456 :                     if (FanCoil(FanCoilNum).HCoilType_Num == HCoil::Water) {
    2996        3456 :                         mdot = PLR * FanCoil(FanCoilNum).MaxHeatCoilFluidFlow;
    2997       10368 :                         SetComponentFlowRate(state,
    2998             :                                              mdot,
    2999        3456 :                                              FanCoil(FanCoilNum).HeatCoilFluidInletNode,
    3000        3456 :                                              FanCoil(FanCoilNum).HeatCoilFluidOutletNodeNum,
    3001        3456 :                                              FanCoil(FanCoilNum).HeatCoilPlantLoc);
    3002             :                     }
    3003             :                 }
    3004             : 
    3005             :                 // at the end calculate output with adjusted PLR
    3006       74255 :                 Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut, PLR);
    3007             : 
    3008             :             } else {
    3009             :                 // no action, zero the air flow rate, the unit is off
    3010       38363 :                 Node(InletNode).MassFlowRate = 0.0;
    3011       38363 :                 Node(OutletNode).MassFlowRate = 0.0;
    3012       38363 :                 FanCoil(FanCoilNum).SpeedFanSel = 0;
    3013       38363 :                 PLR = 0.0;
    3014       38363 :                 Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut, PLR);
    3015             :             }
    3016             : 
    3017      203855 :             AirMassFlow = Node(InletNode).MassFlowRate;
    3018             :             // CR9155 Remove specific humidity calculations
    3019      203855 :             SpecHumOut = Node(OutletNode).HumRat;
    3020      203855 :             SpecHumIn = Node(InletNode).HumRat;
    3021      203855 :             LatentOutput = AirMassFlow * (SpecHumOut - SpecHumIn); // Latent rate (kg/s), dehumid = negative
    3022      203855 :             QTotUnitOut = AirMassFlow * (Node(OutletNode).Enthalpy - Node(InletNode).Enthalpy);
    3023             :             // report variables
    3024      203855 :             FanCoil(FanCoilNum).HeatPower = max(0.0, QUnitOut);
    3025      203855 :             FanCoil(FanCoilNum).SensCoolPower = std::abs(min(DataPrecisionGlobals::constant_zero, QUnitOut));
    3026      203855 :             FanCoil(FanCoilNum).TotCoolPower = std::abs(min(DataPrecisionGlobals::constant_zero, QTotUnitOut));
    3027      203855 :             if (FanCoil(FanCoilNum).FanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
    3028      185095 :                 FanCoil(FanCoilNum).ElecPower = Fans::GetFanPower(state, FanCoil(FanCoilNum).FanIndex);
    3029             :             } else {
    3030       18760 :                 FanCoil(FanCoilNum).ElecPower = state.dataHVACFan->fanObjs[FanCoil(FanCoilNum).FanIndex]->fanPower();
    3031             :             }
    3032      203855 :             FanCoil(FanCoilNum).PLR = PLR;
    3033      203855 :             PowerMet = QUnitOut;
    3034      203855 :             LatOutputProvided = LatentOutput;
    3035             : 
    3036      203855 :         } break;
    3037       17247 :         case CCM::ASHRAE: {
    3038             : 
    3039       17247 :             if (AirMassFlow < SmallMassFlow) UnitOn = false;
    3040             : 
    3041             :             //  zero the hot & cold water flows
    3042       17247 :             mdot = 0.0;
    3043       51741 :             SetComponentFlowRate(state,
    3044             :                                  mdot,
    3045       17247 :                                  FanCoil(FanCoilNum).CoolCoilFluidInletNode,
    3046       17247 :                                  FanCoil(FanCoilNum).CoolCoilFluidOutletNodeNum,
    3047       17247 :                                  FanCoil(FanCoilNum).CoolCoilPlantLoc);
    3048             : 
    3049       17247 :             if (FanCoil(FanCoilNum).HCoilType_Num == HCoil::Water) {
    3050       11498 :                 mdot = 0.0;
    3051       34494 :                 SetComponentFlowRate(state,
    3052             :                                      mdot,
    3053       11498 :                                      FanCoil(FanCoilNum).HeatCoilFluidInletNode,
    3054       11498 :                                      FanCoil(FanCoilNum).HeatCoilFluidOutletNodeNum,
    3055       11498 :                                      FanCoil(FanCoilNum).HeatCoilPlantLoc);
    3056             :             }
    3057             : 
    3058       17247 :             OAMassFlow = 0.0;
    3059             : 
    3060             :             // determine minimum outdoor air flow rate
    3061       17247 :             if (FanCoil(FanCoilNum).DSOAPtr > 0 && FanCoil(FanCoilNum).OutsideAirNode > 0) {
    3062       17244 :                 OAVolumeFlowRate = DataSizing::calcDesignSpecificationOutdoorAir(state, FanCoil(FanCoilNum).DSOAPtr, ControlledZoneNum, true, true);
    3063       51732 :                 RhoAir = PsyRhoAirFnPbTdbW(state,
    3064       17244 :                                            Node(FanCoil(FanCoilNum).OutsideAirNode).Press,
    3065       17244 :                                            Node(FanCoil(FanCoilNum).OutsideAirNode).Temp,
    3066       17244 :                                            Node(FanCoil(FanCoilNum).OutsideAirNode).HumRat);
    3067       17244 :                 OAMassFlow = OAVolumeFlowRate * RhoAir;
    3068             :             }
    3069             : 
    3070       17247 :             MinSAMassFlowRate =
    3071       17247 :                 min(max(OAMassFlow, FanCoil(FanCoilNum).MaxAirMassFlow * FanCoil(FanCoilNum).LowSpeedRatio), FanCoil(FanCoilNum).MaxAirMassFlow);
    3072       17247 :             MaxSAMassFlowRate = FanCoil(FanCoilNum).MaxAirMassFlow;
    3073       17247 :             state.dataFanCoilUnits->HeatingLoad = false;
    3074       17247 :             state.dataFanCoilUnits->CoolingLoad = false;
    3075       17247 :             if (UnitOn) {
    3076       17223 :                 Node(InletNode).MassFlowRate = MinSAMassFlowRate;
    3077       17223 :                 FanCoil(FanCoilNum).MaxNoCoolHeatAirMassFlow = MinSAMassFlowRate;
    3078       17223 :                 FanCoil(FanCoilNum).MaxCoolAirMassFlow = MaxSAMassFlowRate;
    3079       17223 :                 FanCoil(FanCoilNum).MaxHeatAirMassFlow = MaxSAMassFlowRate;
    3080       17223 :                 FanCoil(FanCoilNum).LowSpeedCoolFanRatio = MinSAMassFlowRate / MaxSAMassFlowRate;
    3081       17223 :                 FanCoil(FanCoilNum).LowSpeedHeatFanRatio = MinSAMassFlowRate / MaxSAMassFlowRate;
    3082             : 
    3083       17223 :                 Calc4PipeFanCoil(state,
    3084             :                                  FanCoilNum,
    3085             :                                  ControlledZoneNum,
    3086             :                                  FirstHVACIteration,
    3087             :                                  QUnitOutNoHC,
    3088             :                                  0.0); // needs PLR=0 for electric heating coil, otherwise will run at full capacity
    3089             : 
    3090       17223 :                 QCoilCoolSP = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlledZoneNum).RemainingOutputReqToCoolSP;
    3091       17223 :                 QCoilHeatSP = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlledZoneNum).RemainingOutputReqToHeatSP;
    3092             : 
    3093       23649 :                 if (QCoilHeatSP > 0.0 && QCoilCoolSP > 0.0 &&
    3094        6426 :                     state.dataHeatBalFanSys->TempControlType(ControlledZoneNum) != DataHVACGlobals::ThermostatType::SingleCooling) {
    3095        6096 :                     QZnReq = QCoilHeatSP;
    3096        6096 :                     state.dataFanCoilUnits->HeatingLoad = true;
    3097       11457 :                 } else if (QCoilHeatSP > 0.0 && QCoilCoolSP > 0.0 &&
    3098         330 :                            state.dataHeatBalFanSys->TempControlType(ControlledZoneNum) == DataHVACGlobals::ThermostatType::SingleCooling) {
    3099         330 :                     QZnReq = 0.0;
    3100       21594 :                 } else if (QCoilHeatSP < 0.0 && QCoilCoolSP < 0.0 &&
    3101       10797 :                            state.dataHeatBalFanSys->TempControlType(ControlledZoneNum) != DataHVACGlobals::ThermostatType::SingleHeating) {
    3102       10692 :                     QZnReq = QCoilCoolSP;
    3103       10692 :                     state.dataFanCoilUnits->CoolingLoad = true;
    3104         210 :                 } else if (QCoilHeatSP < 0.0 && QCoilCoolSP < 0.0 &&
    3105         105 :                            state.dataHeatBalFanSys->TempControlType(ControlledZoneNum) == DataHVACGlobals::ThermostatType::SingleHeating) {
    3106         105 :                     QZnReq = 0.0;
    3107           0 :                 } else if (QCoilHeatSP <= 0.0 && QCoilCoolSP >= 0.0) {
    3108           0 :                     QZnReq = 0.0;
    3109             :                 }
    3110             :             }
    3111             : 
    3112       17247 :             if (state.dataFanCoilUnits->CoolingLoad) {
    3113             : 
    3114       10692 :                 Node(InletNode).MassFlowRate = MaxSAMassFlowRate;
    3115             : 
    3116       10692 :                 mdot = FanCoil(FanCoilNum).MaxCoolCoilFluidFlow;
    3117       32076 :                 SetComponentFlowRate(state,
    3118             :                                      mdot,
    3119       10692 :                                      FanCoil(FanCoilNum).CoolCoilFluidInletNode,
    3120       10692 :                                      FanCoil(FanCoilNum).CoolCoilFluidOutletNodeNum,
    3121       10692 :                                      FanCoil(FanCoilNum).CoolCoilPlantLoc);
    3122             : 
    3123        6555 :             } else if (state.dataFanCoilUnits->HeatingLoad) {
    3124             : 
    3125        6096 :                 Node(InletNode).MassFlowRate = MaxSAMassFlowRate;
    3126             : 
    3127        6096 :                 if (FanCoil(FanCoilNum).HCoilType_Num == HCoil::Water) {
    3128        4054 :                     mdot = FanCoil(FanCoilNum).MaxHeatCoilFluidFlow;
    3129       12162 :                     SetComponentFlowRate(state,
    3130             :                                          mdot,
    3131        4054 :                                          FanCoil(FanCoilNum).HeatCoilFluidInletNode,
    3132        4054 :                                          FanCoil(FanCoilNum).HeatCoilFluidOutletNodeNum,
    3133        4054 :                                          FanCoil(FanCoilNum).HeatCoilPlantLoc);
    3134             :                 }
    3135             :             }
    3136             : 
    3137       17247 :             Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOutMax);
    3138             : 
    3139       17247 :             if ((state.dataFanCoilUnits->CoolingLoad && QUnitOutMax < QZnReq) || (state.dataFanCoilUnits->HeatingLoad && QUnitOutMax > QZnReq)) {
    3140       32132 :                 if ((state.dataFanCoilUnits->CoolingLoad && QUnitOutNoHC < QZnReq) ||
    3141       22158 :                     (state.dataFanCoilUnits->HeatingLoad && QUnitOutNoHC > QZnReq)) {
    3142           0 :                     PLR = 0.0;
    3143           0 :                     FanCoil(FanCoilNum).FanPartLoadRatio = 0.0;       // set SZVAV model variable
    3144           0 :                     Node(InletNode).MassFlowRate = MinSAMassFlowRate; // = min air flow rate + ((max-min) air flow rate * FanPartLoadRatio)
    3145           0 :                     mdot = 0.0;
    3146           0 :                     SetComponentFlowRate(state,
    3147             :                                          mdot,
    3148           0 :                                          FanCoil(FanCoilNum).CoolCoilFluidInletNode,
    3149           0 :                                          FanCoil(FanCoilNum).CoolCoilFluidOutletNodeNum,
    3150           0 :                                          FanCoil(FanCoilNum).CoolCoilPlantLoc);
    3151             : 
    3152           0 :                     if (FanCoil(FanCoilNum).HCoilType_Num == HCoil::Water) {
    3153           0 :                         mdot = 0.0;
    3154           0 :                         SetComponentFlowRate(state,
    3155             :                                              mdot,
    3156           0 :                                              FanCoil(FanCoilNum).HeatCoilFluidInletNode,
    3157           0 :                                              FanCoil(FanCoilNum).HeatCoilFluidOutletNodeNum,
    3158           0 :                                              FanCoil(FanCoilNum).HeatCoilPlantLoc);
    3159             :                     }
    3160             :                 } else {
    3161       16066 :                     Real64 OnOffAirFlowRatio = 1.0;
    3162       16066 :                     bool HXUnitOn = false;
    3163       16066 :                     int AirLoopNum = 0;
    3164       16066 :                     DataHVACGlobals::CompressorOperation CompressorOnFlag = DataHVACGlobals::CompressorOperation::Off;
    3165       16066 :                     auto &SZVAVModel(FanCoil(FanCoilNum));
    3166             :                     // seems like passing these (arguments 2-n) as an array (similar to Par) would make this more uniform across different
    3167             :                     // models
    3168       48198 :                     SZVAVModel::calcSZVAVModel(state,
    3169             :                                                SZVAVModel,
    3170             :                                                FanCoilNum,
    3171             :                                                FirstHVACIteration,
    3172       16066 :                                                state.dataFanCoilUnits->CoolingLoad,
    3173       16066 :                                                state.dataFanCoilUnits->HeatingLoad,
    3174             :                                                QZnReq,
    3175             :                                                OnOffAirFlowRatio,
    3176             :                                                HXUnitOn,
    3177             :                                                AirLoopNum,
    3178             :                                                PLR,
    3179             :                                                CompressorOnFlag);
    3180             :                 }
    3181        2366 :             } else if ((state.dataFanCoilUnits->CoolingLoad && QUnitOutMax > QZnReq && QZnReq < 0.0) ||
    3182         467 :                        (state.dataFanCoilUnits->HeatingLoad && QUnitOutMax < QZnReq && QZnReq > 0.0)) {
    3183             :                 // load is larger than capacity, thus run the fancoil unit at full capacity
    3184         722 :                 PLR = 1.0;
    3185             :             }
    3186       17247 :             Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut, PLR);
    3187       17247 :             PowerMet = QUnitOut;
    3188       17247 :             AirMassFlow = Node(InletNode).MassFlowRate;
    3189             :             // CR9155 Remove specific humidity calculations
    3190       17247 :             SpecHumOut = Node(OutletNode).HumRat;
    3191       17247 :             SpecHumIn = Node(InletNode).HumRat;
    3192             :             // Latent rate (kg/s), dehumid = negative
    3193       17247 :             LatOutputProvided = AirMassFlow * (SpecHumOut - SpecHumIn);
    3194       17247 :             FanCoil(FanCoilNum).PLR = PLR;
    3195             : 
    3196             :             // cycling fan constant water flow AND VarFanVarFlow
    3197       17247 :         } break;
    3198           0 :         case CCM::VarFanConsFlow: {
    3199             : 
    3200           0 :             if (state.dataZoneEnergyDemand->CurDeadBandOrSetback(ControlledZoneNum) || AirMassFlow < SmallMassFlow) UnitOn = false;
    3201             : 
    3202             :             //  zero the hot & cold water flows
    3203             :             //    Node(FanCoil(FanCoilNum)%CoolCoilFluidInletNode)%MassFlowRate = 0.0
    3204             :             //    Node(FanCoil(FanCoilNum)%HeatCoilFluidInletNode)%MassFlowRate = 0.0
    3205           0 :             mdot = 0.0;
    3206           0 :             SetComponentFlowRate(state,
    3207             :                                  mdot,
    3208           0 :                                  FanCoil(FanCoilNum).CoolCoilFluidInletNode,
    3209           0 :                                  FanCoil(FanCoilNum).CoolCoilFluidOutletNodeNum,
    3210           0 :                                  FanCoil(FanCoilNum).CoolCoilPlantLoc);
    3211             : 
    3212           0 :             if (FanCoil(FanCoilNum).HCoilType_Num == HCoil::Water) {
    3213           0 :                 mdot = 0.0;
    3214           0 :                 SetComponentFlowRate(state,
    3215             :                                      mdot,
    3216           0 :                                      FanCoil(FanCoilNum).HeatCoilFluidInletNode,
    3217           0 :                                      FanCoil(FanCoilNum).HeatCoilFluidOutletNodeNum,
    3218           0 :                                      FanCoil(FanCoilNum).HeatCoilPlantLoc);
    3219             :             }
    3220           0 :             Calc4PipeFanCoil(state,
    3221             :                              FanCoilNum,
    3222             :                              ControlledZoneNum,
    3223             :                              FirstHVACIteration,
    3224             :                              QUnitOutNoHC,
    3225             :                              0.0); // needs PLR=0 for electric heating coil, otherwise will run at full capacity
    3226             : 
    3227           0 :             if (UnitOn && state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlledZoneNum).RemainingOutputReqToCoolSP < (-1.0 * SmallLoad) &&
    3228           0 :                 state.dataHeatBalFanSys->TempControlType(ControlledZoneNum) != DataHVACGlobals::ThermostatType::SingleHeating) {
    3229             :                 // cooling coil action, maximum cold water flow
    3230           0 :                 mdot = FanCoil(FanCoilNum).MaxCoolCoilFluidFlow;
    3231           0 :                 SetComponentFlowRate(state,
    3232             :                                      mdot,
    3233           0 :                                      FanCoil(FanCoilNum).CoolCoilFluidInletNode,
    3234           0 :                                      FanCoil(FanCoilNum).CoolCoilFluidOutletNodeNum,
    3235           0 :                                      FanCoil(FanCoilNum).CoolCoilPlantLoc);
    3236           0 :                 QZnReq = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlledZoneNum).RemainingOutputReqToCoolSP;
    3237           0 :                 ControlOffset = FanCoil(FanCoilNum).ColdControlOffset;
    3238             : 
    3239             :                 // get the maximum output of the fcu
    3240           0 :                 Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOutMax);
    3241             :                 // calculate the PLR, if load greater than output, PLR = 1 (output = max)
    3242           0 :                 if (QUnitOutMax != 0.0) PLR = std::abs(QZnReq / QUnitOutMax);
    3243           0 :                 if (PLR > 1.0) PLR = 1.0;
    3244             : 
    3245             :                 // adjust the PLR to meet the cooling load calling Calc4PipeFanCoil repeatedly with the PLR adjusted
    3246           0 :                 while (std::abs(Error) > ControlOffset && std::abs(AbsError) > SmallLoad && Iter < MaxIterCycl && PLR != 1.0) {
    3247           0 :                     Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut, PLR);
    3248           0 :                     Error = (QZnReq - QUnitOut) / QZnReq;
    3249           0 :                     AbsError = QZnReq - QUnitOut;
    3250           0 :                     DelPLR = (QZnReq - QUnitOut) / QUnitOutMax;
    3251           0 :                     PLR += Relax * DelPLR;
    3252           0 :                     PLR = max(0.0, min(1.0, PLR));
    3253           0 :                     ++Iter;
    3254           0 :                     if (Iter == 32) Relax = 0.5;
    3255           0 :                     if (Iter == 65) Relax = 0.25;
    3256             :                 }
    3257             : 
    3258             :                 // warning if not converged
    3259           0 :                 if (Iter > (MaxIterCycl - 1)) {
    3260           0 :                     if (FanCoil(FanCoilNum).MaxIterIndexC == 0) {
    3261           0 :                         ShowWarningMessage(state,
    3262           0 :                                            "ZoneHVAC:FourPipeFanCoil=\"" + FanCoil(FanCoilNum).Name +
    3263             :                                                "\" -- Exceeded max iterations while adjusting cycling fan sensible runtime to meet the zone load "
    3264             :                                                "within the cooling convergence tolerance.");
    3265           0 :                         ShowContinueErrorTimeStamp(state, format("Iterations={}", MaxIterCycl));
    3266             :                     }
    3267           0 :                     ShowRecurringWarningErrorAtEnd(state,
    3268           0 :                                                    "ZoneHVAC:FourPipeFanCoil=\"" + FanCoil(FanCoilNum).Name +
    3269             :                                                        "\"  -- Exceeded max iterations error (sensible runtime) continues...",
    3270           0 :                                                    FanCoil(FanCoilNum).MaxIterIndexC);
    3271             :                 }
    3272             : 
    3273             :                 // at the end calculate output with adjusted PLR
    3274           0 :                 Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut, PLR);
    3275             : 
    3276           0 :             } else if (UnitOn && state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlledZoneNum).RemainingOutputReqToHeatSP > SmallLoad &&
    3277           0 :                        state.dataHeatBalFanSys->TempControlType(ControlledZoneNum) != DataHVACGlobals::ThermostatType::SingleCooling) {
    3278             :                 // heating coil action, maximun hot water flow
    3279           0 :                 if (FanCoil(FanCoilNum).HCoilType_Num == HCoil::Water) {
    3280           0 :                     mdot = FanCoil(FanCoilNum).MaxHeatCoilFluidFlow;
    3281           0 :                     SetComponentFlowRate(state,
    3282             :                                          mdot,
    3283           0 :                                          FanCoil(FanCoilNum).HeatCoilFluidInletNode,
    3284           0 :                                          FanCoil(FanCoilNum).HeatCoilFluidOutletNodeNum,
    3285           0 :                                          FanCoil(FanCoilNum).HeatCoilPlantLoc);
    3286             :                 }
    3287           0 :                 QZnReq = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlledZoneNum).RemainingOutputReqToHeatSP;
    3288           0 :                 ControlOffset = FanCoil(FanCoilNum).HotControlOffset;
    3289             : 
    3290             :                 // get the maximum output of the fcu
    3291           0 :                 Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOutMax);
    3292             :                 // calculate the PLR, if load greater than output, PLR = 1 (output = max)
    3293           0 :                 if (QUnitOutMax != 0.0) PLR = std::abs(QZnReq / QUnitOutMax);
    3294           0 :                 if (PLR > 1.0) PLR = 1.0;
    3295             : 
    3296             :                 // adjust the PLR to meet the heating load calling Calc4PipeFanCoil repeatedly with the PLR adjusted
    3297           0 :                 while (std::abs(Error) > ControlOffset && std::abs(AbsError) > SmallLoad && Iter < MaxIterCycl && PLR != 1.0) {
    3298           0 :                     Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut, PLR);
    3299           0 :                     Error = (QZnReq - QUnitOut) / QZnReq;
    3300           0 :                     AbsError = QZnReq - QUnitOut;
    3301           0 :                     DelPLR = (QZnReq - QUnitOut) / QUnitOutMax;
    3302           0 :                     PLR += Relax * DelPLR;
    3303           0 :                     PLR = max(0.0, min(1.0, PLR));
    3304           0 :                     ++Iter;
    3305           0 :                     if (Iter == 32) Relax = 0.5;
    3306           0 :                     if (Iter == 65) Relax = 0.25;
    3307             :                 }
    3308             : 
    3309             :                 // warning if not converged
    3310           0 :                 if (Iter > (MaxIterCycl - 1)) {
    3311           0 :                     if (FanCoil(FanCoilNum).MaxIterIndexH == 0) {
    3312           0 :                         ShowWarningMessage(state,
    3313           0 :                                            "ZoneHVAC:FourPipeFanCoil=\"" + FanCoil(FanCoilNum).Name +
    3314             :                                                "\" -- Exceeded max iterations while adjusting cycling fan sensible runtime to meet the zone load "
    3315             :                                                "within the heating convergence tolerance.");
    3316           0 :                         ShowContinueError(state, format("...Requested zone load = {:.3T} [W]", QZnReq));
    3317           0 :                         ShowContinueError(state, format("...Fan coil capacity   = {:.3T} [W]", QUnitOut));
    3318           0 :                         ShowContinueErrorTimeStamp(state, format("Iterations={}", MaxIterCycl));
    3319             :                     }
    3320           0 :                     ShowRecurringWarningErrorAtEnd(state,
    3321           0 :                                                    "ZoneHVAC:FourPipeFanCoil=\"" + FanCoil(FanCoilNum).Name +
    3322             :                                                        "\"  -- Exceeded max iterations error (sensible runtime) continues...",
    3323           0 :                                                    FanCoil(FanCoilNum).MaxIterIndexH);
    3324             :                 }
    3325             : 
    3326             :                 // at the end calculate output with adjusted PLR
    3327           0 :                 Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut, PLR);
    3328             : 
    3329             :                 // this part of the code is just if we want ventilation in the deadband zone
    3330             :                 // ELSE IF (AirMassFlow .gt. 0.0d0) THEN
    3331             :                 // if fan scheduled available : just ventilation, PLR = 1
    3332             :                 // QUnitOut = QUnitOutNOHC
    3333             :                 // PLR = 1.
    3334             : 
    3335             :             } else {
    3336             :                 // no action, zero the air flow rate, the unit is off
    3337           0 :                 Node(InletNode).MassFlowRate = 0.0;
    3338           0 :                 Node(OutletNode).MassFlowRate = 0.0;
    3339           0 :                 FanCoil(FanCoilNum).SpeedFanSel = 0;
    3340           0 :                 PLR = 0.0;
    3341           0 :                 Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut, PLR);
    3342             :             }
    3343             : 
    3344           0 :             AirMassFlow = Node(InletNode).MassFlowRate;
    3345             :             // CR9155 Remove specific humidity calculations
    3346           0 :             SpecHumOut = Node(OutletNode).HumRat;
    3347           0 :             SpecHumIn = Node(InletNode).HumRat;
    3348           0 :             LatentOutput = AirMassFlow * (SpecHumOut - SpecHumIn); // Latent rate (kg/s), dehumid = negative
    3349           0 :             QSensUnitOutNoATM = calcZoneSensibleOutput(AirMassFlow, Node(OutletNode).Temp, Node(InletNode).Temp, Node(InletNode).HumRat);
    3350           0 :             QTotUnitOut = AirMassFlow * (Node(OutletNode).Enthalpy - Node(InletNode).Enthalpy);
    3351             :             // report variables
    3352           0 :             FanCoil(FanCoilNum).HeatPower = max(0.0, QSensUnitOutNoATM);
    3353           0 :             FanCoil(FanCoilNum).SensCoolPower = std::abs(min(DataPrecisionGlobals::constant_zero, QSensUnitOutNoATM));
    3354           0 :             FanCoil(FanCoilNum).TotCoolPower = std::abs(min(DataPrecisionGlobals::constant_zero, QTotUnitOut));
    3355           0 :             if (FanCoil(FanCoilNum).FanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
    3356           0 :                 FanCoil(FanCoilNum).ElecPower = Fans::GetFanPower(state, FanCoil(FanCoilNum).FanIndex);
    3357             :             } else {
    3358           0 :                 FanCoil(FanCoilNum).ElecPower = state.dataHVACFan->fanObjs[FanCoil(FanCoilNum).FanIndex]->fanPower();
    3359             :             }
    3360           0 :             FanCoil(FanCoilNum).PLR = PLR;
    3361           0 :             PowerMet = QUnitOut;
    3362           0 :             LatOutputProvided = LatentOutput;
    3363             : 
    3364           0 :         } break;
    3365       12375 :         case CCM::MultiSpeedFan: {
    3366             :             // call multi-speed fan staging calculation
    3367       12375 :             SimMultiStage4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut);
    3368       12375 :             AirMassFlow = Node(InletNode).MassFlowRate;
    3369       12375 :             SpecHumOut = Node(OutletNode).HumRat;
    3370       12375 :             SpecHumIn = Node(InletNode).HumRat;
    3371       12375 :             LatentOutput = AirMassFlow * (SpecHumOut - SpecHumIn); // Latent rate (kg/s), dehumid = negative
    3372       12375 :             QSensUnitOutNoATM = calcZoneSensibleOutput(AirMassFlow, Node(OutletNode).Temp, Node(InletNode).Temp, Node(InletNode).HumRat);
    3373       12375 :             QTotUnitOut = AirMassFlow * (Node(OutletNode).Enthalpy - Node(InletNode).Enthalpy);
    3374             :             // report variables
    3375       12375 :             FanCoil(FanCoilNum).HeatPower = max(0.0, QSensUnitOutNoATM);
    3376       12375 :             FanCoil(FanCoilNum).SensCoolPower = std::abs(min(DataPrecisionGlobals::constant_zero, QSensUnitOutNoATM));
    3377       12375 :             FanCoil(FanCoilNum).TotCoolPower = std::abs(min(DataPrecisionGlobals::constant_zero, QTotUnitOut));
    3378       12375 :             if (FanCoil(FanCoilNum).FanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
    3379           0 :                 FanCoil(FanCoilNum).ElecPower = Fans::GetFanPower(state, FanCoil(FanCoilNum).FanIndex);
    3380             :             } else {
    3381       12375 :                 FanCoil(FanCoilNum).ElecPower = state.dataHVACFan->fanObjs[FanCoil(FanCoilNum).FanIndex]->fanPower();
    3382             :             }
    3383       12375 :             PowerMet = QUnitOut;
    3384       12375 :             LatOutputProvided = LatentOutput;
    3385       12375 :         } break;
    3386           0 :         default:
    3387           0 :             break;
    3388             :         }
    3389      514191 :     }
    3390             : 
    3391           0 :     void TightenWaterFlowLimits(EnergyPlusData &state,
    3392             :                                 int const FanCoilNum,          // Unit index in fan coil array
    3393             :                                 bool const CoolingLoad,        // true if zone requires cooling
    3394             :                                 bool const HeatingLoad,        // true if zone requires heating
    3395             :                                 int const WaterControlNode,    // water control node, either cold or hot water
    3396             :                                 int const ControlledZoneNum,   // controlling zone index
    3397             :                                 bool const FirstHVACIteration, //  TRUE if 1st HVAC simulation of system timestep
    3398             :                                 Real64 const QZnReq,           // zone load [W]
    3399             :                                 Real64 &MinWaterFlow,          // minimum water flow rate
    3400             :                                 Real64 &MaxWaterFlow           // maximum water flow rate
    3401             :     )
    3402             :     {
    3403             : 
    3404             :         // SUBROUTINE INFORMATION:
    3405             :         //       AUTHOR         R. Raustad, FSEC
    3406             :         //       DATE WRITTEN   May 2016
    3407             : 
    3408             :         // PURPOSE OF THIS SUBROUTINE:
    3409             :         // Find tighter limits of water flow rate for fan coil unit.
    3410             : 
    3411             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    3412             :         Real64 QUnitOut; // fan coil delivered capacity [W]
    3413             :         Real64 mdot;     // water flow rate passed to fan coil unit [kg/s]
    3414             : 
    3415             :         // RegulaFalsi can reach max iteration when low water flow rate is required to meet load. Test at 10% of flow before iterating
    3416           0 :         mdot = MaxWaterFlow * 0.1;
    3417           0 :         state.dataLoopNodes->Node(WaterControlNode).MassFlowRate = mdot;
    3418           0 :         Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut);
    3419           0 :         if ((CoolingLoad && QUnitOut < QZnReq) || (HeatingLoad && QUnitOut > QZnReq)) {
    3420           0 :             MaxWaterFlow = mdot;
    3421             :             // RegulaFalsi can reach max iteration when low water flow rate is required to meet load. Test at 1% of flow before iterating
    3422           0 :             mdot *= 0.1;
    3423           0 :             state.dataLoopNodes->Node(WaterControlNode).MassFlowRate = mdot;
    3424           0 :             Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut);
    3425           0 :             if ((CoolingLoad && QUnitOut < QZnReq) || (HeatingLoad && QUnitOut > QZnReq)) {
    3426           0 :                 MaxWaterFlow = mdot;
    3427             :                 // RegulaFalsi can reach max iteration when low water flow rate is required to meet load. Test at 0.1% of flow before iterating
    3428           0 :                 mdot *= 0.1;
    3429           0 :                 state.dataLoopNodes->Node(WaterControlNode).MassFlowRate = mdot;
    3430           0 :                 Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut);
    3431           0 :                 if ((CoolingLoad && QUnitOut < QZnReq) || (HeatingLoad && QUnitOut > QZnReq)) {
    3432           0 :                     MaxWaterFlow = mdot;
    3433             :                     // RegulaFalsi can reach max iteration when low water flow rate is required to meet load. Test at 0.01% of flow before iterating
    3434           0 :                     mdot *= 0.1;
    3435           0 :                     state.dataLoopNodes->Node(WaterControlNode).MassFlowRate = mdot;
    3436           0 :                     Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut);
    3437           0 :                     if ((CoolingLoad && QUnitOut < QZnReq) || (HeatingLoad && QUnitOut > QZnReq)) {
    3438           0 :                         MaxWaterFlow = mdot;
    3439             :                         // RegulaFalsi can reach max iteration when low water flow rate is required to meet load. Test at 0.001% of flow before
    3440             :                         // iterating
    3441           0 :                         mdot *= 0.1;
    3442           0 :                         state.dataLoopNodes->Node(WaterControlNode).MassFlowRate = mdot;
    3443           0 :                         Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut);
    3444           0 :                         if ((CoolingLoad && QUnitOut < QZnReq) || (HeatingLoad && QUnitOut > QZnReq)) {
    3445           0 :                             MaxWaterFlow = mdot;
    3446             :                         } else {
    3447           0 :                             MinWaterFlow = mdot;
    3448             :                         }
    3449             :                     } else {
    3450           0 :                         MinWaterFlow = mdot;
    3451             :                     }
    3452             :                 } else {
    3453           0 :                     MinWaterFlow = mdot;
    3454             :                 }
    3455             :             } else {
    3456           0 :                 MinWaterFlow = mdot;
    3457             :             }
    3458             :         } else {
    3459           0 :             MinWaterFlow = mdot;
    3460             :         }
    3461           0 :     }
    3462             : 
    3463           0 :     void TightenAirAndWaterFlowLimits(EnergyPlusData &state,
    3464             :                                       int const FanCoilNum,          // Unit index in fan coil array
    3465             :                                       bool const CoolingLoad,        // true if zone requires cooling
    3466             :                                       bool const HeatingLoad,        // true if zone requires heating
    3467             :                                       int const WaterControlNode,    // water control node, either cold or hot water
    3468             :                                       int const ControlledZoneNum,   // controlling zone index
    3469             :                                       bool const FirstHVACIteration, //  TRUE if 1st HVAC simulation of system timestep
    3470             :                                       Real64 const QZnReq,           // zone load [W]
    3471             :                                       Real64 &PLRMin,                // minimum part-load ratio
    3472             :                                       Real64 &PLRMax                 // maximum part-load ratio
    3473             :     )
    3474             :     {
    3475             : 
    3476             :         // SUBROUTINE INFORMATION:
    3477             :         //       AUTHOR         R. Raustad, FSEC
    3478             :         //       DATE WRITTEN   August 2016
    3479             : 
    3480             :         // PURPOSE OF THIS SUBROUTINE:
    3481             :         // Find tighter limits of air and water flow rate for fan coil unit.
    3482             : 
    3483             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    3484             :         Real64 PLR;      // operating part-load ratio
    3485             :         Real64 QUnitOut; // fan coil delivered capacity [W]
    3486             : 
    3487           0 :         auto &FanCoil(state.dataFanCoilUnits->FanCoil);
    3488             : 
    3489             :         // RegulaFalsi can reach max iteration when low water flow rate is required to meet load. Test at 100% of flow before iterating
    3490           0 :         PLRMin = 0.0;
    3491           0 :         PLRMax = 1.0;
    3492           0 :         PLR = 1.0;
    3493           0 :         if (WaterControlNode == FanCoil(FanCoilNum).CoolCoilFluidInletNode) {
    3494           0 :             state.dataLoopNodes->Node(WaterControlNode).MassFlowRate = PLR * FanCoil(FanCoilNum).MaxCoolCoilFluidFlow;
    3495           0 :         } else if (WaterControlNode == FanCoil(FanCoilNum).HeatCoilFluidInletNode && FanCoil(FanCoilNum).HCoilType_Num != HCoil::Electric) {
    3496           0 :             state.dataLoopNodes->Node(WaterControlNode).MassFlowRate = PLR * FanCoil(FanCoilNum).MaxHeatCoilFluidFlow;
    3497             :         }
    3498           0 :         Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut, PLR);
    3499           0 :         if ((CoolingLoad && QUnitOut < QZnReq) || (HeatingLoad && QUnitOut > QZnReq)) {
    3500           0 :             PLRMax = PLR;
    3501           0 :             PLR *= 0.1;
    3502             :             // RegulaFalsi can reach max iteration when low water flow rate is required to meet load. Test at 10% of flow before iterating
    3503           0 :             if (WaterControlNode == FanCoil(FanCoilNum).CoolCoilFluidInletNode) {
    3504           0 :                 state.dataLoopNodes->Node(WaterControlNode).MassFlowRate = PLR * FanCoil(FanCoilNum).MaxCoolCoilFluidFlow;
    3505           0 :             } else if (WaterControlNode == FanCoil(FanCoilNum).HeatCoilFluidInletNode && FanCoil(FanCoilNum).HCoilType_Num != HCoil::Electric) {
    3506           0 :                 state.dataLoopNodes->Node(WaterControlNode).MassFlowRate = PLR * FanCoil(FanCoilNum).MaxHeatCoilFluidFlow;
    3507             :             }
    3508           0 :             Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut, PLR);
    3509           0 :             if ((CoolingLoad && QUnitOut < QZnReq) || (HeatingLoad && QUnitOut > QZnReq)) {
    3510           0 :                 PLRMax = PLR;
    3511           0 :                 PLR *= 0.1;
    3512             :                 // RegulaFalsi can reach max iteration when low water flow rate is required to meet load. Test at 1% of flow before iterating
    3513           0 :                 if (WaterControlNode == FanCoil(FanCoilNum).CoolCoilFluidInletNode) {
    3514           0 :                     state.dataLoopNodes->Node(WaterControlNode).MassFlowRate = PLR * FanCoil(FanCoilNum).MaxCoolCoilFluidFlow;
    3515           0 :                 } else if (WaterControlNode == FanCoil(FanCoilNum).HeatCoilFluidInletNode && FanCoil(FanCoilNum).HCoilType_Num != HCoil::Electric) {
    3516           0 :                     state.dataLoopNodes->Node(WaterControlNode).MassFlowRate = PLR * FanCoil(FanCoilNum).MaxHeatCoilFluidFlow;
    3517             :                 }
    3518           0 :                 Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut, PLR);
    3519           0 :                 if ((CoolingLoad && QUnitOut < QZnReq) || (HeatingLoad && QUnitOut > QZnReq)) {
    3520           0 :                     PLRMax = PLR;
    3521           0 :                     PLR *= 0.1;
    3522             :                     // RegulaFalsi can reach max iteration when low water flow rate is required to meet load. Test at 0.1% of flow before iterating
    3523           0 :                     if (WaterControlNode == FanCoil(FanCoilNum).CoolCoilFluidInletNode) {
    3524           0 :                         state.dataLoopNodes->Node(WaterControlNode).MassFlowRate = PLR * FanCoil(FanCoilNum).MaxCoolCoilFluidFlow;
    3525           0 :                     } else if (WaterControlNode == FanCoil(FanCoilNum).HeatCoilFluidInletNode &&
    3526           0 :                                FanCoil(FanCoilNum).HCoilType_Num != HCoil::Electric) {
    3527           0 :                         state.dataLoopNodes->Node(WaterControlNode).MassFlowRate = PLR * FanCoil(FanCoilNum).MaxHeatCoilFluidFlow;
    3528             :                     }
    3529           0 :                     if ((CoolingLoad && QUnitOut < QZnReq) || (HeatingLoad && QUnitOut > QZnReq)) {
    3530           0 :                         PLRMax = PLR;
    3531           0 :                         PLR *= 0.1;
    3532             :                         // RegulaFalsi can reach max iteration when low water flow rate is required to meet load. Test at 0.01% of flow before
    3533             :                         // iterating
    3534           0 :                         if (WaterControlNode == FanCoil(FanCoilNum).CoolCoilFluidInletNode) {
    3535           0 :                             state.dataLoopNodes->Node(WaterControlNode).MassFlowRate = PLR * FanCoil(FanCoilNum).MaxCoolCoilFluidFlow;
    3536           0 :                         } else if (WaterControlNode == FanCoil(FanCoilNum).HeatCoilFluidInletNode &&
    3537           0 :                                    FanCoil(FanCoilNum).HCoilType_Num != HCoil::Electric) {
    3538           0 :                             state.dataLoopNodes->Node(WaterControlNode).MassFlowRate = PLR * FanCoil(FanCoilNum).MaxHeatCoilFluidFlow;
    3539             :                         }
    3540           0 :                         if ((CoolingLoad && QUnitOut < QZnReq) || (HeatingLoad && QUnitOut > QZnReq)) {
    3541           0 :                             PLRMax = PLR;
    3542             :                         } else {
    3543           0 :                             PLRMin = PLR;
    3544             :                         }
    3545             :                     } else {
    3546           0 :                         PLRMin = PLR;
    3547             :                     }
    3548             :                 } else {
    3549           0 :                     PLRMin = PLR;
    3550             :                 }
    3551             :             } else {
    3552           0 :                 PLRMin = PLR;
    3553             :             }
    3554             :         } else {
    3555           0 :             PLRMin = PLR;
    3556             :         }
    3557           0 :     }
    3558             : 
    3559     5427232 :     void Calc4PipeFanCoil(EnergyPlusData &state,
    3560             :                           int const FanCoilNum,          // Unit index in fan coil array
    3561             :                           int const ControlledZoneNum,   // ZoneEquipConfig index
    3562             :                           bool const FirstHVACIteration, // flag for 1st HVAV iteration in the time step
    3563             :                           Real64 &LoadMet,               // load met by unit (watts)
    3564             :                           Optional<Real64> PLR,          // Part Load Ratio, fraction of time step fancoil is on
    3565             :                           Real64 eHeatCoilCyclingR       // electric heating coil cycling ratio  used with MultiSpeedFan capacity control
    3566             :     )
    3567             :     {
    3568             : 
    3569             :         // SUBROUTINE INFORMATION:
    3570             :         //       AUTHOR         Fred Buhl
    3571             :         //       DATE WRITTEN   March 2000
    3572             :         //       MODIFIED       July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
    3573             :         //       RE-ENGINEERED  na
    3574             : 
    3575             :         // PURPOSE OF THIS SUBROUTINE:
    3576             :         // Simulate the components making up the 4 pipe fan coil unit.
    3577             : 
    3578             :         // METHODOLOGY EMPLOYED:
    3579             :         // Simulates the unit components sequentially in the air flow direction.
    3580             : 
    3581             :         // REFERENCES:
    3582             :         // na
    3583             : 
    3584             :         // Using/Aliasing
    3585     5427232 :         auto &ZoneCompTurnFansOff = state.dataHVACGlobal->ZoneCompTurnFansOff;
    3586     5427232 :         auto &ZoneCompTurnFansOn = state.dataHVACGlobal->ZoneCompTurnFansOn;
    3587             :         using HeatingCoils::SimulateHeatingCoilComponents;
    3588             :         using HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil;
    3589             :         using MixedAir::SimOAMixer;
    3590             :         using Psychrometrics::PsyHFnTdbW;
    3591             :         using SingleDuct::SimATMixer;
    3592             :         using WaterCoils::SimulateWaterCoilComponents;
    3593             : 
    3594             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    3595             :         int OutletNode;                // unit air outlet node
    3596             :         int InletNode;                 // unit air inlet node
    3597             :         Real64 AirMassFlow;            // total mass flow through the unit
    3598             :         Real64 PartLoad;               // if PLR present PartLoad = PLR
    3599             :         Real64 OASchedValue;           // value of OASchedValue, =1 if not schedule
    3600     5427232 :         Real64 ElecHeaterControl(1.0); // 1 or 0, enables or disables heating coil
    3601             :         Real64 FanSpeedRatio;          // ratio of actual fan flow to max design fan flow
    3602             : 
    3603     5427232 :         auto &Node(state.dataLoopNodes->Node);
    3604     5427232 :         auto &FanCoil(state.dataFanCoilUnits->FanCoil);
    3605             : 
    3606             :         // if PLR present in arguments, get its value, else default PLR = 1
    3607     5427232 :         if (present(PLR)) {
    3608     4241277 :             PartLoad = PLR;
    3609             :         } else {
    3610     1185955 :             PartLoad = 1.0;
    3611             :         }
    3612             : 
    3613     5427232 :         OutletNode = FanCoil(FanCoilNum).AirOutNode;
    3614     5427232 :         InletNode = FanCoil(FanCoilNum).AirInNode;
    3615     5427232 :         state.dataFanCoilUnits->ZoneNode = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneNode;
    3616             : 
    3617             :         // Assume the unit is able to vary the flow. A cycling unit is treated as
    3618             :         // if it were variable flow, with the flow being the averaqe flow over the time step
    3619    16280940 :         if (((GetCurrentScheduleValue(state, FanCoil(FanCoilNum).SchedPtr) > 0.0 &&
    3620     5427232 :               GetCurrentScheduleValue(state, FanCoil(FanCoilNum).fanAvailSchIndex) > 0.0) ||
    3621    10854464 :              state.dataHVACGlobal->ZoneCompTurnFansOn) &&
    3622     5426476 :             !state.dataHVACGlobal->ZoneCompTurnFansOff) {
    3623     5423808 :             if (FanCoil(FanCoilNum).CapCtrlMeth_Num != CCM::ConsFanVarFlow) {
    3624     1919884 :                 if (FanCoil(FanCoilNum).CapCtrlMeth_Num != CCM::ASHRAE) Node(InletNode).MassFlowRate = PartLoad * Node(InletNode).MassFlowRateMax;
    3625             :             } else {
    3626     3503924 :                 Node(InletNode).MassFlowRate = Node(InletNode).MassFlowRateMax;
    3627             :             }
    3628             :         }
    3629             : 
    3630             :         // use the value of the outside air schedule if present
    3631     5427232 :         if (FanCoil(FanCoilNum).SchedOutAirPtr > 0) {
    3632     1024759 :             OASchedValue = GetCurrentScheduleValue(state, FanCoil(FanCoilNum).SchedOutAirPtr);
    3633             :         } else {
    3634     4402473 :             OASchedValue = 1.0;
    3635             :         }
    3636             : 
    3637     5427232 :         if (FanCoil(FanCoilNum).ATMixerExists) {
    3638      349032 :             state.dataFanCoilUnits->ATMixOutNode = FanCoil(FanCoilNum).ATMixerOutNode;
    3639      349032 :             if (FanCoil(FanCoilNum).ATMixerType == ATMixer_InletSide) {
    3640             :                 // set the primary air inlet mass flow rate
    3641      169646 :                 Node(FanCoil(FanCoilNum).ATMixerPriNode).MassFlowRate =
    3642      169646 :                     min(Node(FanCoil(FanCoilNum).ATMixerPriNode).MassFlowRateMaxAvail, Node(InletNode).MassFlowRate);
    3643             :                 // now calculate the the mixer outlet conditions (and the secondary air inlet flow rate)
    3644             :                 // the mixer outlet flow rate has already been set above (it is the "inlet" node flow rate)
    3645      169646 :                 SimATMixer(state, FanCoil(FanCoilNum).ATMixerName, FirstHVACIteration, FanCoil(FanCoilNum).ATMixerIndex);
    3646             :             }
    3647      349032 :             AirMassFlow = Node(InletNode).MassFlowRate;
    3648             :         } else {
    3649             :             // OutdoorAir:Mixer
    3650     5078200 :             if (FanCoil(FanCoilNum).CapCtrlMeth_Num == CCM::CycFan) {
    3651     1533543 :                 Node(FanCoil(FanCoilNum).OutsideAirNode).MassFlowRate =
    3652     1533543 :                     min(OASchedValue * Node(FanCoil(FanCoilNum).OutsideAirNode).MassFlowRateMax * PartLoad * FanCoil(FanCoilNum).SpeedFanRatSel,
    3653     1533543 :                         Node(InletNode).MassFlowRate);
    3654     3544657 :             } else if (FanCoil(FanCoilNum).CapCtrlMeth_Num == CCM::MultiSpeedFan) {
    3655      191980 :                 Node(FanCoil(FanCoilNum).OutsideAirNode).MassFlowRate =
    3656      191980 :                     min(OASchedValue * Node(FanCoil(FanCoilNum).OutsideAirNode).MassFlowRateMax * PartLoad * state.dataFanCoilUnits->FanFlowRatio,
    3657      191980 :                         Node(InletNode).MassFlowRate);
    3658             :             } else {
    3659     3352677 :                 if (FanCoil(FanCoilNum).CapCtrlMeth_Num != CCM::ConsFanVarFlow && FanCoil(FanCoilNum).CapCtrlMeth_Num != CCM::ASHRAE) {
    3660           0 :                     Node(FanCoil(FanCoilNum).OutsideAirNode).MassFlowRate =
    3661           0 :                         min(OASchedValue * Node(FanCoil(FanCoilNum).OutsideAirNode).MassFlowRateMax * PartLoad, Node(InletNode).MassFlowRate);
    3662             :                 } else {
    3663     3352677 :                     Node(FanCoil(FanCoilNum).OutsideAirNode).MassFlowRate =
    3664     3352677 :                         min(OASchedValue * Node(FanCoil(FanCoilNum).OutsideAirNode).MassFlowRateMax, Node(InletNode).MassFlowRate);
    3665             :                 }
    3666             :             }
    3667     5078200 :             Node(FanCoil(FanCoilNum).AirReliefNode).MassFlowRate = Node(FanCoil(FanCoilNum).OutsideAirNode).MassFlowRate;
    3668     5078200 :             AirMassFlow = Node(InletNode).MassFlowRate;
    3669     5078200 :             SimOAMixer(state, FanCoil(FanCoilNum).OAMixName, FirstHVACIteration, FanCoil(FanCoilNum).OAMixIndex);
    3670             :         }
    3671             : 
    3672     5427232 :         if (FanCoil(FanCoilNum).CapCtrlMeth_Num == CCM::CycFan) {
    3673             :             // cycling fan coil unit calculation
    3674     1533543 :             if (FanCoil(FanCoilNum).SpeedFanSel == 1) {
    3675      524766 :                 if (FanCoil(FanCoilNum).FanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
    3676     1612512 :                     Fans::SimulateFanComponents(state,
    3677      403128 :                                                 FanCoil(FanCoilNum).FanName,
    3678             :                                                 FirstHVACIteration,
    3679      403128 :                                                 FanCoil(FanCoilNum).FanIndex,
    3680      403128 :                                                 FanCoil(FanCoilNum).LowSpeedRatio,
    3681             :                                                 ZoneCompTurnFansOn,
    3682             :                                                 ZoneCompTurnFansOff);
    3683             :                 } else {
    3684      121638 :                     state.dataHVACFan->fanObjs[FanCoil(FanCoilNum).FanIndex]->simulate(state, _, ZoneCompTurnFansOn, ZoneCompTurnFansOff, _);
    3685             :                 }
    3686     1008777 :             } else if (FanCoil(FanCoilNum).SpeedFanSel == 2) {
    3687             : 
    3688      488967 :                 if (FanCoil(FanCoilNum).FanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
    3689     1910952 :                     Fans::SimulateFanComponents(state,
    3690      477738 :                                                 FanCoil(FanCoilNum).FanName,
    3691             :                                                 FirstHVACIteration,
    3692      477738 :                                                 FanCoil(FanCoilNum).FanIndex,
    3693      477738 :                                                 FanCoil(FanCoilNum).MedSpeedRatio,
    3694             :                                                 ZoneCompTurnFansOn,
    3695             :                                                 ZoneCompTurnFansOff);
    3696             :                 } else {
    3697       11229 :                     state.dataHVACFan->fanObjs[FanCoil(FanCoilNum).FanIndex]->simulate(state, _, ZoneCompTurnFansOn, ZoneCompTurnFansOff, _);
    3698             :                 }
    3699      519810 :             } else if (FanCoil(FanCoilNum).SpeedFanSel == 3) {
    3700             : 
    3701      443073 :                 if (FanCoil(FanCoilNum).FanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
    3702     1329219 :                     Fans::SimulateFanComponents(state,
    3703      443073 :                                                 FanCoil(FanCoilNum).FanName,
    3704             :                                                 FirstHVACIteration,
    3705      443073 :                                                 FanCoil(FanCoilNum).FanIndex,
    3706             :                                                 1.0,
    3707             :                                                 ZoneCompTurnFansOn,
    3708             :                                                 ZoneCompTurnFansOff);
    3709             :                 } else {
    3710           0 :                     state.dataHVACFan->fanObjs[FanCoil(FanCoilNum).FanIndex]->simulate(state, _, ZoneCompTurnFansOn, ZoneCompTurnFansOff, _);
    3711             :                 }
    3712             :             } else { // using 1.0 here for fan speed ratio seems wrong if FCU max flow rate is different than the fan maximum flow rate
    3713       76737 :                 if (FanCoil(FanCoilNum).FanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
    3714      201825 :                     Fans::SimulateFanComponents(state,
    3715       67275 :                                                 FanCoil(FanCoilNum).FanName,
    3716             :                                                 FirstHVACIteration,
    3717       67275 :                                                 FanCoil(FanCoilNum).FanIndex,
    3718             :                                                 0.0,
    3719             :                                                 ZoneCompTurnFansOn,
    3720             :                                                 ZoneCompTurnFansOff);
    3721             :                 } else {
    3722        9462 :                     state.dataHVACFan->fanObjs[FanCoil(FanCoilNum).FanIndex]->simulate(state, 0.0, ZoneCompTurnFansOn, ZoneCompTurnFansOff, _);
    3723             :                 }
    3724             :             }
    3725     1533543 :             if (FanCoil(FanCoilNum).CCoilType_Num == CCoil::HXAssist) {
    3726           0 :                 SimHXAssistedCoolingCoil(state,
    3727           0 :                                          FanCoil(FanCoilNum).CCoilName,
    3728             :                                          FirstHVACIteration,
    3729             :                                          DataHVACGlobals::CompressorOperation::On,
    3730             :                                          0.0,
    3731           0 :                                          FanCoil(FanCoilNum).CCoilName_Index,
    3732             :                                          ContFanCycCoil);
    3733             :             } else {
    3734     1533543 :                 SimulateWaterCoilComponents(state, FanCoil(FanCoilNum).CCoilName, FirstHVACIteration, FanCoil(FanCoilNum).CCoilName_Index, _, 1, PLR);
    3735             :             }
    3736     1533543 :             if (FanCoil(FanCoilNum).HCoilType_Num == HCoil::Water) {
    3737     1533543 :                 SimulateWaterCoilComponents(state, FanCoil(FanCoilNum).HCoilName, FirstHVACIteration, FanCoil(FanCoilNum).HCoilName_Index, _, 1, PLR);
    3738             :             } else {
    3739           0 :                 if (Node(FanCoil(FanCoilNum).CoolCoilFluidInletNode).MassFlowRate > 0.0) ElecHeaterControl = 0.0;
    3740           0 :                 SimulateHeatingCoilComponents(state,
    3741           0 :                                               FanCoil(FanCoilNum).HCoilName,
    3742             :                                               FirstHVACIteration,
    3743           0 :                                               FanCoil(FanCoilNum).DesignHeatingCapacity * PartLoad * ElecHeaterControl,
    3744           0 :                                               FanCoil(FanCoilNum).HCoilName_Index,
    3745             :                                               _,
    3746             :                                               false,
    3747             :                                               ContFanCycCoil,
    3748             :                                               PartLoad);
    3749             :             }
    3750             : 
    3751     3893689 :         } else if (FanCoil(FanCoilNum).CapCtrlMeth_Num == CCM::MultiSpeedFan) {
    3752      191980 :             if (FanCoil(FanCoilNum).FanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
    3753           0 :                 Fans::SimulateFanComponents(state,
    3754           0 :                                             FanCoil(FanCoilNum).FanName,
    3755             :                                             FirstHVACIteration,
    3756           0 :                                             FanCoil(FanCoilNum).FanIndex,
    3757           0 :                                             state.dataFanCoilUnits->FanFlowRatio,
    3758             :                                             ZoneCompTurnFansOn,
    3759             :                                             ZoneCompTurnFansOff);
    3760             :             } else {
    3761             :                 // FanFlowRatio needs to be accurate here for new fan model
    3762      191980 :                 Real64 ActFanFlowRatio = state.dataFanCoilUnits->FanFlowRatio * PartLoad;
    3763      191980 :                 state.dataHVACFan->fanObjs[FanCoil(FanCoilNum).FanIndex]->simulate(
    3764             :                     state, ActFanFlowRatio, ZoneCompTurnFansOn, ZoneCompTurnFansOff, _);
    3765             :             }
    3766      191980 :             if (FanCoil(FanCoilNum).CCoilType_Num == CCoil::HXAssist) {
    3767           0 :                 SimHXAssistedCoolingCoil(state,
    3768           0 :                                          FanCoil(FanCoilNum).CCoilName,
    3769             :                                          FirstHVACIteration,
    3770             :                                          DataHVACGlobals::CompressorOperation::On,
    3771             :                                          0.0,
    3772           0 :                                          FanCoil(FanCoilNum).CCoilName_Index,
    3773             :                                          ContFanCycCoil);
    3774             :             } else {
    3775      191980 :                 SimulateWaterCoilComponents(state, FanCoil(FanCoilNum).CCoilName, FirstHVACIteration, FanCoil(FanCoilNum).CCoilName_Index, _, 1, PLR);
    3776             :             }
    3777      191980 :             if (FanCoil(FanCoilNum).HCoilType_Num == HCoil::Water) {
    3778      191980 :                 SimulateWaterCoilComponents(state, FanCoil(FanCoilNum).HCoilName, FirstHVACIteration, FanCoil(FanCoilNum).HCoilName_Index, _, 1, PLR);
    3779             :             } else {
    3780           0 :                 if (Node(FanCoil(FanCoilNum).CoolCoilFluidInletNode).MassFlowRate > 0.0) ElecHeaterControl = 0.0;
    3781           0 :                 Real64 QZnReq = 0.0;
    3782           0 :                 if (FanCoil(FanCoilNum).FanOpMode == ContFanCycCoil) {
    3783           0 :                     QZnReq = FanCoil(FanCoilNum).DesignHeatingCapacity * state.dataFanCoilUnits->FanFlowRatio * eHeatCoilCyclingR * ElecHeaterControl;
    3784             :                 } else {
    3785             :                     // proportionally reduce the full flow capacity based on fan flow fraction
    3786           0 :                     QZnReq = FanCoil(FanCoilNum).DesignHeatingCapacity * state.dataFanCoilUnits->FanFlowRatio * PartLoad * eHeatCoilCyclingR *
    3787             :                              ElecHeaterControl;
    3788             :                 }
    3789           0 :                 SimulateHeatingCoilComponents(state,
    3790           0 :                                               FanCoil(FanCoilNum).HCoilName,
    3791             :                                               FirstHVACIteration,
    3792             :                                               QZnReq,
    3793           0 :                                               FanCoil(FanCoilNum).HCoilName_Index,
    3794             :                                               _,
    3795             :                                               false,
    3796           0 :                                               FanCoil(FanCoilNum).FanOpMode, // FanCoil(FanCoilNum).FanOpMode, // ContFanCycCoil, CycFanCycCoil
    3797             :                                               PartLoad);
    3798             :             }
    3799             :         } else { // capacity control method is VariableFanVariableFlow, VariableFanConstantFlow, or ASHRAE90.1
    3800             : 
    3801             :             // calculate fan speed ratio for Fan:OnOff or Fan:SystemModel (not used for other fan types). Only used in fan:OnOff model if performance
    3802             :             // curves are present.
    3803     3701709 :             FanSpeedRatio = Node(InletNode).MassFlowRate / (FanCoil(FanCoilNum).FanAirVolFlow * state.dataEnvrn->StdRhoAir);
    3804             : 
    3805             :             // Constant fan and variable flow calculation AND variable fan
    3806             : 
    3807     3701709 :             if (FanCoil(FanCoilNum).FanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
    3808     8929536 :                 Fans::SimulateFanComponents(state,
    3809     2976512 :                                             FanCoil(FanCoilNum).FanName,
    3810             :                                             FirstHVACIteration,
    3811     2976512 :                                             FanCoil(FanCoilNum).FanIndex,
    3812             :                                             FanSpeedRatio,
    3813             :                                             ZoneCompTurnFansOn,
    3814             :                                             ZoneCompTurnFansOff);
    3815             :             } else {
    3816      725197 :                 state.dataHVACFan->fanObjs[FanCoil(FanCoilNum).FanIndex]->simulate(state, FanSpeedRatio, ZoneCompTurnFansOn, ZoneCompTurnFansOff, _);
    3817             :             }
    3818             : 
    3819     3701709 :             if (FanCoil(FanCoilNum).CCoilType_Num == CCoil::HXAssist) {
    3820           0 :                 SimHXAssistedCoolingCoil(state,
    3821           0 :                                          FanCoil(FanCoilNum).CCoilName,
    3822             :                                          FirstHVACIteration,
    3823             :                                          DataHVACGlobals::CompressorOperation::On,
    3824             :                                          0.0,
    3825           0 :                                          FanCoil(FanCoilNum).CCoilName_Index,
    3826             :                                          ContFanCycCoil);
    3827             :             } else {
    3828     3701709 :                 SimulateWaterCoilComponents(state, FanCoil(FanCoilNum).CCoilName, FirstHVACIteration, FanCoil(FanCoilNum).CCoilName_Index);
    3829             :             }
    3830     3701709 :             if (FanCoil(FanCoilNum).HCoilType_Num == HCoil::Water) {
    3831     3647564 :                 SimulateWaterCoilComponents(state, FanCoil(FanCoilNum).HCoilName, FirstHVACIteration, FanCoil(FanCoilNum).HCoilName_Index);
    3832             :             } else {
    3833       54145 :                 if (Node(FanCoil(FanCoilNum).CoolCoilFluidInletNode).MassFlowRate > 0.0) ElecHeaterControl = 0.0;
    3834      270725 :                 SimulateHeatingCoilComponents(state,
    3835       54145 :                                               FanCoil(FanCoilNum).HCoilName,
    3836             :                                               FirstHVACIteration,
    3837      108290 :                                               FanCoil(FanCoilNum).DesignHeatingCapacity * PartLoad * ElecHeaterControl,
    3838       54145 :                                               FanCoil(FanCoilNum).HCoilName_Index,
    3839             :                                               _,
    3840             :                                               false,
    3841             :                                               ContFanCycCoil,
    3842             :                                               PartLoad);
    3843             :             }
    3844             :         }
    3845             : 
    3846     5427232 :         if (FanCoil(FanCoilNum).ATMixerExists) {
    3847      349032 :             if (FanCoil(FanCoilNum).ATMixerType == ATMixer_SupplySide) {
    3848             :                 // Now calculate the ATM mixer if it is on the supply side of the zone unit
    3849      179386 :                 SimATMixer(state, FanCoil(FanCoilNum).ATMixerName, FirstHVACIteration, FanCoil(FanCoilNum).ATMixerIndex);
    3850      538158 :                 LoadMet = calcZoneSensibleOutput(Node(state.dataFanCoilUnits->ATMixOutNode).MassFlowRate,
    3851      179386 :                                                  Node(state.dataFanCoilUnits->ATMixOutNode).Temp,
    3852      179386 :                                                  Node(state.dataFanCoilUnits->ZoneNode).Temp,
    3853      179386 :                                                  Node(state.dataFanCoilUnits->ZoneNode).HumRat);
    3854             :             } else {
    3855             :                 // ATM Mixer on inlet side
    3856      508938 :                 LoadMet = calcZoneSensibleOutput(
    3857      508938 :                     AirMassFlow, Node(OutletNode).Temp, Node(state.dataFanCoilUnits->ZoneNode).Temp, Node(state.dataFanCoilUnits->ZoneNode).HumRat);
    3858             :             }
    3859             :         } else {
    3860     5078200 :             LoadMet = calcZoneSensibleOutput(AirMassFlow, Node(OutletNode).Temp, Node(InletNode).Temp, Node(InletNode).HumRat);
    3861             :         }
    3862     5427232 :     }
    3863             : 
    3864       12375 :     void SimMultiStage4PipeFanCoil(EnergyPlusData &state,
    3865             :                                    int &FanCoilNum,               // number of the current fan coil unit being simulated
    3866             :                                    int const ZoneNum,             // number of zone being served
    3867             :                                    bool const FirstHVACIteration, // TRUE if 1st HVAC simulation of system timestep
    3868             :                                    Real64 &PowerMet               // Sensible power supplied (W)
    3869             :     )
    3870             :     {
    3871             : 
    3872             :         // SUBROUTINE INFORMATION:
    3873             :         //       AUTHOR         Bereket Nigusse
    3874             :         //       DATE WRITTEN   July 2015
    3875             :         //       MODIFIED       na
    3876             : 
    3877             :         // PURPOSE OF THIS SUBROUTINE:
    3878             :         // Manages multi-speed fancoil unit simulation;
    3879             : 
    3880             :         // METHODOLOGY EMPLOYED:
    3881             :         // Selects the appropriate fan speed for a given zone heating or cooling load
    3882             :         // and determines whether heating or cooling is required, then runs the hot
    3883             :         // or chilled water coils.
    3884             : 
    3885             :         // Using/Aliasing
    3886             :         using namespace DataZoneEnergyDemands;
    3887             :         using PlantUtilities::SetComponentFlowRate;
    3888             : 
    3889             :         // Locals
    3890             :         // SUBROUTINE ARGUMENT DEFINITIONS:
    3891             : 
    3892             :         // SUBROUTINE PARAMETER DEFINITIONS:
    3893             :         // int const MaxIterCycl( 100 );
    3894             : 
    3895             :         // INTERFACE BLOCK SPECIFICATIONS
    3896             : 
    3897             :         // DERIVED TYPE DEFINITIONS
    3898             :         // na
    3899             : 
    3900             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    3901             :         Real64 mdot;          // chilled or hot water flow rate through the water coils
    3902             :         Real64 QZnReq;        // heating or cooling needed by zone [watts]
    3903             :         Real64 QUnitOut;      // heating or sens. cooling provided by fan coil unit [watts]
    3904             :         Real64 QUnitOutMax;   // heating or sens. cooling provided by fan coil unit (running during an entire timestep)
    3905             :         Real64 QTotUnitOut;   // total unit output [watts]
    3906             :         Real64 AirMassFlow;   // air mass flow rate [kg/sec]
    3907             :         Real64 QUnitOutNoHC;  // unit output with no active heating or cooling [W]
    3908             :         Real64 QCoilHeatSP;   // coil load to the heating setpoint [W]
    3909             :         Real64 QCoilCoolSP;   // coil load to the cooling setpoint [W]
    3910             :         Real64 SpeedRatio;    // ratio between lower and higher fan speed
    3911             :         Real64 PartLoadRatio; // Part Load Ratio, fraction of time step fancoil is on
    3912             :         int OutletNode;       // unit air outlet node
    3913             :         int InletNode;        // unit air inlet node
    3914             :         bool UnitOn;          // TRUE if unit is on
    3915             : 
    3916       12375 :         auto &FanCoil(state.dataFanCoilUnits->FanCoil);
    3917       12375 :         auto &HeatingLoad(state.dataFanCoilUnits->HeatingLoad);
    3918       12375 :         auto &CoolingLoad(state.dataFanCoilUnits->CoolingLoad);
    3919             : 
    3920             :         // initialize local variables
    3921       12375 :         UnitOn = true;
    3922       12375 :         SpeedRatio = 0.0;
    3923       12375 :         PartLoadRatio = 0.0;
    3924       12375 :         QZnReq = 0.0;
    3925       12375 :         QUnitOut = 0.0;
    3926       12375 :         QTotUnitOut = 0.0;
    3927       12375 :         QUnitOutMax = 0.0;
    3928       12375 :         QUnitOutNoHC = 0.0;
    3929             : 
    3930       12375 :         OutletNode = FanCoil(FanCoilNum).AirOutNode;
    3931       12375 :         InletNode = FanCoil(FanCoilNum).AirInNode;
    3932       12375 :         AirMassFlow = state.dataLoopNodes->Node(InletNode).MassFlowRate;
    3933             : 
    3934       12375 :         if (state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum) || AirMassFlow < SmallMassFlow) UnitOn = false;
    3935             : 
    3936       12375 :         FanCoil(FanCoilNum).SpeedFanSel = 1;
    3937       12375 :         FanCoil(FanCoilNum).SpeedFanRatSel = FanCoil(FanCoilNum).LowSpeedRatio;
    3938       12375 :         state.dataFanCoilUnits->FanFlowRatio = FanCoil(FanCoilNum).SpeedFanRatSel;
    3939       12375 :         AirMassFlow = FanCoil(FanCoilNum).LowSpeedRatio * FanCoil(FanCoilNum).MaxAirMassFlow;
    3940       12375 :         state.dataLoopNodes->Node(InletNode).MassFlowRate = AirMassFlow;
    3941       12375 :         state.dataLoopNodes->Node(InletNode).MassFlowRateMax = AirMassFlow;
    3942       12375 :         state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = AirMassFlow;
    3943       12375 :         state.dataLoopNodes->Node(InletNode).MassFlowRateMinAvail = AirMassFlow;
    3944             : 
    3945       12375 :         if (FanCoil(FanCoilNum).HCoilType_Num == HCoil::Water) {
    3946       12375 :             mdot = 0.0;
    3947       37125 :             SetComponentFlowRate(state,
    3948             :                                  mdot,
    3949       12375 :                                  FanCoil(FanCoilNum).HeatCoilFluidInletNode,
    3950       12375 :                                  FanCoil(FanCoilNum).HeatCoilFluidOutletNodeNum,
    3951       12375 :                                  FanCoil(FanCoilNum).HeatCoilPlantLoc);
    3952             :         }
    3953       12375 :         mdot = 0.0;
    3954       37125 :         SetComponentFlowRate(state,
    3955             :                              mdot,
    3956       12375 :                              FanCoil(FanCoilNum).CoolCoilFluidInletNode,
    3957       12375 :                              FanCoil(FanCoilNum).CoolCoilFluidOutletNodeNum,
    3958       12375 :                              FanCoil(FanCoilNum).CoolCoilPlantLoc);
    3959             :         // no load output, requires setting eHeatCoilCyclingR = 0.0, for electric heating coils
    3960       12375 :         Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOutNoHC, _, 0.0);
    3961             : 
    3962       12375 :         QCoilCoolSP = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).RemainingOutputReqToCoolSP;
    3963       12375 :         QCoilHeatSP = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).RemainingOutputReqToHeatSP;
    3964       12375 :         state.dataFanCoilUnits->HeatingLoad = false;
    3965       12375 :         state.dataFanCoilUnits->CoolingLoad = false;
    3966             : 
    3967       18790 :         if (QCoilHeatSP > 0.0 && QCoilCoolSP > 0.0 &&
    3968        6415 :             state.dataHeatBalFanSys->TempControlType(ZoneNum) != DataHVACGlobals::ThermostatType::SingleCooling) {
    3969        6070 :             QZnReq = QCoilHeatSP;
    3970        6070 :             HeatingLoad = true;
    3971        6650 :         } else if (QCoilHeatSP > 0.0 && QCoilCoolSP > 0.0 &&
    3972         345 :                    state.dataHeatBalFanSys->TempControlType(ZoneNum) == DataHVACGlobals::ThermostatType::SingleCooling) {
    3973         345 :             QZnReq = 0.0;
    3974       11920 :         } else if (QCoilHeatSP < 0.0 && QCoilCoolSP < 0.0 &&
    3975        5960 :                    state.dataHeatBalFanSys->TempControlType(ZoneNum) != DataHVACGlobals::ThermostatType::SingleHeating) {
    3976        5811 :             QZnReq = QCoilCoolSP;
    3977        5811 :             CoolingLoad = true;
    3978         298 :         } else if (QCoilHeatSP < 0.0 && QCoilCoolSP < 0.0 &&
    3979         149 :                    state.dataHeatBalFanSys->TempControlType(ZoneNum) == DataHVACGlobals::ThermostatType::SingleHeating) {
    3980         149 :             QZnReq = 0.0;
    3981           0 :         } else if (QCoilHeatSP <= 0.0 && QCoilCoolSP >= 0.0) {
    3982           0 :             QZnReq = 0.0;
    3983             :         }
    3984             : 
    3985             :         // Zone load calculation for constant fan systems, adopted from unitary system
    3986       12375 :         if (FanCoil(FanCoilNum).FanOpMode == ContFanCycCoil) {
    3987        8236 :             switch (state.dataHeatBalFanSys->TempControlType(ZoneNum)) {
    3988        4146 :             case DataHVACGlobals::ThermostatType::SingleHeating: {
    3989        4146 :                 CoolingLoad = false;
    3990             :                 // No heating load and constant fan pushes zone below heating set point
    3991        4146 :                 if (QUnitOutNoHC < 0.0 && QCoilHeatSP < 0.0 && QUnitOutNoHC - QCoilHeatSP < -SmallLoad) {
    3992          14 :                     HeatingLoad = true;
    3993          14 :                     CoolingLoad = false;
    3994          14 :                     QZnReq = QCoilHeatSP;
    3995             :                 }
    3996        4146 :             } break;
    3997        4090 :             case DataHVACGlobals::ThermostatType::SingleCooling: {
    3998        4090 :                 HeatingLoad = false;
    3999             :                 // No heating load and constant fan pushes zone above cooling set point
    4000        4090 :                 if (QUnitOutNoHC > 0.0 && QCoilCoolSP > 0.0 && QUnitOutNoHC - QCoilCoolSP > SmallLoad) {
    4001           0 :                     HeatingLoad = false;
    4002           0 :                     CoolingLoad = true;
    4003           0 :                     QZnReq = QCoilCoolSP;
    4004             :                 }
    4005        4090 :             } break;
    4006           0 :             case DataHVACGlobals::ThermostatType::SingleHeatCool: {
    4007             :                 // zone temp above cooling and heating set point temps
    4008           0 :                 if (QCoilHeatSP < 0.0 && QCoilCoolSP < 0.0) {
    4009             :                     // zone pushed below heating set point
    4010           0 :                     if (QUnitOutNoHC < 0.0 && QCoilHeatSP - QUnitOutNoHC > SmallLoad) {
    4011           0 :                         HeatingLoad = true;
    4012           0 :                         CoolingLoad = false;
    4013           0 :                         QZnReq = QCoilHeatSP;
    4014             :                     }
    4015             :                     // zone temp below heating set point temp
    4016           0 :                 } else if (QCoilHeatSP > 0.0 && QCoilCoolSP > 0.0) {
    4017             :                     // zone pushed above cooling set point
    4018           0 :                     if (QUnitOutNoHC > 0.0 && QCoilCoolSP - QUnitOutNoHC > SmallLoad) {
    4019           0 :                         HeatingLoad = false;
    4020           0 :                         CoolingLoad = true;
    4021           0 :                         QZnReq = QCoilCoolSP;
    4022             :                     }
    4023             :                 }
    4024           0 :             } break;
    4025           0 :             case DataHVACGlobals::ThermostatType::DualSetPointWithDeadBand: {
    4026             :                 // zone temp above cooling and heating set point temps
    4027           0 :                 if (QCoilHeatSP < 0.0 && QCoilCoolSP < 0.0) {
    4028             :                     // zone pushed into deadband
    4029           0 :                     if (QUnitOutNoHC < 0.0 && QCoilCoolSP - QUnitOutNoHC > SmallLoad) {
    4030           0 :                         HeatingLoad = false;
    4031           0 :                         CoolingLoad = false;
    4032           0 :                         QZnReq = 0.0;
    4033             :                     }
    4034             :                     // zone pushed below heating set point
    4035           0 :                     if (QUnitOutNoHC < 0.0 && QCoilHeatSP - QUnitOutNoHC > SmallLoad) {
    4036           0 :                         HeatingLoad = true;
    4037           0 :                         CoolingLoad = false;
    4038           0 :                         QZnReq = QCoilHeatSP;
    4039             :                     }
    4040             :                     // zone temp below heating set point temp
    4041           0 :                 } else if (QCoilHeatSP > 0.0 && QCoilCoolSP > 0.0) {
    4042             :                     // zone pushed into deadband
    4043           0 :                     if (QUnitOutNoHC > 0.0 && QUnitOutNoHC - QCoilHeatSP > SmallLoad) {
    4044           0 :                         HeatingLoad = false;
    4045           0 :                         CoolingLoad = false;
    4046           0 :                         QZnReq = 0.0;
    4047             :                     }
    4048             :                     // zone pushed above cooling set point
    4049           0 :                     if (QUnitOutNoHC > 0.0 && QUnitOutNoHC - QCoilCoolSP > SmallLoad) {
    4050           0 :                         HeatingLoad = false;
    4051           0 :                         CoolingLoad = true;
    4052           0 :                         QZnReq = QCoilCoolSP;
    4053             :                     }
    4054             :                     // zone temp between set point temps
    4055           0 :                 } else if (QCoilHeatSP < 0.0 && QCoilCoolSP > 0.0) {
    4056             :                     // zone pushed below heating set point
    4057           0 :                     if (QUnitOutNoHC < 0.0 && QUnitOutNoHC - QCoilHeatSP < -SmallLoad) {
    4058           0 :                         HeatingLoad = true;
    4059           0 :                         CoolingLoad = false;
    4060           0 :                         QZnReq = QCoilHeatSP;
    4061             :                         // zone pushed above cooling set point
    4062           0 :                     } else if (QUnitOutNoHC > 0.0 && QUnitOutNoHC - QCoilCoolSP > SmallLoad) {
    4063           0 :                         HeatingLoad = false;
    4064           0 :                         CoolingLoad = true;
    4065           0 :                         QZnReq = QCoilCoolSP;
    4066             :                     }
    4067             :                 }
    4068           0 :             } break;
    4069           0 :             default:
    4070           0 :                 break;
    4071             :             }
    4072             :             // IF small loads to meet, just shut down unit
    4073        8236 :             if (std::abs(QZnReq) < FanCoilUnits::Small5WLoad) {
    4074         292 :                 QZnReq = 0.0;
    4075         292 :                 CoolingLoad = false;
    4076         292 :                 HeatingLoad = false;
    4077             :             }
    4078             :         }
    4079             : 
    4080       12375 :         if (UnitOn && QZnReq < (-1.0 * FanCoilUnits::Small5WLoad) && CoolingLoad) {
    4081        5808 :             if (FanCoil(FanCoilNum).HCoilType_Num == HCoil::Water) {
    4082        5808 :                 mdot = 0.0;
    4083       17424 :                 SetComponentFlowRate(state,
    4084             :                                      mdot,
    4085        5808 :                                      FanCoil(FanCoilNum).HeatCoilFluidInletNode,
    4086        5808 :                                      FanCoil(FanCoilNum).HeatCoilFluidOutletNodeNum,
    4087        5808 :                                      FanCoil(FanCoilNum).HeatCoilPlantLoc);
    4088             :             }
    4089        5808 :             mdot = FanCoil(FanCoilNum).MaxCoolCoilFluidFlow;
    4090       17424 :             SetComponentFlowRate(state,
    4091             :                                  mdot,
    4092        5808 :                                  FanCoil(FanCoilNum).CoolCoilFluidInletNode,
    4093        5808 :                                  FanCoil(FanCoilNum).CoolCoilFluidOutletNodeNum,
    4094        5808 :                                  FanCoil(FanCoilNum).CoolCoilPlantLoc);
    4095             :             // select fan speed
    4096        5808 :             FanCoil(FanCoilNum).SpeedFanSel = 1;
    4097        5808 :             FanCoil(FanCoilNum).SpeedFanRatSel = FanCoil(FanCoilNum).LowSpeedRatio;
    4098        5808 :             state.dataFanCoilUnits->FanFlowRatio = FanCoil(FanCoilNum).SpeedFanRatSel;
    4099        5808 :             AirMassFlow = FanCoil(FanCoilNum).LowSpeedRatio * FanCoil(FanCoilNum).MaxAirMassFlow;
    4100        5808 :             state.dataLoopNodes->Node(InletNode).MassFlowRate = AirMassFlow;
    4101        5808 :             state.dataLoopNodes->Node(InletNode).MassFlowRateMax = AirMassFlow;
    4102        5808 :             state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = AirMassFlow;
    4103        5808 :             state.dataLoopNodes->Node(InletNode).MassFlowRateMinAvail = AirMassFlow;
    4104        5808 :             Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOutMax);
    4105        5808 :             if (std::abs(QUnitOutMax) < std::abs(QZnReq)) {
    4106        3070 :                 FanCoil(FanCoilNum).SpeedFanSel = 2;
    4107        3070 :                 FanCoil(FanCoilNum).SpeedFanRatSel = FanCoil(FanCoilNum).MedSpeedRatio;
    4108        3070 :                 state.dataFanCoilUnits->FanFlowRatio = FanCoil(FanCoilNum).SpeedFanRatSel;
    4109        3070 :                 AirMassFlow = FanCoil(FanCoilNum).MedSpeedRatio * FanCoil(FanCoilNum).MaxAirMassFlow;
    4110        3070 :                 state.dataLoopNodes->Node(InletNode).MassFlowRate = AirMassFlow;
    4111        3070 :                 state.dataLoopNodes->Node(InletNode).MassFlowRateMax = AirMassFlow;
    4112        3070 :                 state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = AirMassFlow;
    4113        3070 :                 state.dataLoopNodes->Node(InletNode).MassFlowRateMinAvail = FanCoil(FanCoilNum).LowSpeedRatio * FanCoil(FanCoilNum).MaxAirMassFlow;
    4114        3070 :                 Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOutMax);
    4115             :             }
    4116        5808 :             if (std::abs(QUnitOutMax) < std::abs(QZnReq)) {
    4117        1626 :                 FanCoil(FanCoilNum).SpeedFanSel = 3;
    4118        1626 :                 FanCoil(FanCoilNum).SpeedFanRatSel = 1.0;
    4119        1626 :                 state.dataFanCoilUnits->FanFlowRatio = FanCoil(FanCoilNum).SpeedFanRatSel;
    4120        1626 :                 AirMassFlow = FanCoil(FanCoilNum).MaxAirMassFlow;
    4121        1626 :                 state.dataLoopNodes->Node(InletNode).MassFlowRate = AirMassFlow;
    4122        1626 :                 state.dataLoopNodes->Node(InletNode).MassFlowRateMax = AirMassFlow;
    4123        1626 :                 state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = AirMassFlow;
    4124        1626 :                 state.dataLoopNodes->Node(InletNode).MassFlowRateMinAvail = FanCoil(FanCoilNum).MedSpeedRatio * FanCoil(FanCoilNum).MaxAirMassFlow;
    4125             :             }
    4126        5808 :             CalcMultiStage4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QZnReq, SpeedRatio, PartLoadRatio, QUnitOut);
    4127             : 
    4128        6567 :         } else if (UnitOn && QZnReq > FanCoilUnits::Small5WLoad && HeatingLoad) {
    4129             : 
    4130        6070 :             mdot = 0.0;
    4131       18210 :             SetComponentFlowRate(state,
    4132             :                                  mdot,
    4133        6070 :                                  FanCoil(FanCoilNum).CoolCoilFluidInletNode,
    4134        6070 :                                  FanCoil(FanCoilNum).CoolCoilFluidOutletNodeNum,
    4135        6070 :                                  FanCoil(FanCoilNum).CoolCoilPlantLoc);
    4136             : 
    4137        6070 :             if (FanCoil(FanCoilNum).HCoilType_Num == HCoil::Water) {
    4138        6070 :                 mdot = FanCoil(FanCoilNum).MaxHeatCoilFluidFlow;
    4139       18210 :                 SetComponentFlowRate(state,
    4140             :                                      mdot,
    4141        6070 :                                      FanCoil(FanCoilNum).HeatCoilFluidInletNode,
    4142        6070 :                                      FanCoil(FanCoilNum).HeatCoilFluidOutletNodeNum,
    4143        6070 :                                      FanCoil(FanCoilNum).HeatCoilPlantLoc);
    4144             :             }
    4145             :             // select fan speed
    4146        6070 :             FanCoil(FanCoilNum).SpeedFanSel = 1;
    4147        6070 :             FanCoil(FanCoilNum).SpeedFanRatSel = FanCoil(FanCoilNum).LowSpeedRatio;
    4148        6070 :             state.dataFanCoilUnits->FanFlowRatio = FanCoil(FanCoilNum).SpeedFanRatSel;
    4149        6070 :             AirMassFlow = FanCoil(FanCoilNum).LowSpeedRatio * FanCoil(FanCoilNum).MaxAirMassFlow;
    4150        6070 :             state.dataLoopNodes->Node(InletNode).MassFlowRate = AirMassFlow;
    4151        6070 :             state.dataLoopNodes->Node(InletNode).MassFlowRateMax = AirMassFlow;
    4152        6070 :             state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = AirMassFlow;
    4153        6070 :             state.dataLoopNodes->Node(InletNode).MassFlowRateMinAvail = AirMassFlow;
    4154        6070 :             Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOutMax);
    4155        6070 :             if (std::abs(QUnitOutMax) < std::abs(QZnReq)) {
    4156        3212 :                 FanCoil(FanCoilNum).SpeedFanSel = 2;
    4157        3212 :                 FanCoil(FanCoilNum).SpeedFanRatSel = FanCoil(FanCoilNum).MedSpeedRatio;
    4158        3212 :                 state.dataFanCoilUnits->FanFlowRatio = FanCoil(FanCoilNum).SpeedFanRatSel;
    4159        3212 :                 AirMassFlow = FanCoil(FanCoilNum).MedSpeedRatio * FanCoil(FanCoilNum).MaxAirMassFlow;
    4160        3212 :                 state.dataLoopNodes->Node(InletNode).MassFlowRate = AirMassFlow;
    4161        3212 :                 state.dataLoopNodes->Node(InletNode).MassFlowRateMax = AirMassFlow;
    4162        3212 :                 state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = AirMassFlow;
    4163        3212 :                 state.dataLoopNodes->Node(InletNode).MassFlowRateMinAvail = FanCoil(FanCoilNum).LowSpeedRatio * FanCoil(FanCoilNum).MaxAirMassFlow;
    4164        3212 :                 Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOutMax);
    4165             :             }
    4166        6070 :             if (std::abs(QUnitOutMax) < std::abs(QZnReq)) {
    4167           0 :                 FanCoil(FanCoilNum).SpeedFanSel = 3;
    4168           0 :                 FanCoil(FanCoilNum).SpeedFanRatSel = 1.0;
    4169           0 :                 state.dataFanCoilUnits->FanFlowRatio = FanCoil(FanCoilNum).SpeedFanRatSel;
    4170           0 :                 AirMassFlow = FanCoil(FanCoilNum).MaxAirMassFlow;
    4171           0 :                 state.dataLoopNodes->Node(InletNode).MassFlowRate = AirMassFlow;
    4172           0 :                 state.dataLoopNodes->Node(InletNode).MassFlowRateMax = AirMassFlow;
    4173           0 :                 state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = AirMassFlow;
    4174           0 :                 state.dataLoopNodes->Node(InletNode).MassFlowRateMinAvail = FanCoil(FanCoilNum).MedSpeedRatio * FanCoil(FanCoilNum).MaxAirMassFlow;
    4175             :             }
    4176             : 
    4177        6070 :             CalcMultiStage4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QZnReq, SpeedRatio, PartLoadRatio, QUnitOut);
    4178             : 
    4179             :         } else {
    4180             :             // SpeedRatio = 0.0;
    4181         497 :             if (FanCoil(FanCoilNum).FanOpMode == ContFanCycCoil) {
    4182         308 :                 PartLoadRatio = 1.0;
    4183         308 :                 FanCoil(FanCoilNum).SpeedFanSel = 1;
    4184         308 :                 FanCoil(FanCoilNum).SpeedFanRatSel = FanCoil(FanCoilNum).LowSpeedRatio;
    4185         308 :                 state.dataFanCoilUnits->FanFlowRatio = FanCoil(FanCoilNum).SpeedFanRatSel;
    4186         308 :                 AirMassFlow = FanCoil(FanCoilNum).LowSpeedRatio * FanCoil(FanCoilNum).MaxAirMassFlow;
    4187         308 :                 state.dataLoopNodes->Node(InletNode).MassFlowRate = AirMassFlow;
    4188         308 :                 state.dataLoopNodes->Node(InletNode).MassFlowRateMax = AirMassFlow;
    4189         308 :                 state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = AirMassFlow;
    4190         308 :                 state.dataLoopNodes->Node(InletNode).MassFlowRateMinAvail = AirMassFlow;
    4191             :             } else {
    4192         189 :                 PartLoadRatio = 0.0;
    4193         189 :                 AirMassFlow = 0.0;
    4194         189 :                 state.dataLoopNodes->Node(InletNode).MassFlowRate = AirMassFlow;
    4195         189 :                 state.dataLoopNodes->Node(InletNode).MassFlowRateMax = AirMassFlow;
    4196         189 :                 state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = AirMassFlow;
    4197         189 :                 state.dataLoopNodes->Node(InletNode).MassFlowRateMinAvail = AirMassFlow;
    4198         189 :                 state.dataLoopNodes->Node(InletNode).MassFlowRate = 0.0;
    4199         189 :                 state.dataLoopNodes->Node(OutletNode).MassFlowRate = 0.0;
    4200         189 :                 FanCoil(FanCoilNum).SpeedFanSel = 0;
    4201         189 :                 state.dataFanCoilUnits->FanFlowRatio = 0.0;
    4202             :             }
    4203             : 
    4204         497 :             mdot = 0.0;
    4205         497 :             if (FanCoil(FanCoilNum).HCoilType_Num == HCoil::Water) {
    4206        1491 :                 SetComponentFlowRate(state,
    4207             :                                      mdot,
    4208         497 :                                      FanCoil(FanCoilNum).HeatCoilFluidInletNode,
    4209         497 :                                      FanCoil(FanCoilNum).HeatCoilFluidOutletNodeNum,
    4210         497 :                                      FanCoil(FanCoilNum).HeatCoilPlantLoc);
    4211             :             }
    4212        1491 :             SetComponentFlowRate(state,
    4213             :                                  mdot,
    4214         497 :                                  FanCoil(FanCoilNum).CoolCoilFluidInletNode,
    4215         497 :                                  FanCoil(FanCoilNum).CoolCoilFluidOutletNodeNum,
    4216         497 :                                  FanCoil(FanCoilNum).CoolCoilPlantLoc);
    4217             :             // No load output, eHeatCoilCyclingR = 0.0 for electric heating coil
    4218         497 :             Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOut, PartLoadRatio, 0.0);
    4219             :         }
    4220             :         // output variable
    4221       12375 :         state.dataLoopNodes->Node(OutletNode).MassFlowRate = state.dataLoopNodes->Node(InletNode).MassFlowRate;
    4222       12375 :         FanCoil(FanCoilNum).PLR = PartLoadRatio;
    4223       12375 :         FanCoil(FanCoilNum).SpeedRatio = SpeedRatio;
    4224       12375 :         PowerMet = QUnitOut;
    4225       12375 :     }
    4226             : 
    4227       11878 :     void CalcMultiStage4PipeFanCoil(EnergyPlusData &state,
    4228             :                                     int &FanCoilNum,               // number of the current fan coil unit being simulated
    4229             :                                     int const ZoneNum,             // number of zone being served
    4230             :                                     bool const FirstHVACIteration, // TRUE if 1st HVAC simulation of system timestep
    4231             :                                     Real64 const QZnReq,           // current zone cooling or heating load
    4232             :                                     Real64 &SpeedRatio,            // fan coil speed ratio
    4233             :                                     Real64 &PartLoadRatio,         // fan coil part load ratio
    4234             :                                     Real64 &PowerMet               // Sensible power supplied (W)
    4235             :     )
    4236             :     {
    4237             : 
    4238             :         // SUBROUTINE INFORMATION:
    4239             :         //       AUTHOR         Bereket Nigusse
    4240             :         //       DATE WRITTEN   July 2015
    4241             :         //       MODIFIED       na
    4242             : 
    4243             :         // PURPOSE OF THIS SUBROUTINE:
    4244             :         // Simulate a multi-stage fan 4 pipe fan coil unit; adjust its output to
    4245             :         // match the remaining zone load.
    4246             : 
    4247             :         // METHODOLOGY EMPLOYED:
    4248             :         // If this unit is on, calculated the speed ratio when cycling between
    4249             :         // consecutive fan speeds. The hot or chilled water flows either at
    4250             :         // maximum or zero.  The water flow rate is set to zero if there is no
    4251             :         // load.
    4252             : 
    4253             :         // Using/Aliasing
    4254             :         using namespace DataZoneEnergyDemands;
    4255             : 
    4256             :         using PlantUtilities::SetComponentFlowRate;
    4257             : 
    4258             :         // Locals
    4259             :         // SUBROUTINE ARGUMENT DEFINITIONS:
    4260             : 
    4261             :         // SUBROUTINE PARAMETER DEFINITIONS:
    4262       11878 :         constexpr int MaxIterCycl(100);
    4263             : 
    4264             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    4265             :         Real64 PLR;             // Part Load Ratio, fraction of time step fancoil is on
    4266             :         Real64 SRatio;          // capacity speed ratio of the for multi-stage fan fancoil unit
    4267             :         Real64 mdot;            // chilled or hot water flow rate through the water coils
    4268             :         Real64 QUnitOut;        // heating or sens. cooling provided by fan coil unit [watts]
    4269             :         Real64 QUnitOutMax;     // max heating or sens. cooling provided by fan coil unit [watts]
    4270             :         Real64 ControlOffset;   // tolerance for output control
    4271             :         Real64 QUnitOutMaxHS;   // higher fan speed output
    4272             :         Real64 QUnitOutMaxLS;   // lower fan speed output
    4273             :         Real64 HighSpeedRatio;  // fan flow ratio at low speed
    4274             :         Real64 LowSpeedRatio;   // fan flow ratio at low speed
    4275             :         Real64 AirMassFlowAvg;  // supply air flow rate weighted by speed ratio
    4276             :         Real64 AirMassFlowLow;  // supply air flow rate at lower speed
    4277             :         Real64 AirMassFlowHigh; // supply air flow rate at higher speed
    4278             :         Real64 FanElecPowerHS;  // fan electric power calculated at (fan) higher speed
    4279             :         Real64 FanElecPowerLS;  // fan electric power calculated at (fan) lower speed
    4280             :         Real64 Error;           // Error between QZnReq and QUnitOut
    4281             :         Real64 AbsError;        // Absolute error between QZnReq and QUnitOut [W]   !FB
    4282             :         Real64 Relax;
    4283             :         Real64 DelPLR;
    4284             :         int OutletNode; // unit air outlet node
    4285             :         int InletNode;  // unit air inlet node
    4286             :         int Iter;       // iteration counter
    4287             :         int SolFlag;    // return flag from RegulaFalsi for sensible load
    4288             : 
    4289       11878 :         auto &FanCoil(state.dataFanCoilUnits->FanCoil);
    4290             : 
    4291             :         // initialize local variables
    4292       11878 :         mdot = 0.0;
    4293       11878 :         PLR = 1.0;
    4294       11878 :         SRatio = 0.0;
    4295       11878 :         QUnitOut = 0.0;
    4296       11878 :         QUnitOutMax = 0.0;
    4297       11878 :         ControlOffset = 0.0;
    4298       11878 :         FanElecPowerHS = 0.0;
    4299       11878 :         FanElecPowerLS = 0.0;
    4300       11878 :         AirMassFlowAvg = 0.0;
    4301       11878 :         AirMassFlowLow = 0.0;
    4302       11878 :         AirMassFlowHigh = 0.0;
    4303       11878 :         AbsError = 2.0 * FanCoilUnits::Small5WLoad;
    4304       11878 :         Error = 1.0;
    4305       11878 :         Relax = 1.0;
    4306       11878 :         Iter = 0;
    4307             : 
    4308       11878 :         OutletNode = FanCoil(FanCoilNum).AirOutNode;
    4309       11878 :         InletNode = FanCoil(FanCoilNum).AirInNode;
    4310             : 
    4311       11878 :         auto &Node(state.dataLoopNodes->Node);
    4312             : 
    4313       11878 :         if (QZnReq < (-1.0 * FanCoilUnits::Small5WLoad) && state.dataFanCoilUnits->CoolingLoad) {
    4314        5808 :             ControlOffset = FanCoil(FanCoilNum).ColdControlOffset;
    4315        5808 :             if (FanCoil(FanCoilNum).SpeedFanSel == 1) {
    4316        2738 :                 Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOutMax);
    4317        2738 :                 PLR = std::abs(QZnReq / QUnitOutMax);
    4318        2738 :                 if (PLR > 1.0) PLR = 1.0;
    4319             :                 // adjust the PLR to meet the cooling load by calling Calc4PipeFanCoil repeatedly
    4320      173150 :                 while (std::abs(Error) > ControlOffset && std::abs(AbsError) > FanCoilUnits::Small5WLoad && Iter < MaxIterCycl && PLR != 1.0) {
    4321       85206 :                     Node(InletNode).MassFlowRateMinAvail = Node(InletNode).MassFlowRate;
    4322       85206 :                     mdot = PLR * FanCoil(FanCoilNum).MaxCoolCoilFluidFlow;
    4323      255618 :                     SetComponentFlowRate(state,
    4324             :                                          mdot,
    4325       85206 :                                          FanCoil(FanCoilNum).CoolCoilFluidInletNode,
    4326       85206 :                                          FanCoil(FanCoilNum).CoolCoilFluidOutletNodeNum,
    4327       85206 :                                          FanCoil(FanCoilNum).CoolCoilPlantLoc);
    4328       85206 :                     if (FanCoil(FanCoilNum).FanOpMode == ContFanCycCoil) {
    4329       82944 :                         Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOut);
    4330             :                     } else {
    4331        2262 :                         Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOut, PLR);
    4332             :                     }
    4333       85206 :                     Error = (QZnReq - QUnitOut) / QZnReq;
    4334       85206 :                     AbsError = QZnReq - QUnitOut;
    4335       85206 :                     DelPLR = (QZnReq - QUnitOut) / QUnitOutMax;
    4336       85206 :                     PLR += Relax * DelPLR;
    4337       85206 :                     PLR = max(0.0, min(1.0, PLR));
    4338       85206 :                     ++Iter;
    4339       85206 :                     if (Iter == 32) Relax = 0.5;
    4340       85206 :                     if (Iter == 65) Relax = 0.25;
    4341       85206 :                     if (Iter > 70 && PLR == 0.0 && DelPLR < 0.0) Error = 0.0;
    4342             :                 }
    4343        2738 :                 if (FanCoil(FanCoilNum).FanOpMode == ContFanCycCoil) {
    4344        1870 :                     Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOut);
    4345             :                 } else {
    4346         868 :                     Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOut, PLR);
    4347             :                 }
    4348             :                 // warning if not converged
    4349        2738 :                 if (Iter > (MaxIterCycl - 1)) {
    4350           0 :                     if (FanCoil(FanCoilNum).MaxIterIndexC == 0) {
    4351           0 :                         ShowWarningMessage(
    4352             :                             state,
    4353           0 :                             "ZoneHVAC:FourPipeFanCoil=\"" + FanCoil(FanCoilNum).Name +
    4354             :                                 "\" -- Exceeded max iterations while adjusting cycling fan sensible runtime to meet the zone load within "
    4355             :                                 "the cooling convergence tolerance.");
    4356           0 :                         ShowContinueErrorTimeStamp(state, format("Iterations={}", MaxIterCycl));
    4357             :                     }
    4358           0 :                     ShowRecurringWarningErrorAtEnd(state,
    4359           0 :                                                    "ZoneHVAC:FourPipeFanCoil=\"" + FanCoil(FanCoilNum).Name +
    4360             :                                                        "\"  -- Exceeded max iterations error (sensible runtime) continues...",
    4361           0 :                                                    FanCoil(FanCoilNum).MaxIterIndexC);
    4362             :                 }
    4363             : 
    4364             :             } else {
    4365        3070 :                 if (FanCoil(FanCoilNum).SpeedFanSel == 2) {
    4366        1444 :                     HighSpeedRatio = FanCoil(FanCoilNum).MedSpeedRatio;
    4367        1444 :                     LowSpeedRatio = FanCoil(FanCoilNum).LowSpeedRatio;
    4368             :                 } else {
    4369        1626 :                     HighSpeedRatio = 1;
    4370        1626 :                     LowSpeedRatio = FanCoil(FanCoilNum).MedSpeedRatio;
    4371             :                 }
    4372             :                 // get capacity at lower speed
    4373        3070 :                 FanCoil(FanCoilNum).SpeedFanRatSel = LowSpeedRatio;
    4374        3070 :                 FanCoil(FanCoilNum).SpeedFanSel = FanCoil(FanCoilNum).SpeedFanSel - 1;
    4375        3070 :                 AirMassFlowLow = LowSpeedRatio * FanCoil(FanCoilNum).MaxAirMassFlow;
    4376        3070 :                 Node(InletNode).MassFlowRate = AirMassFlowLow;
    4377        3070 :                 Node(InletNode).MassFlowRateMax = AirMassFlowLow;
    4378        3070 :                 Node(InletNode).MassFlowRateMaxAvail = AirMassFlowLow;
    4379        3070 :                 Node(InletNode).MassFlowRateMinAvail = AirMassFlowLow;
    4380        3070 :                 state.dataFanCoilUnits->FanFlowRatio = LowSpeedRatio;
    4381        3070 :                 Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOutMaxLS);
    4382        3070 :                 if (FanCoil(FanCoilNum).FanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
    4383           0 :                     FanElecPowerLS = Fans::GetFanPower(state, FanCoil(FanCoilNum).FanIndex);
    4384             :                 } else {
    4385        3070 :                     FanElecPowerLS = state.dataHVACFan->fanObjs[FanCoil(FanCoilNum).FanIndex]->fanPower();
    4386             :                 }
    4387             :                 // get capacity at higher speed
    4388        3070 :                 FanCoil(FanCoilNum).SpeedFanRatSel = HighSpeedRatio;
    4389        3070 :                 FanCoil(FanCoilNum).SpeedFanSel = FanCoil(FanCoilNum).SpeedFanSel + 1;
    4390        3070 :                 AirMassFlowHigh = HighSpeedRatio * FanCoil(FanCoilNum).MaxAirMassFlow;
    4391        3070 :                 Node(InletNode).MassFlowRate = AirMassFlowHigh;
    4392        3070 :                 Node(InletNode).MassFlowRateMax = AirMassFlowHigh;
    4393        3070 :                 Node(InletNode).MassFlowRateMaxAvail = AirMassFlowHigh;
    4394        3070 :                 Node(InletNode).MassFlowRateMinAvail = AirMassFlowLow;
    4395        3070 :                 state.dataFanCoilUnits->FanFlowRatio = HighSpeedRatio;
    4396        3070 :                 Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOutMaxHS);
    4397        3070 :                 if (FanCoil(FanCoilNum).FanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
    4398           0 :                     FanElecPowerHS = Fans::GetFanPower(state, FanCoil(FanCoilNum).FanIndex);
    4399             :                 } else {
    4400        3070 :                     FanElecPowerHS = state.dataHVACFan->fanObjs[FanCoil(FanCoilNum).FanIndex]->fanPower();
    4401             :                 }
    4402             :                 // calc speed ratio
    4403        3070 :                 if (std::abs(QZnReq) > std::abs(QUnitOutMaxHS)) {
    4404           0 :                     SRatio = 1.0;
    4405           0 :                     AirMassFlowAvg = AirMassFlowHigh;
    4406           0 :                     Node(InletNode).MassFlowRate = AirMassFlowHigh;
    4407           0 :                     Node(InletNode).MassFlowRateMax = AirMassFlowHigh;
    4408           0 :                     Node(InletNode).MassFlowRateMaxAvail = AirMassFlowHigh;
    4409           0 :                     Node(InletNode).MassFlowRateMinAvail = AirMassFlowLow;
    4410           0 :                     state.dataFanCoilUnits->FanFlowRatio = HighSpeedRatio;
    4411           0 :                     Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOut);
    4412             :                 } else {
    4413        3070 :                     SRatio = std::abs((QZnReq - QUnitOutMaxLS) / (QUnitOutMaxHS - QUnitOutMaxLS));
    4414        3070 :                     if (SRatio > 1.0) SRatio = 1.0;
    4415        3070 :                     AirMassFlowAvg = AirMassFlowHigh * SRatio + AirMassFlowLow * (1.0 - SRatio);
    4416        3070 :                     Node(InletNode).MassFlowRate = AirMassFlowAvg;
    4417        3070 :                     Node(InletNode).MassFlowRateMax = AirMassFlowAvg;
    4418        3070 :                     Node(InletNode).MassFlowRateMaxAvail = AirMassFlowAvg;
    4419        3070 :                     Node(InletNode).MassFlowRateMinAvail = AirMassFlowLow;
    4420        3070 :                     state.dataFanCoilUnits->FanFlowRatio = HighSpeedRatio * SRatio + LowSpeedRatio * (1.0 - SRatio);
    4421        3070 :                     Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOut);
    4422             :                     // adjust the PLR to meet the cooling load by calling Calc4PipeFanCoil repeatedly
    4423       14850 :                     while (std::abs(Error) > ControlOffset && std::abs(AbsError) > FanCoilUnits::Small5WLoad && Iter < MaxIterCycl && SRatio != 1.0) {
    4424        5890 :                         AirMassFlowAvg = AirMassFlowHigh * SRatio + AirMassFlowLow * (1.0 - SRatio);
    4425        5890 :                         state.dataFanCoilUnits->FanFlowRatio = HighSpeedRatio * SRatio + LowSpeedRatio * (1.0 - SRatio);
    4426        5890 :                         Node(InletNode).MassFlowRate = AirMassFlowAvg;
    4427        5890 :                         Node(InletNode).MassFlowRateMax = AirMassFlowAvg;
    4428        5890 :                         Node(InletNode).MassFlowRateMaxAvail = AirMassFlowAvg;
    4429        5890 :                         Node(InletNode).MassFlowRateMinAvail = AirMassFlowLow;
    4430        5890 :                         Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOut);
    4431        5890 :                         Error = (QZnReq - QUnitOut) / QZnReq;
    4432        5890 :                         AbsError = QZnReq - QUnitOut;
    4433        5890 :                         DelPLR = (QZnReq - QUnitOut) / (QUnitOutMaxHS - QUnitOutMaxLS);
    4434        5890 :                         SRatio += Relax * DelPLR;
    4435        5890 :                         SRatio = max(0.0, min(1.0, SRatio));
    4436        5890 :                         ++Iter;
    4437        5890 :                         if (Iter == 32) Relax = 0.5;
    4438        5890 :                         if (Iter == 65) Relax = 0.25;
    4439        5890 :                         if (Iter > 70 && SRatio == 0.0 && DelPLR < 0.0) Error = 0.0;
    4440             :                     }
    4441             :                 }
    4442             :             }
    4443        6070 :         } else if (QZnReq > FanCoilUnits::Small5WLoad && state.dataFanCoilUnits->HeatingLoad) {
    4444        6070 :             ControlOffset = FanCoil(FanCoilNum).HotControlOffset;
    4445        6070 :             if (FanCoil(FanCoilNum).SpeedFanSel == 1) {
    4446        2858 :                 Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOutMax);
    4447        2858 :                 PLR = std::abs(QZnReq / QUnitOutMax);
    4448        2858 :                 if (PLR > 1.0) PLR = 1.0;
    4449        2858 :                 if (FanCoil(FanCoilNum).HCoilType_Num == HCoil::Water) {
    4450             :                     // adjust the PLR to meet the heating load by calling Calc4PipeFanCoil repeatedly
    4451       63118 :                     while (std::abs(Error) > ControlOffset && std::abs(AbsError) > FanCoilUnits::Small5WLoad && Iter < MaxIterCycl && PLR != 1.0) {
    4452       30130 :                         Node(InletNode).MassFlowRateMinAvail = Node(InletNode).MassFlowRate;
    4453       30130 :                         mdot = PLR * FanCoil(FanCoilNum).MaxHeatCoilFluidFlow;
    4454       90390 :                         SetComponentFlowRate(state,
    4455             :                                              mdot,
    4456       30130 :                                              FanCoil(FanCoilNum).HeatCoilFluidInletNode,
    4457       30130 :                                              FanCoil(FanCoilNum).HeatCoilFluidOutletNodeNum,
    4458       30130 :                                              FanCoil(FanCoilNum).HeatCoilPlantLoc);
    4459       30130 :                         if (FanCoil(FanCoilNum).FanOpMode == ContFanCycCoil) {
    4460       28456 :                             Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOut);
    4461             :                         } else {
    4462        1674 :                             Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOut, PLR);
    4463             :                         }
    4464       30130 :                         Error = (QZnReq - QUnitOut) / QZnReq;
    4465       30130 :                         AbsError = QZnReq - QUnitOut;
    4466       30130 :                         DelPLR = (QZnReq - QUnitOut) / QUnitOutMax;
    4467       30130 :                         PLR += Relax * DelPLR;
    4468       30130 :                         PLR = max(0.0, min(1.0, PLR));
    4469       30130 :                         ++Iter;
    4470       30130 :                         if (Iter == 32) Relax = 0.5;
    4471       30130 :                         if (Iter == 65) Relax = 0.25;
    4472       30130 :                         if (Iter > 70 && PLR == 0.0 && DelPLR < 0.0) Error = 0.0; // exit loop if PLR = 0
    4473             :                     }
    4474        2858 :                     if (FanCoil(FanCoilNum).FanOpMode == ContFanCycCoil) {
    4475        2572 :                         Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOut);
    4476             :                     } else {
    4477         286 :                         Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOut, PLR);
    4478             :                     }
    4479             :                     // warning if not converged
    4480        2858 :                     if (Iter > (MaxIterCycl - 1)) {
    4481           0 :                         if (FanCoil(FanCoilNum).MaxIterIndexH == 0) {
    4482           0 :                             ShowWarningMessage(
    4483             :                                 state,
    4484           0 :                                 "ZoneHVAC:FourPipeFanCoil=\"" + FanCoil(FanCoilNum).Name +
    4485             :                                     "\" -- Exceeded max iterations while adjusting cycling fan sensible runtime to meet the zone load within "
    4486             :                                     "the heating convergence tolerance.");
    4487           0 :                             ShowContinueErrorTimeStamp(state, format("Iterations={}", MaxIterCycl));
    4488             :                         }
    4489           0 :                         ShowRecurringWarningErrorAtEnd(state,
    4490           0 :                                                        "ZoneHVAC:FourPipeFanCoil=\"" + FanCoil(FanCoilNum).Name +
    4491             :                                                            "\"  -- Exceeded max iterations error (sensible runtime) continues...",
    4492           0 :                                                        FanCoil(FanCoilNum).MaxIterIndexH);
    4493             :                     }
    4494             :                 } else {
    4495           0 :                     Real64 eHeatCoilPLR = PLR;
    4496             :                     // electric heating coil
    4497           0 :                     if (QUnitOutMax > QZnReq) {
    4498             :                         // heating coil output is larger than required, mudulate the electric heating coil output to meet the load
    4499           0 :                         Node(InletNode).MassFlowRateMinAvail = Node(InletNode).MassFlowRate;
    4500             : 
    4501           0 :                         if (FanCoil(FanCoilNum).FanOpMode == ContFanCycCoil) {
    4502           0 :                             auto f = [&state, FanCoilNum, FirstHVACIteration, ZoneNum, QZnReq](Real64 const CyclingR) {
    4503           0 :                                 return CalcFanCoilHeatCoilPLRResidual(state, CyclingR, FanCoilNum, FirstHVACIteration, ZoneNum, QZnReq);
    4504           0 :                             };
    4505           0 :                             General::SolveRoot(state, 0.001, MaxIterCycl, SolFlag, eHeatCoilPLR, f, 0.0, 1.0);
    4506             :                         } else {
    4507           0 :                             auto f = [&state, FirstHVACIteration, FanCoilNum, ZoneNum, QZnReq](Real64 const PartLoadRatio) {
    4508           0 :                                 return CalcFanCoilLoadResidual(state, FanCoilNum, FirstHVACIteration, ZoneNum, QZnReq, PartLoadRatio);
    4509           0 :                             };
    4510           0 :                             General::SolveRoot(state, 0.001, MaxIterCycl, SolFlag, eHeatCoilPLR, f, 0.0, 1.0);
    4511             :                         }
    4512           0 :                         if (SolFlag == -1) {
    4513           0 :                             ++FanCoil(FanCoilNum).ConvgErrCountH;
    4514           0 :                             if (FanCoil(FanCoilNum).ConvgErrCountH < 2) {
    4515           0 :                                 ShowWarningError(state, "Electric heating coil control failed in fan coil unit " + FanCoil(FanCoilNum).Name);
    4516           0 :                                 ShowContinueError(state, "  Iteration limit exceeded in calculating electric heating coil capacity modulation ");
    4517           0 :                                 Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOut, _, eHeatCoilPLR);
    4518           0 :                                 ShowContinueErrorTimeStamp(state, format("Load Request = {}, Final Capacity = {}", QZnReq, QUnitOut));
    4519           0 :                                 ShowContinueErrorTimeStamp(
    4520           0 :                                     state, format("Electric heating coil part load ratio used during last iterations = {}", eHeatCoilPLR));
    4521             :                             } else {
    4522           0 :                                 ShowRecurringWarningErrorAtEnd(state,
    4523           0 :                                                                "Electric heating coil Iteration limit exceeded in fan coil unit " +
    4524           0 :                                                                    FanCoil(FanCoilNum).Name,
    4525           0 :                                                                FanCoil(FanCoilNum).MaxIterIndexH);
    4526             :                             }
    4527           0 :                         } else if (SolFlag == -2) {
    4528           0 :                             ++FanCoil(FanCoilNum).LimitErrCountH;
    4529           0 :                             if (FanCoil(FanCoilNum).LimitErrCountH < 2) {
    4530           0 :                                 ShowWarningError(state,
    4531           0 :                                                  "Part load ratio electric heating coil control failed in fan coil unit " + FanCoil(FanCoilNum).Name);
    4532           0 :                                 ShowContinueError(state, "  Bad par load ratio limits");
    4533           0 :                                 ShowContinueErrorTimeStamp(state, "..Par load ratio set to 0");
    4534             :                             } else {
    4535           0 :                                 ShowRecurringWarningErrorAtEnd(state,
    4536           0 :                                                                "Part load ratio electric heating coil control failed in fan coil unit " +
    4537           0 :                                                                    FanCoil(FanCoilNum).Name,
    4538           0 :                                                                FanCoil(FanCoilNum).BadMassFlowLimIndexH);
    4539             :                             }
    4540             :                         }
    4541             :                     } else {
    4542           0 :                         eHeatCoilPLR = 1.0;
    4543             :                     }
    4544           0 :                     PLR = eHeatCoilPLR;
    4545             :                     // at the end calculate output
    4546           0 :                     if (FanCoil(FanCoilNum).FanOpMode == ContFanCycCoil) {
    4547           0 :                         Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOut, _, eHeatCoilPLR);
    4548             :                     } else {
    4549           0 :                         Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOut, PLR);
    4550             :                     }
    4551             :                 }
    4552             : 
    4553             :             } else {
    4554        3212 :                 if (FanCoil(FanCoilNum).SpeedFanSel == 2) {
    4555        3212 :                     HighSpeedRatio = FanCoil(FanCoilNum).MedSpeedRatio;
    4556        3212 :                     LowSpeedRatio = FanCoil(FanCoilNum).LowSpeedRatio;
    4557             :                 } else {
    4558           0 :                     HighSpeedRatio = 1;
    4559           0 :                     LowSpeedRatio = FanCoil(FanCoilNum).MedSpeedRatio;
    4560             :                 }
    4561             :                 // get capacity at lower speed ratio
    4562        3212 :                 FanCoil(FanCoilNum).SpeedFanRatSel = LowSpeedRatio;
    4563        3212 :                 FanCoil(FanCoilNum).SpeedFanSel = FanCoil(FanCoilNum).SpeedFanSel - 1;
    4564        3212 :                 AirMassFlowLow = LowSpeedRatio * FanCoil(FanCoilNum).MaxAirMassFlow;
    4565        3212 :                 Node(InletNode).MassFlowRate = AirMassFlowLow;
    4566        3212 :                 Node(InletNode).MassFlowRateMax = AirMassFlowLow;
    4567        3212 :                 Node(InletNode).MassFlowRateMaxAvail = AirMassFlowLow;
    4568        3212 :                 Node(InletNode).MassFlowRateMinAvail = AirMassFlowLow;
    4569        3212 :                 state.dataFanCoilUnits->FanFlowRatio = LowSpeedRatio;
    4570        3212 :                 Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOutMaxLS);
    4571        3212 :                 if (FanCoil(FanCoilNum).FanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
    4572           0 :                     FanElecPowerLS = Fans::GetFanPower(state, FanCoil(FanCoilNum).FanIndex);
    4573             :                 } else {
    4574        3212 :                     FanElecPowerLS = state.dataHVACFan->fanObjs[FanCoil(FanCoilNum).FanIndex]->fanPower();
    4575             :                 }
    4576             :                 // get capacity at higher speed
    4577        3212 :                 FanCoil(FanCoilNum).SpeedFanRatSel = HighSpeedRatio;
    4578        3212 :                 FanCoil(FanCoilNum).SpeedFanSel = FanCoil(FanCoilNum).SpeedFanSel + 1;
    4579        3212 :                 AirMassFlowHigh = HighSpeedRatio * FanCoil(FanCoilNum).MaxAirMassFlow;
    4580        3212 :                 Node(InletNode).MassFlowRate = AirMassFlowHigh;
    4581        3212 :                 Node(InletNode).MassFlowRateMax = AirMassFlowHigh;
    4582        3212 :                 Node(InletNode).MassFlowRateMaxAvail = AirMassFlowHigh;
    4583        3212 :                 Node(InletNode).MassFlowRateMinAvail = AirMassFlowLow;
    4584        3212 :                 state.dataFanCoilUnits->FanFlowRatio = HighSpeedRatio;
    4585        3212 :                 Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOutMaxHS);
    4586        3212 :                 if (FanCoil(FanCoilNum).FanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
    4587           0 :                     FanElecPowerHS = Fans::GetFanPower(state, FanCoil(FanCoilNum).FanIndex);
    4588             :                 } else {
    4589        3212 :                     FanElecPowerHS = state.dataHVACFan->fanObjs[FanCoil(FanCoilNum).FanIndex]->fanPower();
    4590             :                 }
    4591             :                 // calc speed ratio
    4592        3212 :                 if (std::abs(QZnReq) > std::abs(QUnitOutMaxHS)) {
    4593           0 :                     SRatio = 1.0;
    4594           0 :                     AirMassFlowAvg = AirMassFlowHigh;
    4595           0 :                     Node(InletNode).MassFlowRate = AirMassFlowAvg;
    4596           0 :                     Node(InletNode).MassFlowRateMax = AirMassFlowAvg;
    4597           0 :                     Node(InletNode).MassFlowRateMaxAvail = AirMassFlowAvg;
    4598           0 :                     Node(InletNode).MassFlowRateMinAvail = AirMassFlowLow;
    4599           0 :                     state.dataFanCoilUnits->FanFlowRatio = HighSpeedRatio;
    4600           0 :                     Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOut);
    4601             :                 } else {
    4602        3212 :                     SRatio = std::abs((QZnReq - QUnitOutMaxLS) / (QUnitOutMaxHS - QUnitOutMaxLS));
    4603        3212 :                     if (SRatio > 1.0) SRatio = 1.0;
    4604        3212 :                     AirMassFlowAvg = AirMassFlowHigh * SRatio + AirMassFlowLow * (1.0 - SRatio);
    4605        3212 :                     Node(InletNode).MassFlowRate = AirMassFlowAvg;
    4606        3212 :                     Node(InletNode).MassFlowRateMax = AirMassFlowAvg;
    4607        3212 :                     Node(InletNode).MassFlowRateMaxAvail = AirMassFlowAvg;
    4608        3212 :                     Node(InletNode).MassFlowRateMinAvail = AirMassFlowLow;
    4609        3212 :                     state.dataFanCoilUnits->FanFlowRatio = HighSpeedRatio * SRatio + LowSpeedRatio * (1.0 - SRatio);
    4610        3212 :                     Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOut);
    4611        3212 :                     ControlOffset = FanCoil(FanCoilNum).HotControlOffset;
    4612             :                     // adjust the PLR to meet the heating load calling Calc4PipeFanCoil repeatedly
    4613       22580 :                     while (std::abs(Error) > ControlOffset && std::abs(AbsError) > FanCoilUnits::Small5WLoad && Iter < MaxIterCycl && SRatio != 1.0) {
    4614        9684 :                         AirMassFlowAvg = AirMassFlowHigh * SRatio + AirMassFlowLow * (1.0 - SRatio);
    4615        9684 :                         Node(InletNode).MassFlowRate = AirMassFlowAvg;
    4616        9684 :                         Node(InletNode).MassFlowRateMax = AirMassFlowAvg;
    4617        9684 :                         Node(InletNode).MassFlowRateMaxAvail = AirMassFlowAvg;
    4618        9684 :                         Node(InletNode).MassFlowRateMinAvail = AirMassFlowLow;
    4619        9684 :                         state.dataFanCoilUnits->FanFlowRatio = HighSpeedRatio * SRatio + LowSpeedRatio * (1.0 - SRatio);
    4620        9684 :                         Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOut);
    4621        9684 :                         Error = (QZnReq - QUnitOut) / QZnReq;
    4622        9684 :                         AbsError = QZnReq - QUnitOut;
    4623        9684 :                         DelPLR = (QZnReq - QUnitOut) / (QUnitOutMaxHS - QUnitOutMaxLS);
    4624        9684 :                         SRatio += Relax * DelPLR;
    4625        9684 :                         SRatio = max(0.0, min(1.0, SRatio));
    4626        9684 :                         ++Iter;
    4627        9684 :                         if (Iter == 32) Relax = 0.5;
    4628        9684 :                         if (Iter == 65) Relax = 0.25;
    4629        9684 :                         if (Iter > 70 && SRatio == 0.0 && DelPLR < 0.0) Error = 0.0;
    4630             :                     }
    4631             :                 }
    4632             :                 // FanElecPower = FanElecPowerHS * SRatio + FanElecPowerLS * ( 1.0 - SRatio ); // why set the ugly global here?
    4633        3212 :                 FanCoil(FanCoilNum).ElecPower = FanElecPowerHS * SRatio + FanElecPowerLS * (1.0 - SRatio);
    4634             :             }
    4635             :         }
    4636       11878 :         Node(OutletNode).MassFlowRate = Node(InletNode).MassFlowRate;
    4637       11878 :         PartLoadRatio = PLR;
    4638       11878 :         SpeedRatio = SRatio;
    4639       11878 :         PowerMet = QUnitOut;
    4640       11878 :     }
    4641             : 
    4642      514191 :     void ReportFanCoilUnit(EnergyPlusData &state, int const FanCoilNum) // number of the current fan coil unit being simulated
    4643             :     {
    4644             : 
    4645             :         // SUBROUTINE INFORMATION:
    4646             :         //       AUTHOR         Fred Buhl
    4647             :         //       DATE WRITTEN   March 2000
    4648             :         //       MODIFIED       na
    4649             :         //       RE-ENGINEERED  na
    4650             : 
    4651             :         // PURPOSE OF THIS SUBROUTINE:
    4652             :         // Fills some of the report variables for the fan coil units
    4653             : 
    4654             :         // METHODOLOGY EMPLOYED:
    4655             :         // NA
    4656             : 
    4657             :         // REFERENCES:
    4658             :         // na
    4659             : 
    4660             :         // Using/Aliasing
    4661      514191 :         auto &TimeStepSys = state.dataHVACGlobal->TimeStepSys;
    4662             : 
    4663             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    4664             :         Real64 ReportingConstant;
    4665             : 
    4666      514191 :         ReportingConstant = TimeStepSys * DataGlobalConstants::SecInHour;
    4667      514191 :         state.dataFanCoilUnits->FanCoil(FanCoilNum).HeatEnergy = state.dataFanCoilUnits->FanCoil(FanCoilNum).HeatPower * ReportingConstant;
    4668      514191 :         state.dataFanCoilUnits->FanCoil(FanCoilNum).SensCoolEnergy = state.dataFanCoilUnits->FanCoil(FanCoilNum).SensCoolPower * ReportingConstant;
    4669      514191 :         state.dataFanCoilUnits->FanCoil(FanCoilNum).TotCoolEnergy = state.dataFanCoilUnits->FanCoil(FanCoilNum).TotCoolPower * ReportingConstant;
    4670      514191 :         state.dataFanCoilUnits->FanCoil(FanCoilNum).ElecEnergy = state.dataFanCoilUnits->FanCoil(FanCoilNum).ElecPower * ReportingConstant;
    4671             : 
    4672      514191 :         if (state.dataFanCoilUnits->FanCoil(FanCoilNum).FirstPass) { // reset sizing flags so other zone equipment can size normally
    4673         162 :             if (!state.dataGlobal->SysSizingCalc) {
    4674          81 :                 DataSizing::resetHVACSizingGlobals(state, state.dataSize->CurZoneEqNum, 0, state.dataFanCoilUnits->FanCoil(FanCoilNum).FirstPass);
    4675             :             }
    4676             :         }
    4677      514191 :     }
    4678             : 
    4679       25465 :     int GetFanCoilZoneInletAirNode(EnergyPlusData &state, int const FanCoilNum)
    4680             :     {
    4681             : 
    4682             :         // FUNCTION INFORMATION:
    4683             :         //       AUTHOR         B Griffith
    4684             :         //       DATE WRITTEN   Dec  2006
    4685             :         //       MODIFIED       na
    4686             :         //       RE-ENGINEERED  na
    4687             : 
    4688             :         // PURPOSE OF THIS FUNCTION:
    4689             :         // lookup function for OA inlet node for ventilation rate reporting
    4690             : 
    4691             :         // Return value
    4692             :         int GetFanCoilZoneInletAirNode;
    4693             : 
    4694       25465 :         if (state.dataFanCoilUnits->GetFanCoilInputFlag) {
    4695           0 :             GetFanCoilUnits(state);
    4696           0 :             state.dataFanCoilUnits->GetFanCoilInputFlag = false;
    4697             :         }
    4698             : 
    4699       25465 :         GetFanCoilZoneInletAirNode = 0;
    4700       25465 :         if (FanCoilNum > 0 && FanCoilNum <= state.dataFanCoilUnits->NumFanCoils) {
    4701       25465 :             GetFanCoilZoneInletAirNode = state.dataFanCoilUnits->FanCoil(FanCoilNum).AirOutNode;
    4702             :         }
    4703             : 
    4704       25465 :         return GetFanCoilZoneInletAirNode;
    4705             :     }
    4706             : 
    4707       25465 :     int GetFanCoilOutAirNode(EnergyPlusData &state, int const FanCoilNum)
    4708             :     {
    4709             : 
    4710             :         // FUNCTION INFORMATION:
    4711             :         //       AUTHOR         B Griffith
    4712             :         //       DATE WRITTEN   Dec  2006
    4713             :         //       MODIFIED       na
    4714             :         //       RE-ENGINEERED  na
    4715             : 
    4716             :         // PURPOSE OF THIS FUNCTION:
    4717             :         // lookup function for OA inlet node for ventilation rate reporting
    4718             : 
    4719             :         // Return value
    4720             :         int GetFanCoilOutAirNode;
    4721             : 
    4722       25465 :         if (state.dataFanCoilUnits->GetFanCoilInputFlag) {
    4723           0 :             GetFanCoilUnits(state);
    4724           0 :             state.dataFanCoilUnits->GetFanCoilInputFlag = false;
    4725             :         }
    4726             : 
    4727       25465 :         GetFanCoilOutAirNode = 0;
    4728       25465 :         if (FanCoilNum > 0 && FanCoilNum <= state.dataFanCoilUnits->NumFanCoils) {
    4729       25465 :             GetFanCoilOutAirNode = state.dataFanCoilUnits->FanCoil(FanCoilNum).OutsideAirNode;
    4730             :         }
    4731             : 
    4732       25465 :         return GetFanCoilOutAirNode;
    4733             :     }
    4734             : 
    4735       25465 :     int GetFanCoilReturnAirNode(EnergyPlusData &state, int const FanCoilNum)
    4736             :     {
    4737             : 
    4738             :         // FUNCTION INFORMATION:
    4739             :         //       AUTHOR         B Griffith
    4740             :         //       DATE WRITTEN   Dec  2006
    4741             :         //       MODIFIED       na
    4742             :         //       RE-ENGINEERED  na
    4743             : 
    4744             :         // PURPOSE OF THIS FUNCTION:
    4745             :         // lookup function for mixer's return node
    4746             : 
    4747             :         // Using/Aliasing
    4748             :         using MixedAir::GetOAMixerReturnNodeNumber;
    4749             : 
    4750             :         // Return value
    4751             :         int GetFanCoilReturnAirNode;
    4752             : 
    4753       25465 :         if (state.dataFanCoilUnits->GetFanCoilInputFlag) {
    4754           0 :             GetFanCoilUnits(state);
    4755           0 :             state.dataFanCoilUnits->GetFanCoilInputFlag = false;
    4756             :         }
    4757             : 
    4758       25465 :         GetFanCoilReturnAirNode = 0;
    4759       25465 :         if (FanCoilNum > 0 && FanCoilNum <= state.dataFanCoilUnits->NumFanCoils) {
    4760       25465 :             if (state.dataFanCoilUnits->FanCoil(FanCoilNum).OAMixIndex > 0) {
    4761       23235 :                 GetFanCoilReturnAirNode = GetOAMixerReturnNodeNumber(state, state.dataFanCoilUnits->FanCoil(FanCoilNum).OAMixIndex);
    4762             :             } else {
    4763        2230 :                 GetFanCoilReturnAirNode = 0;
    4764             :             }
    4765             :         }
    4766             : 
    4767       25465 :         return GetFanCoilReturnAirNode;
    4768             :     }
    4769             : 
    4770       25465 :     int GetFanCoilMixedAirNode(EnergyPlusData &state, int const FanCoilNum)
    4771             :     {
    4772             : 
    4773             :         // FUNCTION INFORMATION:
    4774             :         //       AUTHOR         B Griffith
    4775             :         //       DATE WRITTEN   Dec  2006
    4776             :         //       MODIFIED       na
    4777             :         //       RE-ENGINEERED  na
    4778             : 
    4779             :         // PURPOSE OF THIS FUNCTION:
    4780             :         // lookup function for mixer's return node
    4781             : 
    4782             :         // Using/Aliasing
    4783             :         using MixedAir::GetOAMixerMixedNodeNumber;
    4784             : 
    4785             :         // Return value
    4786             :         int GetFanCoilMixedAirNode;
    4787             : 
    4788       25465 :         if (state.dataFanCoilUnits->GetFanCoilInputFlag) {
    4789           0 :             GetFanCoilUnits(state);
    4790           0 :             state.dataFanCoilUnits->GetFanCoilInputFlag = false;
    4791             :         }
    4792             : 
    4793       25465 :         GetFanCoilMixedAirNode = 0;
    4794       25465 :         if (FanCoilNum > 0 && FanCoilNum <= state.dataFanCoilUnits->NumFanCoils) {
    4795       25465 :             if (state.dataFanCoilUnits->FanCoil(FanCoilNum).OAMixIndex > 0) {
    4796       23235 :                 GetFanCoilMixedAirNode = GetOAMixerMixedNodeNumber(state, state.dataFanCoilUnits->FanCoil(FanCoilNum).OAMixIndex);
    4797             :             } else {
    4798        2230 :                 GetFanCoilMixedAirNode = 0;
    4799             :             }
    4800             :         }
    4801             : 
    4802       25465 :         return GetFanCoilMixedAirNode;
    4803             :     }
    4804             : 
    4805           0 :     int GetFanCoilInletAirNode(EnergyPlusData &state, int const FanCoilNum)
    4806             :     {
    4807             : 
    4808             :         // FUNCTION INFORMATION:
    4809             :         //       AUTHOR         B Griffith
    4810             :         //       DATE WRITTEN   Dec  2006
    4811             :         //       MODIFIED       na
    4812             :         //       RE-ENGINEERED  na
    4813             : 
    4814             :         // PURPOSE OF THIS FUNCTION:
    4815             :         // lookup function for inlet node for Fan Coil unit
    4816             : 
    4817             :         // Return value
    4818             :         int GetFanCoilInletAirNode;
    4819             : 
    4820           0 :         if (state.dataFanCoilUnits->GetFanCoilInputFlag) {
    4821           0 :             GetFanCoilUnits(state);
    4822           0 :             state.dataFanCoilUnits->GetFanCoilInputFlag = false;
    4823             :         }
    4824             : 
    4825           0 :         GetFanCoilInletAirNode = 0;
    4826           0 :         if (FanCoilNum > 0 && FanCoilNum <= state.dataFanCoilUnits->NumFanCoils) {
    4827           0 :             GetFanCoilInletAirNode = state.dataFanCoilUnits->FanCoil(FanCoilNum).AirOutNode;
    4828             :         }
    4829             : 
    4830           0 :         return GetFanCoilInletAirNode;
    4831             :     }
    4832             : 
    4833           0 :     void GetFanCoilIndex(EnergyPlusData &state, std::string const &FanCoilName, int &FanCoilIndex)
    4834             :     {
    4835             :         bool ErrorsFound; // for error trapping
    4836           0 :         if (state.dataFanCoilUnits->GetFanCoilInputFlag) {
    4837           0 :             GetFanCoilUnits(state);
    4838           0 :             state.dataFanCoilUnits->GetFanCoilInputFlag = false;
    4839             :         }
    4840           0 :         FanCoilIndex = UtilityRoutines::FindItemInList(FanCoilName, state.dataFanCoilUnits->FanCoil);
    4841           0 :         if (FanCoilIndex == 0) {
    4842           0 :             ShowSevereError(state, "GetFanCoilIndex: Fan Coil Unit not found=" + FanCoilName);
    4843             :         }
    4844           0 :         ErrorsFound = true;
    4845           0 :     }
    4846             : 
    4847        6126 :     Real64 CalcFanCoilLoadResidual(EnergyPlusData &state,
    4848             :                                    int FanCoilNum,            // Index to this fan coil unit
    4849             :                                    bool FirstHVACIteration,   // FirstHVACIteration flag
    4850             :                                    int ControlledZoneNum,     // zone index
    4851             :                                    Real64 QZnReq,             // Sensible load to be met [W]
    4852             :                                    Real64 const PartLoadRatio // coil part load ratio
    4853             :     )
    4854             :     {
    4855             :         // FUNCTION INFORMATION:
    4856             :         //       AUTHOR         Richard Raustad, FSEC
    4857             :         //       DATE WRITTEN   July 2015
    4858             : 
    4859             :         // PURPOSE OF THIS SUBROUTINE:
    4860             :         // To calculate the part-load ratio for the FCU with electric heating coil
    4861             : 
    4862             :         Real64 QUnitOut; // delivered capacity [W]
    4863        6126 :         Calc4PipeFanCoil(state,
    4864             :                          FanCoilNum,
    4865             :                          ControlledZoneNum,
    4866             :                          FirstHVACIteration,
    4867             :                          QUnitOut,
    4868             :                          PartLoadRatio); // needs PLR=0 for electric heating coil, otherwise will run a full capacity
    4869             :         // Calculate residual based on output magnitude
    4870        6126 :         if (std::abs(QZnReq) <= 100.0) {
    4871           0 :             return (QUnitOut - QZnReq) / 100.0;
    4872             :         } else {
    4873        6126 :             return (QUnitOut - QZnReq) / QZnReq;
    4874             :         }
    4875             :     }
    4876             : 
    4877      673380 :     Real64 CalcFanCoilPLRResidual(EnergyPlusData &state,
    4878             :                                   Real64 const PLR,        // part-load ratio of air and water mass flow rate
    4879             :                                   int FanCoilNum,          // Index to this fan coil unit
    4880             :                                   bool FirstHVACIteration, // FirstHVACIteration flag
    4881             :                                   int ControlledZoneNum,   // zone index
    4882             :                                   int WaterControlNode,    // water node to control
    4883             :                                   Real64 QZnReq            // Sensible load to be met [W] // Function parameters
    4884             :     )
    4885             :     {
    4886             : 
    4887             :         // FUNCTION INFORMATION:
    4888             :         //       AUTHOR         Richard Raustad
    4889             :         //       DATE WRITTEN   August 2016
    4890             : 
    4891             :         // PURPOSE OF THIS SUBROUTINE:
    4892             :         Real64 QUnitOut; // delivered capacity [W]
    4893      673380 :         if (WaterControlNode == state.dataFanCoilUnits->FanCoil(FanCoilNum).CoolCoilFluidInletNode) {
    4894      350503 :             state.dataLoopNodes->Node(WaterControlNode).MassFlowRate = PLR * state.dataFanCoilUnits->FanCoil(FanCoilNum).MaxCoolCoilFluidFlow;
    4895      350503 :             Calc4PipeFanCoil(state,
    4896             :                              FanCoilNum,
    4897             :                              ControlledZoneNum,
    4898             :                              FirstHVACIteration,
    4899             :                              QUnitOut,
    4900             :                              PLR); // needs PLR=0 for electric heating coil, otherwise will run a full capacity
    4901      645754 :         } else if (WaterControlNode == state.dataFanCoilUnits->FanCoil(FanCoilNum).HeatCoilFluidInletNode &&
    4902      322877 :                    state.dataFanCoilUnits->FanCoil(FanCoilNum).HCoilType_Num != HCoil::Electric) {
    4903      322877 :             state.dataLoopNodes->Node(WaterControlNode).MassFlowRate = PLR * state.dataFanCoilUnits->FanCoil(FanCoilNum).MaxHeatCoilFluidFlow;
    4904      322877 :             Calc4PipeFanCoil(state,
    4905             :                              FanCoilNum,
    4906             :                              ControlledZoneNum,
    4907             :                              FirstHVACIteration,
    4908             :                              QUnitOut,
    4909             :                              PLR); // needs PLR=0 for electric heating coil, otherwise will run a full capacity
    4910             :         } else {
    4911           0 :             Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut, PLR); // needs PLR=1 for electric heating coil
    4912             :         }
    4913             : 
    4914             :         // Calculate residual based on output magnitude
    4915      673380 :         if (std::abs(QZnReq) <= 100.0) {
    4916       16860 :             return (QUnitOut - QZnReq) / 100.0;
    4917             :         } else {
    4918      656520 :             return (QUnitOut - QZnReq) / QZnReq;
    4919             :         }
    4920             :     }
    4921             : 
    4922           0 :     Real64 CalcFanCoilHeatCoilPLRResidual(EnergyPlusData &state,
    4923             :                                           Real64 const CyclingR, // electric heating coil cycling ratio
    4924             :                                           int const FanCoilNum,
    4925             :                                           bool const FirstHVACIteration,
    4926             :                                           int const ZoneNum,
    4927             :                                           Real64 const QZnReq)
    4928             :     {
    4929             :         // PURPOSE OF THIS SUBROUTINE:
    4930             :         // Calculate electric heating coil cycling ratio of FanCoilUnit with MultiSpeedFan
    4931             :         // capacity control method when running with at lowest speed for a continuous
    4932             :         // fan operating mode.
    4933             : 
    4934             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    4935             :         Real64 QUnitOut;            // delivered capacity [W]
    4936           0 :         Real64 constexpr PLR = 1.0; // fan coil unit PLR
    4937             : 
    4938             :         // electric heating coil cycling ratio at minimum air flow for constant fan operating mode
    4939           0 :         Calc4PipeFanCoil(state, FanCoilNum, ZoneNum, FirstHVACIteration, QUnitOut, PLR, CyclingR);
    4940             : 
    4941             :         // Calculate residual based on output magnitude
    4942           0 :         if (std::abs(QZnReq) <= 100.0) {
    4943           0 :             return (QUnitOut - QZnReq) / 100.0;
    4944             :         } else {
    4945           0 :             return (QUnitOut - QZnReq) / QZnReq;
    4946             :         }
    4947             :     }
    4948             : 
    4949     1659776 :     Real64 CalcFanCoilCWLoadResidual(EnergyPlusData &state,
    4950             :                                      Real64 const CWFlow, // water mass flow rate [kg/s]
    4951             :                                      int const FanCoilNum,
    4952             :                                      bool const FirstHVACIteration,
    4953             :                                      int const ControlledZoneNum,
    4954             :                                      Real64 const QZnReq)
    4955             :     {
    4956             : 
    4957             :         // FUNCTION INFORMATION:
    4958             :         //       AUTHOR         Fred Buhl Jan 2016
    4959             :         //       DATE WRITTEN   July 2015
    4960             :         //       MODIFIED       na
    4961             :         //       RE-ENGINEERED  na
    4962             : 
    4963             :         // PURPOSE OF THIS SUBROUTINE:
    4964             :         // To calculate the part-load ratio for the FCU with electric heating coil
    4965             : 
    4966             :         Real64 QUnitOut; // delivered capacity [W]
    4967     1659776 :         state.dataLoopNodes->Node(state.dataFanCoilUnits->FanCoil(FanCoilNum).CoolCoilFluidInletNode).MassFlowRate = CWFlow;
    4968     1659776 :         Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut, 1.0);
    4969             : 
    4970             :         // Calculate residual based on output magnitude
    4971     1659776 :         if (std::abs(QZnReq) <= 100.0) {
    4972        8237 :             return (QUnitOut - QZnReq) / 100.0;
    4973             :         } else {
    4974     1651539 :             return (QUnitOut - QZnReq) / QZnReq;
    4975             :         }
    4976             :     }
    4977             : 
    4978       91060 :     Real64 CalcFanCoilWaterFlowResidual(EnergyPlusData &state,
    4979             :                                         Real64 const PLR,
    4980             :                                         int FanCoilNum,
    4981             :                                         bool FirstHVACIteration,
    4982             :                                         int ControlledZoneNum,
    4983             :                                         Real64 QZnReq,
    4984             :                                         int AirInNode,
    4985             :                                         int WaterControlNode,
    4986             :                                         Real64 maxCoilFluidFlow,
    4987             :                                         Real64 AirMassFlowRate)
    4988             :     {
    4989             : 
    4990             :         // FUNCTION INFORMATION:
    4991             :         //       AUTHOR         Richard Raustad, FSEC
    4992             :         //       DATE WRITTEN   December 2015
    4993             :         //       MODIFIED       na
    4994             :         //       RE-ENGINEERED  na
    4995             : 
    4996             :         // PURPOSE OF THIS SUBROUTINE:
    4997             :         // To calculate the part-load ratio for the FCU with varying water flow rate
    4998             : 
    4999       91060 :         Real64 const mDot = PLR * maxCoilFluidFlow;
    5000       91060 :         if (WaterControlNode > 0) state.dataLoopNodes->Node(WaterControlNode).MassFlowRate = mDot;
    5001       91060 :         state.dataLoopNodes->Node(AirInNode).MassFlowRate = AirMassFlowRate;
    5002             : 
    5003             :         Real64 QUnitOut;
    5004      223710 :         if (WaterControlNode == state.dataFanCoilUnits->FanCoil(FanCoilNum).CoolCoilFluidInletNode ||
    5005       83180 :             (WaterControlNode == state.dataFanCoilUnits->FanCoil(FanCoilNum).HeatCoilFluidInletNode &&
    5006       41590 :              state.dataFanCoilUnits->FanCoil(FanCoilNum).HCoilType_Num != HCoil::Electric)) {
    5007             : 
    5008       91060 :             Calc4PipeFanCoil(state,
    5009             :                              FanCoilNum,
    5010             :                              ControlledZoneNum,
    5011             :                              FirstHVACIteration,
    5012             :                              QUnitOut,
    5013             :                              0.0); // needs PLR=0 for electric heating coil, otherwise will run a full capacity
    5014             : 
    5015             :         } else {
    5016           0 :             Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut, PLR);
    5017             :         }
    5018             : 
    5019             :         // Calculate residual based on output magnitude
    5020       91060 :         if (std::abs(QZnReq) <= 100.0) {
    5021          64 :             return (QUnitOut - QZnReq) / 100.0;
    5022             :         } else {
    5023       90996 :             return (QUnitOut - QZnReq) / QZnReq;
    5024             :         }
    5025             :     }
    5026             : 
    5027       20562 :     Real64 CalcFanCoilAirAndWaterFlowResidual(EnergyPlusData &state,
    5028             :                                               Real64 const PLR, // water and air part load ratio
    5029             :                                               int FanCoilNum,
    5030             :                                               bool FirstHVACIteration,
    5031             :                                               int ControlledZoneNum,
    5032             :                                               Real64 QZnReq,
    5033             :                                               int AirInNode,
    5034             :                                               int WaterControlNode,
    5035             :                                               Real64 MinWaterFlow)
    5036             :     {
    5037             : 
    5038             :         // FUNCTION INFORMATION:
    5039             :         //       AUTHOR         Richard Raustad, FSEC
    5040             :         //       DATE WRITTEN   December 2015
    5041             :         //       MODIFIED       na
    5042             :         //       RE-ENGINEERED  na
    5043             : 
    5044             :         // PURPOSE OF THIS SUBROUTINE:
    5045             :         // To calculate the part-load ratio for the FCU with varying water flow rate
    5046             : 
    5047             :         // METHODOLOGY EMPLOYED:
    5048             :         // Use SolveRoot to CALL this Function to converge on a solution
    5049             : 
    5050             :         // set air flow rate
    5051       20562 :         state.dataLoopNodes->Node(AirInNode).MassFlowRate =
    5052       41124 :             state.dataFanCoilUnits->FanCoil(FanCoilNum).MaxAirMassFlow *
    5053       20562 :             (state.dataFanCoilUnits->FanCoil(FanCoilNum).LowSpeedRatio + (PLR * (1.0 - state.dataFanCoilUnits->FanCoil(FanCoilNum).LowSpeedRatio)));
    5054             :         // set water flow rate
    5055       20562 :         if (WaterControlNode == state.dataFanCoilUnits->FanCoil(FanCoilNum).CoolCoilFluidInletNode) {
    5056       20562 :             state.dataLoopNodes->Node(WaterControlNode).MassFlowRate =
    5057       20562 :                 MinWaterFlow + (PLR * (state.dataFanCoilUnits->FanCoil(FanCoilNum).MaxCoolCoilFluidFlow - MinWaterFlow));
    5058           0 :         } else if (WaterControlNode == state.dataFanCoilUnits->FanCoil(FanCoilNum).HeatCoilFluidInletNode) {
    5059           0 :             state.dataLoopNodes->Node(WaterControlNode).MassFlowRate =
    5060           0 :                 MinWaterFlow + (PLR * (state.dataFanCoilUnits->FanCoil(FanCoilNum).MaxHeatCoilFluidFlow - MinWaterFlow));
    5061             :         } else {
    5062             :             // developer error
    5063           0 :             ShowFatalError(state,
    5064           0 :                            "Developer Error - CalcFanCoilAirAndWaterFlowResidual: Water control node not found for " +
    5065           0 :                                state.dataFanCoilUnits->FanCoil(FanCoilNum).Name);
    5066             :         }
    5067             :         Real64 QUnitOut; // delivered capacity [W]
    5068       20562 :         Calc4PipeFanCoil(state,
    5069             :                          FanCoilNum,
    5070             :                          ControlledZoneNum,
    5071             :                          FirstHVACIteration,
    5072             :                          QUnitOut,
    5073             :                          PLR); // needs PLR for electric heating coil to output a specific capacity
    5074             : 
    5075             :         // Calculate residual based on output magnitude
    5076       20562 :         if (std::abs(QZnReq) <= 100.0) {
    5077           0 :             return (QUnitOut - QZnReq) / 100.0;
    5078             :         } else {
    5079       20562 :             return (QUnitOut - QZnReq) / QZnReq;
    5080             :         }
    5081             :     }
    5082             : 
    5083             : } // namespace FanCoilUnits
    5084             : 
    5085        2313 : } // namespace EnergyPlus

Generated by: LCOV version 1.13