LCOV - code coverage report
Current view: top level - EnergyPlus - HVACManager.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 1095 1650 66.4 %
Date: 2024-08-23 23:50:59 Functions: 14 16 87.5 %

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

Generated by: LCOV version 1.14