LCOV - code coverage report
Current view: top level - EnergyPlus - RoomAirModelAirflowNetwork.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 65.4 % 532 348
Test Date: 2025-05-22 16:09:37 Functions: 77.8 % 9 7

            Line data    Source code
       1              : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
       2              : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3              : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4              : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5              : // contributors. All rights reserved.
       6              : //
       7              : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8              : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9              : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10              : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11              : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12              : //
      13              : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14              : // provided that the following conditions are met:
      15              : //
      16              : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17              : //     conditions and the following disclaimer.
      18              : //
      19              : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20              : //     conditions and the following disclaimer in the documentation and/or other materials
      21              : //     provided with the distribution.
      22              : //
      23              : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24              : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25              : //     used to endorse or promote products derived from this software without specific prior
      26              : //     written permission.
      27              : //
      28              : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29              : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30              : //     reference solely to the software portion of its product, Licensee must refer to the
      31              : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32              : //     obtained under this License and may not use a different name for the software. Except as
      33              : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34              : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35              : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36              : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37              : //
      38              : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39              : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40              : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41              : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42              : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43              : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44              : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45              : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46              : // POSSIBILITY OF SUCH DAMAGE.
      47              : 
      48              : // ObjexxFCL Headers
      49              : #include <ObjexxFCL/Array.functions.hh>
      50              : #include <ObjexxFCL/Array1D.hh>
      51              : // #include <ObjexxFCL/Fmath.hh>
      52              : 
      53              : // EnergyPlus Headers
      54              : #include <AirflowNetwork/Solver.hpp>
      55              : #include <EnergyPlus/BaseboardElectric.hh>
      56              : #include <EnergyPlus/BaseboardRadiator.hh>
      57              : #include <EnergyPlus/Data/EnergyPlusData.hh>
      58              : #include <EnergyPlus/DataDefineEquip.hh>
      59              : #include <EnergyPlus/DataEnvironment.hh>
      60              : #include <EnergyPlus/DataHVACGlobals.hh>
      61              : #include <EnergyPlus/DataHeatBalSurface.hh>
      62              : #include <EnergyPlus/DataHeatBalance.hh>
      63              : #include <EnergyPlus/DataLoopNode.hh>
      64              : #include <EnergyPlus/DataMoistureBalance.hh>
      65              : #include <EnergyPlus/DataMoistureBalanceEMPD.hh>
      66              : #include <EnergyPlus/DataRoomAirModel.hh>
      67              : #include <EnergyPlus/DataSurfaceLists.hh>
      68              : #include <EnergyPlus/DataSurfaces.hh>
      69              : #include <EnergyPlus/DataZoneEquipment.hh>
      70              : #include <EnergyPlus/ElectricBaseboardRadiator.hh>
      71              : #include <EnergyPlus/FluidProperties.hh>
      72              : #include <EnergyPlus/General.hh>
      73              : #include <EnergyPlus/GlobalNames.hh>
      74              : #include <EnergyPlus/HWBaseboardRadiator.hh>
      75              : #include <EnergyPlus/HeatBalFiniteDiffManager.hh>
      76              : #include <EnergyPlus/HeatBalanceHAMTManager.hh>
      77              : #include <EnergyPlus/HighTempRadiantSystem.hh>
      78              : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      79              : #include <EnergyPlus/InternalHeatGains.hh>
      80              : #include <EnergyPlus/MoistureBalanceEMPDManager.hh>
      81              : #include <EnergyPlus/OutputProcessor.hh>
      82              : #include <EnergyPlus/Psychrometrics.hh>
      83              : #include <EnergyPlus/RefrigeratedCase.hh>
      84              : #include <EnergyPlus/RoomAirModelAirflowNetwork.hh>
      85              : #include <EnergyPlus/SteamBaseboardRadiator.hh>
      86              : #include <EnergyPlus/UtilityRoutines.hh>
      87              : #include <EnergyPlus/ZoneAirLoopEquipmentManager.hh>
      88              : #include <EnergyPlus/ZoneDehumidifier.hh>
      89              : #include <EnergyPlus/ZonePlenum.hh>
      90              : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
      91              : 
      92              : namespace EnergyPlus {
      93              : 
      94              : namespace RoomAir {
      95              : 
      96              :     // MODULE INFORMATION:
      97              :     //       AUTHOR         Brent Griffith
      98              :     //       DATE WRITTEN   November 2009
      99              :     //       MODIFIED       Lixing Gu, Aug. 2015 for v8.4 replease
     100              : 
     101              :     // PURPOSE OF THIS MODULE:
     102              :     // contains the RoomAir model portions of RoomAirflowNetwork modeling
     103              : 
     104              :     // METHODOLOGY EMPLOYED:
     105              :     // Interact with Surface HB, internal gain, HVAC system and Airflow Network Domains
     106              :     // Do heat and moisture balance calculations on roomair nodes.
     107              : 
     108              :     // Using/Aliasing
     109              :     using namespace DataHeatBalSurface;
     110              :     using namespace DataSurfaces;
     111              :     using namespace DataHeatBalance;
     112              : 
     113            0 :     void SimRoomAirModelAFN(EnergyPlusData &state, int const zoneNum) // index number for the specified zone
     114              :     {
     115              : 
     116              :         // SUBROUTINE INFORMATION:
     117              :         //       AUTHOR         Brent Griffith
     118              :         //       DATE WRITTEN   January 2004/Aug 2005
     119              :         //       MODIFIED       Lixing Gu, Aug. 2015 for v8.4 replease
     120              : 
     121              :         // PURPOSE OF THIS SUBROUTINE:
     122              :         // This subroutine manages RoomAirflowNetwork model simulation
     123              : 
     124              :         // METHODOLOGY EMPLOYED:
     125              :         // calls subroutines (LOL)
     126              : 
     127            0 :         auto const &afnZoneInfo = state.dataRoomAir->AFNZoneInfo(zoneNum);
     128              : 
     129              :         // model control volume for each roomAir:node in the zone.
     130            0 :         for (int roomAirNodeNum = 1; roomAirNodeNum <= afnZoneInfo.NumOfAirNodes; ++roomAirNodeNum) {
     131            0 :             InitRoomAirModelAFN(state, zoneNum, roomAirNodeNum);
     132            0 :             CalcRoomAirModelAFN(state, zoneNum, roomAirNodeNum);
     133              :         }
     134              : 
     135            0 :         UpdateRoomAirModelAFN(state, zoneNum);
     136              : 
     137            0 :     } // SimRoomAirModelAirflowNetwork
     138              : 
     139              :     //****************************************************
     140              : 
     141            0 :     void LoadPredictionRoomAirModelAFN(EnergyPlusData &state,
     142              :                                        int const zoneNum,
     143              :                                        int const roomAirNodeNum) // index number for the specified zone and node
     144              :     {
     145              : 
     146              :         // SUBROUTINE INFORMATION:
     147              :         //       AUTHOR         Lixing Gu
     148              :         //       DATE WRITTEN   June, 2015
     149              : 
     150              :         // PURPOSE OF THIS SUBROUTINE:
     151              :         // Predict zone loads at a controlled node
     152              : 
     153            0 :         InitRoomAirModelAFN(state, zoneNum, roomAirNodeNum);
     154              : 
     155            0 :     } // LoadPredictionRoomAirModelAirflowNetwork
     156              : 
     157              :     //****************************************************
     158              : 
     159            3 :     void InitRoomAirModelAFN(EnergyPlusData &state, int const zoneNum,
     160              :                              int const roomAirNodeNum) // index number for the specified zone
     161              :     {
     162              : 
     163              :         // SUBROUTINE INFORMATION:
     164              :         //       AUTHOR         B. Griffith
     165              :         //       DATE WRITTEN   November 2009
     166              :         //       MODIFIED       Lixing Gu, Aug. 2015 for v8.4 release
     167              : 
     168              :         // PURPOSE OF THIS SUBROUTINE:
     169              :         // Perform one-time checking and term calculations
     170              : 
     171              :         using InternalHeatGains::SumInternalLatentGainsByTypes;
     172              :         using Psychrometrics::PsyCpAirFnW;
     173              :         using Psychrometrics::PsyRhoAirFnPbTdbW;
     174              : 
     175            3 :         Array1D_bool NodeFound; // True if a node is found.
     176            3 :         Array1D_bool EquipFound;
     177            3 :         Array1D<Real64> SupplyFrac;
     178            3 :         Array1D<Real64> ReturnFrac;
     179              : 
     180            3 :         if (state.dataRoomAirflowNetModel->OneTimeFlag) { // then do one - time setup inits
     181              : 
     182              :             // loop over all zones with RoomAirflowNetwork model
     183            2 :             for (int iZone = 1; iZone <= state.dataGlobal->NumOfZones; ++iZone) {
     184            1 :                 auto &afnZoneInfo = state.dataRoomAir->AFNZoneInfo(iZone);
     185            1 :                 if (!afnZoneInfo.IsUsed) continue;
     186            1 :                 int NumSurfs = 0; // NumSurfs isn't used anywhere?
     187            2 :                 for (int spaceNum : state.dataHeatBal->Zone(iZone).spaceIndexes) {
     188            1 :                     auto const &thisSpace = state.dataHeatBal->space(spaceNum);
     189            1 :                     NumSurfs += thisSpace.HTSurfaceLast - thisSpace.HTSurfaceFirst + 1;
     190              :                 }
     191              : 
     192            3 :                 for (auto &afnNode : afnZoneInfo.Node) {
     193              :                     // calculate volume of air in node's control volume
     194            2 :                     afnNode.AirVolume = state.dataHeatBal->Zone(iZone).Volume * afnNode.ZoneVolumeFraction;
     195              : 
     196            4 :                     SetupOutputVariable(state,
     197              :                                         "RoomAirflowNetwork Node NonAirSystemResponse",
     198              :                                         Constant::Units::W,
     199            2 :                                         afnNode.NonAirSystemResponse,
     200              :                                         OutputProcessor::TimeStepType::System,
     201              :                                         OutputProcessor::StoreType::Average,
     202            2 :                                         afnNode.Name);
     203            4 :                     SetupOutputVariable(state,
     204              :                                         "RoomAirflowNetwork Node SysDepZoneLoadsLagged",
     205              :                                         Constant::Units::W,
     206            2 :                                         afnNode.SysDepZoneLoadsLagged,
     207              :                                         OutputProcessor::TimeStepType::System,
     208              :                                         OutputProcessor::StoreType::Average,
     209            2 :                                         afnNode.Name);
     210            4 :                     SetupOutputVariable(state,
     211              :                                         "RoomAirflowNetwork Node SumIntSensibleGain",
     212              :                                         Constant::Units::W,
     213            2 :                                         afnNode.SumIntSensibleGain,
     214              :                                         OutputProcessor::TimeStepType::System,
     215              :                                         OutputProcessor::StoreType::Average,
     216            2 :                                         afnNode.Name);
     217            4 :                     SetupOutputVariable(state,
     218              :                                         "RoomAirflowNetwork Node SumIntLatentGain",
     219              :                                         Constant::Units::W,
     220            2 :                                         afnNode.SumIntLatentGain,
     221              :                                         OutputProcessor::TimeStepType::System,
     222              :                                         OutputProcessor::StoreType::Average,
     223            2 :                                         afnNode.Name);
     224              :                 }
     225              :             }
     226            1 :             state.dataRoomAirflowNetModel->OneTimeFlag = false;
     227              :         }
     228              : 
     229            3 :         if (state.dataRoomAirflowNetModel->OneTimeFlagConf) { // then do one - time setup inits
     230            2 :             if (allocated(state.dataZoneEquip->ZoneEquipConfig) && allocated(state.dataZoneEquip->ZoneEquipList)) {
     231            2 :                 int MaxNodeNum = 0;
     232            2 :                 int MaxEquipNum = 0;
     233            2 :                 bool ErrorsFound = false;
     234            4 :                 for (int iZone = 1; iZone <= state.dataGlobal->NumOfZones; ++iZone) {
     235            2 :                     if (!state.dataHeatBal->Zone(iZone).IsControlled) continue;
     236            2 :                     MaxEquipNum = max(MaxEquipNum, state.dataZoneEquip->ZoneEquipList(iZone).NumOfEquipTypes);
     237            2 :                     MaxNodeNum = max(MaxNodeNum, state.dataZoneEquip->ZoneEquipConfig(iZone).NumInletNodes);
     238              :                 }
     239            2 :                 if (MaxNodeNum > 0) {
     240            2 :                     NodeFound.allocate(MaxNodeNum);
     241            2 :                     NodeFound = false;
     242              :                 }
     243            2 :                 if (MaxEquipNum > 0) {
     244            2 :                     EquipFound.allocate(MaxEquipNum);
     245            2 :                     SupplyFrac.allocate(MaxEquipNum);
     246            2 :                     ReturnFrac.allocate(MaxEquipNum);
     247            2 :                     EquipFound = false;
     248            2 :                     SupplyFrac = 0.0;
     249            2 :                     ReturnFrac = 0.0;
     250              :                 }
     251              : 
     252              :                 // loop over all zones with RoomAirflowNetwork model
     253            4 :                 for (int iZone = 1; iZone <= state.dataGlobal->NumOfZones; ++iZone) {
     254            2 :                     auto const &zone = state.dataHeatBal->Zone(iZone);
     255            2 :                     if (!zone.IsControlled) continue;
     256              : 
     257            2 :                     auto &afnZoneInfo = state.dataRoomAir->AFNZoneInfo(iZone);
     258            2 :                     if (!afnZoneInfo.IsUsed) continue;
     259            2 :                     afnZoneInfo.ActualZoneID = iZone;
     260            2 :                     SupplyFrac = 0.0;
     261            2 :                     ReturnFrac = 0.0;
     262            2 :                     NodeFound = false;
     263            2 :                     int numAirDistUnits = 0;
     264              : 
     265            2 :                     auto const &zoneEquipList = state.dataZoneEquip->ZoneEquipList(iZone);
     266            2 :                     auto const &zoneEquipConfig = state.dataZoneEquip->ZoneEquipConfig(iZone);
     267              : 
     268              :                     // find supply air node number
     269            6 :                     for (auto &afnNode : afnZoneInfo.Node) {
     270            8 :                         for (auto &afnHVAC : afnNode.HVAC) {
     271            8 :                             for (int I = 1; I <= zoneEquipList.NumOfEquipTypes; ++I) { // loop over all equip types
     272            4 :                                 if (zoneEquipList.EquipType(I) == DataZoneEquipment::ZoneEquipType::AirDistributionUnit) {
     273            2 :                                     if (numAirDistUnits == 0)
     274              :                                         numAirDistUnits =
     275            1 :                                             state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneHVAC:AirDistributionUnit");
     276            2 :                                     if (state.dataZoneAirLoopEquipmentManager->GetAirDistUnitsFlag) {
     277            0 :                                         ZoneAirLoopEquipmentManager::GetZoneAirLoopEquipment(state);
     278            0 :                                         state.dataZoneAirLoopEquipmentManager->GetAirDistUnitsFlag = false;
     279              :                                     }
     280              : 
     281            4 :                                     for (int AirDistUnitNum = 1; AirDistUnitNum <= numAirDistUnits; ++AirDistUnitNum) {
     282            2 :                                         if (zoneEquipList.EquipName(I) == state.dataDefineEquipment->AirDistUnit(AirDistUnitNum).Name) {
     283            2 :                                             if (afnHVAC.Name == state.dataDefineEquipment->AirDistUnit(AirDistUnitNum).EquipName(1)) {
     284            2 :                                                 if (afnHVAC.EquipConfigIndex == 0) {
     285            0 :                                                     afnHVAC.EquipConfigIndex = I;
     286              :                                                 }
     287            2 :                                                 EquipFound(I) = true;
     288            2 :                                                 SupplyFrac(I) += afnHVAC.SupplyFraction;
     289            2 :                                                 ReturnFrac(I) += afnHVAC.ReturnFraction;
     290              :                                             }
     291              :                                         }
     292              :                                     }
     293            2 :                                 } else if (Util::SameString(zoneEquipList.EquipName(I), afnHVAC.Name)) {
     294            2 :                                     if (afnHVAC.EquipConfigIndex == 0) {
     295            2 :                                         afnHVAC.EquipConfigIndex = I;
     296              :                                     }
     297            2 :                                     EquipFound(I) = true;
     298            2 :                                     SupplyFrac(I) += afnHVAC.SupplyFraction;
     299            2 :                                     ReturnFrac(I) += afnHVAC.ReturnFraction;
     300              :                                 }
     301              :                             }
     302            4 :                             for (int iNode = 1; iNode <= state.dataLoopNodes->NumOfNodes; ++iNode) { // loop over all nodes to find supply node ID
     303            4 :                                 if (Util::SameString(state.dataLoopNodes->NodeID(iNode), afnHVAC.SupplyNodeName)) {
     304            4 :                                     afnHVAC.SupNodeNum = iNode;
     305            4 :                                     break;
     306              :                                 }
     307              :                             }
     308              :                             // Verify inlet nodes
     309            4 :                             int inletNodeIndex = 0;
     310            4 :                             for (int iNode = 1; iNode <= zoneEquipConfig.NumInletNodes;
     311              :                                  ++iNode) { // loop over all supply inlet nodes in a single zone
     312              :                                 // !Get node conditions
     313            4 :                                 if (zoneEquipConfig.InletNode(iNode) == afnHVAC.SupNodeNum) {
     314            4 :                                     NodeFound(iNode) = true;
     315            4 :                                     inletNodeIndex = iNode;
     316            4 :                                     break;
     317              :                                 }
     318              :                             }
     319              : 
     320            4 :                             if (afnHVAC.SupNodeNum > 0 && afnHVAC.ReturnNodeName.empty()) {
     321              :                                 // Find matching return node
     322            0 :                                 for (int retNode = 1; retNode <= zoneEquipConfig.NumReturnNodes; ++retNode) {
     323            0 :                                     if ((zoneEquipConfig.ReturnNodeInletNum(retNode) == inletNodeIndex) &&
     324            0 :                                         (zoneEquipConfig.ReturnNode(retNode) > 0)) {
     325            0 :                                         afnHVAC.RetNodeNum = zoneEquipConfig.ReturnNode(retNode); // Zone return node
     326            0 :                                         break;
     327              :                                     }
     328              :                                 }
     329              :                             }
     330              : 
     331            4 :                             if (afnHVAC.RetNodeNum == 0) {
     332            4 :                                 for (int iNode = 1; iNode <= state.dataLoopNodes->NumOfNodes; ++iNode) { // loop over all nodes to find return node ID
     333            4 :                                     if (Util::SameString(state.dataLoopNodes->NodeID(iNode), afnHVAC.ReturnNodeName)) {
     334            2 :                                         afnHVAC.RetNodeNum = iNode;
     335            2 :                                         break;
     336              :                                     }
     337              :                                 }
     338              :                             }
     339            8 :                             SetupOutputVariable(state,
     340              :                                                 "RoomAirflowNetwork Node HVAC Supply Fraction",
     341              :                                                 Constant::Units::None,
     342            4 :                                                 afnHVAC.SupplyFraction,
     343              :                                                 OutputProcessor::TimeStepType::System,
     344              :                                                 OutputProcessor::StoreType::Average,
     345            4 :                                                 afnHVAC.Name);
     346            8 :                             SetupOutputVariable(state,
     347              :                                                 "RoomAirflowNetwork Node HVAC Return Fraction",
     348              :                                                 Constant::Units::None,
     349            4 :                                                 afnHVAC.ReturnFraction,
     350              :                                                 OutputProcessor::TimeStepType::System,
     351              :                                                 OutputProcessor::StoreType::Average,
     352            4 :                                                 afnHVAC.Name);
     353              :                         }
     354              :                     }
     355              :                     // Count node with.TRUE.
     356            2 :                     int ISum = 0;
     357            4 :                     for (int iNode = 1; iNode <= MaxNodeNum; ++iNode) { // loop over all supply inlet nodes in a single zone
     358            2 :                         if (NodeFound(iNode)) ++ISum;
     359              :                     }
     360              :                     // Provide error messages with incorrect supplu node inputs
     361            2 :                     if (ISum != zoneEquipConfig.NumInletNodes) {
     362            0 :                         if (ISum > zoneEquipConfig.NumInletNodes) {
     363            0 :                             ShowSevereError(
     364              :                                 state, "GetRoomAirflowNetworkData: The number of equipment listed in RoomAirflowNetwork:Node:HVACEquipment objects");
     365            0 :                             ShowContinueError(state, format("is greater than the number of zone configuration inlet nodes in {}", zone.Name));
     366            0 :                             ShowContinueError(state, "Please check inputs of both objects.");
     367            0 :                             ErrorsFound = true;
     368              :                         } else {
     369            0 :                             ShowSevereError(
     370              :                                 state, "GetRoomAirflowNetworkData: The number of equipment listed in RoomAirflowNetwork:Node:HVACEquipment objects");
     371            0 :                             ShowContinueError(state, format("is less than the number of zone configuration inlet nodes in {}", zone.Name));
     372            0 :                             ShowContinueError(state, "Please check inputs of both objects.");
     373            0 :                             ErrorsFound = true;
     374              :                         }
     375              :                     }
     376              : 
     377              :                     // Check equipment names to ensure they are used in RoomAirflowNetwork : Node : HVACEquipment objects
     378            4 :                     for (int I = 1; I <= zoneEquipList.NumOfEquipTypes; ++I) { // loop over all equip types
     379            2 :                         if (!EquipFound(I)) {
     380            0 :                             ShowSevereError(state,
     381              :                                             "GetRoomAirflowNetworkData: The equipment listed in ZoneEquipList is not found in the lsit of "
     382              :                                             "RoomAir:Node:AirflowNetwork:HVACEquipment objects =");
     383            0 :                             ShowContinueError(state, format("{}. Please check inputs of both objects.", zoneEquipList.EquipName(I)));
     384            0 :                             ErrorsFound = true;
     385              :                         }
     386              :                     }
     387              : 
     388              :                     // Check fraction to ensure sum = 1.0 for every equipment
     389            4 :                     for (int I = 1; I <= zoneEquipList.NumOfEquipTypes; ++I) { // loop over all equip types
     390            2 :                         if (std::abs(SupplyFrac(I) - 1.0) > 0.001) {
     391            0 :                             ShowSevereError(state, "GetRoomAirflowNetworkData: Invalid, zone supply fractions do not sum to 1.0");
     392            0 :                             ShowContinueError(
     393            0 :                                 state, format("Entered in {} defined in RoomAir:Node:AirflowNetwork:HVACEquipment", zoneEquipList.EquipName(I)));
     394            0 :                             ShowContinueError(state,
     395              :                                               "The Fraction of supply fraction values across all the roomair nodes in a zone needs to sum to 1.0.");
     396            0 :                             ShowContinueError(state, format("The sum of fractions entered = {:.3R}", SupplyFrac(I)));
     397            0 :                             ErrorsFound = true;
     398              :                         }
     399            2 :                         if (std::abs(ReturnFrac(I) - 1.0) > 0.001) {
     400            0 :                             ShowSevereError(state, "GetRoomAirflowNetworkData: Invalid, zone return fractions do not sum to 1.0");
     401            0 :                             ShowContinueError(
     402            0 :                                 state, format("Entered in {} defined in RoomAir:Node:AirflowNetwork:HVACEquipment", zoneEquipList.EquipName(I)));
     403            0 :                             ShowContinueError(state,
     404              :                                               "The Fraction of return fraction values across all the roomair nodes in a zone needs to sum to 1.0.");
     405            0 :                             ShowContinueError(state, format("The sum of fractions entered = {:.3R}", ReturnFrac(I)));
     406            0 :                             ErrorsFound = true;
     407              :                         }
     408              :                     }
     409              :                 }
     410            2 :                 state.dataRoomAirflowNetModel->OneTimeFlagConf = false;
     411            2 :                 if (allocated(NodeFound)) NodeFound.deallocate();
     412            2 :                 if (ErrorsFound) {
     413            0 :                     ShowFatalError(state, "GetRoomAirflowNetworkData: Errors found getting air model input.  Program terminates.");
     414              :                 }
     415              :             } // if (allocated)
     416              :         }     // if (OneTimeFlagConf)
     417              : 
     418            3 :         if (state.dataGlobal->BeginEnvrnFlag && state.dataRoomAirflowNetModel->EnvrnFlag) {
     419            2 :             for (int iZone = 1; iZone <= state.dataGlobal->NumOfZones; ++iZone) {
     420            1 :                 auto &afnZoneInfo = state.dataRoomAir->AFNZoneInfo(iZone);
     421            1 :                 if (!afnZoneInfo.IsUsed) continue;
     422            3 :                 for (auto &afnNode : afnZoneInfo.Node) {
     423            2 :                     afnNode.AirTemp = 23.0;
     424            2 :                     afnNode.AirTempX = {23.0, 23.0, 23.0, 23.0};
     425            2 :                     afnNode.AirTempDSX = {23.0, 23.0, 23.0, 23.0};
     426            2 :                     afnNode.AirTempT1 = 23.0;
     427            2 :                     afnNode.AirTempTX = 23.0;
     428            2 :                     afnNode.AirTempT2 = 23.0;
     429              : 
     430            2 :                     afnNode.HumRat = 0.0;
     431            2 :                     afnNode.HumRatX = {0.0, 0.0, 0.0, 0.0};
     432            2 :                     afnNode.HumRatDSX = {0.0, 0.0, 0.0, 0.0};
     433            2 :                     afnNode.HumRatT1 = 0.0;
     434            2 :                     afnNode.HumRatTX = 0.0;
     435            2 :                     afnNode.HumRatT2 = 0.0;
     436              : 
     437            2 :                     afnNode.SysDepZoneLoadsLagged = 0.0;
     438            2 :                     afnNode.SysDepZoneLoadsLaggedOld = 0.0;
     439              :                 }
     440              :             }
     441            1 :             state.dataRoomAirflowNetModel->EnvrnFlag = false;
     442              :         }
     443            3 :         if (!state.dataGlobal->BeginEnvrnFlag) {
     444            0 :             state.dataRoomAirflowNetModel->EnvrnFlag = true;
     445              :         }
     446              : 
     447              :         // reuse code in ZoneTempPredictorCorrector for sensible components.
     448            3 :         CalcNodeSums(state, zoneNum, roomAirNodeNum);
     449              : 
     450            3 :         SumNonAirSystemResponseForNode(state, zoneNum, roomAirNodeNum);
     451              : 
     452              :         // latent gains.
     453            3 :         auto &afnZoneInfo = state.dataRoomAir->AFNZoneInfo(zoneNum);
     454            3 :         auto &afnNode = afnZoneInfo.Node(roomAirNodeNum);
     455              : 
     456            3 :         if (allocated(afnNode.SurfMask)) {
     457            3 :             CalcSurfaceMoistureSums(state, zoneNum, roomAirNodeNum, afnNode.SumHmAW, afnNode.SumHmARa, afnNode.SumHmARaW, afnNode.SurfMask);
     458              :         }
     459              : 
     460              :         // prepare AirflowNetwor flow rates and temperatures
     461            3 :         Real64 SumLinkMCp = 0.0;
     462            3 :         Real64 SumLinkMCpT = 0.0;
     463            3 :         Real64 SumLinkM = 0.0;
     464            3 :         Real64 SumLinkMW = 0.0;
     465              : 
     466            3 :         if (afnNode.AFNNodeID > 0) {
     467           12 :             for (int iLink = 1; iLink <= afnNode.NumOfAirflowLinks; ++iLink) {
     468            9 :                 auto &afnLink = afnNode.Link(iLink);
     469            9 :                 int linkNum = afnLink.AFNSimuID;
     470            9 :                 if (state.afn->AirflowNetworkLinkageData(linkNum).NodeNums[0] == afnNode.AFNNodeID) { // incoming flow
     471            7 :                     int nodeInNum = state.afn->AirflowNetworkLinkageData(linkNum).NodeNums[1];
     472            7 :                     afnLink.TempIn = state.afn->AirflowNetworkNodeSimu(nodeInNum).TZ;
     473            7 :                     afnLink.HumRatIn = state.afn->AirflowNetworkNodeSimu(nodeInNum).WZ;
     474            7 :                     afnLink.MdotIn = state.afn->AirflowNetworkLinkSimu(linkNum).FLOW2;
     475              :                 }
     476            9 :                 if (state.afn->AirflowNetworkLinkageData(linkNum).NodeNums[1] == afnNode.AFNNodeID) { // outgoing flow
     477            2 :                     int nodeInNum = state.afn->AirflowNetworkLinkageData(linkNum).NodeNums[0];
     478            2 :                     afnLink.TempIn = state.afn->AirflowNetworkNodeSimu(nodeInNum).TZ;
     479            2 :                     afnLink.HumRatIn = state.afn->AirflowNetworkNodeSimu(nodeInNum).WZ;
     480            2 :                     afnLink.MdotIn = state.afn->AirflowNetworkLinkSimu(linkNum).FLOW;
     481              :                 }
     482              :             }
     483              : 
     484           12 :             for (int iLink = 1; iLink <= afnNode.NumOfAirflowLinks; ++iLink) {
     485            9 :                 auto &afnLink = afnNode.Link(iLink);
     486            9 :                 Real64 CpAir = PsyCpAirFnW(afnLink.HumRatIn);
     487            9 :                 SumLinkMCp += CpAir * afnLink.MdotIn;
     488            9 :                 SumLinkMCpT += CpAir * afnLink.MdotIn * afnLink.TempIn;
     489            9 :                 SumLinkM += afnLink.MdotIn;
     490            9 :                 SumLinkMW += afnLink.MdotIn * afnLink.HumRatIn;
     491              :             }
     492              :         }
     493              : 
     494            3 :         afnNode.SumLinkMCp = SumLinkMCp;
     495            3 :         afnNode.SumLinkMCpT = SumLinkMCpT;
     496            3 :         afnNode.SumLinkM = SumLinkM;
     497            3 :         afnNode.SumLinkMW = SumLinkMW;
     498            3 :         afnNode.SysDepZoneLoadsLagged = afnNode.SysDepZoneLoadsLaggedOld;
     499              : 
     500            3 :         afnNode.RhoAir = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, afnNode.AirTemp, afnNode.HumRat, "InitRoomAirModelAirflowNetwork");
     501              : 
     502            3 :         afnNode.CpAir = PsyCpAirFnW(afnNode.HumRat);
     503              : 
     504            3 :     } // InitRoomAirModelAirflowNetwork
     505              : 
     506              :     //*****************************************************************************************
     507              : 
     508            2 :     void CalcRoomAirModelAFN(EnergyPlusData &state, int const zoneNum,
     509              :                              int const roomAirNodeNum) // index number for the specified zone and node
     510              :     {
     511              : 
     512              :         // SUBROUTINE INFORMATION:
     513              :         //       AUTHOR         Brent Griffith
     514              :         //       DATE WRITTEN   November 2009
     515              :         //       MODIFIED       Lixing Gu, Aug. 2015 for v8.4 replease
     516              : 
     517              :         // PURPOSE OF THIS SUBROUTINE:
     518              :         // calculate new values for temperature and humidity ratio for room air node
     519              : 
     520              :         // METHODOLOGY EMPLOYED:
     521              :         // take terms(updated in init routine) and use classic air balance equations
     522              :         // solved for state variables. Store results in structure.
     523              : 
     524              :         // Using/Aliasing
     525            2 :         Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
     526              :         using Psychrometrics::PsyHgAirFnWTdb;
     527              :         using Psychrometrics::PsyRhFnTdbWPb;
     528              : 
     529              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     530              :         std::array<Real64, 3> NodeTempX;
     531              :         std::array<Real64, 3> NodeHumRatX;
     532              :         Real64 AirTempT1;
     533              :         Real64 HumRatT1;
     534              : 
     535            2 :         auto &afnZoneInfo = state.dataRoomAir->AFNZoneInfo(zoneNum);
     536            2 :         auto &afnNode = afnZoneInfo.Node(roomAirNodeNum);
     537              : 
     538            2 :         if (state.dataHVACGlobal->UseZoneTimeStepHistory) {
     539            2 :             NodeTempX[0] = afnNode.AirTempX[0];
     540            2 :             NodeTempX[1] = afnNode.AirTempX[1];
     541            2 :             NodeTempX[2] = afnNode.AirTempX[2];
     542              : 
     543            2 :             NodeHumRatX[0] = afnNode.HumRatX[0];
     544            2 :             NodeHumRatX[1] = afnNode.HumRatX[1];
     545            2 :             NodeHumRatX[2] = afnNode.HumRatX[2];
     546              :         } else { // use down - stepped history
     547            0 :             NodeTempX[0] = afnNode.AirTempDSX[0];
     548            0 :             NodeTempX[1] = afnNode.AirTempDSX[1];
     549            0 :             NodeTempX[2] = afnNode.AirTempDSX[2];
     550              : 
     551            0 :             NodeHumRatX[0] = afnNode.HumRatDSX[0];
     552            0 :             NodeHumRatX[1] = afnNode.HumRatDSX[1];
     553            0 :             NodeHumRatX[2] = afnNode.HumRatDSX[2];
     554              :         }
     555              : 
     556            2 :         if (state.dataHeatBal->ZoneAirSolutionAlgo != DataHeatBalance::SolutionAlgo::ThirdOrder) {
     557            0 :             AirTempT1 = afnNode.AirTempT1;
     558            0 :             HumRatT1 = afnNode.HumRatT1;
     559              :         }
     560              :         // solve for node drybulb temperature
     561            2 :         Real64 TempDepCoef = afnNode.SumHA + afnNode.SumLinkMCp + afnNode.SumSysMCp;
     562            2 :         Real64 TempIndCoef = afnNode.SumIntSensibleGain + afnNode.SumHATsurf - afnNode.SumHATref + afnNode.SumLinkMCpT + afnNode.SumSysMCpT +
     563            2 :                              afnNode.NonAirSystemResponse + afnNode.SysDepZoneLoadsLagged;
     564            2 :         Real64 AirCap = afnNode.AirVolume * state.dataHeatBal->Zone(zoneNum).ZoneVolCapMultpSens * afnNode.RhoAir * afnNode.CpAir / TimeStepSysSec;
     565              : 
     566            2 :         if (state.dataHeatBal->ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::AnalyticalSolution) {
     567            0 :             if (TempDepCoef == 0.0) { // B=0
     568            0 :                 afnNode.AirTemp = AirTempT1 + TempIndCoef / AirCap;
     569              :             } else {
     570            0 :                 afnNode.AirTemp = (AirTempT1 - TempIndCoef / TempDepCoef) * std::exp(min(700.0, -TempDepCoef / AirCap)) + TempIndCoef / TempDepCoef;
     571              :             }
     572            2 :         } else if (state.dataHeatBal->ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::EulerMethod) {
     573            0 :             afnNode.AirTemp = (AirCap * AirTempT1 + TempIndCoef) / (AirCap + TempDepCoef);
     574              :         } else {
     575            2 :             afnNode.AirTemp = (TempIndCoef + AirCap * (3.0 * NodeTempX[0] - (3.0 / 2.0) * NodeTempX[1] + (1.0 / 3.0) * NodeTempX[2])) /
     576            2 :                               ((11.0 / 6.0) * AirCap + TempDepCoef);
     577              :         }
     578              : 
     579              :         // solve for node humidity ratio using 3 algorithms
     580            2 :         Real64 H2OHtOfVap = PsyHgAirFnWTdb(afnNode.HumRat, afnNode.AirTemp);
     581            2 :         Real64 A = afnNode.SumLinkM + afnNode.SumHmARa + afnNode.SumSysM;
     582            2 :         Real64 B = (afnNode.SumIntLatentGain / H2OHtOfVap) + afnNode.SumSysMW + afnNode.SumLinkMW + afnNode.SumHmARaW;
     583            2 :         Real64 C = afnNode.RhoAir * afnNode.AirVolume * state.dataHeatBal->Zone(zoneNum).ZoneVolCapMultpMoist / TimeStepSysSec;
     584              : 
     585              :         // Exact solution
     586            2 :         if (state.dataHeatBal->ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::AnalyticalSolution) {
     587            0 :             if (A == 0.0) { // B=0
     588            0 :                 afnNode.HumRat = HumRatT1 + B / C;
     589              :             } else {
     590            0 :                 afnNode.HumRat = (HumRatT1 - B / A) * std::exp(min(700., -A / C)) + B / A;
     591              :             }
     592            2 :         } else if (state.dataHeatBal->ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::EulerMethod) {
     593            0 :             afnNode.HumRat = (C * HumRatT1 + B) / (C + A);
     594              :         } else {
     595            2 :             afnNode.HumRat = (B + C * (3.0 * NodeHumRatX[0] - (3.0 / 2.0) * NodeHumRatX[1] + (1.0 / 3.0) * NodeHumRatX[2])) / ((11.0 / 6.0) * C + A);
     596              :         }
     597              : 
     598            2 :         afnNode.AirCap = AirCap;
     599            2 :         afnNode.AirHumRat = C;
     600              : 
     601            2 :         afnNode.RelHumidity =
     602            2 :             PsyRhFnTdbWPb(state, afnNode.AirTemp, afnNode.HumRat, state.dataEnvrn->OutBaroPress, "CalcRoomAirModelAirflowNetwork") * 100.0;
     603              : 
     604            2 :     } // CalcRoomAirModelAirflowNetwork
     605              : 
     606            1 :     void UpdateRoomAirModelAFN(EnergyPlusData &state, int const zoneNum)
     607              :     {
     608              : 
     609              :         // SUBROUTINE INFORMATION:
     610              :         //       AUTHOR         B Griffith
     611              :         //       DATE WRITTEN   November 2009
     612              :         //       MODIFIED       Lixing Gu, Aug. 2015 for v8.4 replease
     613              : 
     614              :         // PURPOSE OF THIS SUBROUTINE:
     615              :         // update variables
     616            1 :         auto const &afnZoneInfo = state.dataRoomAir->AFNZoneInfo(zoneNum);
     617              : 
     618            1 :         if (!afnZoneInfo.IsUsed) return;
     619              : 
     620            1 :         if (!state.dataGlobal->ZoneSizingCalc) SumSystemDepResponseForNode(state, zoneNum);
     621              : 
     622              :         // Update return node conditions
     623            2 :         for (int I = 1; I <= state.dataZoneEquip->ZoneEquipList(zoneNum).NumOfEquipTypes; ++I) { // loop over all equip types
     624            1 :             Real64 SumMass = 0.0;
     625            1 :             Real64 SumMassT = 0.0;
     626            1 :             Real64 SumMassW = 0.0;
     627            1 :             int RetNodeNum = 0;
     628            3 :             for (auto const &afnNode : afnZoneInfo.Node) {
     629            4 :                 for (auto const &afnHVAC : afnNode.HVAC) {
     630            2 :                     if (afnHVAC.EquipConfigIndex == I && afnHVAC.SupNodeNum > 0 && afnHVAC.RetNodeNum > 0) {
     631            2 :                         Real64 NodeMass = state.dataLoopNodes->Node(afnHVAC.SupNodeNum).MassFlowRate * afnHVAC.ReturnFraction;
     632            2 :                         SumMass += NodeMass;
     633            2 :                         SumMassT += NodeMass * afnNode.AirTemp;
     634            2 :                         SumMassW += NodeMass * afnNode.HumRat;
     635            2 :                         RetNodeNum = afnHVAC.RetNodeNum;
     636              :                     }
     637              :                 }
     638              :             }
     639            1 :             if (SumMass > 0.0) {
     640            1 :                 state.dataLoopNodes->Node(RetNodeNum).Temp = SumMassT / SumMass;
     641            1 :                 state.dataLoopNodes->Node(RetNodeNum).HumRat = SumMassW / SumMass;
     642              :             }
     643              :         }
     644              :     } // UpdateRoomAirModelAirflowNetwork
     645              : 
     646            3 :     void CalcNodeSums(EnergyPlusData &state, int const zoneNum, int const roomAirNodeNum)
     647              :     {
     648              : 
     649              :         // SUBROUTINE INFORMATION:
     650              :         //       AUTHOR         B Griffith
     651              :         //       DATE WRITTEN   August 2009
     652              :         //       MODIFIED       Lixing Gu, Aug. 2015 for v8.4 replease
     653              :         //       RE - ENGINEERED  na
     654              : 
     655              :         // PURPOSE OF THIS SUBROUTINE :
     656              :         // This subroutine calculates the various sums that go into the zone heat balance
     657              :         // equation.This replaces the SUMC, SUMHA, and SUMHAT calculations that were
     658              :         // previously done in various places throughout the program.
     659              :         // The SumHAT portion of the code is reproduced in RadiantSystemHighTemp and
     660              :         // RadiantSystemLowTemp and should be updated accordingly.
     661              :         //
     662              :         // A reference temperature(Tref) is specified for use with the ceiling diffuser
     663              :         // convection correlation.A bogus value of Tref = -999.9 defaults to using
     664              :         // the zone air(i.e.outlet) temperature for the reference temperature.
     665              :         // If Tref is applied to all surfaces, SumHA = 0, and SumHATref /= 0.
     666              :         // If Tref is not used at all, SumHATref = 0, and SumHA /= 0.
     667              :         //
     668              : 
     669              :         // USE STATEMENTS:
     670              :         using InternalHeatGains::SumInternalConvectionGainsByIndices;
     671              :         using InternalHeatGains::SumInternalLatentGainsByIndices;
     672              :         using InternalHeatGains::SumReturnAirConvectionGainsByIndices;
     673              :         using InternalHeatGains::SumReturnAirConvectionGainsByTypes;
     674              :         using Psychrometrics::PsyCpAirFnW;
     675              :         using Psychrometrics::PsyRhoAirFnPbTdbW;
     676              : 
     677              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     678              :         Real64 HA;         //                     !Hc*Area
     679              :         Real64 Area;       //                   !Effective surface area
     680              :         Real64 RefAirTemp; //             !Reference air temperature for surface convection calculations
     681              :         bool Found;        //
     682              : 
     683            3 :         Real64 SumIntGain = 0.0; // node sum of convective internal gains
     684            3 :         Real64 SumHA = 0.0;      // Zone sum of Hc*Area
     685            3 :         Real64 SumHATsurf = 0.0; // Zone sum of Hc*Area*Tsurf
     686            3 :         Real64 SumHATref = 0.0;  // Zone sum of Hc*Area*Tref, for ceiling diffuser convection correlation
     687            3 :         Real64 SumSysMCp = 0.0;  // Zone sum of air system MassFlowRate*Cp
     688            3 :         Real64 SumSysMCpT = 0.0; // Zone sum of air system MassFlowRate*Cp*T
     689            3 :         Real64 SumSysM = 0.0;    // Zone sum of air system MassFlowRate
     690            3 :         Real64 SumSysMW = 0.0;   // Zone sum of air system MassFlowRate*W
     691              : 
     692            3 :         auto const &zone = state.dataHeatBal->Zone(zoneNum);
     693            3 :         auto &afnZoneInfo = state.dataRoomAir->AFNZoneInfo(zoneNum);
     694            3 :         auto &afnNode = afnZoneInfo.Node(roomAirNodeNum);
     695              :         // Sum all convective internal gains: SumIntGain
     696            6 :         afnNode.SumIntSensibleGain = SumInternalConvectionGainsByIndices(
     697            3 :             state, afnNode.NumIntGains, afnNode.intGainsDeviceSpaces, afnNode.IntGainsDeviceIndices, afnNode.IntGainsFractions);
     698              : 
     699            6 :         afnNode.SumIntLatentGain = SumInternalLatentGainsByIndices(
     700            3 :             state, afnNode.NumIntGains, afnNode.intGainsDeviceSpaces, afnNode.IntGainsDeviceIndices, afnNode.IntGainsFractions);
     701              :         // Add heat to return air if zonal system(no return air) or cycling system(return air frequently very low or zero)
     702            3 :         if (state.dataHeatBal->Zone(zoneNum).NoHeatToReturnAir) {
     703              :             // *******************************************
     704            0 :             SumIntGain = SumReturnAirConvectionGainsByIndices(
     705            0 :                 state, afnNode.NumIntGains, afnNode.intGainsDeviceSpaces, afnNode.IntGainsDeviceIndices, afnNode.IntGainsFractions);
     706            0 :             afnNode.SumIntSensibleGain += SumIntGain;
     707              :         }
     708              : 
     709              :         // Check to see if this is a controlled zone
     710              :         // Check to see if this is a plenum zone
     711            3 :         int zoneRetPlenumNum = 0;
     712            3 :         for (int iPlenum = 1; iPlenum <= state.dataZonePlenum->NumZoneReturnPlenums; ++iPlenum) {
     713            0 :             if (state.dataZonePlenum->ZoneRetPlenCond(iPlenum).ActualZoneNum != zoneNum) continue;
     714            0 :             zoneRetPlenumNum = iPlenum;
     715            0 :             break;
     716              :         }
     717            3 :         bool zoneSupPlenumNum = false;
     718            3 :         for (int iPlenum = 1; iPlenum <= state.dataZonePlenum->NumZoneSupplyPlenums; ++iPlenum) {
     719            0 :             if (state.dataZonePlenum->ZoneSupPlenCond(iPlenum).ActualZoneNum != zoneNum) continue;
     720            0 :             zoneSupPlenumNum = iPlenum;
     721            0 :             break;
     722              :         }
     723              : 
     724              :         // Plenum and controlled zones have a different set of inlet nodes which must be calculated.
     725            3 :         auto &zoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum);
     726            3 :         if (zone.IsControlled) {
     727            3 :             auto &zoneEquipConfig = state.dataZoneEquip->ZoneEquipConfig(zoneNum);
     728            6 :             for (int iNode = 1; iNode <= zoneEquipConfig.NumInletNodes; ++iNode) {
     729              :                 // Get node conditions
     730              :                 // this next block is of interest to irratic system loads... maybe nodes are not accurate at time of call ?
     731              :                 // how can we tell ? predict step must be lagged ? correct step, systems have run.
     732            3 :                 auto const &inletNode = state.dataLoopNodes->Node(zoneEquipConfig.InletNode(iNode));
     733            6 :                 for (auto const &afnHVAC : afnNode.HVAC) {
     734            3 :                     if (afnHVAC.SupNodeNum == zoneEquipConfig.InletNode(iNode)) {
     735            3 :                         Real64 MassFlowRate = inletNode.MassFlowRate * afnHVAC.SupplyFraction;
     736            3 :                         Real64 CpAir = PsyCpAirFnW(zoneHB.airHumRat);
     737            3 :                         SumSysMCp += MassFlowRate * CpAir;
     738            3 :                         SumSysMCpT += MassFlowRate * CpAir * inletNode.Temp;
     739            3 :                         SumSysM += MassFlowRate;
     740            3 :                         SumSysMW += MassFlowRate * inletNode.HumRat;
     741              :                     }
     742              :                 } // EquipLoop
     743              :             }     // NodeNum
     744            0 :         } else if (zoneRetPlenumNum != 0) {
     745            0 :             auto const &zoneRetPlenum = state.dataZonePlenum->ZoneRetPlenCond(zoneRetPlenumNum);
     746            0 :             for (int iNode = 1; iNode <= zoneRetPlenum.NumInletNodes; ++iNode) {
     747              :                 // Get node conditions
     748            0 :                 auto const &zoneRetPlenumNode = state.dataLoopNodes->Node(zoneRetPlenum.InletNode(iNode));
     749            0 :                 Real64 CpAir = PsyCpAirFnW(zoneHB.airHumRat);
     750            0 :                 SumSysMCp += zoneRetPlenumNode.MassFlowRate * CpAir;
     751            0 :                 SumSysMCpT += zoneRetPlenumNode.MassFlowRate * CpAir * zoneRetPlenumNode.Temp;
     752              :             } // NodeNum
     753              :             // add in the leaks
     754            0 :             for (int iADU = 1; iADU <= zoneRetPlenum.NumADUs; ++iADU) {
     755            0 :                 int ADUNum = zoneRetPlenum.ADUIndex(iADU);
     756            0 :                 auto const &adu = state.dataDefineEquipment->AirDistUnit(ADUNum);
     757            0 :                 if (adu.UpStreamLeak) {
     758            0 :                     Real64 CpAir = PsyCpAirFnW(zoneHB.airHumRat);
     759            0 :                     SumSysMCp += adu.MassFlowRateUpStrLk * CpAir;
     760            0 :                     SumSysMCpT += adu.MassFlowRateUpStrLk * CpAir * state.dataLoopNodes->Node(adu.InletNodeNum).Temp;
     761              :                 }
     762            0 :                 if (adu.DownStreamLeak) {
     763            0 :                     Real64 CpAir = PsyCpAirFnW(zoneHB.airHumRat);
     764            0 :                     SumSysMCp += adu.MassFlowRateDnStrLk * CpAir;
     765            0 :                     SumSysMCpT += adu.MassFlowRateDnStrLk * CpAir * state.dataLoopNodes->Node(adu.OutletNodeNum).Temp;
     766              :                 }
     767              :             } // ADUListIndex
     768            0 :         } else if (zoneSupPlenumNum != 0) {
     769              :             // Get node conditions
     770            0 :             auto const &zoneSupPlenum = state.dataZonePlenum->ZoneSupPlenCond(zoneSupPlenumNum);
     771            0 :             auto const &inletNode = state.dataLoopNodes->Node(zoneSupPlenum.InletNode);
     772            0 :             Real64 CpAir = PsyCpAirFnW(zoneHB.airHumRat);
     773            0 :             SumSysMCp += inletNode.MassFlowRate * CpAir;
     774            0 :             SumSysMCpT += inletNode.MassFlowRate * CpAir * inletNode.Temp;
     775              :         }
     776              : 
     777            3 :         int ZoneMult = zone.Multiplier * zone.ListMultiplier;
     778              : 
     779            3 :         SumSysMCp /= ZoneMult;
     780            3 :         SumSysMCpT /= ZoneMult;
     781            3 :         SumSysM /= ZoneMult;
     782            3 :         SumSysMW /= ZoneMult;
     783              : 
     784              :         // Sum all surface convection : SumHA, SumHATsurf, SumHATref(and additional contributions to SumIntGain)
     785              :         // Modified by Gu to include assigned surfaces only shown in the surface lsit
     786            3 :         if (!afnNode.HasSurfacesAssigned) return;
     787              : 
     788            3 :         int surfCount = 0;
     789            6 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
     790            3 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
     791            9 :             for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
     792            6 :                 ++surfCount;
     793            6 :                 if (afnZoneInfo.ControlAirNodeID == roomAirNodeNum) {
     794            2 :                     Found = false;
     795            5 :                     for (int Loop = 1; Loop <= afnZoneInfo.NumOfAirNodes; ++Loop) {
     796            4 :                         if (Loop != roomAirNodeNum) {
     797            2 :                             if (afnZoneInfo.Node(Loop).SurfMask(surfCount)) {
     798            1 :                                 Found = true;
     799            1 :                                 break;
     800              :                             }
     801              :                         }
     802              :                     }
     803            2 :                     if (Found) continue;
     804              :                 } else {
     805            4 :                     if (!afnNode.SurfMask(surfCount)) continue;
     806              :                 }
     807              : 
     808            3 :                 HA = 0.0;
     809            3 :                 Area = state.dataSurface->Surface(SurfNum).Area; // For windows, this is the glazing area
     810              : 
     811            3 :                 if (state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window) {
     812              : 
     813              :                     // Add to the convective internal gains
     814            0 :                     if (ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(SurfNum))) {
     815              :                         // The shade area covers the area of the glazing plus the area of the dividers.
     816            0 :                         Area += state.dataSurface->SurfWinDividerArea(SurfNum);
     817            0 :                         SumIntGain += state.dataSurface->SurfWinDividerHeatGain(SurfNum);
     818              :                     }
     819              : 
     820              :                     // Convective heat gain from natural convection in gap between glass and interior shade or blind
     821            0 :                     if (ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(SurfNum)))
     822            0 :                         SumIntGain += state.dataSurface->SurfWinConvHeatFlowNatural(SurfNum);
     823              : 
     824              :                     // Convective heat gain from airflow window
     825            0 :                     if (state.dataSurface->SurfWinAirflowThisTS(SurfNum) > 0.0) {
     826            0 :                         SumIntGain += state.dataSurface->SurfWinConvHeatGainToZoneAir(SurfNum);
     827            0 :                         if (zone.NoHeatToReturnAir) {
     828            0 :                             SumIntGain += state.dataSurface->SurfWinRetHeatGainToZoneAir(SurfNum);
     829            0 :                             state.dataSurface->SurfWinHeatGain(SurfNum) += state.dataSurface->SurfWinRetHeatGainToZoneAir(SurfNum);
     830            0 :                             if (state.dataSurface->SurfWinHeatGain(SurfNum) >= 0.0) {
     831            0 :                                 state.dataSurface->SurfWinHeatGainRep(SurfNum) = state.dataSurface->SurfWinHeatGain(SurfNum);
     832            0 :                                 state.dataSurface->SurfWinHeatGainRepEnergy(SurfNum) =
     833            0 :                                     state.dataSurface->SurfWinHeatGainRep(SurfNum) * state.dataGlobal->TimeStepZone * Constant::rSecsInHour;
     834              :                             } else {
     835            0 :                                 state.dataSurface->SurfWinHeatLossRep(SurfNum) = -state.dataSurface->SurfWinHeatGain(SurfNum);
     836            0 :                                 state.dataSurface->SurfWinHeatLossRepEnergy(SurfNum) =
     837            0 :                                     state.dataSurface->SurfWinHeatLossRep(SurfNum) * state.dataGlobal->TimeStepZone * Constant::rSecsInHour;
     838              :                             }
     839            0 :                             state.dataSurface->SurfWinHeatTransferRepEnergy(SurfNum) =
     840            0 :                                 state.dataSurface->SurfWinHeatGain(SurfNum) * state.dataGlobal->TimeStepZone * Constant::rSecsInHour;
     841              :                         }
     842              :                     }
     843              : 
     844              :                     // Add to the surface convection sums
     845            0 :                     if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) {
     846              :                         // Window frame contribution
     847            0 :                         SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinFrameArea(SurfNum) *
     848            0 :                                       (1.0 + state.dataSurface->SurfWinProjCorrFrIn(SurfNum)) * state.dataSurface->SurfWinFrameTempIn(SurfNum);
     849            0 :                         HA += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinFrameArea(SurfNum) *
     850            0 :                               (1.0 + state.dataSurface->SurfWinProjCorrFrIn(SurfNum));
     851              :                     }
     852              : 
     853            0 :                     if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0 &&
     854            0 :                         !ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(SurfNum))) {
     855              :                         // Window divider contribution(only from shade or blind for window with divider and interior shade or blind)
     856            0 :                         SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinDividerArea(SurfNum) *
     857            0 :                                       (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) *
     858            0 :                                       state.dataSurface->SurfWinDividerTempIn(SurfNum);
     859            0 :                         HA += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinDividerArea(SurfNum) *
     860            0 :                               (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivIn(SurfNum));
     861              :                     }
     862              : 
     863              :                 } // End of check if window
     864              : 
     865            3 :                 HA += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * Area;
     866            3 :                 SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * Area * state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
     867              : 
     868            3 :                 if (state.dataSurface->SurfTAirRef(SurfNum) == DataSurfaces::RefAirTemp::ZoneMeanAirTemp) {
     869              :                     // The zone air is the reference temperature(which is to be solved for in CorrectZoneAirTemp).
     870            3 :                     RefAirTemp = zoneHB.MAT;
     871            3 :                     SumHA += HA;
     872            0 :                 } else if (state.dataSurface->SurfTAirRef(SurfNum) == DataSurfaces::RefAirTemp::AdjacentAirTemp) {
     873            0 :                     RefAirTemp = state.dataHeatBal->SurfTempEffBulkAir(SurfNum);
     874            0 :                     SumHATref += HA * RefAirTemp;
     875            0 :                 } else if (state.dataSurface->SurfTAirRef(SurfNum) == DataSurfaces::RefAirTemp::ZoneSupplyAirTemp) {
     876              :                     // check whether this zone is a controlled zone or not
     877            0 :                     if (!zone.IsControlled) {
     878            0 :                         ShowFatalError(state,
     879            0 :                                        format("Zones must be controlled for Ceiling-Diffuser Convection model. No system serves zone {}", zone.Name));
     880            0 :                         return;
     881              :                     }
     882              :                     // determine supply air temperature as a weighted average of the inlet temperatures.
     883            0 :                     RefAirTemp = SumSysMCpT / SumSysMCp;
     884            0 :                     SumHATref += HA * RefAirTemp;
     885              :                 } else {
     886            0 :                     RefAirTemp = zoneHB.MAT;
     887            0 :                     SumHA += HA;
     888              :                 }
     889              : 
     890              :             } // SurfNum
     891              :         }
     892              :         // Assemble values
     893            3 :         afnNode.SumHA = SumHA;
     894            3 :         afnNode.SumHATsurf = SumHATsurf;
     895            3 :         afnNode.SumHATref = SumHATref;
     896            3 :         afnNode.SumSysMCp = SumSysMCp;
     897            3 :         afnNode.SumSysMCpT = SumSysMCpT;
     898            3 :         afnNode.SumSysM = SumSysM;
     899            3 :         afnNode.SumSysMW = SumSysMW;
     900              : 
     901              :     } // CalcNodeSums
     902              : 
     903            3 :     void CalcSurfaceMoistureSums(EnergyPlusData &state,
     904              :                                  int const zoneNum,
     905              :                                  int const roomAirNodeNum,
     906              :                                  Real64 &SumHmAW,
     907              :                                  Real64 &SumHmARa,
     908              :                                  Real64 &SumHmARaW,
     909              :                                  [[maybe_unused]] Array1D<bool> const &SurfMask)
     910              :     {
     911              : 
     912              :         // SUBROUTINE INFORMATION:
     913              :         //       AUTHOR         B Griffith
     914              :         //                      derived from P. Biddulph-- HAMT, L. Gu -- EPMD,
     915              :         //       DATE WRITTEN   November 2009
     916              :         //       MODIFIED       Lixing Gu, Aug. 2015 for v8.4 replease
     917              : 
     918              :         // PURPOSE OF THIS SUBROUTINE:
     919              :         // Breakout summation of surface moisture interaction terms
     920              : 
     921              :         // Using/Aliasing
     922              : 
     923              :         using HeatBalanceHAMTManager::UpdateHeatBalHAMT;
     924              :         using MoistureBalanceEMPDManager::UpdateMoistureBalanceEMPD;
     925              :         using Psychrometrics::PsyRhFnTdbRhov;
     926              :         using Psychrometrics::PsyRhFnTdbRhovLBnd0C;
     927              :         using Psychrometrics::PsyRhoAirFnPbTdbW;
     928              :         using Psychrometrics::PsyWFnTdbRhPb;
     929              : 
     930            3 :         SumHmAW = 0.0;
     931            3 :         SumHmARa = 0.0;
     932            3 :         SumHmARaW = 0.0;
     933              : 
     934            3 :         auto &afnZoneInfo = state.dataRoomAir->AFNZoneInfo(zoneNum);
     935              : 
     936            3 :         int surfCount = 1;
     937            6 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
     938            3 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
     939            9 :             for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum, ++surfCount) {
     940            6 :                 auto const &surf = state.dataSurface->Surface(SurfNum);
     941            6 :                 if (surf.Class == SurfaceClass::Window) continue;
     942              : 
     943            6 :                 if (afnZoneInfo.ControlAirNodeID == roomAirNodeNum) {
     944            2 :                     bool Found = false;
     945            6 :                     for (int Loop = 1; Loop <= afnZoneInfo.NumOfAirNodes && !Found; ++Loop) {
     946              :                         // None - assigned surfaces belong to the zone node
     947            4 :                         Found = (Loop != roomAirNodeNum) && afnZoneInfo.Node(Loop).SurfMask(surfCount);
     948              :                     }
     949            2 :                     if (Found) continue;
     950              :                 } else {
     951            4 :                     if (!afnZoneInfo.Node(roomAirNodeNum).SurfMask(surfCount)) continue;
     952              :                 }
     953              : 
     954            3 :                 auto const &HMassConvInFD = state.dataMstBal->HMassConvInFD(SurfNum);
     955            3 :                 auto &RhoVaporSurfIn = state.dataMstBal->RhoVaporSurfIn(SurfNum);
     956            3 :                 auto &RhoVaporAirIn = state.dataMstBal->RhoVaporAirIn(SurfNum);
     957            3 :                 if (surf.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
     958            0 :                     UpdateHeatBalHAMT(state, SurfNum);
     959              : 
     960            0 :                     SumHmAW += HMassConvInFD * surf.Area * (RhoVaporSurfIn - RhoVaporAirIn);
     961              : 
     962            0 :                     Real64 RhoAirZone = PsyRhoAirFnPbTdbW(
     963              :                         state,
     964            0 :                         state.dataEnvrn->OutBaroPress,
     965            0 :                         state.dataZoneTempPredictorCorrector->zoneHeatBalance(surf.Zone).MAT,
     966            0 :                         PsyRhFnTdbRhov(state,
     967            0 :                                        state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataSurface->Surface(SurfNum).Zone).MAT,
     968              :                                        RhoVaporAirIn,
     969              :                                        "RhoAirZone"));
     970              : 
     971            0 :                     Real64 Wsurf = PsyWFnTdbRhPb(state,
     972            0 :                                                  state.dataHeatBalSurf->SurfTempInTmp(SurfNum),
     973            0 :                                                  PsyRhFnTdbRhov(state, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), RhoVaporSurfIn, "Wsurf"),
     974            0 :                                                  state.dataEnvrn->OutBaroPress);
     975              : 
     976            0 :                     SumHmARa += HMassConvInFD * surf.Area * RhoAirZone;
     977            0 :                     SumHmARaW += HMassConvInFD * surf.Area * RhoAirZone * Wsurf;
     978              :                 }
     979              : 
     980            3 :                 else if (surf.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
     981              : 
     982            3 :                     UpdateMoistureBalanceEMPD(state, SurfNum);
     983            3 :                     RhoVaporSurfIn = state.dataMstBalEMPD->RVSurface(SurfNum);
     984              : 
     985            3 :                     SumHmAW += HMassConvInFD * surf.Area * (RhoVaporSurfIn - RhoVaporAirIn);
     986            3 :                     SumHmARa +=
     987            6 :                         HMassConvInFD * surf.Area *
     988            6 :                         PsyRhoAirFnPbTdbW(state,
     989            3 :                                           state.dataEnvrn->OutBaroPress,
     990            3 :                                           state.dataHeatBalSurf->SurfTempInTmp(SurfNum),
     991            3 :                                           PsyWFnTdbRhPb(state,
     992            3 :                                                         state.dataHeatBalSurf->SurfTempInTmp(SurfNum),
     993            3 :                                                         PsyRhFnTdbRhovLBnd0C(state, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), RhoVaporAirIn),
     994            3 :                                                         state.dataEnvrn->OutBaroPress));
     995            3 :                     SumHmARaW += HMassConvInFD * surf.Area * RhoVaporSurfIn;
     996              :                 }
     997              :             } // for (SurfNum)
     998              :         }     // for (spaceNum)
     999              : 
    1000            3 :     } // CalcSurfaceMoistureSums
    1001              : 
    1002            3 :     void SumNonAirSystemResponseForNode(EnergyPlusData &state, int const zoneNum, int const roomAirNodeNum)
    1003              :     {
    1004              : 
    1005              :         // SUBROUTINE INFORMATION:
    1006              :         //       AUTHOR         B. Griffith
    1007              :         //       DATE WRITTEN   June 2012
    1008              :         //       MODIFIED       Lixing Gu, Aug. 2015 for v8.4 replease
    1009              : 
    1010              :         // PURPOSE OF THIS SUBROUTINE:
    1011              :         // Sum system response from none air systems
    1012              : 
    1013              :         // USE STATEMENTS:
    1014              :         using BaseboardElectric::SimElectricBaseboard;
    1015              :         using BaseboardRadiator::SimBaseboard;
    1016              :         using ElectricBaseboardRadiator::SimElecBaseboard;
    1017              :         using HighTempRadiantSystem::SimHighTempRadiantSystem;
    1018              :         using HWBaseboardRadiator::SimHWBaseboard;
    1019              :         using RefrigeratedCase::SimAirChillerSet;
    1020              :         using SteamBaseboardRadiator::SimSteamBaseboard;
    1021              : 
    1022              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1023              :         Real64 SysOutputProvided;
    1024              :         Real64 LatOutputProvided;
    1025              : 
    1026              :         // TODO
    1027            3 :         auto &afnZoneInfo = state.dataRoomAir->AFNZoneInfo(zoneNum);
    1028            3 :         auto &afnNode = afnZoneInfo.Node(roomAirNodeNum);
    1029              : 
    1030            3 :         afnNode.NonAirSystemResponse = 0.0;
    1031              : 
    1032            3 :         if (!allocated(state.dataZoneEquip->ZoneEquipConfig)) return;
    1033              : 
    1034            6 :         for (auto &afnHVAC : afnNode.HVAC) {
    1035            3 :             switch (afnHVAC.zoneEquipType) {
    1036              : 
    1037            0 :             case DataZoneEquipment::ZoneEquipType::BaseboardWater: {
    1038              :                 //'ZoneHVAC:Baseboard:RadiantConvective:Water' 13
    1039            0 :                 SimHWBaseboard(state, afnHVAC.Name, zoneNum, false, SysOutputProvided, afnHVAC.CompIndex);
    1040            0 :                 afnNode.NonAirSystemResponse += afnHVAC.SupplyFraction * SysOutputProvided;
    1041              :                 // LatOutputProvided = 0.0d0 !This baseboard does not add / remove any latent heat
    1042            0 :             } break;
    1043              : 
    1044            0 :             case DataZoneEquipment::ZoneEquipType::BaseboardSteam: {
    1045              :                 // CASE(BBSteam_Num) !'ZoneHVAC:Baseboard:RadiantConvective:Steam' 14
    1046            0 :                 SimSteamBaseboard(state, afnHVAC.Name, zoneNum, false, SysOutputProvided, afnHVAC.CompIndex);
    1047              : 
    1048            0 :                 afnNode.NonAirSystemResponse += afnHVAC.SupplyFraction * SysOutputProvided;
    1049              :                 // LatOutputProvided = 0.0d0 !This baseboard does not add / remove any latent heat
    1050            0 :             } break;
    1051              : 
    1052            0 :             case DataZoneEquipment::ZoneEquipType::BaseboardConvectiveWater: {
    1053              :                 // CASE(BBWaterConvective_Num)  !'ZoneHVAC:Baseboard:Convective:Water' 16
    1054            0 :                 SimBaseboard(state, afnHVAC.Name, zoneNum, false, SysOutputProvided, afnHVAC.CompIndex);
    1055            0 :                 afnNode.NonAirSystemResponse += afnHVAC.SupplyFraction * SysOutputProvided;
    1056              :                 // LatOutputProvided = 0.0d0 !This baseboard does not add / remove any latent heat
    1057            0 :             } break;
    1058              : 
    1059            0 :             case DataZoneEquipment::ZoneEquipType::BaseboardConvectiveElectric: {
    1060              :                 // CASE(BBElectricConvective_Num)  !'ZoneHVAC:Baseboard:Convective:Electric' 15
    1061            0 :                 SimElectricBaseboard(state, afnHVAC.Name, zoneNum, SysOutputProvided, afnHVAC.CompIndex);
    1062            0 :                 afnNode.NonAirSystemResponse += afnHVAC.SupplyFraction * SysOutputProvided;
    1063              :                 // LatOutputProvided = 0.0d0 !This baseboard does not add / remove any latent heat
    1064            0 :             } break;
    1065              : 
    1066            0 :             case DataZoneEquipment::ZoneEquipType::RefrigerationChillerSet: {
    1067              :                 // CASE(RefrigerationAirChillerSet_Num)  !'ZoneHVAC:RefrigerationChillerSet' 20
    1068            0 :                 SimAirChillerSet(state, afnHVAC.Name, zoneNum, false, SysOutputProvided, LatOutputProvided, afnHVAC.CompIndex);
    1069            0 :                 afnNode.NonAirSystemResponse += afnHVAC.SupplyFraction * SysOutputProvided;
    1070            0 :             } break;
    1071              : 
    1072            0 :             case DataZoneEquipment::ZoneEquipType::BaseboardElectric: {
    1073              :                 // CASE(BBElectric_Num)  !'ZoneHVAC:Baseboard:RadiantConvective:Electric' 12
    1074            0 :                 SimElecBaseboard(state, afnHVAC.Name, zoneNum, false, SysOutputProvided, afnHVAC.CompIndex);
    1075            0 :                 afnNode.NonAirSystemResponse += afnHVAC.SupplyFraction * SysOutputProvided;
    1076              :                 // LatOutputProvided = 0.0d0 !This baseboard does not add / remove any latent heat
    1077            0 :             } break;
    1078              : 
    1079            0 :             case DataZoneEquipment::ZoneEquipType::HighTemperatureRadiant: {
    1080              :                 // CASE(BBElectric_Num)  !'ZoneHVAC:HighTemperatureRadiant' 17
    1081            0 :                 SimHighTempRadiantSystem(state, afnHVAC.Name, false, SysOutputProvided, afnHVAC.CompIndex);
    1082            0 :                 afnNode.NonAirSystemResponse += afnHVAC.SupplyFraction * SysOutputProvided;
    1083              :                 // LatOutputProvided = 0.0d0 !This baseboard does not add / remove any latent heat
    1084            0 :             } break;
    1085              : 
    1086            3 :             default: {
    1087            3 :             } break;
    1088              :             } // switch
    1089              : 
    1090              :             // Zone sum of system convective gains, collected via NonAirSystemResponse
    1091              :         }
    1092              : 
    1093              :     } // SumNonAirSystemResponseForNode
    1094              : 
    1095              :     //*****************************************************************************************
    1096              : 
    1097            1 :     void SumSystemDepResponseForNode(EnergyPlusData &state, int const zoneNum)
    1098              :     {
    1099              :         // SUBROUTINE INFORMATION:
    1100              :         //       AUTHOR         B.Griffith
    1101              :         //       DATE WRITTEN   aug 2005, Jan2004
    1102              :         //       MODIFIED       Lixing Gu, Aug. 2015 for v8.4 replease
    1103              : 
    1104              :         // PURPOSE OF THIS SUBROUTINE:
    1105              :         // Sum system sensible loads used at the next time step
    1106              : 
    1107              :         // USE STATEMENTS:
    1108              :         using ZoneDehumidifier::SimZoneDehumidifier;
    1109              : 
    1110              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1111              :         Real64 LatOutputProvided;
    1112              : 
    1113              :         // TODO
    1114              : 
    1115            1 :         auto &afnZoneInfo = state.dataRoomAir->AFNZoneInfo(zoneNum);
    1116              : 
    1117              :         // SysDepZoneLoads saved to be added to zone heat balance next
    1118            1 :         Real64 SysOutputProvided = 0.0;
    1119            3 :         for (auto &afnNode : afnZoneInfo.Node) {
    1120            2 :             afnNode.SysDepZoneLoadsLaggedOld = 0.0;
    1121            4 :             for (auto &afnHVAC : afnNode.HVAC) {
    1122            2 :                 if (afnHVAC.zoneEquipType == DataZoneEquipment::ZoneEquipType::DehumidifierDX) {
    1123            0 :                     if (SysOutputProvided == 0.0)
    1124            0 :                         SimZoneDehumidifier(state, afnHVAC.Name, zoneNum, false, SysOutputProvided, LatOutputProvided, afnHVAC.CompIndex);
    1125            0 :                     if (SysOutputProvided > 0.0) break;
    1126              :                 }
    1127              :             }
    1128              :         }
    1129              : 
    1130            1 :         if (SysOutputProvided > 0.0) {
    1131            0 :             for (auto &afnNode : afnZoneInfo.Node) {
    1132            0 :                 for (auto const &afnHVAC : afnNode.HVAC) {
    1133            0 :                     if (afnHVAC.zoneEquipType == DataZoneEquipment::ZoneEquipType::DehumidifierDX) {
    1134            0 :                         afnNode.SysDepZoneLoadsLaggedOld += afnHVAC.SupplyFraction * SysOutputProvided;
    1135              :                     }
    1136              :                 }
    1137              :             }
    1138              :         }
    1139              : 
    1140            1 :     } // SumSystemDepResponseForNode
    1141              : 
    1142              :     //*****************************************************************************************
    1143              : 
    1144              : } // namespace RoomAir
    1145              : 
    1146              : } // namespace EnergyPlus
        

Generated by: LCOV version 2.0-1