LCOV - code coverage report
Current view: top level - EnergyPlus - HVACManager.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 1078 1701 63.4 %
Date: 2023-01-17 19:17:23 Functions: 16 20 80.0 %

          Line data    Source code
       1             : // EnergyPlus, Copyright (c) 1996-2023, The Board of Trustees of the University of Illinois,
       2             : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3             : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4             : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5             : // contributors. All rights reserved.
       6             : //
       7             : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8             : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9             : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10             : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11             : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12             : //
      13             : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14             : // provided that the following conditions are met:
      15             : //
      16             : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17             : //     conditions and the following disclaimer.
      18             : //
      19             : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20             : //     conditions and the following disclaimer in the documentation and/or other materials
      21             : //     provided with the distribution.
      22             : //
      23             : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24             : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25             : //     used to endorse or promote products derived from this software without specific prior
      26             : //     written permission.
      27             : //
      28             : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29             : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30             : //     reference solely to the software portion of its product, Licensee must refer to the
      31             : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32             : //     obtained under this License and may not use a different name for the software. Except as
      33             : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34             : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35             : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36             : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37             : //
      38             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39             : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40             : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41             : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42             : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43             : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45             : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46             : // POSSIBILITY OF SUCH DAMAGE.
      47             : 
      48             : // C++ Headers
      49             : #include <algorithm>
      50             : #include <cmath>
      51             : #include <string>
      52             : 
      53             : // ObjexxFCL Headers
      54             : #include <ObjexxFCL/Array.functions.hh>
      55             : #include <ObjexxFCL/Fmath.hh>
      56             : 
      57             : // EnergyPlus Headers
      58             : #include <AirflowNetwork/Solver.hpp>
      59             : #include <EnergyPlus/Coils/CoilCoolingDX.hh>
      60             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      61             : #include <EnergyPlus/DataAirLoop.hh>
      62             : #include <EnergyPlus/DataAirSystems.hh>
      63             : #include <EnergyPlus/DataConvergParams.hh>
      64             : #include <EnergyPlus/DataHVACGlobals.hh>
      65             : #include <EnergyPlus/DataHeatBalFanSys.hh>
      66             : #include <EnergyPlus/DataHeatBalance.hh>
      67             : #include <EnergyPlus/DataLoopNode.hh>
      68             : #include <EnergyPlus/DataReportingFlags.hh>
      69             : #include <EnergyPlus/DataSurfaces.hh>
      70             : #include <EnergyPlus/DataSystemVariables.hh>
      71             : #include <EnergyPlus/DataZoneEnergyDemands.hh>
      72             : #include <EnergyPlus/DemandManager.hh>
      73             : #include <EnergyPlus/DisplayRoutines.hh>
      74             : #include <EnergyPlus/EMSManager.hh>
      75             : #include <EnergyPlus/ElectricPowerServiceManager.hh>
      76             : #include <EnergyPlus/Fans.hh>
      77             : #include <EnergyPlus/General.hh>
      78             : #include <EnergyPlus/HVACManager.hh>
      79             : #include <EnergyPlus/HVACSizingSimulationManager.hh>
      80             : #include <EnergyPlus/IceThermalStorage.hh>
      81             : #include <EnergyPlus/InternalHeatGains.hh>
      82             : #include <EnergyPlus/NodeInputManager.hh>
      83             : #include <EnergyPlus/NonZoneEquipmentManager.hh>
      84             : #include <EnergyPlus/OutAirNodeManager.hh>
      85             : #include <EnergyPlus/OutputProcessor.hh>
      86             : #include <EnergyPlus/OutputReportTabular.hh>
      87             : #include <EnergyPlus/Plant/DataPlant.hh>
      88             : #include <EnergyPlus/Plant/PlantManager.hh>
      89             : #include <EnergyPlus/PlantCondLoopOperation.hh>
      90             : #include <EnergyPlus/PlantLoopHeatPumpEIR.hh>
      91             : #include <EnergyPlus/PlantUtilities.hh>
      92             : #include <EnergyPlus/PollutionModule.hh>
      93             : #include <EnergyPlus/Psychrometrics.hh>
      94             : #include <EnergyPlus/RefrigeratedCase.hh>
      95             : #include <EnergyPlus/ScheduleManager.hh>
      96             : #include <EnergyPlus/SetPointManager.hh>
      97             : #include <EnergyPlus/SimAirServingZones.hh>
      98             : #include <EnergyPlus/SizingManager.hh>
      99             : #include <EnergyPlus/SystemAvailabilityManager.hh>
     100             : #include <EnergyPlus/SystemReports.hh>
     101             : #include <EnergyPlus/UtilityRoutines.hh>
     102             : #include <EnergyPlus/WaterManager.hh>
     103             : #include <EnergyPlus/ZoneContaminantPredictorCorrector.hh>
     104             : #include <EnergyPlus/ZoneEquipmentManager.hh>
     105             : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
     106             : 
     107             : namespace EnergyPlus::HVACManager {
     108             : 
     109             : // PURPOSE OF THIS MODULE:
     110             : // This module contains the high level HVAC control
     111             : // subroutines.  Subroutine ManageHVAC, which is called from the heat balance,
     112             : // calls the HVAC simulation and is the most probable insertion point for
     113             : // connections to other HVAC engines.  ManageHVAC also controls the system
     114             : // timestep, automatically shortening the timestep to meet convergence criteria.
     115             : 
     116             : // METHODOLOGY EMPLOYED:
     117             : // The basic solution technique is iteration with lagging.
     118             : // The timestep is shortened using a bisection method.
     119             : 
     120             : using namespace DataEnvironment;
     121             : using namespace DataHVACGlobals;
     122             : using namespace DataLoopNode;
     123             : using namespace DataAirLoop;
     124             : 
     125             : static constexpr std::array<Real64, DataPlant::NumConvergenceHistoryTerms> ConvergenceHistoryARR = {0.0, -1.0, -2.0, -3.0, -4.0};
     126             : constexpr Real64 sum_ConvergenceHistoryARR(-10.0);
     127             : constexpr Real64 square_sum_ConvergenceHistoryARR(100.0);
     128             : constexpr Real64 sum_square_ConvergenceHistoryARR(30.0);
     129             : 
     130     2568313 : void ManageHVAC(EnergyPlusData &state)
     131             : {
     132             : 
     133             :     // SUBROUTINE INFORMATION:
     134             :     //       AUTHORS:  Russ Taylor, Dan Fisher
     135             :     //       DATE WRITTEN:  Jan. 1998
     136             :     //       MODIFIED       Jul 2003 (CC) added a subroutine call for air models
     137             :     //       RE-ENGINEERED  May 2008, Brent Griffith, revised variable time step method and zone conditions history
     138             : 
     139             :     // PURPOSE OF THIS SUBROUTINE:
     140             :     // This routine effectively replaces the IBLAST
     141             :     // "SystemDriver" routine.  The main function of the routine
     142             :     // is to set the system timestep, "TimeStepSys", call the models related to zone
     143             :     // air temperatures, and .
     144             : 
     145             :     // METHODOLOGY EMPLOYED:
     146             :     //  manage calls to Predictor and Corrector and other updates in ZoneTempPredictorCorrector
     147             :     //  manage variable time step and when zone air histories are updated.
     148             : 
     149             :     // Using/Aliasing
     150             :     using DemandManager::ManageDemand;
     151             :     using DemandManager::UpdateDemandManagers;
     152             :     using EMSManager::ManageEMS;
     153             :     using InternalHeatGains::UpdateInternalGainValues;
     154             :     using NodeInputManager::CalcMoreNodeInfo;
     155             :     using OutAirNodeManager::SetOutAirNodes;
     156             :     using OutputReportTabular::GatherComponentLoadsHVAC;
     157             :     using OutputReportTabular::UpdateTabularReports; // added for writing tabular output reports
     158             :     using PollutionModule::CalculatePollution;
     159             :     using RefrigeratedCase::ManageRefrigeratedCaseRacks;
     160             :     using ScheduleManager::GetCurrentScheduleValue;
     161             :     using SizingManager::UpdateFacilitySizing;
     162             :     using SystemAvailabilityManager::ManageHybridVentilation;
     163             :     using SystemReports::InitEnergyReports;
     164             :     using SystemReports::ReportSystemEnergyUse;
     165             :     using WaterManager::ManageWater;
     166             :     using WaterManager::ManageWaterInits;
     167             :     using ZoneContaminantPredictorCorrector::ManageZoneContaminanUpdates;
     168             :     using ZoneEquipmentManager::CalcAirFlowSimple;
     169             :     using ZoneEquipmentManager::UpdateZoneSizing;
     170             :     using ZoneTempPredictorCorrector::DetectOscillatingZoneTemp;
     171             :     using ZoneTempPredictorCorrector::ManageZoneAirUpdates;
     172             : 
     173             :     // SUBROUTINE PARAMETER DEFINITIONS:
     174             :     static constexpr std::string_view EndOfHeaderString("End of Data Dictionary");                          // End of data dictionary marker
     175             :     static constexpr std::string_view EnvironmentStampFormatStr("{},{},{:7.2F},{:7.2F},{:7.2F},{:7.2F}\n"); // Format descriptor for environ stamp
     176             : 
     177             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     178             :     Real64 PriorTimeStep;       // magnitude of time step for previous history terms
     179     2568313 :     Real64 ZoneTempChange(0.0); // change in zone air temperature from timestep t-1 to t
     180             :     int NodeNum;
     181             :     bool ReportDebug;
     182             :     int ZoneNum;
     183             : 
     184             :     bool DummyLogical;
     185             : 
     186     2568313 :     auto &AirLoopsSimOnce = state.dataHVACGlobal->AirLoopsSimOnce;
     187     2568313 :     auto &NumOfSysTimeStepsLastZoneTimeStep = state.dataHVACGlobal->NumOfSysTimeStepsLastZoneTimeStep;
     188     2568313 :     auto &SysTimeElapsed = state.dataHVACGlobal->SysTimeElapsed;
     189     2568313 :     auto &TimeStepSys = state.dataHVACGlobal->TimeStepSys;
     190     2568313 :     auto &FirstTimeStepSysFlag = state.dataHVACGlobal->FirstTimeStepSysFlag;
     191     2568313 :     auto &ShortenTimeStepSys = state.dataHVACGlobal->ShortenTimeStepSys;
     192     2568313 :     auto &UseZoneTimeStepHistory = state.dataHVACGlobal->UseZoneTimeStepHistory;
     193     2568313 :     auto &NumOfSysTimeSteps = state.dataHVACGlobal->NumOfSysTimeSteps;
     194     2568313 :     auto &FracTimeStepZone = state.dataHVACGlobal->FracTimeStepZone;
     195     2568313 :     auto &LimitNumSysSteps = state.dataHVACGlobal->LimitNumSysSteps;
     196             : 
     197             :     // SYSTEM INITIALIZATION
     198     2568313 :     if (state.dataHVACMgr->TriggerGetAFN) {
     199         771 :         state.dataHVACMgr->TriggerGetAFN = false;
     200         771 :         DisplayString(state, "Initializing HVAC");
     201         771 :         state.afn->manage_balance(); // first call only gets input and returns.
     202             :     }
     203             : 
     204    21013702 :     for (auto &thisZoneHB : state.dataZoneTempPredictorCorrector->zoneHeatBalance) {
     205    18445389 :         thisZoneHB.ZT = thisZoneHB.MAT;
     206             :         // save for use with thermal comfort control models (Fang, Pierce, and KSU)
     207    18445389 :         thisZoneHB.ZTAV = 0.0;
     208    18445389 :         thisZoneHB.ZoneAirHumRatAvg = 0.0;
     209             :     }
     210     2568313 :     if (state.dataHeatBal->doSpaceHeatBalance) {
     211       28308 :         for (auto &thisSpaceHB : state.dataZoneTempPredictorCorrector->spaceHeatBalance) {
     212       24264 :             thisSpaceHB.ZT = thisSpaceHB.MAT;
     213             :             // save for use with thermal comfort control models (Fang, Pierce, and KSU)
     214       24264 :             thisSpaceHB.ZTAV = 0.0;
     215       24264 :             thisSpaceHB.ZoneAirHumRatAvg = 0.0;
     216             :         }
     217             :     }
     218     2568313 :     state.dataHeatBalFanSys->ZoneThermostatSetPointHiAver = 0.0;
     219     2568313 :     state.dataHeatBalFanSys->ZoneThermostatSetPointLoAver = 0.0;
     220     2568313 :     state.dataHVACMgr->PrintedWarmup = false;
     221     2568313 :     if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
     222       37650 :         state.dataContaminantBalance->OutdoorCO2 = GetCurrentScheduleValue(state, state.dataContaminantBalance->Contaminant.CO2OutdoorSchedPtr);
     223       37650 :         state.dataContaminantBalance->ZoneAirCO2Avg = 0.0;
     224             :     }
     225     2568313 :     if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
     226        7089 :         state.dataContaminantBalance->OutdoorGC =
     227        7089 :             GetCurrentScheduleValue(state, state.dataContaminantBalance->Contaminant.GenericContamOutdoorSchedPtr);
     228        7089 :         if (allocated(state.dataContaminantBalance->ZoneAirGCAvg)) state.dataContaminantBalance->ZoneAirGCAvg = 0.0;
     229             :     }
     230             : 
     231     2568313 :     if (state.dataGlobal->BeginEnvrnFlag && state.dataHVACMgr->MyEnvrnFlag) {
     232        6218 :         AirLoopsSimOnce = false;
     233        6218 :         state.dataHVACMgr->MyEnvrnFlag = false;
     234        6218 :         NumOfSysTimeStepsLastZoneTimeStep = 1;
     235        6218 :         state.dataHVACGlobal->PreviousTimeStep = state.dataGlobal->TimeStepZone;
     236             :     }
     237     2568313 :     if (!state.dataGlobal->BeginEnvrnFlag) {
     238     2562095 :         state.dataHVACMgr->MyEnvrnFlag = true;
     239             :     }
     240             : 
     241     2568313 :     state.dataHeatBalFanSys->QRadSurfAFNDuct = 0.0;
     242     2568313 :     SysTimeElapsed = 0.0;
     243     2568313 :     TimeStepSys = state.dataGlobal->TimeStepZone;
     244     2568313 :     FirstTimeStepSysFlag = true;
     245     2568313 :     ShortenTimeStepSys = false;
     246     2568313 :     UseZoneTimeStepHistory = true;
     247     2568313 :     PriorTimeStep = state.dataGlobal->TimeStepZone;
     248     2568313 :     NumOfSysTimeSteps = 1;
     249     2568313 :     FracTimeStepZone = TimeStepSys / state.dataGlobal->TimeStepZone;
     250             : 
     251             :     bool anyEMSRan;
     252     2568313 :     ManageEMS(state, EMSManager::EMSCallFrom::BeginTimestepBeforePredictor, anyEMSRan, ObjexxFCL::Optional_int_const()); // calling point
     253             : 
     254     2568313 :     SetOutAirNodes(state);
     255             : 
     256     2568313 :     ManageRefrigeratedCaseRacks(state);
     257             : 
     258             :     // ZONE INITIALIZATION  'Get Zone Setpoints'
     259     5136626 :     ManageZoneAirUpdates(state,
     260             :                          DataHeatBalFanSys::PredictorCorrectorCtrl::GetZoneSetPoints,
     261             :                          ZoneTempChange,
     262     2568313 :                          ShortenTimeStepSys,
     263     2568313 :                          UseZoneTimeStepHistory,
     264             :                          PriorTimeStep);
     265     2568313 :     if (state.dataContaminantBalance->Contaminant.SimulateContaminants)
     266       95556 :         ManageZoneContaminanUpdates(
     267       95556 :             state, DataHeatBalFanSys::PredictorCorrectorCtrl::GetZoneSetPoints, ShortenTimeStepSys, UseZoneTimeStepHistory, PriorTimeStep);
     268             : 
     269     2568313 :     ManageHybridVentilation(state);
     270             : 
     271     2568313 :     CalcAirFlowSimple(state);
     272     2568313 :     if (state.afn->simulation_control.type != AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
     273       96108 :         state.afn->RollBackFlag = false;
     274       96108 :         state.afn->manage_balance(false);
     275             :     }
     276             : 
     277     2568313 :     SetHeatToReturnAirFlag(state);
     278             : 
     279    21013702 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
     280    18445389 :         auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum);
     281    18445389 :         thisZoneHB.SysDepZoneLoadsLagged = thisZoneHB.SysDepZoneLoads;
     282    18445389 :         if (state.dataHeatBal->doSpaceHeatBalance) {
     283       48528 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
     284             :                 // SpaceHB ToDo: For now allocate by space volume frac
     285       24264 :                 state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).SysDepZoneLoadsLagged =
     286       24264 :                     thisZoneHB.SysDepZoneLoads * state.dataHeatBal->space(spaceNum).fracZoneVolume;
     287             :             }
     288             :         }
     289             :     }
     290             : 
     291     2568313 :     UpdateInternalGainValues(state, true, true);
     292             : 
     293     5136626 :     ManageZoneAirUpdates(
     294     5136626 :         state, DataHeatBalFanSys::PredictorCorrectorCtrl::PredictStep, ZoneTempChange, ShortenTimeStepSys, UseZoneTimeStepHistory, PriorTimeStep);
     295             : 
     296     2568313 :     if (state.dataContaminantBalance->Contaminant.SimulateContaminants)
     297       95556 :         ManageZoneContaminanUpdates(
     298       95556 :             state, DataHeatBalFanSys::PredictorCorrectorCtrl::PredictStep, ShortenTimeStepSys, UseZoneTimeStepHistory, PriorTimeStep);
     299             : 
     300     2568313 :     SimHVAC(state);
     301             : 
     302     2568313 :     if (state.dataGlobal->AnyIdealCondEntSetPointInModel && state.dataGlobal->MetersHaveBeenInitialized && !state.dataGlobal->WarmupFlag) {
     303         384 :         state.dataGlobal->RunOptCondEntTemp = true;
     304        3500 :         while (state.dataGlobal->RunOptCondEntTemp) {
     305        1558 :             SimHVAC(state);
     306             :         }
     307             :     }
     308             : 
     309     2568313 :     ManageWaterInits(state);
     310             : 
     311             :     // Only simulate once per zone timestep; must be after SimHVAC
     312     2568313 :     if (FirstTimeStepSysFlag && state.dataGlobal->MetersHaveBeenInitialized) {
     313     1776765 :         ManageDemand(state);
     314             :     }
     315             : 
     316     2568313 :     state.dataGlobal->BeginTimeStepFlag = false; // At this point, we have been through the first pass through SimHVAC so this needs to be set
     317             : 
     318     5136626 :     ManageZoneAirUpdates(
     319     5136626 :         state, DataHeatBalFanSys::PredictorCorrectorCtrl::CorrectStep, ZoneTempChange, ShortenTimeStepSys, UseZoneTimeStepHistory, PriorTimeStep);
     320     2568313 :     if (state.dataContaminantBalance->Contaminant.SimulateContaminants)
     321       95556 :         ManageZoneContaminanUpdates(
     322       95556 :             state, DataHeatBalFanSys::PredictorCorrectorCtrl::CorrectStep, ShortenTimeStepSys, UseZoneTimeStepHistory, PriorTimeStep);
     323             : 
     324     2568313 :     if (ZoneTempChange > state.dataConvergeParams->MaxZoneTempDiff && !state.dataGlobal->KickOffSimulation) {
     325             :         // determine value of adaptive system time step
     326             :         // model how many system timesteps we want in zone timestep
     327      345401 :         int ZTempTrendsNumSysSteps = int(ZoneTempChange / state.dataConvergeParams->MaxZoneTempDiff + 1.0); // add 1 for truncation
     328      345401 :         NumOfSysTimeSteps = min(ZTempTrendsNumSysSteps, LimitNumSysSteps);
     329             :         // then determine timestep length for even distribution, protect div by zero
     330      345401 :         if (NumOfSysTimeSteps > 0) TimeStepSys = state.dataGlobal->TimeStepZone / NumOfSysTimeSteps;
     331      345401 :         TimeStepSys = max(TimeStepSys, state.dataConvergeParams->MinTimeStepSys);
     332      345401 :         UseZoneTimeStepHistory = false;
     333      345401 :         ShortenTimeStepSys = true;
     334             :     } else {
     335     2222912 :         NumOfSysTimeSteps = 1;
     336     2222912 :         UseZoneTimeStepHistory = true;
     337             :     }
     338             : 
     339     2568313 :     if (UseZoneTimeStepHistory) state.dataHVACGlobal->PreviousTimeStep = state.dataGlobal->TimeStepZone;
     340     5887100 :     for (int SysTimestepLoop = 1; SysTimestepLoop <= NumOfSysTimeSteps; ++SysTimestepLoop) {
     341     3318787 :         if (state.dataGlobal->stopSimulation) break;
     342             : 
     343     3318787 :         if (TimeStepSys < state.dataGlobal->TimeStepZone) {
     344             : 
     345     1055447 :             ManageHybridVentilation(state);
     346     1055447 :             CalcAirFlowSimple(state, SysTimestepLoop);
     347     1055447 :             if (state.afn->simulation_control.type != AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
     348       62740 :                 state.afn->RollBackFlag = false;
     349       62740 :                 state.afn->manage_balance(false);
     350             :             }
     351             : 
     352     1055447 :             UpdateInternalGainValues(state, true, true);
     353             : 
     354     2110894 :             ManageZoneAirUpdates(state,
     355             :                                  DataHeatBalFanSys::PredictorCorrectorCtrl::PredictStep,
     356             :                                  ZoneTempChange,
     357     1055447 :                                  ShortenTimeStepSys,
     358     1055447 :                                  UseZoneTimeStepHistory,
     359             :                                  PriorTimeStep);
     360             : 
     361     1055447 :             if (state.dataContaminantBalance->Contaminant.SimulateContaminants)
     362       48050 :                 ManageZoneContaminanUpdates(
     363       48050 :                     state, DataHeatBalFanSys::PredictorCorrectorCtrl::PredictStep, ShortenTimeStepSys, UseZoneTimeStepHistory, PriorTimeStep);
     364     1055447 :             SimHVAC(state);
     365             : 
     366     1055447 :             if (state.dataGlobal->AnyIdealCondEntSetPointInModel && state.dataGlobal->MetersHaveBeenInitialized && !state.dataGlobal->WarmupFlag) {
     367          76 :                 state.dataGlobal->RunOptCondEntTemp = true;
     368        1196 :                 while (state.dataGlobal->RunOptCondEntTemp) {
     369         560 :                     SimHVAC(state);
     370             :                 }
     371             :             }
     372             : 
     373     1055447 :             ManageWaterInits(state);
     374             : 
     375             :             // Need to set the flag back since we do not need to shift the temps back again in the correct step.
     376     1055447 :             ShortenTimeStepSys = false;
     377             : 
     378     2110894 :             ManageZoneAirUpdates(state,
     379             :                                  DataHeatBalFanSys::PredictorCorrectorCtrl::CorrectStep,
     380             :                                  ZoneTempChange,
     381     1055447 :                                  ShortenTimeStepSys,
     382     1055447 :                                  UseZoneTimeStepHistory,
     383             :                                  PriorTimeStep);
     384     1055447 :             if (state.dataContaminantBalance->Contaminant.SimulateContaminants)
     385       48050 :                 ManageZoneContaminanUpdates(
     386       48050 :                     state, DataHeatBalFanSys::PredictorCorrectorCtrl::CorrectStep, ShortenTimeStepSys, UseZoneTimeStepHistory, PriorTimeStep);
     387             : 
     388     2110894 :             ManageZoneAirUpdates(state,
     389             :                                  DataHeatBalFanSys::PredictorCorrectorCtrl::PushSystemTimestepHistories,
     390             :                                  ZoneTempChange,
     391     1055447 :                                  ShortenTimeStepSys,
     392     1055447 :                                  UseZoneTimeStepHistory,
     393             :                                  PriorTimeStep);
     394     1055447 :             if (state.dataContaminantBalance->Contaminant.SimulateContaminants)
     395       48050 :                 ManageZoneContaminanUpdates(state,
     396             :                                             DataHeatBalFanSys::PredictorCorrectorCtrl::PushSystemTimestepHistories,
     397       24025 :                                             ShortenTimeStepSys,
     398       24025 :                                             UseZoneTimeStepHistory,
     399             :                                             PriorTimeStep);
     400     1055447 :             state.dataHVACGlobal->PreviousTimeStep = TimeStepSys;
     401             :         }
     402             : 
     403     3318787 :         FracTimeStepZone = TimeStepSys / state.dataGlobal->TimeStepZone;
     404             : 
     405    28499453 :         for (ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
     406    25180666 :             auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
     407    25180666 :             thisZoneHB.ZTAV += thisZoneHB.ZT * FracTimeStepZone;
     408    25180666 :             thisZoneHB.ZoneAirHumRatAvg += thisZoneHB.ZoneAirHumRat * FracTimeStepZone;
     409    25180666 :             if (state.dataHeatBal->doSpaceHeatBalance) {
     410       55068 :                 for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) {
     411       27534 :                     auto &thisSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum);
     412       27534 :                     thisSpaceHB.ZTAV += thisSpaceHB.ZT * FracTimeStepZone;
     413       27534 :                     thisSpaceHB.ZoneAirHumRatAvg += thisSpaceHB.ZoneAirHumRat * FracTimeStepZone;
     414             :                 }
     415             :             }
     416    25180666 :             if (state.dataContaminantBalance->Contaminant.CO2Simulation)
     417      328207 :                 state.dataContaminantBalance->ZoneAirCO2Avg(ZoneNum) += state.dataContaminantBalance->ZoneAirCO2(ZoneNum) * FracTimeStepZone;
     418    25180666 :             if (state.dataContaminantBalance->Contaminant.GenericContamSimulation)
     419      231201 :                 state.dataContaminantBalance->ZoneAirGCAvg(ZoneNum) += state.dataContaminantBalance->ZoneAirGC(ZoneNum) * FracTimeStepZone;
     420    25180666 :             if (state.dataZoneTempPredictorCorrector->NumOnOffCtrZone > 0) {
     421      346719 :                 state.dataHeatBalFanSys->ZoneThermostatSetPointHiAver(ZoneNum) +=
     422      346719 :                     state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ZoneNum) * FracTimeStepZone;
     423      346719 :                 state.dataHeatBalFanSys->ZoneThermostatSetPointLoAver(ZoneNum) +=
     424      346719 :                     state.dataHeatBalFanSys->ZoneThermostatSetPointLo(ZoneNum) * FracTimeStepZone;
     425             :             }
     426             :         }
     427             : 
     428     3318787 :         DetectOscillatingZoneTemp(state);
     429     3318787 :         UpdateZoneListAndGroupLoads(state);           // Must be called before UpdateDataandReport(OutputProcessor::TimeStepType::TimeStepSystem)
     430     3318787 :         IceThermalStorage::UpdateIceFractions(state); // Update fraction of ice stored in TES
     431     3318787 :         ManageWater(state);
     432             :         // update electricity data for net, purchased, sold etc.
     433     3318787 :         DummyLogical = false;
     434     3318787 :         state.dataElectPwrSvcMgr->facilityElectricServiceObj->manageElectricPowerService(state, false, DummyLogical, true);
     435             : 
     436             :         // Update the plant and condenser loop capacitance model temperature history.
     437     3318787 :         PlantManager::UpdateNodeThermalHistory(state);
     438             : 
     439     3318787 :         if (state.dataOutRptTab->displayHeatEmissionsSummary) {
     440     1266396 :             OutputReportTabular::CalcHeatEmissionReport(state);
     441             :         }
     442             : 
     443     3318787 :         ManageEMS(
     444     6637574 :             state, EMSManager::EMSCallFrom::EndSystemTimestepBeforeHVACReporting, anyEMSRan, ObjexxFCL::Optional_int_const()); // EMS calling point
     445             : 
     446             :         // This is where output processor data is updated for System Timestep reporting
     447     3318787 :         if (!state.dataGlobal->WarmupFlag) {
     448      523087 :             if (state.dataGlobal->DoOutputReporting && !state.dataGlobal->ZoneSizingCalc) {
     449      391386 :                 CalcMoreNodeInfo(state);
     450      391386 :                 CalculatePollution(state);
     451      391386 :                 InitEnergyReports(state);
     452      391386 :                 ReportSystemEnergyUse(state);
     453             :             }
     454      523087 :             if (state.dataGlobal->DoOutputReporting || (state.dataGlobal->ZoneSizingCalc && state.dataGlobal->CompLoadReportIsReq)) {
     455      401522 :                 ReportAirHeatBalance(state);
     456      401522 :                 if (state.dataGlobal->ZoneSizingCalc) GatherComponentLoadsHVAC(state);
     457             :             }
     458      523087 :             if (state.dataGlobal->DoOutputReporting) {
     459      391386 :                 SystemReports::ReportVentilationLoads(state);
     460      391386 :                 UpdateDataandReport(state, OutputProcessor::TimeStepType::System);
     461      774031 :                 if (state.dataGlobal->KindOfSim == DataGlobalConstants::KindOfSim::HVACSizeDesignDay ||
     462      382645 :                     state.dataGlobal->KindOfSim == DataGlobalConstants::KindOfSim::HVACSizeRunPeriodDesign) {
     463        8741 :                     if (state.dataHVACSizingSimMgr->hvacSizingSimulationManager)
     464        8741 :                         state.dataHVACSizingSimMgr->hvacSizingSimulationManager->UpdateSizingLogsSystemStep(state);
     465             :                 }
     466      391386 :                 UpdateTabularReports(state, OutputProcessor::TimeStepType::System);
     467             :             }
     468      523087 :             if (state.dataGlobal->ZoneSizingCalc) {
     469      131701 :                 UpdateZoneSizing(state, DataGlobalConstants::CallIndicator::DuringDay);
     470      131701 :                 UpdateFacilitySizing(state, DataGlobalConstants::CallIndicator::DuringDay);
     471             :             }
     472      523087 :             EIRPlantLoopHeatPumps::EIRPlantLoopHeatPump::checkConcurrentOperation(state);
     473     2795700 :         } else if (!state.dataGlobal->KickOffSimulation && state.dataGlobal->DoOutputReporting && state.dataSysVars->ReportDuringWarmup) {
     474           0 :             if (state.dataGlobal->BeginDayFlag && !state.dataEnvrn->PrintEnvrnStampWarmupPrinted) {
     475           0 :                 state.dataEnvrn->PrintEnvrnStampWarmup = true;
     476           0 :                 state.dataEnvrn->PrintEnvrnStampWarmupPrinted = true;
     477             :             }
     478           0 :             if (!state.dataGlobal->BeginDayFlag) state.dataEnvrn->PrintEnvrnStampWarmupPrinted = false;
     479           0 :             if (state.dataEnvrn->PrintEnvrnStampWarmup) {
     480           0 :                 if (state.dataReportFlag->PrintEndDataDictionary && state.dataGlobal->DoOutputReporting && !state.dataHVACMgr->PrintedWarmup) {
     481           0 :                     print(state.files.eso, "{}\n", EndOfHeaderString);
     482           0 :                     print(state.files.mtr, "{}\n", EndOfHeaderString);
     483           0 :                     state.dataReportFlag->PrintEndDataDictionary = false;
     484             :                 }
     485           0 :                 if (state.dataGlobal->DoOutputReporting && !state.dataHVACMgr->PrintedWarmup) {
     486             : 
     487           0 :                     print(state.files.eso,
     488             :                           EnvironmentStampFormatStr,
     489             :                           "1",
     490           0 :                           "Warmup {" + state.dataReportFlag->cWarmupDay + "} " + state.dataEnvrn->EnvironmentName,
     491           0 :                           state.dataEnvrn->Latitude,
     492           0 :                           state.dataEnvrn->Longitude,
     493           0 :                           state.dataEnvrn->TimeZoneNumber,
     494           0 :                           state.dataEnvrn->Elevation);
     495           0 :                     print(state.files.mtr,
     496             :                           EnvironmentStampFormatStr,
     497             :                           "1",
     498           0 :                           "Warmup {" + state.dataReportFlag->cWarmupDay + "} " + state.dataEnvrn->EnvironmentName,
     499           0 :                           state.dataEnvrn->Latitude,
     500           0 :                           state.dataEnvrn->Longitude,
     501           0 :                           state.dataEnvrn->TimeZoneNumber,
     502           0 :                           state.dataEnvrn->Elevation);
     503           0 :                     state.dataEnvrn->PrintEnvrnStampWarmup = false;
     504             :                 }
     505           0 :                 state.dataHVACMgr->PrintedWarmup = true;
     506             :             }
     507           0 :             if (!state.dataGlobal->DoingSizing) {
     508           0 :                 CalcMoreNodeInfo(state);
     509             :             }
     510           0 :             UpdateDataandReport(state, OutputProcessor::TimeStepType::System);
     511           0 :             if (state.dataGlobal->KindOfSim == DataGlobalConstants::KindOfSim::HVACSizeDesignDay ||
     512           0 :                 state.dataGlobal->KindOfSim == DataGlobalConstants::KindOfSim::HVACSizeRunPeriodDesign) {
     513           0 :                 if (state.dataHVACSizingSimMgr->hvacSizingSimulationManager)
     514           0 :                     state.dataHVACSizingSimMgr->hvacSizingSimulationManager->UpdateSizingLogsSystemStep(state);
     515             :             }
     516     2795700 :         } else if (state.dataSysVars->UpdateDataDuringWarmupExternalInterface) { // added for FMI
     517           0 :             if (state.dataGlobal->BeginDayFlag && !state.dataEnvrn->PrintEnvrnStampWarmupPrinted) {
     518           0 :                 state.dataEnvrn->PrintEnvrnStampWarmup = true;
     519           0 :                 state.dataEnvrn->PrintEnvrnStampWarmupPrinted = true;
     520             :             }
     521           0 :             if (!state.dataGlobal->BeginDayFlag) state.dataEnvrn->PrintEnvrnStampWarmupPrinted = false;
     522           0 :             if (state.dataEnvrn->PrintEnvrnStampWarmup) {
     523           0 :                 if (state.dataReportFlag->PrintEndDataDictionary && state.dataGlobal->DoOutputReporting && !state.dataHVACMgr->PrintedWarmup) {
     524           0 :                     print(state.files.eso, "{}\n", EndOfHeaderString);
     525           0 :                     print(state.files.mtr, "{}\n", EndOfHeaderString);
     526           0 :                     state.dataReportFlag->PrintEndDataDictionary = false;
     527             :                 }
     528           0 :                 if (state.dataGlobal->DoOutputReporting && !state.dataHVACMgr->PrintedWarmup) {
     529           0 :                     print(state.files.eso,
     530             :                           EnvironmentStampFormatStr,
     531             :                           "1",
     532           0 :                           "Warmup {" + state.dataReportFlag->cWarmupDay + "} " + state.dataEnvrn->EnvironmentName,
     533           0 :                           state.dataEnvrn->Latitude,
     534           0 :                           state.dataEnvrn->Longitude,
     535           0 :                           state.dataEnvrn->TimeZoneNumber,
     536           0 :                           state.dataEnvrn->Elevation);
     537           0 :                     print(state.files.mtr,
     538             :                           EnvironmentStampFormatStr,
     539             :                           "1",
     540           0 :                           "Warmup {" + state.dataReportFlag->cWarmupDay + "} " + state.dataEnvrn->EnvironmentName,
     541           0 :                           state.dataEnvrn->Latitude,
     542           0 :                           state.dataEnvrn->Longitude,
     543           0 :                           state.dataEnvrn->TimeZoneNumber,
     544           0 :                           state.dataEnvrn->Elevation);
     545           0 :                     state.dataEnvrn->PrintEnvrnStampWarmup = false;
     546             :                 }
     547           0 :                 state.dataHVACMgr->PrintedWarmup = true;
     548             :             }
     549           0 :             UpdateDataandReport(state, OutputProcessor::TimeStepType::System);
     550             :         }
     551     3318787 :         ManageEMS(
     552     6637574 :             state, EMSManager::EMSCallFrom::EndSystemTimestepAfterHVACReporting, anyEMSRan, ObjexxFCL::Optional_int_const()); // EMS calling point
     553             :         // UPDATE SYSTEM CLOCKS
     554     3318787 :         SysTimeElapsed += TimeStepSys;
     555             : 
     556     3318787 :         FirstTimeStepSysFlag = false;
     557             :     } // system time step  loop (loops once if no downstepping)
     558             : 
     559    21013702 :     for (auto &thisZoneHB : state.dataZoneTempPredictorCorrector->zoneHeatBalance) {
     560    18445389 :         thisZoneHB.ZTAVComf = thisZoneHB.ZTAV;
     561    18445389 :         thisZoneHB.ZoneAirHumRatAvgComf = thisZoneHB.ZoneAirHumRatAvg;
     562             :     }
     563     2568313 :     if (state.dataHeatBal->doSpaceHeatBalance) {
     564       28308 :         for (auto &thisSpaceHB : state.dataZoneTempPredictorCorrector->spaceHeatBalance) {
     565       24264 :             thisSpaceHB.ZTAVComf = thisSpaceHB.ZTAV;
     566       24264 :             thisSpaceHB.ZoneAirHumRatAvgComf = thisSpaceHB.ZoneAirHumRatAvg;
     567             :         }
     568             :     }
     569             : 
     570     5136626 :     ManageZoneAirUpdates(state,
     571             :                          DataHeatBalFanSys::PredictorCorrectorCtrl::PushZoneTimestepHistories,
     572             :                          ZoneTempChange,
     573     2568313 :                          ShortenTimeStepSys,
     574     2568313 :                          UseZoneTimeStepHistory,
     575             :                          PriorTimeStep);
     576     2568313 :     if (state.dataContaminantBalance->Contaminant.SimulateContaminants)
     577       95556 :         ManageZoneContaminanUpdates(
     578       95556 :             state, DataHeatBalFanSys::PredictorCorrectorCtrl::PushZoneTimestepHistories, ShortenTimeStepSys, UseZoneTimeStepHistory, PriorTimeStep);
     579             : 
     580     2568313 :     NumOfSysTimeStepsLastZoneTimeStep = NumOfSysTimeSteps;
     581             : 
     582     2568313 :     UpdateDemandManagers(state);
     583             : 
     584             :     // DO FINAL UPDATE OF RECORD KEEPING VARIABLES
     585             :     // Report the Node Data to Aid in Debugging
     586     2568313 :     if (state.dataReportFlag->DebugOutput) {
     587           0 :         if (state.dataReportFlag->EvenDuringWarmup) {
     588           0 :             ReportDebug = true;
     589             :         } else {
     590           0 :             ReportDebug = !state.dataGlobal->WarmupFlag;
     591             :         }
     592           0 :         if ((ReportDebug) && (state.dataGlobal->DayOfSim > 0)) { // Report the node data
     593           0 :             if (size(state.dataLoopNodes->Node) > 0 && !state.dataHVACMgr->DebugNamesReported) {
     594           0 :                 print(state.files.debug, "{}\n", "node #   Name");
     595           0 :                 for (NodeNum = 1; NodeNum <= isize(state.dataLoopNodes->Node); ++NodeNum) {
     596           0 :                     print(state.files.debug, " {:3}     {}\n", NodeNum, state.dataLoopNodes->NodeID(NodeNum));
     597             :                 }
     598           0 :                 state.dataHVACMgr->DebugNamesReported = true;
     599             :             }
     600           0 :             if (size(state.dataLoopNodes->Node) > 0) {
     601           0 :                 print(state.files.debug, "\n\n Day of Sim     Hour of Day    Time\n");
     602           0 :                 print(state.files.debug,
     603             :                       "{:12}{:12} {:22.15N} \n",
     604           0 :                       state.dataGlobal->DayOfSim,
     605           0 :                       state.dataGlobal->HourOfDay,
     606           0 :                       state.dataGlobal->TimeStep * state.dataGlobal->TimeStepZone);
     607           0 :                 print(state.files.debug,
     608             :                       "{}\n",
     609             :                       "node #   Temp   MassMinAv  MassMaxAv TempSP      MassFlow       MassMin       MassMax        MassSP    Press        "
     610           0 :                       "Enthal     HumRat Fluid Type");
     611             :             }
     612           0 :             for (NodeNum = 1; NodeNum <= isize(state.dataLoopNodes->Node); ++NodeNum) {
     613             :                 static constexpr std::string_view Format_20{
     614             :                     " {:3} {:8.2F}  {:8.3F}  {:8.3F}  {:8.2F} {:13.2F} {:13.2F} {:13.2F} {:13.2F}  {:#7.0F}  {:11.2F}  {:9.5F}  {}\n"};
     615             : 
     616           0 :                 print(state.files.debug,
     617             :                       Format_20,
     618             :                       NodeNum,
     619           0 :                       state.dataLoopNodes->Node(NodeNum).Temp,
     620           0 :                       state.dataLoopNodes->Node(NodeNum).MassFlowRateMinAvail,
     621           0 :                       state.dataLoopNodes->Node(NodeNum).MassFlowRateMaxAvail,
     622           0 :                       state.dataLoopNodes->Node(NodeNum).TempSetPoint,
     623           0 :                       state.dataLoopNodes->Node(NodeNum).MassFlowRate,
     624           0 :                       state.dataLoopNodes->Node(NodeNum).MassFlowRateMin,
     625           0 :                       state.dataLoopNodes->Node(NodeNum).MassFlowRateMax,
     626           0 :                       state.dataLoopNodes->Node(NodeNum).MassFlowRateSetPoint,
     627           0 :                       state.dataLoopNodes->Node(NodeNum).Press,
     628           0 :                       state.dataLoopNodes->Node(NodeNum).Enthalpy,
     629           0 :                       state.dataLoopNodes->Node(NodeNum).HumRat,
     630           0 :                       DataLoopNode::NodeFluidTypeNames[static_cast<int>(state.dataLoopNodes->Node(NodeNum).FluidType)]);
     631             :             }
     632             :         }
     633             :     }
     634     2568313 : }
     635             : 
     636     3626116 : void SimHVAC(EnergyPlusData &state)
     637             : {
     638             : 
     639             :     // SUBROUTINE INFORMATION:
     640             :     //       AUTHOR:          Dan Fisher
     641             :     //       DATE WRITTEN:    April 1997
     642             :     //       DATE MODIFIED:   May 1998 (RKS,RDT)
     643             : 
     644             :     // PURPOSE OF THIS SUBROUTINE: Selects and calls the HVAC loop managers
     645             : 
     646             :     // METHODOLOGY EMPLOYED: Each loop manager is called or passed over
     647             :     // in succession based on the logical flags associated with the manager.
     648             :     // The logical flags are set in the manager routines and passed
     649             :     // as parameters to this routine.  Each loop manager potentially
     650             :     // affects a different set of other loop managers.
     651             : 
     652             :     // Future development could involve specifying any number of user
     653             :     // selectable control schemes based on the logical flags used in
     654             :     // this default control algorithm.
     655             : 
     656             :     // Using/Aliasing
     657             :     using DataPlant::NumConvergenceHistoryTerms;
     658             :     using EMSManager::ManageEMS;
     659             :     using General::CreateSysTimeIntervalString;
     660             :     using NonZoneEquipmentManager::ManageNonZoneEquipment;
     661             :     using PlantCondLoopOperation::SetupPlantEMSActuators;
     662             :     using PlantManager::GetPlantInput;
     663             :     using PlantManager::GetPlantLoopData;
     664             :     using PlantManager::InitOneTimePlantSizingInfo;
     665             :     using PlantManager::ReInitPlantLoopsAtFirstHVACIteration;
     666             :     using PlantManager::SetupBranchControlTypes;
     667             :     using PlantManager::SetupInitialPlantCallingOrder;
     668             :     using PlantManager::SetupReports;
     669             :     using PlantUtilities::AnyPlantSplitterMixerLacksContinuity;
     670             :     using PlantUtilities::CheckForRunawayPlantTemps;
     671             :     using PlantUtilities::CheckPlantMixerSplitterConsistency;
     672             :     using PlantUtilities::SetAllPlantSimFlagsToValue;
     673             :     using SetPointManager::ManageSetPoints;
     674             :     using SystemAvailabilityManager::ManageSystemAvailability;
     675             :     using ZoneEquipmentManager::ManageZoneEquipment;
     676             : 
     677             :     // SUBROUTINE PARAMETER DEFINITIONS:
     678     3626116 :     bool constexpr SimWithPlantFlowUnlocked(false);
     679     3626116 :     bool constexpr SimWithPlantFlowLocked(true);
     680             : 
     681             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     682             :     bool FirstHVACIteration; // True when solution technique on first iteration
     683     3626116 :     auto &ErrCount = state.dataHVACMgr->ErrCount;
     684     3626116 :     auto &MaxErrCount = state.dataHVACMgr->MaxErrCount;
     685     3626116 :     auto &ErrEnvironmentName = state.dataHVACMgr->ErrEnvironmentName;
     686             :     int LoopNum;
     687             : 
     688             :     int AirSysNum;
     689             :     int StackDepth;
     690     6264988 :     std::string HistoryTrace;
     691             :     Real64 SlopeHumRat;
     692             :     Real64 SlopeMdot;
     693             :     Real64 SlopeTemps;
     694             :     Real64 AvgValue;
     695             :     bool FoundOscillationByDuplicate;
     696             :     int ZoneNum;
     697             :     int NodeIndex;
     698             :     bool MonotonicIncreaseFound;
     699             :     bool MonotonicDecreaseFound;
     700             : 
     701             :     static constexpr std::array<Real64, DataConvergParams::ConvergLogStackDepth> ConvergLogStackARR = {
     702             :         0.0, -1.0, -2.0, -3.0, -4.0, -5.0, -6.0, -7.0, -8.0, -9.0};
     703     3626116 :     Real64 constexpr sum_ConvergLogStackARR(-45);
     704     3626116 :     Real64 constexpr square_sum_ConvergLogStackARR(2025);
     705     3626116 :     Real64 constexpr sum_square_ConvergLogStackARR(285);
     706             : 
     707     3626116 :     auto &SimZoneEquipmentFlag = state.dataHVACGlobal->SimZoneEquipmentFlag;
     708     3626116 :     auto &SimNonZoneEquipmentFlag = state.dataHVACGlobal->SimNonZoneEquipmentFlag;
     709     3626116 :     auto &SimAirLoopsFlag = state.dataHVACGlobal->SimAirLoopsFlag;
     710     3626116 :     auto &SimPlantLoopsFlag = state.dataHVACGlobal->SimPlantLoopsFlag;
     711     3626116 :     auto &SimElecCircuitsFlag = state.dataHVACGlobal->SimElecCircuitsFlag;
     712     3626116 :     auto &NumPrimaryAirSys = state.dataHVACGlobal->NumPrimaryAirSys;
     713     3626116 :     auto &DoSetPointTest = state.dataHVACGlobal->DoSetPointTest;
     714     3626116 :     auto &SetPointErrorFlag = state.dataHVACGlobal->SetPointErrorFlag;
     715             : 
     716             :     // Initialize all of the simulation flags to true for the first iteration
     717     3626116 :     SimZoneEquipmentFlag = true;
     718     3626116 :     SimNonZoneEquipmentFlag = true;
     719     3626116 :     SimAirLoopsFlag = true;
     720     3626116 :     SimPlantLoopsFlag = true;
     721     3626116 :     SimElecCircuitsFlag = true;
     722     3626116 :     FirstHVACIteration = true;
     723             : 
     724     3626116 :     if (state.dataAirLoop->AirLoopInputsFilled) {
     725     6858357 :         for (auto &e : state.dataAirLoop->AirLoopControlInfo) {
     726             :             // Reset air loop control info for cooling coil active flag (used in TU's for reheat air flow control)
     727     4220254 :             e.CoolingActiveFlag = false;
     728             :             // Reset air loop control info for heating coil active flag (used in OA controller for HX control)
     729     4220254 :             e.HeatingActiveFlag = false;
     730             :             // reset outside air system HX to off first time through
     731     4220254 :             e.HeatRecoveryBypass = true;
     732             :             // set HX check status flag to check for custom control in MixedAir.cc
     733     4220254 :             e.CheckHeatRecoveryBypassStatus = true;
     734             :             // set OA comp simulated flag to false
     735     4220254 :             e.OASysComponentsSimulated = false;
     736             :             // set economizer flow locked flag to false, will reset if custom HX control is used
     737     4220254 :             e.EconomizerFlowLocked = false;
     738             :             // set air loop resim flags for when heat recovery is used and air loop needs another iteration
     739     4220254 :             e.HeatRecoveryResimFlag = true;
     740     4220254 :             e.HeatRecoveryResimFlag2 = false;
     741     4220254 :             e.ResimAirLoopFlag = false;
     742             :         }
     743             :     }
     744             : 
     745             :     // This setups the reports for the Iteration variable that limits how many times
     746             :     //  it goes through all of the HVAC managers before moving on.
     747             :     // The plant loop 'get inputs' and initialization are also done here in order to allow plant loop connected components
     748             :     // simulated by managers other than the plant manager to run correctly.
     749     3626116 :     state.dataHVACMgr->HVACManageIteration = 0;
     750     3626116 :     state.dataPlnt->PlantManageSubIterations = 0;
     751     3626116 :     state.dataPlnt->PlantManageHalfLoopCalls = 0;
     752     3626116 :     SetAllPlantSimFlagsToValue(state, true);
     753     3626116 :     if (!state.dataHVACMgr->SimHVACIterSetup) {
     754        2313 :         SetupOutputVariable(state,
     755             :                             "HVAC System Solver Iteration Count",
     756             :                             OutputProcessor::Unit::None,
     757         771 :                             state.dataHVACMgr->HVACManageIteration,
     758             :                             OutputProcessor::SOVTimeStepType::HVAC,
     759             :                             OutputProcessor::SOVStoreType::Summed,
     760        1542 :                             "SimHVAC");
     761        2313 :         SetupOutputVariable(state,
     762             :                             "Air System Solver Iteration Count",
     763             :                             OutputProcessor::Unit::None,
     764         771 :                             state.dataHVACMgr->RepIterAir,
     765             :                             OutputProcessor::SOVTimeStepType::HVAC,
     766             :                             OutputProcessor::SOVStoreType::Summed,
     767        1542 :                             "SimHVAC");
     768        2313 :         SetupOutputVariable(state,
     769             :                             "Air System Relief Air Total Heat Loss Energy",
     770             :                             OutputProcessor::Unit::J,
     771         771 :                             state.dataHeatBal->SysTotalHVACReliefHeatLoss,
     772             :                             OutputProcessor::SOVTimeStepType::HVAC,
     773             :                             OutputProcessor::SOVStoreType::Summed,
     774        1542 :                             "SimHVAC");
     775        2313 :         SetupOutputVariable(state,
     776             :                             "HVAC System Total Heat Rejection Energy",
     777             :                             OutputProcessor::Unit::J,
     778         771 :                             state.dataHeatBal->SysTotalHVACRejectHeatLoss,
     779             :                             OutputProcessor::SOVTimeStepType::HVAC,
     780             :                             OutputProcessor::SOVStoreType::Summed,
     781        1542 :                             "SimHVAC");
     782         771 :         ManageSetPoints(state); // need to call this before getting plant loop data so setpoint checks can complete okay
     783         771 :         GetPlantLoopData(state);
     784         771 :         GetPlantInput(state);
     785         771 :         SetupInitialPlantCallingOrder(state);
     786         771 :         SetupBranchControlTypes(state); // new routine to do away with input for branch control type
     787             :         //    CALL CheckPlantLoopData
     788         771 :         SetupReports(state);
     789         771 :         if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
     790          71 :             SetupPlantEMSActuators(state);
     791             :         }
     792             : 
     793         771 :         if (state.dataPlnt->TotNumLoops > 0) {
     794        1332 :             SetupOutputVariable(state,
     795             :                                 "Plant Solver Sub Iteration Count",
     796             :                                 OutputProcessor::Unit::None,
     797         444 :                                 state.dataPlnt->PlantManageSubIterations,
     798             :                                 OutputProcessor::SOVTimeStepType::HVAC,
     799             :                                 OutputProcessor::SOVStoreType::Summed,
     800         888 :                                 "SimHVAC");
     801        1332 :             SetupOutputVariable(state,
     802             :                                 "Plant Solver Half Loop Calls Count",
     803             :                                 OutputProcessor::Unit::None,
     804         444 :                                 state.dataPlnt->PlantManageHalfLoopCalls,
     805             :                                 OutputProcessor::SOVTimeStepType::HVAC,
     806             :                                 OutputProcessor::SOVStoreType::Summed,
     807         888 :                                 "SimHVAC");
     808        1553 :             for (LoopNum = 1; LoopNum <= state.dataPlnt->TotNumLoops; ++LoopNum) {
     809             :                 // init plant sizing numbers in main plant data structure
     810        1109 :                 InitOneTimePlantSizingInfo(state, LoopNum);
     811             :             }
     812             :         }
     813         771 :         state.dataHVACMgr->SimHVACIterSetup = true;
     814             :     }
     815             : 
     816     3626116 :     if (state.dataGlobal->ZoneSizingCalc) {
     817      987244 :         ManageZoneEquipment(state, FirstHVACIteration, SimZoneEquipmentFlag, SimAirLoopsFlag);
     818             :         // need to call non zone equipment so water use zone gains can be included in sizing calcs
     819      987244 :         ManageNonZoneEquipment(state, FirstHVACIteration, SimNonZoneEquipmentFlag);
     820      987244 :         state.dataElectPwrSvcMgr->facilityElectricServiceObj->manageElectricPowerService(state, FirstHVACIteration, SimElecCircuitsFlag, false);
     821      987244 :         return;
     822             :     }
     823             : 
     824             :     // Before the HVAC simulation, reset control flags and specified flow
     825             :     // rates that might have been set by the set point and availability
     826             :     // managers.
     827             : 
     828     2638872 :     ResetHVACControl(state);
     829             : 
     830             :     // Before the HVAC simulation, call ManageSetPoints to set all the HVAC
     831             :     // node setpoints
     832     2638872 :     bool anyEMSRan = false;
     833     2638872 :     ManageEMS(state, EMSManager::EMSCallFrom::BeforeHVACManagers, anyEMSRan, ObjexxFCL::Optional_int_const()); // calling point
     834             : 
     835     2638872 :     ManageSetPoints(state);
     836             : 
     837             :     // re-initialize plant loop and nodes.
     838     2638872 :     ReInitPlantLoopsAtFirstHVACIteration(state);
     839             : 
     840             :     // Before the HVAC simulation, call ManageSystemAvailability to set
     841             :     // the system on/off flags
     842     2638872 :     ManageSystemAvailability(state);
     843             : 
     844     2638872 :     ManageEMS(state, EMSManager::EMSCallFrom::AfterHVACManagers, anyEMSRan, ObjexxFCL::Optional_int_const()); // calling point
     845     2638872 :     ManageEMS(state, EMSManager::EMSCallFrom::HVACIterationLoop, anyEMSRan, ObjexxFCL::Optional_int_const()); // calling point id
     846             : 
     847             :     // first explicitly call each system type with FirstHVACIteration,
     848             : 
     849             :     // Manages the various component simulations
     850     2638872 :     SimSelectedEquipment(state,
     851             :                          SimAirLoopsFlag,
     852             :                          SimZoneEquipmentFlag,
     853             :                          SimNonZoneEquipmentFlag,
     854             :                          SimPlantLoopsFlag,
     855             :                          SimElecCircuitsFlag,
     856             :                          FirstHVACIteration,
     857             :                          SimWithPlantFlowUnlocked);
     858             : 
     859             :     // Eventually, when all of the flags are set to false, the
     860             :     // simulation has converged for this system time step.
     861             : 
     862     2638872 :     SimPlantLoopsFlag = true;
     863     2638872 :     SetAllPlantSimFlagsToValue(state, true); // set so loop to simulate at least once on non-first hvac
     864             : 
     865     2638872 :     FirstHVACIteration = false;
     866             : 
     867             :     // then iterate among all systems after first HVAC iteration is over
     868             : 
     869             :     // Main iteration loop for HVAC.  If any of the simulation flags are
     870             :     // true, then specific components must be resimulated.
     871    11505046 :     while ((SimAirLoopsFlag || SimZoneEquipmentFlag || SimNonZoneEquipmentFlag || SimPlantLoopsFlag || SimElecCircuitsFlag) &&
     872     2956732 :            (state.dataHVACMgr->HVACManageIteration <= state.dataConvergeParams->MaxIter)) {
     873             : 
     874     2954721 :         if (state.dataGlobal->stopSimulation) break;
     875             : 
     876     2954721 :         ManageEMS(state, EMSManager::EMSCallFrom::HVACIterationLoop, anyEMSRan, ObjexxFCL::Optional_int_const()); // calling point id
     877             : 
     878             :         // Manages the various component simulations
     879     2954721 :         SimSelectedEquipment(state,
     880             :                              SimAirLoopsFlag,
     881             :                              SimZoneEquipmentFlag,
     882             :                              SimNonZoneEquipmentFlag,
     883             :                              SimPlantLoopsFlag,
     884             :                              SimElecCircuitsFlag,
     885             :                              FirstHVACIteration,
     886             :                              SimWithPlantFlowUnlocked);
     887             : 
     888             :         // Eventually, when all of the flags are set to false, the
     889             :         // simulation has converged for this system time step.
     890             : 
     891     2954721 :         UpdateZoneInletConvergenceLog(state);
     892             : 
     893     2954721 :         ++state.dataHVACMgr->HVACManageIteration; // Increment the iteration counter
     894             : 
     895     2954721 :         if (anyEMSRan && state.dataHVACMgr->HVACManageIteration <= 2) {
     896             :             // the calling point emsCallFromHVACIterationLoop is only effective for air loops if this while loop runs at least twice
     897      177522 :             SimAirLoopsFlag = true;
     898             :         }
     899     2954721 :         if (state.dataHVACMgr->HVACManageIteration < state.dataHVACGlobal->MinAirLoopIterationsAfterFirst) {
     900             :             // sequenced zone loads for airloops may require extra iterations depending upon zone equipment order and load distribution type
     901       70019 :             SimAirLoopsFlag = true;
     902       70019 :             SimZoneEquipmentFlag = true;
     903             :         }
     904             :     }
     905     2638872 :     if (state.dataGlobal->AnyPlantInModel) {
     906     1423921 :         if (AnyPlantSplitterMixerLacksContinuity(state)) {
     907             :             // rerun systems in a "Final flow lock/last iteration" mode
     908             :             // now call for one second to last plant simulation
     909        7382 :             SimAirLoopsFlag = false;
     910        7382 :             SimZoneEquipmentFlag = false;
     911        7382 :             SimNonZoneEquipmentFlag = false;
     912        7382 :             SimPlantLoopsFlag = true;
     913        7382 :             SimElecCircuitsFlag = false;
     914        7382 :             SimSelectedEquipment(state,
     915             :                                  SimAirLoopsFlag,
     916             :                                  SimZoneEquipmentFlag,
     917             :                                  SimNonZoneEquipmentFlag,
     918             :                                  SimPlantLoopsFlag,
     919             :                                  SimElecCircuitsFlag,
     920             :                                  FirstHVACIteration,
     921             :                                  SimWithPlantFlowUnlocked);
     922             :             // now call for all non-plant simulation, but with plant flow lock on
     923        7382 :             SimAirLoopsFlag = true;
     924        7382 :             SimZoneEquipmentFlag = true;
     925        7382 :             SimNonZoneEquipmentFlag = true;
     926        7382 :             SimPlantLoopsFlag = false;
     927        7382 :             SimElecCircuitsFlag = true;
     928        7382 :             SimSelectedEquipment(state,
     929             :                                  SimAirLoopsFlag,
     930             :                                  SimZoneEquipmentFlag,
     931             :                                  SimNonZoneEquipmentFlag,
     932             :                                  SimPlantLoopsFlag,
     933             :                                  SimElecCircuitsFlag,
     934             :                                  FirstHVACIteration,
     935             :                                  SimWithPlantFlowLocked);
     936        7382 :             UpdateZoneInletConvergenceLog(state);
     937             :             // now call for a last plant simulation
     938        7382 :             SimAirLoopsFlag = false;
     939        7382 :             SimZoneEquipmentFlag = false;
     940        7382 :             SimNonZoneEquipmentFlag = false;
     941        7382 :             SimPlantLoopsFlag = true;
     942        7382 :             SimElecCircuitsFlag = false;
     943        7382 :             SimSelectedEquipment(state,
     944             :                                  SimAirLoopsFlag,
     945             :                                  SimZoneEquipmentFlag,
     946             :                                  SimNonZoneEquipmentFlag,
     947             :                                  SimPlantLoopsFlag,
     948             :                                  SimElecCircuitsFlag,
     949             :                                  FirstHVACIteration,
     950             :                                  SimWithPlantFlowUnlocked);
     951             :             // now call for a last all non-plant simulation, but with plant flow lock on
     952        7382 :             SimAirLoopsFlag = true;
     953        7382 :             SimZoneEquipmentFlag = true;
     954        7382 :             SimNonZoneEquipmentFlag = true;
     955        7382 :             SimPlantLoopsFlag = false;
     956        7382 :             SimElecCircuitsFlag = true;
     957        7382 :             SimSelectedEquipment(state,
     958             :                                  SimAirLoopsFlag,
     959             :                                  SimZoneEquipmentFlag,
     960             :                                  SimNonZoneEquipmentFlag,
     961             :                                  SimPlantLoopsFlag,
     962             :                                  SimElecCircuitsFlag,
     963             :                                  FirstHVACIteration,
     964             :                                  SimWithPlantFlowLocked);
     965        7382 :             UpdateZoneInletConvergenceLog(state);
     966             :         }
     967             :     }
     968             : 
     969             :     // Test plant loop for errors
     970     6302465 :     for (LoopNum = 1; LoopNum <= state.dataPlnt->TotNumLoops; ++LoopNum) {
     971    10990779 :         for (DataPlant::LoopSideLocation LoopSide : DataPlant::LoopSideKeys) {
     972     7327186 :             CheckPlantMixerSplitterConsistency(state, LoopNum, LoopSide, FirstHVACIteration);
     973     7327186 :             CheckForRunawayPlantTemps(state, LoopNum, LoopSide);
     974             :         }
     975             :     }
     976             : 
     977     2638872 :     if ((state.dataHVACMgr->HVACManageIteration > state.dataConvergeParams->MaxIter) && (!state.dataGlobal->WarmupFlag)) {
     978         290 :         ++ErrCount;
     979         290 :         if (ErrCount < 15) {
     980         110 :             ErrEnvironmentName = state.dataEnvrn->EnvironmentName;
     981         330 :             ShowWarningError(state,
     982         550 :                              format("SimHVAC: Maximum iterations ({}) exceeded for all HVAC loops, at {}, {} {}",
     983         110 :                                     state.dataConvergeParams->MaxIter,
     984         110 :                                     state.dataEnvrn->EnvironmentName,
     985         110 :                                     state.dataEnvrn->CurMnDy,
     986         330 :                                     CreateSysTimeIntervalString(state)));
     987         110 :             if (SimAirLoopsFlag) {
     988         105 :                 ShowContinueError(state, "The solution for one or more of the Air Loop HVAC systems did not appear to converge");
     989             :             }
     990         110 :             if (SimZoneEquipmentFlag) {
     991          18 :                 ShowContinueError(state, "The solution for zone HVAC equipment did not appear to converge");
     992             :             }
     993         110 :             if (SimNonZoneEquipmentFlag) {
     994           0 :                 ShowContinueError(state, "The solution for non-zone equipment did not appear to converge");
     995             :             }
     996         110 :             if (SimPlantLoopsFlag) {
     997           0 :                 ShowContinueError(state, "The solution for one or more plant systems did not appear to converge");
     998             :             }
     999         110 :             if (SimElecCircuitsFlag) {
    1000           0 :                 ShowContinueError(state, "The solution for on-site electric generators did not appear to converge");
    1001             :             }
    1002         110 :             if (ErrCount == 1 && !state.dataGlobal->DisplayExtraWarnings) {
    1003          15 :                 ShowContinueError(state, "...use Output:Diagnostics,DisplayExtraWarnings; to show more details on each max iteration exceeded.");
    1004             :             }
    1005         110 :             if (state.dataGlobal->DisplayExtraWarnings) {
    1006             : 
    1007           0 :                 for (AirSysNum = 1; AirSysNum <= NumPrimaryAirSys; ++AirSysNum) {
    1008             : 
    1009           0 :                     auto &arrayRef = state.dataConvergeParams->AirLoopConvergence(AirSysNum).HVACMassFlowNotConverged;
    1010           0 :                     if (std::any_of(std::begin(arrayRef), std::end(arrayRef), [](bool i) { return i; })) {
    1011             : 
    1012           0 :                         ShowContinueError(state,
    1013           0 :                                           "Air System Named = " + state.dataAirLoop->AirToZoneNodeInfo(AirSysNum).AirLoopName +
    1014             :                                               " did not converge for mass flow rate");
    1015           0 :                         ShowContinueError(state, "Check values should be zero. Most Recent values listed first.");
    1016           0 :                         HistoryTrace = "";
    1017           0 :                         for (StackDepth = 0; StackDepth < DataConvergParams::ConvergLogStackDepth; ++StackDepth) {
    1018           0 :                             HistoryTrace +=
    1019           0 :                                 format("{:.6R},", state.dataConvergeParams->AirLoopConvergence(AirSysNum).HVACFlowDemandToSupplyTolValue[StackDepth]);
    1020             :                         }
    1021             : 
    1022           0 :                         ShowContinueError(state, "Demand-to-Supply interface mass flow rate check value iteration history trace: " + HistoryTrace);
    1023           0 :                         HistoryTrace = "";
    1024           0 :                         for (StackDepth = 0; StackDepth < DataConvergParams::ConvergLogStackDepth; ++StackDepth) {
    1025           0 :                             HistoryTrace += format(
    1026           0 :                                 "{:.6R},", state.dataConvergeParams->AirLoopConvergence(AirSysNum).HVACFlowSupplyDeck1ToDemandTolValue[StackDepth]);
    1027             :                         }
    1028           0 :                         ShowContinueError(state,
    1029           0 :                                           "Supply-to-demand interface deck 1 mass flow rate check value iteration history trace: " + HistoryTrace);
    1030             : 
    1031           0 :                         if (state.dataAirLoop->AirToZoneNodeInfo(AirSysNum).NumSupplyNodes >= 2) {
    1032           0 :                             HistoryTrace = "";
    1033           0 :                             for (StackDepth = 0; StackDepth < DataConvergParams::ConvergLogStackDepth; ++StackDepth) {
    1034           0 :                                 HistoryTrace +=
    1035           0 :                                     format("{:.6R},",
    1036           0 :                                            state.dataConvergeParams->AirLoopConvergence(AirSysNum).HVACFlowSupplyDeck2ToDemandTolValue[StackDepth]);
    1037             :                             }
    1038           0 :                             ShowContinueError(
    1039           0 :                                 state, "Supply-to-demand interface deck 2 mass flow rate check value iteration history trace: " + HistoryTrace);
    1040             :                         }
    1041             :                     } // mass flow rate not converged
    1042             : 
    1043           0 :                     auto &arrayRef2 = state.dataConvergeParams->AirLoopConvergence(AirSysNum).HVACHumRatNotConverged;
    1044           0 :                     if (std::any_of(std::begin(arrayRef2), std::end(arrayRef2), [](bool i) { return i; })) {
    1045             : 
    1046           0 :                         ShowContinueError(state,
    1047           0 :                                           "Air System Named = " + state.dataAirLoop->AirToZoneNodeInfo(AirSysNum).AirLoopName +
    1048             :                                               " did not converge for humidity ratio");
    1049           0 :                         ShowContinueError(state, "Check values should be zero. Most Recent values listed first.");
    1050           0 :                         HistoryTrace = "";
    1051           0 :                         for (StackDepth = 0; StackDepth < DataConvergParams::ConvergLogStackDepth; ++StackDepth) {
    1052           0 :                             HistoryTrace +=
    1053           0 :                                 format("{:.6R},", state.dataConvergeParams->AirLoopConvergence(AirSysNum).HVACHumDemandToSupplyTolValue[StackDepth]);
    1054             :                         }
    1055           0 :                         ShowContinueError(state, "Demand-to-Supply interface humidity ratio check value iteration history trace: " + HistoryTrace);
    1056           0 :                         HistoryTrace = "";
    1057           0 :                         for (StackDepth = 0; StackDepth < DataConvergParams::ConvergLogStackDepth; ++StackDepth) {
    1058           0 :                             HistoryTrace += format(
    1059           0 :                                 "{:.6R},", state.dataConvergeParams->AirLoopConvergence(AirSysNum).HVACHumSupplyDeck1ToDemandTolValue[StackDepth]);
    1060             :                         }
    1061           0 :                         ShowContinueError(state,
    1062           0 :                                           "Supply-to-demand interface deck 1 humidity ratio check value iteration history trace: " + HistoryTrace);
    1063             : 
    1064           0 :                         if (state.dataAirLoop->AirToZoneNodeInfo(AirSysNum).NumSupplyNodes >= 2) {
    1065           0 :                             HistoryTrace = "";
    1066           0 :                             for (StackDepth = 0; StackDepth < DataConvergParams::ConvergLogStackDepth; ++StackDepth) {
    1067           0 :                                 HistoryTrace +=
    1068           0 :                                     format("{:.6R},",
    1069           0 :                                            state.dataConvergeParams->AirLoopConvergence(AirSysNum).HVACHumSupplyDeck2ToDemandTolValue[StackDepth]);
    1070             :                             }
    1071           0 :                             ShowContinueError(
    1072           0 :                                 state, "Supply-to-demand interface deck 2 humidity ratio check value iteration history trace: " + HistoryTrace);
    1073             :                         }
    1074             :                     } // humidity ratio not converged
    1075             : 
    1076           0 :                     auto &arrayRef3 = state.dataConvergeParams->AirLoopConvergence(AirSysNum).HVACTempNotConverged;
    1077           0 :                     if (std::any_of(std::begin(arrayRef3), std::end(arrayRef3), [](bool i) { return i; })) {
    1078             : 
    1079           0 :                         ShowContinueError(state,
    1080           0 :                                           "Air System Named = " + state.dataAirLoop->AirToZoneNodeInfo(AirSysNum).AirLoopName +
    1081             :                                               " did not converge for temperature");
    1082           0 :                         ShowContinueError(state, "Check values should be zero. Most Recent values listed first.");
    1083           0 :                         HistoryTrace = "";
    1084           0 :                         for (StackDepth = 0; StackDepth < DataConvergParams::ConvergLogStackDepth; ++StackDepth) {
    1085           0 :                             HistoryTrace +=
    1086           0 :                                 format("{:.6R},", state.dataConvergeParams->AirLoopConvergence(AirSysNum).HVACTempDemandToSupplyTolValue[StackDepth]);
    1087             :                         }
    1088           0 :                         ShowContinueError(state, "Demand-to-Supply interface temperature check value iteration history trace: " + HistoryTrace);
    1089           0 :                         HistoryTrace = "";
    1090           0 :                         for (StackDepth = 0; StackDepth < DataConvergParams::ConvergLogStackDepth; ++StackDepth) {
    1091           0 :                             HistoryTrace += format(
    1092           0 :                                 "{:.6R},", state.dataConvergeParams->AirLoopConvergence(AirSysNum).HVACTempSupplyDeck1ToDemandTolValue[StackDepth]);
    1093             :                         }
    1094           0 :                         ShowContinueError(state,
    1095           0 :                                           "Supply-to-demand interface deck 1 temperature check value iteration history trace: " + HistoryTrace);
    1096             : 
    1097           0 :                         if (state.dataAirLoop->AirToZoneNodeInfo(AirSysNum).NumSupplyNodes >= 2) {
    1098           0 :                             HistoryTrace = "";
    1099           0 :                             for (StackDepth = 0; StackDepth < DataConvergParams::ConvergLogStackDepth; ++StackDepth) {
    1100           0 :                                 HistoryTrace +=
    1101           0 :                                     format("{:.6R},",
    1102           0 :                                            state.dataConvergeParams->AirLoopConvergence(AirSysNum).HVACTempSupplyDeck1ToDemandTolValue[StackDepth]);
    1103             :                             }
    1104           0 :                             ShowContinueError(state,
    1105           0 :                                               "Supply-to-demand interface deck 2 temperature check value iteration history trace: " + HistoryTrace);
    1106             :                         }
    1107             :                     } // Temps not converged
    1108             : 
    1109           0 :                     auto &arrayRef4 = state.dataConvergeParams->AirLoopConvergence(AirSysNum).HVACEnergyNotConverged;
    1110           0 :                     if (std::any_of(std::begin(arrayRef4), std::end(arrayRef4), [](bool i) { return i; })) {
    1111             : 
    1112           0 :                         ShowContinueError(state,
    1113           0 :                                           "Air System Named = " + state.dataAirLoop->AirToZoneNodeInfo(AirSysNum).AirLoopName +
    1114             :                                               " did not converge for energy");
    1115           0 :                         ShowContinueError(state, "Check values should be zero. Most Recent values listed first.");
    1116           0 :                         HistoryTrace = "";
    1117           0 :                         for (StackDepth = 0; StackDepth < DataConvergParams::ConvergLogStackDepth; ++StackDepth) {
    1118           0 :                             HistoryTrace += format(
    1119           0 :                                 "{:.6R},", state.dataConvergeParams->AirLoopConvergence(AirSysNum).HVACEnergyDemandToSupplyTolValue[StackDepth]);
    1120             :                         }
    1121           0 :                         ShowContinueError(state, "Demand-to-Supply interface energy check value iteration history trace: " + HistoryTrace);
    1122           0 :                         HistoryTrace = "";
    1123           0 :                         for (StackDepth = 0; StackDepth < DataConvergParams::ConvergLogStackDepth; ++StackDepth) {
    1124           0 :                             HistoryTrace += format(
    1125           0 :                                 "{:.6R},", state.dataConvergeParams->AirLoopConvergence(AirSysNum).HVACEnergySupplyDeck1ToDemandTolValue[StackDepth]);
    1126             :                         }
    1127           0 :                         ShowContinueError(state, "Supply-to-demand interface deck 1 energy check value iteration history trace: " + HistoryTrace);
    1128             : 
    1129           0 :                         if (state.dataAirLoop->AirToZoneNodeInfo(AirSysNum).NumSupplyNodes >= 2) {
    1130           0 :                             HistoryTrace = "";
    1131           0 :                             for (StackDepth = 0; StackDepth < DataConvergParams::ConvergLogStackDepth; ++StackDepth) {
    1132           0 :                                 HistoryTrace +=
    1133           0 :                                     format("{:.6R},",
    1134           0 :                                            state.dataConvergeParams->AirLoopConvergence(AirSysNum).HVACEnergySupplyDeck2ToDemandTolValue[StackDepth]);
    1135             :                             }
    1136           0 :                             ShowContinueError(state, "Supply-to-demand interface deck 2 energy check value iteration history trace: " + HistoryTrace);
    1137             :                         }
    1138             :                     } // energy not converged
    1139             : 
    1140             :                 } // loop over air loop systems
    1141             : 
    1142             :                 // loop over zones and check for issues with zone inlet nodes
    1143           0 :                 for (ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    1144             : 
    1145           0 :                     for (NodeIndex = 1; NodeIndex <= state.dataConvergeParams->ZoneInletConvergence(ZoneNum).NumInletNodes; ++NodeIndex) {
    1146             : 
    1147           0 :                         auto &humRatInletNode = state.dataConvergeParams->ZoneInletConvergence(ZoneNum).InletNode(NodeIndex).HumidityRatio;
    1148           0 :                         auto &mdotInletNode = state.dataConvergeParams->ZoneInletConvergence(ZoneNum).InletNode(NodeIndex).MassFlowRate;
    1149           0 :                         auto &inletTemp = state.dataConvergeParams->ZoneInletConvergence(ZoneNum).InletNode(NodeIndex).Temperature;
    1150             : 
    1151             :                         // Check humidity ratio
    1152           0 :                         FoundOscillationByDuplicate = false;
    1153           0 :                         MonotonicDecreaseFound = false;
    1154           0 :                         MonotonicIncreaseFound = false;
    1155             :                         // check for evidence of oscillation by identifying duplicates when latest value not equal to average
    1156           0 :                         Real64 summation = 0.0;
    1157           0 :                         summation = std::accumulate(humRatInletNode.begin(), humRatInletNode.end(), 0.0);
    1158           0 :                         AvgValue = summation / double(DataConvergParams::ConvergLogStackDepth);
    1159           0 :                         if (std::abs(humRatInletNode[0] - AvgValue) >
    1160             :                             DataConvergParams::HVACHumRatOscillationToler) { // last iterate differs from average
    1161           0 :                             FoundOscillationByDuplicate = false;
    1162           0 :                             for (StackDepth = 1; StackDepth < DataConvergParams::ConvergLogStackDepth; ++StackDepth) {
    1163           0 :                                 if (std::abs(humRatInletNode[0] - humRatInletNode[StackDepth]) < DataConvergParams::HVACHumRatOscillationToler) {
    1164           0 :                                     FoundOscillationByDuplicate = true;
    1165           0 :                                     ShowContinueError(
    1166             :                                         state,
    1167           0 :                                         format("Node named {} shows oscillating humidity ratio across iterations with a repeated value of {:.6R}",
    1168           0 :                                                state.dataLoopNodes->NodeID(
    1169           0 :                                                    state.dataConvergeParams->ZoneInletConvergence(ZoneNum).InletNode(NodeIndex).NodeNum),
    1170           0 :                                                humRatInletNode[0]));
    1171           0 :                                     break;
    1172             :                                 }
    1173             :                             }
    1174           0 :                             if (!FoundOscillationByDuplicate) {
    1175             : 
    1176           0 :                                 auto humRatInletNodDotProd = std::inner_product(
    1177           0 :                                     std::begin(ConvergLogStackARR), std::end(ConvergLogStackARR), std::begin(humRatInletNode), 0.0);
    1178           0 :                                 Real64 summation2 = 0.0;
    1179           0 :                                 summation2 = std::accumulate(humRatInletNode.begin(), humRatInletNode.end(), 0.0);
    1180           0 :                                 SlopeHumRat =
    1181           0 :                                     (sum_ConvergLogStackARR * summation2 - double(DataConvergParams::ConvergLogStackDepth) * humRatInletNodDotProd) /
    1182             :                                     (square_sum_ConvergLogStackARR - double(DataConvergParams::ConvergLogStackDepth) * sum_square_ConvergLogStackARR);
    1183           0 :                                 if (std::abs(SlopeHumRat) > DataConvergParams::HVACHumRatSlopeToler) {
    1184             : 
    1185           0 :                                     if (SlopeHumRat < 0.0) { // check for monotonic decrease
    1186           0 :                                         MonotonicDecreaseFound = true;
    1187           0 :                                         for (StackDepth = 1; StackDepth < DataConvergParams::ConvergLogStackDepth; ++StackDepth) {
    1188           0 :                                             if (humRatInletNode[StackDepth - 1] > humRatInletNode[StackDepth]) {
    1189           0 :                                                 MonotonicDecreaseFound = false;
    1190           0 :                                                 break;
    1191             :                                             }
    1192             :                                         }
    1193           0 :                                         if (MonotonicDecreaseFound) {
    1194           0 :                                             ShowContinueError(
    1195             :                                                 state,
    1196           0 :                                                 format("Node named {} shows monotonically decreasing humidity ratio with a trend "
    1197             :                                                        "rate across iterations of {:.6R} [ kg-water/kg-dryair/iteration]",
    1198           0 :                                                        state.dataLoopNodes->NodeID(
    1199           0 :                                                            state.dataConvergeParams->ZoneInletConvergence(ZoneNum).InletNode(NodeIndex).NodeNum),
    1200           0 :                                                        SlopeHumRat));
    1201             :                                         }
    1202             :                                     } else { // check for monotonic increase
    1203           0 :                                         MonotonicIncreaseFound = true;
    1204           0 :                                         for (StackDepth = 1; StackDepth < DataConvergParams::ConvergLogStackDepth; ++StackDepth) {
    1205           0 :                                             if (humRatInletNode[StackDepth - 1] < humRatInletNode[StackDepth]) {
    1206           0 :                                                 MonotonicIncreaseFound = false;
    1207           0 :                                                 break;
    1208             :                                             }
    1209             :                                         }
    1210           0 :                                         if (MonotonicIncreaseFound) {
    1211           0 :                                             ShowContinueError(
    1212             :                                                 state,
    1213           0 :                                                 format("Node named {} shows monotonically increasing humidity ratio with a trend "
    1214             :                                                        "rate across iterations of {:.6R} [ kg-water/kg-dryair/iteration]",
    1215           0 :                                                        state.dataLoopNodes->NodeID(
    1216           0 :                                                            state.dataConvergeParams->ZoneInletConvergence(ZoneNum).InletNode(NodeIndex).NodeNum),
    1217           0 :                                                        SlopeHumRat));
    1218             :                                         }
    1219             :                                     }
    1220             :                                 } // significant slope in iterates
    1221             :                             }     // no osciallation
    1222             :                         }         // last value does not equal average of stack.
    1223             : 
    1224           0 :                         if (MonotonicDecreaseFound || MonotonicIncreaseFound || FoundOscillationByDuplicate) {
    1225           0 :                             HistoryTrace = "";
    1226           0 :                             for (StackDepth = 0; StackDepth < DataConvergParams::ConvergLogStackDepth; ++StackDepth) {
    1227           0 :                                 HistoryTrace += format("{:.6R},", humRatInletNode[StackDepth]);
    1228             :                             }
    1229           0 :                             ShowContinueError(
    1230             :                                 state,
    1231           0 :                                 "Node named " +
    1232           0 :                                     state.dataLoopNodes->NodeID(
    1233           0 :                                         state.dataConvergeParams->ZoneInletConvergence(ZoneNum).InletNode(NodeIndex).NodeNum) +
    1234           0 :                                     " humidity ratio [kg-water/kg-dryair] iteration history trace (most recent first): " + HistoryTrace);
    1235             :                         } // need to report trace
    1236             :                         // end humidity ratio
    1237             : 
    1238             :                         // Check Mass flow rate
    1239           0 :                         FoundOscillationByDuplicate = false;
    1240           0 :                         MonotonicDecreaseFound = false;
    1241           0 :                         MonotonicIncreaseFound = false;
    1242             :                         // check for evidence of oscillation by identify duplicates when latest value not equal to average
    1243           0 :                         Real64 summation2 = 0.0;
    1244           0 :                         summation2 = std::accumulate(mdotInletNode.begin(), mdotInletNode.end(), 0.0);
    1245           0 :                         AvgValue = summation2 / double(DataConvergParams::ConvergLogStackDepth);
    1246           0 :                         if (std::abs(mdotInletNode[0] - AvgValue) >
    1247             :                             DataConvergParams::HVACFlowRateOscillationToler) { // last iterate differs from average
    1248           0 :                             FoundOscillationByDuplicate = false;
    1249           0 :                             for (StackDepth = 1; StackDepth < DataConvergParams::ConvergLogStackDepth; ++StackDepth) {
    1250           0 :                                 if (std::abs(mdotInletNode[0] - mdotInletNode[StackDepth]) < DataConvergParams::HVACFlowRateOscillationToler) {
    1251           0 :                                     FoundOscillationByDuplicate = true;
    1252           0 :                                     ShowContinueError(
    1253             :                                         state,
    1254           0 :                                         format("Node named {} shows oscillating mass flow rate across iterations with a repeated value of {:.6R}",
    1255           0 :                                                state.dataLoopNodes->NodeID(
    1256           0 :                                                    state.dataConvergeParams->ZoneInletConvergence(ZoneNum).InletNode(NodeIndex).NodeNum),
    1257           0 :                                                mdotInletNode[0]));
    1258           0 :                                     break;
    1259             :                                 }
    1260             :                             }
    1261           0 :                             if (!FoundOscillationByDuplicate) {
    1262             : 
    1263             :                                 auto humRatInletNodDotProd =
    1264           0 :                                     std::inner_product(std::begin(ConvergLogStackARR), std::end(ConvergLogStackARR), std::begin(mdotInletNode), 0.0);
    1265           0 :                                 Real64 summation3 = 0.0;
    1266           0 :                                 summation3 = std::accumulate(mdotInletNode.begin(), mdotInletNode.end(), 0.0);
    1267           0 :                                 SlopeMdot =
    1268           0 :                                     (sum_ConvergLogStackARR * summation3 - double(DataConvergParams::ConvergLogStackDepth) * humRatInletNodDotProd) /
    1269             :                                     (square_sum_ConvergLogStackARR - double(DataConvergParams::ConvergLogStackDepth) * sum_square_ConvergLogStackARR);
    1270           0 :                                 if (std::abs(SlopeMdot) > DataConvergParams::HVACFlowRateSlopeToler) {
    1271           0 :                                     if (SlopeMdot < 0.0) { // check for monotonic decrease
    1272           0 :                                         MonotonicDecreaseFound = true;
    1273           0 :                                         for (StackDepth = 1; StackDepth < DataConvergParams::ConvergLogStackDepth; ++StackDepth) {
    1274           0 :                                             if (mdotInletNode[StackDepth - 1] > mdotInletNode[StackDepth]) {
    1275           0 :                                                 MonotonicDecreaseFound = false;
    1276           0 :                                                 break;
    1277             :                                             }
    1278             :                                         }
    1279           0 :                                         if (MonotonicDecreaseFound) {
    1280           0 :                                             ShowContinueError(
    1281             :                                                 state,
    1282           0 :                                                 format("Node named {} shows monotonically decreasing mass flow rate with a trend "
    1283             :                                                        "rate across iterations of {:.6R} [kg/s/iteration]",
    1284           0 :                                                        state.dataLoopNodes->NodeID(
    1285           0 :                                                            state.dataConvergeParams->ZoneInletConvergence(ZoneNum).InletNode(NodeIndex).NodeNum),
    1286           0 :                                                        SlopeMdot));
    1287             :                                         }
    1288             :                                     } else { // check for monotonic increase
    1289           0 :                                         MonotonicIncreaseFound = true;
    1290           0 :                                         for (StackDepth = 1; StackDepth < DataConvergParams::ConvergLogStackDepth; ++StackDepth) {
    1291           0 :                                             if (mdotInletNode[StackDepth - 1] < mdotInletNode[StackDepth]) {
    1292           0 :                                                 MonotonicIncreaseFound = false;
    1293           0 :                                                 break;
    1294             :                                             }
    1295             :                                         }
    1296           0 :                                         if (MonotonicIncreaseFound) {
    1297           0 :                                             ShowContinueError(
    1298             :                                                 state,
    1299           0 :                                                 format("Node named {} shows monotonically increasing mass flow rate with a trend "
    1300             :                                                        "rate across iterations of {:.6R} [kg/s/iteration]",
    1301           0 :                                                        state.dataLoopNodes->NodeID(
    1302           0 :                                                            state.dataConvergeParams->ZoneInletConvergence(ZoneNum).InletNode(NodeIndex).NodeNum),
    1303           0 :                                                        SlopeMdot));
    1304             :                                         }
    1305             :                                     }
    1306             :                                 } // significant slope in iterates
    1307             :                             }     // no oscillation
    1308             :                         }         // last value does not equal average of stack.
    1309             : 
    1310           0 :                         if (MonotonicDecreaseFound || MonotonicIncreaseFound || FoundOscillationByDuplicate) {
    1311           0 :                             HistoryTrace = "";
    1312           0 :                             for (StackDepth = 0; StackDepth < DataConvergParams::ConvergLogStackDepth; ++StackDepth) {
    1313           0 :                                 HistoryTrace += format("{:.6R},", mdotInletNode[StackDepth]);
    1314             :                             }
    1315           0 :                             ShowContinueError(state,
    1316           0 :                                               "Node named " +
    1317           0 :                                                   state.dataLoopNodes->NodeID(
    1318           0 :                                                       state.dataConvergeParams->ZoneInletConvergence(ZoneNum).InletNode(NodeIndex).NodeNum) +
    1319           0 :                                                   " mass flow rate [kg/s] iteration history trace (most recent first): " + HistoryTrace);
    1320             :                         } // need to report trace
    1321             :                         // end mass flow rate
    1322             : 
    1323             :                         // Check Temperatures
    1324           0 :                         FoundOscillationByDuplicate = false;
    1325           0 :                         MonotonicDecreaseFound = false;
    1326           0 :                         MonotonicIncreaseFound = false;
    1327             :                         // check for evidence of oscillation by identify duplicates when latest value not equal to average
    1328           0 :                         Real64 summation3 = 0.0;
    1329           0 :                         summation3 = std::accumulate(inletTemp.begin(), inletTemp.end(), 0.0);
    1330           0 :                         AvgValue = summation3 / double(DataConvergParams::ConvergLogStackDepth);
    1331           0 :                         if (std::abs(inletTemp[0] - AvgValue) >
    1332             :                             DataConvergParams::HVACTemperatureOscillationToler) { // last iterate differs from average
    1333           0 :                             FoundOscillationByDuplicate = false;
    1334           0 :                             for (StackDepth = 1; StackDepth < DataConvergParams::ConvergLogStackDepth; ++StackDepth) {
    1335           0 :                                 if (std::abs(inletTemp[0] - inletTemp[StackDepth]) < DataConvergParams::HVACTemperatureOscillationToler) {
    1336           0 :                                     FoundOscillationByDuplicate = true;
    1337           0 :                                     ShowContinueError(
    1338             :                                         state,
    1339           0 :                                         format("Node named {} shows oscillating temperatures across iterations with a repeated value of {:.6R}",
    1340           0 :                                                state.dataLoopNodes->NodeID(
    1341           0 :                                                    state.dataConvergeParams->ZoneInletConvergence(ZoneNum).InletNode(NodeIndex).NodeNum),
    1342           0 :                                                inletTemp[0]));
    1343           0 :                                     break;
    1344             :                                 }
    1345             :                             }
    1346           0 :                             if (!FoundOscillationByDuplicate) {
    1347             : 
    1348             :                                 auto inletTempDotProd =
    1349           0 :                                     std::inner_product(std::begin(ConvergLogStackARR), std::end(ConvergLogStackARR), std::begin(inletTemp), 0.0);
    1350             : 
    1351           0 :                                 Real64 summation4 = 0.0;
    1352           0 :                                 summation4 = std::accumulate(inletTemp.begin(), inletTemp.end(), 0.0);
    1353           0 :                                 SlopeTemps =
    1354           0 :                                     (sum_ConvergLogStackARR * summation4 - double(DataConvergParams::ConvergLogStackDepth) * inletTempDotProd) /
    1355             :                                     (square_sum_ConvergLogStackARR - double(DataConvergParams::ConvergLogStackDepth) * sum_square_ConvergLogStackARR);
    1356           0 :                                 if (std::abs(SlopeTemps) > DataConvergParams::HVACTemperatureSlopeToler) {
    1357           0 :                                     if (SlopeTemps < 0.0) { // check for monotonic decrease
    1358           0 :                                         MonotonicDecreaseFound = true;
    1359           0 :                                         for (StackDepth = 1; StackDepth < DataConvergParams::ConvergLogStackDepth; ++StackDepth) {
    1360           0 :                                             if (inletTemp[StackDepth - 1] > inletTemp[StackDepth]) {
    1361           0 :                                                 MonotonicDecreaseFound = false;
    1362           0 :                                                 break;
    1363             :                                             }
    1364             :                                         }
    1365           0 :                                         if (MonotonicDecreaseFound) {
    1366           0 :                                             ShowContinueError(
    1367             :                                                 state,
    1368           0 :                                                 format("Node named {} shows monotonically decreasing temperature with a trend rate "
    1369             :                                                        "across iterations of {:.4R} [C/iteration]",
    1370           0 :                                                        state.dataLoopNodes->NodeID(
    1371           0 :                                                            state.dataConvergeParams->ZoneInletConvergence(ZoneNum).InletNode(NodeIndex).NodeNum),
    1372           0 :                                                        SlopeTemps));
    1373             :                                         }
    1374             :                                     } else { // check for monotonic increase
    1375           0 :                                         MonotonicIncreaseFound = true;
    1376           0 :                                         for (StackDepth = 1; StackDepth < DataConvergParams::ConvergLogStackDepth; ++StackDepth) {
    1377           0 :                                             if (inletTemp[StackDepth - 1] < inletTemp[StackDepth]) {
    1378           0 :                                                 MonotonicIncreaseFound = false;
    1379           0 :                                                 break;
    1380             :                                             }
    1381             :                                         }
    1382           0 :                                         if (MonotonicIncreaseFound) {
    1383           0 :                                             ShowContinueError(
    1384             :                                                 state,
    1385           0 :                                                 format("Node named {} shows monotonically increasing temperatures with a trend "
    1386             :                                                        "rate across iterations of {:.4R} [C/iteration]",
    1387           0 :                                                        state.dataLoopNodes->NodeID(
    1388           0 :                                                            state.dataConvergeParams->ZoneInletConvergence(ZoneNum).InletNode(NodeIndex).NodeNum),
    1389           0 :                                                        SlopeTemps));
    1390             :                                         }
    1391             :                                     }
    1392             :                                 } // significant slope in iterates
    1393             :                             }     // no osciallation
    1394             :                         }         // last value does not equal average of stack.
    1395             : 
    1396           0 :                         if (MonotonicDecreaseFound || MonotonicIncreaseFound || FoundOscillationByDuplicate) {
    1397           0 :                             HistoryTrace = "";
    1398           0 :                             for (StackDepth = 0; StackDepth < DataConvergParams::ConvergLogStackDepth; ++StackDepth) {
    1399           0 :                                 HistoryTrace += format("{:.6R},", inletTemp[StackDepth]);
    1400             :                             }
    1401           0 :                             ShowContinueError(state,
    1402           0 :                                               "Node named " +
    1403           0 :                                                   state.dataLoopNodes->NodeID(
    1404           0 :                                                       state.dataConvergeParams->ZoneInletConvergence(ZoneNum).InletNode(NodeIndex).NodeNum) +
    1405           0 :                                                   " temperature [C] iteration history trace (most recent first): " + HistoryTrace);
    1406             :                         } // need to report trace
    1407             :                           // end Temperature checks
    1408             : 
    1409             :                     } // loop over zone inlet nodes
    1410             :                 }     // loop over zones
    1411             : 
    1412           0 :                 for (LoopNum = 1; LoopNum <= state.dataPlnt->TotNumLoops; ++LoopNum) {
    1413             : 
    1414           0 :                     if (state.dataConvergeParams->PlantConvergence(LoopNum).PlantMassFlowNotConverged) {
    1415           0 :                         ShowContinueError(state,
    1416           0 :                                           "Plant System Named = " + state.dataPlnt->PlantLoop(LoopNum).Name + " did not converge for mass flow rate");
    1417           0 :                         ShowContinueError(state, "Check values should be zero. Most Recent values listed first.");
    1418           0 :                         HistoryTrace = "";
    1419           0 :                         for (StackDepth = 0; StackDepth < DataConvergParams::ConvergLogStackDepth; ++StackDepth) {
    1420           0 :                             HistoryTrace +=
    1421           0 :                                 format("{:.6R},", state.dataConvergeParams->PlantConvergence(LoopNum).PlantFlowDemandToSupplyTolValue[StackDepth]);
    1422             :                         }
    1423           0 :                         ShowContinueError(state, "Demand-to-Supply interface mass flow rate check value iteration history trace: " + HistoryTrace);
    1424           0 :                         HistoryTrace = "";
    1425           0 :                         for (StackDepth = 0; StackDepth < DataConvergParams::ConvergLogStackDepth; ++StackDepth) {
    1426           0 :                             HistoryTrace +=
    1427           0 :                                 format("{:.6R},", state.dataConvergeParams->PlantConvergence(LoopNum).PlantFlowSupplyToDemandTolValue[StackDepth]);
    1428             :                         }
    1429           0 :                         ShowContinueError(state, "Supply-to-Demand interface mass flow rate check value iteration history trace: " + HistoryTrace);
    1430             : 
    1431             :                         // now work with history logs for mass flow to detect issues
    1432           0 :                         for (auto ThisLoopSide : DataPlant::LoopSideKeys) {
    1433             : 
    1434           0 :                             auto &mdotHistInletNode = state.dataPlnt->PlantLoop(LoopNum).LoopSide(ThisLoopSide).InletNode.MassFlowRateHistory;
    1435           0 :                             auto &mdotHistOutletNode = state.dataPlnt->PlantLoop(LoopNum).LoopSide(ThisLoopSide).OutletNode.MassFlowRateHistory;
    1436             : 
    1437             :                             // loop side inlet node
    1438           0 :                             FoundOscillationByDuplicate = false;
    1439           0 :                             MonotonicDecreaseFound = false;
    1440           0 :                             MonotonicIncreaseFound = false;
    1441           0 :                             AvgValue = sum(mdotHistInletNode) / double(NumConvergenceHistoryTerms);
    1442           0 :                             if (std::abs(mdotHistInletNode(1) - AvgValue) > DataConvergParams::PlantFlowRateOscillationToler) {
    1443           0 :                                 FoundOscillationByDuplicate = false;
    1444           0 :                                 for (StackDepth = 2; StackDepth <= NumConvergenceHistoryTerms; ++StackDepth) {
    1445           0 :                                     if (std::abs(mdotHistInletNode(1) - mdotHistInletNode(StackDepth)) <
    1446             :                                         DataConvergParams::PlantFlowRateOscillationToler) {
    1447           0 :                                         FoundOscillationByDuplicate = true;
    1448           0 :                                         ShowContinueError(
    1449             :                                             state,
    1450           0 :                                             format("Node named {} shows oscillating flow rates across iterations with a repeated value of {:.7R}",
    1451           0 :                                                    state.dataPlnt->PlantLoop(LoopNum).LoopSide(ThisLoopSide).NodeNameIn,
    1452           0 :                                                    mdotHistInletNode(1)));
    1453           0 :                                         break;
    1454             :                                     }
    1455             :                                 }
    1456             :                             }
    1457           0 :                             if (!FoundOscillationByDuplicate) {
    1458             : 
    1459           0 :                                 Real64 mdotHistInletNodeDotProd = std::inner_product(
    1460           0 :                                     std::begin(ConvergenceHistoryARR), std::end(ConvergenceHistoryARR), std::begin(mdotHistInletNode), 0.0);
    1461             : 
    1462           0 :                                 SlopeMdot =
    1463           0 :                                     (sum_ConvergenceHistoryARR * sum(mdotHistInletNode) -
    1464           0 :                                      double(NumConvergenceHistoryTerms) * mdotHistInletNodeDotProd) /
    1465             :                                     (square_sum_ConvergenceHistoryARR - double(NumConvergenceHistoryTerms) * sum_square_ConvergenceHistoryARR);
    1466           0 :                                 if (std::abs(SlopeMdot) > DataConvergParams::PlantFlowRateSlopeToler) {
    1467           0 :                                     if (SlopeMdot < 0.0) { // check for monotonic decrease
    1468           0 :                                         MonotonicDecreaseFound = true;
    1469           0 :                                         for (StackDepth = 2; StackDepth <= NumConvergenceHistoryTerms; ++StackDepth) {
    1470           0 :                                             if (mdotHistInletNode(StackDepth - 1) > mdotHistInletNode(StackDepth)) {
    1471           0 :                                                 MonotonicDecreaseFound = false;
    1472           0 :                                                 break;
    1473             :                                             }
    1474             :                                         }
    1475           0 :                                         if (MonotonicDecreaseFound) {
    1476           0 :                                             ShowContinueError(state,
    1477           0 :                                                               format("Node named {} shows monotonically decreasing mass flow rate with a trend "
    1478             :                                                                      "rate across iterations of {:.7R} [kg/s/iteration]",
    1479           0 :                                                                      state.dataPlnt->PlantLoop(LoopNum).LoopSide(ThisLoopSide).NodeNameIn,
    1480           0 :                                                                      SlopeMdot));
    1481             :                                         }
    1482             :                                     } else { // check for monotonic increase
    1483           0 :                                         MonotonicIncreaseFound = true;
    1484           0 :                                         for (StackDepth = 2; StackDepth <= NumConvergenceHistoryTerms; ++StackDepth) {
    1485           0 :                                             if (mdotHistInletNode(StackDepth - 1) < mdotHistInletNode(StackDepth)) {
    1486           0 :                                                 MonotonicIncreaseFound = false;
    1487           0 :                                                 break;
    1488             :                                             }
    1489             :                                         }
    1490           0 :                                         if (MonotonicIncreaseFound) {
    1491           0 :                                             ShowContinueError(state,
    1492           0 :                                                               format("Node named {} shows monotonically increasing mass flow rate with a trend "
    1493             :                                                                      "rate across iterations of {:.7R} [kg/s/iteration]",
    1494           0 :                                                                      state.dataPlnt->PlantLoop(LoopNum).LoopSide(ThisLoopSide).NodeNameIn,
    1495           0 :                                                                      SlopeMdot));
    1496             :                                         }
    1497             :                                     }
    1498             :                                 } // significant slope found
    1499             :                             }     // no oscillation found
    1500             : 
    1501           0 :                             if (MonotonicDecreaseFound || MonotonicIncreaseFound || FoundOscillationByDuplicate) {
    1502           0 :                                 HistoryTrace = "";
    1503           0 :                                 for (StackDepth = 1; StackDepth <= NumConvergenceHistoryTerms; ++StackDepth) {
    1504           0 :                                     HistoryTrace += format("{:.7R},", mdotHistInletNode(StackDepth));
    1505             :                                 }
    1506           0 :                                 ShowContinueError(state,
    1507           0 :                                                   "Node named " + state.dataPlnt->PlantLoop(LoopNum).LoopSide(ThisLoopSide).NodeNameIn +
    1508           0 :                                                       " mass flow rate [kg/s] iteration history trace (most recent first): " + HistoryTrace);
    1509             :                             } // need to report trace
    1510             :                             // end of inlet node
    1511             : 
    1512             :                             // loop side outlet node
    1513           0 :                             FoundOscillationByDuplicate = false;
    1514           0 :                             MonotonicDecreaseFound = false;
    1515           0 :                             MonotonicIncreaseFound = false;
    1516           0 :                             AvgValue = sum(mdotHistOutletNode) / double(NumConvergenceHistoryTerms);
    1517           0 :                             if (std::abs(mdotHistOutletNode(1) - AvgValue) > DataConvergParams::PlantFlowRateOscillationToler) {
    1518           0 :                                 FoundOscillationByDuplicate = false;
    1519           0 :                                 for (StackDepth = 2; StackDepth <= NumConvergenceHistoryTerms; ++StackDepth) {
    1520           0 :                                     if (std::abs(mdotHistOutletNode(1) - mdotHistOutletNode(StackDepth)) <
    1521             :                                         DataConvergParams::PlantFlowRateOscillationToler) {
    1522           0 :                                         FoundOscillationByDuplicate = true;
    1523           0 :                                         ShowContinueError(
    1524             :                                             state,
    1525           0 :                                             format("Node named {} shows oscillating flow rates across iterations with a repeated value of {:.7R}",
    1526           0 :                                                    state.dataPlnt->PlantLoop(LoopNum).LoopSide(ThisLoopSide).NodeNameOut,
    1527           0 :                                                    mdotHistOutletNode(1)));
    1528           0 :                                         break;
    1529             :                                     }
    1530             :                                 }
    1531             :                             }
    1532           0 :                             if (!FoundOscillationByDuplicate) {
    1533             : 
    1534           0 :                                 Real64 mdotHistOutletNodeDotProd = std::inner_product(
    1535           0 :                                     std::begin(ConvergenceHistoryARR), std::end(ConvergenceHistoryARR), std::begin(mdotHistOutletNode), 0.0);
    1536             : 
    1537           0 :                                 SlopeMdot =
    1538           0 :                                     (sum_ConvergenceHistoryARR * sum(mdotHistOutletNode) -
    1539           0 :                                      double(NumConvergenceHistoryTerms) * mdotHistOutletNodeDotProd) /
    1540             :                                     (square_sum_ConvergenceHistoryARR - double(NumConvergenceHistoryTerms) * sum_square_ConvergenceHistoryARR);
    1541           0 :                                 if (std::abs(SlopeMdot) > DataConvergParams::PlantFlowRateSlopeToler) {
    1542           0 :                                     if (SlopeMdot < 0.0) { // check for monotonic decrease
    1543           0 :                                         MonotonicDecreaseFound = true;
    1544           0 :                                         for (StackDepth = 2; StackDepth <= NumConvergenceHistoryTerms; ++StackDepth) {
    1545           0 :                                             if (mdotHistOutletNode(StackDepth - 1) > mdotHistOutletNode(StackDepth)) {
    1546           0 :                                                 MonotonicDecreaseFound = false;
    1547           0 :                                                 break;
    1548             :                                             }
    1549             :                                         }
    1550           0 :                                         if (MonotonicDecreaseFound) {
    1551           0 :                                             ShowContinueError(state,
    1552           0 :                                                               format("Node named {} shows monotonically decreasing mass flow rate with a trend "
    1553             :                                                                      "rate across iterations of {:.7R} [kg/s/iteration]",
    1554           0 :                                                                      state.dataPlnt->PlantLoop(LoopNum).LoopSide(ThisLoopSide).NodeNameOut,
    1555           0 :                                                                      SlopeMdot));
    1556             :                                         }
    1557             :                                     } else { // check for monotonic increase
    1558           0 :                                         MonotonicIncreaseFound = true;
    1559           0 :                                         for (StackDepth = 2; StackDepth <= NumConvergenceHistoryTerms; ++StackDepth) {
    1560           0 :                                             if (mdotHistOutletNode(StackDepth - 1) < mdotHistOutletNode(StackDepth)) {
    1561           0 :                                                 MonotonicIncreaseFound = false;
    1562           0 :                                                 break;
    1563             :                                             }
    1564             :                                         }
    1565           0 :                                         if (MonotonicIncreaseFound) {
    1566           0 :                                             ShowContinueError(state,
    1567           0 :                                                               format("Node named {} shows monotonically increasing mass flow rate with a trend "
    1568             :                                                                      "rate across iterations of {:.7R} [kg/s/iteration]",
    1569           0 :                                                                      state.dataPlnt->PlantLoop(LoopNum).LoopSide(ThisLoopSide).NodeNameOut,
    1570           0 :                                                                      SlopeMdot));
    1571             :                                         }
    1572             :                                     }
    1573             :                                 } // significant slope found
    1574             :                             }     // no oscillation found
    1575             : 
    1576           0 :                             if (MonotonicDecreaseFound || MonotonicIncreaseFound || FoundOscillationByDuplicate) {
    1577           0 :                                 HistoryTrace = "";
    1578           0 :                                 for (StackDepth = 1; StackDepth <= NumConvergenceHistoryTerms; ++StackDepth) {
    1579           0 :                                     HistoryTrace += format("{:.7R},", mdotHistOutletNode(StackDepth));
    1580             :                                 }
    1581           0 :                                 ShowContinueError(state,
    1582           0 :                                                   "Node named " + state.dataPlnt->PlantLoop(LoopNum).LoopSide(ThisLoopSide).NodeNameOut +
    1583           0 :                                                       " mass flow rate [kg/s] iteration history trace (most recent first): " + HistoryTrace);
    1584             :                             } // need to report trace
    1585             :                               // end of Outlet node
    1586             : 
    1587             :                         } // plant loop sides
    1588             : 
    1589             :                     } // mass flow not converged
    1590             : 
    1591           0 :                     if (state.dataConvergeParams->PlantConvergence(LoopNum).PlantTempNotConverged) {
    1592           0 :                         ShowContinueError(state,
    1593           0 :                                           "Plant System Named = " + state.dataPlnt->PlantLoop(LoopNum).Name + " did not converge for temperature");
    1594           0 :                         ShowContinueError(state, "Check values should be zero. Most Recent values listed first.");
    1595           0 :                         HistoryTrace = "";
    1596           0 :                         for (StackDepth = 0; StackDepth < DataConvergParams::ConvergLogStackDepth; ++StackDepth) {
    1597           0 :                             HistoryTrace +=
    1598           0 :                                 format("{:.6R},", state.dataConvergeParams->PlantConvergence(LoopNum).PlantTempDemandToSupplyTolValue[StackDepth]);
    1599             :                         }
    1600           0 :                         ShowContinueError(state, "Demand-to-Supply interface temperature check value iteration history trace: " + HistoryTrace);
    1601           0 :                         HistoryTrace = "";
    1602           0 :                         for (StackDepth = 0; StackDepth < DataConvergParams::ConvergLogStackDepth; ++StackDepth) {
    1603           0 :                             HistoryTrace +=
    1604           0 :                                 format("{:.6R},", state.dataConvergeParams->PlantConvergence(LoopNum).PlantTempSupplyToDemandTolValue[StackDepth]);
    1605             :                         }
    1606           0 :                         ShowContinueError(state, "Supply-to-Demand interface temperature check value iteration history trace: " + HistoryTrace);
    1607             : 
    1608             :                         // now work with history logs for mass flow to detect issues
    1609           0 :                         for (auto ThisLoopSide : DataPlant::LoopSideKeys) {
    1610             : 
    1611           0 :                             auto &tempHistInletNode = state.dataPlnt->PlantLoop(LoopNum).LoopSide(ThisLoopSide).InletNode.TemperatureHistory;
    1612           0 :                             auto &tempHistOutletNode = state.dataPlnt->PlantLoop(LoopNum).LoopSide(ThisLoopSide).OutletNode.TemperatureHistory;
    1613             : 
    1614             :                             // loop side inlet node
    1615           0 :                             FoundOscillationByDuplicate = false;
    1616           0 :                             MonotonicDecreaseFound = false;
    1617           0 :                             MonotonicIncreaseFound = false;
    1618           0 :                             AvgValue = sum(tempHistInletNode) / double(NumConvergenceHistoryTerms);
    1619           0 :                             if (std::abs(tempHistInletNode(1) - AvgValue) > DataConvergParams::PlantTemperatureOscillationToler) {
    1620           0 :                                 FoundOscillationByDuplicate = false;
    1621           0 :                                 for (StackDepth = 2; StackDepth <= NumConvergenceHistoryTerms; ++StackDepth) {
    1622           0 :                                     if (std::abs(tempHistInletNode(1) - tempHistInletNode(StackDepth)) <
    1623             :                                         DataConvergParams::PlantTemperatureOscillationToler) {
    1624           0 :                                         FoundOscillationByDuplicate = true;
    1625           0 :                                         ShowContinueError(
    1626             :                                             state,
    1627           0 :                                             format("Node named {} shows oscillating temperatures across iterations with a repeated value of {:.5R}",
    1628           0 :                                                    state.dataPlnt->PlantLoop(LoopNum).LoopSide(ThisLoopSide).NodeNameIn,
    1629           0 :                                                    tempHistInletNode(1)));
    1630           0 :                                         break;
    1631             :                                     }
    1632             :                                 }
    1633             :                             }
    1634           0 :                             if (!FoundOscillationByDuplicate) {
    1635             : 
    1636           0 :                                 Real64 tempHistInletNodeDotProd = std::inner_product(
    1637           0 :                                     std::begin(ConvergenceHistoryARR), std::end(ConvergenceHistoryARR), std::begin(tempHistInletNode), 0.0);
    1638             : 
    1639           0 :                                 SlopeTemps =
    1640           0 :                                     (sum_ConvergenceHistoryARR * sum(tempHistInletNode) -
    1641           0 :                                      double(NumConvergenceHistoryTerms) * tempHistInletNodeDotProd) /
    1642             :                                     (square_sum_ConvergenceHistoryARR - double(NumConvergenceHistoryTerms) * sum_square_ConvergenceHistoryARR);
    1643           0 :                                 if (std::abs(SlopeTemps) > DataConvergParams::PlantTemperatureSlopeToler) {
    1644           0 :                                     if (SlopeTemps < 0.0) { // check for monotonic decrease
    1645           0 :                                         MonotonicDecreaseFound = true;
    1646           0 :                                         for (StackDepth = 2; StackDepth <= NumConvergenceHistoryTerms; ++StackDepth) {
    1647           0 :                                             if (tempHistInletNode(StackDepth - 1) > tempHistInletNode(StackDepth)) {
    1648           0 :                                                 MonotonicDecreaseFound = false;
    1649           0 :                                                 break;
    1650             :                                             }
    1651             :                                         }
    1652           0 :                                         if (MonotonicDecreaseFound) {
    1653           0 :                                             ShowContinueError(state,
    1654           0 :                                                               format("Node named {} shows monotonically decreasing temperatures with a trend "
    1655             :                                                                      "rate across iterations of {:.5R} [C/iteration]",
    1656           0 :                                                                      state.dataPlnt->PlantLoop(LoopNum).LoopSide(ThisLoopSide).NodeNameIn,
    1657           0 :                                                                      SlopeTemps));
    1658             :                                         }
    1659             :                                     } else { // check for monotonic increase
    1660           0 :                                         MonotonicIncreaseFound = true;
    1661           0 :                                         for (StackDepth = 2; StackDepth <= NumConvergenceHistoryTerms; ++StackDepth) {
    1662           0 :                                             if (tempHistInletNode(StackDepth - 1) < tempHistInletNode(StackDepth)) {
    1663           0 :                                                 MonotonicIncreaseFound = false;
    1664           0 :                                                 break;
    1665             :                                             }
    1666             :                                         }
    1667           0 :                                         if (MonotonicIncreaseFound) {
    1668           0 :                                             ShowContinueError(state,
    1669           0 :                                                               format("Node named {} shows monotonically increasing temperatures with a trend "
    1670             :                                                                      "rate across iterations of {:.5R} [C/iteration]",
    1671           0 :                                                                      state.dataPlnt->PlantLoop(LoopNum).LoopSide(ThisLoopSide).NodeNameIn,
    1672           0 :                                                                      SlopeTemps));
    1673             :                                         }
    1674             :                                     }
    1675             :                                 } // significant slope found
    1676             :                             }     // no oscillation found
    1677             : 
    1678           0 :                             if (MonotonicDecreaseFound || MonotonicIncreaseFound || FoundOscillationByDuplicate) {
    1679           0 :                                 HistoryTrace = "";
    1680           0 :                                 for (StackDepth = 1; StackDepth <= NumConvergenceHistoryTerms; ++StackDepth) {
    1681           0 :                                     HistoryTrace += format("{:.5R},", tempHistInletNode(StackDepth));
    1682             :                                 }
    1683           0 :                                 ShowContinueError(state,
    1684           0 :                                                   "Node named " + state.dataPlnt->PlantLoop(LoopNum).LoopSide(ThisLoopSide).NodeNameIn +
    1685           0 :                                                       " temperature [C] iteration history trace (most recent first): " + HistoryTrace);
    1686             :                             } // need to report trace
    1687             :                             // end of inlet node
    1688             : 
    1689             :                             // loop side outlet node
    1690           0 :                             FoundOscillationByDuplicate = false;
    1691           0 :                             MonotonicDecreaseFound = false;
    1692           0 :                             MonotonicIncreaseFound = false;
    1693           0 :                             AvgValue = sum(tempHistOutletNode) / double(NumConvergenceHistoryTerms);
    1694           0 :                             if (std::abs(tempHistOutletNode(1) - AvgValue) > DataConvergParams::PlantTemperatureOscillationToler) {
    1695           0 :                                 FoundOscillationByDuplicate = false;
    1696           0 :                                 for (StackDepth = 2; StackDepth <= NumConvergenceHistoryTerms; ++StackDepth) {
    1697           0 :                                     if (std::abs(tempHistOutletNode(1) - tempHistOutletNode(StackDepth)) <
    1698             :                                         DataConvergParams::PlantTemperatureOscillationToler) {
    1699           0 :                                         FoundOscillationByDuplicate = true;
    1700           0 :                                         ShowContinueError(
    1701             :                                             state,
    1702           0 :                                             format("Node named {} shows oscillating temperatures across iterations with a repeated value of {:.5R}",
    1703           0 :                                                    state.dataPlnt->PlantLoop(LoopNum).LoopSide(ThisLoopSide).NodeNameOut,
    1704           0 :                                                    tempHistOutletNode(1)));
    1705           0 :                                         break;
    1706             :                                     }
    1707             :                                 }
    1708             :                             }
    1709           0 :                             if (!FoundOscillationByDuplicate) {
    1710             : 
    1711           0 :                                 Real64 tempHistOutletNodeDotProd = std::inner_product(
    1712           0 :                                     std::begin(ConvergenceHistoryARR), std::end(ConvergenceHistoryARR), std::begin(tempHistOutletNode), 0.0);
    1713             : 
    1714           0 :                                 SlopeTemps =
    1715           0 :                                     (sum_ConvergenceHistoryARR * sum(tempHistOutletNode) -
    1716           0 :                                      double(NumConvergenceHistoryTerms) * tempHistOutletNodeDotProd) /
    1717             :                                     (square_sum_ConvergenceHistoryARR - double(NumConvergenceHistoryTerms) * sum_square_ConvergenceHistoryARR);
    1718           0 :                                 if (std::abs(SlopeTemps) > DataConvergParams::PlantFlowRateSlopeToler) {
    1719           0 :                                     if (SlopeTemps < 0.0) { // check for monotonic decrease
    1720           0 :                                         MonotonicDecreaseFound = true;
    1721           0 :                                         for (StackDepth = 2; StackDepth <= NumConvergenceHistoryTerms; ++StackDepth) {
    1722           0 :                                             if (state.dataPlnt->PlantLoop(LoopNum)
    1723           0 :                                                     .LoopSide(ThisLoopSide)
    1724           0 :                                                     .OutletNode.TemperatureHistory(StackDepth - 1) > tempHistOutletNode(StackDepth)) {
    1725           0 :                                                 MonotonicDecreaseFound = false;
    1726           0 :                                                 break;
    1727             :                                             }
    1728             :                                         }
    1729           0 :                                         if (MonotonicDecreaseFound) {
    1730           0 :                                             ShowContinueError(state,
    1731           0 :                                                               format("Node named {} shows monotonically decreasing temperatures with a trend "
    1732             :                                                                      "rate across iterations of {:.5R} [C/iteration]",
    1733           0 :                                                                      state.dataPlnt->PlantLoop(LoopNum).LoopSide(ThisLoopSide).NodeNameOut,
    1734           0 :                                                                      SlopeTemps));
    1735             :                                         }
    1736             :                                     } else { // check for monotonic increase
    1737           0 :                                         MonotonicIncreaseFound = true;
    1738           0 :                                         for (StackDepth = 2; StackDepth <= NumConvergenceHistoryTerms; ++StackDepth) {
    1739           0 :                                             if (state.dataPlnt->PlantLoop(LoopNum)
    1740           0 :                                                     .LoopSide(ThisLoopSide)
    1741           0 :                                                     .OutletNode.TemperatureHistory(StackDepth - 1) < tempHistOutletNode(StackDepth)) {
    1742           0 :                                                 MonotonicIncreaseFound = false;
    1743           0 :                                                 break;
    1744             :                                             }
    1745             :                                         }
    1746           0 :                                         if (MonotonicIncreaseFound) {
    1747           0 :                                             ShowContinueError(state,
    1748           0 :                                                               format("Node named {} shows monotonically increasing temperatures with a trend "
    1749             :                                                                      "rate across iterations of {:.5R} [C/iteration]",
    1750           0 :                                                                      state.dataPlnt->PlantLoop(LoopNum).LoopSide(ThisLoopSide).NodeNameOut,
    1751           0 :                                                                      SlopeTemps));
    1752             :                                         }
    1753             :                                     }
    1754             :                                 } // significant slope found
    1755             :                             }     // no oscillation found
    1756             : 
    1757           0 :                             if (MonotonicDecreaseFound || MonotonicIncreaseFound || FoundOscillationByDuplicate) {
    1758           0 :                                 HistoryTrace = "";
    1759           0 :                                 for (StackDepth = 1; StackDepth <= NumConvergenceHistoryTerms; ++StackDepth) {
    1760           0 :                                     HistoryTrace += format("{:.5R},", tempHistOutletNode(StackDepth));
    1761             :                                 }
    1762           0 :                                 ShowContinueError(state,
    1763           0 :                                                   "Node named " + state.dataPlnt->PlantLoop(LoopNum).LoopSide(ThisLoopSide).NodeNameOut +
    1764           0 :                                                       " temperature [C] iteration history trace (most recent first): " + HistoryTrace);
    1765             :                             } // need to report trace
    1766             :                               // end of Outlet node
    1767             : 
    1768             :                         } // plant loop sides
    1769             : 
    1770             :                     } // temperature not converged
    1771             :                 }     // loop over plant loop systems
    1772             :             }
    1773             :         } else {
    1774         180 :             if (state.dataEnvrn->EnvironmentName == ErrEnvironmentName) {
    1775         540 :                 ShowRecurringWarningErrorAtEnd(state,
    1776         360 :                                                "SimHVAC: Exceeding Maximum iterations for all HVAC loops, during " +
    1777         540 :                                                    state.dataEnvrn->EnvironmentName + " continues",
    1778             :                                                MaxErrCount);
    1779             :             } else {
    1780           0 :                 MaxErrCount = 0;
    1781           0 :                 ErrEnvironmentName = state.dataEnvrn->EnvironmentName;
    1782           0 :                 ShowRecurringWarningErrorAtEnd(state,
    1783           0 :                                                "SimHVAC: Exceeding Maximum iterations for all HVAC loops, during " +
    1784           0 :                                                    state.dataEnvrn->EnvironmentName + " continues",
    1785             :                                                MaxErrCount);
    1786             :             }
    1787             :         }
    1788             :     }
    1789             : 
    1790     2638872 :     CheckAirLoopFlowBalance(state);
    1791             : 
    1792             :     // Set node setpoints to a flag value so that controllers can check whether their sensed nodes
    1793             :     // have a setpoint
    1794     2638872 :     if (!state.dataGlobal->ZoneSizingCalc && !state.dataGlobal->SysSizingCalc) {
    1795     2638872 :         if (state.dataHVACMgr->MySetPointInit) {
    1796         769 :             if (state.dataLoopNodes->NumOfNodes > 0) {
    1797       60129 :                 for (auto &e : state.dataLoopNodes->Node) {
    1798       59425 :                     e.TempSetPoint = SensedNodeFlagValue;
    1799       59425 :                     e.HumRatSetPoint = SensedNodeFlagValue;
    1800       59425 :                     e.HumRatMin = SensedNodeFlagValue;
    1801       59425 :                     e.HumRatMax = SensedNodeFlagValue;
    1802       59425 :                     e.MassFlowRateSetPoint = SensedNodeFlagValue; // BG 5-26-2009 (being checked in HVACControllers.cc)
    1803             :                 }
    1804         704 :                 state.dataLoopNodes->DefaultNodeValues.TempSetPoint = SensedNodeFlagValue;
    1805         704 :                 state.dataLoopNodes->DefaultNodeValues.HumRatSetPoint = SensedNodeFlagValue;
    1806         704 :                 state.dataLoopNodes->DefaultNodeValues.HumRatMin = SensedNodeFlagValue;
    1807         704 :                 state.dataLoopNodes->DefaultNodeValues.HumRatMax = SensedNodeFlagValue;
    1808         704 :                 state.dataLoopNodes->DefaultNodeValues.MassFlowRateSetPoint =
    1809             :                     SensedNodeFlagValue; // BG 5-26-2009 (being checked in HVACControllers.cc)
    1810             :             }
    1811         769 :             state.dataHVACMgr->MySetPointInit = false;
    1812         769 :             DoSetPointTest = true;
    1813             :         } else {
    1814     2638103 :             DoSetPointTest = false;
    1815             :         }
    1816             : 
    1817     2638872 :         if (state.dataCoilCooingDX->stillNeedToReportStandardRatings) {
    1818      947186 :             if (!state.dataGlobal->ZoneSizingCalc && !state.dataGlobal->SysSizingCalc && !state.dataGlobal->WarmupFlag) {
    1819         769 :                 CoilCoolingDX::reportAllStandardRatings(state);
    1820             :             }
    1821             :         }
    1822             :     }
    1823     2638872 :     if (SetPointErrorFlag) {
    1824           0 :         ShowFatalError(state, "Previous severe set point errors cause program termination");
    1825             :     }
    1826             : }
    1827             : 
    1828     5623121 : void SimSelectedEquipment(EnergyPlusData &state,
    1829             :                           bool &SimAirLoops,         // True when the air loops need to be (re)simulated
    1830             :                           bool &SimZoneEquipment,    // True when zone equipment components need to be (re)simulated
    1831             :                           bool &SimNonZoneEquipment, // True when non-zone equipment components need to be (re)simulated
    1832             :                           bool &SimPlantLoops,       // True when the main plant loops need to be (re)simulated
    1833             :                           bool &SimElecCircuits,     // True when electric circuits need to be (re)simulated
    1834             :                           bool &FirstHVACIteration,  // True when solution technique on first iteration
    1835             :                           bool const LockPlantFlows)
    1836             : {
    1837             : 
    1838             :     // SUBROUTINE INFORMATION:
    1839             :     //       AUTHOR         Russ Taylor, Rick Strand
    1840             :     //       DATE WRITTEN   May 1998
    1841             :     //       MODIFIED       na
    1842             :     //       RE-ENGINEERED  na
    1843             : 
    1844             :     // PURPOSE OF THIS SUBROUTINE:
    1845             :     // This subroutine receives the flags from SimHVAC which determines
    1846             :     // which middle-level managers must be called.
    1847             : 
    1848             :     // METHODOLOGY EMPLOYED:
    1849             :     // Each flag is checked and the appropriate manager is then called.
    1850             : 
    1851             :     // Using/Aliasing
    1852             :     using NonZoneEquipmentManager::ManageNonZoneEquipment;
    1853             :     using PlantManager::ManagePlantLoops;
    1854             :     using PlantUtilities::AnyPlantLoopSidesNeedSim;
    1855             :     using PlantUtilities::ResetAllPlantInterConnectFlags;
    1856             :     using PlantUtilities::SetAllFlowLocks;
    1857             :     using SimAirServingZones::ManageAirLoops;
    1858             :     using ZoneEquipmentManager::ManageZoneEquipment;
    1859             : 
    1860             :     // Locals
    1861             :     // SUBROUTINE ARGUMENT DEFINITIONS:
    1862             :     bool ResimulateAirZone; // True when solution technique on third iteration used in AirflowNetwork
    1863             : 
    1864             :     // SUBROUTINE PARAMETER DEFINITIONS:
    1865     5623121 :     int constexpr MaxAir(5); // Iteration Max for Air Simulation Iterations
    1866             : 
    1867             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1868             :     int IterAir; // counts iterations to enforce maximum iteration limit
    1869             : 
    1870     5623121 :     IterAir = 0;
    1871             : 
    1872             :     // Set all plant flow locks to UNLOCKED to allow air side components to operate properly
    1873             :     // This requires that the plant flow resolver carefully set the min/max avail limits on
    1874             :     //  air side components to ensure they request within bounds.
    1875     5623121 :     if (LockPlantFlows) {
    1876       14764 :         SetAllFlowLocks(state, DataPlant::FlowLock::Locked);
    1877             :     } else {
    1878     5608357 :         SetAllFlowLocks(state, DataPlant::FlowLock::Unlocked);
    1879             :     }
    1880     5623121 :     ResetAllPlantInterConnectFlags(state);
    1881             : 
    1882     5623121 :     if (state.dataGlobal->BeginEnvrnFlag && state.dataHVACMgr->MyEnvrnFlag2) {
    1883             :         // Following comment is incorrect!  (LKL) Even the first time through this does more than read in data.
    1884             :         // Zone equipment data needs to be read in before air loop data to allow the
    1885             :         // determination of which zones are connected to which air loops.
    1886             :         // This call of ManageZoneEquipment does nothing except force the
    1887             :         // zone equipment data to be read in.
    1888        4495 :         ManageZoneEquipment(state, FirstHVACIteration, SimZoneEquipment, SimAirLoops);
    1889        4495 :         state.dataHVACMgr->MyEnvrnFlag2 = false;
    1890             :     }
    1891     5623121 :     if (!state.dataGlobal->BeginEnvrnFlag) {
    1892     5596759 :         state.dataHVACMgr->MyEnvrnFlag2 = true;
    1893             :     }
    1894             : 
    1895     5623121 :     if (FirstHVACIteration) {
    1896     2638872 :         state.dataHVACMgr->RepIterAir = 0;
    1897             :         // Call AirflowNetwork simulation to calculate air flows and pressures
    1898     2638872 :         if (state.afn->simulation_control.type != AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
    1899      136813 :             state.afn->manage_balance(FirstHVACIteration);
    1900             :         }
    1901     2638872 :         ManageAirLoops(state, FirstHVACIteration, SimAirLoops, SimZoneEquipment);
    1902     2638872 :         state.dataAirLoop->AirLoopInputsFilled = true; // all air loop inputs have been read in
    1903     2638872 :         SimAirLoops = true; // Need to make sure that SimAirLoop is simulated at min twice to calculate PLR in some air loop equipment
    1904     2638872 :         state.dataHVACGlobal->AirLoopsSimOnce = true; // air loops simulated once for this environment
    1905     2638872 :         ResetTerminalUnitFlowLimits(state);
    1906     2638872 :         state.dataHVACMgr->FlowMaxAvailAlreadyReset = true;
    1907     2638872 :         ManageZoneEquipment(state, FirstHVACIteration, SimZoneEquipment, SimAirLoops);
    1908     2638872 :         SimZoneEquipment = true; // needs to be simulated at least twice for flow resolution to propagate to this routine
    1909     2638872 :         ManageNonZoneEquipment(state, FirstHVACIteration, SimNonZoneEquipment);
    1910     7916616 :         state.dataElectPwrSvcMgr->facilityElectricServiceObj->manageElectricPowerService(
    1911     5277744 :             state, FirstHVACIteration, state.dataHVACGlobal->SimElecCircuitsFlag, false);
    1912             : 
    1913     2638872 :         ManagePlantLoops(state, FirstHVACIteration, SimAirLoops, SimZoneEquipment, SimNonZoneEquipment, SimPlantLoops, SimElecCircuits);
    1914             : 
    1915     2638872 :         state.dataErrTracking->AskForPlantCheckOnAbort = true; // need to make a first pass through plant calcs before this check make sense
    1916     7916616 :         state.dataElectPwrSvcMgr->facilityElectricServiceObj->manageElectricPowerService(
    1917     5277744 :             state, FirstHVACIteration, state.dataHVACGlobal->SimElecCircuitsFlag, false);
    1918             :     } else {
    1919     2984249 :         state.dataHVACMgr->FlowResolutionNeeded = false;
    1920    10676547 :         while ((SimAirLoops || SimZoneEquipment) && (IterAir <= MaxAir)) {
    1921     3846149 :             ++IterAir; // Increment the iteration counter
    1922             :             // Call AirflowNetwork simulation to calculate air flows and pressures
    1923     3846149 :             ResimulateAirZone = false;
    1924     3846149 :             if (state.afn->simulation_control.type != AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
    1925      357307 :                 state.afn->manage_balance(FirstHVACIteration, IterAir, ResimulateAirZone);
    1926             :             }
    1927     3846149 :             if (SimAirLoops) {
    1928     3845724 :                 ManageAirLoops(state, FirstHVACIteration, SimAirLoops, SimZoneEquipment);
    1929     3845724 :                 SimElecCircuits = true; // If this was simulated there are possible electric changes that need to be simulated
    1930             :             }
    1931             : 
    1932             :             // make sure flow resolution gets done
    1933     3846149 :             if (state.dataHVACMgr->FlowResolutionNeeded) {
    1934      103080 :                 SimZoneEquipment = true;
    1935             :             }
    1936     3846149 :             if (SimZoneEquipment) {
    1937     3406461 :                 if ((IterAir == 1) && (!state.dataHVACMgr->FlowMaxAvailAlreadyReset)) { // don't do reset if already done in FirstHVACIteration
    1938             :                     // ResetTerminalUnitFlowLimits(); // don't do reset at all - interferes with convergence and terminal unit flow controls
    1939      150583 :                     state.dataHVACMgr->FlowResolutionNeeded = true;
    1940             :                 } else {
    1941     3255878 :                     ResolveAirLoopFlowLimits(state);
    1942     3255878 :                     state.dataHVACMgr->FlowResolutionNeeded = false;
    1943             :                 }
    1944     3406461 :                 ManageZoneEquipment(state, FirstHVACIteration, SimZoneEquipment, SimAirLoops);
    1945     3406461 :                 SimElecCircuits = true; // If this was simulated there are possible electric changes that need to be simulated
    1946             :             }
    1947     3846149 :             state.dataHVACMgr->FlowMaxAvailAlreadyReset = false;
    1948             : 
    1949             :             //      IterAir = IterAir + 1   ! Increment the iteration counter
    1950     3846149 :             if (state.afn->simulation_control.type != AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
    1951      357307 :                 if (ResimulateAirZone) { // Need to make sure that SimAirLoop and SimZoneEquipment are simulated
    1952      166412 :                     SimAirLoops = true;  // at min three times using ONOFF fan with the AirflowNetwork model
    1953      166412 :                     SimZoneEquipment = true;
    1954             :                 }
    1955             :             }
    1956             :         }
    1957             : 
    1958     2984249 :         state.dataHVACMgr->RepIterAir += IterAir;
    1959             :         // Check to see if any components have been locked out. If so, SimAirLoops will be reset to TRUE.
    1960     2984249 :         ResolveLockoutFlags(state, SimAirLoops);
    1961             : 
    1962     2984249 :         if (SimNonZoneEquipment) {
    1963     2653636 :             ManageNonZoneEquipment(state, FirstHVACIteration, SimNonZoneEquipment);
    1964     2653636 :             SimElecCircuits = true; // If this was simulated there are possible electric changes that need to be simulated
    1965             :         }
    1966             : 
    1967     2984249 :         if (SimElecCircuits) {
    1968     8907000 :             state.dataElectPwrSvcMgr->facilityElectricServiceObj->manageElectricPowerService(
    1969     5938000 :                 state, FirstHVACIteration, state.dataHVACGlobal->SimElecCircuitsFlag, false);
    1970             :         }
    1971             : 
    1972     2984249 :         if (!SimPlantLoops) {
    1973             :             // check to see if any air side component may have requested plant resim
    1974      330128 :             if (AnyPlantLoopSidesNeedSim(state)) {
    1975       45758 :                 SimPlantLoops = true;
    1976             :             }
    1977             :         }
    1978             : 
    1979     2984249 :         if (SimPlantLoops) {
    1980     2699879 :             ManagePlantLoops(state, FirstHVACIteration, SimAirLoops, SimZoneEquipment, SimNonZoneEquipment, SimPlantLoops, SimElecCircuits);
    1981             :         }
    1982             : 
    1983     2984249 :         if (SimElecCircuits) {
    1984        4824 :             state.dataElectPwrSvcMgr->facilityElectricServiceObj->manageElectricPowerService(
    1985        3216 :                 state, FirstHVACIteration, state.dataHVACGlobal->SimElecCircuitsFlag, false);
    1986             :         }
    1987             :     }
    1988     5623121 : }
    1989             : 
    1990     2638872 : void ResetTerminalUnitFlowLimits(EnergyPlusData &state)
    1991             : {
    1992             : 
    1993             :     // SUBROUTINE INFORMATION:
    1994             :     //       AUTHOR         Fred Buhl
    1995             :     //       DATE WRITTEN   Feb 2010
    1996             :     //       MODIFIED       na
    1997             :     //       RE-ENGINEERED  na
    1998             : 
    1999             :     // PURPOSE OF THIS SUBROUTINE:
    2000             :     // Reset the max flow available limits at the inlet nodes of terminal units
    2001             : 
    2002             :     // METHODOLOGY EMPLOYED:
    2003             :     // Loops through all air loops, finds the inlet nodes of the terminal units
    2004             :     // served by each air loop, and resets the node MassFlowRateMaxAvail (and MinAvail) to
    2005             :     // the hard max and mins.
    2006             : 
    2007             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2008             :     int AirLoopIndex;
    2009             :     int ZonesCooledIndex;
    2010             :     int ZonesHeatedIndex;
    2011             :     int TermInletNode;
    2012             : 
    2013     6860298 :     for (AirLoopIndex = 1; AirLoopIndex <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopIndex) { // loop over the primary air loops
    2014    17273386 :         for (ZonesCooledIndex = 1; ZonesCooledIndex <= state.dataAirLoop->AirToZoneNodeInfo(AirLoopIndex).NumZonesCooled;
    2015             :              ++ZonesCooledIndex) { // loop over the zones cooled by this air loop
    2016    13051960 :             TermInletNode = state.dataAirLoop->AirToZoneNodeInfo(AirLoopIndex).TermUnitCoolInletNodes(ZonesCooledIndex);
    2017             :             // reset the max avail flow rate at the terminal unit cold air inlet to the max
    2018    13051960 :             state.dataLoopNodes->Node(TermInletNode).MassFlowRateMaxAvail = state.dataLoopNodes->Node(TermInletNode).MassFlowRateMax;
    2019    13051960 :             state.dataLoopNodes->Node(TermInletNode).MassFlowRateMinAvail = state.dataLoopNodes->Node(TermInletNode).MassFlowRateMin;
    2020             :         }
    2021     4304665 :         for (ZonesHeatedIndex = 1; ZonesHeatedIndex <= state.dataAirLoop->AirToZoneNodeInfo(AirLoopIndex).NumZonesHeated;
    2022             :              ++ZonesHeatedIndex) { // loop over the zones heated by this air loop
    2023       83239 :             TermInletNode = state.dataAirLoop->AirToZoneNodeInfo(AirLoopIndex).TermUnitHeatInletNodes(ZonesHeatedIndex);
    2024             :             // reset the max avail flow rate at the terminal unit hot air inlet to the max
    2025       83239 :             state.dataLoopNodes->Node(TermInletNode).MassFlowRateMaxAvail = state.dataLoopNodes->Node(TermInletNode).MassFlowRateMax;
    2026       83239 :             state.dataLoopNodes->Node(TermInletNode).MassFlowRateMinAvail = state.dataLoopNodes->Node(TermInletNode).MassFlowRateMin;
    2027             :         }
    2028             :     }
    2029     2638872 : }
    2030             : 
    2031     3255878 : void ResolveAirLoopFlowLimits(EnergyPlusData &state)
    2032             : {
    2033             : 
    2034             :     // SUBROUTINE INFORMATION:
    2035             :     //       AUTHOR         Fred Buhl
    2036             :     //       DATE WRITTEN   August 2003
    2037             :     //       MODIFIED       na
    2038             :     //       RE-ENGINEERED  na
    2039             : 
    2040             :     // PURPOSE OF THIS SUBROUTINE:
    2041             :     // This subroutine is for resolving hard flow mismatches between zone equipment and
    2042             :     // the primary air loop. Such a mismatch can occur when the air terminal units are
    2043             :     // requesting more air than the central air system can supply.
    2044             : 
    2045             :     // METHODOLOGY EMPLOYED:
    2046             :     // Sets the MassFlowRateMaxAvail on the terminal unit inlet nodes to match the
    2047             :     // maximum available from the primary air loop.
    2048             : 
    2049             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2050             :     int AirLoopIndex;
    2051             :     int ZonesCooledIndex;
    2052             :     int ZonesHeatedIndex;
    2053             :     int TermInletNode;
    2054             :     int SupplyIndex;
    2055             :     int SupplyNode;
    2056             :     Real64 FlowRatio;
    2057             : 
    2058     9393621 :     for (AirLoopIndex = 1; AirLoopIndex <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopIndex) { // loop over the primary air loops
    2059             : 
    2060     6137743 :         auto &AirToZoneNodeInfo(state.dataAirLoop->AirToZoneNodeInfo(AirLoopIndex));
    2061             : 
    2062    12302008 :         for (SupplyIndex = 1; SupplyIndex <= AirToZoneNodeInfo.NumSupplyNodes; ++SupplyIndex) {           // loop over the air loop supply outlets
    2063     6164265 :             if (AirToZoneNodeInfo.SupplyDuctType(SupplyIndex) == DataHVACGlobals::AirDuctType::Cooling) { // check for cooling duct
    2064             :                 // check if terminal units requesting more air than air loop can supply; if so, set terminal unit inlet
    2065             :                 // node mass flow max avail to what air loop can supply
    2066     5856059 :                 SupplyNode = AirToZoneNodeInfo.AirLoopSupplyNodeNum(SupplyIndex);
    2067     5856059 :                 if (state.dataLoopNodes->Node(SupplyNode).MassFlowRate > 0.0) {
    2068             :                     // must include bypass flow for ChangeoverBypass system so that terminal units are not restricted (e.g., MaxAvail is lowered)
    2069    14637171 :                     if ((state.dataLoopNodes->Node(SupplyNode).MassFlowRateSetPoint - state.dataLoopNodes->Node(SupplyNode).MassFlowRate -
    2070     9758114 :                          state.dataAirLoop->AirLoopFlow(AirLoopIndex).BypassMassFlow) > DataConvergParams::HVACFlowRateToler * 0.01) {
    2071      599179 :                         FlowRatio = state.dataLoopNodes->Node(SupplyNode).MassFlowRate / state.dataLoopNodes->Node(SupplyNode).MassFlowRateSetPoint;
    2072     1364704 :                         for (ZonesCooledIndex = 1; ZonesCooledIndex <= AirToZoneNodeInfo.NumZonesCooled; ++ZonesCooledIndex) {
    2073      765525 :                             TermInletNode = AirToZoneNodeInfo.TermUnitCoolInletNodes(ZonesCooledIndex);
    2074      765525 :                             state.dataLoopNodes->Node(TermInletNode).MassFlowRateMaxAvail =
    2075      765525 :                                 state.dataLoopNodes->Node(TermInletNode).MassFlowRate * FlowRatio;
    2076      765525 :                             state.dataLoopNodes->Node(TermInletNode).MassFlowRateMinAvail =
    2077      765525 :                                 min(state.dataLoopNodes->Node(TermInletNode).MassFlowRateMaxAvail,
    2078      765525 :                                     state.dataLoopNodes->Node(TermInletNode).MassFlowRateMinAvail);
    2079             :                         }
    2080             :                     }
    2081    14637171 :                     if ((state.dataLoopNodes->Node(SupplyNode).MassFlowRateSetPoint - state.dataLoopNodes->Node(SupplyNode).MassFlowRate -
    2082     9758114 :                          state.dataAirLoop->AirLoopFlow(AirLoopIndex).BypassMassFlow) < -DataConvergParams::HVACFlowRateToler * 0.01) {
    2083      219194 :                         if (state.dataLoopNodes->Node(SupplyNode).MassFlowRateSetPoint == 0.0) {
    2084             :                             //               CALL ShowFatalError('ResolveAirLoopFlowLimits: Node MassFlowRateSetPoint = 0.0, Node='//  &
    2085             :                             //                                   TRIM(state.dataLoopNodes->NodeID(SupplyNode))//  &
    2086             :                             //                                   ', check for Node Connection Errors in the following messages.')
    2087          36 :                             for (ZonesCooledIndex = 1; ZonesCooledIndex <= AirToZoneNodeInfo.NumZonesCooled; ++ZonesCooledIndex) {
    2088          18 :                                 TermInletNode = AirToZoneNodeInfo.TermUnitCoolInletNodes(ZonesCooledIndex);
    2089          18 :                                 state.dataLoopNodes->Node(TermInletNode).MassFlowRateMaxAvail =
    2090          18 :                                     state.dataLoopNodes->Node(TermInletNode).MassFlowRateMax;
    2091          18 :                                 state.dataLoopNodes->Node(TermInletNode).MassFlowRateMinAvail =
    2092          18 :                                     state.dataLoopNodes->Node(SupplyNode).MassFlowRate / double(AirToZoneNodeInfo.NumZonesCooled);
    2093             :                             }
    2094             :                         } else {
    2095      219176 :                             FlowRatio =
    2096      219176 :                                 state.dataLoopNodes->Node(SupplyNode).MassFlowRate / state.dataLoopNodes->Node(SupplyNode).MassFlowRateSetPoint;
    2097      453544 :                             for (ZonesCooledIndex = 1; ZonesCooledIndex <= AirToZoneNodeInfo.NumZonesCooled; ++ZonesCooledIndex) {
    2098      234368 :                                 TermInletNode = AirToZoneNodeInfo.TermUnitCoolInletNodes(ZonesCooledIndex);
    2099      234368 :                                 state.dataLoopNodes->Node(TermInletNode).MassFlowRateMinAvail =
    2100      234368 :                                     state.dataLoopNodes->Node(TermInletNode).MassFlowRate * FlowRatio;
    2101      234368 :                                 state.dataLoopNodes->Node(TermInletNode).MassFlowRateMaxAvail =
    2102      234368 :                                     max(state.dataLoopNodes->Node(TermInletNode).MassFlowRateMaxAvail,
    2103      234368 :                                         state.dataLoopNodes->Node(TermInletNode).MassFlowRateMinAvail);
    2104             :                             }
    2105             :                         }
    2106             :                     }
    2107             :                 }
    2108             :             }
    2109             :         }
    2110    12302008 :         for (SupplyIndex = 1; SupplyIndex <= AirToZoneNodeInfo.NumSupplyNodes; ++SupplyIndex) {           // loop over the air loop supply outlets
    2111     6164265 :             if (AirToZoneNodeInfo.SupplyDuctType(SupplyIndex) == DataHVACGlobals::AirDuctType::Heating) { // check for heating duct
    2112             :                 // check if terminal units requesting more air than air loop can supply; if so, set terminal unit inlet
    2113             :                 // node mass flow max avail to what air loop can supply
    2114       26522 :                 SupplyNode = AirToZoneNodeInfo.AirLoopSupplyNodeNum(SupplyIndex);
    2115       26522 :                 if (state.dataLoopNodes->Node(SupplyNode).MassFlowRate > 0.0) {
    2116             :                     // must include bypass flow for ChangeoverBypass system so that terminal units are not restricted (e.g., MaxAvail is lowered)
    2117       62016 :                     if ((state.dataLoopNodes->Node(SupplyNode).MassFlowRateSetPoint - state.dataLoopNodes->Node(SupplyNode).MassFlowRate -
    2118       41344 :                          state.dataAirLoop->AirLoopFlow(AirLoopIndex).BypassMassFlow) > DataConvergParams::HVACFlowRateToler * 0.01) {
    2119           0 :                         FlowRatio = state.dataLoopNodes->Node(SupplyNode).MassFlowRate / state.dataLoopNodes->Node(SupplyNode).MassFlowRateSetPoint;
    2120           0 :                         for (ZonesHeatedIndex = 1; ZonesHeatedIndex <= AirToZoneNodeInfo.NumZonesHeated; ++ZonesHeatedIndex) {
    2121           0 :                             TermInletNode = AirToZoneNodeInfo.TermUnitHeatInletNodes(ZonesHeatedIndex);
    2122           0 :                             state.dataLoopNodes->Node(TermInletNode).MassFlowRateMaxAvail =
    2123           0 :                                 state.dataLoopNodes->Node(TermInletNode).MassFlowRate * FlowRatio;
    2124           0 :                             state.dataLoopNodes->Node(TermInletNode).MassFlowRateMinAvail =
    2125           0 :                                 min(state.dataLoopNodes->Node(TermInletNode).MassFlowRateMaxAvail,
    2126           0 :                                     state.dataLoopNodes->Node(TermInletNode).MassFlowRateMinAvail);
    2127             :                         }
    2128             :                     }
    2129       62016 :                     if ((state.dataLoopNodes->Node(SupplyNode).MassFlowRateSetPoint - state.dataLoopNodes->Node(SupplyNode).MassFlowRate -
    2130       41344 :                          state.dataAirLoop->AirLoopFlow(AirLoopIndex).BypassMassFlow) < -DataConvergParams::HVACFlowRateToler * 0.01) {
    2131           2 :                         if (state.dataLoopNodes->Node(SupplyNode).MassFlowRateSetPoint == 0.0) {
    2132             :                             // ', check for Node Connection Errors in the following messages.')
    2133           0 :                             for (ZonesHeatedIndex = 1; ZonesHeatedIndex <= AirToZoneNodeInfo.NumZonesHeated; ++ZonesHeatedIndex) {
    2134           0 :                                 TermInletNode = AirToZoneNodeInfo.TermUnitHeatInletNodes(ZonesHeatedIndex);
    2135           0 :                                 state.dataLoopNodes->Node(TermInletNode).MassFlowRateMaxAvail =
    2136           0 :                                     state.dataLoopNodes->Node(TermInletNode).MassFlowRateMax;
    2137           0 :                                 state.dataLoopNodes->Node(TermInletNode).MassFlowRateMinAvail =
    2138           0 :                                     state.dataLoopNodes->Node(SupplyNode).MassFlowRate / double(AirToZoneNodeInfo.NumZonesCooled);
    2139             :                             }
    2140             :                         } else {
    2141           2 :                             FlowRatio =
    2142           2 :                                 state.dataLoopNodes->Node(SupplyNode).MassFlowRate / state.dataLoopNodes->Node(SupplyNode).MassFlowRateSetPoint;
    2143          14 :                             for (ZonesHeatedIndex = 1; ZonesHeatedIndex <= AirToZoneNodeInfo.NumZonesHeated; ++ZonesHeatedIndex) {
    2144          12 :                                 TermInletNode = AirToZoneNodeInfo.TermUnitHeatInletNodes(ZonesHeatedIndex);
    2145          12 :                                 state.dataLoopNodes->Node(TermInletNode).MassFlowRateMinAvail =
    2146          12 :                                     state.dataLoopNodes->Node(TermInletNode).MassFlowRate * FlowRatio;
    2147          12 :                                 state.dataLoopNodes->Node(TermInletNode).MassFlowRateMaxAvail =
    2148          12 :                                     max(state.dataLoopNodes->Node(TermInletNode).MassFlowRateMaxAvail,
    2149          12 :                                         state.dataLoopNodes->Node(TermInletNode).MassFlowRateMinAvail);
    2150             :                             }
    2151             :                         }
    2152             :                     }
    2153             :                 }
    2154             :             }
    2155             :         }
    2156             :     }
    2157     3255878 : }
    2158             : 
    2159     2984249 : void ResolveLockoutFlags(EnergyPlusData &state, bool &SimAir) // TRUE means air loops must be (re)simulated
    2160             : {
    2161             : 
    2162             :     // SUBROUTINE INFORMATION:
    2163             :     //       AUTHOR         Fred Buhl
    2164             :     //       DATE WRITTEN   December 2003
    2165             :     //       MODIFIED       na
    2166             :     //       RE-ENGINEERED  na
    2167             : 
    2168             :     // PURPOSE OF THIS SUBROUTINE:
    2169             :     // This subroutine checks for components lockout flags and asks for air loop resimulation
    2170             :     // if any components have been locked out
    2171             : 
    2172             :     // METHODOLOGY EMPLOYED:
    2173             :     // Checks if loop lockout flags are .TRUE.; if so, sets SimAirLoops to .TRUE.
    2174             : 
    2175     2984249 :     auto &AirLoopControlInfo(state.dataAirLoop->AirLoopControlInfo);
    2176             : 
    2177     8377596 :     for (int AirLoopIndex = 1; AirLoopIndex <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopIndex) { // loop over the primary air loops
    2178             :         // check if economizer ia active and if there is a request that it be locked out
    2179     6276956 :         if (AirLoopControlInfo(AirLoopIndex).EconoActive &&
    2180     1639884 :             (AirLoopControlInfo(AirLoopIndex).ReqstEconoLockoutWithCompressor || AirLoopControlInfo(AirLoopIndex).ReqstEconoLockoutWithHeating)) {
    2181       52367 :             AirLoopControlInfo(AirLoopIndex).EconoLockout = true;
    2182       52367 :             SimAir = true;
    2183             :         }
    2184             :     }
    2185     2984249 : }
    2186             : 
    2187     2638872 : void ResetHVACControl(EnergyPlusData &state)
    2188             : {
    2189             : 
    2190             :     // SUBROUTINE INFORMATION:
    2191             :     //       AUTHOR         Fred Buhl
    2192             :     //       DATE WRITTEN   December 2004
    2193             :     //       MODIFIED       na
    2194             :     //       RE-ENGINEERED  na
    2195             : 
    2196             :     // PURPOSE OF THIS SUBROUTINE:
    2197             :     // This subroutine resets loop control flags and specified flow rates that may
    2198             :     // have been set by the set point and availability managers in the previous
    2199             :     // time step
    2200             : 
    2201     2638872 :     if (state.dataHVACGlobal->NumPrimaryAirSys == 0) return;
    2202     6101943 :     for (auto &e : state.dataAirLoop->AirLoopControlInfo) {
    2203     4221179 :         e.NightVent = false;
    2204     4221179 :         e.LoopFlowRateSet = false;
    2205             :     }
    2206     6101943 :     for (auto &e : state.dataAirLoop->AirLoopFlow)
    2207     4221179 :         e.ReqSupplyFrac = 1.0;
    2208             : }
    2209             : 
    2210        1613 : void ResetNodeData(EnergyPlusData &state)
    2211             : {
    2212             : 
    2213             :     // SUBROUTINE INFORMATION:
    2214             :     //       AUTHOR         Linda Lawrie
    2215             :     //       DATE WRITTEN   March 2005
    2216             :     //       MODIFIED       na
    2217             :     //       RE-ENGINEERED  na
    2218             : 
    2219             :     // PURPOSE OF THIS SUBROUTINE:
    2220             :     // This routine resets all node data to "initial" conditions.
    2221             : 
    2222        1613 :     if (state.dataLoopNodes->NumOfNodes <= 0) return;
    2223             : 
    2224      125701 :     for (auto &e : state.dataLoopNodes->Node) {
    2225      124244 :         e.Temp = state.dataLoopNodes->DefaultNodeValues.Temp;
    2226      124244 :         e.TempMin = state.dataLoopNodes->DefaultNodeValues.TempMin;
    2227      124244 :         e.TempMax = state.dataLoopNodes->DefaultNodeValues.TempMax;
    2228      124244 :         e.TempSetPoint = state.dataLoopNodes->DefaultNodeValues.TempSetPoint;
    2229      124244 :         e.MassFlowRate = state.dataLoopNodes->DefaultNodeValues.MassFlowRate;
    2230      124244 :         e.MassFlowRateMin = state.dataLoopNodes->DefaultNodeValues.MassFlowRateMin;
    2231      124244 :         e.MassFlowRateMax = state.dataLoopNodes->DefaultNodeValues.MassFlowRateMax;
    2232      124244 :         e.MassFlowRateMinAvail = state.dataLoopNodes->DefaultNodeValues.MassFlowRateMinAvail;
    2233      124244 :         e.MassFlowRateMaxAvail = state.dataLoopNodes->DefaultNodeValues.MassFlowRateMaxAvail;
    2234      124244 :         e.MassFlowRateSetPoint = state.dataLoopNodes->DefaultNodeValues.MassFlowRateSetPoint;
    2235      124244 :         e.Quality = state.dataLoopNodes->DefaultNodeValues.Quality;
    2236      124244 :         e.Press = state.dataLoopNodes->DefaultNodeValues.Press;
    2237      124244 :         e.Enthalpy = state.dataLoopNodes->DefaultNodeValues.Enthalpy;
    2238      124244 :         e.HumRat = state.dataLoopNodes->DefaultNodeValues.HumRat;
    2239      124244 :         e.HumRatMin = state.dataLoopNodes->DefaultNodeValues.HumRatMin;
    2240      124244 :         e.HumRatMax = state.dataLoopNodes->DefaultNodeValues.HumRatMax;
    2241      124244 :         e.HumRatSetPoint = state.dataLoopNodes->DefaultNodeValues.HumRatSetPoint;
    2242      124244 :         e.TempSetPointHi = state.dataLoopNodes->DefaultNodeValues.TempSetPointHi;
    2243      124244 :         e.TempSetPointLo = state.dataLoopNodes->DefaultNodeValues.TempSetPointLo;
    2244             :     }
    2245             : 
    2246        1457 :     if (allocated(state.dataLoopNodes->MoreNodeInfo)) {
    2247      125701 :         for (auto &e : state.dataLoopNodes->MoreNodeInfo) {
    2248      124244 :             e.WetBulbTemp = state.dataLoopNodes->DefaultNodeValues.Temp;
    2249      124244 :             e.RelHumidity = 0.0;
    2250      124244 :             e.ReportEnthalpy = state.dataLoopNodes->DefaultNodeValues.Enthalpy;
    2251      124244 :             e.VolFlowRateStdRho = 0.0;
    2252      124244 :             e.VolFlowRateCrntRho = 0.0;
    2253      124244 :             e.Density = 0.0;
    2254             :         }
    2255             :     }
    2256             : }
    2257             : 
    2258     3318787 : void UpdateZoneListAndGroupLoads(EnergyPlusData &state)
    2259             : {
    2260             : 
    2261             :     // SUBROUTINE INFORMATION:
    2262             :     //       AUTHOR         Apparently someone who doesn't believe in documenting.
    2263             :     //       DATE WRITTEN   ???
    2264             :     //       MODIFIED       na
    2265             :     //       RE-ENGINEERED  na
    2266             : 
    2267             :     // Using/Aliasing
    2268             :     using namespace DataHeatBalance;
    2269             : 
    2270             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2271             :     int ZoneNum;
    2272             :     int ListNum;
    2273             :     int GroupNum;
    2274             :     int Mult;
    2275             : 
    2276     3318787 :     auto &ZoneList(state.dataHeatBal->ZoneList);
    2277     3318787 :     auto &ZoneGroup(state.dataHeatBal->ZoneGroup);
    2278     3318787 :     auto &ZoneListSNLoadHeatEnergy(state.dataHeatBal->ZoneListSNLoadHeatEnergy);
    2279     3318787 :     auto &ZoneListSNLoadCoolEnergy(state.dataHeatBal->ZoneListSNLoadCoolEnergy);
    2280     3318787 :     auto &ZoneListSNLoadHeatRate(state.dataHeatBal->ZoneListSNLoadHeatRate);
    2281     3318787 :     auto &ZoneListSNLoadCoolRate(state.dataHeatBal->ZoneListSNLoadCoolRate);
    2282             : 
    2283             :     // Sum ZONE LIST and ZONE GROUP report variables
    2284     3458626 :     for (ListNum = 1; ListNum <= state.dataHeatBal->NumOfZoneLists; ++ListNum) {
    2285      139839 :         ZoneListSNLoadHeatEnergy(ListNum) = 0.0;
    2286      139839 :         ZoneListSNLoadCoolEnergy(ListNum) = 0.0;
    2287      139839 :         ZoneListSNLoadHeatRate(ListNum) = 0.0;
    2288      139839 :         ZoneListSNLoadCoolRate(ListNum) = 0.0;
    2289             :     }
    2290             : 
    2291     3458626 :     for (ListNum = 1; ListNum <= state.dataHeatBal->NumOfZoneLists; ++ListNum) {
    2292      707485 :         for (ZoneNum = 1; ZoneNum <= ZoneList(ListNum).NumOfZones; ++ZoneNum) {
    2293      567646 :             Mult = state.dataHeatBal->Zone(ZoneNum).Multiplier;
    2294      567646 :             ZoneListSNLoadHeatEnergy(ListNum) +=
    2295      567646 :                 state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneList(ListNum).Zone(ZoneNum)).ZoneSNLoadHeatEnergy * Mult;
    2296      567646 :             ZoneListSNLoadCoolEnergy(ListNum) +=
    2297      567646 :                 state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneList(ListNum).Zone(ZoneNum)).ZoneSNLoadCoolEnergy * Mult;
    2298      567646 :             ZoneListSNLoadHeatRate(ListNum) +=
    2299      567646 :                 state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneList(ListNum).Zone(ZoneNum)).ZoneSNLoadHeatRate * Mult;
    2300      567646 :             ZoneListSNLoadCoolRate(ListNum) +=
    2301      567646 :                 state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneList(ListNum).Zone(ZoneNum)).ZoneSNLoadCoolRate * Mult;
    2302             :         } // ZoneNum
    2303             :     }     // ListNum
    2304             : 
    2305     3346117 :     for (GroupNum = 1; GroupNum <= state.dataHeatBal->NumOfZoneGroups; ++GroupNum) {
    2306       27330 :         Mult = state.dataHeatBal->ZoneGroup(GroupNum).Multiplier;
    2307       27330 :         state.dataHeatBal->ZoneGroupSNLoadHeatEnergy(GroupNum) = ZoneListSNLoadHeatEnergy(ZoneGroup(GroupNum).ZoneList) * Mult;
    2308       27330 :         state.dataHeatBal->ZoneGroupSNLoadCoolEnergy(GroupNum) = ZoneListSNLoadCoolEnergy(ZoneGroup(GroupNum).ZoneList) * Mult;
    2309       27330 :         state.dataHeatBal->ZoneGroupSNLoadHeatRate(GroupNum) = ZoneListSNLoadHeatRate(ZoneGroup(GroupNum).ZoneList) * Mult;
    2310       27330 :         state.dataHeatBal->ZoneGroupSNLoadCoolRate(GroupNum) = ZoneListSNLoadCoolRate(ZoneGroup(GroupNum).ZoneList) * Mult;
    2311             :     } // GroupNum
    2312     3318787 : }
    2313             : 
    2314      389283 : void ReportInfiltrations(EnergyPlusData &state)
    2315             : {
    2316             :     // SUBROUTINE INFORMATION:
    2317             :     //       AUTHOR         Yueyue Zhou
    2318             :     //       DATE WRITTEN   July 2021
    2319             : 
    2320             :     // PURPOSE OF THIS SUBROUTINE:
    2321             :     // This subroutine currently creates the values for standard Infiltration object level reporting
    2322             : 
    2323             :     // METHODOLOGY EMPLOYED:
    2324             : 
    2325             :     // REFERENCES:
    2326             : 
    2327             :     using DataHVACGlobals::CycleOn;
    2328             :     using DataHVACGlobals::CycleOnZoneFansOnly;
    2329             :     using Psychrometrics::PsyCpAirFnW;
    2330             :     using Psychrometrics::PsyHgAirFnWTdb;
    2331             :     using Psychrometrics::PsyRhoAirFnPbTdbW;
    2332             :     // SUBROUTINE PARAMETER DEFINITIONS:
    2333      389283 :     static std::string const RoutineName("ReportInfiltrations");
    2334             : 
    2335             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2336             :     Real64 AirDensity;          // Density of air (kg/m^3)
    2337             :     Real64 CpAir;               // Heat capacity of air (J/kg-C)
    2338             :     Real64 TotalLoad;           // Total loss or gain
    2339             :     Real64 H2OHtOfVap;          // Heat of vaporization of air
    2340             :     Real64 ADSCorrectionFactor; // Correction factor of air flow model values when ADS is simulated
    2341      389283 :     Real64 TimeStepSys = state.dataHVACGlobal->TimeStepSys;
    2342             : 
    2343     2317345 :     for (auto &thisInfiltration : state.dataHeatBal->Infiltration) {
    2344             : 
    2345     1928062 :         int NZ = thisInfiltration.ZonePtr;
    2346     1928062 :         auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(NZ);
    2347     1928062 :         auto &thisZone = state.dataHeatBal->Zone(NZ);
    2348     1928062 :         ADSCorrectionFactor = 1.0;
    2349     1928062 :         if (state.afn->simulation_control.type == AirflowNetwork::ControlType::MultizoneWithDistributionOnlyDuringFanOperation) {
    2350             :             // CR7608 IF (TurnFansOn .AND. AirflowNetworkZoneFlag(NZ)) ADSCorrectionFactor=0
    2351        3830 :             if ((state.dataZoneEquip->ZoneEquipAvail(NZ) == CycleOn || state.dataZoneEquip->ZoneEquipAvail(NZ) == CycleOnZoneFansOnly) &&
    2352        1134 :                 state.afn->AirflowNetworkZoneFlag(NZ))
    2353        1134 :                 ADSCorrectionFactor = 0.0;
    2354             :         }
    2355             : 
    2356     1928062 :         CpAir = PsyCpAirFnW(state.dataEnvrn->OutHumRat);
    2357     1928062 :         thisInfiltration.InfilMdot = thisInfiltration.MCpI_temp / CpAir * ADSCorrectionFactor;
    2358     1928062 :         thisInfiltration.InfilMass = thisInfiltration.InfilMdot * TimeStepSys * DataGlobalConstants::SecInHour;
    2359             : 
    2360     1928062 :         if (thisZoneHB.MAT > thisZone.OutDryBulbTemp) {
    2361             : 
    2362     2775916 :             thisInfiltration.InfilHeatLoss = thisInfiltration.MCpI_temp * (thisZoneHB.MAT - thisZone.OutDryBulbTemp) * TimeStepSys *
    2363     1387958 :                                              DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2364     1387958 :             thisInfiltration.InfilHeatGain = 0.0;
    2365             : 
    2366      540104 :         } else if (thisZoneHB.MAT <= thisZone.OutDryBulbTemp) {
    2367             : 
    2368     1080208 :             thisInfiltration.InfilHeatGain = thisInfiltration.MCpI_temp * (thisZone.OutDryBulbTemp - thisZoneHB.MAT) * TimeStepSys *
    2369      540104 :                                              DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2370      540104 :             thisInfiltration.InfilHeatLoss = 0.0;
    2371             :         }
    2372             : 
    2373             :         // Report infiltration latent gains and losses
    2374     1928062 :         H2OHtOfVap = PsyHgAirFnWTdb(thisZoneHB.ZoneAirHumRat, thisZoneHB.MAT);
    2375     1928062 :         if (thisZoneHB.ZoneAirHumRat > state.dataEnvrn->OutHumRat) {
    2376             : 
    2377     2005234 :             thisInfiltration.InfilLatentLoss = thisInfiltration.InfilMdot * (thisZoneHB.ZoneAirHumRat - state.dataEnvrn->OutHumRat) * H2OHtOfVap *
    2378     1002617 :                                                TimeStepSys * DataGlobalConstants::SecInHour;
    2379     1002617 :             thisInfiltration.InfilLatentGain = 0.0;
    2380             : 
    2381      925445 :         } else if (thisZoneHB.ZoneAirHumRat <= state.dataEnvrn->OutHumRat) {
    2382             : 
    2383     1850890 :             thisInfiltration.InfilLatentGain = thisInfiltration.InfilMdot * (state.dataEnvrn->OutHumRat - thisZoneHB.ZoneAirHumRat) * H2OHtOfVap *
    2384      925445 :                                                TimeStepSys * DataGlobalConstants::SecInHour;
    2385      925445 :             thisInfiltration.InfilLatentLoss = 0.0;
    2386             :         }
    2387             :         // Total infiltration losses and gains
    2388     1928062 :         TotalLoad =
    2389     1928062 :             thisInfiltration.InfilHeatGain + thisInfiltration.InfilLatentGain - thisInfiltration.InfilHeatLoss - thisInfiltration.InfilLatentLoss;
    2390     1928062 :         if (TotalLoad > 0) {
    2391      490950 :             thisInfiltration.InfilTotalGain = TotalLoad;
    2392      490950 :             thisInfiltration.InfilTotalLoss = 0.0;
    2393             :         } else {
    2394     1437112 :             thisInfiltration.InfilTotalGain = 0.0;
    2395     1437112 :             thisInfiltration.InfilTotalLoss = -TotalLoad;
    2396             :         }
    2397             :         // CR7751  second, calculate using indoor conditions for density property
    2398     1928062 :         AirDensity = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, thisZoneHB.MAT, thisZoneHB.ZoneAirHumRatAvg, RoutineName);
    2399     1928062 :         thisInfiltration.InfilVdotCurDensity = thisInfiltration.InfilMdot / AirDensity;
    2400     1928062 :         thisInfiltration.InfilVolumeCurDensity = thisInfiltration.InfilVdotCurDensity * TimeStepSys * DataGlobalConstants::SecInHour;
    2401     1928062 :         thisInfiltration.InfilAirChangeRate = thisInfiltration.InfilVolumeCurDensity / (TimeStepSys * thisZone.Volume);
    2402             : 
    2403             :         // CR7751 third, calculate using standard dry air at nominal elevation
    2404     1928062 :         AirDensity = state.dataEnvrn->StdRhoAir;
    2405     1928062 :         thisInfiltration.InfilVdotStdDensity = thisInfiltration.InfilMdot / AirDensity;
    2406     1928062 :         thisInfiltration.InfilVolumeStdDensity = thisInfiltration.InfilVdotStdDensity * TimeStepSys * DataGlobalConstants::SecInHour;
    2407             :     }
    2408      389283 : }
    2409             : 
    2410      401522 : void ReportAirHeatBalance(EnergyPlusData &state)
    2411             : {
    2412             : 
    2413             :     // SUBROUTINE INFORMATION:
    2414             :     //       AUTHOR         Linda Lawrie
    2415             :     //       DATE WRITTEN   July 2000
    2416             :     //       MODIFIED       Shirey, Jan 2008 (MIXING/CROSS MIXING outputs)
    2417             : 
    2418             :     // PURPOSE OF THIS SUBROUTINE:
    2419             :     // This subroutine updates the report variables for the AirHeatBalance.
    2420             : 
    2421             :     // Using/Aliasing
    2422             :     using DataHVACGlobals::CycleOn;
    2423             :     using DataHVACGlobals::CycleOnZoneFansOnly;
    2424             :     using DataHVACGlobals::FanType_ZoneExhaust;
    2425             :     using Psychrometrics::PsyCpAirFnW;
    2426             :     using Psychrometrics::PsyHgAirFnWTdb;
    2427             :     using Psychrometrics::PsyRhoAirFnPbTdbW;
    2428             : 
    2429             :     static constexpr std::string_view RoutineName3("ReportAirHeatBalance:3");
    2430             : 
    2431             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2432             :     Real64 AirDensity;                                // Density of air (kg/m^3)
    2433             :     Real64 CpAir;                                     // Heat capacity of air (J/kg-C)
    2434             :     Real64 ADSCorrectionFactor;                       // Correction factor of air flow model values when ADS is simulated
    2435             :     Real64 H2OHtOfVap;                                // Heat of vaporization of air
    2436             :     Real64 TotalLoad;                                 // Total loss or gain
    2437      401522 :     auto &MixSenLoad = state.dataHVACMgr->MixSenLoad; // Mixing sensible loss or gain
    2438      401522 :     auto &MixLatLoad = state.dataHVACMgr->MixLatLoad; // Mixing latent loss or gain
    2439             : 
    2440      401522 :     state.dataHeatBal->ZoneTotalExfiltrationHeatLoss = 0.0;
    2441      401522 :     state.dataHeatBal->ZoneTotalExhaustHeatLoss = 0.0;
    2442             : 
    2443      401522 :     auto &Zone(state.dataHeatBal->Zone);
    2444      401522 :     auto &ZnAirRpt(state.dataHeatBal->ZnAirRpt);
    2445      401522 :     auto &Ventilation(state.dataHeatBal->Ventilation);
    2446      401522 :     auto &Mixing(state.dataHeatBal->Mixing);
    2447      401522 :     auto &CrossMixing(state.dataHeatBal->CrossMixing);
    2448      401522 :     auto &RefDoorMixing(state.dataHeatBal->RefDoorMixing);
    2449      401522 :     auto &ZoneEquipConfig(state.dataZoneEquip->ZoneEquipConfig);
    2450      401522 :     auto &Fan(state.dataFans->Fan);
    2451      401522 :     auto &TimeStepSys(state.dataHVACGlobal->TimeStepSys);
    2452             : 
    2453      401522 :     if (state.afn->simulation_control.type != AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
    2454       13012 :         state.afn->report();
    2455             :     }
    2456             : 
    2457             :     // Reports zone exhaust loss by exhaust fans
    2458     3038160 :     for (int ZoneLoop = 1; ZoneLoop <= state.dataGlobal->NumOfZones; ++ZoneLoop) { // Start of zone loads report variable update loop ...
    2459     2636638 :         CpAir = PsyCpAirFnW(state.dataEnvrn->OutHumRat);
    2460     2636638 :         H2OHtOfVap = PsyHgAirFnWTdb(state.dataEnvrn->OutHumRat, Zone(ZoneLoop).OutDryBulbTemp);
    2461     2636638 :         ADSCorrectionFactor = 1.0;
    2462     2636638 :         if (state.afn->simulation_control.type == AirflowNetwork::ControlType::MultizoneWithDistributionOnlyDuringFanOperation) {
    2463        3830 :             if ((state.dataZoneEquip->ZoneEquipAvail(ZoneLoop) == CycleOn || state.dataZoneEquip->ZoneEquipAvail(ZoneLoop) == CycleOnZoneFansOnly) &&
    2464        1134 :                 state.afn->AirflowNetworkZoneFlag(ZoneLoop)) {
    2465        1134 :                 ADSCorrectionFactor = 0.0;
    2466             :             }
    2467             :         }
    2468             : 
    2469     2636638 :         ZnAirRpt(ZoneLoop).ExhTotalLoss = 0;
    2470     2636638 :         ZnAirRpt(ZoneLoop).ExhSensiLoss = 0;
    2471             : 
    2472    23390912 :         for (int FanNum = 1; FanNum <= state.dataFans->NumFans; ++FanNum) {
    2473             :             //  Add reportable vars
    2474    20754274 :             if (Fan(FanNum).FanType_Num == FanType_ZoneExhaust) {
    2475     3835011 :                 for (int ExhNum = 1; ExhNum <= ZoneEquipConfig(ZoneLoop).NumExhaustNodes; ExhNum++) {
    2476      453572 :                     if (Fan(FanNum).InletNodeNum == ZoneEquipConfig(ZoneLoop).ExhaustNode(ExhNum)) {
    2477       53959 :                         ZnAirRpt(ZoneLoop).ExhTotalLoss +=
    2478       53959 :                             Fan(FanNum).OutletAirMassFlowRate * (Fan(FanNum).OutletAirEnthalpy - state.dataEnvrn->OutEnthalpy) * ADSCorrectionFactor;
    2479      161877 :                         ZnAirRpt(ZoneLoop).ExhSensiLoss += Fan(FanNum).OutletAirMassFlowRate * CpAir *
    2480      107918 :                                                            (Fan(FanNum).OutletAirTemp - Zone(ZoneLoop).OutDryBulbTemp) * ADSCorrectionFactor;
    2481       53959 :                         break;
    2482             :                     }
    2483             :                 }
    2484             :             }
    2485             :         }
    2486             : 
    2487     2636638 :         ZnAirRpt(ZoneLoop).ExhLatentLoss = ZnAirRpt(ZoneLoop).ExhTotalLoss - ZnAirRpt(ZoneLoop).ExhSensiLoss;
    2488             :     }
    2489             : 
    2490             :     // Report results for SIMPLE option only
    2491      414534 :     if (!(state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution ||
    2492       13012 :           state.afn->simulation_control.type == AirflowNetwork::ControlType::MultizoneWithDistributionOnlyDuringFanOperation)) {
    2493       12239 :         return;
    2494             :     }
    2495             : 
    2496      389283 :     if (state.dataHVACMgr->ReportAirHeatBalanceFirstTimeFlag) {
    2497         737 :         MixSenLoad.allocate(state.dataGlobal->NumOfZones);
    2498         737 :         MixLatLoad.allocate(state.dataGlobal->NumOfZones);
    2499         737 :         state.dataHVACMgr->ReportAirHeatBalanceFirstTimeFlag = false;
    2500             :     }
    2501             : 
    2502      389283 :     ReportInfiltrations(state);
    2503             : 
    2504     2985033 :     for (int ZoneLoop = 1; ZoneLoop <= state.dataGlobal->NumOfZones; ++ZoneLoop) { // Start of zone loads report variable update loop ...
    2505     2595750 :         auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneLoop);
    2506             : 
    2507             :         // Break the infiltration load into heat gain and loss components
    2508     2595750 :         ADSCorrectionFactor = 1.0;
    2509             : 
    2510     2595750 :         if (state.afn->simulation_control.type == AirflowNetwork::ControlType::MultizoneWithDistributionOnlyDuringFanOperation) {
    2511             :             // CR7608 IF (TurnFansOn .AND. AirflowNetworkZoneFlag(ZoneLoop)) ADSCorrectionFactor=0
    2512        3830 :             if ((state.dataZoneEquip->ZoneEquipAvail(ZoneLoop) == CycleOn || state.dataZoneEquip->ZoneEquipAvail(ZoneLoop) == CycleOnZoneFansOnly) &&
    2513        1134 :                 state.afn->AirflowNetworkZoneFlag(ZoneLoop))
    2514        1134 :                 ADSCorrectionFactor = 0.0;
    2515             :         }
    2516             : 
    2517     2595750 :         if (thisZoneHB.MAT > Zone(ZoneLoop).OutDryBulbTemp) {
    2518             : 
    2519     3733436 :             ZnAirRpt(ZoneLoop).InfilHeatLoss = thisZoneHB.MCPI * (thisZoneHB.MAT - Zone(ZoneLoop).OutDryBulbTemp) * TimeStepSys *
    2520     1866718 :                                                DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2521     1866718 :             ZnAirRpt(ZoneLoop).InfilHeatGain = 0.0;
    2522             : 
    2523      729032 :         } else if (thisZoneHB.MAT <= Zone(ZoneLoop).OutDryBulbTemp) {
    2524             : 
    2525     1458064 :             ZnAirRpt(ZoneLoop).InfilHeatGain = thisZoneHB.MCPI * (Zone(ZoneLoop).OutDryBulbTemp - thisZoneHB.MAT) * TimeStepSys *
    2526      729032 :                                                DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2527      729032 :             ZnAirRpt(ZoneLoop).InfilHeatLoss = 0.0;
    2528             :         }
    2529             :         // Report infiltration latent gains and losses
    2530     2595750 :         CpAir = PsyCpAirFnW(state.dataEnvrn->OutHumRat);
    2531     2595750 :         H2OHtOfVap = PsyHgAirFnWTdb(thisZoneHB.ZoneAirHumRat, thisZoneHB.MAT);
    2532     2595750 :         if (thisZoneHB.ZoneAirHumRat > state.dataEnvrn->OutHumRat) {
    2533             : 
    2534     3918351 :             ZnAirRpt(ZoneLoop).InfilLatentLoss = thisZoneHB.MCPI / CpAir * (thisZoneHB.ZoneAirHumRat - state.dataEnvrn->OutHumRat) * H2OHtOfVap *
    2535     2612234 :                                                  TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2536     1306117 :             ZnAirRpt(ZoneLoop).InfilLatentGain = 0.0;
    2537             : 
    2538     1289633 :         } else if (thisZoneHB.ZoneAirHumRat <= state.dataEnvrn->OutHumRat) {
    2539             : 
    2540     3868899 :             ZnAirRpt(ZoneLoop).InfilLatentGain = thisZoneHB.MCPI / CpAir * (state.dataEnvrn->OutHumRat - thisZoneHB.ZoneAirHumRat) * H2OHtOfVap *
    2541     2579266 :                                                  TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2542     1289633 :             ZnAirRpt(ZoneLoop).InfilLatentLoss = 0.0;
    2543             :         }
    2544             :         // Total infiltration losses and gains
    2545     5191500 :         TotalLoad = ZnAirRpt(ZoneLoop).InfilHeatGain + ZnAirRpt(ZoneLoop).InfilLatentGain - ZnAirRpt(ZoneLoop).InfilHeatLoss -
    2546     2595750 :                     ZnAirRpt(ZoneLoop).InfilLatentLoss;
    2547     2595750 :         if (TotalLoad > 0) {
    2548      490419 :             ZnAirRpt(ZoneLoop).InfilTotalGain = TotalLoad * ADSCorrectionFactor;
    2549      490419 :             ZnAirRpt(ZoneLoop).InfilTotalLoss = 0.0;
    2550             :         } else {
    2551     2105331 :             ZnAirRpt(ZoneLoop).InfilTotalGain = 0.0;
    2552     2105331 :             ZnAirRpt(ZoneLoop).InfilTotalLoss = -TotalLoad * ADSCorrectionFactor;
    2553             :         }
    2554             : 
    2555             :         // first calculate mass flows using outside air heat capacity for consistency with input to heat balance
    2556     2595750 :         ZnAirRpt(ZoneLoop).InfilMdot = (thisZoneHB.MCPI / CpAir) * ADSCorrectionFactor;
    2557     2595750 :         ZnAirRpt(ZoneLoop).InfilMass = ZnAirRpt(ZoneLoop).InfilMdot * TimeStepSys * DataGlobalConstants::SecInHour;
    2558     2595750 :         ZnAirRpt(ZoneLoop).VentilMdot = (thisZoneHB.MCPV / CpAir) * ADSCorrectionFactor;
    2559     2595750 :         ZnAirRpt(ZoneLoop).VentilMass = ZnAirRpt(ZoneLoop).VentilMdot * TimeStepSys * DataGlobalConstants::SecInHour;
    2560             : 
    2561             :         // CR7751  second, calculate using indoor conditions for density property
    2562     2595750 :         AirDensity = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, thisZoneHB.MAT, thisZoneHB.ZoneAirHumRatAvg, RoutineName3);
    2563     2595750 :         ZnAirRpt(ZoneLoop).InfilVdotCurDensity = ZnAirRpt(ZoneLoop).InfilMdot / AirDensity;
    2564     2595750 :         ZnAirRpt(ZoneLoop).InfilVolumeCurDensity = ZnAirRpt(ZoneLoop).InfilVdotCurDensity * TimeStepSys * DataGlobalConstants::SecInHour;
    2565     2595750 :         ZnAirRpt(ZoneLoop).InfilAirChangeRate = ZnAirRpt(ZoneLoop).InfilVolumeCurDensity / (TimeStepSys * Zone(ZoneLoop).Volume);
    2566     2595750 :         ZnAirRpt(ZoneLoop).VentilVdotCurDensity = ZnAirRpt(ZoneLoop).VentilMdot / AirDensity;
    2567     2595750 :         ZnAirRpt(ZoneLoop).VentilVolumeCurDensity = ZnAirRpt(ZoneLoop).VentilVdotCurDensity * TimeStepSys * DataGlobalConstants::SecInHour;
    2568     2595750 :         ZnAirRpt(ZoneLoop).VentilAirChangeRate = ZnAirRpt(ZoneLoop).VentilVolumeCurDensity / (TimeStepSys * Zone(ZoneLoop).Volume);
    2569             : 
    2570             :         // CR7751 third, calculate using standard dry air at nominal elevation
    2571     2595750 :         AirDensity = state.dataEnvrn->StdRhoAir;
    2572     2595750 :         ZnAirRpt(ZoneLoop).InfilVdotStdDensity = ZnAirRpt(ZoneLoop).InfilMdot / AirDensity;
    2573     2595750 :         ZnAirRpt(ZoneLoop).InfilVolumeStdDensity = ZnAirRpt(ZoneLoop).InfilVdotStdDensity * TimeStepSys * DataGlobalConstants::SecInHour;
    2574     2595750 :         ZnAirRpt(ZoneLoop).VentilVdotStdDensity = ZnAirRpt(ZoneLoop).VentilMdot / AirDensity;
    2575     2595750 :         ZnAirRpt(ZoneLoop).VentilVolumeStdDensity = ZnAirRpt(ZoneLoop).VentilVdotStdDensity * TimeStepSys * DataGlobalConstants::SecInHour;
    2576             : 
    2577             :         //    ZnAirRpt(ZoneLoop)%VentilFanElec = 0.0
    2578     2595750 :         ZnAirRpt(ZoneLoop).VentilAirTemp = 0.0;
    2579     2595750 :         ZnAirRpt(ZoneLoop).VentilHeatLoss = 0.0;
    2580     2595750 :         ZnAirRpt(ZoneLoop).VentilHeatGain = 0.0;
    2581     2595750 :         int VentZoneNum = 0;           // Number of ventilation object per zone
    2582     2595750 :         Real64 VentZoneMassflow = 0.0; // Total mass flow rate per zone
    2583     2595750 :         Real64 VentZoneAirTemp = 0.0;  // Average Zone inlet temperature
    2584             : 
    2585     4454299 :         for (int VentNum = 1; VentNum <= state.dataHeatBal->TotVentilation; ++VentNum) {
    2586     1858549 :             if (Ventilation(VentNum).ZonePtr == ZoneLoop) {
    2587             :                 // moved into CalcAirFlowSimple
    2588             :                 //        ZnAirRpt(ZoneLoop)%VentilFanElec  =
    2589             :                 //        ZnAirRpt(ZoneLoop)%VentilFanElec+Ventilation(VentNum)%FanPower*TimeStepSys*DataGlobalConstants::SecInHour()
    2590             :                 //        &
    2591             :                 //          *ADSCorrectionFactor
    2592       43801 :                 if (ADSCorrectionFactor > 0) {
    2593       42667 :                     ZnAirRpt(ZoneLoop).VentilAirTemp += Ventilation(VentNum).AirTemp * Ventilation(VentNum).MCP;
    2594       42667 :                     VentZoneMassflow += Ventilation(VentNum).MCP;
    2595       42667 :                     VentZoneAirTemp += Ventilation(VentNum).AirTemp;
    2596             :                 } else {
    2597        1134 :                     ZnAirRpt(ZoneLoop).VentilAirTemp = Zone(ZoneLoop).OutDryBulbTemp;
    2598             :                 }
    2599             :                 // Break the ventilation load into heat gain and loss components
    2600       43801 :                 if (thisZoneHB.MAT > Ventilation(VentNum).AirTemp) {
    2601       67830 :                     ZnAirRpt(ZoneLoop).VentilHeatLoss += Ventilation(VentNum).MCP * (thisZoneHB.MAT - Ventilation(VentNum).AirTemp) * TimeStepSys *
    2602       33915 :                                                          DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2603        9886 :                 } else if (thisZoneHB.MAT <= Ventilation(VentNum).AirTemp) {
    2604       19772 :                     ZnAirRpt(ZoneLoop).VentilHeatGain += Ventilation(VentNum).MCP * (Ventilation(VentNum).AirTemp - thisZoneHB.MAT) * TimeStepSys *
    2605        9886 :                                                          DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2606             :                 }
    2607             : 
    2608       43801 :                 ++VentZoneNum;
    2609       43801 :                 if (VentZoneNum > 1) continue;
    2610             : 
    2611             :                 // Report ventilation latent gains and losses
    2612       42832 :                 H2OHtOfVap = PsyHgAirFnWTdb(thisZoneHB.ZoneAirHumRat, thisZoneHB.MAT);
    2613       42832 :                 if (thisZoneHB.ZoneAirHumRat > state.dataEnvrn->OutHumRat) {
    2614       66936 :                     ZnAirRpt(ZoneLoop).VentilLatentLoss = ZnAirRpt(ZoneLoop).VentilMdot * (thisZoneHB.ZoneAirHumRat - state.dataEnvrn->OutHumRat) *
    2615       33468 :                                                           H2OHtOfVap * TimeStepSys * DataGlobalConstants::SecInHour;
    2616       33468 :                     ZnAirRpt(ZoneLoop).VentilLatentGain = 0.0;
    2617        9364 :                 } else if (thisZoneHB.ZoneAirHumRat <= state.dataEnvrn->OutHumRat) {
    2618       18728 :                     ZnAirRpt(ZoneLoop).VentilLatentGain = ZnAirRpt(ZoneLoop).VentilMdot * (state.dataEnvrn->OutHumRat - thisZoneHB.ZoneAirHumRat) *
    2619        9364 :                                                           H2OHtOfVap * TimeStepSys * DataGlobalConstants::SecInHour;
    2620        9364 :                     ZnAirRpt(ZoneLoop).VentilLatentLoss = 0.0;
    2621             :                 }
    2622             :                 // Total ventilation losses and gains
    2623       85664 :                 TotalLoad = ZnAirRpt(ZoneLoop).VentilHeatGain + ZnAirRpt(ZoneLoop).VentilLatentGain - ZnAirRpt(ZoneLoop).VentilHeatLoss -
    2624       42832 :                             ZnAirRpt(ZoneLoop).VentilLatentLoss;
    2625       42832 :                 if (TotalLoad > 0) {
    2626        1011 :                     ZnAirRpt(ZoneLoop).VentilTotalGain = TotalLoad * ADSCorrectionFactor;
    2627        1011 :                     ZnAirRpt(ZoneLoop).VentilTotalLoss = 0.0;
    2628             :                 } else {
    2629       41821 :                     ZnAirRpt(ZoneLoop).VentilTotalGain = 0.0;
    2630       41821 :                     ZnAirRpt(ZoneLoop).VentilTotalLoss = -TotalLoad * ADSCorrectionFactor;
    2631             :                 }
    2632             :             }
    2633             :         }
    2634             : 
    2635     2595750 :         if (ADSCorrectionFactor > 0 && VentZoneNum > 1 && VentZoneMassflow > 0.0) {
    2636         357 :             ZnAirRpt(ZoneLoop).VentilAirTemp /= VentZoneMassflow;
    2637     2595393 :         } else if (ADSCorrectionFactor > 0 && VentZoneNum == 1) {
    2638       40729 :             ZnAirRpt(ZoneLoop).VentilAirTemp = VentZoneAirTemp;
    2639             :         } else { // Just in case
    2640     2554664 :             ZnAirRpt(ZoneLoop).VentilAirTemp = Zone(ZoneLoop).OutDryBulbTemp;
    2641             :         }
    2642             : 
    2643             :         // Report mixing sensible and latent loads
    2644     2595750 :         MixSenLoad(ZoneLoop) = 0.0; // Initialize arrays to zero before starting to sum
    2645     2595750 :         MixLatLoad(ZoneLoop) = 0.0;
    2646     2595750 :         ZnAirRpt(ZoneLoop).MixVolume = 0.0;         // zero reported volume prior to summations below
    2647     2595750 :         ZnAirRpt(ZoneLoop).MixVdotCurDensity = 0.0; // zero reported volume flow rate prior to summations below
    2648     2595750 :         ZnAirRpt(ZoneLoop).MixVdotStdDensity = 0.0; // zero reported volume flow rate prior to summations below
    2649     2595750 :         ZnAirRpt(ZoneLoop).MixMass = 0.0;           // ! zero reported mass prior to summations below
    2650     2595750 :         ZnAirRpt(ZoneLoop).MixMdot = 0.0;           // ! zero reported mass flow rate prior to summations below
    2651             :         //    MixingLoad = 0.0d0
    2652             : 
    2653     4610682 :         for (int MixNum = 1; MixNum <= state.dataHeatBal->TotMixing; ++MixNum) {
    2654     2014932 :             if ((Mixing(MixNum).ZonePtr == ZoneLoop) && Mixing(MixNum).ReportFlag) {
    2655       27047 :                 auto &fromZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(Mixing(MixNum).FromZone);
    2656             :                 //        MixSenLoad(ZoneLoop) = MixSenLoad(ZoneLoop)+MCPM(ZoneLoop)*MAT(Mixing(MixNum)%FromZone)
    2657             :                 //        H2OHtOfVap = PsyHgAirFnWTdb(ZoneAirHumRat(ZoneLoop), MAT(ZoneLoop))
    2658             :                 //        Per Jan 17, 2008 conference call, agreed to use average conditions for Rho, Cp and Hfg
    2659             :                 //           and to recalculate the report variable using end of time step temps and humrats
    2660      108188 :                 AirDensity = PsyRhoAirFnPbTdbW(state,
    2661       27047 :                                                state.dataEnvrn->OutBaroPress,
    2662       27047 :                                                (thisZoneHB.MAT + fromZoneHB.MAT) / 2.0,
    2663       27047 :                                                (thisZoneHB.ZoneAirHumRat + fromZoneHB.ZoneAirHumRat) / 2.0,
    2664       54094 :                                                std::string());
    2665       27047 :                 CpAir = PsyCpAirFnW((thisZoneHB.ZoneAirHumRat + fromZoneHB.ZoneAirHumRat) / 2.0);
    2666       27047 :                 ZnAirRpt(ZoneLoop).MixVolume +=
    2667       27047 :                     Mixing(MixNum).DesiredAirFlowRate * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2668       27047 :                 ZnAirRpt(ZoneLoop).MixVdotCurDensity += Mixing(MixNum).DesiredAirFlowRate * ADSCorrectionFactor;
    2669       27047 :                 ZnAirRpt(ZoneLoop).MixMass +=
    2670       27047 :                     Mixing(MixNum).DesiredAirFlowRate * AirDensity * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2671       27047 :                 ZnAirRpt(ZoneLoop).MixMdot += Mixing(MixNum).DesiredAirFlowRate * AirDensity * ADSCorrectionFactor;
    2672       27047 :                 ZnAirRpt(ZoneLoop).MixVdotStdDensity +=
    2673       27047 :                     Mixing(MixNum).DesiredAirFlowRate * (AirDensity / state.dataEnvrn->StdRhoAir) * ADSCorrectionFactor;
    2674       27047 :                 MixSenLoad(ZoneLoop) += Mixing(MixNum).DesiredAirFlowRate * AirDensity * CpAir * (thisZoneHB.MAT - fromZoneHB.MAT);
    2675       27047 :                 H2OHtOfVap = PsyHgAirFnWTdb((thisZoneHB.ZoneAirHumRat + fromZoneHB.ZoneAirHumRat) / 2.0, (thisZoneHB.MAT + fromZoneHB.MAT) / 2.0);
    2676             :                 //        MixLatLoad(ZoneLoop) = MixLatLoad(ZoneLoop)+MixingMassFlowZone(ZoneLoop)*(ZoneAirHumRat(ZoneLoop)- &
    2677             :                 //                     ZoneAirHumRat(Mixing(MixNum)%FromZone))*H2OHtOfVap
    2678       27047 :                 MixLatLoad(ZoneLoop) +=
    2679       27047 :                     Mixing(MixNum).DesiredAirFlowRate * AirDensity * (thisZoneHB.ZoneAirHumRat - fromZoneHB.ZoneAirHumRat) * H2OHtOfVap;
    2680             :             }
    2681             :         }
    2682             : 
    2683     2624602 :         for (int MixNum = 1; MixNum <= state.dataHeatBal->TotCrossMixing; ++MixNum) {
    2684       28852 :             if ((CrossMixing(MixNum).ZonePtr == ZoneLoop) && CrossMixing(MixNum).ReportFlag) {
    2685        4099 :                 auto &fromZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(CrossMixing(MixNum).FromZone);
    2686             :                 //        MixSenLoad(ZoneLoop) = MixSenLoad(ZoneLoop)+MCPM(ZoneLoop)*MAT(CrossMixing(MixNum)%FromZone)
    2687             :                 //        Per Jan 17, 2008 conference call, agreed to use average conditions for Rho, Cp and Hfg
    2688             :                 //           and to recalculate the report variable using end of time step temps and humrats
    2689       16396 :                 AirDensity = PsyRhoAirFnPbTdbW(state,
    2690        4099 :                                                state.dataEnvrn->OutBaroPress,
    2691        4099 :                                                (thisZoneHB.MAT + fromZoneHB.MAT) / 2.0,
    2692        4099 :                                                (thisZoneHB.ZoneAirHumRat + fromZoneHB.ZoneAirHumRat) / 2.0,
    2693        8198 :                                                std::string());
    2694        4099 :                 CpAir = PsyCpAirFnW((thisZoneHB.ZoneAirHumRat + fromZoneHB.ZoneAirHumRat) / 2.0);
    2695        4099 :                 ZnAirRpt(ZoneLoop).MixVolume +=
    2696        4099 :                     CrossMixing(MixNum).DesiredAirFlowRate * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2697        4099 :                 ZnAirRpt(ZoneLoop).MixVdotCurDensity += CrossMixing(MixNum).DesiredAirFlowRate * ADSCorrectionFactor;
    2698        4099 :                 ZnAirRpt(ZoneLoop).MixMass +=
    2699        4099 :                     CrossMixing(MixNum).DesiredAirFlowRate * AirDensity * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2700        4099 :                 ZnAirRpt(ZoneLoop).MixMdot += CrossMixing(MixNum).DesiredAirFlowRate * AirDensity * ADSCorrectionFactor;
    2701        4099 :                 ZnAirRpt(ZoneLoop).MixVdotStdDensity +=
    2702        4099 :                     CrossMixing(MixNum).DesiredAirFlowRate * (AirDensity / state.dataEnvrn->StdRhoAir) * ADSCorrectionFactor;
    2703        4099 :                 MixSenLoad(ZoneLoop) += CrossMixing(MixNum).DesiredAirFlowRate * AirDensity * CpAir * (thisZoneHB.MAT - fromZoneHB.MAT);
    2704        4099 :                 H2OHtOfVap = PsyHgAirFnWTdb((thisZoneHB.ZoneAirHumRat + fromZoneHB.ZoneAirHumRat) / 2.0, (thisZoneHB.MAT + fromZoneHB.MAT) / 2.0);
    2705             :                 //       MixLatLoad(ZoneLoop) = MixLatLoad(ZoneLoop)+MixingMassFlowZone(ZoneLoop)*(ZoneAirHumRat(ZoneLoop)- &
    2706             :                 //                     ZoneAirHumRat(CrossMixing(MixNum)%FromZone))*H2OHtOfVap
    2707        4099 :                 MixLatLoad(ZoneLoop) +=
    2708        4099 :                     CrossMixing(MixNum).DesiredAirFlowRate * AirDensity * (thisZoneHB.ZoneAirHumRat - fromZoneHB.ZoneAirHumRat) * H2OHtOfVap;
    2709             :             }
    2710       28852 :             if ((CrossMixing(MixNum).FromZone == ZoneLoop) && CrossMixing(MixNum).ReportFlag) {
    2711        4099 :                 auto &mixingZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(CrossMixing(MixNum).ZonePtr);
    2712       16396 :                 AirDensity = PsyRhoAirFnPbTdbW(state,
    2713        4099 :                                                state.dataEnvrn->OutBaroPress,
    2714        4099 :                                                (thisZoneHB.MAT + mixingZoneHB.MAT) / 2.0,
    2715        4099 :                                                (thisZoneHB.ZoneAirHumRat + mixingZoneHB.ZoneAirHumRat) / 2.0,
    2716        8198 :                                                std::string());
    2717        4099 :                 CpAir = PsyCpAirFnW((thisZoneHB.ZoneAirHumRat + mixingZoneHB.ZoneAirHumRat) / 2.0);
    2718        4099 :                 ZnAirRpt(ZoneLoop).MixVolume +=
    2719        4099 :                     CrossMixing(MixNum).DesiredAirFlowRate * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2720        4099 :                 ZnAirRpt(ZoneLoop).MixVdotCurDensity += CrossMixing(MixNum).DesiredAirFlowRate * ADSCorrectionFactor;
    2721        4099 :                 ZnAirRpt(ZoneLoop).MixMass +=
    2722        4099 :                     CrossMixing(MixNum).DesiredAirFlowRate * AirDensity * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2723        4099 :                 ZnAirRpt(ZoneLoop).MixMdot += CrossMixing(MixNum).DesiredAirFlowRate * AirDensity * ADSCorrectionFactor;
    2724        4099 :                 ZnAirRpt(ZoneLoop).MixVdotStdDensity +=
    2725        4099 :                     CrossMixing(MixNum).DesiredAirFlowRate * (AirDensity / state.dataEnvrn->StdRhoAir) * ADSCorrectionFactor;
    2726        4099 :                 MixSenLoad(ZoneLoop) += CrossMixing(MixNum).DesiredAirFlowRate * AirDensity * CpAir * (thisZoneHB.MAT - mixingZoneHB.MAT);
    2727        4099 :                 H2OHtOfVap = PsyHgAirFnWTdb((thisZoneHB.ZoneAirHumRat + mixingZoneHB.ZoneAirHumRat) / 2.0, (thisZoneHB.MAT + mixingZoneHB.MAT) / 2.0);
    2728        4099 :                 MixLatLoad(ZoneLoop) +=
    2729        4099 :                     CrossMixing(MixNum).DesiredAirFlowRate * AirDensity * (thisZoneHB.ZoneAirHumRat - mixingZoneHB.ZoneAirHumRat) * H2OHtOfVap;
    2730             :             }
    2731             :         }
    2732             : 
    2733     2595750 :         if (state.dataHeatBal->TotRefDoorMixing > 0) {
    2734             :             // IF(ZoneLoop .NE. NumOfZones)THEN  !Refrigeration Door Mixing
    2735             :             // Note - do each Pair a Single time, so must do increment reports for both zones
    2736             :             //       Can't have a pair that has ZoneA zone number = NumOfZones because organized
    2737             :             //       in input with lowest zone # first no matter how input in idf
    2738       11956 :             if (RefDoorMixing(ZoneLoop).RefDoorMixFlag) { // .TRUE. for both zoneA and zoneB
    2739        4270 :                 if (RefDoorMixing(ZoneLoop).ZonePtr == ZoneLoop) {
    2740        5124 :                     for (int j = 1; j <= RefDoorMixing(ZoneLoop).NumRefDoorConnections; ++j) {
    2741             :                         //    Capture impact when zoneloop is the 'primary zone'
    2742             :                         //    that is, the zone of a pair with the lower zone number
    2743        2562 :                         if (RefDoorMixing(ZoneLoop).VolRefDoorFlowRate(j) > 0.0) {
    2744        1431 :                             int ZoneB = RefDoorMixing(ZoneLoop).MateZonePtr(j);
    2745        1431 :                             auto &zoneBHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneB);
    2746        5724 :                             AirDensity = PsyRhoAirFnPbTdbW(state,
    2747        1431 :                                                            state.dataEnvrn->OutBaroPress,
    2748        1431 :                                                            (thisZoneHB.MAT + zoneBHB.MAT) / 2.0,
    2749        1431 :                                                            (thisZoneHB.ZoneAirHumRat + zoneBHB.ZoneAirHumRat) / 2.0,
    2750        2862 :                                                            std::string());
    2751        1431 :                             CpAir = PsyCpAirFnW((thisZoneHB.ZoneAirHumRat + zoneBHB.ZoneAirHumRat) / 2.0);
    2752        1431 :                             H2OHtOfVap =
    2753        1431 :                                 PsyHgAirFnWTdb((thisZoneHB.ZoneAirHumRat + zoneBHB.ZoneAirHumRat) / 2.0, (thisZoneHB.MAT + zoneBHB.MAT) / 2.0);
    2754        1431 :                             ZnAirRpt(ZoneLoop).MixVolume +=
    2755        1431 :                                 RefDoorMixing(ZoneLoop).VolRefDoorFlowRate(j) * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2756        1431 :                             ZnAirRpt(ZoneLoop).MixVdotCurDensity += RefDoorMixing(ZoneLoop).VolRefDoorFlowRate(j) * ADSCorrectionFactor;
    2757        2862 :                             ZnAirRpt(ZoneLoop).MixMass += RefDoorMixing(ZoneLoop).VolRefDoorFlowRate(j) * AirDensity * TimeStepSys *
    2758        1431 :                                                           DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2759        1431 :                             ZnAirRpt(ZoneLoop).MixMdot += RefDoorMixing(ZoneLoop).VolRefDoorFlowRate(j) * AirDensity * ADSCorrectionFactor;
    2760        1431 :                             ZnAirRpt(ZoneLoop).MixVdotStdDensity +=
    2761        1431 :                                 RefDoorMixing(ZoneLoop).VolRefDoorFlowRate(j) * (AirDensity / state.dataEnvrn->StdRhoAir) * ADSCorrectionFactor;
    2762        1431 :                             MixSenLoad(ZoneLoop) +=
    2763        1431 :                                 RefDoorMixing(ZoneLoop).VolRefDoorFlowRate(j) * AirDensity * CpAir * (thisZoneHB.MAT - zoneBHB.MAT);
    2764        4293 :                             MixLatLoad(ZoneLoop) += RefDoorMixing(ZoneLoop).VolRefDoorFlowRate(j) * AirDensity *
    2765        2862 :                                                     (thisZoneHB.ZoneAirHumRat - zoneBHB.ZoneAirHumRat) * H2OHtOfVap;
    2766             :                         } // flow > 0
    2767             :                     }     // J-1, numref connections
    2768             :                 }         // zone A (zoneptr = zoneloop)
    2769       23058 :                 for (int ZoneA = 1; ZoneA <= (ZoneLoop - 1); ++ZoneA) {
    2770       18788 :                     auto &zoneAHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneA);
    2771             :                     //    Capture impact when zoneloop is the 'mating zone'
    2772             :                     //    that is, the zone of a pair with the higher zone number(matezoneptr = zoneloop)
    2773       18788 :                     if (RefDoorMixing(ZoneA).RefDoorMixFlag) {
    2774       14518 :                         for (int j = 1; j <= RefDoorMixing(ZoneA).NumRefDoorConnections; ++j) {
    2775        5978 :                             if (RefDoorMixing(ZoneA).MateZonePtr(j) == ZoneLoop) {
    2776        2562 :                                 if (RefDoorMixing(ZoneA).VolRefDoorFlowRate(j) > 0.0) {
    2777        5724 :                                     AirDensity = PsyRhoAirFnPbTdbW(state,
    2778        1431 :                                                                    state.dataEnvrn->OutBaroPress,
    2779        1431 :                                                                    (thisZoneHB.MAT + zoneAHB.MAT) / 2.0,
    2780        1431 :                                                                    (thisZoneHB.ZoneAirHumRat + zoneAHB.ZoneAirHumRat) / 2.0,
    2781        2862 :                                                                    std::string());
    2782        1431 :                                     CpAir = PsyCpAirFnW((thisZoneHB.ZoneAirHumRat + zoneAHB.ZoneAirHumRat) / 2.0);
    2783        1431 :                                     H2OHtOfVap = PsyHgAirFnWTdb((thisZoneHB.ZoneAirHumRat + zoneAHB.ZoneAirHumRat) / 2.0,
    2784        1431 :                                                                 (thisZoneHB.MAT + zoneAHB.MAT) / 2.0);
    2785        2862 :                                     ZnAirRpt(ZoneLoop).MixVolume += RefDoorMixing(ZoneA).VolRefDoorFlowRate(j) * TimeStepSys *
    2786        1431 :                                                                     DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2787        1431 :                                     ZnAirRpt(ZoneLoop).MixVdotCurDensity += RefDoorMixing(ZoneA).VolRefDoorFlowRate(j) * ADSCorrectionFactor;
    2788        2862 :                                     ZnAirRpt(ZoneLoop).MixMass += RefDoorMixing(ZoneA).VolRefDoorFlowRate(j) * AirDensity * TimeStepSys *
    2789        1431 :                                                                   DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2790        1431 :                                     ZnAirRpt(ZoneLoop).MixMdot += RefDoorMixing(ZoneA).VolRefDoorFlowRate(j) * AirDensity * ADSCorrectionFactor;
    2791        1431 :                                     ZnAirRpt(ZoneLoop).MixVdotStdDensity +=
    2792        1431 :                                         RefDoorMixing(ZoneA).VolRefDoorFlowRate(j) * (AirDensity / state.dataEnvrn->StdRhoAir) * ADSCorrectionFactor;
    2793        1431 :                                     MixSenLoad(ZoneLoop) +=
    2794        1431 :                                         RefDoorMixing(ZoneA).VolRefDoorFlowRate(j) * AirDensity * CpAir * (thisZoneHB.MAT - zoneAHB.MAT);
    2795        4293 :                                     MixLatLoad(ZoneLoop) += RefDoorMixing(ZoneA).VolRefDoorFlowRate(j) * AirDensity *
    2796        2862 :                                                             (thisZoneHB.ZoneAirHumRat - zoneAHB.ZoneAirHumRat) * H2OHtOfVap;
    2797             :                                 } // volflowrate > 0
    2798             :                             }     // matezoneptr (zoneB) = Zonelooop
    2799             :                         }         // NumRefDoorConnections
    2800             :                     }             // Refdoormix flag on ZoneA
    2801             :                 }                 // zone A from 1 to (zoneloop - 1)
    2802             :             }                     // Refdoormix flag on zoneloop
    2803             :         }                         //(TotRefDoorMixing .GT. 0)
    2804             :         // end refrigeration door mixing reports
    2805             : 
    2806             :         //    MixingLoad(ZoneLoop) = MCPM(ZoneLoop)*MAT(ZoneLoop) - MixSenLoad(ZoneLoop)
    2807     2595750 :         if (MixSenLoad(ZoneLoop) > 0.0) {
    2808       17144 :             ZnAirRpt(ZoneLoop).MixHeatLoss = MixSenLoad(ZoneLoop) * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2809       17144 :             ZnAirRpt(ZoneLoop).MixHeatGain = 0.0;
    2810             :         } else {
    2811     2578606 :             ZnAirRpt(ZoneLoop).MixHeatLoss = 0.0;
    2812     2578606 :             ZnAirRpt(ZoneLoop).MixHeatGain = -MixSenLoad(ZoneLoop) * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2813             :         }
    2814             :         // Report mixing latent loads
    2815             :         //    MixingLoad(ZoneLoop) = MixLatLoad(ZoneLoop)
    2816     2595750 :         if (MixLatLoad(ZoneLoop) > 0.0) {
    2817       16441 :             ZnAirRpt(ZoneLoop).MixLatentLoss = MixLatLoad(ZoneLoop) * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2818       16441 :             ZnAirRpt(ZoneLoop).MixLatentGain = 0.0;
    2819             :         } else {
    2820     2579309 :             ZnAirRpt(ZoneLoop).MixLatentLoss = 0.0;
    2821     2579309 :             ZnAirRpt(ZoneLoop).MixLatentGain = -MixLatLoad(ZoneLoop) * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2822             :         }
    2823             :         // Total Mixing losses and gains
    2824     2595750 :         TotalLoad =
    2825     2595750 :             ZnAirRpt(ZoneLoop).MixHeatGain + ZnAirRpt(ZoneLoop).MixLatentGain - ZnAirRpt(ZoneLoop).MixHeatLoss - ZnAirRpt(ZoneLoop).MixLatentLoss;
    2826     2595750 :         if (TotalLoad > 0) {
    2827        8552 :             ZnAirRpt(ZoneLoop).MixTotalGain = TotalLoad * ADSCorrectionFactor;
    2828        8552 :             ZnAirRpt(ZoneLoop).MixTotalLoss = 0.0;
    2829             :         } else {
    2830     2587198 :             ZnAirRpt(ZoneLoop).MixTotalGain = 0.0;
    2831     2587198 :             ZnAirRpt(ZoneLoop).MixTotalLoss = -TotalLoad * ADSCorrectionFactor;
    2832             :         }
    2833             : 
    2834             :         // Reporting combined outdoor air flows
    2835     2601144 :         for (int j = 1; j <= state.dataHeatBal->TotZoneAirBalance; ++j) {
    2836       10788 :             if (state.dataHeatBal->ZoneAirBalance(j).BalanceMethod == DataHeatBalance::AirBalance::Quadrature &&
    2837        5394 :                 ZoneLoop == state.dataHeatBal->ZoneAirBalance(j).ZonePtr) {
    2838        1798 :                 if (thisZoneHB.MAT > Zone(ZoneLoop).OutDryBulbTemp) {
    2839        3314 :                     ZnAirRpt(ZoneLoop).OABalanceHeatLoss = thisZoneHB.MDotCPOA * (thisZoneHB.MAT - Zone(ZoneLoop).OutDryBulbTemp) * TimeStepSys *
    2840        1657 :                                                            DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2841        1657 :                     ZnAirRpt(ZoneLoop).OABalanceHeatGain = 0.0;
    2842             :                 } else {
    2843         141 :                     ZnAirRpt(ZoneLoop).OABalanceHeatLoss = 0.0;
    2844         282 :                     ZnAirRpt(ZoneLoop).OABalanceHeatGain = -thisZoneHB.MDotCPOA * (thisZoneHB.MAT - Zone(ZoneLoop).OutDryBulbTemp) * TimeStepSys *
    2845         141 :                                                            DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2846             :                 }
    2847        1798 :                 H2OHtOfVap = PsyHgAirFnWTdb(state.dataEnvrn->OutHumRat, Zone(ZoneLoop).OutDryBulbTemp);
    2848        1798 :                 if (thisZoneHB.ZoneAirHumRat > state.dataEnvrn->OutHumRat) {
    2849         396 :                     ZnAirRpt(ZoneLoop).OABalanceLatentLoss = thisZoneHB.MDotOA * (thisZoneHB.ZoneAirHumRat - state.dataEnvrn->OutHumRat) *
    2850         198 :                                                              H2OHtOfVap * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2851         198 :                     ZnAirRpt(ZoneLoop).OABalanceLatentGain = 0.0;
    2852        1600 :                 } else if (thisZoneHB.ZoneAirHumRat <= state.dataEnvrn->OutHumRat) {
    2853        3200 :                     ZnAirRpt(ZoneLoop).OABalanceLatentGain = thisZoneHB.MDotOA * (state.dataEnvrn->OutHumRat - thisZoneHB.ZoneAirHumRat) *
    2854        1600 :                                                              H2OHtOfVap * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2855        1600 :                     ZnAirRpt(ZoneLoop).OABalanceLatentLoss = 0.0;
    2856             :                 }
    2857             :                 // Total ventilation losses and gains
    2858        3596 :                 TotalLoad = ZnAirRpt(ZoneLoop).OABalanceHeatGain + ZnAirRpt(ZoneLoop).OABalanceLatentGain - ZnAirRpt(ZoneLoop).OABalanceHeatLoss -
    2859        1798 :                             ZnAirRpt(ZoneLoop).OABalanceLatentLoss;
    2860        1798 :                 if (TotalLoad > 0) {
    2861         164 :                     ZnAirRpt(ZoneLoop).OABalanceTotalGain = TotalLoad * ADSCorrectionFactor;
    2862         164 :                     ZnAirRpt(ZoneLoop).OABalanceTotalLoss = 0.0;
    2863             :                 } else {
    2864        1634 :                     ZnAirRpt(ZoneLoop).OABalanceTotalGain = 0.0;
    2865        1634 :                     ZnAirRpt(ZoneLoop).OABalanceTotalLoss = -TotalLoad * ADSCorrectionFactor;
    2866             :                 }
    2867        1798 :                 ZnAirRpt(ZoneLoop).OABalanceMass = (thisZoneHB.MDotOA) * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2868        1798 :                 ZnAirRpt(ZoneLoop).OABalanceMdot = (thisZoneHB.MDotOA) * ADSCorrectionFactor;
    2869        1798 :                 AirDensity = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, thisZoneHB.MAT, thisZoneHB.ZoneAirHumRatAvg, std::string());
    2870        1798 :                 ZnAirRpt(ZoneLoop).OABalanceVolumeCurDensity =
    2871        1798 :                     (thisZoneHB.MDotOA / AirDensity) * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2872        1798 :                 ZnAirRpt(ZoneLoop).OABalanceAirChangeRate = ZnAirRpt(ZoneLoop).OABalanceVolumeCurDensity / (TimeStepSys * Zone(ZoneLoop).Volume);
    2873        1798 :                 ZnAirRpt(ZoneLoop).OABalanceVdotCurDensity = (thisZoneHB.MDotOA / AirDensity) * ADSCorrectionFactor;
    2874        1798 :                 AirDensity = state.dataEnvrn->StdRhoAir;
    2875        1798 :                 ZnAirRpt(ZoneLoop).OABalanceVolumeStdDensity =
    2876        1798 :                     (thisZoneHB.MDotOA / AirDensity) * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2877        1798 :                 ZnAirRpt(ZoneLoop).OABalanceVdotStdDensity = (thisZoneHB.MDotOA / AirDensity) * ADSCorrectionFactor;
    2878        1798 :                 ZnAirRpt(ZoneLoop).OABalanceFanElec = ZnAirRpt(ZoneLoop).VentilFanElec;
    2879             :             }
    2880             :         }
    2881             :         // Reports exfiltration loss
    2882     2595750 :         H2OHtOfVap = PsyHgAirFnWTdb(state.dataEnvrn->OutHumRat, Zone(ZoneLoop).OutDryBulbTemp);
    2883     2595750 :         ZnAirRpt(ZoneLoop).SysInletMass = 0;
    2884     2595750 :         ZnAirRpt(ZoneLoop).SysOutletMass = 0;
    2885     2595750 :         if (!ZoneEquipConfig(ZoneLoop).IsControlled) {
    2886      363525 :             for (int k = 1; k <= ZoneEquipConfig(ZoneLoop).NumInletNodes; ++k) {
    2887           0 :                 ZnAirRpt(ZoneLoop).SysInletMass += state.dataLoopNodes->Node(ZoneEquipConfig(ZoneLoop).InletNode(k)).MassFlowRate * TimeStepSys *
    2888           0 :                                                    DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2889             :             }
    2890      363525 :             for (int k = 1; k <= ZoneEquipConfig(ZoneLoop).NumExhaustNodes; ++k) {
    2891           0 :                 ZnAirRpt(ZoneLoop).SysOutletMass += state.dataLoopNodes->Node(ZoneEquipConfig(ZoneLoop).ExhaustNode(k)).MassFlowRate * TimeStepSys *
    2892           0 :                                                     DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2893             :             }
    2894      363525 :             for (int k = 1; k <= ZoneEquipConfig(ZoneLoop).NumReturnNodes; ++k) {
    2895           0 :                 ZnAirRpt(ZoneLoop).SysOutletMass += state.dataLoopNodes->Node(ZoneEquipConfig(ZoneLoop).ReturnNode(k)).MassFlowRate * TimeStepSys *
    2896           0 :                                                     DataGlobalConstants::SecInHour * ADSCorrectionFactor;
    2897             :             }
    2898             :         }
    2899             : 
    2900     7787250 :         ZnAirRpt(ZoneLoop).ExfilMass = ZnAirRpt(ZoneLoop).InfilMass + ZnAirRpt(ZoneLoop).VentilMass + ZnAirRpt(ZoneLoop).MixMass +
    2901     5191500 :                                        ZnAirRpt(ZoneLoop).OABalanceMass + ZnAirRpt(ZoneLoop).SysInletMass - ZnAirRpt(ZoneLoop).SysOutletMass; // kg
    2902     7787250 :         ZnAirRpt(ZoneLoop).ExfilSensiLoss = ZnAirRpt(ZoneLoop).ExfilMass / (TimeStepSys * DataGlobalConstants::SecInHour) *
    2903     5191500 :                                             (thisZoneHB.MAT - Zone(ZoneLoop).OutDryBulbTemp) * CpAir; // W
    2904     7787250 :         ZnAirRpt(ZoneLoop).ExfilLatentLoss = ZnAirRpt(ZoneLoop).ExfilMass / (TimeStepSys * DataGlobalConstants::SecInHour) *
    2905     5191500 :                                              (thisZoneHB.ZoneAirHumRat - state.dataEnvrn->OutHumRat) * H2OHtOfVap;
    2906     2595750 :         ZnAirRpt(ZoneLoop).ExfilTotalLoss = ZnAirRpt(ZoneLoop).ExfilLatentLoss + ZnAirRpt(ZoneLoop).ExfilSensiLoss;
    2907             : 
    2908     2595750 :         state.dataHeatBal->ZoneTotalExfiltrationHeatLoss += ZnAirRpt(ZoneLoop).ExfilTotalLoss * TimeStepSys * DataGlobalConstants::SecInHour;
    2909     2595750 :         state.dataHeatBal->ZoneTotalExhaustHeatLoss += ZnAirRpt(ZoneLoop).ExhTotalLoss * TimeStepSys * DataGlobalConstants::SecInHour;
    2910             :     }
    2911             : }
    2912             : 
    2913     2568313 : void SetHeatToReturnAirFlag(EnergyPlusData &state)
    2914             : {
    2915             : 
    2916             :     // SUBROUTINE INFORMATION:
    2917             :     //       AUTHOR         Fred Buhl
    2918             :     //       DATE WRITTEN   February 2008
    2919             : 
    2920             :     // PURPOSE OF THIS SUBROUTINE:
    2921             :     // This sets some flags at the air loop and zone level: these flags indicate
    2922             :     // whether an air loop represents a "unitary" system, and whether the system is operating
    2923             :     // in a on/off (cycling fan) mode. At the zone level flags are set to indicate whether
    2924             :     // the zone is served by a zonal system only, and whether the air loop serving the zone (idf any)
    2925             :     // is in cycling fan mode. Using this information, the subroutine sets a flag at the zone level
    2926             :     // to tell ManageZoneAirUpdates (predict and correct) what to do with the heat to return air.
    2927             : 
    2928             :     // METHODOLOGY EMPLOYED:
    2929             :     // Uses program data structures AirLoopControlInfo and ZoneEquipInfo
    2930             : 
    2931             :     // Using/Aliasing
    2932     2568313 :     auto &NumPrimaryAirSys = state.dataHVACGlobal->NumPrimaryAirSys;
    2933             :     using ScheduleManager::CheckScheduleValue;
    2934             :     using ScheduleManager::GetCurrentScheduleValue;
    2935             :     using ScheduleManager::GetScheduleMaxValue;
    2936             : 
    2937     2568313 :     bool CyclingFan(false); // TRUE means air loop operates in cycling fan mode at some point
    2938             : 
    2939     2568313 :     auto &AirLoopControlInfo(state.dataAirLoop->AirLoopControlInfo);
    2940     2568313 :     auto &ZoneEquipConfig(state.dataZoneEquip->ZoneEquipConfig);
    2941             : 
    2942     2568313 :     if (!state.dataHVACGlobal->AirLoopsSimOnce) return;
    2943             : 
    2944     1780535 :     if (state.dataHVACMgr->MyOneTimeFlag) {
    2945             :         // set the air loop Any Continuous Fan flag
    2946        1941 :         for (int AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
    2947        1172 :             if (AirLoopControlInfo(AirLoopNum).UnitarySys) { // for unitary systems check the cycling fan schedule
    2948         469 :                 if (AirLoopControlInfo(AirLoopNum).CycFanSchedPtr > 0) {
    2949         444 :                     Real64 CycFanMaxVal = GetScheduleMaxValue(state, AirLoopControlInfo(AirLoopNum).CycFanSchedPtr);
    2950         444 :                     if (CycFanMaxVal > 0.0) {
    2951         245 :                         AirLoopControlInfo(AirLoopNum).AnyContFan = true;
    2952             :                     } else {
    2953         199 :                         AirLoopControlInfo(AirLoopNum).AnyContFan = false;
    2954             :                     }
    2955             :                 } else { // no schedule means always cycling fan
    2956          25 :                     AirLoopControlInfo(AirLoopNum).AnyContFan = false;
    2957             :                 }
    2958             :             } else { // for nonunitary (central) all systems are continuous fan
    2959         703 :                 AirLoopControlInfo(AirLoopNum).AnyContFan = true;
    2960             :             }
    2961             :         }
    2962             :         // check to see if a controlled zone is served exclusively by a zonal system
    2963        5571 :         for (int ControlledZoneNum = 1; ControlledZoneNum <= state.dataGlobal->NumOfZones; ++ControlledZoneNum) {
    2964        4802 :             bool airLoopFound = false;
    2965        9035 :             for (int zoneInNode = 1; zoneInNode <= ZoneEquipConfig(ControlledZoneNum).NumInletNodes; ++zoneInNode) {
    2966        4233 :                 if (ZoneEquipConfig(ControlledZoneNum).InletNodeAirLoopNum(zoneInNode) > 0) {
    2967        3455 :                     airLoopFound = true;
    2968             :                 }
    2969             :             }
    2970        4802 :             if (!airLoopFound && ZoneEquipConfig(ControlledZoneNum).NumInletNodes == ZoneEquipConfig(ControlledZoneNum).NumExhaustNodes) {
    2971        1158 :                 ZoneEquipConfig(ControlledZoneNum).ZonalSystemOnly = true;
    2972             :             }
    2973             :         }
    2974             :         // issue warning messages if zone is served by a zonal system or a cycling system and the input calls for
    2975             :         // heat gain to return air
    2976        5571 :         for (int ControlledZoneNum = 1; ControlledZoneNum <= state.dataGlobal->NumOfZones; ++ControlledZoneNum) {
    2977        4802 :             if (!ZoneEquipConfig(ControlledZoneNum).IsControlled) continue;
    2978        4094 :             CyclingFan = false;
    2979        8327 :             for (int zoneInNode = 1; zoneInNode <= ZoneEquipConfig(ControlledZoneNum).NumInletNodes; ++zoneInNode) {
    2980        4233 :                 int AirLoopNum = ZoneEquipConfig(ControlledZoneNum).InletNodeAirLoopNum(zoneInNode);
    2981        4233 :                 if (AirLoopNum > 0) {
    2982        3455 :                     if (AirLoopControlInfo(AirLoopNum).CycFanSchedPtr > 0) {
    2983         561 :                         CyclingFan = CheckScheduleValue(state, AirLoopControlInfo(AirLoopNum).CycFanSchedPtr, 0.0);
    2984             :                     }
    2985             :                 }
    2986             :             }
    2987        4094 :             if (ZoneEquipConfig(ControlledZoneNum).ZonalSystemOnly || CyclingFan) {
    2988         825 :                 auto const &thisZone = state.dataHeatBal->Zone(ControlledZoneNum);
    2989         825 :                 if (thisZone.RefrigCaseRA) {
    2990          12 :                     ShowWarningError(state,
    2991           8 :                                      "For zone=" + thisZone.Name + " return air cooling by refrigerated cases will be applied to the zone air.");
    2992           4 :                     ShowContinueError(state, "  This zone has no return air or is served by an on/off HVAC system.");
    2993             :                 }
    2994       28598 :                 for (int LightNum = 1; LightNum <= state.dataHeatBal->TotLights; ++LightNum) {
    2995       27793 :                     if (state.dataHeatBal->Lights(LightNum).ZonePtr != ControlledZoneNum) continue;
    2996         855 :                     if (state.dataHeatBal->Lights(LightNum).FractionReturnAir > 0.0) {
    2997          20 :                         ShowWarningError(state, "For zone=" + thisZone.Name + " return air heat gain from lights will be applied to the zone air.");
    2998          20 :                         ShowContinueError(state, "  This zone has no return air or is served by an on/off HVAC system.");
    2999          20 :                         break;
    3000             :                     }
    3001             :                 }
    3002        1650 :                 for (int spaceNum : thisZone.spaceIndexes) {
    3003         825 :                     auto &thisSpace = state.dataHeatBal->space(spaceNum);
    3004        7880 :                     for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
    3005        7055 :                         if (state.dataSurface->SurfWinAirflowDestination(SurfNum) == DataSurfaces::WindowAirFlowDestination::Return) {
    3006           0 :                             ShowWarningError(
    3007           0 :                                 state, "For zone=" + thisZone.Name + " return air heat gain from air flow windows will be applied to the zone air.");
    3008           0 :                             ShowContinueError(state, "  This zone has no return air or is served by an on/off HVAC system.");
    3009             :                         }
    3010             :                     }
    3011             :                 }
    3012             :             }
    3013             :         }
    3014         769 :         state.dataHVACMgr->MyOneTimeFlag = false;
    3015             :     }
    3016             : 
    3017             :     // set the air loop fan operation mode
    3018     4276201 :     for (int AirLoopNum = 1; AirLoopNum <= NumPrimaryAirSys; ++AirLoopNum) {
    3019     2495666 :         if (AirLoopControlInfo(AirLoopNum).CycFanSchedPtr > 0) {
    3020      858027 :             if (GetCurrentScheduleValue(state, AirLoopControlInfo(AirLoopNum).CycFanSchedPtr) == 0.0) {
    3021      386648 :                 AirLoopControlInfo(AirLoopNum).FanOpMode = CycFanCycCoil;
    3022             :             } else {
    3023      471379 :                 AirLoopControlInfo(AirLoopNum).FanOpMode = ContFanCycCoil;
    3024             :             }
    3025             :         }
    3026             :     }
    3027             :     // set the zone level NoHeatToReturnAir flag
    3028             :     // if any air loop in the zone is continuous fan, then set NoHeatToReturnAir = false and sort it out node-by-node
    3029    12704141 :     for (int ControlledZoneNum = 1; ControlledZoneNum <= state.dataGlobal->NumOfZones; ++ControlledZoneNum) {
    3030    10923606 :         auto &thisZone = state.dataHeatBal->Zone(ControlledZoneNum);
    3031    10923606 :         if (!ZoneEquipConfig(ControlledZoneNum).IsControlled) continue;
    3032     9326278 :         thisZone.NoHeatToReturnAir = true;
    3033     9326278 :         if (!ZoneEquipConfig(ControlledZoneNum).ZonalSystemOnly) {
    3034     9748153 :             for (int zoneInNode = 1; zoneInNode <= ZoneEquipConfig(ControlledZoneNum).NumInletNodes; ++zoneInNode) {
    3035     8703085 :                 int AirLoopNum = ZoneEquipConfig(ControlledZoneNum).InletNodeAirLoopNum(zoneInNode);
    3036     8703085 :                 if (AirLoopNum > 0) {
    3037     7963301 :                     if (AirLoopControlInfo(AirLoopNum).FanOpMode == ContFanCycCoil) {
    3038     7417643 :                         thisZone.NoHeatToReturnAir = false;
    3039     7417643 :                         break;
    3040             :                     }
    3041             :                 }
    3042             :             }
    3043             :         }
    3044             :     }
    3045             : }
    3046             : 
    3047     2969485 : void UpdateZoneInletConvergenceLog(EnergyPlusData &state)
    3048             : {
    3049             : 
    3050     2969485 :     std::array<Real64, DataConvergParams::ConvergLogStackDepth> tmpRealARR = {0};
    3051             : 
    3052    25290215 :     for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    3053             : 
    3054    41861791 :         for (int NodeIndex = 1; NodeIndex <= state.dataConvergeParams->ZoneInletConvergence(ZoneNum).NumInletNodes; ++NodeIndex) {
    3055    19541061 :             int NodeNum = state.dataConvergeParams->ZoneInletConvergence(ZoneNum).InletNode(NodeIndex).NodeNum;
    3056             : 
    3057    19541061 :             tmpRealARR = state.dataConvergeParams->ZoneInletConvergence(ZoneNum).InletNode(NodeIndex).HumidityRatio;
    3058    19541061 :             state.dataConvergeParams->ZoneInletConvergence(ZoneNum).InletNode(NodeIndex).HumidityRatio[0] = state.dataLoopNodes->Node(NodeNum).HumRat;
    3059   195410610 :             for (int logIndex = 1; logIndex < DataConvergParams::ConvergLogStackDepth; logIndex++) {
    3060   175869549 :                 state.dataConvergeParams->ZoneInletConvergence(ZoneNum).InletNode(NodeIndex).HumidityRatio[logIndex] = tmpRealARR[logIndex - 1];
    3061             :             }
    3062             : 
    3063    19541061 :             tmpRealARR = state.dataConvergeParams->ZoneInletConvergence(ZoneNum).InletNode(NodeIndex).MassFlowRate;
    3064    19541061 :             state.dataConvergeParams->ZoneInletConvergence(ZoneNum).InletNode(NodeIndex).MassFlowRate[0] =
    3065    19541061 :                 state.dataLoopNodes->Node(NodeNum).MassFlowRate;
    3066   195410610 :             for (int logIndex = 1; logIndex < DataConvergParams::ConvergLogStackDepth; logIndex++) {
    3067   175869549 :                 state.dataConvergeParams->ZoneInletConvergence(ZoneNum).InletNode(NodeIndex).MassFlowRate[logIndex] = tmpRealARR[logIndex - 1];
    3068             :             }
    3069             : 
    3070    19541061 :             tmpRealARR = state.dataConvergeParams->ZoneInletConvergence(ZoneNum).InletNode(NodeIndex).Temperature;
    3071    19541061 :             state.dataConvergeParams->ZoneInletConvergence(ZoneNum).InletNode(NodeIndex).Temperature[0] = state.dataLoopNodes->Node(NodeNum).Temp;
    3072   195410610 :             for (int logIndex = 1; logIndex < DataConvergParams::ConvergLogStackDepth; logIndex++) {
    3073   175869549 :                 state.dataConvergeParams->ZoneInletConvergence(ZoneNum).InletNode(NodeIndex).Temperature[logIndex] = tmpRealARR[logIndex - 1];
    3074             :             }
    3075             :         }
    3076             :     }
    3077     2969485 : }
    3078             : 
    3079     2638872 : void CheckAirLoopFlowBalance(EnergyPlusData &state)
    3080             : {
    3081             :     // Check for unbalanced airloop
    3082     2638872 :     if (!state.dataGlobal->WarmupFlag && state.dataHVACGlobal->AirLoopsSimOnce) {
    3083     1081804 :         for (int AirLoopNum = 1; AirLoopNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopNum) {
    3084      646074 :             auto &thisAirLoopFlow(state.dataAirLoop->AirLoopFlow(AirLoopNum));
    3085      646074 :             if (!thisAirLoopFlow.FlowError) {
    3086      645984 :                 Real64 unbalancedExhaustDelta = thisAirLoopFlow.SupFlow - thisAirLoopFlow.OAFlow - thisAirLoopFlow.SysRetFlow;
    3087      645984 :                 if (unbalancedExhaustDelta > SmallMassFlow) {
    3088           3 :                     ShowSevereError(state,
    3089           2 :                                     "CheckAirLoopFlowBalance: AirLoopHVAC " + state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Name +
    3090             :                                         " is unbalanced. Supply is > return plus outdoor air.");
    3091           1 :                     ShowContinueErrorTimeStamp(state, "");
    3092           3 :                     ShowContinueError(state,
    3093           2 :                                       format("  Flows [m3/s at standard density]: Supply={:.6R}  Return={:.6R}  Outdoor Air={:.6R}",
    3094           2 :                                              thisAirLoopFlow.SupFlow / state.dataEnvrn->StdRhoAir,
    3095           2 :                                              thisAirLoopFlow.SysRetFlow / state.dataEnvrn->StdRhoAir,
    3096           3 :                                              thisAirLoopFlow.OAFlow / state.dataEnvrn->StdRhoAir));
    3097           1 :                     ShowContinueError(state, format("  Imbalance={:.6R}", unbalancedExhaustDelta / state.dataEnvrn->StdRhoAir));
    3098           1 :                     ShowContinueError(state, "  This error will only be reported once per system.");
    3099           1 :                     thisAirLoopFlow.FlowError = true;
    3100             :                 }
    3101             :             }
    3102             :         }
    3103             :     }
    3104     2638872 : }
    3105             : 
    3106        2313 : } // namespace EnergyPlus::HVACManager

Generated by: LCOV version 1.13