LCOV - code coverage report
Current view: top level - EnergyPlus - WindowAC.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 70.9 % 763 541
Test Date: 2025-05-22 16:09:37 Functions: 100.0 % 14 14

            Line data    Source code
       1              : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
       2              : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3              : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4              : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5              : // contributors. All rights reserved.
       6              : //
       7              : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8              : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9              : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10              : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11              : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12              : //
      13              : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14              : // provided that the following conditions are met:
      15              : //
      16              : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17              : //     conditions and the following disclaimer.
      18              : //
      19              : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20              : //     conditions and the following disclaimer in the documentation and/or other materials
      21              : //     provided with the distribution.
      22              : //
      23              : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24              : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25              : //     used to endorse or promote products derived from this software without specific prior
      26              : //     written permission.
      27              : //
      28              : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29              : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30              : //     reference solely to the software portion of its product, Licensee must refer to the
      31              : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32              : //     obtained under this License and may not use a different name for the software. Except as
      33              : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34              : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35              : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36              : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37              : //
      38              : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39              : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40              : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41              : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42              : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43              : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44              : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45              : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46              : // POSSIBILITY OF SUCH DAMAGE.
      47              : 
      48              : // C++ Headers
      49              : #include <cmath>
      50              : 
      51              : // ObjexxFCL Headers
      52              : #include <ObjexxFCL/Array.functions.hh>
      53              : 
      54              : // EnergyPlus Headers
      55              : #include <EnergyPlus/Autosizing/CoolingAirFlowSizing.hh>
      56              : #include <EnergyPlus/Autosizing/CoolingCapacitySizing.hh>
      57              : #include <EnergyPlus/Autosizing/SystemAirFlowSizing.hh>
      58              : #include <EnergyPlus/BranchNodeConnections.hh>
      59              : #include <EnergyPlus/DXCoils.hh>
      60              : #include <EnergyPlus/Data/EnergyPlusData.hh>
      61              : #include <EnergyPlus/DataAirSystems.hh>
      62              : #include <EnergyPlus/DataHVACGlobals.hh>
      63              : #include <EnergyPlus/DataHeatBalFanSys.hh>
      64              : #include <EnergyPlus/DataHeatBalance.hh>
      65              : #include <EnergyPlus/DataLoopNode.hh>
      66              : #include <EnergyPlus/DataSizing.hh>
      67              : #include <EnergyPlus/DataZoneEnergyDemands.hh>
      68              : #include <EnergyPlus/DataZoneEquipment.hh>
      69              : #include <EnergyPlus/EMSManager.hh>
      70              : #include <EnergyPlus/Fans.hh>
      71              : #include <EnergyPlus/General.hh>
      72              : #include <EnergyPlus/GeneralRoutines.hh>
      73              : #include <EnergyPlus/HVACHXAssistedCoolingCoil.hh>
      74              : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      75              : #include <EnergyPlus/MixedAir.hh>
      76              : #include <EnergyPlus/NodeInputManager.hh>
      77              : #include <EnergyPlus/OutputProcessor.hh>
      78              : #include <EnergyPlus/Psychrometrics.hh>
      79              : #include <EnergyPlus/ReportCoilSelection.hh>
      80              : #include <EnergyPlus/ScheduleManager.hh>
      81              : #include <EnergyPlus/UtilityRoutines.hh>
      82              : #include <EnergyPlus/VariableSpeedCoils.hh>
      83              : #include <EnergyPlus/WindowAC.hh>
      84              : 
      85              : namespace EnergyPlus {
      86              : 
      87              : namespace WindowAC {
      88              : 
      89              :     // Module containing the routines dealing window air conditioner units
      90              : 
      91              :     // MODULE INFORMATION:
      92              :     //       AUTHOR         Fred Buhl
      93              :     //       DATE WRITTEN   May 2000
      94              :     //       MODIFIED       Richard Raustad, FSEC Oct 2003
      95              :     //       RE-ENGINEERED  na
      96              : 
      97              :     // PURPOSE OF THIS MODULE:
      98              :     // To encapsulate the data and algorithms needed to simulate window air
      99              :     // conditioner units.
     100              : 
     101              :     // METHODOLOGY EMPLOYED:
     102              :     // Units are modeled as a collection of components: outside air mixer,
     103              :     // fan and DX coil. Control is by means of cycling: either continuous
     104              :     // air flow with the DX compressor cycling on/off or the entire unit -
     105              :     // fan and compressor cycling on/off. Cycling behavior is not explicitly
     106              :     // modeled - instead cycling inefficiencies must be included in the efficiency
     107              :     // curves of the DX module.
     108              : 
     109              :     using namespace DataLoopNode;
     110              :     using namespace DataSizing;
     111              :     using HVAC::CoilDX_CoolingHXAssisted;
     112              :     using HVAC::CoilDX_CoolingSingleSpeed;
     113              :     using HVAC::SmallAirVolFlow;
     114              :     using HVAC::SmallLoad;
     115              :     using HVAC::SmallMassFlow;
     116              :     using Psychrometrics::PsyCpAirFnW;
     117              :     using Psychrometrics::PsyHFnTdbW;
     118              :     using Psychrometrics::PsyRhoAirFnPbTdbW;
     119              : 
     120         5562 :     void SimWindowAC(EnergyPlusData &state,
     121              :                      std::string_view CompName,     // name of the window AC unit
     122              :                      int const ZoneNum,             // number of zone being served
     123              :                      bool const FirstHVACIteration, // TRUE if 1st HVAC simulation of system timestep
     124              :                      Real64 &PowerMet,              // Sensible power supplied by window AC (W)
     125              :                      Real64 &LatOutputProvided,     // Latent add/removal supplied by window AC (kg/s), dehumid = negative
     126              :                      int &CompIndex                 // component index
     127              :     )
     128              :     {
     129              : 
     130              :         // SUBROUTINE INFORMATION:
     131              :         //       AUTHOR         Fred Buhl
     132              :         //       DATE WRITTEN   May 2000
     133              :         //       MODIFIED       Don Shirey, Aug 2009 (LatOutputProvided)
     134              :         //       RE-ENGINEERED  na
     135              : 
     136              :         // PURPOSE OF THIS SUBROUTINE:
     137              :         // Manages the simulation of a window AC unit. Called from SimZone Equipment
     138              : 
     139              :         int WindACNum;                     // index of window AC unit being simulated
     140              :         Real64 QZnReq;                     // zone load (W)
     141              :         Real64 RemainingOutputToCoolingSP; // - remaining load to cooling setpoint (W)
     142              : 
     143              :         // First time SimWindowAC is called, get the input for all the window AC units
     144         5562 :         if (state.dataWindowAC->GetWindowACInputFlag) {
     145            3 :             GetWindowAC(state);
     146            3 :             state.dataWindowAC->GetWindowACInputFlag = false;
     147              :         }
     148              : 
     149              :         // Find the correct Window AC Equipment
     150         5562 :         if (CompIndex == 0) {
     151            6 :             WindACNum = Util::FindItemInList(CompName, state.dataWindowAC->WindAC);
     152            6 :             if (WindACNum == 0) {
     153            0 :                 ShowFatalError(state, format("SimWindowAC: Unit not found={}", CompName));
     154              :             }
     155            6 :             CompIndex = WindACNum;
     156              :         } else {
     157         5556 :             WindACNum = CompIndex;
     158         5556 :             if (WindACNum > state.dataWindowAC->NumWindAC || WindACNum < 1) {
     159            0 :                 ShowFatalError(state,
     160            0 :                                format("SimWindowAC:  Invalid CompIndex passed={}, Number of Units={}, Entered Unit name={}",
     161              :                                       WindACNum,
     162            0 :                                       state.dataWindowAC->NumWindAC,
     163              :                                       CompName));
     164              :             }
     165         5556 :             if (state.dataWindowAC->CheckEquipName(WindACNum)) {
     166            4 :                 if (CompName != state.dataWindowAC->WindAC(WindACNum).Name) {
     167            0 :                     ShowFatalError(state,
     168            0 :                                    format("SimWindowAC: Invalid CompIndex passed={}, Unit name={}, stored Unit Name for that index={}",
     169              :                                           WindACNum,
     170              :                                           CompName,
     171            0 :                                           state.dataWindowAC->WindAC(WindACNum).Name));
     172              :                 }
     173            4 :                 state.dataWindowAC->CheckEquipName(WindACNum) = false;
     174              :             }
     175              :         }
     176              : 
     177         5562 :         RemainingOutputToCoolingSP = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).RemainingOutputReqToCoolSP;
     178              : 
     179         5562 :         if (RemainingOutputToCoolingSP < 0.0 && state.dataHeatBalFanSys->TempControlType(ZoneNum) != HVAC::SetptType::SingleHeat) {
     180         2716 :             QZnReq = RemainingOutputToCoolingSP;
     181              :         } else {
     182         2846 :             QZnReq = 0.0;
     183              :         }
     184              : 
     185         5562 :         state.dataSize->ZoneEqDXCoil = true;
     186         5562 :         state.dataSize->ZoneCoolingOnlyFan = true;
     187              : 
     188              :         // Initialize the window AC unit
     189         5562 :         InitWindowAC(state, WindACNum, QZnReq, ZoneNum, FirstHVACIteration);
     190              : 
     191         5562 :         SimCyclingWindowAC(state, WindACNum, ZoneNum, FirstHVACIteration, PowerMet, QZnReq, LatOutputProvided);
     192              : 
     193              :         // Report the result of the simulation
     194         5562 :         ReportWindowAC(state, WindACNum);
     195              : 
     196         5562 :         state.dataSize->ZoneEqDXCoil = false;
     197         5562 :         state.dataSize->ZoneCoolingOnlyFan = false;
     198         5562 :     }
     199              : 
     200           10 :     void GetWindowAC(EnergyPlusData &state)
     201              :     {
     202              : 
     203              :         // SUBROUTINE INFORMATION:
     204              :         //       AUTHOR         Fred Buhl
     205              :         //       DATE WRITTEN   May 2000
     206              :         //       MODIFIED       Chandan Sharma, FSEC, March 2011: Added zone sys avail manager
     207              :         //                      Bereket Nigusse, FSEC, April 2011: eliminated input node names,
     208              :         //                                                         added OA Mixer object type
     209              :         //                                                         and fan object type
     210              :         //       RE-ENGINEERED  na
     211              : 
     212              :         // PURPOSE OF THIS SUBROUTINE:
     213              :         // Obtains input data for window AC units and stores it in window AC data structures
     214              : 
     215              :         // METHODOLOGY EMPLOYED:
     216              :         // Uses "Get" routines to read in data.
     217              : 
     218              :         using BranchNodeConnections::SetUpCompSets;
     219              : 
     220              :         using NodeInputManager::GetOnlySingleNode;
     221           10 :         auto &GetDXCoilOutletNode(DXCoils::GetCoilOutletNode);
     222           10 :         auto &GetDXHXAsstdCoilOutletNode(HVACHXAssistedCoolingCoil::GetCoilOutletNode);
     223              :         using MixedAir::GetOAMixerIndex;
     224              :         using MixedAir::GetOAMixerNodeNumbers;
     225              : 
     226              :         // SUBROUTINE PARAMETER DEFINITIONS:
     227              :         static constexpr std::string_view RoutineName("GetWindowAC: "); // include trailing blank space
     228              :         static constexpr std::string_view routineName = "GetWindowAC";  // include trailing blank space
     229              : 
     230              :         int WindACIndex; // loop index
     231              :         int WindACNum;   // current window AC number
     232           10 :         std::string CompSetFanInlet;
     233           10 :         std::string CompSetCoolInlet;
     234           10 :         std::string CompSetFanOutlet;
     235           10 :         std::string CompSetCoolOutlet;
     236              :         int NumAlphas;                   // Number of Alphas for each GetObjectItem call
     237              :         int NumNumbers;                  // Number of Numbers for each GetObjectItem call
     238           10 :         Array1D_int OANodeNums(4);       // Node numbers of Outdoor air mixer (OA, EA, RA, MA)
     239              :         int IOStatus;                    // Used in GetObjectItem
     240           10 :         bool ErrorsFound(false);         // Set to true if errors in input, fatal at end of routine
     241              :         Real64 FanVolFlow;               // Fan volumetric flow rate
     242              :         bool CoilNodeErrFlag;            // Used in error messages for mining coil outlet node number
     243           10 :         std::string CurrentModuleObject; // Object type for getting and error messages
     244           10 :         Array1D_string Alphas;           // Alpha input items for object
     245           10 :         Array1D_string cAlphaFields;     // Alpha field names
     246           10 :         Array1D_string cNumericFields;   // Numeric field names
     247           10 :         Array1D<Real64> Numbers;         // Numeric input items for object
     248           10 :         Array1D_bool lAlphaBlanks;       // Logical array, alpha field input BLANK = .TRUE.
     249           10 :         Array1D_bool lNumericBlanks;     // Logical array, numeric field input BLANK = .TRUE.
     250           10 :         int TotalArgs(0);                // Total number of alpha and numeric arguments (max) for a
     251              :         int CtrlZone;                    // index to loop counter
     252              :         int NodeNum;                     // index to loop counter
     253              :         bool ZoneNodeNotFound;           // used in error checking
     254              : 
     255              :         // find the number of each type of window AC unit
     256           10 :         CurrentModuleObject = "ZoneHVAC:WindowAirConditioner";
     257              : 
     258           10 :         state.dataWindowAC->NumWindACCyc = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
     259           10 :         state.dataWindowAC->NumWindAC = state.dataWindowAC->NumWindACCyc;
     260              :         // allocate the data structures
     261           10 :         state.dataWindowAC->WindAC.allocate(state.dataWindowAC->NumWindAC);
     262           10 :         state.dataWindowAC->CheckEquipName.dimension(state.dataWindowAC->NumWindAC, true);
     263           10 :         state.dataWindowAC->WindACNumericFields.allocate(state.dataWindowAC->NumWindAC);
     264              : 
     265           10 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, TotalArgs, NumAlphas, NumNumbers);
     266              : 
     267           10 :         Alphas.allocate(NumAlphas);
     268           10 :         cAlphaFields.allocate(NumAlphas);
     269           10 :         cNumericFields.allocate(NumNumbers);
     270           10 :         Numbers.dimension(NumNumbers, 0.0);
     271           10 :         lAlphaBlanks.dimension(NumAlphas, true);
     272           10 :         lNumericBlanks.dimension(NumNumbers, true);
     273              : 
     274              :         // loop over window AC units; get and load the input data
     275           14 :         for (WindACIndex = 1; WindACIndex <= state.dataWindowAC->NumWindACCyc; ++WindACIndex) {
     276              : 
     277            4 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     278              :                                                                      CurrentModuleObject,
     279              :                                                                      WindACIndex,
     280              :                                                                      Alphas,
     281              :                                                                      NumAlphas,
     282              :                                                                      Numbers,
     283              :                                                                      NumNumbers,
     284              :                                                                      IOStatus,
     285              :                                                                      lNumericBlanks,
     286              :                                                                      lAlphaBlanks,
     287              :                                                                      cAlphaFields,
     288              :                                                                      cNumericFields);
     289              : 
     290            4 :             WindACNum = WindACIndex;
     291              : 
     292            4 :             ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
     293              : 
     294            4 :             state.dataWindowAC->WindACNumericFields(WindACNum).FieldNames.allocate(NumNumbers);
     295            4 :             state.dataWindowAC->WindACNumericFields(WindACNum).FieldNames = "";
     296            4 :             state.dataWindowAC->WindACNumericFields(WindACNum).FieldNames = cNumericFields;
     297            4 :             Util::IsNameEmpty(state, Alphas(1), CurrentModuleObject, ErrorsFound);
     298              : 
     299            4 :             state.dataWindowAC->WindAC(WindACNum).Name = Alphas(1);
     300            4 :             state.dataWindowAC->WindAC(WindACNum).UnitType = state.dataWindowAC->WindowAC_UnitType; // 'ZoneHVAC:WindowAirConditioner'
     301              : 
     302            4 :             if (lAlphaBlanks(2)) {
     303            2 :                 state.dataWindowAC->WindAC(WindACNum).availSched = Sched::GetScheduleAlwaysOn(state);
     304            2 :             } else if ((state.dataWindowAC->WindAC(WindACNum).availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
     305            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
     306            0 :                 ErrorsFound = true;
     307              :             }
     308              : 
     309            4 :             state.dataWindowAC->WindAC(WindACNum).MaxAirVolFlow = Numbers(1);
     310            4 :             state.dataWindowAC->WindAC(WindACNum).OutAirVolFlow = Numbers(2);
     311              : 
     312            8 :             state.dataWindowAC->WindAC(WindACNum).AirInNode = GetOnlySingleNode(state,
     313            4 :                                                                                 Alphas(3),
     314              :                                                                                 ErrorsFound,
     315              :                                                                                 DataLoopNode::ConnectionObjectType::ZoneHVACWindowAirConditioner,
     316            4 :                                                                                 Alphas(1),
     317              :                                                                                 DataLoopNode::NodeFluidType::Air,
     318              :                                                                                 DataLoopNode::ConnectionType::Inlet,
     319              :                                                                                 NodeInputManager::CompFluidStream::Primary,
     320              :                                                                                 ObjectIsParent);
     321              : 
     322            8 :             state.dataWindowAC->WindAC(WindACNum).AirOutNode = GetOnlySingleNode(state,
     323            4 :                                                                                  Alphas(4),
     324              :                                                                                  ErrorsFound,
     325              :                                                                                  DataLoopNode::ConnectionObjectType::ZoneHVACWindowAirConditioner,
     326            4 :                                                                                  Alphas(1),
     327              :                                                                                  DataLoopNode::NodeFluidType::Air,
     328              :                                                                                  DataLoopNode::ConnectionType::Outlet,
     329              :                                                                                  NodeInputManager::CompFluidStream::Primary,
     330              :                                                                                  ObjectIsParent);
     331              : 
     332            4 :             state.dataWindowAC->WindAC(WindACNum).OAMixType = Alphas(5);
     333            4 :             state.dataWindowAC->WindAC(WindACNum).OAMixName = Alphas(6);
     334              :             // Get outdoor air mixer node numbers
     335            4 :             bool errFlag = false;
     336            8 :             ValidateComponent(state,
     337            4 :                               state.dataWindowAC->WindAC(WindACNum).OAMixType,
     338            4 :                               state.dataWindowAC->WindAC(WindACNum).OAMixName,
     339              :                               errFlag,
     340              :                               CurrentModuleObject);
     341            4 :             if (errFlag) {
     342            0 :                 ShowContinueError(state, format("specified in {} = \"{}\".", CurrentModuleObject, state.dataWindowAC->WindAC(WindACNum).Name));
     343            0 :                 ErrorsFound = true;
     344              :             } else {
     345              :                 // Get outdoor air mixer node numbers
     346            4 :                 OANodeNums = GetOAMixerNodeNumbers(state, state.dataWindowAC->WindAC(WindACNum).OAMixName, errFlag);
     347            4 :                 if (errFlag) {
     348            0 :                     ShowContinueError(state,
     349            0 :                                       format("that was specified in {} = \"{}\"", CurrentModuleObject, state.dataWindowAC->WindAC(WindACNum).Name));
     350            0 :                     ShowContinueError(state, "..OutdoorAir:Mixer is required. Enter an OutdoorAir:Mixer object with this name.");
     351            0 :                     ErrorsFound = true;
     352              :                 } else {
     353            4 :                     state.dataWindowAC->WindAC(WindACNum).OutsideAirNode = OANodeNums(1);
     354            4 :                     state.dataWindowAC->WindAC(WindACNum).AirReliefNode = OANodeNums(2);
     355            4 :                     state.dataWindowAC->WindAC(WindACNum).ReturnAirNode = OANodeNums(3);
     356            4 :                     state.dataWindowAC->WindAC(WindACNum).MixedAirNode = OANodeNums(4);
     357              :                 }
     358              :             }
     359              : 
     360            4 :             auto &windAC = state.dataWindowAC->WindAC(WindACNum);
     361              : 
     362            4 :             windAC.FanName = Alphas(8);
     363              : 
     364            4 :             windAC.fanType = static_cast<HVAC::FanType>(getEnumValue(HVAC::fanTypeNamesUC, Alphas(7)));
     365              : 
     366            4 :             if (windAC.fanType != HVAC::FanType::OnOff && windAC.fanType != HVAC::FanType::Constant && windAC.fanType != HVAC::FanType::SystemModel) {
     367            0 :                 ShowSevereInvalidKey(state, eoh, cAlphaFields(8), Alphas(8), "Fan Type must be Fan:OnOff, Fan:ConstantVolume, or Fan:SystemModel.");
     368              : 
     369            4 :             } else if ((windAC.FanIndex = Fans::GetFanIndex(state, windAC.FanName)) == 0) {
     370            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(8), windAC.FanName);
     371              : 
     372              :             } else {
     373            4 :                 auto *fan = state.dataFans->fans(windAC.FanIndex);
     374            4 :                 assert(windAC.fanType == fan->type);
     375              : 
     376            4 :                 FanVolFlow = fan->maxAirFlowRate;
     377            4 :                 if (FanVolFlow != AutoSize) {
     378            0 :                     if (FanVolFlow < windAC.MaxAirVolFlow) {
     379            0 :                         ShowWarningError(state,
     380            0 :                                          format("Air flow rate = {:.7T} in fan object {} is less than the maximum supply air flow "
     381              :                                                 "rate ({:.7T}) in the {} object.",
     382              :                                                 FanVolFlow,
     383            0 :                                                 windAC.FanName,
     384            0 :                                                 windAC.MaxAirVolFlow,
     385              :                                                 CurrentModuleObject));
     386            0 :                         ShowContinueError(
     387            0 :                             state, format(" The fan flow rate must be >= to the {} in the {} object.", cNumericFields(1), CurrentModuleObject));
     388            0 :                         ShowContinueError(state, format(" Occurs in {} = {}", CurrentModuleObject, state.dataWindowAC->WindAC(WindACNum).Name));
     389            0 :                         ErrorsFound = true;
     390              :                     }
     391              :                 }
     392            4 :                 windAC.fanAvailSched = fan->availSched;
     393              :             }
     394              : 
     395            4 :             state.dataWindowAC->WindAC(WindACNum).DXCoilName = Alphas(10);
     396              : 
     397            6 :             if (Util::SameString(Alphas(9), "Coil:Cooling:DX:SingleSpeed") ||
     398            6 :                 Util::SameString(Alphas(9), "CoilSystem:Cooling:DX:HeatExchangerAssisted") ||
     399            6 :                 Util::SameString(Alphas(9), "Coil:Cooling:DX:VariableSpeed")) {
     400            4 :                 state.dataWindowAC->WindAC(WindACNum).DXCoilType = Alphas(9);
     401            4 :                 CoilNodeErrFlag = false;
     402            4 :                 if (Util::SameString(Alphas(9), "Coil:Cooling:DX:SingleSpeed")) {
     403            2 :                     state.dataWindowAC->WindAC(WindACNum).DXCoilType_Num = CoilDX_CoolingSingleSpeed;
     404            2 :                     state.dataWindowAC->WindAC(WindACNum).CoilOutletNodeNum = GetDXCoilOutletNode(
     405            2 :                         state, state.dataWindowAC->WindAC(WindACNum).DXCoilType, state.dataWindowAC->WindAC(WindACNum).DXCoilName, CoilNodeErrFlag);
     406            2 :                 } else if (Util::SameString(Alphas(9), "CoilSystem:Cooling:DX:HeatExchangerAssisted")) {
     407            0 :                     state.dataWindowAC->WindAC(WindACNum).DXCoilType_Num = CoilDX_CoolingHXAssisted;
     408            0 :                     state.dataWindowAC->WindAC(WindACNum).CoilOutletNodeNum = GetDXHXAsstdCoilOutletNode(
     409            0 :                         state, state.dataWindowAC->WindAC(WindACNum).DXCoilType, state.dataWindowAC->WindAC(WindACNum).DXCoilName, CoilNodeErrFlag);
     410            2 :                 } else if (Util::SameString(Alphas(9), "Coil:Cooling:DX:VariableSpeed")) {
     411            2 :                     state.dataWindowAC->WindAC(WindACNum).DXCoilType_Num = HVAC::Coil_CoolingAirToAirVariableSpeed;
     412            2 :                     state.dataWindowAC->WindAC(WindACNum).CoilOutletNodeNum = VariableSpeedCoils::GetCoilOutletNodeVariableSpeed(
     413            2 :                         state, state.dataWindowAC->WindAC(WindACNum).DXCoilType, state.dataWindowAC->WindAC(WindACNum).DXCoilName, CoilNodeErrFlag);
     414            2 :                     state.dataWindowAC->WindAC(WindACNum).DXCoilNumOfSpeeds =
     415            2 :                         VariableSpeedCoils::GetVSCoilNumOfSpeeds(state, state.dataWindowAC->WindAC(WindACNum).DXCoilName, ErrorsFound);
     416              :                 }
     417            4 :                 if (CoilNodeErrFlag) {
     418            0 :                     ShowContinueError(state,
     419            0 :                                       format(" that was specified in {} = \"{}\".", CurrentModuleObject, state.dataWindowAC->WindAC(WindACNum).Name));
     420            0 :                     ErrorsFound = true;
     421              :                 }
     422              :             } else {
     423            0 :                 ShowWarningError(state, format("Invalid {} = {}", cAlphaFields(9), Alphas(9)));
     424            0 :                 ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, state.dataWindowAC->WindAC(WindACNum).Name));
     425            0 :                 ErrorsFound = true;
     426              :             }
     427              : 
     428            4 :             if (lAlphaBlanks(11)) {
     429            2 :                 state.dataWindowAC->WindAC(WindACNum).fanOp = HVAC::FanOp::Cycling;
     430            2 :             } else if ((state.dataWindowAC->WindAC(WindACNum).fanOpModeSched = Sched::GetSchedule(state, Alphas(11))) == nullptr) {
     431            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(11), Alphas(11));
     432            0 :                 ErrorsFound = true;
     433              :             }
     434              : 
     435            4 :             state.dataWindowAC->WindAC(WindACNum).fanPlace = static_cast<HVAC::FanPlace>(getEnumValue(HVAC::fanPlaceNamesUC, Alphas(12)));
     436            4 :             assert(state.dataWindowAC->WindAC(WindACNum).fanPlace != HVAC::FanPlace::Invalid);
     437              : 
     438            4 :             state.dataWindowAC->WindAC(WindACNum).ConvergenceTol = Numbers(3);
     439              : 
     440            4 :             if (!lAlphaBlanks(13)) {
     441            0 :                 state.dataWindowAC->WindAC(WindACNum).AvailManagerListName = Alphas(13);
     442              :             }
     443              : 
     444            4 :             state.dataWindowAC->WindAC(WindACNum).HVACSizingIndex = 0;
     445            4 :             if (!lAlphaBlanks(14)) {
     446            1 :                 state.dataWindowAC->WindAC(WindACNum).HVACSizingIndex = Util::FindItemInList(Alphas(14), state.dataSize->ZoneHVACSizing);
     447            1 :                 if (state.dataWindowAC->WindAC(WindACNum).HVACSizingIndex == 0) {
     448            0 :                     ShowSevereError(state, format("{} = {} not found.", cAlphaFields(14), Alphas(14)));
     449            0 :                     ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, state.dataWindowAC->WindAC(WindACNum).Name));
     450            0 :                     ErrorsFound = true;
     451              :                 }
     452              :             }
     453              : 
     454              :             // Add fan to component sets array
     455            4 :             if (state.dataWindowAC->WindAC(WindACNum).fanPlace == HVAC::FanPlace::BlowThru) {
     456              : 
     457              :                 // Window AC air inlet node must be the same as a zone exhaust node and the OA Mixer return node
     458              :                 // check that Window AC air inlet node is the same as a zone exhaust node.
     459            4 :                 ZoneNodeNotFound = true;
     460           10 :                 for (CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
     461            6 :                     if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) continue;
     462            8 :                     for (NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumExhaustNodes; ++NodeNum) {
     463            6 :                         if (state.dataWindowAC->WindAC(WindACNum).AirInNode == state.dataZoneEquip->ZoneEquipConfig(CtrlZone).ExhaustNode(NodeNum)) {
     464            4 :                             ZoneNodeNotFound = false;
     465            4 :                             break;
     466              :                         }
     467              :                     }
     468              :                 }
     469            4 :                 if (ZoneNodeNotFound) {
     470            0 :                     ShowSevereError(state,
     471            0 :                                     format("{} = \"{}\". Window AC air inlet node name must be the same as a zone exhaust node name.",
     472              :                                            CurrentModuleObject,
     473            0 :                                            state.dataWindowAC->WindAC(WindACNum).Name));
     474            0 :                     ShowContinueError(state, "..Zone exhaust node name is specified in ZoneHVAC:EquipmentConnections object.");
     475            0 :                     ShowContinueError(
     476              :                         state,
     477            0 :                         format("..Window AC air inlet node name = {}", state.dataLoopNodes->NodeID(state.dataWindowAC->WindAC(WindACNum).AirInNode)));
     478            0 :                     ErrorsFound = true;
     479              :                 }
     480              :                 // check that Window AC air outlet node is a zone inlet node.
     481            4 :                 ZoneNodeNotFound = true;
     482           10 :                 for (CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
     483            6 :                     if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) continue;
     484            8 :                     for (NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumInletNodes; ++NodeNum) {
     485            6 :                         if (state.dataWindowAC->WindAC(WindACNum).AirOutNode == state.dataZoneEquip->ZoneEquipConfig(CtrlZone).InletNode(NodeNum)) {
     486            4 :                             state.dataWindowAC->WindAC(WindACNum).ZonePtr = CtrlZone;
     487            4 :                             ZoneNodeNotFound = false;
     488            4 :                             break;
     489              :                         }
     490              :                     }
     491              :                 }
     492            4 :                 if (ZoneNodeNotFound) {
     493            0 :                     ShowSevereError(state,
     494            0 :                                     format("{} = \"{}\". Window AC air outlet node name must be the same as a zone inlet node name.",
     495              :                                            CurrentModuleObject,
     496            0 :                                            state.dataWindowAC->WindAC(WindACNum).Name));
     497            0 :                     ShowContinueError(state, "..Zone inlet node name is specified in ZoneHVAC:EquipmentConnections object.");
     498            0 :                     ShowContinueError(state,
     499            0 :                                       format("..Window AC air outlet node name = {}",
     500            0 :                                              state.dataLoopNodes->NodeID(state.dataWindowAC->WindAC(WindACNum).AirOutNode)));
     501            0 :                     ErrorsFound = true;
     502              :                 }
     503            4 :                 CompSetFanInlet = state.dataLoopNodes->NodeID(state.dataWindowAC->WindAC(WindACNum).MixedAirNode);
     504            4 :                 CompSetFanOutlet = "UNDEFINED";
     505            4 :                 CompSetCoolInlet = "UNDEFINED";
     506            4 :                 CompSetCoolOutlet = state.dataLoopNodes->NodeID(state.dataWindowAC->WindAC(WindACNum).AirOutNode);
     507              :             } else { // draw through fan from IF (WindAC(WindACNum)%FanPlace == BlowThru) THEN
     508              :                 // check that Window AC air inlet node is the same as a zone exhaust node.
     509            0 :                 ZoneNodeNotFound = true;
     510            0 :                 for (CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
     511            0 :                     if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) continue;
     512            0 :                     for (NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumExhaustNodes; ++NodeNum) {
     513            0 :                         if (state.dataWindowAC->WindAC(WindACNum).AirInNode == state.dataZoneEquip->ZoneEquipConfig(CtrlZone).ExhaustNode(NodeNum)) {
     514            0 :                             ZoneNodeNotFound = false;
     515            0 :                             break;
     516              :                         }
     517              :                     }
     518              :                 }
     519            0 :                 if (ZoneNodeNotFound) {
     520            0 :                     ShowSevereError(state,
     521            0 :                                     format("{} = \"{}\". Window AC air inlet node name must be the same as a zone exhaust node name.",
     522              :                                            CurrentModuleObject,
     523            0 :                                            state.dataWindowAC->WindAC(WindACNum).Name));
     524            0 :                     ShowContinueError(state, "..Zone exhaust node name is specified in ZoneHVAC:EquipmentConnections object.");
     525            0 :                     ShowContinueError(
     526              :                         state,
     527            0 :                         format("..Window AC inlet node name = {}", state.dataLoopNodes->NodeID(state.dataWindowAC->WindAC(WindACNum).AirInNode)));
     528            0 :                     ErrorsFound = true;
     529              :                 }
     530              :                 // check that Window AC air outlet node is the same as a zone inlet node.
     531            0 :                 ZoneNodeNotFound = true;
     532            0 :                 for (CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
     533            0 :                     if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) continue;
     534            0 :                     for (NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumInletNodes; ++NodeNum) {
     535            0 :                         if (state.dataWindowAC->WindAC(WindACNum).AirOutNode == state.dataZoneEquip->ZoneEquipConfig(CtrlZone).InletNode(NodeNum)) {
     536            0 :                             state.dataWindowAC->WindAC(WindACNum).ZonePtr = CtrlZone;
     537            0 :                             ZoneNodeNotFound = false;
     538            0 :                             break;
     539              :                         }
     540              :                     }
     541              :                 }
     542            0 :                 if (ZoneNodeNotFound) {
     543            0 :                     ShowSevereError(state,
     544            0 :                                     format("{} = \"{}\". Window AC air outlet node name must be the same as a zone inlet node name.",
     545              :                                            CurrentModuleObject,
     546            0 :                                            state.dataWindowAC->WindAC(WindACNum).Name));
     547            0 :                     ShowContinueError(state, "..Zone inlet node name is specified in ZoneHVAC:EquipmentConnections object.");
     548            0 :                     ShowContinueError(
     549              :                         state,
     550            0 :                         format("..Window AC outlet node name = {}", state.dataLoopNodes->NodeID(state.dataWindowAC->WindAC(WindACNum).AirOutNode)));
     551            0 :                     ErrorsFound = true;
     552              :                 }
     553            0 :                 CompSetFanInlet = state.dataLoopNodes->NodeID(state.dataWindowAC->WindAC(WindACNum).CoilOutletNodeNum);
     554            0 :                 CompSetFanOutlet = state.dataLoopNodes->NodeID(state.dataWindowAC->WindAC(WindACNum).AirOutNode);
     555            0 :                 CompSetCoolInlet = state.dataLoopNodes->NodeID(state.dataWindowAC->WindAC(WindACNum).MixedAirNode);
     556            0 :                 CompSetCoolOutlet = state.dataLoopNodes->NodeID(state.dataWindowAC->WindAC(WindACNum).CoilOutletNodeNum);
     557              :             }
     558              :             // Add fan to component sets array
     559            8 :             SetUpCompSets(state,
     560            4 :                           state.dataWindowAC->cWindowAC_UnitTypes(state.dataWindowAC->WindAC(WindACNum).UnitType),
     561            4 :                           state.dataWindowAC->WindAC(WindACNum).Name,
     562            4 :                           HVAC::fanTypeNames[(int)state.dataWindowAC->WindAC(WindACNum).fanType],
     563            4 :                           state.dataWindowAC->WindAC(WindACNum).FanName,
     564              :                           CompSetFanInlet,
     565              :                           CompSetFanOutlet);
     566              : 
     567              :             // Add cooling coil to component sets array
     568            8 :             SetUpCompSets(state,
     569            4 :                           state.dataWindowAC->cWindowAC_UnitTypes(state.dataWindowAC->WindAC(WindACNum).UnitType),
     570            4 :                           state.dataWindowAC->WindAC(WindACNum).Name,
     571            4 :                           state.dataWindowAC->WindAC(WindACNum).DXCoilType,
     572            4 :                           state.dataWindowAC->WindAC(WindACNum).DXCoilName,
     573              :                           CompSetCoolInlet,
     574              :                           CompSetCoolOutlet);
     575              : 
     576              :             // Set up component set for OA mixer - use OA node and Mixed air node
     577            8 :             SetUpCompSets(state,
     578            4 :                           state.dataWindowAC->cWindowAC_UnitTypes(state.dataWindowAC->WindAC(WindACNum).UnitType),
     579            4 :                           state.dataWindowAC->WindAC(WindACNum).Name,
     580            4 :                           state.dataWindowAC->WindAC(WindACNum).OAMixType,
     581            4 :                           state.dataWindowAC->WindAC(WindACNum).OAMixName,
     582            4 :                           state.dataLoopNodes->NodeID(state.dataWindowAC->WindAC(WindACNum).OutsideAirNode),
     583            4 :                           state.dataLoopNodes->NodeID(state.dataWindowAC->WindAC(WindACNum).MixedAirNode));
     584              :         }
     585              : 
     586           10 :         Alphas.deallocate();
     587           10 :         cAlphaFields.deallocate();
     588           10 :         cNumericFields.deallocate();
     589           10 :         Numbers.deallocate();
     590           10 :         lAlphaBlanks.deallocate();
     591           10 :         lNumericBlanks.deallocate();
     592              : 
     593           10 :         if (ErrorsFound) {
     594            0 :             ShowFatalError(state,
     595            0 :                            format("{}Errors found in getting {} input.  Preceding condition causes termination.", RoutineName, CurrentModuleObject));
     596              :         }
     597              : 
     598           14 :         for (WindACNum = 1; WindACNum <= state.dataWindowAC->NumWindAC; ++WindACNum) {
     599              :             // Setup Report variables for the Fan Coils
     600            8 :             SetupOutputVariable(state,
     601              :                                 "Zone Window Air Conditioner Total Cooling Rate",
     602              :                                 Constant::Units::W,
     603            4 :                                 state.dataWindowAC->WindAC(WindACNum).TotCoolEnergyRate,
     604              :                                 OutputProcessor::TimeStepType::System,
     605              :                                 OutputProcessor::StoreType::Average,
     606            4 :                                 state.dataWindowAC->WindAC(WindACNum).Name);
     607            8 :             SetupOutputVariable(state,
     608              :                                 "Zone Window Air Conditioner Total Cooling Energy",
     609              :                                 Constant::Units::J,
     610            4 :                                 state.dataWindowAC->WindAC(WindACNum).TotCoolEnergy,
     611              :                                 OutputProcessor::TimeStepType::System,
     612              :                                 OutputProcessor::StoreType::Sum,
     613            4 :                                 state.dataWindowAC->WindAC(WindACNum).Name);
     614            8 :             SetupOutputVariable(state,
     615              :                                 "Zone Window Air Conditioner Sensible Cooling Rate",
     616              :                                 Constant::Units::W,
     617            4 :                                 state.dataWindowAC->WindAC(WindACNum).SensCoolEnergyRate,
     618              :                                 OutputProcessor::TimeStepType::System,
     619              :                                 OutputProcessor::StoreType::Average,
     620            4 :                                 state.dataWindowAC->WindAC(WindACNum).Name);
     621            8 :             SetupOutputVariable(state,
     622              :                                 "Zone Window Air Conditioner Sensible Cooling Energy",
     623              :                                 Constant::Units::J,
     624            4 :                                 state.dataWindowAC->WindAC(WindACNum).SensCoolEnergy,
     625              :                                 OutputProcessor::TimeStepType::System,
     626              :                                 OutputProcessor::StoreType::Sum,
     627            4 :                                 state.dataWindowAC->WindAC(WindACNum).Name);
     628            8 :             SetupOutputVariable(state,
     629              :                                 "Zone Window Air Conditioner Latent Cooling Rate",
     630              :                                 Constant::Units::W,
     631            4 :                                 state.dataWindowAC->WindAC(WindACNum).LatCoolEnergyRate,
     632              :                                 OutputProcessor::TimeStepType::System,
     633              :                                 OutputProcessor::StoreType::Average,
     634            4 :                                 state.dataWindowAC->WindAC(WindACNum).Name);
     635            8 :             SetupOutputVariable(state,
     636              :                                 "Zone Window Air Conditioner Latent Cooling Energy",
     637              :                                 Constant::Units::J,
     638            4 :                                 state.dataWindowAC->WindAC(WindACNum).LatCoolEnergy,
     639              :                                 OutputProcessor::TimeStepType::System,
     640              :                                 OutputProcessor::StoreType::Sum,
     641            4 :                                 state.dataWindowAC->WindAC(WindACNum).Name);
     642            8 :             SetupOutputVariable(state,
     643              :                                 "Zone Window Air Conditioner Electricity Rate",
     644              :                                 Constant::Units::W,
     645            4 :                                 state.dataWindowAC->WindAC(WindACNum).ElecPower,
     646              :                                 OutputProcessor::TimeStepType::System,
     647              :                                 OutputProcessor::StoreType::Average,
     648            4 :                                 state.dataWindowAC->WindAC(WindACNum).Name);
     649            8 :             SetupOutputVariable(state,
     650              :                                 "Zone Window Air Conditioner Electricity Energy",
     651              :                                 Constant::Units::J,
     652            4 :                                 state.dataWindowAC->WindAC(WindACNum).ElecConsumption,
     653              :                                 OutputProcessor::TimeStepType::System,
     654              :                                 OutputProcessor::StoreType::Sum,
     655            4 :                                 state.dataWindowAC->WindAC(WindACNum).Name);
     656            8 :             SetupOutputVariable(state,
     657              :                                 "Zone Window Air Conditioner Fan Part Load Ratio",
     658              :                                 Constant::Units::None,
     659            4 :                                 state.dataWindowAC->WindAC(WindACNum).FanPartLoadRatio,
     660              :                                 OutputProcessor::TimeStepType::System,
     661              :                                 OutputProcessor::StoreType::Average,
     662            4 :                                 state.dataWindowAC->WindAC(WindACNum).Name);
     663            8 :             SetupOutputVariable(state,
     664              :                                 "Zone Window Air Conditioner Compressor Part Load Ratio",
     665              :                                 Constant::Units::None,
     666            4 :                                 state.dataWindowAC->WindAC(WindACNum).CompPartLoadRatio,
     667              :                                 OutputProcessor::TimeStepType::System,
     668              :                                 OutputProcessor::StoreType::Average,
     669            4 :                                 state.dataWindowAC->WindAC(WindACNum).Name);
     670            4 :             SetupOutputVariable(state,
     671              :                                 "Zone Window Air Conditioner Fan Availability Status",
     672              :                                 Constant::Units::None,
     673            4 :                                 (int &)state.dataWindowAC->WindAC(WindACNum).availStatus,
     674              :                                 OutputProcessor::TimeStepType::System,
     675              :                                 OutputProcessor::StoreType::Average,
     676            4 :                                 state.dataWindowAC->WindAC(WindACNum).Name);
     677            4 :             if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
     678            0 :                 SetupEMSActuator(state,
     679              :                                  "Window Air Conditioner",
     680            0 :                                  state.dataWindowAC->WindAC(WindACNum).Name,
     681              :                                  "Part Load Ratio",
     682              :                                  "[fraction]",
     683            0 :                                  state.dataWindowAC->WindAC(WindACNum).EMSOverridePartLoadFrac,
     684            0 :                                  state.dataWindowAC->WindAC(WindACNum).EMSValueForPartLoadFrac);
     685              :             }
     686              :         }
     687           14 :         for (WindACNum = 1; WindACNum <= state.dataWindowAC->NumWindAC; ++WindACNum) {
     688            4 :             state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(state,
     689            4 :                                                                                      state.dataWindowAC->WindAC(WindACNum).DXCoilName,
     690            4 :                                                                                      state.dataWindowAC->WindAC(WindACNum).DXCoilType,
     691            4 :                                                                                      state.dataWindowAC->WindAC(WindACNum).FanName,
     692            4 :                                                                                      state.dataWindowAC->WindAC(WindACNum).fanType,
     693            4 :                                                                                      state.dataWindowAC->WindAC(WindACNum).FanIndex);
     694              :         }
     695           10 :     }
     696              : 
     697         5562 :     void InitWindowAC(EnergyPlusData &state,
     698              :                       int const WindACNum,          // number of the current window AC unit being simulated
     699              :                       Real64 &QZnReq,               // zone load (modified as needed) (W)
     700              :                       int const ZoneNum,            // index to zone
     701              :                       bool const FirstHVACIteration // TRUE when first HVAC iteration
     702              :     )
     703              :     {
     704              : 
     705              :         // SUBROUTINE INFORMATION:
     706              :         //       AUTHOR         Fred Buhl
     707              :         //       DATE WRITTEN   May 2000
     708              :         //       MODIFIED       Chandan Sharma, FSEC, March 2011: Added zone sys avail manager
     709              : 
     710              :         // PURPOSE OF THIS SUBROUTINE:
     711              :         // This subroutine is for initializations of the Window AC Components.
     712              : 
     713              :         // METHODOLOGY EMPLOYED:
     714              :         // Uses the status flags to trigger initializations.
     715              : 
     716              :         // Do the one time initializations
     717         5562 :         if (state.dataWindowAC->MyOneTimeFlag) {
     718              : 
     719            3 :             state.dataWindowAC->MyEnvrnFlag.allocate(state.dataWindowAC->NumWindAC);
     720            3 :             state.dataWindowAC->MySizeFlag.allocate(state.dataWindowAC->NumWindAC);
     721            3 :             state.dataWindowAC->MyZoneEqFlag.allocate(state.dataWindowAC->NumWindAC);
     722            3 :             state.dataWindowAC->MyEnvrnFlag = true;
     723            3 :             state.dataWindowAC->MySizeFlag = true;
     724            3 :             state.dataWindowAC->MyZoneEqFlag = true;
     725            3 :             state.dataWindowAC->MyOneTimeFlag = false;
     726              :         }
     727              : 
     728         5562 :         if (allocated(state.dataAvail->ZoneComp)) {
     729         5558 :             auto &availMgr = state.dataAvail->ZoneComp(DataZoneEquipment::ZoneEquipType::WindowAirConditioner).ZoneCompAvailMgrs(WindACNum);
     730         5558 :             if (state.dataWindowAC->MyZoneEqFlag(WindACNum)) { // initialize the name of each availability manager list and zone number
     731            4 :                 availMgr.AvailManagerListName = state.dataWindowAC->WindAC(WindACNum).AvailManagerListName;
     732            4 :                 availMgr.ZoneNum = ZoneNum;
     733            4 :                 state.dataWindowAC->MyZoneEqFlag(WindACNum) = false;
     734              :             }
     735         5558 :             state.dataWindowAC->WindAC(WindACNum).availStatus = availMgr.availStatus;
     736              :         }
     737              : 
     738              :         // need to check all Window AC units to see if they are on Zone Equipment List or issue warning
     739         5562 :         if (!state.dataWindowAC->ZoneEquipmentListChecked && state.dataZoneEquip->ZoneEquipInputsFilled) {
     740            3 :             state.dataWindowAC->ZoneEquipmentListChecked = true;
     741            7 :             for (int Loop = 1; Loop <= state.dataWindowAC->NumWindAC; ++Loop) {
     742            8 :                 if (DataZoneEquipment::CheckZoneEquipmentList(state,
     743            4 :                                                               state.dataWindowAC->cWindowAC_UnitTypes(state.dataWindowAC->WindAC(Loop).UnitType),
     744            4 :                                                               state.dataWindowAC->WindAC(Loop).Name))
     745            4 :                     continue;
     746            0 :                 ShowSevereError(state,
     747            0 :                                 format("InitWindowAC: Window AC Unit=[{},{}] is not on any ZoneHVAC:EquipmentList.  It will not be simulated.",
     748            0 :                                        state.dataWindowAC->cWindowAC_UnitTypes(state.dataWindowAC->WindAC(Loop).UnitType),
     749            0 :                                        state.dataWindowAC->WindAC(Loop).Name));
     750              :             }
     751              :         }
     752              : 
     753         5562 :         if (!state.dataGlobal->SysSizingCalc && state.dataWindowAC->MySizeFlag(WindACNum)) {
     754              : 
     755            4 :             SizeWindowAC(state, WindACNum);
     756              : 
     757            4 :             state.dataWindowAC->MySizeFlag(WindACNum) = false;
     758              :         }
     759              : 
     760              :         // Do the Begin Environment initializations
     761         5562 :         if (state.dataGlobal->BeginEnvrnFlag && state.dataWindowAC->MyEnvrnFlag(WindACNum)) {
     762           10 :             int InNode = state.dataWindowAC->WindAC(WindACNum).AirInNode;
     763           10 :             int OutNode = state.dataWindowAC->WindAC(WindACNum).AirOutNode;
     764           10 :             int OutsideAirNode = state.dataWindowAC->WindAC(WindACNum).OutsideAirNode;
     765           10 :             Real64 RhoAir = state.dataEnvrn->StdRhoAir;
     766              :             // set the mass flow rates from the input volume flow rates
     767           10 :             state.dataWindowAC->WindAC(WindACNum).MaxAirMassFlow = RhoAir * state.dataWindowAC->WindAC(WindACNum).MaxAirVolFlow;
     768           10 :             state.dataWindowAC->WindAC(WindACNum).OutAirMassFlow = RhoAir * state.dataWindowAC->WindAC(WindACNum).OutAirVolFlow;
     769              :             // set the node max and min mass flow rates
     770           10 :             state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMax = state.dataWindowAC->WindAC(WindACNum).OutAirMassFlow;
     771           10 :             state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMin = 0.0;
     772           10 :             state.dataLoopNodes->Node(OutNode).MassFlowRateMax = state.dataWindowAC->WindAC(WindACNum).MaxAirMassFlow;
     773           10 :             state.dataLoopNodes->Node(OutNode).MassFlowRateMin = 0.0;
     774           10 :             state.dataLoopNodes->Node(InNode).MassFlowRateMax = state.dataWindowAC->WindAC(WindACNum).MaxAirMassFlow;
     775           10 :             state.dataLoopNodes->Node(InNode).MassFlowRateMin = 0.0;
     776           10 :             state.dataWindowAC->MyEnvrnFlag(WindACNum) = false;
     777              :         } // end one time inits
     778              : 
     779         5562 :         if (!state.dataGlobal->BeginEnvrnFlag) {
     780         5512 :             state.dataWindowAC->MyEnvrnFlag(WindACNum) = true;
     781              :         }
     782              : 
     783         5562 :         if (state.dataWindowAC->WindAC(WindACNum).fanOpModeSched != nullptr) {
     784         5542 :             if (state.dataWindowAC->WindAC(WindACNum).fanOpModeSched->getCurrentVal() == 0.0) {
     785            0 :                 state.dataWindowAC->WindAC(WindACNum).fanOp = HVAC::FanOp::Cycling;
     786              :             } else {
     787         5542 :                 state.dataWindowAC->WindAC(WindACNum).fanOp = HVAC::FanOp::Continuous;
     788              :             }
     789              :         }
     790              : 
     791              :         // These initializations are done every iteration
     792         5562 :         int InletNode = state.dataWindowAC->WindAC(WindACNum).AirInNode;
     793         5562 :         int OutsideAirNode = state.dataWindowAC->WindAC(WindACNum).OutsideAirNode;
     794         5562 :         int AirRelNode = state.dataWindowAC->WindAC(WindACNum).AirReliefNode;
     795              :         // Set the inlet node mass flow rate
     796        11124 :         if (state.dataWindowAC->WindAC(WindACNum).availSched->getCurrentVal() <= 0.0 ||
     797        11124 :             (state.dataWindowAC->WindAC(WindACNum).fanAvailSched->getCurrentVal() <= 0.0 && !state.dataHVACGlobal->TurnFansOn) ||
     798         5562 :             state.dataHVACGlobal->TurnFansOff) {
     799            0 :             state.dataWindowAC->WindAC(WindACNum).PartLoadFrac = 0.0;
     800            0 :             state.dataLoopNodes->Node(InletNode).MassFlowRate = 0.0;
     801            0 :             state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = 0.0;
     802            0 :             state.dataLoopNodes->Node(InletNode).MassFlowRateMinAvail = 0.0;
     803            0 :             state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate = 0.0;
     804            0 :             state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMaxAvail = 0.0;
     805            0 :             state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMinAvail = 0.0;
     806            0 :             state.dataLoopNodes->Node(AirRelNode).MassFlowRate = 0.0;
     807            0 :             state.dataLoopNodes->Node(AirRelNode).MassFlowRateMaxAvail = 0.0;
     808            0 :             state.dataLoopNodes->Node(AirRelNode).MassFlowRateMinAvail = 0.0;
     809              :         } else {
     810         5562 :             state.dataWindowAC->WindAC(WindACNum).PartLoadFrac = 1.0;
     811         5562 :             state.dataLoopNodes->Node(InletNode).MassFlowRate = state.dataWindowAC->WindAC(WindACNum).MaxAirMassFlow;
     812         5562 :             state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = state.dataLoopNodes->Node(InletNode).MassFlowRate;
     813         5562 :             state.dataLoopNodes->Node(InletNode).MassFlowRateMinAvail = state.dataLoopNodes->Node(InletNode).MassFlowRate;
     814         5562 :             state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate = state.dataWindowAC->WindAC(WindACNum).OutAirMassFlow;
     815         5562 :             state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMaxAvail = state.dataWindowAC->WindAC(WindACNum).OutAirMassFlow;
     816         5562 :             state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMinAvail = 0.0;
     817         5562 :             state.dataLoopNodes->Node(AirRelNode).MassFlowRate = state.dataWindowAC->WindAC(WindACNum).OutAirMassFlow;
     818         5562 :             state.dataLoopNodes->Node(AirRelNode).MassFlowRateMaxAvail = state.dataWindowAC->WindAC(WindACNum).OutAirMassFlow;
     819         5562 :             state.dataLoopNodes->Node(AirRelNode).MassFlowRateMinAvail = 0.0;
     820              :         }
     821              : 
     822              :         // Original thermostat control logic (works only for cycling fan systems)
     823         8278 :         if (QZnReq < (-1.0 * HVAC::SmallLoad) && !state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum) &&
     824         2716 :             state.dataWindowAC->WindAC(WindACNum).PartLoadFrac > 0.0) {
     825         2716 :             state.dataWindowAC->CoolingLoad = true;
     826              :         } else {
     827         2846 :             state.dataWindowAC->CoolingLoad = false;
     828              :         }
     829              : 
     830              :         // Constant fan systems are tested for ventilation load to determine if load to be met changes.
     831        16646 :         if (state.dataWindowAC->WindAC(WindACNum).fanOp == HVAC::FanOp::Continuous && state.dataWindowAC->WindAC(WindACNum).PartLoadFrac > 0.0 &&
     832        16646 :             (state.dataWindowAC->WindAC(WindACNum).fanAvailSched->getCurrentVal() > 0.0 || state.dataHVACGlobal->TurnFansOn) &&
     833         5542 :             !state.dataHVACGlobal->TurnFansOff) {
     834              : 
     835              :             Real64 NoCompOutput; // sensible load delivered with compressor off (W)
     836         5542 :             CalcWindowACOutput(state, WindACNum, FirstHVACIteration, state.dataWindowAC->WindAC(WindACNum).fanOp, 0.0, false, NoCompOutput);
     837              : 
     838         5542 :             Real64 QToCoolSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).RemainingOutputReqToCoolSP;
     839              : 
     840              :             // If the unit has a net heating capacity and the zone temp is below the Tstat cooling setpoint
     841         5560 :             if (NoCompOutput > (-1.0 * HVAC::SmallLoad) && QToCoolSetPt > (-1.0 * HVAC::SmallLoad) &&
     842           18 :                 state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum)) {
     843           16 :                 if (NoCompOutput > QToCoolSetPt) {
     844            0 :                     QZnReq = QToCoolSetPt;
     845            0 :                     state.dataWindowAC->CoolingLoad = true;
     846              :                 }
     847              :             }
     848              :         }
     849         5562 :     }
     850              : 
     851            4 :     void SizeWindowAC(EnergyPlusData &state, int const WindACNum)
     852              :     {
     853              : 
     854              :         // SUBROUTINE INFORMATION:
     855              :         //       AUTHOR         Fred Buhl
     856              :         //       DATE WRITTEN   January 2002
     857              :         //       MODIFIED       August 2013 Daeho Kang, add component sizing table entries
     858              :         //                      July 2014, B. Nigusse, added scalable sizing
     859              : 
     860              :         // PURPOSE OF THIS SUBROUTINE:
     861              :         // This subroutine is for sizing Window AC  Unit components for which flow rates have not been
     862              :         // specified in the input.
     863              : 
     864              :         // METHODOLOGY EMPLOYED:
     865              :         // Obtains flow rates from the zone or system sizing arrays
     866              : 
     867              :         // Using/Aliasing
     868              :         using namespace DataSizing;
     869              : 
     870              :         // SUBROUTINE PARAMETER DEFINITIONS:
     871              :         static constexpr std::string_view RoutineName("SizeWindowAC: "); // include trailing blank space
     872              : 
     873              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     874            4 :         auto &windowAC = state.dataWindowAC->WindAC(WindACNum);
     875              : 
     876            4 :         Real64 MaxAirVolFlowDes = 0.0;                                // Autosized maximum air flow for reporting
     877            4 :         Real64 MaxAirVolFlowUser = 0.0;                               // Hardsized maximum air flow for reporting
     878            4 :         Real64 OutAirVolFlowDes = 0.0;                                // Autosized outdoor air flow for reporting
     879            4 :         Real64 OutAirVolFlowUser = 0.0;                               // Hardsized outdoor ari flow for reporting
     880            4 :         bool IsAutoSize = false;                                      // Indicator to autosize
     881            4 :         std::string const CompType = "ZoneHVAC:WindowAirConditioner"; // component name
     882            4 :         std::string const CompName = windowAC.Name;                   // component type
     883            4 :         Real64 TempSize = AutoSize;                                   // autosized value of coil input field
     884            4 :         int FieldNum = 2;                                             // IDD numeric field number where input field description is found
     885            4 :         bool PrintFlag = false;                                       // TRUE when sizing information is reported in the eio file
     886              : 
     887            4 :         state.dataSize->DataFracOfAutosizedCoolingAirflow = 1.0;
     888            4 :         state.dataSize->DataFracOfAutosizedHeatingAirflow = 1.0;
     889            4 :         state.dataSize->DataFracOfAutosizedCoolingCapacity = 1.0;
     890            4 :         state.dataSize->DataFracOfAutosizedHeatingCapacity = 1.0;
     891            4 :         state.dataSize->DataScalableSizingON = false;
     892            4 :         state.dataSize->ZoneHeatingOnlyFan = false;
     893            4 :         state.dataSize->ZoneCoolingOnlyFan = true;
     894            4 :         state.dataSize->DataScalableCapSizingON = false;
     895            4 :         state.dataSize->DataZoneNumber = windowAC.ZonePtr;
     896            4 :         state.dataSize->DataFanType = windowAC.fanType;
     897            4 :         state.dataSize->DataFanIndex = windowAC.FanIndex;
     898            4 :         state.dataSize->DataFanPlacement = windowAC.fanPlace;
     899              : 
     900            4 :         if (state.dataSize->CurZoneEqNum > 0) {
     901            4 :             auto &zoneEqSizing = state.dataSize->ZoneEqSizing(state.dataSize->CurZoneEqNum);
     902              : 
     903            4 :             if (windowAC.HVACSizingIndex > 0) {
     904              :                 // N1 , \field Maximum Supply Air Flow Rate
     905            1 :                 auto const &zoneHVACSizing = state.dataSize->ZoneHVACSizing(windowAC.HVACSizingIndex);
     906              : 
     907            1 :                 int SizingMethod = HVAC::CoolingAirflowSizing;
     908            1 :                 PrintFlag = true;
     909            1 :                 int const SAFMethod = zoneHVACSizing.CoolingSAFMethod;
     910            1 :                 zoneEqSizing.SizingMethod(SizingMethod) = SAFMethod;
     911            1 :                 if (SAFMethod == None || SAFMethod == SupplyAirFlowRate || SAFMethod == FlowPerFloorArea ||
     912              :                     SAFMethod == FractionOfAutosizedCoolingAirflow) {
     913            1 :                     if (SAFMethod == SupplyAirFlowRate) {
     914            0 :                         if (zoneHVACSizing.MaxCoolAirVolFlow > 0.0) {
     915            0 :                             zoneEqSizing.AirVolFlow = zoneHVACSizing.MaxCoolAirVolFlow;
     916            0 :                             zoneEqSizing.SystemAirFlow = true;
     917              :                         }
     918            0 :                         TempSize = zoneHVACSizing.MaxCoolAirVolFlow;
     919            1 :                     } else if (SAFMethod == FlowPerFloorArea) {
     920            0 :                         zoneEqSizing.SystemAirFlow = true;
     921            0 :                         zoneEqSizing.AirVolFlow =
     922            0 :                             zoneHVACSizing.MaxCoolAirVolFlow * state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
     923            0 :                         TempSize = zoneEqSizing.AirVolFlow;
     924            0 :                         state.dataSize->DataScalableSizingON = true;
     925            1 :                     } else if (SAFMethod == FractionOfAutosizedCoolingAirflow) {
     926            1 :                         state.dataSize->DataFracOfAutosizedCoolingAirflow = zoneHVACSizing.MaxCoolAirVolFlow;
     927            1 :                         TempSize = AutoSize;
     928            1 :                         state.dataSize->DataScalableSizingON = true;
     929              :                     } else {
     930            0 :                         TempSize = zoneHVACSizing.MaxCoolAirVolFlow;
     931              :                     }
     932            1 :                     bool errorsFound = false;
     933            1 :                     CoolingAirFlowSizer sizingCoolingAirFlow;
     934            1 :                     std::string stringOverride = "Maximum Supply Air Flow Rate [m3/s]";
     935            1 :                     if (state.dataGlobal->isEpJSON) {
     936            0 :                         stringOverride = "maximum_supply_air_flow_rate [m3/s]";
     937              :                     }
     938            1 :                     sizingCoolingAirFlow.overrideSizingString(stringOverride);
     939              :                     // sizingCoolingAirFlow.setHVACSizingIndexData(windowAC.HVACSizingIndex);
     940            1 :                     sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
     941            1 :                     windowAC.MaxAirVolFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
     942              : 
     943            1 :                 } else if (SAFMethod == FlowPerCoolingCapacity) {
     944            0 :                     SizingMethod = HVAC::CoolingCapacitySizing;
     945            0 :                     TempSize = AutoSize;
     946            0 :                     PrintFlag = false;
     947            0 :                     state.dataSize->DataScalableSizingON = true;
     948            0 :                     state.dataSize->DataFlowUsedForSizing = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolVolFlow;
     949            0 :                     if (zoneHVACSizing.CoolingCapMethod == FractionOfAutosizedCoolingCapacity) {
     950            0 :                         state.dataSize->DataFracOfAutosizedCoolingCapacity = zoneHVACSizing.ScaledCoolingCapacity;
     951              :                     }
     952            0 :                     bool errorsFound = false;
     953            0 :                     CoolingCapacitySizer sizerCoolingCapacity;
     954            0 :                     sizerCoolingCapacity.overrideSizingString("");
     955            0 :                     sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
     956            0 :                     state.dataSize->DataCapacityUsedForSizing = sizerCoolingCapacity.size(state, TempSize, errorsFound);
     957            0 :                     state.dataSize->DataFlowPerCoolingCapacity = zoneHVACSizing.MaxCoolAirVolFlow;
     958            0 :                     PrintFlag = true;
     959            0 :                     TempSize = AutoSize;
     960            0 :                     errorsFound = false;
     961            0 :                     CoolingAirFlowSizer sizingCoolingAirFlow;
     962            0 :                     std::string stringOverride = "Maximum Supply Air Flow Rate [m3/s]";
     963            0 :                     if (state.dataGlobal->isEpJSON) {
     964            0 :                         stringOverride = "maximum_supply_air_flow_rate [m3/s]";
     965              :                     }
     966            0 :                     sizingCoolingAirFlow.overrideSizingString(stringOverride);
     967              :                     // sizingCoolingAirFlow.setHVACSizingIndexData(windowAC.HVACSizingIndex);
     968            0 :                     sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
     969            0 :                     windowAC.MaxAirVolFlow = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
     970            0 :                 }
     971              :                 // DataScalableSizingON = false;
     972              : 
     973              :                 // initialize capacity sizing variables: cooling
     974              :                 // capacity sizing methods (HeatingDesignCapacity, CapacityPerFloorArea, FractionOfAutosizedCoolingCapacity, and
     975              :                 // FractionOfAutosizedHeatingCapacity )
     976            1 :                 int const CapSizingMethod = zoneHVACSizing.CoolingCapMethod;
     977            1 :                 zoneEqSizing.SizingMethod(SizingMethod) = CapSizingMethod;
     978            1 :                 if (CapSizingMethod == CoolingDesignCapacity || CapSizingMethod == CapacityPerFloorArea ||
     979              :                     CapSizingMethod == FractionOfAutosizedCoolingCapacity) {
     980            1 :                     if (CapSizingMethod == CoolingDesignCapacity) {
     981            0 :                         if (zoneHVACSizing.ScaledCoolingCapacity > 0.0) {
     982            0 :                             zoneEqSizing.CoolingCapacity = true;
     983            0 :                             zoneEqSizing.DesCoolingLoad = zoneHVACSizing.ScaledCoolingCapacity;
     984              :                         }
     985            1 :                     } else if (CapSizingMethod == CapacityPerFloorArea) {
     986            0 :                         zoneEqSizing.CoolingCapacity = true;
     987            0 :                         zoneEqSizing.DesCoolingLoad =
     988            0 :                             zoneHVACSizing.ScaledCoolingCapacity * state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
     989            0 :                         state.dataSize->DataScalableCapSizingON = true;
     990            1 :                     } else if (CapSizingMethod == FractionOfAutosizedCoolingCapacity) {
     991            1 :                         state.dataSize->DataFracOfAutosizedCoolingCapacity = zoneHVACSizing.ScaledCoolingCapacity;
     992            1 :                         state.dataSize->DataScalableCapSizingON = true;
     993              :                     }
     994              :                 }
     995              :             } else {
     996              :                 // no scalable sizing method has been specified. Sizing proceeds using the method
     997              :                 // specified in the zoneHVAC object
     998              :                 // N1 , \field Maximum Supply Air Flow Rate
     999            3 :                 int FieldNum = 1;
    1000            3 :                 PrintFlag = true;
    1001            3 :                 std::string stringOverride = state.dataWindowAC->WindACNumericFields(WindACNum).FieldNames(FieldNum) + " [m3/s]";
    1002            3 :                 TempSize = windowAC.MaxAirVolFlow;
    1003            3 :                 bool errorsFound = false;
    1004            3 :                 SystemAirFlowSizer sizerSystemAirFlow;
    1005            3 :                 sizerSystemAirFlow.overrideSizingString(stringOverride);
    1006              :                 // sizerSystemAirFlow.setHVACSizingIndexData(windowAC.HVACSizingIndex);
    1007            3 :                 sizerSystemAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    1008            3 :                 windowAC.MaxAirVolFlow = sizerSystemAirFlow.size(state, TempSize, errorsFound);
    1009            3 :             }
    1010              : 
    1011            4 :             if (windowAC.OutAirVolFlow == AutoSize) {
    1012              : 
    1013            4 :                 CheckZoneSizing(state, state.dataWindowAC->cWindowAC_UnitTypes(windowAC.UnitType), windowAC.Name);
    1014            4 :                 windowAC.OutAirVolFlow = min(state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA, windowAC.MaxAirVolFlow);
    1015            4 :                 if (windowAC.OutAirVolFlow < SmallAirVolFlow) {
    1016            2 :                     windowAC.OutAirVolFlow = 0.0;
    1017              :                 }
    1018            8 :                 BaseSizer::reportSizerOutput(state,
    1019            4 :                                              state.dataWindowAC->cWindowAC_UnitTypes(windowAC.UnitType),
    1020              :                                              windowAC.Name,
    1021              :                                              "Maximum Outdoor Air Flow Rate [m3/s]",
    1022              :                                              windowAC.OutAirVolFlow);
    1023              :             }
    1024              : 
    1025            4 :             zoneEqSizing.OAVolFlow = windowAC.OutAirVolFlow;
    1026            4 :             zoneEqSizing.AirVolFlow = windowAC.MaxAirVolFlow;
    1027              :             // Make the Fan be sized by this
    1028            4 :             zoneEqSizing.CoolingAirFlow = true;
    1029            4 :             zoneEqSizing.CoolingAirVolFlow = windowAC.MaxAirVolFlow;
    1030              :         }
    1031              : 
    1032            4 :         state.dataSize->DataScalableCapSizingON = false;
    1033            4 :     }
    1034              : 
    1035         5562 :     void SimCyclingWindowAC(EnergyPlusData &state,
    1036              :                             int const WindACNum,                // number of the current window AC unit being simulated
    1037              :                             [[maybe_unused]] int const ZoneNum, // number of zone being served !unused1208
    1038              :                             bool const FirstHVACIteration,      // TRUE if 1st HVAC simulation of system timestep
    1039              :                             Real64 &PowerMet,                   // Sensible power supplied (W)
    1040              :                             Real64 const QZnReq,                // Sensible load to be met (W)
    1041              :                             Real64 &LatOutputProvided           // Latent power supplied (kg/s), negative = dehumidification
    1042              :     )
    1043              :     {
    1044              : 
    1045              :         // SUBROUTINE INFORMATION:
    1046              :         //       AUTHOR         Fred Buhl
    1047              :         //       DATE WRITTEN   May 2000
    1048              :         //       MODIFIED       Buhl/Shirey Mar 2001, Shirey Aug 2009 (LatOutputProvided)
    1049              : 
    1050              :         // PURPOSE OF THIS SUBROUTINE:
    1051              :         // Simulate a cycling window air conditioner unit; adjust its output to match the
    1052              :         // remaining zone load.
    1053              : 
    1054              :         // METHODOLOGY EMPLOYED:
    1055              :         // If unit is on, calls ControlWindACOutput to obtain the desired unit output
    1056              : 
    1057              :         Real64 PartLoadFrac; // unit part load fraction
    1058              :         bool HXUnitOn;       // Used to control HX heat recovery as needed
    1059              : 
    1060              :         // zero the DX coil electricity consumption
    1061              : 
    1062         5562 :         state.dataHVACGlobal->DXElecCoolingPower = 0.0;
    1063              :         // initialize local variables
    1064         5562 :         bool UnitOn = true;
    1065         5562 :         bool CoilOn = true;
    1066         5562 :         Real64 QUnitOut = 0.0;     // Dry air sens. cooling provided by AC unit [watts]
    1067         5562 :         Real64 LatentOutput = 0.0; // Latent (moisture) add/removal rate, negative is dehumidification [kg/s]
    1068         5562 :         int OutletNode = state.dataWindowAC->WindAC(WindACNum).AirOutNode;
    1069         5562 :         int InletNode = state.dataWindowAC->WindAC(WindACNum).AirInNode;
    1070         5562 :         Real64 AirMassFlow = state.dataLoopNodes->Node(InletNode).MassFlowRate;
    1071         5562 :         Real64 Test = AirMassFlow;
    1072         5562 :         Real64 CpAir = PsyCpAirFnW(state.dataLoopNodes->Node(InletNode).HumRat); // inlet air specific heat [J/kg-C]
    1073         5562 :         HVAC::FanOp fanOp = state.dataWindowAC->WindAC(WindACNum).fanOp;
    1074              : 
    1075              :         // set the on/off flags
    1076         5562 :         if (state.dataWindowAC->WindAC(WindACNum).fanOp == HVAC::FanOp::Cycling) {
    1077              :             // cycling unit: only runs if there is a load.
    1078           20 :             if (!state.dataWindowAC->CoolingLoad || AirMassFlow < SmallMassFlow) {
    1079           18 :                 UnitOn = false;
    1080           18 :                 CoilOn = false;
    1081              :             }
    1082         5542 :         } else if (state.dataWindowAC->WindAC(WindACNum).fanOp == HVAC::FanOp::Continuous) {
    1083              :             // continuous unit: fan runs if scheduled on; coil runs only if cooling load
    1084         5542 :             if (AirMassFlow < SmallMassFlow) {
    1085            2 :                 UnitOn = false;
    1086            2 :                 CoilOn = false;
    1087         5540 :             } else if (!state.dataWindowAC->CoolingLoad) {
    1088         2828 :                 CoilOn = false;
    1089              :             }
    1090              :         }
    1091              : 
    1092         5562 :         state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
    1093              : 
    1094         5562 :         if (UnitOn && CoilOn) {
    1095         2714 :             HXUnitOn = false;
    1096         2714 :             ControlCycWindACOutput(state, WindACNum, FirstHVACIteration, fanOp, QZnReq, PartLoadFrac, HXUnitOn);
    1097              :         } else {
    1098         2848 :             PartLoadFrac = 0.0;
    1099         2848 :             HXUnitOn = false;
    1100              :         }
    1101              : 
    1102         5562 :         state.dataWindowAC->WindAC(WindACNum).PartLoadFrac = PartLoadFrac;
    1103              : 
    1104         5562 :         CalcWindowACOutput(state, WindACNum, FirstHVACIteration, fanOp, PartLoadFrac, HXUnitOn, QUnitOut);
    1105              : 
    1106              :         // Reseting AirMassFlow to inlet node mass flow rate since inlet mass flow rate may be getting
    1107              :         // manipulated in subroutine CalcWindowACOutput
    1108              : 
    1109         5562 :         AirMassFlow = state.dataLoopNodes->Node(InletNode).MassFlowRate;
    1110         5562 :         Real64 MinHumRat = min(state.dataLoopNodes->Node(InletNode).HumRat, state.dataLoopNodes->Node(OutletNode).HumRat);
    1111         5562 :         QUnitOut = AirMassFlow * (PsyHFnTdbW(state.dataLoopNodes->Node(OutletNode).Temp, MinHumRat) -
    1112         5562 :                                   PsyHFnTdbW(state.dataLoopNodes->Node(InletNode).Temp, MinHumRat));
    1113              : 
    1114         5562 :         Real64 SensCoolOut = AirMassFlow * (PsyHFnTdbW(state.dataLoopNodes->Node(OutletNode).Temp, MinHumRat) -
    1115         5562 :                                             PsyHFnTdbW(state.dataLoopNodes->Node(InletNode).Temp, MinHumRat));
    1116              : 
    1117              :         // CR9155 Remove specific humidity calculations
    1118         5562 :         Real64 SpecHumOut = state.dataLoopNodes->Node(OutletNode).HumRat;
    1119         5562 :         Real64 SpecHumIn = state.dataLoopNodes->Node(InletNode).HumRat;
    1120         5562 :         LatentOutput = AirMassFlow * (SpecHumOut - SpecHumIn); // Latent rate, kg/s
    1121              : 
    1122         5562 :         Real64 QTotUnitOut = AirMassFlow * (state.dataLoopNodes->Node(OutletNode).Enthalpy - state.dataLoopNodes->Node(InletNode).Enthalpy);
    1123              : 
    1124              :         // report variables
    1125         5562 :         state.dataWindowAC->WindAC(WindACNum).CompPartLoadRatio = state.dataWindowAC->WindAC(WindACNum).PartLoadFrac;
    1126         5562 :         if (state.dataWindowAC->WindAC(WindACNum).fanOp == HVAC::FanOp::Cycling) {
    1127           20 :             state.dataWindowAC->WindAC(WindACNum).FanPartLoadRatio = state.dataWindowAC->WindAC(WindACNum).PartLoadFrac;
    1128              :         } else {
    1129         5542 :             if (UnitOn) {
    1130         5540 :                 state.dataWindowAC->WindAC(WindACNum).FanPartLoadRatio = 1.0;
    1131              :             } else {
    1132            2 :                 state.dataWindowAC->WindAC(WindACNum).FanPartLoadRatio = 0.0;
    1133              :             }
    1134              :         }
    1135         5562 :         state.dataWindowAC->WindAC(WindACNum).SensCoolEnergyRate = std::abs(min(0.0, SensCoolOut));
    1136         5562 :         state.dataWindowAC->WindAC(WindACNum).TotCoolEnergyRate = std::abs(min(0.0, QTotUnitOut));
    1137         5562 :         state.dataWindowAC->WindAC(WindACNum).SensCoolEnergyRate =
    1138         5562 :             min(state.dataWindowAC->WindAC(WindACNum).SensCoolEnergyRate, state.dataWindowAC->WindAC(WindACNum).TotCoolEnergyRate);
    1139         5562 :         state.dataWindowAC->WindAC(WindACNum).LatCoolEnergyRate =
    1140         5562 :             state.dataWindowAC->WindAC(WindACNum).TotCoolEnergyRate - state.dataWindowAC->WindAC(WindACNum).SensCoolEnergyRate;
    1141         5562 :         Real64 locFanElecPower = state.dataFans->fans(state.dataWindowAC->WindAC(WindACNum).FanIndex)->totalPower;
    1142         5562 :         state.dataWindowAC->WindAC(WindACNum).ElecPower = locFanElecPower + state.dataHVACGlobal->DXElecCoolingPower;
    1143              : 
    1144         5562 :         PowerMet = QUnitOut;
    1145         5562 :         LatOutputProvided = LatentOutput;
    1146         5562 :     }
    1147              : 
    1148         5562 :     void ReportWindowAC(EnergyPlusData &state, int const WindACNum) // number of the current AC unit being simulated
    1149              :     {
    1150              : 
    1151              :         // SUBROUTINE INFORMATION:
    1152              :         //       AUTHOR         Fred Buhl
    1153              :         //       DATE WRITTEN   May 2000
    1154              : 
    1155              :         // PURPOSE OF THIS SUBROUTINE:
    1156              :         // Fills some of the report variables for the window AC units
    1157              : 
    1158         5562 :         Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
    1159              : 
    1160         5562 :         state.dataWindowAC->WindAC(WindACNum).SensCoolEnergy = state.dataWindowAC->WindAC(WindACNum).SensCoolEnergyRate * TimeStepSysSec;
    1161         5562 :         state.dataWindowAC->WindAC(WindACNum).TotCoolEnergy = state.dataWindowAC->WindAC(WindACNum).TotCoolEnergyRate * TimeStepSysSec;
    1162         5562 :         state.dataWindowAC->WindAC(WindACNum).LatCoolEnergy = state.dataWindowAC->WindAC(WindACNum).LatCoolEnergyRate * TimeStepSysSec;
    1163         5562 :         state.dataWindowAC->WindAC(WindACNum).ElecConsumption = state.dataWindowAC->WindAC(WindACNum).ElecPower * TimeStepSysSec;
    1164              : 
    1165         5562 :         if (state.dataWindowAC->WindAC(WindACNum).FirstPass) { // reset sizing flags so other zone equipment can size normally
    1166            8 :             if (!state.dataGlobal->SysSizingCalc) {
    1167            4 :                 DataSizing::resetHVACSizingGlobals(state, state.dataSize->CurZoneEqNum, 0, state.dataWindowAC->WindAC(WindACNum).FirstPass);
    1168              :             }
    1169              :         }
    1170         5562 :     }
    1171              : 
    1172        18606 :     void CalcWindowACOutput(EnergyPlusData &state,
    1173              :                             int const WindACNum,           // Unit index in fan coil array
    1174              :                             bool const FirstHVACIteration, // flag for 1st HVAV iteration in the time step
    1175              :                             HVAC::FanOp const fanOp,       // operating mode: FanOp::Cycling | FanOp::Continuous
    1176              :                             Real64 const PartLoadFrac,     // unit part load fraction
    1177              :                             bool const HXUnitOn,           // Flag to toggle HX heat recovery as needed
    1178              :                             Real64 &LoadMet                // load met by unit (watts)
    1179              :     )
    1180              :     {
    1181              : 
    1182              :         // SUBROUTINE INFORMATION:
    1183              :         //       AUTHOR         Fred Buhl
    1184              :         //       DATE WRITTEN   May 2000
    1185              :         //       MODIFIED       July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
    1186              : 
    1187              :         // PURPOSE OF THIS SUBROUTINE:
    1188              :         // Simulate the components making up the cycling window AC unit.
    1189              : 
    1190              :         // METHODOLOGY EMPLOYED:
    1191              :         // Simulates the unit components sequentially in the air flow direction.
    1192              : 
    1193        18606 :         int OutletNode = state.dataWindowAC->WindAC(WindACNum).AirOutNode;
    1194        18606 :         int InletNode = state.dataWindowAC->WindAC(WindACNum).AirInNode;
    1195        18606 :         int OutsideAirNode = state.dataWindowAC->WindAC(WindACNum).OutsideAirNode;
    1196        18606 :         int AirRelNode = state.dataWindowAC->WindAC(WindACNum).AirReliefNode;
    1197              :         // for cycling fans, pretend we have VAV
    1198        18606 :         if (fanOp == HVAC::FanOp::Cycling) {
    1199           26 :             state.dataLoopNodes->Node(InletNode).MassFlowRate = state.dataLoopNodes->Node(InletNode).MassFlowRateMax * PartLoadFrac;
    1200              :             // Don't let the outside air flow be > supply air flow
    1201           26 :             state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate =
    1202           26 :                 min(state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMax, state.dataLoopNodes->Node(InletNode).MassFlowRate);
    1203           26 :             state.dataLoopNodes->Node(AirRelNode).MassFlowRate = state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    1204              :         }
    1205        18606 :         Real64 AirMassFlow = state.dataLoopNodes->Node(InletNode).MassFlowRate;
    1206        18606 :         MixedAir::SimOAMixer(state, state.dataWindowAC->WindAC(WindACNum).OAMixName, state.dataWindowAC->WindAC(WindACNum).OAMixIndex);
    1207              : 
    1208              :         // if blow through, simulate fan then coil. For draw through, simulate coil then fan.
    1209        18606 :         if (state.dataWindowAC->WindAC(WindACNum).fanPlace == HVAC::FanPlace::BlowThru) {
    1210        18606 :             state.dataFans->fans(state.dataWindowAC->WindAC(WindACNum).FanIndex)->simulate(state, FirstHVACIteration, PartLoadFrac);
    1211              :         }
    1212              : 
    1213        18606 :         if (state.dataWindowAC->WindAC(WindACNum).DXCoilType_Num == CoilDX_CoolingHXAssisted) {
    1214            0 :             HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
    1215            0 :                                                                 state.dataWindowAC->WindAC(WindACNum).DXCoilName,
    1216              :                                                                 FirstHVACIteration,
    1217              :                                                                 HVAC::CompressorOp::On,
    1218              :                                                                 PartLoadFrac,
    1219            0 :                                                                 state.dataWindowAC->WindAC(WindACNum).DXCoilIndex,
    1220            0 :                                                                 state.dataWindowAC->WindAC(WindACNum).fanOp,
    1221              :                                                                 HXUnitOn);
    1222        18606 :         } else if (state.dataWindowAC->WindAC(WindACNum).DXCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
    1223           26 :             Real64 QZnReq(-1.0);           // Zone load (W), input to variable-speed DX coil
    1224           26 :             Real64 QLatReq(0.0);           // Zone latent load, input to variable-speed DX coil
    1225           26 :             Real64 OnOffAirFlowRatio(1.0); // ratio of compressor on flow to average flow over time step
    1226              : 
    1227           26 :             VariableSpeedCoils::SimVariableSpeedCoils(state,
    1228           26 :                                                       state.dataWindowAC->WindAC(WindACNum).DXCoilName,
    1229           26 :                                                       state.dataWindowAC->WindAC(WindACNum).DXCoilIndex,
    1230           26 :                                                       state.dataWindowAC->WindAC(WindACNum).fanOp,
    1231              :                                                       HVAC::CompressorOp::On,
    1232              :                                                       PartLoadFrac,
    1233           26 :                                                       state.dataWindowAC->WindAC(WindACNum).DXCoilNumOfSpeeds,
    1234              :                                                       1.0,
    1235              :                                                       QZnReq,
    1236              :                                                       QLatReq,
    1237              :                                                       OnOffAirFlowRatio);
    1238              : 
    1239              :         } else {
    1240        37160 :             DXCoils::SimDXCoil(state,
    1241        18580 :                                state.dataWindowAC->WindAC(WindACNum).DXCoilName,
    1242              :                                HVAC::CompressorOp::On,
    1243              :                                FirstHVACIteration,
    1244        18580 :                                state.dataWindowAC->WindAC(WindACNum).DXCoilIndex,
    1245        18580 :                                state.dataWindowAC->WindAC(WindACNum).fanOp,
    1246              :                                PartLoadFrac);
    1247              :         }
    1248              : 
    1249        18606 :         if (state.dataWindowAC->WindAC(WindACNum).fanPlace == HVAC::FanPlace::DrawThru) {
    1250            0 :             state.dataFans->fans(state.dataWindowAC->WindAC(WindACNum).FanIndex)->simulate(state, FirstHVACIteration, PartLoadFrac);
    1251              :         }
    1252              : 
    1253        18606 :         Real64 MinHumRat = min(state.dataLoopNodes->Node(InletNode).HumRat, state.dataLoopNodes->Node(OutletNode).HumRat);
    1254        18606 :         LoadMet = AirMassFlow * (PsyHFnTdbW(state.dataLoopNodes->Node(OutletNode).Temp, MinHumRat) -
    1255        18606 :                                  PsyHFnTdbW(state.dataLoopNodes->Node(InletNode).Temp, MinHumRat));
    1256        18606 :     }
    1257              : 
    1258         2714 :     void ControlCycWindACOutput(EnergyPlusData &state,
    1259              :                                 int const WindACNum,           // Unit index in fan coil array
    1260              :                                 bool const FirstHVACIteration, // flag for 1st HVAV iteration in the time step
    1261              :                                 HVAC::FanOp const fanOp,       // operating mode: FanOp::Cycling | FanOp::Continuous
    1262              :                                 Real64 const QZnReq,           // cooling output needed by zone [W]
    1263              :                                 Real64 &PartLoadFrac,          // unit part load fraction
    1264              :                                 bool &HXUnitOn                 // Used to control HX heat recovery as needed
    1265              :     )
    1266              :     {
    1267              : 
    1268              :         // SUBROUTINE INFORMATION:
    1269              :         //       AUTHOR         Fred Buhl
    1270              :         //       DATE WRITTEN   May 2000
    1271              :         //       MODIFIED       Shirey, May 2001
    1272              : 
    1273              :         // PURPOSE OF THIS SUBROUTINE:
    1274              :         // Determine the part load fraction of the air conditioner for this time step
    1275              : 
    1276              :         // METHODOLOGY EMPLOYED:
    1277              :         // Linear interpolation between max and min outputs
    1278              : 
    1279         2714 :         int constexpr MaxIter(50);    // maximum number of iterations
    1280         2714 :         Real64 constexpr MinPLF(0.0); // minimum part load factor allowed
    1281              : 
    1282              :         Real64 FullOutput;   // unit full output [W]
    1283              :         Real64 NoCoolOutput; // output when no active cooling [W]
    1284              :         Real64 ActualOutput; // output at current partloadfrac [W]
    1285              : 
    1286              :         // DX Cooling HX assisted coils can cycle the heat exchanger, see if coil ON, HX OFF can meet humidity setpoint if one exists
    1287         2714 :         if (state.dataWindowAC->WindAC(WindACNum).DXCoilType_Num == CoilDX_CoolingHXAssisted) {
    1288              :             // Check for a setpoint at the HX outlet node, if it doesn't exist always run the HX
    1289            0 :             if (state.dataLoopNodes->Node(state.dataWindowAC->WindAC(WindACNum).CoilOutletNodeNum).HumRatMax == SensedNodeFlagValue) {
    1290            0 :                 HXUnitOn = true;
    1291              :             } else {
    1292            0 :                 HXUnitOn = false;
    1293              :             }
    1294              :         } else {
    1295         2714 :             HXUnitOn = false;
    1296              :         }
    1297              : 
    1298         2714 :         if (state.dataWindowAC->WindAC(WindACNum).EMSOverridePartLoadFrac) {
    1299              : 
    1300            0 :             PartLoadFrac = state.dataWindowAC->WindAC(WindACNum).EMSValueForPartLoadFrac;
    1301              :         }
    1302              : 
    1303              :         // Get result when DX coil is off
    1304         2714 :         CalcWindowACOutput(state, WindACNum, FirstHVACIteration, fanOp, 0.0, HXUnitOn, NoCoolOutput);
    1305              : 
    1306              :         // If NoCoolOutput < QZnReq, the coil needs to be off
    1307         2714 :         if (NoCoolOutput < QZnReq) {
    1308           12 :             PartLoadFrac = 0.0;
    1309          628 :             return;
    1310              :         }
    1311              : 
    1312              :         // Get full load result
    1313         2702 :         CalcWindowACOutput(state, WindACNum, FirstHVACIteration, fanOp, 1.0, HXUnitOn, FullOutput);
    1314              : 
    1315              :         // Since we are cooling, we expect FullOutput to be < 0 and FullOutput < NoCoolOutput
    1316              :         // Check that this is the case; if not set PartLoadFrac = 0.0 (off) and return
    1317         2702 :         if (FullOutput >= 0.0 || FullOutput >= NoCoolOutput) {
    1318            0 :             PartLoadFrac = 0.0;
    1319            0 :             return;
    1320              :         }
    1321              : 
    1322              :         // If the QZnReq <= FullOutput the unit needs to run full out
    1323         2702 :         if (QZnReq <= FullOutput && state.dataWindowAC->WindAC(WindACNum).DXCoilType_Num != CoilDX_CoolingHXAssisted) {
    1324          616 :             PartLoadFrac = 1.0;
    1325          616 :             return;
    1326              :         }
    1327              : 
    1328              :         // If the QZnReq <= FullOutput and a HXAssisted coil is used, check the node setpoint for a maximum humidity ratio set point
    1329              :         // HumRatMax will be equal to -999 if no setpoint exists or some set point managers may still use 0 as a no moisture load indicator
    1330         2086 :         if (QZnReq <= FullOutput && state.dataWindowAC->WindAC(WindACNum).DXCoilType_Num == CoilDX_CoolingHXAssisted &&
    1331            0 :             state.dataLoopNodes->Node(state.dataWindowAC->WindAC(WindACNum).CoilOutletNodeNum).HumRatMax <= 0.0) {
    1332            0 :             PartLoadFrac = 1.0;
    1333            0 :             return;
    1334              :         }
    1335              : 
    1336              :         // QZnReq should now be greater than FullOutput and less than NoCoolOutput)
    1337              :         // Calculate the part load fraction
    1338              : 
    1339         2086 :         PartLoadFrac = max(MinPLF, std::abs(QZnReq - NoCoolOutput) / std::abs(FullOutput - NoCoolOutput));
    1340              : 
    1341         2086 :         Real64 ErrorToler = state.dataWindowAC->WindAC(WindACNum).ConvergenceTol; // Error tolerance for convergence from input deck
    1342         2086 :         Real64 Error = 1.0;                                                       // initialize error value for comparison against tolerance
    1343         2086 :         int Iter = 0;                                                             // initialize iteration counter
    1344         2086 :         Real64 Relax = 1.0;
    1345              : 
    1346         4172 :         while ((std::abs(Error) > ErrorToler) && (Iter <= MaxIter) && PartLoadFrac > MinPLF) {
    1347              :             // Get result when DX coil is operating at partloadfrac
    1348         2086 :             CalcWindowACOutput(state, WindACNum, FirstHVACIteration, fanOp, PartLoadFrac, HXUnitOn, ActualOutput);
    1349         2086 :             Error = (QZnReq - ActualOutput) / QZnReq;
    1350         2086 :             Real64 DelPLF = (QZnReq - ActualOutput) / FullOutput;
    1351         2086 :             PartLoadFrac += Relax * DelPLF;
    1352         2086 :             PartLoadFrac = max(MinPLF, min(1.0, PartLoadFrac));
    1353         2086 :             ++Iter;
    1354         2086 :             if (Iter == 16) {
    1355            0 :                 Relax = 0.5;
    1356              :             }
    1357              :         }
    1358         2086 :         if (Iter > MaxIter) {
    1359            0 :             if (state.dataWindowAC->WindAC(WindACNum).MaxIterIndex1 == 0) {
    1360            0 :                 ShowWarningMessage(state,
    1361            0 :                                    format("ZoneHVAC:WindowAirConditioner=\"{}\" -- Exceeded max iterations while adjusting compressor sensible "
    1362              :                                           "runtime to meet the zone load within the cooling convergence tolerance.",
    1363            0 :                                           state.dataWindowAC->WindAC(WindACNum).Name));
    1364            0 :                 ShowContinueErrorTimeStamp(state, format("Iterations={}", MaxIter));
    1365              :             }
    1366            0 :             ShowRecurringWarningErrorAtEnd(state,
    1367            0 :                                            "ZoneHVAC:WindowAirConditioner=\"" + state.dataWindowAC->WindAC(WindACNum).Name +
    1368              :                                                "\"  -- Exceeded max iterations error (sensible runtime) continues...",
    1369            0 :                                            state.dataWindowAC->WindAC(WindACNum).MaxIterIndex1);
    1370              :         }
    1371              : 
    1372              :         // HX is off up until this point where the outlet air humidity ratio is tested to see if HX needs to be turned on
    1373         2086 :         if (state.dataWindowAC->WindAC(WindACNum).DXCoilType_Num == CoilDX_CoolingHXAssisted &&
    1374            0 :             state.dataLoopNodes->Node(state.dataWindowAC->WindAC(WindACNum).CoilOutletNodeNum).HumRatMax <
    1375         2086 :                 state.dataLoopNodes->Node(state.dataWindowAC->WindAC(WindACNum).CoilOutletNodeNum).HumRat &&
    1376            0 :             state.dataLoopNodes->Node(state.dataWindowAC->WindAC(WindACNum).CoilOutletNodeNum).HumRatMax > 0.0) {
    1377              : 
    1378              :             //   Run the HX to recovery energy and improve latent performance
    1379            0 :             HXUnitOn = true;
    1380              : 
    1381              :             //   Get full load result
    1382            0 :             CalcWindowACOutput(state, WindACNum, FirstHVACIteration, fanOp, 1.0, HXUnitOn, FullOutput);
    1383              : 
    1384            0 :             if (state.dataLoopNodes->Node(state.dataWindowAC->WindAC(WindACNum).CoilOutletNodeNum).HumRatMax <
    1385            0 :                     state.dataLoopNodes->Node(state.dataWindowAC->WindAC(WindACNum).CoilOutletNodeNum).HumRat ||
    1386            0 :                 QZnReq <= FullOutput) {
    1387            0 :                 PartLoadFrac = 1.0;
    1388            0 :                 return;
    1389              :             }
    1390              : 
    1391            0 :             Error = 1.0; // initialize error value for comparison against tolerance
    1392            0 :             Iter = 0;    // initialize iteration counter
    1393            0 :             Relax = 1.0;
    1394              : 
    1395            0 :             while ((std::abs(Error) > ErrorToler) && (Iter <= MaxIter) && PartLoadFrac > MinPLF) {
    1396              :                 // Get result when DX coil is operating at partloadfrac
    1397            0 :                 CalcWindowACOutput(state, WindACNum, FirstHVACIteration, fanOp, PartLoadFrac, HXUnitOn, ActualOutput);
    1398            0 :                 Error = (QZnReq - ActualOutput) / QZnReq;
    1399            0 :                 Real64 DelPLF = (QZnReq - ActualOutput) / FullOutput;
    1400            0 :                 PartLoadFrac += Relax * DelPLF;
    1401            0 :                 PartLoadFrac = max(MinPLF, min(1.0, PartLoadFrac));
    1402            0 :                 ++Iter;
    1403            0 :                 if (Iter == 16) {
    1404            0 :                     Relax = 0.5;
    1405              :                 }
    1406              :             }
    1407            0 :             if (Iter > MaxIter) {
    1408            0 :                 if (state.dataWindowAC->WindAC(WindACNum).MaxIterIndex2 == 0) {
    1409            0 :                     ShowWarningMessage(state,
    1410            0 :                                        format("ZoneHVAC:WindowAirConditioner=\"{}\" -- Exceeded max iterations while adjusting compressor latent "
    1411              :                                               "runtime to meet the zone load within the cooling convergence tolerance.",
    1412            0 :                                               state.dataWindowAC->WindAC(WindACNum).Name));
    1413            0 :                     ShowContinueErrorTimeStamp(state, format("Iterations={}", MaxIter));
    1414              :                 }
    1415            0 :                 ShowRecurringWarningErrorAtEnd(state,
    1416            0 :                                                "ZoneHVAC:WindowAirConditioner=\"" + state.dataWindowAC->WindAC(WindACNum).Name +
    1417              :                                                    "\"  -- Exceeded max iterations error (latent runtime) continues...",
    1418            0 :                                                state.dataWindowAC->WindAC(WindACNum).MaxIterIndex2);
    1419              :             }
    1420              : 
    1421              :         } // WindAC(WindACNum)%DXCoilType_Num == CoilDX_CoolingHXAssisted && *
    1422              :     }
    1423              : 
    1424           42 :     bool getWindowACNodeNumber(EnergyPlusData &state, int const nodeNumber)
    1425              :     {
    1426           42 :         if (state.dataWindowAC->GetWindowACInputFlag) {
    1427            7 :             GetWindowAC(state);
    1428            7 :             state.dataWindowAC->GetWindowACInputFlag = false;
    1429              :         }
    1430              : 
    1431           43 :         for (int windowACIndex = 1; windowACIndex <= state.dataWindowAC->NumWindAC; ++windowACIndex) {
    1432            3 :             auto &windowAC = state.dataWindowAC->WindAC(windowACIndex);
    1433            3 :             int FanInletNodeIndex = state.dataFans->fans(windowAC.FanIndex)->inletNodeNum;
    1434            3 :             int FanOutletNodeIndex = state.dataFans->fans(windowAC.FanIndex)->outletNodeNum;
    1435              : 
    1436            3 :             if (windowAC.OutAirVolFlow == 0 &&
    1437            3 :                 (nodeNumber == windowAC.OutsideAirNode || nodeNumber == windowAC.MixedAirNode || nodeNumber == windowAC.AirReliefNode ||
    1438            2 :                  nodeNumber == FanInletNodeIndex || nodeNumber == FanOutletNodeIndex || nodeNumber == windowAC.AirInNode ||
    1439            1 :                  nodeNumber == windowAC.CoilOutletNodeNum || nodeNumber == windowAC.AirOutNode || nodeNumber == windowAC.ReturnAirNode)) {
    1440            2 :                 return true;
    1441              :             }
    1442              :         }
    1443           40 :         return false;
    1444              :     }
    1445              : 
    1446          385 :     int GetWindowACZoneInletAirNode(EnergyPlusData &state, int const WindACNum)
    1447              :     {
    1448              : 
    1449              :         // FUNCTION INFORMATION:
    1450              :         //       AUTHOR         B Griffith
    1451              :         //       DATE WRITTEN   Dec  2006
    1452              : 
    1453              :         // PURPOSE OF THIS FUNCTION:
    1454              :         // lookup function for zone inlet node
    1455              : 
    1456              :         // Return value
    1457              :         int GetWindowACZoneInletAirNode;
    1458              : 
    1459          385 :         if (state.dataWindowAC->GetWindowACInputFlag) {
    1460            0 :             GetWindowAC(state);
    1461            0 :             state.dataWindowAC->GetWindowACInputFlag = false;
    1462              :         }
    1463              : 
    1464          385 :         GetWindowACZoneInletAirNode = state.dataWindowAC->WindAC(WindACNum).AirOutNode;
    1465              : 
    1466          385 :         return GetWindowACZoneInletAirNode;
    1467              :     }
    1468              : 
    1469          385 :     int GetWindowACOutAirNode(EnergyPlusData &state, int const WindACNum)
    1470              :     {
    1471              : 
    1472              :         // FUNCTION INFORMATION:
    1473              :         //       AUTHOR         B Griffith
    1474              :         //       DATE WRITTEN   Dec  2006
    1475              : 
    1476              :         // PURPOSE OF THIS FUNCTION:
    1477              :         // lookup function for OA inlet node
    1478              : 
    1479          385 :         if (state.dataWindowAC->GetWindowACInputFlag) {
    1480            0 :             GetWindowAC(state);
    1481            0 :             state.dataWindowAC->GetWindowACInputFlag = false;
    1482              :         }
    1483              : 
    1484          385 :         return state.dataWindowAC->WindAC(WindACNum).OutsideAirNode;
    1485              :     }
    1486              : 
    1487          385 :     int GetWindowACReturnAirNode(EnergyPlusData &state, int const WindACNum)
    1488              :     {
    1489              : 
    1490              :         // FUNCTION INFORMATION:
    1491              :         //       AUTHOR         B Griffith
    1492              :         //       DATE WRITTEN   Dec  2006
    1493              : 
    1494              :         // PURPOSE OF THIS FUNCTION:
    1495              :         // lookup function for mixer return air node for ventilation load reporting
    1496              : 
    1497              :         // Return value
    1498              :         int GetWindowACReturnAirNode;
    1499              : 
    1500          385 :         if (state.dataWindowAC->GetWindowACInputFlag) {
    1501            0 :             GetWindowAC(state);
    1502            0 :             state.dataWindowAC->GetWindowACInputFlag = false;
    1503              :         }
    1504              : 
    1505          385 :         if (WindACNum > 0 && WindACNum <= state.dataWindowAC->NumWindAC) {
    1506          384 :             if (state.dataWindowAC->WindAC(WindACNum).OAMixIndex > 0) {
    1507          384 :                 GetWindowACReturnAirNode = MixedAir::GetOAMixerReturnNodeNumber(state, state.dataWindowAC->WindAC(WindACNum).OAMixIndex);
    1508              :             } else {
    1509            0 :                 GetWindowACReturnAirNode = 0;
    1510              :             }
    1511              :         } else {
    1512            1 :             GetWindowACReturnAirNode = 0;
    1513              :         }
    1514              : 
    1515          385 :         return GetWindowACReturnAirNode;
    1516              :     }
    1517              : 
    1518          385 :     int GetWindowACMixedAirNode(EnergyPlusData &state, int const WindACNum)
    1519              :     {
    1520              : 
    1521              :         // FUNCTION INFORMATION:
    1522              :         //       AUTHOR         B Griffith
    1523              :         //       DATE WRITTEN   Dec  2006
    1524              : 
    1525              :         // PURPOSE OF THIS FUNCTION:
    1526              :         // lookup function for mixed air node for ventilation rate reporting
    1527              : 
    1528              :         // Return value
    1529              :         int GetWindowACMixedAirNode;
    1530              : 
    1531          385 :         if (state.dataWindowAC->GetWindowACInputFlag) {
    1532            0 :             GetWindowAC(state);
    1533            0 :             state.dataWindowAC->GetWindowACInputFlag = false;
    1534              :         }
    1535              : 
    1536          385 :         if (WindACNum > 0 && WindACNum <= state.dataWindowAC->NumWindAC) {
    1537          384 :             if (state.dataWindowAC->WindAC(WindACNum).OAMixIndex > 0) {
    1538          384 :                 GetWindowACMixedAirNode = MixedAir::GetOAMixerMixedNodeNumber(state, state.dataWindowAC->WindAC(WindACNum).OAMixIndex);
    1539              :             } else {
    1540            0 :                 GetWindowACMixedAirNode = 0;
    1541              :             }
    1542              :         } else {
    1543            1 :             GetWindowACMixedAirNode = 0;
    1544              :         }
    1545              : 
    1546          385 :         return GetWindowACMixedAirNode;
    1547              :     }
    1548              : 
    1549            1 :     int getWindowACIndex(EnergyPlusData &state, std::string_view CompName)
    1550              :     {
    1551            1 :         if (state.dataWindowAC->GetWindowACInputFlag) {
    1552            0 :             GetWindowAC(state);
    1553            0 :             state.dataWindowAC->GetWindowACInputFlag = false;
    1554              :         }
    1555              : 
    1556            1 :         for (int WindACIndex = 1; WindACIndex <= state.dataWindowAC->NumWindAC; ++WindACIndex) {
    1557            1 :             if (Util::SameString(state.dataWindowAC->WindAC(WindACIndex).Name, CompName)) {
    1558            1 :                 return WindACIndex;
    1559              :             }
    1560              :         }
    1561              : 
    1562            0 :         return 0;
    1563              :     }
    1564              : 
    1565              : } // namespace WindowAC
    1566              : 
    1567              : } // namespace EnergyPlus
        

Generated by: LCOV version 2.0-1