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

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

Generated by: LCOV version 2.0-1