LCOV - code coverage report
Current view: top level - EnergyPlus - VentilatedSlab.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 20.7 % 2279 471
Test Date: 2025-06-02 12:03:30 Functions: 38.5 % 13 5

            Line data    Source code
       1              : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
       2              : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3              : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4              : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5              : // contributors. All rights reserved.
       6              : //
       7              : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8              : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9              : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10              : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11              : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12              : //
      13              : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14              : // provided that the following conditions are met:
      15              : //
      16              : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17              : //     conditions and the following disclaimer.
      18              : //
      19              : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20              : //     conditions and the following disclaimer in the documentation and/or other materials
      21              : //     provided with the distribution.
      22              : //
      23              : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24              : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25              : //     used to endorse or promote products derived from this software without specific prior
      26              : //     written permission.
      27              : //
      28              : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29              : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30              : //     reference solely to the software portion of its product, Licensee must refer to the
      31              : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32              : //     obtained under this License and may not use a different name for the software. Except as
      33              : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34              : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35              : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36              : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37              : //
      38              : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39              : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40              : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41              : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42              : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43              : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44              : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45              : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46              : // POSSIBILITY OF SUCH DAMAGE.
      47              : 
      48              : // C++ Headers
      49              : #include <cmath>
      50              : 
      51              : // ObjexxFCL Headers
      52              : #include <ObjexxFCL/Array.functions.hh>
      53              : 
      54              : // EnergyPlus Headers
      55              : #include <EnergyPlus/Autosizing/CoolingAirFlowSizing.hh>
      56              : #include <EnergyPlus/Autosizing/CoolingCapacitySizing.hh>
      57              : #include <EnergyPlus/Autosizing/HeatingAirFlowSizing.hh>
      58              : #include <EnergyPlus/Autosizing/HeatingCapacitySizing.hh>
      59              : #include <EnergyPlus/Autosizing/SystemAirFlowSizing.hh>
      60              : #include <EnergyPlus/BranchNodeConnections.hh>
      61              : #include <EnergyPlus/Construction.hh>
      62              : #include <EnergyPlus/Data/EnergyPlusData.hh>
      63              : #include <EnergyPlus/DataAirSystems.hh>
      64              : #include <EnergyPlus/DataEnvironment.hh>
      65              : #include <EnergyPlus/DataHVACGlobals.hh>
      66              : #include <EnergyPlus/DataHeatBalFanSys.hh>
      67              : #include <EnergyPlus/DataHeatBalSurface.hh>
      68              : #include <EnergyPlus/DataHeatBalance.hh>
      69              : #include <EnergyPlus/DataIPShortCuts.hh>
      70              : #include <EnergyPlus/DataLoopNode.hh>
      71              : #include <EnergyPlus/DataSizing.hh>
      72              : #include <EnergyPlus/DataSurfaceLists.hh>
      73              : #include <EnergyPlus/DataSurfaces.hh>
      74              : #include <EnergyPlus/DataZoneEquipment.hh>
      75              : #include <EnergyPlus/Fans.hh>
      76              : #include <EnergyPlus/FluidProperties.hh>
      77              : #include <EnergyPlus/General.hh>
      78              : #include <EnergyPlus/GeneralRoutines.hh>
      79              : #include <EnergyPlus/HVACHXAssistedCoolingCoil.hh>
      80              : #include <EnergyPlus/HeatBalanceSurfaceManager.hh>
      81              : #include <EnergyPlus/HeatingCoils.hh>
      82              : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      83              : #include <EnergyPlus/NodeInputManager.hh>
      84              : #include <EnergyPlus/OutAirNodeManager.hh>
      85              : #include <EnergyPlus/OutputProcessor.hh>
      86              : #include <EnergyPlus/PlantUtilities.hh>
      87              : #include <EnergyPlus/Psychrometrics.hh>
      88              : #include <EnergyPlus/ScheduleManager.hh>
      89              : #include <EnergyPlus/SteamCoils.hh>
      90              : #include <EnergyPlus/UtilityRoutines.hh>
      91              : #include <EnergyPlus/VentilatedSlab.hh>
      92              : #include <EnergyPlus/WaterCoils.hh>
      93              : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
      94              : 
      95              : namespace EnergyPlus {
      96              : 
      97              : namespace VentilatedSlab {
      98              : 
      99              :     // Module containing the routines dealing with the Ventilated Slab
     100              : 
     101              :     // MODULE INFORMATION:
     102              :     //       AUTHOR         Young Tae Chae, Rick Strand
     103              :     //       DATE WRITTEN   June 2008
     104              : 
     105              :     // PURPOSE OF THIS MODULE:
     106              :     // Simulate Ventilated Slab Systems.
     107              : 
     108              :     // METHODOLOGY EMPLOYED:
     109              :     // Systems are modeled as a collection of components: radiant panel, outside air mixer,
     110              :     // fan, heating coil and/or cooling coil plus an integrated control
     111              :     // algorithm that adjusts the hot or cold water flow to meet the setpoint
     112              :     // condition.  Outside air mixing is handled locally as either fixed percent
     113              :     // or as attempting to meet a prescribed mixed air temperature.
     114              : 
     115              :     // REFERENCES:
     116              :     // ASHRAE Systems and Equipment Handbook (SI), 1996. pp. 31.1-31.3
     117              :     // Fred Buhl's fan coil module (FanCoilUnits.cc)
     118              : 
     119              :     std::string const cMO_VentilatedSlab = "ZoneHVAC:VentilatedSlab";
     120              : 
     121              :     //    int constexpr NotOperating = 0; // Parameter for use with OperatingMode variable, set for no heating/cooling
     122              :     int constexpr HeatingMode = 1; // Parameter for use with OperatingMode variable, set for heating
     123              :     int constexpr CoolingMode = 2; // Parameter for use with OperatingMode variable, set for cooling
     124              : 
     125            0 :     void SimVentilatedSlab(EnergyPlusData &state,
     126              :                            std::string const &CompName,   // name of the fan coil unit
     127              :                            int const ZoneNum,             // number of zone being served
     128              :                            bool const FirstHVACIteration, // TRUE if 1st HVAC simulation of system timestep
     129              :                            Real64 &PowerMet,              // Sensible power supplied (W)
     130              :                            Real64 &LatOutputProvided,     // Latent add/removal supplied by window AC (kg/s), dehumid = negative
     131              :                            int &CompIndex)
     132              :     {
     133              : 
     134              :         // SUBROUTINE INFORMATION:
     135              :         //       AUTHOR         Rick Strand
     136              :         //       DATE WRITTEN   May 2000
     137              :         //       MODIFIED       Don Shirey, Aug 2009 (LatOutputProvided)
     138              :         //       RE-ENGINEERED  Rick Strand and Young T. Chae for Ventilated Slab (June, 2008)
     139              : 
     140              :         // PURPOSE OF THIS SUBROUTINE:
     141              :         // This is the main driver subroutine for the Ventilated Slab simulation.
     142              : 
     143              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     144              :         int Item; // index of ventilated slab being simulated
     145              : 
     146            0 :         if (state.dataVentilatedSlab->GetInputFlag) {
     147            0 :             GetVentilatedSlabInput(state);
     148            0 :             state.dataVentilatedSlab->GetInputFlag = false;
     149              :         }
     150              : 
     151              :         // Find the correct VentilatedSlabInput
     152            0 :         if (CompIndex == 0) {
     153            0 :             Item = Util::FindItemInList(CompName, state.dataVentilatedSlab->VentSlab);
     154            0 :             if (Item == 0) {
     155            0 :                 ShowFatalError(state, format("SimVentilatedSlab: system not found={}", CompName));
     156              :             }
     157            0 :             CompIndex = Item;
     158              :         } else {
     159            0 :             Item = CompIndex;
     160            0 :             if (Item > state.dataVentilatedSlab->NumOfVentSlabs || Item < 1) {
     161            0 :                 ShowFatalError(state,
     162            0 :                                format("SimVentilatedSlab:  Invalid CompIndex passed={}, Number of Systems={}, Entered System name={}",
     163              :                                       Item,
     164            0 :                                       state.dataVentilatedSlab->NumOfVentSlabs,
     165              :                                       CompName));
     166              :             }
     167            0 :             if (state.dataVentilatedSlab->CheckEquipName(Item)) {
     168            0 :                 if (CompName != state.dataVentilatedSlab->VentSlab(Item).Name) {
     169            0 :                     ShowFatalError(state,
     170            0 :                                    format("SimVentilatedSlab: Invalid CompIndex passed={}, System name={}, stored System Name for that index={}",
     171              :                                           Item,
     172              :                                           CompName,
     173            0 :                                           state.dataVentilatedSlab->VentSlab(Item).Name));
     174              :                 }
     175            0 :                 state.dataVentilatedSlab->CheckEquipName(Item) = false;
     176              :             }
     177              :         }
     178              : 
     179            0 :         state.dataSize->ZoneEqVentedSlab = true;
     180              : 
     181            0 :         InitVentilatedSlab(state, Item, ZoneNum, FirstHVACIteration);
     182              : 
     183            0 :         CalcVentilatedSlab(state, Item, ZoneNum, FirstHVACIteration, PowerMet, LatOutputProvided);
     184              : 
     185            0 :         UpdateVentilatedSlab(state, Item, FirstHVACIteration);
     186              : 
     187            0 :         ReportVentilatedSlab(state, Item);
     188              : 
     189            0 :         state.dataSize->ZoneEqVentedSlab = false;
     190            0 :     }
     191              : 
     192            1 :     void GetVentilatedSlabInput(EnergyPlusData &state)
     193              :     {
     194              : 
     195              :         // SUBROUTINE INFORMATION:
     196              :         //       AUTHOR         Young Tae Chae, Rick Strand
     197              :         //       DATE WRITTEN   June 2008
     198              :         //       MODIFIED       July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
     199              : 
     200              :         // PURPOSE OF THIS SUBROUTINE:
     201              :         // This subroutine obtains the input for ventilated slab and sets
     202              :         // up the appropriate derived type.
     203              : 
     204              :         // METHODOLOGY EMPLOYED:
     205              :         // Standard EnergyPlus methodology.
     206              : 
     207              :         // REFERENCES:
     208              :         // Fred Buhl's fan coil module (FanCoilUnits.cc)
     209              :         // Kwang Ho Lee's Unit Ventilator Module (UnitVentilator.cc)
     210              :         // Rick Strand's Low temperature Radiant system (RadiantSystemLowTemp.cc)
     211              : 
     212              :         static constexpr std::string_view routineName = "GetVentilatedSlabInput";
     213              :         // Using/Aliasing
     214            1 :         auto &GetWaterCoilMaxFlowRate(WaterCoils::GetCoilMaxWaterFlowRate);
     215            1 :         auto &GetSteamCoilMaxFlowRate(SteamCoils::GetCoilMaxWaterFlowRate);
     216            1 :         auto &GetHXAssistedCoilFlowRate(HVACHXAssistedCoolingCoil::GetCoilMaxWaterFlowRate);
     217              : 
     218              :         // SUBROUTINE PARAMETER DEFINITIONS:
     219            1 :         constexpr std::array<std::string_view, static_cast<int>(VentilatedSlabConfig::Num)> VentilatedSlabConfigNamesUC{
     220              :             "SLABONLY", "SLABANDZONE", "SERIESSLABS"};
     221              : 
     222            1 :         constexpr std::array<std::string_view, static_cast<int>(ControlType::Num)> ControlTypeNamesUC{
     223              :             "MEANAIRTEMPERATURE",
     224              :             "MEANRADIANTTEMPERATURE",
     225              :             "OPERATIVETEMPERATURE",
     226              :             "OUTDOORDRYBULBTEMPERATURE",
     227              :             "OUTDOORWETBULBTEMPERATURE",
     228              :             "SURFACETEMPERATURE",
     229              :             "ZONEAIRDEWPOINTTEMPERATURE",
     230              :         };
     231              : 
     232            3 :         static std::string const CurrentModuleObject("ZoneHVAC:VentilatedSlab");
     233              : 
     234              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     235            1 :         bool ErrorsFound(false);       // Set to true if errors in input, fatal at end of routine
     236              :         int IOStatus;                  // Used in GetObjectItem
     237              :         bool IsNotOK;                  // TRUE if there was a problem with a list name
     238              :         int NumAlphas;                 // Number of Alphas for each GetObjectItem call
     239              :         int NumArgs;                   // Unused variable that is part of a subroutine call
     240              :         int NumNumbers;                // Number of Numbers for each GetObjectItem call
     241              :         int Item;                      // Item to be "gotten"
     242              :         int BaseNum;                   // Temporary number for creating RadiantSystemTypes structure
     243              :         bool errFlag;                  // interim error flag
     244              :         int SurfNum;                   // DO loop counter for surfaces
     245              :         bool IsValid;                  // Set for outside air node check
     246            1 :         Array1D_string cAlphaArgs;     // Alpha input items for object
     247            1 :         Array1D_string cAlphaFields;   // Alpha field names
     248            1 :         Array1D_string cNumericFields; // Numeric field names
     249            1 :         Array1D<Real64> rNumericArgs;  // Numeric input items for object
     250            1 :         Array1D_bool lAlphaBlanks;     // Logical array, alpha field input BLANK = .TRUE.
     251            1 :         Array1D_bool lNumericBlanks;   // Logical array, numeric field input BLANK = .TRUE.
     252              :         bool SteamMessageNeeded;
     253              : 
     254            1 :         constexpr std::array<std::string_view, static_cast<int>(OutsideAirControlType::Num)> OutsideAirControlTypeNamesUC{
     255              :             "VARIABLEPERCENT", "FIXEDTEMPERATURE", "FIXEDAMOUNT"};
     256            1 :         constexpr std::array<std::string_view, static_cast<int>(CoilType::Num)> CoilTypeNamesUC{"NONE", "HEATING", "COOLING", "HEATINGANDCOOLING"};
     257              : 
     258            1 :         constexpr std::array<std::string_view, static_cast<int>(HeatingCoilType::Num)> HeatingCoilTypeNamesUC{
     259              :             "COIL:HEATING:ELECTRIC", "COIL:HEATING:FUEL", "COIL:HEATING:WATER", "COIL:HEATING:STEAM"};
     260            1 :         constexpr std::array<std::string_view, static_cast<int>(CoolingCoilType::Num)> CoolingCoilTypeNamesUC{
     261              :             "COIL:COOLING:WATER", "COIL:COOLING:WATER:DETAILEDGEOMETRY", "COILSYSTEM:COOLING:WATER:HEATEXCHANGERASSISTED"};
     262              : 
     263              :         // Figure out how many Ventilated Slab Systems there are in the input file
     264              : 
     265            1 :         SteamMessageNeeded = true;
     266            1 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumArgs, NumAlphas, NumNumbers);
     267            1 :         cAlphaArgs.allocate(NumAlphas);
     268            1 :         cAlphaFields.allocate(NumAlphas);
     269            1 :         cNumericFields.allocate(NumNumbers);
     270            1 :         rNumericArgs.dimension(NumNumbers, 0.0);
     271            1 :         lAlphaBlanks.dimension(NumAlphas, true);
     272            1 :         lNumericBlanks.dimension(NumNumbers, true);
     273              : 
     274              :         // make sure data is gotten for surface lists
     275            1 :         BaseNum = DataSurfaceLists::GetNumberOfSurfListVentSlab(state);
     276              : 
     277            1 :         state.dataVentilatedSlab->NumOfVentSlabs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
     278              :         // Allocate the local derived type and do one-time initializations for all parts of it
     279              : 
     280            1 :         state.dataVentilatedSlab->VentSlab.allocate(state.dataVentilatedSlab->NumOfVentSlabs);
     281            1 :         state.dataVentilatedSlab->CheckEquipName.dimension(state.dataVentilatedSlab->NumOfVentSlabs, true);
     282            1 :         state.dataVentilatedSlab->VentSlabNumericFields.allocate(state.dataVentilatedSlab->NumOfVentSlabs);
     283              : 
     284            3 :         for (Item = 1; Item <= state.dataVentilatedSlab->NumOfVentSlabs;
     285              :              ++Item) { // Begin looping over the entire ventilated slab systems found in the input file...
     286              : 
     287            4 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     288              :                                                                      CurrentModuleObject,
     289              :                                                                      Item,
     290            2 :                                                                      state.dataIPShortCut->cAlphaArgs,
     291              :                                                                      NumAlphas,
     292            2 :                                                                      state.dataIPShortCut->rNumericArgs,
     293              :                                                                      NumNumbers,
     294              :                                                                      IOStatus,
     295              :                                                                      lNumericBlanks,
     296              :                                                                      lAlphaBlanks,
     297              :                                                                      cAlphaFields,
     298              :                                                                      cNumericFields);
     299              : 
     300            2 :             ErrorObjectHeader eoh{routineName, CurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)};
     301              : 
     302            2 :             state.dataVentilatedSlab->VentSlabNumericFields(Item).FieldNames.allocate(NumNumbers);
     303            2 :             state.dataVentilatedSlab->VentSlabNumericFields(Item).FieldNames = cNumericFields;
     304            2 :             Util::IsNameEmpty(state, state.dataIPShortCut->cAlphaArgs(1), CurrentModuleObject, ErrorsFound);
     305            2 :             auto &ventSlab = state.dataVentilatedSlab->VentSlab(Item);
     306              : 
     307            2 :             ventSlab.Name = state.dataIPShortCut->cAlphaArgs(1);
     308            2 :             if (lAlphaBlanks(2)) {
     309            0 :                 ventSlab.availSched = Sched::GetScheduleAlwaysOn(state);
     310            2 :             } else if ((ventSlab.availSched = Sched::GetSchedule(state, state.dataIPShortCut->cAlphaArgs(2))) == nullptr) {
     311            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(2), state.dataIPShortCut->cAlphaArgs(2));
     312            0 :                 ErrorsFound = true;
     313              :             }
     314              : 
     315            2 :             ventSlab.ZonePtr = Util::FindItemInList(state.dataIPShortCut->cAlphaArgs(3), state.dataHeatBal->Zone);
     316            2 :             if (ventSlab.ZonePtr == 0) {
     317            0 :                 if (lAlphaBlanks(3)) {
     318            0 :                     ShowSevereError(
     319            0 :                         state, format(R"({}="{}" invalid {} is required but input is blank.)", CurrentModuleObject, ventSlab.Name, cAlphaFields(3)));
     320              :                 } else {
     321            0 :                     ShowSevereError(state,
     322            0 :                                     format(R"({}="{}" invalid {}="{}" not found.)",
     323              :                                            CurrentModuleObject,
     324            0 :                                            ventSlab.Name,
     325              :                                            cAlphaFields(3),
     326            0 :                                            state.dataIPShortCut->cAlphaArgs(3)));
     327              :                 }
     328            0 :                 ErrorsFound = true;
     329              :             }
     330              : 
     331            2 :             ventSlab.SurfListName = state.dataIPShortCut->cAlphaArgs(4);
     332            2 :             int SurfListNum = 0;
     333              :             //    IF (NumOfSlabLists > 0) SurfListNum = Util::FindItemInList(VentSlab(Item)%SurfListName, SlabList%Name, NumOfSlabLists)
     334            2 :             if (state.dataSurfLists->NumOfSurfListVentSlab > 0) {
     335            2 :                 SurfListNum = Util::FindItemInList(ventSlab.SurfListName, state.dataSurfLists->SlabList);
     336              :             }
     337            2 :             if (SurfListNum > 0) { // Found a valid surface list
     338            2 :                 ventSlab.NumOfSurfaces = state.dataSurfLists->SlabList(SurfListNum).NumOfSurfaces;
     339            2 :                 ventSlab.ZName.allocate(ventSlab.NumOfSurfaces);
     340            2 :                 ventSlab.ZPtr.allocate(ventSlab.NumOfSurfaces);
     341            2 :                 ventSlab.SurfaceName.allocate(ventSlab.NumOfSurfaces);
     342            2 :                 ventSlab.SurfacePtr.allocate(ventSlab.NumOfSurfaces);
     343            2 :                 ventSlab.CDiameter.allocate(ventSlab.NumOfSurfaces);
     344            2 :                 ventSlab.CLength.allocate(ventSlab.NumOfSurfaces);
     345            2 :                 ventSlab.CNumbers.allocate(ventSlab.NumOfSurfaces);
     346            2 :                 ventSlab.SlabIn.allocate(ventSlab.NumOfSurfaces);
     347            2 :                 ventSlab.SlabOut.allocate(ventSlab.NumOfSurfaces);
     348              : 
     349            2 :                 state.dataVentilatedSlab->MaxCloNumOfSurfaces = max(state.dataVentilatedSlab->MaxCloNumOfSurfaces, ventSlab.NumOfSurfaces);
     350            7 :                 for (SurfNum = 1; SurfNum <= state.dataSurfLists->SlabList(SurfListNum).NumOfSurfaces; ++SurfNum) {
     351            5 :                     ventSlab.ZName(SurfNum) = state.dataSurfLists->SlabList(SurfListNum).ZoneName(SurfNum);
     352            5 :                     ventSlab.ZPtr(SurfNum) = state.dataSurfLists->SlabList(SurfListNum).ZonePtr(SurfNum);
     353            5 :                     ventSlab.SurfaceName(SurfNum) = state.dataSurfLists->SlabList(SurfListNum).SurfName(SurfNum);
     354            5 :                     ventSlab.SurfacePtr(SurfNum) = state.dataSurfLists->SlabList(SurfListNum).SurfPtr(SurfNum);
     355            5 :                     ventSlab.CDiameter(SurfNum) = state.dataSurfLists->SlabList(SurfListNum).CoreDiameter(SurfNum);
     356            5 :                     ventSlab.CLength(SurfNum) = state.dataSurfLists->SlabList(SurfListNum).CoreLength(SurfNum);
     357            5 :                     ventSlab.CNumbers(SurfNum) = state.dataSurfLists->SlabList(SurfListNum).CoreNumbers(SurfNum);
     358            5 :                     ventSlab.SlabIn(SurfNum) = state.dataSurfLists->SlabList(SurfListNum).SlabInNodeName(SurfNum);
     359            5 :                     ventSlab.SlabOut(SurfNum) = state.dataSurfLists->SlabList(SurfListNum).SlabOutNodeName(SurfNum);
     360            5 :                     if (ventSlab.SurfacePtr(SurfNum) != 0) {
     361            5 :                         state.dataSurface->surfIntConv(ventSlab.SurfacePtr(SurfNum)).hasActiveInIt = true;
     362              :                     }
     363              :                 }
     364              : 
     365              :             } else { // User entered a single surface name rather than a surface list
     366            0 :                 ventSlab.NumOfSurfaces = 1;
     367            0 :                 ventSlab.SurfacePtr.allocate(ventSlab.NumOfSurfaces);
     368            0 :                 ventSlab.SurfaceName.allocate(ventSlab.NumOfSurfaces);
     369            0 :                 ventSlab.SurfaceFlowFrac.allocate(ventSlab.NumOfSurfaces);
     370            0 :                 state.dataVentilatedSlab->MaxCloNumOfSurfaces = max(state.dataVentilatedSlab->MaxCloNumOfSurfaces, ventSlab.NumOfSurfaces);
     371            0 :                 ventSlab.SurfaceName(1) = ventSlab.SurfListName;
     372            0 :                 ventSlab.SurfacePtr(1) = Util::FindItemInList(ventSlab.SurfaceName(1), state.dataSurface->Surface);
     373            0 :                 ventSlab.SurfaceFlowFrac(1) = 1.0;
     374              :                 // Error checking for single surfaces
     375            0 :                 if (ventSlab.SurfacePtr(1) == 0) {
     376            0 :                     ShowSevereError(state,
     377            0 :                                     format(R"({}="{}" invalid {}="{}" not found.)",
     378              :                                            CurrentModuleObject,
     379            0 :                                            ventSlab.Name,
     380              :                                            cAlphaFields(4),
     381            0 :                                            state.dataIPShortCut->cAlphaArgs(4)));
     382            0 :                     ErrorsFound = true;
     383            0 :                 } else if (state.dataSurface->SurfIsRadSurfOrVentSlabOrPool(ventSlab.SurfacePtr(1))) {
     384            0 :                     ShowSevereError(state, format("{}=\"{}\", invalid Surface", CurrentModuleObject, ventSlab.Name));
     385            0 :                     ShowContinueError(state,
     386            0 :                                       format("{}=\"{}\" has been used in another radiant system or ventilated slab.",
     387              :                                              cAlphaFields(4),
     388            0 :                                              state.dataIPShortCut->cAlphaArgs(4)));
     389            0 :                     ErrorsFound = true;
     390              :                 }
     391            0 :                 if (ventSlab.SurfacePtr(1) != 0) {
     392            0 :                     state.dataSurface->surfIntConv(ventSlab.SurfacePtr(1)).hasActiveInIt = true;
     393            0 :                     state.dataSurface->SurfIsRadSurfOrVentSlabOrPool(ventSlab.SurfacePtr(1)) = true;
     394              :                 }
     395              :             }
     396              : 
     397              :             // Error checking for zones and construction information
     398              : 
     399            2 :             if (SurfListNum > 0) {
     400              : 
     401            7 :                 for (SurfNum = 1; SurfNum <= ventSlab.NumOfSurfaces; ++SurfNum) {
     402              : 
     403            5 :                     int const ConstrNum = state.dataSurface->Surface(ventSlab.SurfacePtr(SurfNum)).Construction;
     404            5 :                     auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
     405            5 :                     if (ventSlab.SurfacePtr(SurfNum) == 0) {
     406            0 :                         continue; // invalid surface -- detected earlier
     407              :                     }
     408            5 :                     if (ventSlab.ZPtr(SurfNum) == 0) {
     409            0 :                         continue; // invalid zone -- detected earlier
     410              :                     }
     411            5 :                     if (state.dataSurface->Surface(ventSlab.SurfacePtr(SurfNum)).Construction == 0) {
     412            0 :                         continue; // invalid construction, detected earlier
     413              :                     }
     414            5 :                     if (!thisConstruct.SourceSinkPresent) {
     415            0 :                         ShowSevereError(state,
     416            0 :                                         format("{}=\"{}\" invalid surface=\"{}\".",
     417              :                                                CurrentModuleObject,
     418            0 :                                                ventSlab.Name,
     419            0 :                                                state.dataSurface->Surface(ventSlab.SurfacePtr(SurfNum)).Name));
     420            0 :                         ShowContinueError(state,
     421            0 :                                           format("Surface Construction does not have a source/sink, Construction name= \"{}\".", thisConstruct.Name));
     422            0 :                         ErrorsFound = true;
     423              :                     }
     424              :                 }
     425              :             } else {
     426            0 :                 for (SurfNum = 1; SurfNum <= ventSlab.NumOfSurfaces; ++SurfNum) {
     427            0 :                     int const ConstrNum = state.dataSurface->Surface(ventSlab.SurfacePtr(SurfNum)).Construction;
     428            0 :                     auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
     429            0 :                     if (ventSlab.SurfacePtr(SurfNum) == 0) {
     430            0 :                         continue; // invalid surface -- detected earlier
     431              :                     }
     432            0 :                     if (ventSlab.ZonePtr == 0) {
     433            0 :                         continue; // invalid zone -- detected earlier
     434              :                     }
     435            0 :                     if (state.dataSurface->Surface(ventSlab.SurfacePtr(SurfNum)).Zone != ventSlab.ZonePtr) {
     436            0 :                         ShowSevereError(state,
     437            0 :                                         format("{}=\"{}\" invalid surface=\"{}\".",
     438              :                                                CurrentModuleObject,
     439            0 :                                                ventSlab.Name,
     440            0 :                                                state.dataSurface->Surface(ventSlab.SurfacePtr(SurfNum)).Name));
     441            0 :                         ShowContinueError(state,
     442            0 :                                           format("Surface in Zone={} {} in Zone={}",
     443            0 :                                                  state.dataHeatBal->Zone(state.dataSurface->Surface(ventSlab.SurfacePtr(SurfNum)).Zone).Name,
     444              :                                                  CurrentModuleObject,
     445            0 :                                                  state.dataIPShortCut->cAlphaArgs(3)));
     446            0 :                         ErrorsFound = true;
     447              :                     }
     448            0 :                     if (state.dataSurface->Surface(ventSlab.SurfacePtr(SurfNum)).Construction == 0) {
     449            0 :                         continue; // invalid construction, detected earlier
     450              :                     }
     451            0 :                     if (!thisConstruct.SourceSinkPresent) {
     452            0 :                         ShowSevereError(state,
     453            0 :                                         format("{}=\"{}\" invalid surface=\"{}\".",
     454              :                                                CurrentModuleObject,
     455            0 :                                                ventSlab.Name,
     456            0 :                                                state.dataSurface->Surface(ventSlab.SurfacePtr(SurfNum)).Name));
     457            0 :                         ShowContinueError(state,
     458            0 :                                           format("Surface Construction does not have a source/sink, Construction name= \"{}\".", thisConstruct.Name));
     459            0 :                         ErrorsFound = true;
     460              :                     }
     461              :                 }
     462              :             }
     463              : 
     464            2 :             ventSlab.MaxAirVolFlow = state.dataIPShortCut->rNumericArgs(1);
     465              : 
     466              :             // Outside air information:
     467            2 :             ventSlab.MinOutAirVolFlow = state.dataIPShortCut->rNumericArgs(2);
     468            2 :             ventSlab.OutAirVolFlow = state.dataIPShortCut->rNumericArgs(3);
     469              : 
     470            2 :             ventSlab.outsideAirControlType =
     471            2 :                 static_cast<OutsideAirControlType>(getEnumValue(OutsideAirControlTypeNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(5))));
     472              : 
     473            2 :             switch (ventSlab.outsideAirControlType) {
     474              : 
     475            2 :             case OutsideAirControlType::VariablePercent: {
     476            2 :                 if (lAlphaBlanks(7)) {
     477            0 :                     ShowSevereEmptyField(state, eoh, state.dataIPShortCut->cAlphaFieldNames(7));
     478            0 :                     ErrorsFound = true;
     479            2 :                 } else if ((ventSlab.maxOASched = Sched::GetSchedule(state, state.dataIPShortCut->cAlphaArgs(7))) == nullptr) {
     480            0 :                     ShowSevereItemNotFound(state, eoh, cAlphaFields(7), state.dataIPShortCut->cAlphaArgs(7));
     481            0 :                     ErrorsFound = true;
     482            2 :                 } else if (!ventSlab.maxOASched->checkMinMaxVals(state, Clusive::In, 0.0, Clusive::In, 1.0)) {
     483            0 :                     Sched::ShowSevereBadMinMax(state, eoh, cAlphaFields(7), state.dataIPShortCut->cAlphaArgs(7), Clusive::In, 0.0, Clusive::In, 1.0);
     484            0 :                     ErrorsFound = true;
     485              :                 }
     486            2 :             } break;
     487              : 
     488            0 :             case OutsideAirControlType::FixedOAControl: {
     489            0 :                 if (lAlphaBlanks(7)) {
     490            0 :                     ShowSevereEmptyField(state, eoh, state.dataIPShortCut->cAlphaFieldNames(7));
     491            0 :                     ErrorsFound = true;
     492            0 :                 } else if ((ventSlab.maxOASched = Sched::GetSchedule(state, state.dataIPShortCut->cAlphaArgs(7))) == nullptr) {
     493            0 :                     ShowSevereItemNotFound(state, eoh, cAlphaFields(7), state.dataIPShortCut->cAlphaArgs(7));
     494            0 :                     ErrorsFound = true;
     495            0 :                 } else if (!ventSlab.maxOASched->checkMinVal(state, Clusive::In, 0.0)) {
     496            0 :                     Sched::ShowSevereBadMin(state, eoh, cAlphaFields(7), state.dataIPShortCut->cAlphaArgs(7), Clusive::In, 0.0);
     497            0 :                     ErrorsFound = true;
     498              :                 }
     499            0 :             } break;
     500              : 
     501            0 :             case OutsideAirControlType::FixedTemperature: {
     502            0 :                 if (lAlphaBlanks(7)) {
     503            0 :                     ShowSevereEmptyField(state, eoh, cAlphaFields(7));
     504            0 :                     ErrorsFound = true;
     505            0 :                 } else if ((ventSlab.tempSched = Sched::GetSchedule(state, state.dataIPShortCut->cAlphaArgs(7))) == nullptr) {
     506            0 :                     ShowSevereItemNotFound(state, eoh, cAlphaFields(7), state.dataIPShortCut->cAlphaArgs(7));
     507            0 :                     ErrorsFound = true;
     508              :                 }
     509            0 :             } break;
     510              : 
     511            0 :             default: {
     512            0 :                 ShowSevereError(
     513              :                     state,
     514            0 :                     format(R"({}="{}" invalid {}="{}".)", CurrentModuleObject, ventSlab.Name, cAlphaFields(5), state.dataIPShortCut->cAlphaArgs(5)));
     515            0 :             } break;
     516              :             } // switch (outsideAirControlType)
     517              : 
     518            2 :             if (lAlphaBlanks(6)) {
     519            2 :             } else if ((ventSlab.minOASched = Sched::GetSchedule(state, state.dataIPShortCut->cAlphaArgs(6))) == nullptr) {
     520            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(6), state.dataIPShortCut->cAlphaArgs(6));
     521            0 :                 ErrorsFound = true;
     522              :             }
     523              : 
     524              :             // System Configuration:
     525            2 :             ventSlab.SysConfg = static_cast<VentilatedSlabConfig>(getEnumValue(VentilatedSlabConfigNamesUC, state.dataIPShortCut->cAlphaArgs(8)));
     526            2 :             if (ventSlab.SysConfg == VentilatedSlabConfig::Invalid) {
     527            0 :                 ShowWarningInvalidKey(state, eoh, cAlphaFields(8), state.dataIPShortCut->cAlphaArgs(8), "Control reset to SLAB ONLY Configuration.");
     528            0 :                 ventSlab.SysConfg = VentilatedSlabConfig::SlabOnly;
     529              :             }
     530              : 
     531              :             // Hollow Core information :
     532            2 :             ventSlab.CoreDiameter = state.dataIPShortCut->rNumericArgs(4);
     533            2 :             ventSlab.CoreLength = state.dataIPShortCut->rNumericArgs(5);
     534            2 :             ventSlab.CoreNumbers = state.dataIPShortCut->rNumericArgs(6);
     535              : 
     536            2 :             if (Util::SameString(state.dataIPShortCut->cAlphaArgs(8), "SurfaceListNames")) {
     537            0 :                 if (!lNumericBlanks(4)) {
     538            0 :                     ShowWarningError(state,
     539            0 :                                      format("{}=\"{}\"  Core Diameter is not needed for the series slabs configuration- ignored.",
     540              :                                             CurrentModuleObject,
     541            0 :                                             ventSlab.Name));
     542            0 :                     ShowContinueError(state, "...It has been assigned on SlabGroup.");
     543              :                 }
     544              :             }
     545              : 
     546            2 :             if (Util::SameString(state.dataIPShortCut->cAlphaArgs(8), "SurfaceListNames")) {
     547            0 :                 if (!lNumericBlanks(5)) {
     548            0 :                     ShowWarningError(state,
     549            0 :                                      format("{}=\"{}\"  Core Length is not needed for the series slabs configuration- ignored.",
     550              :                                             CurrentModuleObject,
     551            0 :                                             ventSlab.Name));
     552            0 :                     ShowContinueError(state, "...It has been assigned on SlabGroup.");
     553              :                 }
     554              :             }
     555              : 
     556            2 :             if (Util::SameString(state.dataIPShortCut->cAlphaArgs(8), "SurfaceListNames")) {
     557            0 :                 if (!lNumericBlanks(6)) {
     558            0 :                     ShowWarningError(state,
     559            0 :                                      format("{}=\"{}\"  Core Numbers is not needed for the series slabs configuration- ignored.",
     560              :                                             CurrentModuleObject,
     561            0 :                                             ventSlab.Name));
     562            0 :                     ShowContinueError(state, "...It has been assigned on SlabGroup.");
     563              :                 }
     564              :             }
     565              : 
     566              :             // Process the temperature control type
     567            2 :             ventSlab.controlType = static_cast<ControlType>(getEnumValue(ControlTypeNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(9))));
     568              : 
     569            2 :             if (ventSlab.controlType == ControlType::Invalid) {
     570            0 :                 ShowSevereError(
     571              :                     state,
     572            0 :                     format(R"({}="{}" invalid {}="{}".)", CurrentModuleObject, ventSlab.Name, cAlphaFields(9), state.dataIPShortCut->cAlphaArgs(9)));
     573            0 :                 ShowContinueError(state, "Control reset to ODB control.");
     574            0 :                 ventSlab.controlType = ControlType::OutdoorDryBulbTemp;
     575              :             }
     576              : 
     577              :             // Heating User Input Data For Ventilated Slab Control :
     578              : 
     579              :             // High Air Temp :
     580            2 :             if (lAlphaBlanks(10)) {
     581            2 :             } else if ((ventSlab.hotAirHiTempSched = Sched::GetSchedule(state, state.dataIPShortCut->cAlphaArgs(10))) == nullptr) {
     582            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(10), state.dataIPShortCut->cAlphaArgs(10));
     583            0 :                 ErrorsFound = true;
     584              :             }
     585              : 
     586              :             // Low Air Temp :
     587            2 :             if (lAlphaBlanks(11)) {
     588            2 :             } else if ((ventSlab.hotAirLoTempSched = Sched::GetSchedule(state, state.dataIPShortCut->cAlphaArgs(11))) == nullptr) {
     589            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(11), state.dataIPShortCut->cAlphaArgs(11));
     590            0 :                 ErrorsFound = true;
     591              :             }
     592              : 
     593            2 :             if (lAlphaBlanks(12)) {
     594            2 :             } else if ((ventSlab.hotCtrlHiTempSched = Sched::GetSchedule(state, state.dataIPShortCut->cAlphaArgs(12))) == nullptr) {
     595            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(12), state.dataIPShortCut->cAlphaArgs(12));
     596            0 :                 ErrorsFound = true;
     597              :             }
     598              : 
     599            2 :             if (lAlphaBlanks(13)) {
     600            2 :             } else if ((ventSlab.hotCtrlLoTempSched = Sched::GetSchedule(state, state.dataIPShortCut->cAlphaArgs(13))) == nullptr) {
     601            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(13), state.dataIPShortCut->cAlphaArgs(13));
     602            0 :                 ErrorsFound = true;
     603              :             }
     604              : 
     605              :             // Cooling User Input Data For Ventilated Slab Control :
     606              :             // Cooling High Temp Sch.
     607            2 :             if (lAlphaBlanks(14)) {
     608            2 :             } else if ((ventSlab.coldAirHiTempSched = Sched::GetSchedule(state, state.dataIPShortCut->cAlphaArgs(14))) == nullptr) {
     609            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(14), state.dataIPShortCut->cAlphaArgs(14));
     610            0 :                 ErrorsFound = true;
     611              :             }
     612              : 
     613              :             // Cooling Low Temp Sch.
     614            2 :             if (lAlphaBlanks(15)) {
     615            2 :             } else if ((ventSlab.coldAirLoTempSched = Sched::GetSchedule(state, state.dataIPShortCut->cAlphaArgs(15))) == nullptr) {
     616            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(15), state.dataIPShortCut->cAlphaArgs(15));
     617            0 :                 ErrorsFound = true;
     618              :             }
     619              : 
     620              :             // Cooling Control High Sch.
     621            2 :             if (lAlphaBlanks(16)) {
     622            2 :             } else if ((ventSlab.coldCtrlHiTempSched = Sched::GetSchedule(state, state.dataIPShortCut->cAlphaArgs(16))) == nullptr) {
     623            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(16), state.dataIPShortCut->cAlphaArgs(16));
     624            0 :                 ErrorsFound = true;
     625              :             }
     626              : 
     627              :             // Cooling Control Low Sch.
     628            2 :             if (lAlphaBlanks(17)) {
     629            2 :             } else if ((ventSlab.coldCtrlLoTempSched = Sched::GetSchedule(state, state.dataIPShortCut->cAlphaArgs(17))) == nullptr) {
     630            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(17), state.dataIPShortCut->cAlphaArgs(17));
     631            0 :                 ErrorsFound = true;
     632              :             }
     633              : 
     634              :             // Main air nodes (except outside air node):
     635              :             // Refer the Unit Ventilator Air Node note
     636              : 
     637              :             // MJW CR7903 - Ventilated slab was not drawing properly in HVAC Diagram svg output
     638              :             //  This object is structured differently from other zone equipment in that it functions
     639              :             //  as both a parent and non-parent, and it has an implicit OA mixer.  This makes it difficult
     640              :             //  to register the nodes in a way that HVAC Diagram can understand and in a way that satisfies
     641              :             //  node connection tests.  Here's an explanation of the changes made for this CR:
     642              :             //      In general, nodes associated with the ventilated slab system (the overall parent object)
     643              :             //         are registered with "-SYSTEM" appended to the object type and object name
     644              :             //         This same suffix is also added later when SetUpCompSets is called, for the same reason
     645              :             //      In general, nodes associated with the implicit OA mixer object
     646              :             //         are registered with "-OA MIXER" appended to the object type and object name
     647              :             //      %ReturnAirNode is one inlet to the implicit oa mixer
     648              :             //         For SlabOnly and SeriesSlab this node does nothing,
     649              :             //             so DataLoopNode::NodeConnectionType::Internal,ObjectIsNotParent, -OA MIXER
     650              :             //         For SlabandZone, this node extracts air from the zone,
     651              :             //             so DataLoopNode::NodeConnectionType::Inlet,ObjectIsNotParent, -OA MIXER
     652              :             //         For SlabandZone, this node is also used to associate the whole system with a pair of zone inlet/exhaust nodes,
     653              :             //             so it is registered again as DataLoopNode::NodeConnectionType::Inlet,1,ObjectIsParent, -SYSTEM
     654              :             //      %RadInNode is the ultimate air inlet to the slab or series of slabs
     655              :             //         For all types of ventilated slab, this is DataLoopNode::NodeConnectionType::Inlet,ObjectIsNotParent
     656              :             //      %OAMixerOutNode is the outlet from the implicit OA mixer
     657              :             //         For all types of ventilated slab, this is DataLoopNode::NodeConnectionType::Outlet,ObjectIsNotParent
     658              :             //      %FanOutletNode is the outlet from the explicit fan child object (redundant input, should mine from child)
     659              :             //         For all types of ventilated slab, this is DataLoopNode::NodeConnectionType::Internal,ObjectIsParent
     660              :             //      %ZoneAirInNode is applicable only to SlabandZone configuration. It is the node that flows into the zone,
     661              :             //         and it is also the outlet from the ventilated slab section, so it must be registered twice
     662              :             //         First for the overall system, DataLoopNode::NodeConnectionType::Outlet,ObjectIsParent, -SYSTEM
     663              :             //         Second as the slab outlet, DataLoopNode::NodeConnectionType::Outlet,ObjectIsNotParent
     664              :             //      %OutsideAirNode is the outdoor air inlet to the OA mixer
     665              :             //         For all types of ventilated slab, this is DataLoopNode::NodeConnectionType::Inlet,ObjectIsNotParent, -OA MIXER
     666              : 
     667            2 :             if (ventSlab.SysConfg == VentilatedSlabConfig::SlabOnly) {
     668              : 
     669            0 :                 ventSlab.ReturnAirNode = NodeInputManager::GetOnlySingleNode(state,
     670            0 :                                                                              state.dataIPShortCut->cAlphaArgs(18),
     671              :                                                                              ErrorsFound,
     672              :                                                                              DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
     673            0 :                                                                              ventSlab.Name + "-OA MIXER",
     674              :                                                                              DataLoopNode::NodeFluidType::Air,
     675              :                                                                              DataLoopNode::ConnectionType::Outlet,
     676              :                                                                              NodeInputManager::CompFluidStream::Primary,
     677              :                                                                              DataLoopNode::ObjectIsNotParent);
     678            0 :                 ventSlab.ReturnAirNode = NodeInputManager::GetOnlySingleNode(state,
     679            0 :                                                                              state.dataIPShortCut->cAlphaArgs(18),
     680              :                                                                              ErrorsFound,
     681              :                                                                              DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
     682            0 :                                                                              ventSlab.Name,
     683              :                                                                              DataLoopNode::NodeFluidType::Air,
     684              :                                                                              DataLoopNode::ConnectionType::Inlet,
     685              :                                                                              NodeInputManager::CompFluidStream::Primary,
     686              :                                                                              DataLoopNode::ObjectIsParent);
     687            0 :                 ventSlab.RadInNode = NodeInputManager::GetOnlySingleNode(state,
     688            0 :                                                                          state.dataIPShortCut->cAlphaArgs(19),
     689              :                                                                          ErrorsFound,
     690              :                                                                          DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
     691            0 :                                                                          ventSlab.Name,
     692              :                                                                          DataLoopNode::NodeFluidType::Air,
     693              :                                                                          DataLoopNode::ConnectionType::Inlet,
     694              :                                                                          NodeInputManager::CompFluidStream::Primary,
     695              :                                                                          DataLoopNode::ObjectIsNotParent);
     696              : 
     697            0 :                 ventSlab.OAMixerOutNode = NodeInputManager::GetOnlySingleNode(state,
     698            0 :                                                                               state.dataIPShortCut->cAlphaArgs(23),
     699              :                                                                               ErrorsFound,
     700              :                                                                               DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
     701            0 :                                                                               ventSlab.Name + "-OA MIXER",
     702              :                                                                               DataLoopNode::NodeFluidType::Air,
     703              :                                                                               DataLoopNode::ConnectionType::Outlet,
     704              :                                                                               NodeInputManager::CompFluidStream::Primary,
     705              :                                                                               DataLoopNode::ObjectIsNotParent);
     706            0 :                 ventSlab.FanOutletNode = NodeInputManager::GetOnlySingleNode(state,
     707            0 :                                                                              state.dataIPShortCut->cAlphaArgs(24),
     708              :                                                                              ErrorsFound,
     709              :                                                                              DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
     710            0 :                                                                              ventSlab.Name,
     711              :                                                                              DataLoopNode::NodeFluidType::Air,
     712              :                                                                              DataLoopNode::ConnectionType::Internal,
     713              :                                                                              NodeInputManager::CompFluidStream::Primary,
     714              :                                                                              DataLoopNode::ObjectIsParent);
     715              : 
     716            2 :             } else if (ventSlab.SysConfg == VentilatedSlabConfig::SeriesSlabs) {
     717              : 
     718            2 :                 ventSlab.ReturnAirNode = NodeInputManager::GetOnlySingleNode(state,
     719            2 :                                                                              state.dataIPShortCut->cAlphaArgs(18),
     720              :                                                                              ErrorsFound,
     721              :                                                                              DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
     722            4 :                                                                              ventSlab.Name + "-OA MIXER",
     723              :                                                                              DataLoopNode::NodeFluidType::Air,
     724              :                                                                              DataLoopNode::ConnectionType::Outlet,
     725              :                                                                              NodeInputManager::CompFluidStream::Primary,
     726              :                                                                              DataLoopNode::ObjectIsNotParent);
     727            2 :                 ventSlab.ReturnAirNode = NodeInputManager::GetOnlySingleNode(state,
     728            2 :                                                                              state.dataIPShortCut->cAlphaArgs(18),
     729              :                                                                              ErrorsFound,
     730              :                                                                              DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
     731            2 :                                                                              ventSlab.Name,
     732              :                                                                              DataLoopNode::NodeFluidType::Air,
     733              :                                                                              DataLoopNode::ConnectionType::Inlet,
     734              :                                                                              NodeInputManager::CompFluidStream::Primary,
     735              :                                                                              DataLoopNode::ObjectIsParent);
     736            2 :                 ventSlab.RadInNode = NodeInputManager::GetOnlySingleNode(state,
     737            2 :                                                                          state.dataIPShortCut->cAlphaArgs(19),
     738              :                                                                          ErrorsFound,
     739              :                                                                          DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
     740            2 :                                                                          ventSlab.Name,
     741              :                                                                          DataLoopNode::NodeFluidType::Air,
     742              :                                                                          DataLoopNode::ConnectionType::Inlet,
     743              :                                                                          NodeInputManager::CompFluidStream::Primary,
     744              :                                                                          DataLoopNode::ObjectIsNotParent);
     745              : 
     746            2 :                 ventSlab.OAMixerOutNode = NodeInputManager::GetOnlySingleNode(state,
     747            2 :                                                                               state.dataIPShortCut->cAlphaArgs(23),
     748              :                                                                               ErrorsFound,
     749              :                                                                               DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
     750            4 :                                                                               ventSlab.Name + "-OA MIXER",
     751              :                                                                               DataLoopNode::NodeFluidType::Air,
     752              :                                                                               DataLoopNode::ConnectionType::Outlet,
     753              :                                                                               NodeInputManager::CompFluidStream::Primary,
     754              :                                                                               DataLoopNode::ObjectIsNotParent);
     755            4 :                 ventSlab.FanOutletNode = NodeInputManager::GetOnlySingleNode(state,
     756            2 :                                                                              state.dataIPShortCut->cAlphaArgs(24),
     757              :                                                                              ErrorsFound,
     758              :                                                                              DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
     759            2 :                                                                              ventSlab.Name,
     760              :                                                                              DataLoopNode::NodeFluidType::Air,
     761              :                                                                              DataLoopNode::ConnectionType::Internal,
     762              :                                                                              NodeInputManager::CompFluidStream::Primary,
     763              :                                                                              DataLoopNode::ObjectIsParent);
     764              : 
     765            0 :             } else if (ventSlab.SysConfg == VentilatedSlabConfig::SlabAndZone) {
     766              : 
     767            0 :                 ventSlab.ReturnAirNode = NodeInputManager::GetOnlySingleNode(state,
     768            0 :                                                                              state.dataIPShortCut->cAlphaArgs(18),
     769              :                                                                              ErrorsFound,
     770              :                                                                              DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
     771            0 :                                                                              ventSlab.Name + "-SYSTEM",
     772              :                                                                              DataLoopNode::NodeFluidType::Air,
     773              :                                                                              DataLoopNode::ConnectionType::Inlet,
     774              :                                                                              NodeInputManager::CompFluidStream::Primary,
     775              :                                                                              DataLoopNode::ObjectIsParent);
     776            0 :                 ventSlab.ReturnAirNode = NodeInputManager::GetOnlySingleNode(state,
     777            0 :                                                                              state.dataIPShortCut->cAlphaArgs(18),
     778              :                                                                              ErrorsFound,
     779              :                                                                              DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
     780            0 :                                                                              ventSlab.Name,
     781              :                                                                              DataLoopNode::NodeFluidType::Air,
     782              :                                                                              DataLoopNode::ConnectionType::Inlet,
     783              :                                                                              NodeInputManager::CompFluidStream::Primary,
     784              :                                                                              DataLoopNode::ObjectIsParent);
     785            0 :                 ventSlab.ReturnAirNode = NodeInputManager::GetOnlySingleNode(state,
     786            0 :                                                                              state.dataIPShortCut->cAlphaArgs(18),
     787              :                                                                              ErrorsFound,
     788              :                                                                              DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
     789            0 :                                                                              ventSlab.Name + "-OA MIXER",
     790              :                                                                              DataLoopNode::NodeFluidType::Air,
     791              :                                                                              DataLoopNode::ConnectionType::Inlet,
     792              :                                                                              NodeInputManager::CompFluidStream::Primary,
     793              :                                                                              DataLoopNode::ObjectIsNotParent);
     794            0 :                 ventSlab.RadInNode = NodeInputManager::GetOnlySingleNode(state,
     795            0 :                                                                          state.dataIPShortCut->cAlphaArgs(19),
     796              :                                                                          ErrorsFound,
     797              :                                                                          DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
     798            0 :                                                                          ventSlab.Name,
     799              :                                                                          DataLoopNode::NodeFluidType::Air,
     800              :                                                                          DataLoopNode::ConnectionType::Inlet,
     801              :                                                                          NodeInputManager::CompFluidStream::Primary,
     802              :                                                                          DataLoopNode::ObjectIsNotParent);
     803            0 :                 ventSlab.OAMixerOutNode = NodeInputManager::GetOnlySingleNode(state,
     804            0 :                                                                               state.dataIPShortCut->cAlphaArgs(23),
     805              :                                                                               ErrorsFound,
     806              :                                                                               DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
     807            0 :                                                                               ventSlab.Name + "-OA MIXER",
     808              :                                                                               DataLoopNode::NodeFluidType::Air,
     809              :                                                                               DataLoopNode::ConnectionType::Outlet,
     810              :                                                                               NodeInputManager::CompFluidStream::Primary,
     811              :                                                                               DataLoopNode::ObjectIsNotParent);
     812            0 :                 ventSlab.FanOutletNode = NodeInputManager::GetOnlySingleNode(state,
     813            0 :                                                                              state.dataIPShortCut->cAlphaArgs(24),
     814              :                                                                              ErrorsFound,
     815              :                                                                              DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
     816            0 :                                                                              ventSlab.Name,
     817              :                                                                              DataLoopNode::NodeFluidType::Air,
     818              :                                                                              DataLoopNode::ConnectionType::Internal,
     819              :                                                                              NodeInputManager::CompFluidStream::Primary,
     820              :                                                                              DataLoopNode::ObjectIsParent);
     821              :             }
     822              : 
     823            2 :             if (ventSlab.SysConfg == VentilatedSlabConfig::SlabOnly) {
     824            0 :                 if (!lAlphaBlanks(20)) {
     825            0 :                     ShowWarningError(state,
     826            0 :                                      format("{}=\"{}\" {}=\"{}\" not needed - ignored.",
     827              :                                             CurrentModuleObject,
     828            0 :                                             ventSlab.Name,
     829              :                                             cAlphaFields(20),
     830            0 :                                             state.dataIPShortCut->cAlphaArgs(20)));
     831            0 :                     ShowContinueError(state, "It is used for \"SlabAndZone\" only");
     832              :                 }
     833              : 
     834            2 :             } else if (ventSlab.SysConfg == VentilatedSlabConfig::SlabAndZone) {
     835            0 :                 if (lAlphaBlanks(20)) {
     836            0 :                     ShowSevereError(
     837            0 :                         state, format("{}=\"{}\" invalid {} is blank and must be entered.", CurrentModuleObject, ventSlab.Name, cAlphaFields(20)));
     838            0 :                     ErrorsFound = true;
     839              :                 }
     840              : 
     841            0 :                 ventSlab.ZoneAirInNode = NodeInputManager::GetOnlySingleNode(state,
     842            0 :                                                                              state.dataIPShortCut->cAlphaArgs(20),
     843              :                                                                              ErrorsFound,
     844              :                                                                              DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
     845            0 :                                                                              ventSlab.Name + "-SYSTEM",
     846              :                                                                              DataLoopNode::NodeFluidType::Air,
     847              :                                                                              DataLoopNode::ConnectionType::Outlet,
     848              :                                                                              NodeInputManager::CompFluidStream::Primary,
     849              :                                                                              DataLoopNode::ObjectIsParent);
     850              : 
     851            0 :                 ventSlab.ZoneAirInNode = NodeInputManager::GetOnlySingleNode(state,
     852            0 :                                                                              state.dataIPShortCut->cAlphaArgs(20),
     853              :                                                                              ErrorsFound,
     854              :                                                                              DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
     855            0 :                                                                              ventSlab.Name,
     856              :                                                                              DataLoopNode::NodeFluidType::Air,
     857              :                                                                              DataLoopNode::ConnectionType::Outlet,
     858              :                                                                              NodeInputManager::CompFluidStream::Primary,
     859              :                                                                              DataLoopNode::ObjectIsNotParent);
     860              :             }
     861              : 
     862              :             //  Set connection type to 'Inlet', because it now uses an OA node
     863            2 :             ventSlab.OutsideAirNode = NodeInputManager::GetOnlySingleNode(state,
     864            2 :                                                                           state.dataIPShortCut->cAlphaArgs(21),
     865              :                                                                           ErrorsFound,
     866              :                                                                           DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
     867            4 :                                                                           ventSlab.Name + "-OA MIXER",
     868              :                                                                           DataLoopNode::NodeFluidType::Air,
     869              :                                                                           DataLoopNode::ConnectionType::Inlet,
     870              :                                                                           NodeInputManager::CompFluidStream::Primary,
     871              :                                                                           DataLoopNode::ObjectIsNotParent);
     872              : 
     873            2 :             if (!lAlphaBlanks(21)) {
     874            2 :                 OutAirNodeManager::CheckAndAddAirNodeNumber(state, ventSlab.OutsideAirNode, IsValid);
     875            2 :                 if (!IsValid) {
     876            0 :                     ShowWarningError(
     877              :                         state,
     878            0 :                         format("{}=\"{}\", Adding OutdoorAir:Node={}", CurrentModuleObject, ventSlab.Name, state.dataIPShortCut->cAlphaArgs(21)));
     879              :                 }
     880              :             }
     881              : 
     882            2 :             ventSlab.AirReliefNode = NodeInputManager::GetOnlySingleNode(state,
     883            2 :                                                                          state.dataIPShortCut->cAlphaArgs(22),
     884              :                                                                          ErrorsFound,
     885              :                                                                          DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
     886            4 :                                                                          ventSlab.Name + "-OA MIXER",
     887              :                                                                          DataLoopNode::NodeFluidType::Air,
     888              :                                                                          DataLoopNode::ConnectionType::ReliefAir,
     889              :                                                                          NodeInputManager::CompFluidStream::Primary,
     890              :                                                                          DataLoopNode::ObjectIsNotParent);
     891              : 
     892              :             // Fan information:
     893            2 :             ventSlab.FanName = state.dataIPShortCut->cAlphaArgs(25);
     894              : 
     895            2 :             if ((ventSlab.Fan_Index = Fans::GetFanIndex(state, ventSlab.FanName)) == 0) {
     896            0 :                 ShowSevereItemNotFound(state, eoh, state.dataIPShortCut->cAlphaFieldNames(25), state.dataIPShortCut->cAlphaArgs(25));
     897            0 :                 ErrorsFound = true;
     898              :             } else {
     899            2 :                 ventSlab.fanType = state.dataFans->fans(ventSlab.Fan_Index)->type;
     900            2 :                 if (ventSlab.fanType != HVAC::FanType::Constant && ventSlab.fanType != HVAC::FanType::SystemModel) {
     901            0 :                     ShowSevereCustom(state,
     902              :                                      eoh,
     903            0 :                                      format("Only fans of type Fan:ConstantVolume and Fan:SystemModel are supported.  {} is of type {}",
     904            0 :                                             ventSlab.FanName,
     905            0 :                                             HVAC::fanTypeNames[(int)ventSlab.fanType]));
     906            0 :                     ErrorsFound = true;
     907              :                 }
     908              :             }
     909            2 :             if (ventSlab.outsideAirControlType == OutsideAirControlType::FixedOAControl) {
     910            0 :                 ventSlab.OutAirVolFlow = ventSlab.MinOutAirVolFlow;
     911            0 :                 ventSlab.maxOASched = ventSlab.minOASched;
     912              :             }
     913              : 
     914              :             // Add fan to component sets array
     915            4 :             BranchNodeConnections::SetUpCompSets(state,
     916              :                                                  CurrentModuleObject,
     917              :                                                  ventSlab.Name,
     918              :                                                  "UNDEFINED",
     919            2 :                                                  state.dataIPShortCut->cAlphaArgs(25),
     920            2 :                                                  state.dataIPShortCut->cAlphaArgs(23),
     921            2 :                                                  state.dataIPShortCut->cAlphaArgs(24));
     922              : 
     923              :             // Coil options assign
     924              : 
     925            2 :             ventSlab.coilOption = static_cast<CoilType>(getEnumValue(CoilTypeNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(26))));
     926              : 
     927            2 :             if (ventSlab.coilOption == CoilType::Invalid) {
     928            0 :                 ShowSevereError(
     929              :                     state,
     930            0 :                     format(
     931            0 :                         R"({}="{}" invalid {}="{}".)", CurrentModuleObject, ventSlab.Name, cAlphaFields(26), state.dataIPShortCut->cAlphaArgs(26)));
     932            0 :                 ErrorsFound = true;
     933              :             }
     934              : 
     935            2 :             if (ventSlab.coilOption == CoilType::Both || ventSlab.coilOption == CoilType::Heating) {
     936              :                 // Heating coil information:
     937              :                 //        A27, \field Heating Coil Object Type
     938              :                 //             \type choice
     939              :                 //             \key Coil:Heating:Water
     940              :                 //             \key Coil:Heating:Electric
     941              :                 //             \key Coil:Heating:Fuel
     942              :                 //             \key Coil:Heating:Steam
     943              :                 //        A28, \field Heating Coil Name
     944              :                 //             \type object-list
     945              :                 //             \object-list HeatingCoilName
     946              : 
     947              :                 // Heating coil information:
     948            2 :                 if (!lAlphaBlanks(28)) {
     949            2 :                     ventSlab.heatingCoilPresent = true;
     950            2 :                     ventSlab.heatingCoilTypeCh = state.dataIPShortCut->cAlphaArgs(27);
     951            2 :                     errFlag = false;
     952              : 
     953            2 :                     ventSlab.hCoilType =
     954            2 :                         static_cast<HeatingCoilType>(getEnumValue(HeatingCoilTypeNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(27))));
     955              : 
     956            2 :                     switch (ventSlab.hCoilType) {
     957              : 
     958            1 :                     case HeatingCoilType::Water: {
     959            1 :                         ventSlab.heatingCoilType = DataPlant::PlantEquipmentType::CoilWaterSimpleHeating;
     960            1 :                         break;
     961              :                     }
     962            0 :                     case HeatingCoilType::Steam: {
     963            0 :                         ventSlab.heatingCoilType = DataPlant::PlantEquipmentType::CoilSteamAirHeating;
     964            0 :                         ventSlab.heatingCoil_fluid = Fluid::GetSteam(state);
     965            0 :                         if (ventSlab.heatingCoil_fluid == nullptr) {
     966            0 :                             ShowSevereError(state, format("{}=\"{}Steam Properties not found.", CurrentModuleObject, ventSlab.Name));
     967            0 :                             if (SteamMessageNeeded) {
     968            0 :                                 ShowContinueError(state, "Steam Fluid Properties should have been included in the input file.");
     969              :                             }
     970            0 :                             ErrorsFound = true;
     971            0 :                             SteamMessageNeeded = false;
     972              :                         }
     973            0 :                         break;
     974              :                     }
     975            1 :                     case HeatingCoilType::Electric:
     976              :                     case HeatingCoilType::Gas:
     977            1 :                         break;
     978            0 :                     default: {
     979            0 :                         ShowSevereError(state,
     980            0 :                                         format(R"({}="{}" invalid {}="{}".)",
     981              :                                                CurrentModuleObject,
     982            0 :                                                ventSlab.Name,
     983              :                                                cAlphaFields(27),
     984            0 :                                                state.dataIPShortCut->cAlphaArgs(27)));
     985            0 :                         ErrorsFound = true;
     986            0 :                         errFlag = true;
     987            0 :                         break;
     988              :                     }
     989              :                     }
     990            2 :                     if (!errFlag) {
     991            2 :                         ventSlab.heatingCoilName = state.dataIPShortCut->cAlphaArgs(28);
     992            2 :                         ValidateComponent(state, state.dataIPShortCut->cAlphaArgs(27), ventSlab.heatingCoilName, IsNotOK, CurrentModuleObject);
     993            2 :                         if (IsNotOK) {
     994            0 :                             ShowContinueError(state,
     995            0 :                                               format("{}=\"{}\" invalid {}=\"{}\".",
     996              :                                                      CurrentModuleObject,
     997            0 :                                                      ventSlab.Name,
     998              :                                                      cAlphaFields(28),
     999            0 :                                                      state.dataIPShortCut->cAlphaArgs(28)));
    1000            0 :                             ShowContinueError(state, format("... not valid for {}=\"{}\".", cAlphaFields(27), state.dataIPShortCut->cAlphaArgs(27)));
    1001            0 :                             ErrorsFound = true;
    1002              :                         }
    1003              :                     }
    1004              : 
    1005            2 :                     ventSlab.MinVolHotWaterFlow = 0.0;
    1006            2 :                     ventSlab.MinVolHotSteamFlow = 0.0;
    1007              : 
    1008              :                     // The heating coil control node is necessary for a hot water coil, but not necessary for an
    1009              :                     // electric or gas coil.
    1010            2 :                     if (ventSlab.hCoilType == HeatingCoilType::Gas || ventSlab.hCoilType == HeatingCoilType::Electric) {
    1011            1 :                         if (!lAlphaBlanks(29)) {
    1012            0 :                             ShowWarningError(state,
    1013            0 :                                              format("{}=\"{}\" {}=\"{}\" not needed - ignored.",
    1014              :                                                     CurrentModuleObject,
    1015            0 :                                                     ventSlab.Name,
    1016              :                                                     cAlphaFields(29),
    1017            0 :                                                     state.dataIPShortCut->cAlphaArgs(29)));
    1018            0 :                             ShowContinueError(state, "..It is used for hot water coils only.");
    1019              :                         }
    1020              :                     } else {
    1021            1 :                         if (lAlphaBlanks(29)) {
    1022            0 :                             ShowSevereError(
    1023              :                                 state,
    1024            0 :                                 format("{}=\"{}\" invalid {} is blank and must be entered.", CurrentModuleObject, ventSlab.Name, cAlphaFields(29)));
    1025            0 :                             ErrorsFound = true;
    1026              :                         }
    1027            2 :                         ventSlab.HotControlNode = NodeInputManager::GetOnlySingleNode(state,
    1028            1 :                                                                                       state.dataIPShortCut->cAlphaArgs(29),
    1029              :                                                                                       ErrorsFound,
    1030              :                                                                                       DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
    1031            1 :                                                                                       ventSlab.Name,
    1032              :                                                                                       DataLoopNode::NodeFluidType::Water,
    1033              :                                                                                       DataLoopNode::ConnectionType::Actuator,
    1034              :                                                                                       NodeInputManager::CompFluidStream::Primary,
    1035              :                                                                                       DataLoopNode::ObjectIsParent);
    1036              :                     }
    1037            2 :                     ventSlab.HotControlOffset = 0.001;
    1038              : 
    1039            2 :                     if (ventSlab.hCoilType == HeatingCoilType::Water) {
    1040            1 :                         ventSlab.MaxVolHotWaterFlow = GetWaterCoilMaxFlowRate(state, "Coil:Heating:Water", ventSlab.heatingCoilName, ErrorsFound);
    1041            1 :                         ventSlab.MaxVolHotSteamFlow = GetWaterCoilMaxFlowRate(state, "Coil:Heating:Water", ventSlab.heatingCoilName, ErrorsFound);
    1042            1 :                     } else if (ventSlab.hCoilType == HeatingCoilType::Steam) {
    1043            0 :                         ventSlab.MaxVolHotWaterFlow = GetSteamCoilMaxFlowRate(state, "Coil:Heating:Steam", ventSlab.heatingCoilName, ErrorsFound);
    1044            0 :                         ventSlab.MaxVolHotSteamFlow = GetSteamCoilMaxFlowRate(state, "Coil:Heating:Steam", ventSlab.heatingCoilName, ErrorsFound);
    1045              :                     }
    1046              : 
    1047              :                 } else { // no heating coil
    1048            0 :                     ShowSevereError(state, format("{}=\"{}\" missing heating coil.", CurrentModuleObject, ventSlab.Name));
    1049            0 :                     ShowContinueError(state,
    1050            0 :                                       format("a heating coil is required for {}=\"{}\".", cAlphaFields(26), state.dataIPShortCut->cAlphaArgs(26)));
    1051            0 :                     ErrorsFound = true;
    1052              :                 }
    1053              :             }
    1054              : 
    1055            2 :             if (ventSlab.coilOption == CoilType::Both || ventSlab.coilOption == CoilType::Cooling) {
    1056              :                 // Cooling coil information (if one is present):
    1057              :                 //        A30, \field Cooling Coil Object Type
    1058              :                 //             \type choice
    1059              :                 //             \key Coil:Cooling:Water
    1060              :                 //             \key Coil:Cooling:Water:DetailedGeometry
    1061              :                 //             \key CoilSystem:Cooling:Water:HeatExchangerAssisted
    1062              :                 //        A31, \field Cooling Coil Name
    1063              :                 //             \type object-list
    1064              :                 //             \object-list CoolingCoilsWater
    1065              :                 // Cooling coil information (if one is present):
    1066            2 :                 if (!lAlphaBlanks(31)) {
    1067            2 :                     ventSlab.coolingCoilPresent = true;
    1068            2 :                     ventSlab.coolingCoilTypeCh = state.dataIPShortCut->cAlphaArgs(30);
    1069            2 :                     errFlag = false;
    1070              : 
    1071            2 :                     ventSlab.cCoilType =
    1072            2 :                         static_cast<CoolingCoilType>(getEnumValue(CoolingCoilTypeNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(30))));
    1073            2 :                     switch (ventSlab.cCoilType) {
    1074            2 :                     case CoolingCoilType::WaterCooling: {
    1075            2 :                         ventSlab.coolingCoilType = DataPlant::PlantEquipmentType::CoilWaterCooling;
    1076            2 :                         ventSlab.coolingCoilPlantName = state.dataIPShortCut->cAlphaArgs(31);
    1077            2 :                         break;
    1078              :                     }
    1079            0 :                     case CoolingCoilType::DetailedCooling: {
    1080            0 :                         ventSlab.coolingCoilType = DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling;
    1081            0 :                         ventSlab.coolingCoilPlantName = state.dataIPShortCut->cAlphaArgs(31);
    1082            0 :                         break;
    1083              :                     }
    1084            0 :                     case CoolingCoilType::HXAssisted: {
    1085            0 :                         HVACHXAssistedCoolingCoil::GetHXCoilTypeAndName(state,
    1086            0 :                                                                         state.dataIPShortCut->cAlphaArgs(30),
    1087            0 :                                                                         state.dataIPShortCut->cAlphaArgs(31),
    1088              :                                                                         ErrorsFound,
    1089            0 :                                                                         ventSlab.coolingCoilPlantType,
    1090            0 :                                                                         ventSlab.coolingCoilPlantName);
    1091            0 :                         if (Util::SameString(ventSlab.coolingCoilPlantType, "Coil:Cooling:Water")) {
    1092            0 :                             ventSlab.coolingCoilType = DataPlant::PlantEquipmentType::CoilWaterCooling;
    1093            0 :                         } else if (Util::SameString(ventSlab.coolingCoilPlantType, "Coil:Cooling:Water:DetailedGeometry")) {
    1094            0 :                             ventSlab.coolingCoilType = DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling;
    1095              :                         } else {
    1096            0 :                             ShowSevereError(state, format("GetVentilatedSlabInput: {}=\"{}\", invalid", CurrentModuleObject, ventSlab.Name));
    1097            0 :                             ShowContinueError(state, format("For: {}=\"{}\".", cAlphaFields(30), state.dataIPShortCut->cAlphaArgs(30)));
    1098            0 :                             ShowContinueError(state,
    1099            0 :                                               format("Invalid Coil Type={}, Name={}", ventSlab.coolingCoilPlantType, ventSlab.coolingCoilPlantName));
    1100            0 :                             ShowContinueError(state, R"(must be "Coil:Cooling:Water" or "Coil:Cooling:Water:DetailedGeometry")");
    1101            0 :                             ErrorsFound = true;
    1102              :                         }
    1103            0 :                         break;
    1104              :                     }
    1105            0 :                     default: {
    1106            0 :                         ShowSevereError(state,
    1107            0 :                                         format(R"({}="{}" invalid {}="{}".)",
    1108              :                                                CurrentModuleObject,
    1109            0 :                                                ventSlab.Name,
    1110              :                                                cAlphaFields(29),
    1111            0 :                                                state.dataIPShortCut->cAlphaArgs(29)));
    1112            0 :                         ErrorsFound = true;
    1113            0 :                         errFlag = true;
    1114            0 :                         break;
    1115              :                     }
    1116              :                     }
    1117              : 
    1118            2 :                     if (!errFlag) {
    1119            2 :                         ventSlab.coolingCoilName = state.dataIPShortCut->cAlphaArgs(31);
    1120            2 :                         ValidateComponent(state, state.dataIPShortCut->cAlphaArgs(30), ventSlab.coolingCoilName, IsNotOK, "ZoneHVAC:VentilatedSlab ");
    1121            2 :                         if (IsNotOK) {
    1122            0 :                             ShowContinueError(state,
    1123            0 :                                               format("{}=\"{}\" invalid {}=\"{}\".",
    1124              :                                                      CurrentModuleObject,
    1125            0 :                                                      ventSlab.Name,
    1126              :                                                      cAlphaFields(31),
    1127            0 :                                                      state.dataIPShortCut->cAlphaArgs(31)));
    1128            0 :                             ShowContinueError(state, format("... not valid for {}=\"{}\".", cAlphaFields(30), state.dataIPShortCut->cAlphaArgs(30)));
    1129            0 :                             ErrorsFound = true;
    1130              :                         }
    1131              :                     }
    1132              : 
    1133            2 :                     ventSlab.MinVolColdWaterFlow = 0.0;
    1134              : 
    1135            2 :                     ventSlab.ColdControlNode = NodeInputManager::GetOnlySingleNode(state,
    1136            2 :                                                                                    state.dataIPShortCut->cAlphaArgs(32),
    1137              :                                                                                    ErrorsFound,
    1138              :                                                                                    DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
    1139            2 :                                                                                    ventSlab.Name,
    1140              :                                                                                    DataLoopNode::NodeFluidType::Water,
    1141              :                                                                                    DataLoopNode::ConnectionType::Actuator,
    1142              :                                                                                    NodeInputManager::CompFluidStream::Primary,
    1143              :                                                                                    DataLoopNode::ObjectIsParent);
    1144              : 
    1145            2 :                     if (lAlphaBlanks(32)) {
    1146            0 :                         ShowSevereError(
    1147              :                             state,
    1148            0 :                             format("{}=\"{}\" invalid {} is blank and must be entered.", CurrentModuleObject, ventSlab.Name, cAlphaFields(32)));
    1149            0 :                         ErrorsFound = true;
    1150              :                     }
    1151              : 
    1152            2 :                     ventSlab.ColdControlOffset = 0.001;
    1153              : 
    1154            2 :                     if (ventSlab.cCoilType == CoolingCoilType::WaterCooling) {
    1155            2 :                         ventSlab.MaxVolColdWaterFlow = GetWaterCoilMaxFlowRate(state, "Coil:Cooling:Water", ventSlab.coolingCoilName, ErrorsFound);
    1156            0 :                     } else if (ventSlab.cCoilType == CoolingCoilType::DetailedCooling) {
    1157            0 :                         ventSlab.MaxVolColdWaterFlow =
    1158            0 :                             GetWaterCoilMaxFlowRate(state, "Coil:Cooling:Water:DetailedGeometry", ventSlab.coolingCoilName, ErrorsFound);
    1159            0 :                     } else if (ventSlab.cCoilType == CoolingCoilType::HXAssisted) {
    1160            0 :                         ventSlab.MaxVolColdWaterFlow =
    1161            0 :                             GetHXAssistedCoilFlowRate(state, "CoilSystem:Cooling:Water:HeatExchangerAssisted", ventSlab.coolingCoilName, ErrorsFound);
    1162              :                     }
    1163              : 
    1164              :                 } else { // No Cooling Coil
    1165            0 :                     ShowSevereError(state, format("{}=\"{}\" missing cooling coil.", CurrentModuleObject, ventSlab.Name));
    1166            0 :                     ShowContinueError(state,
    1167            0 :                                       format("a cooling coil is required for {}=\"{}\".", cAlphaFields(26), state.dataIPShortCut->cAlphaArgs(26)));
    1168            0 :                     ErrorsFound = true;
    1169              :                 }
    1170              :             }
    1171              : 
    1172            2 :             ventSlab.HVACSizingIndex = 0;
    1173            2 :             if (!lAlphaBlanks(34)) {
    1174            0 :                 ventSlab.HVACSizingIndex = Util::FindItemInList(state.dataIPShortCut->cAlphaArgs(34), state.dataSize->ZoneHVACSizing);
    1175            0 :                 if (ventSlab.HVACSizingIndex == 0) {
    1176            0 :                     ShowSevereError(state, format("{} = {} not found.", cAlphaFields(34), state.dataIPShortCut->cAlphaArgs(34)));
    1177            0 :                     ShowContinueError(state, format("Occurs in {} = {}", cMO_VentilatedSlab, ventSlab.Name));
    1178            0 :                     ErrorsFound = true;
    1179              :                 }
    1180              :             }
    1181              : 
    1182            2 :             switch (ventSlab.coilOption) {
    1183            2 :             case CoilType::Both: { // 'HeatingAndCooling'
    1184              :                 // Add cooling coil to component sets array when present
    1185            4 :                 BranchNodeConnections::SetUpCompSets(state,
    1186              :                                                      CurrentModuleObject,
    1187              :                                                      ventSlab.Name,
    1188            2 :                                                      state.dataIPShortCut->cAlphaArgs(30),
    1189            2 :                                                      state.dataIPShortCut->cAlphaArgs(31),
    1190            2 :                                                      state.dataIPShortCut->cAlphaArgs(24),
    1191              :                                                      "UNDEFINED");
    1192              : 
    1193              :                 // Add heating coil to component sets array when cooling coil present
    1194            6 :                 BranchNodeConnections::SetUpCompSets(state,
    1195              :                                                      CurrentModuleObject,
    1196              :                                                      ventSlab.Name,
    1197            2 :                                                      state.dataIPShortCut->cAlphaArgs(27),
    1198            2 :                                                      state.dataIPShortCut->cAlphaArgs(28),
    1199              :                                                      "UNDEFINED",
    1200            2 :                                                      state.dataIPShortCut->cAlphaArgs(19));
    1201            2 :                 break;
    1202              :             }
    1203            0 :             case CoilType::Heating: { // 'Heating'
    1204              :                 // Add heating coil to component sets array when no cooling coil present
    1205            0 :                 BranchNodeConnections::SetUpCompSets(state,
    1206              :                                                      CurrentModuleObject,
    1207              :                                                      ventSlab.Name,
    1208            0 :                                                      state.dataIPShortCut->cAlphaArgs(27),
    1209            0 :                                                      state.dataIPShortCut->cAlphaArgs(28),
    1210            0 :                                                      state.dataIPShortCut->cAlphaArgs(24),
    1211            0 :                                                      state.dataIPShortCut->cAlphaArgs(19));
    1212            0 :                 break;
    1213              :             }
    1214            0 :             case CoilType::Cooling: { // 'Cooling'
    1215              :                 // Add cooling coil to component sets array when no heating coil present
    1216            0 :                 BranchNodeConnections::SetUpCompSets(state,
    1217              :                                                      CurrentModuleObject,
    1218              :                                                      ventSlab.Name,
    1219            0 :                                                      state.dataIPShortCut->cAlphaArgs(30),
    1220            0 :                                                      state.dataIPShortCut->cAlphaArgs(31),
    1221            0 :                                                      state.dataIPShortCut->cAlphaArgs(24),
    1222            0 :                                                      state.dataIPShortCut->cAlphaArgs(19));
    1223            0 :                 break;
    1224              :             }
    1225            0 :             case CoilType::None:
    1226              :             default:
    1227            0 :                 break;
    1228              :             }
    1229              : 
    1230              :         } // ...loop over all of the ventilated slab found in the input file
    1231              : 
    1232            1 :         cAlphaArgs.deallocate();
    1233            1 :         cAlphaFields.deallocate();
    1234            1 :         cNumericFields.deallocate();
    1235            1 :         rNumericArgs.deallocate();
    1236            1 :         lAlphaBlanks.deallocate();
    1237            1 :         lNumericBlanks.deallocate();
    1238              : 
    1239            1 :         if (ErrorsFound) {
    1240            0 :             ShowFatalError(state, format("{} errors occurred in input.  Program terminates.", CurrentModuleObject));
    1241              :         }
    1242              : 
    1243              :         // Setup Report variables for the VENTILATED SLAB
    1244            3 :         for (Item = 1; Item <= state.dataVentilatedSlab->NumOfVentSlabs; ++Item) {
    1245            2 :             auto &ventSlab = state.dataVentilatedSlab->VentSlab(Item);
    1246            4 :             SetupOutputVariable(state,
    1247              :                                 "Zone Ventilated Slab Radiant Heating Rate",
    1248              :                                 Constant::Units::W,
    1249            2 :                                 ventSlab.RadHeatingPower,
    1250              :                                 OutputProcessor::TimeStepType::System,
    1251              :                                 OutputProcessor::StoreType::Average,
    1252            2 :                                 ventSlab.Name);
    1253            4 :             SetupOutputVariable(state,
    1254              :                                 "Zone Ventilated Slab Radiant Heating Energy",
    1255              :                                 Constant::Units::J,
    1256            2 :                                 ventSlab.RadHeatingEnergy,
    1257              :                                 OutputProcessor::TimeStepType::System,
    1258              :                                 OutputProcessor::StoreType::Sum,
    1259            2 :                                 ventSlab.Name);
    1260            4 :             SetupOutputVariable(state,
    1261              :                                 "Zone Ventilated Slab Radiant Cooling Rate",
    1262              :                                 Constant::Units::W,
    1263            2 :                                 ventSlab.RadCoolingPower,
    1264              :                                 OutputProcessor::TimeStepType::System,
    1265              :                                 OutputProcessor::StoreType::Average,
    1266            2 :                                 ventSlab.Name);
    1267            4 :             SetupOutputVariable(state,
    1268              :                                 "Zone Ventilated Slab Radiant Cooling Energy",
    1269              :                                 Constant::Units::J,
    1270            2 :                                 ventSlab.RadCoolingEnergy,
    1271              :                                 OutputProcessor::TimeStepType::System,
    1272              :                                 OutputProcessor::StoreType::Sum,
    1273            2 :                                 ventSlab.Name);
    1274            4 :             SetupOutputVariable(state,
    1275              :                                 "Zone Ventilated Slab Coil Heating Rate",
    1276              :                                 Constant::Units::W,
    1277            2 :                                 ventSlab.HeatCoilPower,
    1278              :                                 OutputProcessor::TimeStepType::System,
    1279              :                                 OutputProcessor::StoreType::Average,
    1280            2 :                                 ventSlab.Name);
    1281            4 :             SetupOutputVariable(state,
    1282              :                                 "Zone Ventilated Slab Coil Heating Energy",
    1283              :                                 Constant::Units::J,
    1284            2 :                                 ventSlab.HeatCoilEnergy,
    1285              :                                 OutputProcessor::TimeStepType::System,
    1286              :                                 OutputProcessor::StoreType::Sum,
    1287            2 :                                 ventSlab.Name);
    1288            4 :             SetupOutputVariable(state,
    1289              :                                 "Zone Ventilated Slab Coil Total Cooling Rate",
    1290              :                                 Constant::Units::W,
    1291            2 :                                 ventSlab.TotCoolCoilPower,
    1292              :                                 OutputProcessor::TimeStepType::System,
    1293              :                                 OutputProcessor::StoreType::Average,
    1294            2 :                                 ventSlab.Name);
    1295            4 :             SetupOutputVariable(state,
    1296              :                                 "Zone Ventilated Slab Coil Total Cooling Energy",
    1297              :                                 Constant::Units::J,
    1298            2 :                                 ventSlab.TotCoolCoilEnergy,
    1299              :                                 OutputProcessor::TimeStepType::System,
    1300              :                                 OutputProcessor::StoreType::Sum,
    1301            2 :                                 ventSlab.Name);
    1302            4 :             SetupOutputVariable(state,
    1303              :                                 "Zone Ventilated Slab Coil Sensible Cooling Rate",
    1304              :                                 Constant::Units::W,
    1305            2 :                                 ventSlab.SensCoolCoilPower,
    1306              :                                 OutputProcessor::TimeStepType::System,
    1307              :                                 OutputProcessor::StoreType::Average,
    1308            2 :                                 ventSlab.Name);
    1309            4 :             SetupOutputVariable(state,
    1310              :                                 "Zone Ventilated Slab Coil Sensible Cooling Energy",
    1311              :                                 Constant::Units::J,
    1312            2 :                                 ventSlab.SensCoolCoilEnergy,
    1313              :                                 OutputProcessor::TimeStepType::System,
    1314              :                                 OutputProcessor::StoreType::Sum,
    1315            2 :                                 ventSlab.Name);
    1316            4 :             SetupOutputVariable(state,
    1317              :                                 "Zone Ventilated Slab Coil Latent Cooling Rate",
    1318              :                                 Constant::Units::W,
    1319            2 :                                 ventSlab.LateCoolCoilPower,
    1320              :                                 OutputProcessor::TimeStepType::System,
    1321              :                                 OutputProcessor::StoreType::Average,
    1322            2 :                                 ventSlab.Name);
    1323            4 :             SetupOutputVariable(state,
    1324              :                                 "Zone Ventilated Slab Coil Latent Cooling Energy",
    1325              :                                 Constant::Units::J,
    1326            2 :                                 ventSlab.LateCoolCoilEnergy,
    1327              :                                 OutputProcessor::TimeStepType::System,
    1328              :                                 OutputProcessor::StoreType::Sum,
    1329            2 :                                 ventSlab.Name);
    1330            4 :             SetupOutputVariable(state,
    1331              :                                 "Zone Ventilated Slab Air Mass Flow Rate",
    1332              :                                 Constant::Units::kg_s,
    1333            2 :                                 ventSlab.AirMassFlowRate,
    1334              :                                 OutputProcessor::TimeStepType::System,
    1335              :                                 OutputProcessor::StoreType::Average,
    1336            2 :                                 ventSlab.Name);
    1337            4 :             SetupOutputVariable(state,
    1338              :                                 "Zone Ventilated Slab Fan Electricity Rate",
    1339              :                                 Constant::Units::W,
    1340            2 :                                 ventSlab.ElecFanPower,
    1341              :                                 OutputProcessor::TimeStepType::System,
    1342              :                                 OutputProcessor::StoreType::Average,
    1343            2 :                                 ventSlab.Name);
    1344              :             //! Note that the ventilated slab fan electric is NOT metered because this value is already metered through the fan component
    1345            4 :             SetupOutputVariable(state,
    1346              :                                 "Zone Ventilated Slab Fan Electricity Energy",
    1347              :                                 Constant::Units::J,
    1348            2 :                                 ventSlab.ElecFanEnergy,
    1349              :                                 OutputProcessor::TimeStepType::System,
    1350              :                                 OutputProcessor::StoreType::Sum,
    1351            2 :                                 ventSlab.Name);
    1352            4 :             SetupOutputVariable(state,
    1353              :                                 "Zone Ventilated Slab Inlet Air Temperature",
    1354              :                                 Constant::Units::C,
    1355            2 :                                 ventSlab.SlabInTemp,
    1356              :                                 OutputProcessor::TimeStepType::System,
    1357              :                                 OutputProcessor::StoreType::Average,
    1358            2 :                                 ventSlab.Name);
    1359            4 :             SetupOutputVariable(state,
    1360              :                                 "Zone Ventilated Slab Outlet Air Temperature",
    1361              :                                 Constant::Units::C,
    1362            2 :                                 ventSlab.SlabOutTemp,
    1363              :                                 OutputProcessor::TimeStepType::System,
    1364              :                                 OutputProcessor::StoreType::Average,
    1365            2 :                                 ventSlab.Name);
    1366            4 :             SetupOutputVariable(state,
    1367              :                                 "Zone Ventilated Slab Zone Inlet Air Temperature",
    1368              :                                 Constant::Units::C,
    1369            2 :                                 ventSlab.ZoneInletTemp,
    1370              :                                 OutputProcessor::TimeStepType::System,
    1371              :                                 OutputProcessor::StoreType::Average,
    1372            2 :                                 ventSlab.Name);
    1373            4 :             SetupOutputVariable(state,
    1374              :                                 "Zone Ventilated Slab Return Air Temperature",
    1375              :                                 Constant::Units::C,
    1376            2 :                                 ventSlab.ReturnAirTemp,
    1377              :                                 OutputProcessor::TimeStepType::System,
    1378              :                                 OutputProcessor::StoreType::Average,
    1379            2 :                                 ventSlab.Name);
    1380            4 :             SetupOutputVariable(state,
    1381              :                                 "Zone Ventilated Slab Fan Outlet Air Temperature",
    1382              :                                 Constant::Units::C,
    1383            2 :                                 ventSlab.FanOutletTemp,
    1384              :                                 OutputProcessor::TimeStepType::System,
    1385              :                                 OutputProcessor::StoreType::Average,
    1386            2 :                                 ventSlab.Name);
    1387            2 :             SetupOutputVariable(state,
    1388              :                                 "Zone Ventilated Slab Fan Availability Status",
    1389              :                                 Constant::Units::None,
    1390            2 :                                 (int &)ventSlab.availStatus,
    1391              :                                 OutputProcessor::TimeStepType::System,
    1392              :                                 OutputProcessor::StoreType::Average,
    1393            2 :                                 ventSlab.Name);
    1394              :         }
    1395            1 :     }
    1396              : 
    1397            1 :     void InitVentilatedSlab(EnergyPlusData &state,
    1398              :                             int const Item,               // index for the current ventilated slab
    1399              :                             int const VentSlabZoneNum,    // number of zone being served
    1400              :                             bool const FirstHVACIteration // TRUE if 1st HVAC simulation of system timestep
    1401              :     )
    1402              :     {
    1403              : 
    1404              :         // SUBROUTINE INFORMATION:
    1405              :         //       AUTHOR         Young Tae Chae, Rick Strand
    1406              :         //       DATE WRITTEN   June 2008
    1407              :         //       MODIFIED       July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
    1408              : 
    1409              :         // PURPOSE OF THIS SUBROUTINE:
    1410              :         // This subroutine initializes all of the data elements which are necessary
    1411              :         // to simulate a Ventilated Slab.
    1412              : 
    1413              :         // METHODOLOGY EMPLOYED:
    1414              :         // Uses the status flags to trigger initializations.
    1415              : 
    1416              :         // Using/Aliasing
    1417            1 :         auto &ventSlab = state.dataVentilatedSlab->VentSlab(Item);
    1418              : 
    1419              :         // SUBROUTINE PARAMETER DEFINITIONS:
    1420              :         static constexpr std::string_view RoutineName("InitVentilatedSlab");
    1421              : 
    1422              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1423              :         int AirRelNode; // relief air node number in Ventilated Slab loop
    1424              :         Real64 RhoAir;  // air density at InNode
    1425              :         Real64 TempSteamIn;
    1426              :         Real64 SteamDensity;
    1427              :         Real64 rho;
    1428              : 
    1429              :         // Do the one time initializations
    1430              : 
    1431            1 :         if (state.dataVentilatedSlab->MyOneTimeFlag) {
    1432            1 :             state.dataVentilatedSlab->MyEnvrnFlag.allocate(state.dataVentilatedSlab->NumOfVentSlabs);
    1433            1 :             state.dataVentilatedSlab->MySizeFlag.allocate(state.dataVentilatedSlab->NumOfVentSlabs);
    1434            1 :             state.dataVentilatedSlab->MyPlantScanFlag.allocate(state.dataVentilatedSlab->NumOfVentSlabs);
    1435            1 :             state.dataVentilatedSlab->MyZoneEqFlag.allocate(state.dataVentilatedSlab->NumOfVentSlabs);
    1436              : 
    1437              :             // Initialize total areas for all radiant systems and dimension record keeping arrays
    1438            3 :             for (auto &thisVentSlab : state.dataVentilatedSlab->VentSlab) {
    1439            2 :                 thisVentSlab.TotalSurfaceArea = 0.0;
    1440            2 :                 int numRadSurfs = thisVentSlab.NumOfSurfaces;
    1441            7 :                 for (int SurfNum = 1; SurfNum <= numRadSurfs; ++SurfNum) {
    1442            5 :                     thisVentSlab.TotalSurfaceArea += state.dataSurface->Surface(thisVentSlab.SurfacePtr(SurfNum)).Area;
    1443              :                 }
    1444            2 :                 thisVentSlab.QRadSysSrcAvg.dimension(numRadSurfs, 0.0);
    1445            2 :                 thisVentSlab.LastQRadSysSrc.dimension(numRadSurfs, 0.0);
    1446            2 :                 thisVentSlab.LastSysTimeElapsed = 0.0;
    1447            2 :                 thisVentSlab.LastTimeStepSys = 0.0;
    1448            1 :             }
    1449            1 :             state.dataVentilatedSlab->MyEnvrnFlag = true;
    1450            1 :             state.dataVentilatedSlab->MySizeFlag = true;
    1451            1 :             state.dataVentilatedSlab->MyPlantScanFlag = true;
    1452            1 :             state.dataVentilatedSlab->MyZoneEqFlag = true;
    1453            1 :             state.dataVentilatedSlab->MyOneTimeFlag = false;
    1454              :         }
    1455              : 
    1456            1 :         if (allocated(state.dataAvail->ZoneComp)) {
    1457            0 :             auto &availMgr = state.dataAvail->ZoneComp(DataZoneEquipment::ZoneEquipType::VentilatedSlab).ZoneCompAvailMgrs(Item);
    1458            0 :             if (state.dataVentilatedSlab->MyZoneEqFlag(Item)) { // initialize the name of each availability manager list and zone number
    1459            0 :                 availMgr.AvailManagerListName = ventSlab.AvailManagerListName;
    1460            0 :                 availMgr.ZoneNum = VentSlabZoneNum;
    1461            0 :                 state.dataVentilatedSlab->MyZoneEqFlag(Item) = false;
    1462              :             }
    1463            0 :             ventSlab.availStatus = availMgr.availStatus;
    1464              :         }
    1465              : 
    1466            1 :         if (state.dataVentilatedSlab->MyPlantScanFlag(Item) && allocated(state.dataPlnt->PlantLoop)) {
    1467            0 :             if ((ventSlab.heatingCoilType == DataPlant::PlantEquipmentType::CoilWaterSimpleHeating) ||
    1468            0 :                 (ventSlab.heatingCoilType == DataPlant::PlantEquipmentType::CoilSteamAirHeating)) {
    1469            0 :                 bool errFlag = false;
    1470            0 :                 PlantUtilities::ScanPlantLoopsForObject(
    1471            0 :                     state, ventSlab.heatingCoilName, ventSlab.heatingCoilType, ventSlab.HWPlantLoc, errFlag, _, _, _, _, _);
    1472            0 :                 if (errFlag) {
    1473            0 :                     ShowContinueError(state, format("Reference Unit=\"{}\", type=ZoneHVAC:VentilatedSlab", ventSlab.Name));
    1474            0 :                     ShowFatalError(state, "InitVentilatedSlab: Program terminated due to previous condition(s).");
    1475              :                 }
    1476              : 
    1477            0 :                 ventSlab.HotCoilOutNodeNum = DataPlant::CompData::getPlantComponent(state, ventSlab.HWPlantLoc).NodeNumOut;
    1478              :             }
    1479            0 :             if ((ventSlab.coolingCoilType == DataPlant::PlantEquipmentType::CoilWaterCooling) ||
    1480            0 :                 (ventSlab.coolingCoilType == DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling)) {
    1481            0 :                 bool errFlag = false;
    1482            0 :                 PlantUtilities::ScanPlantLoopsForObject(state, ventSlab.coolingCoilPlantName, ventSlab.coolingCoilType, ventSlab.CWPlantLoc, errFlag);
    1483            0 :                 if (errFlag) {
    1484            0 :                     ShowContinueError(state, format("Reference Unit=\"{}\", type=ZoneHVAC:VentilatedSlab", ventSlab.Name));
    1485            0 :                     ShowFatalError(state, "InitVentilatedSlab: Program terminated due to previous condition(s).");
    1486              :                 }
    1487            0 :                 ventSlab.ColdCoilOutNodeNum = DataPlant::CompData::getPlantComponent(state, ventSlab.CWPlantLoc).NodeNumOut;
    1488            0 :             } else {
    1489            0 :                 if (ventSlab.coolingCoilPresent) {
    1490            0 :                     ShowFatalError(state, format("InitVentilatedSlab: Unit={}, invalid cooling coil type. Program terminated.", ventSlab.Name));
    1491              :                 }
    1492              :             }
    1493            0 :             state.dataVentilatedSlab->MyPlantScanFlag(Item) = false;
    1494            1 :         } else if (state.dataVentilatedSlab->MyPlantScanFlag(Item) && !state.dataGlobal->AnyPlantInModel) {
    1495            1 :             state.dataVentilatedSlab->MyPlantScanFlag(Item) = false;
    1496              :         }
    1497              : 
    1498              :         // need to check all Ventilated Slab units to see if they are on Zone Equipment List or issue warning
    1499            1 :         if (!state.dataVentilatedSlab->ZoneEquipmentListChecked && state.dataZoneEquip->ZoneEquipInputsFilled) {
    1500            1 :             state.dataVentilatedSlab->ZoneEquipmentListChecked = true;
    1501            3 :             for (int RadNum = 1; RadNum <= state.dataVentilatedSlab->NumOfVentSlabs; ++RadNum) {
    1502            2 :                 if (DataZoneEquipment::CheckZoneEquipmentList(state, cMO_VentilatedSlab, state.dataVentilatedSlab->VentSlab(RadNum).Name)) {
    1503            2 :                     continue;
    1504              :                 }
    1505            0 :                 ShowSevereError(
    1506              :                     state,
    1507            0 :                     format("InitVentilatedSlab: Ventilated Slab Unit=[{},{}] is not on any ZoneHVAC:EquipmentList.  It will not be simulated.",
    1508              :                            cMO_VentilatedSlab,
    1509            0 :                            state.dataVentilatedSlab->VentSlab(RadNum).Name));
    1510              :             }
    1511              :         }
    1512              : 
    1513            1 :         if (!state.dataGlobal->SysSizingCalc && state.dataVentilatedSlab->MySizeFlag(Item) && !state.dataVentilatedSlab->MyPlantScanFlag(Item)) {
    1514              : 
    1515            1 :             SizeVentilatedSlab(state, Item);
    1516              : 
    1517            1 :             state.dataVentilatedSlab->MySizeFlag(Item) = false;
    1518              :         }
    1519              : 
    1520            1 :         int InNode = ventSlab.ReturnAirNode;
    1521            1 :         int OutNode = ventSlab.RadInNode;
    1522            1 :         int OutsideAirNode = ventSlab.OutsideAirNode;
    1523              : 
    1524              :         // Do the one time initializations
    1525            1 :         if (state.dataGlobal->BeginEnvrnFlag && state.dataVentilatedSlab->MyEnvrnFlag(Item) && !state.dataVentilatedSlab->MyPlantScanFlag(Item)) {
    1526              : 
    1527              :             // Coil Part
    1528            0 :             RhoAir = state.dataEnvrn->StdRhoAir;
    1529              : 
    1530            0 :             if (state.dataVentilatedSlab->NumOfVentSlabs > 0) {
    1531            0 :                 for (auto &e : state.dataVentilatedSlab->VentSlab) {
    1532            0 :                     e.ZeroVentSlabSourceSumHATsurf = 0.0;
    1533            0 :                     e.RadHeatingPower = 0.0;
    1534            0 :                     e.RadHeatingEnergy = 0.0;
    1535            0 :                     e.RadCoolingPower = 0.0;
    1536            0 :                     e.RadCoolingEnergy = 0.0;
    1537            0 :                     e.QRadSysSrcAvg = 0.0;
    1538            0 :                     e.LastQRadSysSrc = 0.0;
    1539            0 :                     e.LastSysTimeElapsed = 0.0;
    1540            0 :                     e.LastTimeStepSys = 0.0;
    1541            0 :                 }
    1542              :             }
    1543              : 
    1544              :             // set the initial Temperature of Return Air
    1545              : 
    1546              :             // set the mass flow rates from the input volume flow rates
    1547            0 :             ventSlab.MaxAirMassFlow = RhoAir * ventSlab.MaxAirVolFlow;
    1548            0 :             ventSlab.OutAirMassFlow = RhoAir * ventSlab.OutAirVolFlow;
    1549            0 :             ventSlab.MinOutAirMassFlow = RhoAir * ventSlab.MinOutAirVolFlow;
    1550            0 :             if (ventSlab.OutAirMassFlow > ventSlab.MaxAirMassFlow) {
    1551            0 :                 ventSlab.OutAirMassFlow = ventSlab.MaxAirMassFlow;
    1552            0 :                 ventSlab.MinOutAirMassFlow = ventSlab.OutAirMassFlow * (ventSlab.MinOutAirVolFlow / ventSlab.OutAirVolFlow);
    1553            0 :                 ShowWarningError(state,
    1554            0 :                                  format("Outdoor air mass flow rate higher than unit flow rate, reset to unit flow rate for {}", ventSlab.Name));
    1555              :             }
    1556              : 
    1557              :             // set the node max and min mass flow rates
    1558            0 :             state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMax = ventSlab.OutAirMassFlow;
    1559            0 :             state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMin = 0.0;
    1560              : 
    1561            0 :             state.dataLoopNodes->Node(OutNode).MassFlowRateMax = ventSlab.MaxAirMassFlow;
    1562            0 :             state.dataLoopNodes->Node(OutNode).MassFlowRateMin = 0.0;
    1563              : 
    1564            0 :             state.dataLoopNodes->Node(InNode).MassFlowRateMax = ventSlab.MaxAirMassFlow;
    1565            0 :             state.dataLoopNodes->Node(InNode).MassFlowRateMin = 0.0;
    1566              : 
    1567            0 :             if (ventSlab.heatingCoilPresent) { // Only initialize these if a heating coil is actually present
    1568              : 
    1569            0 :                 if (ventSlab.heatingCoilType == DataPlant::PlantEquipmentType::CoilWaterSimpleHeating &&
    1570            0 :                     !state.dataVentilatedSlab->MyPlantScanFlag(Item)) {
    1571            0 :                     rho = state.dataPlnt->PlantLoop(ventSlab.HWPlantLoc.loopNum).glycol->getDensity(state, Constant::HWInitConvTemp, RoutineName);
    1572              : 
    1573            0 :                     ventSlab.MaxHotWaterFlow = rho * ventSlab.MaxVolHotWaterFlow;
    1574            0 :                     ventSlab.MinHotWaterFlow = rho * ventSlab.MinVolHotWaterFlow;
    1575              : 
    1576            0 :                     PlantUtilities::InitComponentNodes(
    1577              :                         state, ventSlab.MinHotWaterFlow, ventSlab.MaxHotWaterFlow, ventSlab.HotControlNode, ventSlab.HotCoilOutNodeNum);
    1578              :                 }
    1579            0 :                 if (ventSlab.heatingCoilType == DataPlant::PlantEquipmentType::CoilSteamAirHeating &&
    1580            0 :                     !state.dataVentilatedSlab->MyPlantScanFlag(Item)) {
    1581            0 :                     TempSteamIn = 100.00;
    1582            0 :                     SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, RoutineName);
    1583            0 :                     ventSlab.MaxHotSteamFlow = SteamDensity * ventSlab.MaxVolHotSteamFlow;
    1584            0 :                     ventSlab.MinHotSteamFlow = SteamDensity * ventSlab.MinVolHotSteamFlow;
    1585              : 
    1586            0 :                     PlantUtilities::InitComponentNodes(
    1587              :                         state, ventSlab.MinHotSteamFlow, ventSlab.MaxHotSteamFlow, ventSlab.HotControlNode, ventSlab.HotCoilOutNodeNum);
    1588              :                 }
    1589              :             } //(VentSlab(Item)%HCoilPresent)
    1590              : 
    1591            0 :             if (ventSlab.coolingCoilPresent && !state.dataVentilatedSlab->MyPlantScanFlag(Item)) {
    1592              :                 // Only initialize these if a cooling coil is actually present
    1593            0 :                 if ((ventSlab.coolingCoilType == DataPlant::PlantEquipmentType::CoilWaterCooling) ||
    1594            0 :                     (ventSlab.coolingCoilType == DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling)) {
    1595            0 :                     rho = state.dataPlnt->PlantLoop(ventSlab.CWPlantLoc.loopNum).glycol->getDensity(state, Constant::CWInitConvTemp, RoutineName);
    1596            0 :                     ventSlab.MaxColdWaterFlow = rho * ventSlab.MaxVolColdWaterFlow;
    1597            0 :                     ventSlab.MinColdWaterFlow = rho * ventSlab.MinVolColdWaterFlow;
    1598            0 :                     PlantUtilities::InitComponentNodes(
    1599              :                         state, ventSlab.MinColdWaterFlow, ventSlab.MaxColdWaterFlow, ventSlab.ColdControlNode, ventSlab.ColdCoilOutNodeNum);
    1600              :                 }
    1601              :             }
    1602              : 
    1603            0 :             state.dataVentilatedSlab->MyEnvrnFlag(Item) = false;
    1604              : 
    1605              :         } // ...end start of environment inits
    1606              : 
    1607            1 :         if (!state.dataGlobal->BeginEnvrnFlag) {
    1608              : 
    1609            1 :             state.dataVentilatedSlab->MyEnvrnFlag(Item) = true;
    1610              :         }
    1611              : 
    1612              :         // These initializations are done every iteration...
    1613            1 :         AirRelNode = ventSlab.AirReliefNode;
    1614              : 
    1615              :         // First, set the flow conditions up so that there is flow through the ventilated
    1616              :         // slab system(this will be shut down if the system is not available or there
    1617              :         // is no load
    1618            1 :         state.dataLoopNodes->Node(InNode).MassFlowRate = ventSlab.MaxAirMassFlow;
    1619            1 :         state.dataLoopNodes->Node(InNode).MassFlowRateMaxAvail = ventSlab.MaxAirMassFlow;
    1620            1 :         state.dataLoopNodes->Node(InNode).MassFlowRateMinAvail = ventSlab.MaxAirMassFlow;
    1621            1 :         state.dataLoopNodes->Node(OutNode).MassFlowRate = ventSlab.MaxAirMassFlow;
    1622            1 :         state.dataLoopNodes->Node(OutNode).MassFlowRateMaxAvail = ventSlab.MaxAirMassFlow;
    1623            1 :         state.dataLoopNodes->Node(OutNode).MassFlowRateMinAvail = ventSlab.MaxAirMassFlow;
    1624            1 :         state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate = ventSlab.OutAirMassFlow;
    1625            1 :         state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMaxAvail = ventSlab.OutAirMassFlow;
    1626            1 :         state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMinAvail = ventSlab.OutAirMassFlow;
    1627            1 :         state.dataLoopNodes->Node(AirRelNode).MassFlowRate = ventSlab.OutAirMassFlow;
    1628            1 :         state.dataLoopNodes->Node(AirRelNode).MassFlowRateMaxAvail = ventSlab.OutAirMassFlow;
    1629            1 :         state.dataLoopNodes->Node(AirRelNode).MassFlowRateMinAvail = ventSlab.OutAirMassFlow;
    1630              : 
    1631              :         // Initialize the relief air (same as inlet conditions to the Ventilated Slab ..
    1632              :         // Note that mass flow rates will be taken care of later.
    1633            1 :         state.dataLoopNodes->Node(AirRelNode) = state.dataLoopNodes->Node(InNode);
    1634            1 :         state.dataVentilatedSlab->OAMassFlowRate = 0.0;
    1635              : 
    1636              :         // Just in case the system is off and conditions do not get sent through
    1637              :         // the system for some reason, set the outlet conditions equal to the inlet
    1638              :         // conditions of the ventilated slab mixer
    1639            1 :         state.dataLoopNodes->Node(OutNode).Temp = state.dataLoopNodes->Node(InNode).Temp;
    1640            1 :         state.dataLoopNodes->Node(OutNode).Press = state.dataLoopNodes->Node(InNode).Press;
    1641            1 :         state.dataLoopNodes->Node(OutNode).HumRat = state.dataLoopNodes->Node(InNode).HumRat;
    1642            1 :         state.dataLoopNodes->Node(OutNode).Enthalpy = state.dataLoopNodes->Node(InNode).Enthalpy;
    1643              : 
    1644              :         // These initializations only need to be done once at the start of the iterations...
    1645            1 :         if (state.dataGlobal->BeginTimeStepFlag && FirstHVACIteration) {
    1646              :             // Initialize the outside air conditions...
    1647            0 :             state.dataLoopNodes->Node(OutsideAirNode).Temp = state.dataLoopNodes->Node(OutsideAirNode).OutAirDryBulb;
    1648            0 :             state.dataLoopNodes->Node(OutsideAirNode).HumRat = state.dataEnvrn->OutHumRat;
    1649            0 :             state.dataLoopNodes->Node(OutsideAirNode).Press = state.dataEnvrn->OutBaroPress;
    1650              : 
    1651              :             // The first pass through in a particular time step
    1652            0 :             int ZoneNum = ventSlab.ZonePtr;
    1653            0 :             ventSlab.ZeroVentSlabSourceSumHATsurf =
    1654            0 :                 state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state); // Set this to figure what part of the load the radiant system meets
    1655            0 :             ventSlab.QRadSysSrcAvg = 0.0;                           // Initialize this variable to zero (radiant system defaults to off)
    1656            0 :             ventSlab.LastQRadSysSrc = 0.0;     // At the start of a time step, reset to zero so average calculation can begin again
    1657            0 :             ventSlab.LastSysTimeElapsed = 0.0; // At the start of a time step, reset to zero so average calculation can begin again
    1658            0 :             ventSlab.LastTimeStepSys = 0.0;    // At the start of a time step, reset to zero so average calculation can begin again
    1659              :         }
    1660            1 :     }
    1661              : 
    1662            1 :     void SizeVentilatedSlab(EnergyPlusData &state, int const Item)
    1663              :     {
    1664              : 
    1665              :         // SUBROUTINE INFORMATION:
    1666              :         //       AUTHOR         Young Tae Chae, Rick Strand
    1667              :         //       DATE WRITTEN   June 2008
    1668              :         //       MODIFIED       July 2013 Daeho Kang, add component sizing table entries
    1669              :         //                      July 2014, B. Nigusse, added scalable sizing
    1670              : 
    1671              :         // PURPOSE OF THIS SUBROUTINE:
    1672              :         // This subroutine is for sizing Ventilated Slab components for which flow rates have not been
    1673              :         // specified in the input.
    1674              : 
    1675              :         // METHODOLOGY EMPLOYED:
    1676              :         // Obtains flow rates from the zone sizing arrays and plant sizing data.
    1677              : 
    1678              :         // SUBROUTINE PARAMETER DEFINITIONS:
    1679              :         static constexpr std::string_view RoutineName("SizeVentilatedSlab");
    1680              : 
    1681            1 :         int CurZoneEqNum = state.dataSize->CurZoneEqNum;
    1682            1 :         auto &ventSlab = state.dataVentilatedSlab->VentSlab(Item);
    1683              : 
    1684              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1685              :         bool ErrorsFound;
    1686              :         Real64 DesCoilLoad;
    1687              :         Real64 TempSteamIn;
    1688              :         Real64 EnthSteamInDry;
    1689              :         Real64 EnthSteamOutWet;
    1690              :         Real64 LatentHeatSteam;
    1691              :         Real64 SteamDensity;
    1692            1 :         std::string CoolingCoilName;
    1693            1 :         std::string CoolingCoilType;
    1694              :         Real64 rho;
    1695              :         Real64 Cp;
    1696              :         Real64 MaxAirVolFlowDes;        // Autosized maximum air flow for reporting
    1697              :         Real64 MaxAirVolFlowUser;       // Hardsized maximum air flow for reporting
    1698              :         Real64 OutAirVolFlowDes;        // Autosized outdoor air flow for reporting
    1699              :         Real64 OutAirVolFlowUser;       // Hardsized outdoor air flow for reporting
    1700              :         Real64 MinOutAirVolFlowDes;     // Autosized minimum outdoor air flow for reporting
    1701              :         Real64 MinOutAirVolFlowUser;    // Hardsized minimum outdoor air flow for reporting
    1702              :         Real64 MaxVolHotWaterFlowDes;   // Autosized maximum hot water flow for reporting
    1703              :         Real64 MaxVolHotWaterFlowUser;  // Hardsized maximum hot water flow for reporting
    1704              :         Real64 MaxVolHotSteamFlowDes;   // Autosized maximum hot steam flow for reporting
    1705              :         Real64 MaxVolHotSteamFlowUser;  // Hardsized maximum hot steam flow for reporting
    1706              :         Real64 MaxVolColdWaterFlowDes;  // Autosized maximum cold water flow for reporting
    1707              :         Real64 MaxVolColdWaterFlowUser; // Hardsized maximum cold water flow for reporting
    1708            1 :         std::string CompName;           // component name
    1709            1 :         std::string CompType;           // component type
    1710            1 :         std::string SizingString;       // input field sizing description (e.g., Nominal Capacity)
    1711              :         Real64 TempSize;                // autosized value of coil input field
    1712            1 :         int FieldNum = 2;               // IDD numeric field number where input field description is found
    1713              :         int SizingMethod;  // Integer representation of sizing method name (e.g., CoolingAirflowSizing, HeatingAirflowSizing, CoolingCapacitySizing,
    1714              :                            // HeatingCapacitySizing, etc.)
    1715              :         bool PrintFlag;    // TRUE when sizing information is reported in the eio file
    1716              :         int zoneHVACIndex; // index of zoneHVAC equipment sizing specification
    1717              :         Real64 CoolingAirVolFlowScalable; // cooling airvolume for rate determined using scalable sizing method
    1718              :         Real64 HeatingAirVolFlowScalable; // heating airvolume for rate determined using scalable sizing method
    1719              :         bool DoWaterCoilSizing;           // if TRUE do water coil sizing calculation
    1720              :         Real64 WaterCoilSizDeltaT;        // water coil deltaT for design water flow rate autosizing
    1721              : 
    1722            1 :         WaterCoilSizDeltaT = 0.0;
    1723            1 :         ErrorsFound = false;
    1724            1 :         MaxAirVolFlowDes = 0.0;
    1725            1 :         MaxAirVolFlowUser = 0.0;
    1726            1 :         OutAirVolFlowDes = 0.0;
    1727            1 :         OutAirVolFlowUser = 0.0;
    1728            1 :         MinOutAirVolFlowDes = 0.0;
    1729            1 :         MinOutAirVolFlowUser = 0.0;
    1730            1 :         MaxVolHotWaterFlowDes = 0.0;
    1731            1 :         MaxVolHotWaterFlowUser = 0.0;
    1732            1 :         MaxVolHotSteamFlowDes = 0.0;
    1733            1 :         MaxVolHotSteamFlowUser = 0.0;
    1734            1 :         MaxVolColdWaterFlowDes = 0.0;
    1735            1 :         MaxVolColdWaterFlowUser = 0.0;
    1736            1 :         CoolingAirVolFlowScalable = 0.0;
    1737            1 :         HeatingAirVolFlowScalable = 0.0;
    1738            1 :         state.dataSize->DataScalableSizingON = false;
    1739            1 :         state.dataSize->DataScalableCapSizingON = false;
    1740            1 :         CompType = cMO_VentilatedSlab;
    1741            1 :         CompName = ventSlab.Name;
    1742            1 :         state.dataSize->DataZoneNumber = ventSlab.ZonePtr;
    1743            1 :         state.dataSize->DataFanType = ventSlab.fanType;
    1744            1 :         state.dataSize->DataFanIndex = ventSlab.Fan_Index;
    1745              :         // ventilated slab unit is always blow thru
    1746            1 :         state.dataSize->DataFanPlacement = HVAC::FanPlace::BlowThru;
    1747              : 
    1748            1 :         if (ventSlab.HVACSizingIndex > 0) {
    1749            0 :             zoneHVACIndex = ventSlab.HVACSizingIndex;
    1750              :             // N1 , \field Maximum Supply Air Flow Rate
    1751            0 :             FieldNum = 1;
    1752            0 :             PrintFlag = true;
    1753            0 :             SizingString = state.dataVentilatedSlab->VentSlabNumericFields(Item).FieldNames(FieldNum) + " [m3/s]";
    1754            0 :             auto &zoneEqSizing = state.dataSize->ZoneEqSizing(CurZoneEqNum);
    1755            0 :             if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).CoolingSAFMethod > 0) {
    1756            0 :                 SizingMethod = HVAC::CoolingAirflowSizing;
    1757            0 :                 int SAFMethod = state.dataSize->ZoneHVACSizing(zoneHVACIndex).CoolingSAFMethod;
    1758            0 :                 zoneEqSizing.SizingMethod(SizingMethod) = SAFMethod;
    1759            0 :                 if (SAFMethod == DataSizing::None || SAFMethod == DataSizing::SupplyAirFlowRate || SAFMethod == DataSizing::FlowPerFloorArea ||
    1760              :                     SAFMethod == DataSizing::FractionOfAutosizedCoolingAirflow) {
    1761            0 :                     if (SAFMethod == DataSizing::SupplyAirFlowRate) {
    1762            0 :                         if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow > 0.0) {
    1763            0 :                             zoneEqSizing.AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
    1764            0 :                             zoneEqSizing.SystemAirFlow = true;
    1765              :                         }
    1766            0 :                         TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
    1767            0 :                     } else if (SAFMethod == DataSizing::FlowPerFloorArea) {
    1768            0 :                         zoneEqSizing.SystemAirFlow = true;
    1769            0 :                         zoneEqSizing.AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow *
    1770            0 :                                                   state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
    1771            0 :                         TempSize = zoneEqSizing.AirVolFlow;
    1772            0 :                         state.dataSize->DataScalableSizingON = true;
    1773            0 :                     } else if (SAFMethod == DataSizing::FractionOfAutosizedCoolingAirflow) {
    1774            0 :                         state.dataSize->DataFracOfAutosizedCoolingAirflow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
    1775            0 :                         TempSize = DataSizing::AutoSize;
    1776            0 :                         state.dataSize->DataScalableSizingON = true;
    1777              :                     } else {
    1778            0 :                         TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
    1779              :                     }
    1780            0 :                     CoolingAirFlowSizer sizingCoolingAirFlow;
    1781            0 :                     std::string stringOverride = "Maximum Air Flow Rate [m3/s]";
    1782            0 :                     if (state.dataGlobal->isEpJSON) {
    1783            0 :                         stringOverride = "maximum_air_flow_rate [m3/s]";
    1784              :                     }
    1785            0 :                     sizingCoolingAirFlow.overrideSizingString(stringOverride);
    1786              :                     // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
    1787            0 :                     sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    1788            0 :                     CoolingAirVolFlowScalable = sizingCoolingAirFlow.size(state, TempSize, ErrorsFound);
    1789              : 
    1790            0 :                 } else if (SAFMethod == DataSizing::FlowPerCoolingCapacity) {
    1791            0 :                     TempSize = DataSizing::AutoSize;
    1792            0 :                     PrintFlag = false;
    1793            0 :                     state.dataSize->DataScalableSizingON = true;
    1794            0 :                     state.dataSize->DataFlowUsedForSizing = state.dataSize->FinalZoneSizing(CurZoneEqNum).DesCoolVolFlow;
    1795            0 :                     CoolingCapacitySizer sizerCoolingCapacity;
    1796            0 :                     sizerCoolingCapacity.overrideSizingString(SizingString);
    1797            0 :                     sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    1798            0 :                     state.dataSize->DataAutosizedCoolingCapacity = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
    1799            0 :                     state.dataSize->DataFlowPerCoolingCapacity = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
    1800            0 :                     PrintFlag = true;
    1801            0 :                     TempSize = DataSizing::AutoSize;
    1802            0 :                     CoolingAirFlowSizer sizingCoolingAirFlow;
    1803            0 :                     std::string stringOverride = "Maximum Air Flow Rate [m3/s]";
    1804            0 :                     if (state.dataGlobal->isEpJSON) {
    1805            0 :                         stringOverride = "maximum_air_flow_rate [m3/s]";
    1806              :                     }
    1807            0 :                     sizingCoolingAirFlow.overrideSizingString(stringOverride);
    1808              :                     // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
    1809            0 :                     sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    1810            0 :                     CoolingAirVolFlowScalable = sizingCoolingAirFlow.size(state, TempSize, ErrorsFound);
    1811            0 :                 }
    1812              :             }
    1813            0 :             if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).HeatingSAFMethod > 0) {
    1814            0 :                 SizingMethod = HVAC::HeatingAirflowSizing;
    1815            0 :                 int SAFMethod = state.dataSize->ZoneHVACSizing(zoneHVACIndex).HeatingSAFMethod;
    1816            0 :                 zoneEqSizing.SizingMethod(SizingMethod) = SAFMethod;
    1817            0 :                 if (SAFMethod == DataSizing::None || SAFMethod == DataSizing::SupplyAirFlowRate || SAFMethod == DataSizing::FlowPerFloorArea ||
    1818              :                     SAFMethod == DataSizing::FractionOfAutosizedHeatingAirflow) {
    1819            0 :                     if (SAFMethod == DataSizing::SupplyAirFlowRate) {
    1820            0 :                         if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow > 0.0) {
    1821            0 :                             zoneEqSizing.AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow;
    1822            0 :                             zoneEqSizing.SystemAirFlow = true;
    1823              :                         }
    1824            0 :                         TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow;
    1825            0 :                     } else if (SAFMethod == DataSizing::FlowPerFloorArea) {
    1826            0 :                         zoneEqSizing.SystemAirFlow = true;
    1827            0 :                         zoneEqSizing.AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow *
    1828            0 :                                                   state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
    1829            0 :                         TempSize = zoneEqSizing.AirVolFlow;
    1830            0 :                         state.dataSize->DataScalableSizingON = true;
    1831            0 :                     } else if (SAFMethod == DataSizing::FractionOfAutosizedHeatingAirflow) {
    1832            0 :                         state.dataSize->DataFracOfAutosizedHeatingAirflow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow;
    1833            0 :                         TempSize = DataSizing::AutoSize;
    1834            0 :                         state.dataSize->DataScalableSizingON = true;
    1835              :                     } else {
    1836            0 :                         TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow;
    1837              :                     }
    1838            0 :                     HeatingAirFlowSizer sizingHeatingAirFlow;
    1839            0 :                     sizingHeatingAirFlow.overrideSizingString(SizingString);
    1840              :                     // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
    1841            0 :                     sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    1842            0 :                     HeatingAirVolFlowScalable = sizingHeatingAirFlow.size(state, TempSize, ErrorsFound);
    1843            0 :                 } else if (SAFMethod == DataSizing::FlowPerHeatingCapacity) {
    1844            0 :                     TempSize = DataSizing::AutoSize;
    1845            0 :                     PrintFlag = false;
    1846            0 :                     state.dataSize->DataScalableSizingON = true;
    1847            0 :                     state.dataSize->DataFlowUsedForSizing = state.dataSize->FinalZoneSizing(CurZoneEqNum).DesHeatVolFlow;
    1848            0 :                     HeatingCapacitySizer sizerHeatingCapacity;
    1849            0 :                     sizerHeatingCapacity.overrideSizingString(SizingString);
    1850            0 :                     sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    1851            0 :                     state.dataSize->DataAutosizedHeatingCapacity = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
    1852            0 :                     state.dataSize->DataFlowPerHeatingCapacity = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow;
    1853            0 :                     PrintFlag = true;
    1854            0 :                     TempSize = DataSizing::AutoSize;
    1855            0 :                     HeatingAirFlowSizer sizingHeatingAirFlow;
    1856            0 :                     sizingHeatingAirFlow.overrideSizingString(SizingString);
    1857              :                     // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
    1858            0 :                     sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    1859            0 :                     HeatingAirVolFlowScalable = sizingHeatingAirFlow.size(state, TempSize, ErrorsFound);
    1860            0 :                 }
    1861              :             }
    1862              :             // DataScalableSizingON = false;
    1863            0 :             ventSlab.MaxAirVolFlow = max(CoolingAirVolFlowScalable, HeatingAirVolFlowScalable);
    1864              :         } else {
    1865              :             // no scalble sizing method has been specified. Sizing proceeds using the method
    1866              :             // specified in the zoneHVAC object
    1867              :             // N1 , \field Maximum Supply Air Flow Rate
    1868            1 :             FieldNum = 1;
    1869            1 :             PrintFlag = true;
    1870            1 :             SizingString = state.dataVentilatedSlab->VentSlabNumericFields(Item).FieldNames(FieldNum) + " [m3/s]";
    1871            1 :             TempSize = ventSlab.MaxAirVolFlow;
    1872            1 :             SystemAirFlowSizer sizerSystemAirFlow;
    1873            1 :             sizerSystemAirFlow.overrideSizingString(SizingString);
    1874              :             // sizerSystemAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
    1875            1 :             sizerSystemAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    1876            1 :             ventSlab.MaxAirVolFlow = sizerSystemAirFlow.size(state, TempSize, ErrorsFound);
    1877            1 :         }
    1878              : 
    1879            1 :         bool IsAutoSize = false;
    1880            1 :         if (ventSlab.OutAirVolFlow == DataSizing::AutoSize) {
    1881            0 :             IsAutoSize = true;
    1882              :         }
    1883            1 :         if (CurZoneEqNum > 0) {
    1884            1 :             if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) {
    1885            1 :                 if (ventSlab.OutAirVolFlow > 0.0) {
    1886            1 :                     BaseSizer::reportSizerOutput(
    1887              :                         state, cMO_VentilatedSlab, ventSlab.Name, "User-Specified Maximum Outdoor Air Flow Rate [m3/s]", ventSlab.OutAirVolFlow);
    1888              :                 }
    1889              :             } else { // Autosize or hard-size with sizing run
    1890            0 :                 CheckZoneSizing(state, cMO_VentilatedSlab, ventSlab.Name);
    1891            0 :                 OutAirVolFlowDes = ventSlab.MaxAirVolFlow;
    1892            0 :                 if (IsAutoSize) {
    1893            0 :                     ventSlab.OutAirVolFlow = OutAirVolFlowDes;
    1894            0 :                     BaseSizer::reportSizerOutput(
    1895              :                         state, cMO_VentilatedSlab, ventSlab.Name, "Design Size Maximum Outdoor Air Flow Rate [m3/s]", OutAirVolFlowDes);
    1896              :                 } else {
    1897            0 :                     if (ventSlab.OutAirVolFlow > 0.0 && OutAirVolFlowDes > 0.0) {
    1898            0 :                         OutAirVolFlowUser = ventSlab.OutAirVolFlow;
    1899            0 :                         BaseSizer::reportSizerOutput(state,
    1900              :                                                      cMO_VentilatedSlab,
    1901              :                                                      ventSlab.Name,
    1902              :                                                      "Design Size Maximum Outdoor Air Flow Rate [m3/s]",
    1903              :                                                      OutAirVolFlowDes,
    1904              :                                                      "User-Specified Maximum Outdoor Air Flow Rate [m3/s]",
    1905              :                                                      OutAirVolFlowUser);
    1906            0 :                         if (state.dataGlobal->DisplayExtraWarnings) {
    1907            0 :                             if ((std::abs(OutAirVolFlowDes - OutAirVolFlowUser) / OutAirVolFlowUser) > state.dataSize->AutoVsHardSizingThreshold) {
    1908            0 :                                 ShowMessage(state,
    1909            0 :                                             format("SizeVentilatedSlab: Potential issue with equipment sizing for ZoneHVAC:VentilatedSlab = \"{}\".",
    1910            0 :                                                    ventSlab.Name));
    1911            0 :                                 ShowContinueError(state, format("User-Specified Maximum Outdoor Air Flow Rate of {:.5R} [m3/s]", OutAirVolFlowUser));
    1912            0 :                                 ShowContinueError(
    1913            0 :                                     state, format("differs from Design Size Maximum Outdoor Air Flow Rate of {:.5R} [m3/s]", OutAirVolFlowDes));
    1914            0 :                                 ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    1915            0 :                                 ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    1916              :                             }
    1917              :                         }
    1918              :                     }
    1919              :                 }
    1920              :             }
    1921              :         }
    1922              : 
    1923            1 :         IsAutoSize = false;
    1924            1 :         if (ventSlab.MinOutAirVolFlow == DataSizing::AutoSize) {
    1925            0 :             IsAutoSize = true;
    1926              :         }
    1927            1 :         if (CurZoneEqNum > 0) {
    1928            1 :             if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) {
    1929            1 :                 if (ventSlab.MinOutAirVolFlow > 0.0) {
    1930            1 :                     BaseSizer::reportSizerOutput(
    1931              :                         state, cMO_VentilatedSlab, ventSlab.Name, "User-Specified Minimum Outdoor Air Flow Rate [m3/s]", ventSlab.MinOutAirVolFlow);
    1932              :                 }
    1933              :             } else {
    1934            0 :                 CheckZoneSizing(state, cMO_VentilatedSlab, ventSlab.Name);
    1935            0 :                 MinOutAirVolFlowDes = min(state.dataSize->FinalZoneSizing(CurZoneEqNum).MinOA, ventSlab.MaxAirVolFlow);
    1936            0 :                 if (MinOutAirVolFlowDes < HVAC::SmallAirVolFlow) {
    1937            0 :                     MinOutAirVolFlowDes = 0.0;
    1938              :                 }
    1939            0 :                 if (IsAutoSize) {
    1940            0 :                     ventSlab.MinOutAirVolFlow = MinOutAirVolFlowDes;
    1941            0 :                     BaseSizer::reportSizerOutput(
    1942              :                         state, cMO_VentilatedSlab, ventSlab.Name, "Design Size Minimum Outdoor Air Flow Rate [m3/s]", MinOutAirVolFlowDes);
    1943              :                 } else { // Hard-size with sizing data
    1944            0 :                     if (ventSlab.MinOutAirVolFlow > 0.0 && MinOutAirVolFlowDes > 0.0) {
    1945            0 :                         MinOutAirVolFlowUser = ventSlab.MinOutAirVolFlow;
    1946            0 :                         BaseSizer::reportSizerOutput(state,
    1947              :                                                      cMO_VentilatedSlab,
    1948              :                                                      ventSlab.Name,
    1949              :                                                      "Design Size Minimum Outdoor Air Flow Rate [m3/s]",
    1950              :                                                      MinOutAirVolFlowDes,
    1951              :                                                      "User-Specified Minimum Outdoor Air Flow Rate [m3/s]",
    1952              :                                                      MinOutAirVolFlowUser);
    1953            0 :                         if (state.dataGlobal->DisplayExtraWarnings) {
    1954            0 :                             if ((std::abs(MinOutAirVolFlowDes - MinOutAirVolFlowUser) / MinOutAirVolFlowUser) >
    1955            0 :                                 state.dataSize->AutoVsHardSizingThreshold) {
    1956            0 :                                 ShowMessage(state,
    1957            0 :                                             format("SizeVentilatedSlab: Potential issue with equipment sizing for ZoneHVAC:VentilatedSlab = \"{}\".",
    1958            0 :                                                    ventSlab.Name));
    1959            0 :                                 ShowContinueError(state,
    1960            0 :                                                   format("User-Specified Minimum Outdoor Air Flow Rate of {:.5R} [m3/s]", MinOutAirVolFlowUser));
    1961            0 :                                 ShowContinueError(
    1962            0 :                                     state, format("differs from Design Size Minimum Outdoor Air Flow Rate of {:.5R} [m3/s]", MinOutAirVolFlowDes));
    1963            0 :                                 ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    1964            0 :                                 ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    1965              :                             }
    1966              :                         }
    1967              :                     }
    1968              :                 }
    1969              :             }
    1970              :         }
    1971              : 
    1972            1 :         IsAutoSize = false;
    1973            1 :         if (ventSlab.MaxVolHotWaterFlow == DataSizing::AutoSize) {
    1974            0 :             IsAutoSize = true;
    1975              :         }
    1976            1 :         if (ventSlab.hCoilType == HeatingCoilType::Water) {
    1977              : 
    1978            1 :             if (CurZoneEqNum > 0) {
    1979            1 :                 if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) {
    1980            1 :                     if (ventSlab.MaxVolHotWaterFlow > 0.0) {
    1981            1 :                         BaseSizer::reportSizerOutput(
    1982              :                             state, cMO_VentilatedSlab, ventSlab.Name, "User-Specified Maximum Hot Water Flow [m3/s]", ventSlab.MaxVolHotWaterFlow);
    1983              :                     }
    1984              :                 } else { // Autosize or hard-size with sizing run
    1985            0 :                     CheckZoneSizing(state, cMO_VentilatedSlab, ventSlab.Name);
    1986              : 
    1987            0 :                     int CoilWaterInletNode = WaterCoils::GetCoilWaterInletNode(state, "Coil:Heating:Water", ventSlab.heatingCoilName, ErrorsFound);
    1988            0 :                     int CoilWaterOutletNode = WaterCoils::GetCoilWaterOutletNode(state, "Coil:Heating:Water", ventSlab.heatingCoilName, ErrorsFound);
    1989            0 :                     if (IsAutoSize) {
    1990            0 :                         int PltSizHeatNum = PlantUtilities::MyPlantSizingIndex(
    1991              :                             state, "Coil:Heating:Water", ventSlab.heatingCoilName, CoilWaterInletNode, CoilWaterOutletNode, ErrorsFound);
    1992            0 :                         int CoilNum = WaterCoils::GetWaterCoilIndex(state, "COIL:HEATING:WATER", ventSlab.heatingCoilName, ErrorsFound);
    1993            0 :                         if (state.dataWaterCoils->WaterCoil(CoilNum).UseDesignWaterDeltaTemp) {
    1994            0 :                             WaterCoilSizDeltaT = state.dataWaterCoils->WaterCoil(CoilNum).DesignWaterDeltaTemp;
    1995            0 :                             DoWaterCoilSizing = true;
    1996              :                         } else {
    1997            0 :                             if (PltSizHeatNum > 0) {
    1998            0 :                                 WaterCoilSizDeltaT = state.dataSize->PlantSizData(PltSizHeatNum).DeltaT;
    1999            0 :                                 DoWaterCoilSizing = true;
    2000              :                             } else {
    2001            0 :                                 DoWaterCoilSizing = false;
    2002              :                                 // If there is no heating Plant Sizing object and autosizing was requested, issue fatal error message
    2003            0 :                                 ShowSevereError(state, "Autosizing of water flow requires a heating loop Sizing:Plant object");
    2004            0 :                                 ShowContinueError(state, format("Occurs in {} Object={}", cMO_VentilatedSlab, ventSlab.Name));
    2005            0 :                                 ErrorsFound = true;
    2006              :                             }
    2007              :                         }
    2008            0 :                         if (DoWaterCoilSizing) {
    2009            0 :                             if (state.dataSize->FinalZoneSizing(CurZoneEqNum).DesHeatMassFlow >= HVAC::SmallAirVolFlow) {
    2010            0 :                                 auto &zoneEqSizing = state.dataSize->ZoneEqSizing(CurZoneEqNum);
    2011            0 :                                 SizingMethod = HVAC::HeatingCapacitySizing;
    2012            0 :                                 if (ventSlab.HVACSizingIndex > 0) {
    2013            0 :                                     zoneHVACIndex = ventSlab.HVACSizingIndex;
    2014            0 :                                     int CapSizingMethod = state.dataSize->ZoneHVACSizing(zoneHVACIndex).HeatingCapMethod;
    2015            0 :                                     zoneEqSizing.SizingMethod(SizingMethod) = CapSizingMethod;
    2016            0 :                                     if (CapSizingMethod == DataSizing::HeatingDesignCapacity || CapSizingMethod == DataSizing::CapacityPerFloorArea ||
    2017              :                                         CapSizingMethod == DataSizing::FractionOfAutosizedHeatingCapacity) {
    2018            0 :                                         if (CapSizingMethod == DataSizing::HeatingDesignCapacity) {
    2019            0 :                                             if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity > 0.0) {
    2020            0 :                                                 zoneEqSizing.HeatingCapacity = true;
    2021            0 :                                                 zoneEqSizing.DesHeatingLoad = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity;
    2022              :                                             } else {
    2023            0 :                                                 state.dataSize->DataFlowUsedForSizing = state.dataSize->FinalZoneSizing(CurZoneEqNum).DesHeatVolFlow;
    2024              :                                             }
    2025            0 :                                             TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity;
    2026            0 :                                         } else if (CapSizingMethod == DataSizing::CapacityPerFloorArea) {
    2027            0 :                                             zoneEqSizing.HeatingCapacity = true;
    2028            0 :                                             zoneEqSizing.DesHeatingLoad = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity *
    2029            0 :                                                                           state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
    2030            0 :                                             state.dataSize->DataScalableCapSizingON = true;
    2031            0 :                                         } else if (CapSizingMethod == DataSizing::FractionOfAutosizedHeatingCapacity) {
    2032            0 :                                             state.dataSize->DataFracOfAutosizedHeatingCapacity =
    2033            0 :                                                 state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity;
    2034            0 :                                             state.dataSize->DataFlowUsedForSizing = state.dataSize->FinalZoneSizing(CurZoneEqNum).DesHeatVolFlow;
    2035            0 :                                             TempSize = DataSizing::AutoSize;
    2036            0 :                                             state.dataSize->DataScalableCapSizingON = true;
    2037              :                                         }
    2038              :                                     }
    2039            0 :                                     SizingString = "";
    2040            0 :                                     PrintFlag = false;
    2041            0 :                                     HeatingCapacitySizer sizerHeatingCapacity;
    2042            0 :                                     sizerHeatingCapacity.overrideSizingString(SizingString);
    2043            0 :                                     sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    2044            0 :                                     DesCoilLoad = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
    2045            0 :                                     state.dataSize->DataScalableCapSizingON = false;
    2046            0 :                                 } else {
    2047            0 :                                     SizingString = "";
    2048            0 :                                     PrintFlag = false;
    2049            0 :                                     TempSize = DataSizing::AutoSize;
    2050            0 :                                     HeatingCapacitySizer sizerHeatingCapacity;
    2051            0 :                                     sizerHeatingCapacity.overrideSizingString(SizingString);
    2052            0 :                                     sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    2053            0 :                                     DesCoilLoad = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
    2054            0 :                                 }
    2055            0 :                                 rho = state.dataPlnt->PlantLoop(ventSlab.HWPlantLoc.loopNum)
    2056            0 :                                           .glycol->getDensity(state, Constant::HWInitConvTemp, RoutineName);
    2057            0 :                                 Cp = state.dataPlnt->PlantLoop(ventSlab.HWPlantLoc.loopNum)
    2058            0 :                                          .glycol->getSpecificHeat(state, Constant::HWInitConvTemp, RoutineName);
    2059            0 :                                 MaxVolHotWaterFlowDes = DesCoilLoad / (WaterCoilSizDeltaT * Cp * rho);
    2060              :                             } else {
    2061            0 :                                 MaxVolHotWaterFlowDes = 0.0;
    2062              :                             }
    2063              :                         }
    2064            0 :                         ventSlab.MaxVolHotWaterFlow = MaxVolHotWaterFlowDes;
    2065            0 :                         BaseSizer::reportSizerOutput(
    2066              :                             state, cMO_VentilatedSlab, ventSlab.Name, "Design Size Maximum Hot Water Flow [m3/s]", MaxVolHotWaterFlowDes);
    2067              :                     } else { // Hard-size with sizing data
    2068            0 :                         if (ventSlab.MaxVolHotWaterFlow > 0.0 && MaxVolHotWaterFlowDes > 0.0) {
    2069            0 :                             MaxVolHotWaterFlowUser = ventSlab.MaxVolHotWaterFlow;
    2070            0 :                             BaseSizer::reportSizerOutput(state,
    2071              :                                                          cMO_VentilatedSlab,
    2072              :                                                          ventSlab.Name,
    2073              :                                                          "Design Size Maximum Hot Water Flow [m3/s]",
    2074              :                                                          MaxVolHotWaterFlowDes,
    2075              :                                                          "User-Specified Maximum Hot Water Flow [m3/s]",
    2076              :                                                          MaxVolHotWaterFlowUser);
    2077            0 :                             if (state.dataGlobal->DisplayExtraWarnings) {
    2078            0 :                                 if ((std::abs(MaxVolHotWaterFlowDes - MaxVolHotWaterFlowUser) / MaxVolHotWaterFlowUser) >
    2079            0 :                                     state.dataSize->AutoVsHardSizingThreshold) {
    2080            0 :                                     ShowMessage(
    2081              :                                         state,
    2082            0 :                                         format("SizeVentilatedSlab: Potential issue with equipment sizing for ZoneHVAC:VentilatedSlab = \"{}\".",
    2083            0 :                                                ventSlab.Name));
    2084            0 :                                     ShowContinueError(state,
    2085            0 :                                                       format("User-Specified Maximum Hot Water Flow of {:.5R} [m3/s]", MaxVolHotWaterFlowUser));
    2086            0 :                                     ShowContinueError(
    2087            0 :                                         state, format("differs from Design Size Maximum Hot Water Flow of {:.5R} [m3/s]", MaxVolHotWaterFlowDes));
    2088            0 :                                     ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    2089            0 :                                     ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    2090              :                                 }
    2091              :                             }
    2092              :                         }
    2093              :                     }
    2094              :                 }
    2095              :             }
    2096              :         } else {
    2097            0 :             ventSlab.MaxVolHotWaterFlow = 0.0;
    2098              :         }
    2099              : 
    2100            1 :         IsAutoSize = false;
    2101            1 :         if (ventSlab.MaxVolHotSteamFlow == DataSizing::AutoSize) {
    2102            0 :             IsAutoSize = true;
    2103              :         }
    2104            1 :         if (ventSlab.hCoilType == HeatingCoilType::Steam) {
    2105              : 
    2106            0 :             if (CurZoneEqNum > 0) {
    2107            0 :                 if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) {
    2108            0 :                     if (ventSlab.MaxVolHotSteamFlow > 0.0) {
    2109            0 :                         BaseSizer::reportSizerOutput(
    2110              :                             state, cMO_VentilatedSlab, ventSlab.Name, "User-Specified Maximum Steam Flow [m3/s]", ventSlab.MaxVolHotSteamFlow);
    2111              :                     }
    2112              :                 } else { // Autosize or hard-size with sizing run
    2113            0 :                     CheckZoneSizing(state, "ZoneHVAC:VentilatedSlab", ventSlab.Name);
    2114              : 
    2115            0 :                     int CoilSteamInletNode = SteamCoils::GetCoilSteamInletNode(state, "Coil:Heating:Steam", ventSlab.heatingCoilName, ErrorsFound);
    2116            0 :                     int CoilSteamOutletNode = SteamCoils::GetCoilSteamOutletNode(state, "Coil:Heating:Steam", ventSlab.heatingCoilName, ErrorsFound);
    2117            0 :                     if (IsAutoSize) {
    2118            0 :                         int PltSizHeatNum = PlantUtilities::MyPlantSizingIndex(
    2119              :                             state, "Coil:Heating:Steam", ventSlab.heatingCoilName, CoilSteamInletNode, CoilSteamOutletNode, ErrorsFound);
    2120            0 :                         if (PltSizHeatNum > 0) {
    2121            0 :                             if (state.dataSize->FinalZoneSizing(CurZoneEqNum).DesHeatMassFlow >= HVAC::SmallAirVolFlow) {
    2122            0 :                                 SizingMethod = HVAC::HeatingCapacitySizing;
    2123            0 :                                 if (ventSlab.HVACSizingIndex > 0) {
    2124            0 :                                     auto &zoneEqSizing = state.dataSize->ZoneEqSizing(CurZoneEqNum);
    2125            0 :                                     zoneHVACIndex = ventSlab.HVACSizingIndex;
    2126            0 :                                     int CapSizingMethod = state.dataSize->ZoneHVACSizing(zoneHVACIndex).HeatingCapMethod;
    2127            0 :                                     zoneEqSizing.SizingMethod(SizingMethod) = CapSizingMethod;
    2128            0 :                                     if (CapSizingMethod == DataSizing::HeatingDesignCapacity || CapSizingMethod == DataSizing::CapacityPerFloorArea ||
    2129              :                                         CapSizingMethod == DataSizing::FractionOfAutosizedHeatingCapacity) {
    2130            0 :                                         if (CapSizingMethod == DataSizing::HeatingDesignCapacity) {
    2131            0 :                                             if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity > 0.0) {
    2132            0 :                                                 zoneEqSizing.HeatingCapacity = true;
    2133            0 :                                                 zoneEqSizing.DesHeatingLoad = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity;
    2134              :                                             } else {
    2135            0 :                                                 state.dataSize->DataFlowUsedForSizing = state.dataSize->FinalZoneSizing(CurZoneEqNum).DesHeatVolFlow;
    2136              :                                             }
    2137            0 :                                             TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity;
    2138            0 :                                         } else if (CapSizingMethod == DataSizing::CapacityPerFloorArea) {
    2139            0 :                                             zoneEqSizing.HeatingCapacity = true;
    2140            0 :                                             zoneEqSizing.DesHeatingLoad = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity *
    2141            0 :                                                                           state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
    2142            0 :                                             state.dataSize->DataScalableCapSizingON = true;
    2143            0 :                                         } else if (CapSizingMethod == DataSizing::FractionOfAutosizedHeatingCapacity) {
    2144            0 :                                             state.dataSize->DataFracOfAutosizedHeatingCapacity =
    2145            0 :                                                 state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity;
    2146            0 :                                             state.dataSize->DataFlowUsedForSizing = state.dataSize->FinalZoneSizing(CurZoneEqNum).DesHeatVolFlow;
    2147            0 :                                             TempSize = DataSizing::AutoSize;
    2148            0 :                                             state.dataSize->DataScalableCapSizingON = true;
    2149              :                                         }
    2150              :                                     }
    2151            0 :                                     SizingString = "";
    2152            0 :                                     PrintFlag = false;
    2153            0 :                                     HeatingCapacitySizer sizerHeatingCapacity;
    2154            0 :                                     sizerHeatingCapacity.overrideSizingString(SizingString);
    2155            0 :                                     sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    2156            0 :                                     DesCoilLoad = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
    2157            0 :                                     state.dataSize->DataScalableCapSizingON = false;
    2158            0 :                                 } else {
    2159            0 :                                     SizingString = "";
    2160            0 :                                     PrintFlag = false;
    2161            0 :                                     TempSize = DataSizing::AutoSize;
    2162            0 :                                     HeatingCapacitySizer sizerHeatingCapacity;
    2163            0 :                                     sizerHeatingCapacity.overrideSizingString(SizingString);
    2164            0 :                                     sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    2165            0 :                                     DesCoilLoad = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
    2166            0 :                                 }
    2167            0 :                                 TempSteamIn = 100.00;
    2168            0 :                                 auto *steam = Fluid::GetSteam(state);
    2169            0 :                                 EnthSteamInDry = steam->getSatEnthalpy(state, TempSteamIn, 1.0, RoutineName);
    2170            0 :                                 EnthSteamOutWet = steam->getSatEnthalpy(state, TempSteamIn, 0.0, RoutineName);
    2171            0 :                                 LatentHeatSteam = EnthSteamInDry - EnthSteamOutWet;
    2172            0 :                                 SteamDensity = steam->getSatDensity(state, TempSteamIn, 1.0, RoutineName);
    2173            0 :                                 int DummyWaterIndex = 1;
    2174              : 
    2175            0 :                                 auto *water = Fluid::GetWater(state);
    2176            0 :                                 Cp = water->getSpecificHeat(state, Constant::HWInitConvTemp, RoutineName);
    2177            0 :                                 rho = water->getDensity(state, Constant::HWInitConvTemp, RoutineName);
    2178            0 :                                 MaxVolHotSteamFlowDes =
    2179            0 :                                     DesCoilLoad / ((state.dataSize->PlantSizData(PltSizHeatNum).DeltaT * Cp * rho) + SteamDensity * LatentHeatSteam);
    2180              :                             } else {
    2181            0 :                                 MaxVolHotSteamFlowDes = 0.0;
    2182              :                             }
    2183              :                         } else {
    2184            0 :                             ShowSevereError(state, "Autosizing of Steam flow requires a heating loop Sizing:Plant object");
    2185            0 :                             ShowContinueError(state, format("Occurs in ZoneHVAC:VentilatedSlab Object={}", ventSlab.Name));
    2186            0 :                             ErrorsFound = true;
    2187              :                         }
    2188            0 :                         ventSlab.MaxVolHotSteamFlow = MaxVolHotSteamFlowDes;
    2189            0 :                         BaseSizer::reportSizerOutput(
    2190              :                             state, cMO_VentilatedSlab, ventSlab.Name, "Design Size Maximum Steam Flow [m3/s]", MaxVolHotSteamFlowDes);
    2191              :                     } else {
    2192            0 :                         if (ventSlab.MaxVolHotSteamFlow > 0.0 && MaxVolHotSteamFlowDes > 0.0) {
    2193            0 :                             MaxVolHotSteamFlowUser = ventSlab.MaxVolHotSteamFlow;
    2194            0 :                             BaseSizer::reportSizerOutput(state,
    2195              :                                                          cMO_VentilatedSlab,
    2196              :                                                          ventSlab.Name,
    2197              :                                                          "Design Size Maximum Steam Flow [m3/s]",
    2198              :                                                          MaxVolHotSteamFlowDes,
    2199              :                                                          "User-Specified Maximum Steam Flow [m3/s]",
    2200              :                                                          MaxVolHotSteamFlowUser);
    2201            0 :                             if (state.dataGlobal->DisplayExtraWarnings) {
    2202            0 :                                 if ((std::abs(MaxVolHotSteamFlowDes - MaxVolHotSteamFlowUser) / MaxVolHotSteamFlowUser) >
    2203            0 :                                     state.dataSize->AutoVsHardSizingThreshold) {
    2204            0 :                                     ShowMessage(
    2205              :                                         state,
    2206            0 :                                         format("SizeVentilatedSlab: Potential issue with equipment sizing for ZoneHVAC:VentilatedSlab = \"{}\".",
    2207            0 :                                                ventSlab.Name));
    2208            0 :                                     ShowContinueError(state, format("User-Specified Maximum Steam Flow of {:.5R} [m3/s]", MaxVolHotSteamFlowUser));
    2209            0 :                                     ShowContinueError(state,
    2210            0 :                                                       format("differs from Design Size Maximum Steam Flow of {:.5R} [m3/s]", MaxVolHotSteamFlowDes));
    2211            0 :                                     ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    2212            0 :                                     ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    2213              :                                 }
    2214              :                             }
    2215              :                         }
    2216              :                     }
    2217              :                 }
    2218              :             }
    2219              :         } else {
    2220            1 :             ventSlab.MaxVolHotSteamFlow = 0.0;
    2221              :         }
    2222              : 
    2223            1 :         IsAutoSize = false;
    2224            1 :         if (ventSlab.MaxVolColdWaterFlow == DataSizing::AutoSize) {
    2225            0 :             IsAutoSize = true;
    2226              :         }
    2227            1 :         if (CurZoneEqNum > 0) {
    2228            1 :             if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) {
    2229            1 :                 if (ventSlab.MaxVolColdWaterFlow > 0.0) {
    2230            1 :                     BaseSizer::reportSizerOutput(
    2231              :                         state, cMO_VentilatedSlab, ventSlab.Name, "User-Specified Maximum Cold Water Flow [m3/s]", ventSlab.MaxVolColdWaterFlow);
    2232              :                 }
    2233              :             } else {
    2234            0 :                 CheckZoneSizing(state, cMO_VentilatedSlab, ventSlab.Name);
    2235            0 :                 if (ventSlab.cCoilType == CoolingCoilType::HXAssisted) {
    2236              :                     CoolingCoilName =
    2237            0 :                         HVACHXAssistedCoolingCoil::GetHXDXCoilName(state, ventSlab.coolingCoilTypeCh, ventSlab.coolingCoilName, ErrorsFound);
    2238              :                     CoolingCoilType =
    2239            0 :                         HVACHXAssistedCoolingCoil::GetHXCoilType(state, ventSlab.coolingCoilTypeCh, ventSlab.coolingCoilName, ErrorsFound);
    2240              :                 } else {
    2241            0 :                     CoolingCoilName = ventSlab.coolingCoilName;
    2242            0 :                     CoolingCoilType = ventSlab.coolingCoilTypeCh;
    2243              :                 }
    2244            0 :                 int CoilWaterInletNode = WaterCoils::GetCoilWaterInletNode(state, CoolingCoilType, CoolingCoilName, ErrorsFound);
    2245            0 :                 int CoilWaterOutletNode = WaterCoils::GetCoilWaterOutletNode(state, CoolingCoilType, CoolingCoilName, ErrorsFound);
    2246            0 :                 if (IsAutoSize) {
    2247            0 :                     int PltSizCoolNum = PlantUtilities::MyPlantSizingIndex(
    2248              :                         state, CoolingCoilType, CoolingCoilName, CoilWaterInletNode, CoilWaterOutletNode, ErrorsFound);
    2249            0 :                     int CoilNum = WaterCoils::GetWaterCoilIndex(state, CoolingCoilType, CoolingCoilName, ErrorsFound);
    2250            0 :                     if (state.dataWaterCoils->WaterCoil(CoilNum).UseDesignWaterDeltaTemp) {
    2251            0 :                         WaterCoilSizDeltaT = state.dataWaterCoils->WaterCoil(CoilNum).DesignWaterDeltaTemp;
    2252            0 :                         DoWaterCoilSizing = true;
    2253              :                     } else {
    2254            0 :                         if (PltSizCoolNum > 0) {
    2255            0 :                             WaterCoilSizDeltaT = state.dataSize->PlantSizData(PltSizCoolNum).DeltaT;
    2256            0 :                             DoWaterCoilSizing = true;
    2257              :                         } else {
    2258            0 :                             DoWaterCoilSizing = false;
    2259              :                             // If there is no cooling Plant Sizing object and autosizing was requested, issue fatal error message
    2260            0 :                             ShowSevereError(state, "Autosizing of water flow requires a cooling loop Sizing:Plant object");
    2261            0 :                             ShowContinueError(state, format("Occurs in {} Object={}", cMO_VentilatedSlab, ventSlab.Name));
    2262            0 :                             ErrorsFound = true;
    2263              :                         }
    2264              :                     }
    2265            0 :                     if (DoWaterCoilSizing) {
    2266            0 :                         if (state.dataSize->FinalZoneSizing(CurZoneEqNum).DesCoolMassFlow >= HVAC::SmallAirVolFlow) {
    2267            0 :                             SizingMethod = HVAC::CoolingCapacitySizing;
    2268            0 :                             if (ventSlab.HVACSizingIndex > 0) {
    2269            0 :                                 auto &zoneEqSizing = state.dataSize->ZoneEqSizing(CurZoneEqNum);
    2270            0 :                                 zoneHVACIndex = ventSlab.HVACSizingIndex;
    2271            0 :                                 int CapSizingMethod = state.dataSize->ZoneHVACSizing(zoneHVACIndex).CoolingCapMethod;
    2272            0 :                                 zoneEqSizing.SizingMethod(SizingMethod) = CapSizingMethod;
    2273            0 :                                 if (CapSizingMethod == DataSizing::CoolingDesignCapacity || CapSizingMethod == DataSizing::CapacityPerFloorArea ||
    2274              :                                     CapSizingMethod == DataSizing::FractionOfAutosizedCoolingCapacity) {
    2275            0 :                                     if (CapSizingMethod == DataSizing::CoolingDesignCapacity) {
    2276            0 :                                         if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity > 0.0) {
    2277            0 :                                             zoneEqSizing.CoolingCapacity = true;
    2278            0 :                                             zoneEqSizing.DesCoolingLoad = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity;
    2279              :                                         } else {
    2280            0 :                                             state.dataSize->DataFlowUsedForSizing = state.dataSize->FinalZoneSizing(CurZoneEqNum).DesCoolVolFlow;
    2281              :                                         }
    2282            0 :                                         TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity;
    2283            0 :                                     } else if (CapSizingMethod == DataSizing::CapacityPerFloorArea) {
    2284            0 :                                         zoneEqSizing.CoolingCapacity = true;
    2285            0 :                                         zoneEqSizing.DesCoolingLoad = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity *
    2286            0 :                                                                       state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
    2287            0 :                                         state.dataSize->DataScalableCapSizingON = true;
    2288            0 :                                     } else if (CapSizingMethod == DataSizing::FractionOfAutosizedCoolingCapacity) {
    2289            0 :                                         state.dataSize->DataFracOfAutosizedHeatingCapacity =
    2290            0 :                                             state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity;
    2291            0 :                                         state.dataSize->DataFlowUsedForSizing = state.dataSize->FinalZoneSizing(CurZoneEqNum).DesCoolVolFlow;
    2292            0 :                                         TempSize = DataSizing::AutoSize;
    2293            0 :                                         state.dataSize->DataScalableCapSizingON = true;
    2294              :                                     }
    2295              :                                 }
    2296            0 :                                 SizingString = "";
    2297            0 :                                 PrintFlag = false;
    2298            0 :                                 CoolingCapacitySizer sizerCoolingCapacity;
    2299            0 :                                 sizerCoolingCapacity.overrideSizingString(SizingString);
    2300            0 :                                 sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    2301            0 :                                 DesCoilLoad = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
    2302            0 :                                 state.dataSize->DataScalableCapSizingON = false;
    2303            0 :                             } else {
    2304            0 :                                 SizingString = "";
    2305            0 :                                 PrintFlag = false;
    2306            0 :                                 TempSize = DataSizing::AutoSize;
    2307            0 :                                 state.dataSize->DataFlowUsedForSizing = state.dataSize->FinalZoneSizing(CurZoneEqNum).DesCoolVolFlow;
    2308            0 :                                 CoolingCapacitySizer sizerCoolingCapacity;
    2309            0 :                                 sizerCoolingCapacity.overrideSizingString(SizingString);
    2310            0 :                                 sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    2311            0 :                                 DesCoilLoad = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
    2312            0 :                             }
    2313            0 :                             rho = state.dataPlnt->PlantLoop(ventSlab.CWPlantLoc.loopNum).glycol->getDensity(state, 5., RoutineName);
    2314            0 :                             Cp = state.dataPlnt->PlantLoop(ventSlab.CWPlantLoc.loopNum).glycol->getSpecificHeat(state, 5., RoutineName);
    2315            0 :                             MaxVolColdWaterFlowDes = DesCoilLoad / (WaterCoilSizDeltaT * Cp * rho);
    2316              :                         } else {
    2317            0 :                             MaxVolColdWaterFlowDes = 0.0;
    2318              :                         }
    2319              :                     }
    2320            0 :                     ventSlab.MaxVolColdWaterFlow = MaxVolColdWaterFlowDes;
    2321            0 :                     BaseSizer::reportSizerOutput(
    2322              :                         state, cMO_VentilatedSlab, ventSlab.Name, "Design Size Maximum Cold Water Flow [m3/s]", MaxVolColdWaterFlowDes);
    2323              :                 } else {
    2324            0 :                     if (ventSlab.MaxVolColdWaterFlow > 0.0 && MaxVolColdWaterFlowDes > 0.0) {
    2325            0 :                         MaxVolColdWaterFlowUser = ventSlab.MaxVolColdWaterFlow;
    2326            0 :                         BaseSizer::reportSizerOutput(state,
    2327              :                                                      cMO_VentilatedSlab,
    2328              :                                                      ventSlab.Name,
    2329              :                                                      "Design Size Maximum Cold Water Flow [m3/s]",
    2330              :                                                      MaxVolColdWaterFlowDes,
    2331              :                                                      "User-Specified Maximum Cold Water Flow [m3/s]",
    2332              :                                                      MaxVolColdWaterFlowUser);
    2333            0 :                         if (state.dataGlobal->DisplayExtraWarnings) {
    2334            0 :                             if ((std::abs(MaxVolColdWaterFlowDes - MaxVolColdWaterFlowUser) / MaxVolColdWaterFlowUser) >
    2335            0 :                                 state.dataSize->AutoVsHardSizingThreshold) {
    2336            0 :                                 ShowMessage(state,
    2337            0 :                                             format("SizeVentilatedSlab: Potential issue with equipment sizing for ZoneHVAC:VentilatedSlab = \"{}\".",
    2338            0 :                                                    ventSlab.Name));
    2339            0 :                                 ShowContinueError(state, format("User-Specified Maximum Cold Water Flow of {:.5R} [m3/s]", MaxVolColdWaterFlowUser));
    2340            0 :                                 ShowContinueError(
    2341            0 :                                     state, format("differs from Design Size Maximum Cold Water Flow of {:.5R} [m3/s]", MaxVolColdWaterFlowDes));
    2342            0 :                                 ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    2343            0 :                                 ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    2344              :                             }
    2345              :                         }
    2346              :                     }
    2347              :                 }
    2348              :             }
    2349              :         }
    2350              : 
    2351            1 :         if (ventSlab.cCoilType == CoolingCoilType::HXAssisted) {
    2352            0 :             CoolingCoilName = HVACHXAssistedCoolingCoil::GetHXDXCoilName(state, ventSlab.coolingCoilTypeCh, ventSlab.coolingCoilName, ErrorsFound);
    2353            0 :             CoolingCoilType = HVACHXAssistedCoolingCoil::GetHXCoilType(state, ventSlab.coolingCoilTypeCh, ventSlab.coolingCoilName, ErrorsFound);
    2354              :         } else {
    2355            1 :             CoolingCoilName = ventSlab.coolingCoilName;
    2356            1 :             CoolingCoilType = ventSlab.coolingCoilTypeCh;
    2357              :         }
    2358            1 :         WaterCoils::SetCoilDesFlow(state, CoolingCoilType, CoolingCoilName, ventSlab.MaxAirVolFlow, ErrorsFound);
    2359            1 :         WaterCoils::SetCoilDesFlow(state, ventSlab.heatingCoilTypeCh, ventSlab.heatingCoilName, ventSlab.MaxAirVolFlow, ErrorsFound);
    2360              : 
    2361            1 :         if (CurZoneEqNum > 0) {
    2362            1 :             auto &zoneEqSizing = state.dataSize->ZoneEqSizing(CurZoneEqNum);
    2363            1 :             zoneEqSizing.MaxHWVolFlow = ventSlab.MaxVolHotWaterFlow;
    2364            1 :             zoneEqSizing.MaxCWVolFlow = ventSlab.MaxVolColdWaterFlow;
    2365              :         }
    2366              : 
    2367            1 :         if (ErrorsFound) {
    2368            0 :             ShowFatalError(state, "Preceding sizing errors cause program termination");
    2369              :         }
    2370            1 :     }
    2371              : 
    2372            0 :     void CalcVentilatedSlab(EnergyPlusData &state,
    2373              :                             int &Item,                     // number of the current ventilated slab being simulated
    2374              :                             int const ZoneNum,             // number of zone being served
    2375              :                             bool const FirstHVACIteration, // TRUE if 1st HVAC simulation of system timestep
    2376              :                             Real64 &PowerMet,              // power supplied (W)
    2377              :                             Real64 &LatOutputProvided      // latent capacity supplied (kg/s)
    2378              :     )
    2379              :     {
    2380              : 
    2381              :         // SUBROUTINE INFORMATION:
    2382              :         //       AUTHOR         Young Tae Chae, Rick Strand
    2383              :         //       DATE WRITTEN   June 2008
    2384              :         //       MODIFIED       Don Shirey, Aug 2009 (LatOutputProvided)
    2385              :         //                      July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
    2386              : 
    2387              :         // PURPOSE OF THIS SUBROUTINE:
    2388              :         // This subroutine mainly controls the action of the Ventilated Slab
    2389              :         // (or more exactly, it controls the amount of outside air brought in)
    2390              :         // based on the user input for controls and the defined controls
    2391              :         // algorithms.
    2392              : 
    2393              :         // METHODOLOGY EMPLOYED:
    2394              :         // Ventilated slab is controlled based on user input and what is happening in the
    2395              :         // simulation.  There are various cases to consider:
    2396              :         // 1. OFF: Unit is schedule off or there is no load on it.  All flow
    2397              :         //    rates are set to zero and the temperatures are set to zone conditions
    2398              :         //    (except for the outside air inlet).
    2399              :         // 2. HEATING/VARIABLE PERCENT: The unit is on, there is a heating load,
    2400              :         //    and variable percent control is specified.  The outside air fraction
    2401              :         //    is set to the minimum outside air fraction (schedule based) and the
    2402              :         //    heating coil is activated.
    2403              :         // 3. HEATING/FIXED TEMPERATURE: The unit is on, there is a heating load,
    2404              :         //    and fixed temperature control is specified.  The outside air fraction
    2405              :         //    is varied in an attempt to obtain a mixed air temperature equal to
    2406              :         //    the user specified temperature (schedule based).  The heating coil
    2407              :         //    is activated, if necessary.
    2408              :         // 4. COOLING/NO COIL: The unit is on, there is a cooling load, and no
    2409              :         //    coil is present or it has been scheduled off.  Set the amount of
    2410              :         //    outside air based on the control type.  Simulate the "mixing box".
    2411              :         // 5. COOLING/WITH COIL: The unit is on, there is a cooling load, and
    2412              :         //    a cooling coil is present and scheduled on.  Tries to use outside
    2413              :         //    air as best as possible and then calls a cooling coil
    2414              :         // Note: controls are strictly temperature based and do not factor
    2415              :         // humidity into the equation (not an enthalpy economy cycle but rather
    2416              :         // a simple return air economy cycle).  In addition, temperature predictions
    2417              :         // are not strict energy balances here in the control routine though
    2418              :         // in the mixing routine an energy balance is preserved.
    2419              : 
    2420              :         // REFERENCES:
    2421              :         // ASHRAE Systems and Equipment Handbook (SI), 1996. page 31.3
    2422              : 
    2423              :         // Using/Aliasing
    2424            0 :         auto &ventSlab = state.dataVentilatedSlab->VentSlab(Item);
    2425              : 
    2426              :         // SUBROUTINE PARAMETER DEFINITIONS:
    2427            0 :         Real64 constexpr LowTempDiff(0.1); // Smallest allowed temperature difference for comparisons
    2428              :         // (below this value the temperatures are assumed equal)
    2429            0 :         Real64 constexpr LowOAFracDiff(0.01); // Smallest allowed outside air fraction difference for comparison
    2430              :         // (below this value the fractions are assumed equal)
    2431              : 
    2432              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2433              :         Real64 QZnReq;
    2434              :         Real64 AirMassFlow;  // air mass flow rate [kg/sec]
    2435              :         int AirRelNode;      // outside air relief node
    2436              :         int ControlNode;     // the hot water or cold water inlet node
    2437              :         int InletNode;       // system air inlet node
    2438              :         int FanOutletNode;   // system fan outlet node
    2439              :         int ZoneAirInNode;   // zone supply air node
    2440              :         Real64 MaxOAFrac;    // maximum possible outside air fraction
    2441              :         Real64 MaxWaterFlow; // maximum water flow for heating or cooling [kg/sec]
    2442              :         Real64 MinOAFrac;    // minimum possible outside air fraction
    2443              :         Real64 MinWaterFlow; // minimum water flow for heating or cooling [kg/sec]
    2444              :         int OutletNode;      // air outlet node
    2445              :         int OutsideAirNode;  // outside air node
    2446              :         int MixoutNode;      // oa mixer outlet node
    2447              :         int ReturnAirNode;   // return air node
    2448              :         Real64 QUnitOut;     // heating or sens. cooling provided by fan coil unit [watts]
    2449              :         Real64 LatentOutput; // Latent (moisture) add/removal rate, negative is dehumidification [kg/s]
    2450              :         Real64 Tdesired;     // desired temperature after mixing inlet and outdoor air [degrees C]
    2451              :         Real64 Tinlet;       // temperature of air coming into the ventilated slab [degrees C]
    2452              :         Real64 Toutdoor;     // temperature of outdoor air being introduced into the ventilated slab [degrees C]
    2453              :         Real64 MaxSteamFlow;
    2454              :         Real64 MinSteamFlow;
    2455              :         Real64 RadInTemp;      // "Desired" radiant system air inlet temperature [Celsius]**setpoint
    2456              :         Real64 SetPointTemp;   // temperature that will be used to control the radiant system [Celsius]
    2457              :         Real64 SetPointTempHi; // Current high point in setpoint temperature range
    2458              :         Real64 SetPointTempLo; // Current low point in setpoint temperature range
    2459              :         Real64 AirTempHi;      // Current high point in water temperature range
    2460              :         Real64 AirTempLo;      // Current low point in water temperature range
    2461              :         Real64 AirTempHeatHi;  // Current high point in water temperature range
    2462              :         Real64 AirTempCoolLo;  // Current low point in water temperature range
    2463              :         Real64 CpFan;          // Intermediate calculational variable for specific heat of air <<NOV9 Updated
    2464              :         Real64 ZoneRadNum;     // number of zone being served *********************
    2465              :         int RadSurfNum;        // DO loop counter for the surfaces that comprise a particular radiant system
    2466            0 :         static std::string const CurrentModuleObject("ZoneHVAC:VentilatedSlab");
    2467              : 
    2468            0 :         switch (ventSlab.coilOption) {
    2469            0 :         case CoilType::Both: {
    2470              : 
    2471            0 :             switch (ventSlab.hCoilType) {
    2472            0 :             case HeatingCoilType::Water: {
    2473            0 :                 WaterCoils::CheckWaterCoilSchedule(state, ventSlab.heatingCoilName, ventSlab.heatingCoilSchedValue, ventSlab.heatingCoil_Index);
    2474            0 :                 break;
    2475              :             }
    2476            0 :             case HeatingCoilType::Steam: {
    2477            0 :                 SteamCoils::CheckSteamCoilSchedule(
    2478            0 :                     state, "Coil:Heating:Steam", ventSlab.heatingCoilName, ventSlab.heatingCoilSchedValue, ventSlab.heatingCoil_Index);
    2479            0 :                 break;
    2480              :             }
    2481            0 :             case HeatingCoilType::Electric: {
    2482            0 :                 HeatingCoils::CheckHeatingCoilSchedule(
    2483            0 :                     state, "Coil:Heating:Electric", ventSlab.heatingCoilName, ventSlab.heatingCoilSchedValue, ventSlab.heatingCoil_Index);
    2484            0 :                 break;
    2485              :             }
    2486            0 :             case HeatingCoilType::Gas: {
    2487            0 :                 HeatingCoils::CheckHeatingCoilSchedule(
    2488            0 :                     state, "Coil:Heating:Fuel", ventSlab.heatingCoilName, ventSlab.heatingCoilSchedValue, ventSlab.heatingCoil_Index);
    2489            0 :                 break;
    2490              :             }
    2491            0 :             default:
    2492            0 :                 break;
    2493              :             }
    2494              : 
    2495            0 :             switch (ventSlab.cCoilType) {
    2496            0 :             case CoolingCoilType::WaterCooling:
    2497              :             case CoolingCoilType::DetailedCooling: {
    2498            0 :                 WaterCoils::CheckWaterCoilSchedule(state, ventSlab.coolingCoilName, ventSlab.coolingCoilSchedValue, ventSlab.coolingCoil_Index);
    2499            0 :                 break;
    2500              :             }
    2501            0 :             case CoolingCoilType::HXAssisted: {
    2502            0 :                 HVACHXAssistedCoolingCoil::CheckHXAssistedCoolingCoilSchedule(state,
    2503              :                                                                               "CoilSystem:Cooling:Water:HeatExchangerAssisted",
    2504              :                                                                               ventSlab.coolingCoilName,
    2505            0 :                                                                               ventSlab.coolingCoilSchedValue,
    2506            0 :                                                                               ventSlab.coolingCoil_Index);
    2507            0 :                 break;
    2508              :             }
    2509            0 :             default:
    2510            0 :                 break;
    2511              :             }
    2512            0 :             break;
    2513              :         }
    2514            0 :         case CoilType::Heating: {
    2515              : 
    2516            0 :             switch (ventSlab.hCoilType) {
    2517            0 :             case HeatingCoilType::Water: {
    2518            0 :                 WaterCoils::CheckWaterCoilSchedule(state, ventSlab.heatingCoilName, ventSlab.heatingCoilSchedValue, ventSlab.heatingCoil_Index);
    2519            0 :                 break;
    2520              :             }
    2521            0 :             case HeatingCoilType::Steam: {
    2522            0 :                 SteamCoils::CheckSteamCoilSchedule(
    2523            0 :                     state, "Coil:Heating:Steam", ventSlab.heatingCoilName, ventSlab.heatingCoilSchedValue, ventSlab.heatingCoil_Index);
    2524            0 :                 break;
    2525              :             }
    2526            0 :             case HeatingCoilType::Electric: {
    2527            0 :                 HeatingCoils::CheckHeatingCoilSchedule(
    2528            0 :                     state, "Coil:Heating:Electric", ventSlab.heatingCoilName, ventSlab.heatingCoilSchedValue, ventSlab.heatingCoil_Index);
    2529            0 :                 break;
    2530              :             }
    2531            0 :             case HeatingCoilType::Gas: {
    2532            0 :                 HeatingCoils::CheckHeatingCoilSchedule(
    2533            0 :                     state, "Coil:Heating:Fuel", ventSlab.heatingCoilName, ventSlab.heatingCoilSchedValue, ventSlab.heatingCoil_Index);
    2534            0 :                 break;
    2535              :             }
    2536            0 :             default:
    2537            0 :                 break;
    2538              :             }
    2539            0 :             break;
    2540              :         }
    2541            0 :         case CoilType::Cooling: {
    2542              : 
    2543            0 :             switch (ventSlab.cCoilType) {
    2544            0 :             case CoolingCoilType::WaterCooling:
    2545              :             case CoolingCoilType::DetailedCooling: {
    2546            0 :                 WaterCoils::CheckWaterCoilSchedule(state, ventSlab.coolingCoilName, ventSlab.coolingCoilSchedValue, ventSlab.coolingCoil_Index);
    2547            0 :                 break;
    2548              :             }
    2549            0 :             case CoolingCoilType::HXAssisted: {
    2550            0 :                 HVACHXAssistedCoolingCoil::CheckHXAssistedCoolingCoilSchedule(state,
    2551              :                                                                               "CoilSystem:Cooling:Water:HeatExchangerAssisted",
    2552              :                                                                               ventSlab.coolingCoilName,
    2553            0 :                                                                               ventSlab.coolingCoilSchedValue,
    2554            0 :                                                                               ventSlab.coolingCoil_Index);
    2555            0 :                 break;
    2556              :             }
    2557            0 :             default:
    2558            0 :                 break;
    2559              :             }
    2560              :         }
    2561              :         case CoilType::None:
    2562              :         default:
    2563            0 :             break;
    2564              :         }
    2565              : 
    2566              :         // initialize local variables
    2567            0 :         ControlNode = 0;
    2568            0 :         QUnitOut = 0.0;
    2569            0 :         LatentOutput = 0.0;
    2570            0 :         MaxWaterFlow = 0.0;
    2571            0 :         MinWaterFlow = 0.0;
    2572            0 :         AirMassFlow = 0.0;
    2573            0 :         InletNode = ventSlab.ReturnAirNode;
    2574            0 :         OutletNode = ventSlab.RadInNode;
    2575            0 :         FanOutletNode = ventSlab.FanOutletNode;
    2576            0 :         ZoneAirInNode = ventSlab.ZoneAirInNode;
    2577            0 :         OutsideAirNode = ventSlab.OutsideAirNode;
    2578            0 :         AirRelNode = ventSlab.AirReliefNode;
    2579            0 :         MixoutNode = ventSlab.OAMixerOutNode;
    2580            0 :         ReturnAirNode = ventSlab.ReturnAirNode;
    2581            0 :         ZoneRadNum = ventSlab.ZonePtr;
    2582            0 :         RadSurfNum = ventSlab.NumOfSurfaces;
    2583            0 :         Tinlet = state.dataLoopNodes->Node(InletNode).Temp;
    2584            0 :         Toutdoor = state.dataLoopNodes->Node(OutsideAirNode).Temp;
    2585            0 :         auto const &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
    2586              : 
    2587              :         // Control Type Check
    2588            0 :         switch (ventSlab.controlType) {
    2589            0 :         case ControlType::MeanAirTemp: {
    2590            0 :             SetPointTemp = thisZoneHB.MAT;
    2591            0 :             break;
    2592              :         }
    2593            0 :         case ControlType::MeanRadTemp: {
    2594            0 :             SetPointTemp = thisZoneHB.MRT;
    2595            0 :             break;
    2596              :         }
    2597            0 :         case ControlType::OperativeTemp: {
    2598            0 :             SetPointTemp = 0.5 * (thisZoneHB.MAT + thisZoneHB.MRT);
    2599            0 :             break;
    2600              :         }
    2601            0 :         case ControlType::OutdoorDryBulbTemp: {
    2602            0 :             SetPointTemp = state.dataEnvrn->OutDryBulbTemp;
    2603            0 :             break;
    2604              :         }
    2605            0 :         case ControlType::OutdoorWetBulbTemp: {
    2606            0 :             SetPointTemp = state.dataEnvrn->OutWetBulbTemp;
    2607            0 :             break;
    2608              :         }
    2609            0 :         case ControlType::SurfaceTemp: {
    2610            0 :             SetPointTemp = state.dataHeatBalSurf->SurfInsideTempHist(1)(ventSlab.SurfacePtr(RadSurfNum));
    2611            0 :             break;
    2612              :         }
    2613            0 :         case ControlType::DewPointTemp: {
    2614            0 :             SetPointTemp = Psychrometrics::PsyTdpFnWPb(
    2615            0 :                 state, state.dataZoneTempPredictorCorrector->zoneHeatBalance(ventSlab.ZonePtr).airHumRat, state.dataEnvrn->OutBaroPress);
    2616            0 :             break;
    2617              :         }
    2618            0 :         default: {              // Should never get here
    2619            0 :             SetPointTemp = 0.0; // Suppress uninitialized warning
    2620            0 :             ShowSevereError(state, format("Illegal control type in low temperature radiant system: {}", ventSlab.Name));
    2621            0 :             ShowFatalError(state, "Preceding condition causes termination.");
    2622            0 :         } break;
    2623              :         } // switch (ctrlType)
    2624              : 
    2625              :         // Load Check
    2626              : 
    2627            0 :         AirTempHeatHi = ventSlab.hotCtrlHiTempSched->getCurrentVal();
    2628            0 :         AirTempCoolLo = ventSlab.coldCtrlLoTempSched->getCurrentVal();
    2629              : 
    2630            0 :         if (((SetPointTemp >= AirTempHeatHi) && (SetPointTemp <= AirTempCoolLo)) || (ventSlab.availSched->getCurrentVal() <= 0)) {
    2631              : 
    2632              :             // System is off or has no load upon it; set the flow rates to zero and then
    2633              :             // simulate the components with the no flow conditions
    2634            0 :             state.dataLoopNodes->Node(InletNode).MassFlowRate = 0.0;
    2635            0 :             state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = 0.0;
    2636            0 :             state.dataLoopNodes->Node(InletNode).MassFlowRateMinAvail = 0.0;
    2637            0 :             state.dataLoopNodes->Node(OutletNode).MassFlowRate = 0.0;
    2638            0 :             state.dataLoopNodes->Node(OutletNode).MassFlowRateMaxAvail = 0.0;
    2639            0 :             state.dataLoopNodes->Node(OutletNode).MassFlowRateMinAvail = 0.0;
    2640            0 :             state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate = 0.0;
    2641            0 :             state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMaxAvail = 0.0;
    2642            0 :             state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMinAvail = 0.0;
    2643            0 :             state.dataLoopNodes->Node(AirRelNode).MassFlowRate = 0.0;
    2644            0 :             state.dataLoopNodes->Node(AirRelNode).MassFlowRateMaxAvail = 0.0;
    2645            0 :             state.dataLoopNodes->Node(AirRelNode).MassFlowRateMinAvail = 0.0;
    2646            0 :             state.dataLoopNodes->Node(ReturnAirNode).MassFlowRate = 0.0;
    2647            0 :             state.dataLoopNodes->Node(ReturnAirNode).MassFlowRateMaxAvail = 0.0;
    2648            0 :             state.dataLoopNodes->Node(ReturnAirNode).MassFlowRateMinAvail = 0.0;
    2649            0 :             state.dataLoopNodes->Node(MixoutNode).MassFlowRate = 0.0;
    2650            0 :             state.dataLoopNodes->Node(MixoutNode).MassFlowRateMaxAvail = 0.0;
    2651            0 :             state.dataLoopNodes->Node(MixoutNode).MassFlowRateMinAvail = 0.0;
    2652            0 :             state.dataLoopNodes->Node(FanOutletNode).MassFlowRate = 0.0;
    2653            0 :             state.dataLoopNodes->Node(FanOutletNode).MassFlowRateMaxAvail = 0.0;
    2654            0 :             state.dataLoopNodes->Node(FanOutletNode).MassFlowRateMinAvail = 0.0;
    2655            0 :             AirMassFlow = 0.0;
    2656            0 :             state.dataVentilatedSlab->HCoilOn = false;
    2657              : 
    2658              :             // Node condition
    2659            0 :             state.dataLoopNodes->Node(InletNode).Temp = state.dataHeatBalSurf->SurfInsideTempHist(1)(ventSlab.SurfacePtr(1));
    2660            0 :             state.dataLoopNodes->Node(FanOutletNode).Temp = state.dataLoopNodes->Node(InletNode).Temp;
    2661            0 :             state.dataLoopNodes->Node(OutletNode).Temp = state.dataLoopNodes->Node(FanOutletNode).Temp;
    2662              : 
    2663              :             // Node condition
    2664            0 :             if (ventSlab.SysConfg == VentilatedSlabConfig::SeriesSlabs) {
    2665            0 :                 bool ErrorsFound = false; // Set to true if errors in input, fatal at end of routine
    2666            0 :                 for (RadSurfNum = 1; RadSurfNum <= ventSlab.NumOfSurfaces; ++RadSurfNum) {
    2667            0 :                     std::string SlabName = ventSlab.SurfaceName(RadSurfNum);
    2668            0 :                     std::string MSlabIn = ventSlab.SlabIn(RadSurfNum);
    2669            0 :                     std::string MSlabOut = ventSlab.SlabOut(RadSurfNum);
    2670            0 :                     ventSlab.MSlabInNode = NodeInputManager::GetOnlySingleNode(state,
    2671              :                                                                                MSlabIn,
    2672              :                                                                                ErrorsFound,
    2673              :                                                                                DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
    2674              :                                                                                SlabName,
    2675              :                                                                                DataLoopNode::NodeFluidType::Air,
    2676              :                                                                                DataLoopNode::ConnectionType::Internal,
    2677              :                                                                                NodeInputManager::CompFluidStream::Primary,
    2678              :                                                                                DataLoopNode::ObjectIsNotParent);
    2679            0 :                     ventSlab.MSlabOutNode = NodeInputManager::GetOnlySingleNode(state,
    2680              :                                                                                 MSlabOut,
    2681              :                                                                                 ErrorsFound,
    2682              :                                                                                 DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
    2683              :                                                                                 SlabName,
    2684              :                                                                                 DataLoopNode::NodeFluidType::Air,
    2685              :                                                                                 DataLoopNode::ConnectionType::Internal,
    2686              :                                                                                 NodeInputManager::CompFluidStream::Primary,
    2687              :                                                                                 DataLoopNode::ObjectIsNotParent);
    2688            0 :                     int MSlabInletNode = ventSlab.MSlabInNode;
    2689            0 :                     int MSlabOutletNode = ventSlab.MSlabOutNode;
    2690              : 
    2691            0 :                     state.dataLoopNodes->Node(MSlabInletNode).Temp = state.dataLoopNodes->Node(InletNode).Temp;
    2692            0 :                     state.dataLoopNodes->Node(MSlabOutletNode).Temp = state.dataLoopNodes->Node(MSlabInletNode).Temp;
    2693            0 :                 }
    2694              :             }
    2695              : 
    2696            0 :             CalcVentilatedSlabComps(state, Item, FirstHVACIteration, QUnitOut);
    2697              : 
    2698              :         } else { // System On
    2699              : 
    2700            0 :             if (SetPointTemp < AirTempHeatHi) { // HEATING MODE
    2701            0 :                 state.dataVentilatedSlab->OperatingMode = HeatingMode;
    2702              : 
    2703              :                 // Check the setpoint and temperature span
    2704            0 :                 SetPointTempHi = ventSlab.hotCtrlHiTempSched->getCurrentVal();
    2705            0 :                 SetPointTempLo = ventSlab.hotCtrlLoTempSched->getCurrentVal();
    2706            0 :                 if (SetPointTempHi < SetPointTempLo) {
    2707            0 :                     ShowSevereError(state, format("Heating setpoint temperature mismatch in{}", ventSlab.Name));
    2708            0 :                     ShowContinueError(state, "High setpoint temperature is less than low setpoint temperature--check your schedule input");
    2709            0 :                     ShowFatalError(state, "Preceding condition causes termination.");
    2710              :                 }
    2711              : 
    2712            0 :                 AirTempHi = ventSlab.hotAirHiTempSched->getCurrentVal();
    2713            0 :                 AirTempLo = ventSlab.hotAirLoTempSched->getCurrentVal();
    2714              : 
    2715            0 :                 if (AirTempHi < AirTempLo) {
    2716            0 :                     ShowSevereError(state, format("Heating Air temperature mismatch in{}", ventSlab.Name));
    2717            0 :                     ShowContinueError(state, "High Air temperature is less than low Air temperature--check your schedule input");
    2718            0 :                     ShowFatalError(state, "Preceding condition causes termination.");
    2719              :                 }
    2720              : 
    2721            0 :                 if (SetPointTemp >= SetPointTempHi) {
    2722              :                     // System is above high heating setpoint so we should be able to turn the system off
    2723            0 :                     RadInTemp = AirTempLo;
    2724              : 
    2725            0 :                 } else if (SetPointTemp <= SetPointTempLo) {
    2726              :                     // System is running with its highest inlet temperature
    2727            0 :                     RadInTemp = AirTempHi;
    2728              :                 } else {
    2729              :                     // Interpolate to obtain the current radiant system inlet temperature
    2730            0 :                     RadInTemp = AirTempHi - (AirTempHi - AirTempLo) * (SetPointTemp - SetPointTempLo) / (SetPointTempHi - SetPointTempLo);
    2731              :                 }
    2732              : 
    2733            0 :                 state.dataLoopNodes->Node(ventSlab.RadInNode).Temp = RadInTemp;
    2734              : 
    2735            0 :                 ControlNode = ventSlab.HotControlNode;
    2736            0 :                 MaxWaterFlow = ventSlab.MaxHotWaterFlow;
    2737            0 :                 MinWaterFlow = ventSlab.MinHotWaterFlow;
    2738            0 :                 MaxSteamFlow = ventSlab.MaxHotSteamFlow;
    2739            0 :                 MinSteamFlow = ventSlab.MinHotSteamFlow;
    2740              : 
    2741              :                 // On the first HVAC iteration the system values are given to the controller, but after that
    2742              :                 // the demand limits are in place and there needs to be feedback to the Zone Equipment
    2743              : 
    2744            0 :                 if (!FirstHVACIteration && ventSlab.hCoilType == HeatingCoilType::Water) {
    2745            0 :                     MaxWaterFlow = state.dataLoopNodes->Node(ControlNode).MassFlowRateMaxAvail;
    2746            0 :                     MinWaterFlow = state.dataLoopNodes->Node(ControlNode).MassFlowRateMinAvail;
    2747              :                 }
    2748              : 
    2749            0 :                 if (!FirstHVACIteration && ventSlab.hCoilType == HeatingCoilType::Steam) {
    2750            0 :                     MaxSteamFlow = state.dataLoopNodes->Node(ControlNode).MassFlowRateMaxAvail;
    2751            0 :                     MinSteamFlow = state.dataLoopNodes->Node(ControlNode).MassFlowRateMinAvail;
    2752              :                 }
    2753              : 
    2754            0 :                 state.dataVentilatedSlab->HCoilOn = true;
    2755              : 
    2756            0 :                 if (state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate > 0.0) {
    2757            0 :                     MinOAFrac =
    2758            0 :                         ventSlab.minOASched->getCurrentVal() * (ventSlab.MinOutAirMassFlow / state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate);
    2759              :                 } else {
    2760            0 :                     MinOAFrac = 0.0;
    2761              :                 }
    2762              : 
    2763            0 :                 MinOAFrac = min(1.0, max(0.0, MinOAFrac));
    2764              : 
    2765            0 :                 if ((!ventSlab.heatingCoilPresent) || (ventSlab.heatingCoilSchedValue <= 0.0)) {
    2766              :                     // In heating mode, but there is no coil to provide heating.  This is handled
    2767              :                     // differently than if there was a heating coil present.  Fixed temperature
    2768              :                     // will still try to vary the amount of outside air to meet the desired
    2769              :                     // mixed air temperature, while variable percent will go to full ventilation
    2770              :                     // when it is most advantageous.
    2771              : 
    2772              :                     // If there are no coil, Slab In Node is assumed to be Fan Outlet Node
    2773              : 
    2774            0 :                     OutletNode = FanOutletNode;
    2775              : 
    2776            0 :                     switch (ventSlab.outsideAirControlType) {
    2777            0 :                     case OutsideAirControlType::FixedOAControl: {
    2778              :                         // In this control type, the outdoor air flow rate is fixed to the maximum value
    2779              :                         // which is equal to the minimum value, regardless of all the other conditions.
    2780            0 :                         state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    2781            0 :                         break;
    2782              :                     }
    2783            0 :                     case OutsideAirControlType::VariablePercent: {
    2784              :                         // This algorithm is probably a bit simplistic in that it just bounces
    2785              :                         // back and forth between the maximum outside air and the minimum.  In
    2786              :                         // reality, a system *might* vary between the two based on the load in
    2787              :                         // the zone.  This simple flow control might cause some overcooling but
    2788              :                         // chances are that if there is a cooling load and the zone temperature
    2789              :                         // gets above the outside temperature that overcooling won't be significant.
    2790            0 :                         Tinlet = state.dataLoopNodes->Node(InletNode).Temp;
    2791            0 :                         Toutdoor = state.dataLoopNodes->Node(OutsideAirNode).Temp;
    2792              : 
    2793            0 :                         if (Tinlet >= Toutdoor) {
    2794              : 
    2795            0 :                             state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    2796              : 
    2797              :                         } else { // Tinlet < Toutdoor
    2798            0 :                             MaxOAFrac = ventSlab.maxOASched->getCurrentVal();
    2799            0 :                             state.dataVentilatedSlab->OAMassFlowRate = MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    2800              :                         }
    2801            0 :                         break;
    2802              :                     }
    2803            0 :                     case OutsideAirControlType::FixedTemperature: {
    2804              :                         // This is basically the same algorithm as for the heating case...
    2805            0 :                         Tdesired = ventSlab.tempSched->getCurrentVal();
    2806            0 :                         MaxOAFrac = 1.0;
    2807              : 
    2808            0 :                         if (std::abs(Tinlet - Toutdoor) <= LowTempDiff) { // no difference in indoor and outdoor conditions-->set OA to minimum
    2809            0 :                             state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    2810            0 :                         } else if (std::abs(MaxOAFrac - MinOAFrac) <= LowOAFracDiff) { // no difference in outside air fractions
    2811            0 :                             state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    2812            0 :                         } else if (((Tdesired <= Tinlet) && (Tdesired >= Toutdoor)) || ((Tdesired >= Tinlet) && (Tdesired <= Toutdoor))) {
    2813              :                             // Desired temperature is between the inlet and outdoor temperatures
    2814              :                             // so vary the flow rate between no outside air and no recirculation air
    2815              :                             // then applying the maximum and minimum limits the user has scheduled
    2816              :                             // to make sure too much/little outside air is being introduced
    2817            0 :                             state.dataVentilatedSlab->OAMassFlowRate =
    2818            0 :                                 ((Tdesired - Tinlet) / (Toutdoor - Tinlet)) * state.dataLoopNodes->Node(InletNode).MassFlowRate;
    2819            0 :                             state.dataVentilatedSlab->OAMassFlowRate =
    2820            0 :                                 max(state.dataVentilatedSlab->OAMassFlowRate, (MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate));
    2821            0 :                             state.dataVentilatedSlab->OAMassFlowRate =
    2822            0 :                                 min(state.dataVentilatedSlab->OAMassFlowRate, (MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate));
    2823            0 :                         } else if ((Tdesired < Tinlet) && (Tdesired < Toutdoor)) {
    2824              :                             // Desired temperature is below both the inlet and outdoor temperatures
    2825              :                             // so use whichever flow rate (max or min) that will get closer
    2826            0 :                             if (Tinlet < Toutdoor) { // Tinlet closer to Tdesired so use minimum outside air
    2827            0 :                                 state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    2828              :                             } else { // Toutdoor closer to Tdesired so use maximum outside air
    2829            0 :                                 state.dataVentilatedSlab->OAMassFlowRate = MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    2830              :                             }
    2831            0 :                         } else if ((Tdesired > Tinlet) && (Tdesired > Toutdoor)) {
    2832              :                             // Desired temperature is above both the inlet and outdoor temperatures
    2833              :                             // so use whichever flow rate (max or min) that will get closer
    2834            0 :                             if (Tinlet > Toutdoor) { // Tinlet closer to Tdesired so use minimum outside air
    2835            0 :                                 state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    2836              :                             } else { // Toutdoor closer to Tdesired so use maximum outside air
    2837            0 :                                 state.dataVentilatedSlab->OAMassFlowRate = MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    2838              :                             }
    2839              :                         } else {
    2840              :                             // It should NEVER get to this point, but just in case...
    2841            0 :                             ShowFatalError(state, format("Ventilated Slab simulation control: illogical condition for {}", ventSlab.Name));
    2842              :                         }
    2843            0 :                         break;
    2844              :                     }
    2845            0 :                     default:
    2846            0 :                         break;
    2847              :                     }
    2848              : 
    2849            0 :                     CalcVentilatedSlabComps(state, Item, FirstHVACIteration, QUnitOut);
    2850              : 
    2851              :                 } else { // Heating Coil present
    2852              : 
    2853            0 :                     switch (ventSlab.outsideAirControlType) {
    2854            0 :                     case OutsideAirControlType::FixedOAControl: {
    2855              :                         // In this control type, the outdoor air flow rate is fixed to the maximum value
    2856              :                         // which is equal to the minimum value, regardless of all the other conditions.
    2857            0 :                         if (state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate > 0.0) {
    2858            0 :                             MaxOAFrac = min(1.0, max(0.0, ventSlab.maxOASched->getCurrentVal()));
    2859              :                         } else {
    2860            0 :                             MaxOAFrac = 0.0;
    2861              :                         }
    2862            0 :                         state.dataVentilatedSlab->OAMassFlowRate = MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    2863            0 :                         break;
    2864              :                     }
    2865            0 :                     case OutsideAirControlType::VariablePercent: {
    2866              :                         // In heating mode, the ouside air for "variable percent" control
    2867              :                         // is set to the minimum value
    2868              : 
    2869            0 :                         state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    2870            0 :                         break;
    2871              :                     }
    2872            0 :                     case OutsideAirControlType::FixedTemperature: {
    2873              :                         // This is basically the same algorithm as for the heating case...
    2874            0 :                         Tdesired = ventSlab.tempSched->getCurrentVal();
    2875            0 :                         MaxOAFrac = 1.0;
    2876              : 
    2877            0 :                         if (std::abs(Tinlet - Toutdoor) <= LowTempDiff) { // no difference in indoor and outdoor conditions-->set OA to minimum
    2878            0 :                             state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    2879            0 :                         } else if (std::abs(MaxOAFrac - MinOAFrac) <= LowOAFracDiff) { // no difference in outside air fractions
    2880            0 :                             state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    2881            0 :                         } else if (((Tdesired <= Tinlet) && (Tdesired >= Toutdoor)) || ((Tdesired >= Tinlet) && (Tdesired <= Toutdoor))) {
    2882              :                             // Desired temperature is between the inlet and outdoor temperatures
    2883              :                             // so vary the flow rate between no outside air and no recirculation air
    2884              :                             // then applying the maximum and minimum limits the user has scheduled
    2885              :                             // to make sure too much/little outside air is being introduced
    2886            0 :                             state.dataVentilatedSlab->OAMassFlowRate =
    2887            0 :                                 ((Tdesired - Tinlet) / (Toutdoor - Tinlet)) * state.dataLoopNodes->Node(InletNode).MassFlowRate;
    2888            0 :                             state.dataVentilatedSlab->OAMassFlowRate =
    2889            0 :                                 max(state.dataVentilatedSlab->OAMassFlowRate, (MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate));
    2890            0 :                             state.dataVentilatedSlab->OAMassFlowRate =
    2891            0 :                                 min(state.dataVentilatedSlab->OAMassFlowRate, (MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate));
    2892            0 :                         } else if ((Tdesired < Tinlet) && (Tdesired < Toutdoor)) {
    2893              :                             // Desired temperature is below both the inlet and outdoor temperatures
    2894              :                             // so use whichever flow rate (max or min) that will get closer
    2895            0 :                             if (Tinlet < Toutdoor) { // Tinlet closer to Tdesired so use minimum outside air
    2896            0 :                                 state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    2897              :                             } else { // Toutdoor closer to Tdesired so use maximum outside air
    2898            0 :                                 state.dataVentilatedSlab->OAMassFlowRate = MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    2899              :                             }
    2900            0 :                         } else if ((Tdesired > Tinlet) && (Tdesired > Toutdoor)) {
    2901              :                             // Desired temperature is above both the inlet and outdoor temperatures
    2902              :                             // so use whichever flow rate (max or min) that will get closer
    2903            0 :                             if (Tinlet > Toutdoor) { // Tinlet closer to Tdesired so use minimum outside air
    2904            0 :                                 state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    2905              :                             } else { // Toutdoor closer to Tdesired so use maximum outside air
    2906            0 :                                 state.dataVentilatedSlab->OAMassFlowRate = MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    2907              :                             }
    2908              :                         } else {
    2909              :                             // It should NEVER get to this point, but just in case...
    2910            0 :                             ShowFatalError(state, format("Ventilated Slab simulation control: illogical condition for {}", ventSlab.Name));
    2911              :                         }
    2912            0 :                         break;
    2913              :                     }
    2914            0 :                     default:
    2915            0 :                         break;
    2916              :                     }
    2917              : 
    2918            0 :                     SimVentSlabOAMixer(state, Item);
    2919              : 
    2920            0 :                     state.dataFans->fans(ventSlab.Fan_Index)->simulate(state, FirstHVACIteration, _, _);
    2921              : 
    2922            0 :                     CpFan = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(FanOutletNode).HumRat);
    2923            0 :                     QZnReq =
    2924            0 :                         (state.dataLoopNodes->Node(OutletNode).MassFlowRate) * CpFan * (RadInTemp - state.dataLoopNodes->Node(FanOutletNode).Temp);
    2925              : 
    2926              :                     // Setup the coil configuration
    2927            0 :                     switch (ventSlab.hCoilType) {
    2928              : 
    2929            0 :                     case HeatingCoilType::Water: {
    2930              :                         // control water flow to obtain output matching QZnReq
    2931              : 
    2932            0 :                         ControlCompOutput(state,
    2933            0 :                                           ventSlab.Name,
    2934              :                                           cMO_VentilatedSlab,
    2935              :                                           Item,
    2936              :                                           FirstHVACIteration,
    2937              :                                           QZnReq,
    2938              :                                           ControlNode,
    2939              :                                           MaxWaterFlow,
    2940              :                                           MinWaterFlow,
    2941              :                                           0.001,
    2942            0 :                                           ventSlab.ControlCompTypeNum,
    2943            0 :                                           ventSlab.CompErrIndex,
    2944              :                                           _,
    2945              :                                           _,
    2946              :                                           _,
    2947              :                                           _,
    2948              :                                           _,
    2949            0 :                                           ventSlab.HWPlantLoc);
    2950            0 :                         break;
    2951              :                     }
    2952            0 :                     case HeatingCoilType::Gas:
    2953              :                     case HeatingCoilType::Electric:
    2954              :                     case HeatingCoilType::Steam: {
    2955              : 
    2956            0 :                         CalcVentilatedSlabComps(state, Item, FirstHVACIteration, QUnitOut);
    2957            0 :                         break;
    2958              :                     }
    2959            0 :                     default:
    2960            0 :                         break;
    2961              :                     }
    2962              : 
    2963              :                 } //  Coil/no coil block
    2964              : 
    2965            0 :             } else if (SetPointTemp > AirTempCoolLo) { // Cooling Mode
    2966              : 
    2967            0 :                 state.dataVentilatedSlab->OperatingMode = CoolingMode;
    2968            0 :                 SetPointTempHi = ventSlab.coldCtrlHiTempSched->getCurrentVal();
    2969            0 :                 SetPointTempLo = ventSlab.coldCtrlLoTempSched->getCurrentVal();
    2970            0 :                 if (SetPointTempHi < SetPointTempLo) {
    2971            0 :                     ShowSevereError(state, format("Cooling setpoint temperature mismatch in{}", ventSlab.Name));
    2972            0 :                     ShowContinueError(state, "High setpoint temperature is less than low setpoint temperature--check your schedule input");
    2973            0 :                     ShowFatalError(state, "Preceding condition causes termination.");
    2974              :                 }
    2975              : 
    2976            0 :                 AirTempHi = ventSlab.coldAirHiTempSched->getCurrentVal();
    2977            0 :                 AirTempLo = ventSlab.coldAirLoTempSched->getCurrentVal();
    2978            0 :                 if (AirTempHi < AirTempLo) {
    2979            0 :                     ShowSevereError(state, format("Cooling Air temperature mismatch in{}", ventSlab.Name));
    2980            0 :                     ShowContinueError(state, "High Air temperature is less than low Air temperature--check your schedule input");
    2981            0 :                     ShowFatalError(state, "Preceding condition causes termination.");
    2982              :                 }
    2983              : 
    2984            0 :                 if (SetPointTemp <= SetPointTempLo) {
    2985              :                     // System is below low cooling setpoint so we should be able to turn the system off
    2986            0 :                     RadInTemp = AirTempHi;
    2987            0 :                 } else if (SetPointTemp >= SetPointTempHi) {
    2988              :                     // System is running with its lowest inlet temperature
    2989            0 :                     RadInTemp = AirTempLo;
    2990              :                 } else {
    2991              :                     // Interpolate to obtain the current radiant system inlet temperature
    2992            0 :                     RadInTemp = AirTempHi - (AirTempHi - AirTempLo) * (SetPointTemp - SetPointTempLo) / (SetPointTempHi - SetPointTempLo);
    2993              :                 }
    2994              : 
    2995            0 :                 ControlNode = ventSlab.ColdControlNode;
    2996            0 :                 MaxWaterFlow = ventSlab.MaxColdWaterFlow;
    2997            0 :                 MinWaterFlow = ventSlab.MinColdWaterFlow;
    2998              : 
    2999              :                 // On the first HVAC iteration the system values are given to the controller, but after that
    3000              :                 // the demand limits are in place and there needs to be feedback to the Zone Equipment
    3001            0 :                 if ((!FirstHVACIteration) && (ControlNode > 0) && (ventSlab.coolingCoilPresent)) {
    3002            0 :                     MaxWaterFlow = state.dataLoopNodes->Node(ControlNode).MassFlowRateMaxAvail;
    3003            0 :                     MinWaterFlow = state.dataLoopNodes->Node(ControlNode).MassFlowRateMinAvail;
    3004              :                 }
    3005            0 :                 state.dataVentilatedSlab->HCoilOn = false;
    3006              : 
    3007            0 :                 if (state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate > 0.0) {
    3008            0 :                     MinOAFrac =
    3009            0 :                         ventSlab.minOASched->getCurrentVal() * (ventSlab.MinOutAirMassFlow / state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate);
    3010              :                 } else {
    3011            0 :                     MinOAFrac = 0.0;
    3012              :                 }
    3013            0 :                 MinOAFrac = min(1.0, max(0.0, MinOAFrac));
    3014              : 
    3015            0 :                 if ((!ventSlab.coolingCoilPresent) || (ventSlab.coolingCoilSchedValue <= 0.0)) {
    3016              :                     // In cooling mode, but there is no coil to provide cooling.  This is handled
    3017              :                     // differently than if there was a cooling coil present.  Fixed temperature
    3018              :                     // will still try to vary the amount of outside air to meet the desired
    3019              :                     // mixed air temperature, while variable percent will go to full ventilation
    3020              :                     // when it is most advantageous.
    3021              : 
    3022              :                     // If there are no coil, Slab In Node is assumed to be Fan Outlet Node
    3023            0 :                     OutletNode = FanOutletNode;
    3024              : 
    3025            0 :                     switch (ventSlab.outsideAirControlType) {
    3026              : 
    3027            0 :                     case OutsideAirControlType::FixedOAControl: {
    3028              :                         // In this control type, the outdoor air flow rate is fixed to the maximum value
    3029              :                         // which is equal to the minimum value, regardless of all the other conditions.
    3030            0 :                         if (state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate > 0.0) {
    3031            0 :                             MaxOAFrac = min(1.0, max(0.0, ventSlab.maxOASched->getCurrentVal()));
    3032              :                         } else {
    3033            0 :                             MaxOAFrac = 0.0;
    3034              :                         }
    3035            0 :                         state.dataVentilatedSlab->OAMassFlowRate = MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    3036            0 :                         break;
    3037              :                     }
    3038            0 :                     case OutsideAirControlType::VariablePercent: {
    3039              :                         // This algorithm is probably a bit simplistic in that it just bounces
    3040              :                         // back and forth between the maximum outside air and the minimum.  In
    3041              :                         // reality, a system *might* vary between the two based on the load in
    3042              :                         // the zone.  This simple flow control might cause some overcooling but
    3043              :                         // chances are that if there is a cooling load and the zone temperature
    3044              :                         // gets above the outside temperature that overcooling won't be significant.
    3045              : 
    3046            0 :                         Tinlet = state.dataLoopNodes->Node(InletNode).Temp;
    3047            0 :                         Toutdoor = state.dataLoopNodes->Node(OutsideAirNode).Temp;
    3048              : 
    3049            0 :                         if (Tinlet <= Toutdoor) {
    3050              : 
    3051            0 :                             state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    3052              : 
    3053              :                         } else { // Tinlet > Toutdoor
    3054            0 :                             MaxOAFrac = ventSlab.maxOASched->getCurrentVal();
    3055            0 :                             state.dataVentilatedSlab->OAMassFlowRate = MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    3056              :                         }
    3057            0 :                         break;
    3058              :                     }
    3059            0 :                     case OutsideAirControlType::FixedTemperature: {
    3060              :                         // This is basically the same algorithm as for the heating case...
    3061            0 :                         Tdesired = ventSlab.tempSched->getCurrentVal();
    3062            0 :                         MaxOAFrac = 1.0;
    3063              : 
    3064            0 :                         if (std::abs(Tinlet - Toutdoor) <= LowTempDiff) { // no difference in indoor and outdoor conditions-->set OA to minimum
    3065            0 :                             state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    3066            0 :                         } else if (std::abs(MaxOAFrac - MinOAFrac) <= LowOAFracDiff) { // no difference in outside air fractions
    3067            0 :                             state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    3068            0 :                         } else if (((Tdesired <= Tinlet) && (Tdesired >= Toutdoor)) || ((Tdesired >= Tinlet) && (Tdesired <= Toutdoor))) {
    3069              :                             // Desired temperature is between the inlet and outdoor temperatures
    3070              :                             // so vary the flow rate between no outside air and no recirculation air
    3071              :                             // then applying the maximum and minimum limits the user has scheduled
    3072              :                             // to make sure too much/little outside air is being introduced
    3073            0 :                             state.dataVentilatedSlab->OAMassFlowRate =
    3074            0 :                                 ((Tdesired - Tinlet) / (Toutdoor - Tinlet)) * state.dataLoopNodes->Node(InletNode).MassFlowRate;
    3075            0 :                             state.dataVentilatedSlab->OAMassFlowRate =
    3076            0 :                                 max(state.dataVentilatedSlab->OAMassFlowRate, (MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate));
    3077            0 :                             state.dataVentilatedSlab->OAMassFlowRate =
    3078            0 :                                 min(state.dataVentilatedSlab->OAMassFlowRate, (MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate));
    3079            0 :                         } else if ((Tdesired < Tinlet) && (Tdesired < Toutdoor)) {
    3080              :                             // Desired temperature is below both the inlet and outdoor temperatures
    3081              :                             // so use whichever flow rate (max or min) that will get closer
    3082            0 :                             if (Tinlet < Toutdoor) { // Tinlet closer to Tdesired so use minimum outside air
    3083            0 :                                 state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    3084              :                             } else { // Toutdoor closer to Tdesired so use maximum outside air
    3085            0 :                                 state.dataVentilatedSlab->OAMassFlowRate = MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    3086              :                             }
    3087            0 :                         } else if ((Tdesired > Tinlet) && (Tdesired > Toutdoor)) {
    3088              :                             // Desired temperature is above both the inlet and outdoor temperatures
    3089              :                             // so use whichever flow rate (max or min) that will get closer
    3090            0 :                             if (Tinlet > Toutdoor) { // Tinlet closer to Tdesired so use minimum outside air
    3091            0 :                                 state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    3092              :                             } else { // Toutdoor closer to Tdesired so use maximum outside air
    3093            0 :                                 state.dataVentilatedSlab->OAMassFlowRate = MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    3094              :                             }
    3095              :                         } else {
    3096              :                             // It should NEVER get to this point, but just in case...
    3097            0 :                             ShowFatalError(state, format("{} simulation control: illogical condition for {}", cMO_VentilatedSlab, ventSlab.Name));
    3098              :                         }
    3099            0 :                         break;
    3100              :                     }
    3101            0 :                     default:
    3102            0 :                         break;
    3103              :                     }
    3104              : 
    3105            0 :                     CalcVentilatedSlabComps(state, Item, FirstHVACIteration, QUnitOut);
    3106              : 
    3107              :                 } else {
    3108              :                     // There is a cooling load and there is a cooling coil present (presumably).
    3109              :                     // Variable percent will throttle outside air back to the minimum while
    3110              :                     // fixed temperature will still try to vary the outside air amount to meet
    3111              :                     // the desired mixed air temperature.
    3112              : 
    3113            0 :                     switch (ventSlab.outsideAirControlType) {
    3114              : 
    3115            0 :                     case OutsideAirControlType::FixedOAControl: {
    3116              :                         // In this control type, the outdoor air flow rate is fixed to the maximum value
    3117              :                         // which is equal to the minimum value, regardless of all the other conditions.
    3118            0 :                         if (state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate > 0.0) {
    3119            0 :                             MaxOAFrac = min(1.0, max(0.0, ventSlab.maxOASched->getCurrentVal()));
    3120              :                         } else {
    3121            0 :                             MaxOAFrac = 0.0;
    3122              :                         }
    3123            0 :                         state.dataVentilatedSlab->OAMassFlowRate = MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    3124            0 :                         break;
    3125              :                     }
    3126            0 :                     case OutsideAirControlType::VariablePercent: {
    3127              :                         // A cooling coil is present so let it try to do the cooling...
    3128            0 :                         state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    3129            0 :                         break;
    3130              :                     }
    3131            0 :                     case OutsideAirControlType::FixedTemperature: {
    3132              :                         // This is basically the same algorithm as for the heating case...
    3133            0 :                         Tdesired = ventSlab.tempSched->getCurrentVal();
    3134              : 
    3135            0 :                         MaxOAFrac = 1.0;
    3136              : 
    3137            0 :                         if (std::abs(Tinlet - Toutdoor) <= LowTempDiff) { // no difference in indoor and outdoor conditions-->set OA to minimum
    3138            0 :                             state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    3139            0 :                         } else if (std::abs(MaxOAFrac - MinOAFrac) <= LowOAFracDiff) { // no difference in outside air fractions
    3140            0 :                             state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    3141            0 :                         } else if (((Tdesired <= Tinlet) && (Tdesired >= Toutdoor)) || ((Tdesired >= Tinlet) && (Tdesired <= Toutdoor))) {
    3142              :                             // Desired temperature is between the inlet and outdoor temperatures
    3143              :                             // so vary the flow rate between no outside air and no recirculation air
    3144              :                             // then applying the maximum and minimum limits the user has scheduled
    3145              :                             // to make sure too much/little outside air is being introduced
    3146            0 :                             state.dataVentilatedSlab->OAMassFlowRate =
    3147            0 :                                 ((Tdesired - Tinlet) / (Toutdoor - Tinlet)) * state.dataLoopNodes->Node(InletNode).MassFlowRate;
    3148            0 :                             state.dataVentilatedSlab->OAMassFlowRate =
    3149            0 :                                 max(state.dataVentilatedSlab->OAMassFlowRate, (MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate));
    3150            0 :                             state.dataVentilatedSlab->OAMassFlowRate =
    3151            0 :                                 min(state.dataVentilatedSlab->OAMassFlowRate, (MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate));
    3152            0 :                         } else if ((Tdesired < Tinlet) && (Tdesired < Toutdoor)) {
    3153              :                             // Desired temperature is below both the inlet and outdoor temperatures
    3154              :                             // so use whichever flow rate (max or min) that will get closer
    3155            0 :                             if (Tinlet < Toutdoor) { // Tinlet closer to Tdesired so use minimum outside air
    3156            0 :                                 state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    3157              :                             } else { // Toutdoor closer to Tdesired so use maximum outside air
    3158            0 :                                 state.dataVentilatedSlab->OAMassFlowRate = MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    3159              :                             }
    3160            0 :                         } else if ((Tdesired > Tinlet) && (Tdesired > Toutdoor)) {
    3161              :                             // Desired temperature is above both the inlet and outdoor temperatures
    3162              :                             // so use whichever flow rate (max or min) that will get closer
    3163            0 :                             if (Tinlet > Toutdoor) { // Tinlet closer to Tdesired so use minimum outside air
    3164            0 :                                 state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    3165              :                             } else { // Toutdoor closer to Tdesired so use maximum outside air
    3166            0 :                                 state.dataVentilatedSlab->OAMassFlowRate = MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
    3167              :                             }
    3168              :                         } else {
    3169              :                             // It should NEVER get to this point, but just in case...
    3170            0 :                             ShowFatalError(state, format("{} simulation control: illogical condition for {}", cMO_VentilatedSlab, ventSlab.Name));
    3171              :                         }
    3172            0 :                         break;
    3173              :                     }
    3174            0 :                     default:
    3175            0 :                         break;
    3176              :                     }
    3177              : 
    3178              :                     // control water flow to obtain output matching Low Setpoint Temperateure
    3179            0 :                     state.dataVentilatedSlab->HCoilOn = false;
    3180              : 
    3181            0 :                     SimVentSlabOAMixer(state, Item);
    3182            0 :                     state.dataFans->fans(ventSlab.Fan_Index)->simulate(state, FirstHVACIteration, _, _);
    3183              : 
    3184            0 :                     CpFan = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(FanOutletNode).HumRat);
    3185            0 :                     QZnReq =
    3186            0 :                         (state.dataLoopNodes->Node(OutletNode).MassFlowRate) * CpFan * (RadInTemp - state.dataLoopNodes->Node(FanOutletNode).Temp);
    3187              : 
    3188            0 :                     ControlCompOutput(state,
    3189            0 :                                       ventSlab.Name,
    3190              :                                       cMO_VentilatedSlab,
    3191              :                                       Item,
    3192              :                                       FirstHVACIteration,
    3193              :                                       QZnReq,
    3194              :                                       ControlNode,
    3195              :                                       MaxWaterFlow,
    3196              :                                       MinWaterFlow,
    3197              :                                       0.001,
    3198            0 :                                       ventSlab.ControlCompTypeNum,
    3199            0 :                                       ventSlab.CompErrIndex,
    3200              :                                       _,
    3201              :                                       _,
    3202              :                                       _,
    3203              :                                       _,
    3204              :                                       _,
    3205            0 :                                       ventSlab.CWPlantLoc);
    3206              :                 }
    3207              : 
    3208              :             } // ...end of HEATING/COOLING IF-THEN block
    3209              : 
    3210            0 :             CalcVentilatedSlabRadComps(state, Item, FirstHVACIteration);
    3211              : 
    3212              :         } // ...end of system ON/OFF IF-THEN block
    3213              : 
    3214              :         // Resimulate fans if AirMassFlow is zero and FanElecPower is > 0, indicating that load or condensation controls shut off the ventilated slab
    3215              :         // in CalcVentilatedSlabRadComps
    3216            0 :         AirMassFlow = state.dataLoopNodes->Node(OutletNode).MassFlowRate;
    3217            0 :         Real64 locFanElecPower = state.dataFans->fans(ventSlab.Fan_Index)->totalPower;
    3218              : 
    3219            0 :         if ((AirMassFlow <= 0.0) && (locFanElecPower > 0.0)) {
    3220            0 :             state.dataLoopNodes->Node(MixoutNode).MassFlowRate = 0.0;
    3221            0 :             state.dataLoopNodes->Node(MixoutNode).MassFlowRateMaxAvail = 0.0;
    3222            0 :             state.dataLoopNodes->Node(MixoutNode).MassFlowRateMinAvail = 0.0;
    3223            0 :             state.dataLoopNodes->Node(FanOutletNode).MassFlowRate = 0.0;
    3224            0 :             state.dataLoopNodes->Node(FanOutletNode).MassFlowRateMaxAvail = 0.0;
    3225            0 :             state.dataLoopNodes->Node(FanOutletNode).MassFlowRateMinAvail = 0.0;
    3226            0 :             state.dataFans->fans(ventSlab.Fan_Index)->simulate(state, FirstHVACIteration, _, _);
    3227              :         }
    3228              : 
    3229            0 :         CalcVentilatedSlabCoilOutput(state, Item, PowerMet, LatOutputProvided);
    3230            0 :     }
    3231              : 
    3232            0 :     void CalcVentilatedSlabComps(EnergyPlusData &state,
    3233              :                                  int const Item,                // system index in ventilated slab array
    3234              :                                  bool const FirstHVACIteration, // flag for 1st HVAV iteration in the time step
    3235              :                                  Real64 &LoadMet                // load met by the system (watts)
    3236              :     )
    3237              :     {
    3238              : 
    3239              :         // SUBROUTINE INFORMATION:
    3240              :         //       AUTHOR         Young Tae Chae, Rick Strand
    3241              :         //       DATE WRITTEN   June 2008
    3242              :         //       MODIFIED       July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
    3243              : 
    3244              :         // PURPOSE OF THIS SUBROUTINE:
    3245              :         // This subroutine launches the individual component simulations.
    3246              :         // This is called either when the system is off to carry null conditions
    3247              :         // through the system or during control iterations to continue updating
    3248              :         // what is going on within the unit.
    3249              : 
    3250              :         // METHODOLOGY EMPLOYED:
    3251              :         // Simply calls the different components in order.  Only slight wrinkles
    3252              :         // here are that the ventilated slab system has it's own outside air mixed and
    3253              :         // that a cooling coil must be present in order to call a cooling coil
    3254              :         // simulation.  Other than that, the subroutine is very straightforward.
    3255              : 
    3256              :         // Using/Aliasing
    3257            0 :         auto &ventSlab = state.dataVentilatedSlab->VentSlab(Item);
    3258              : 
    3259              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    3260              :         Real64 AirMassFlow; // total mass flow through the system
    3261              :         Real64 CpAirZn;     // specific heat of dry air at zone conditions (zone conditions same as system inlet)
    3262              :         int InletNode;      // system air inlet node
    3263              :         int OutletNode;     // system air outlet node
    3264              :         // unused0309  INTEGER        :: HCoilOutAirNode
    3265              :         Real64 QCoilReq; // Heat addition required from an electric/gas heating coil
    3266              :         Real64 HCoilOutAirTemp;
    3267              :         Real64 HCoilInAirTemp;
    3268              :         // unused1208  REAL(r64)           :: RadInTemp       ! Set temperature for "Slab In Node"
    3269              : 
    3270            0 :         SimVentSlabOAMixer(state, Item);
    3271            0 :         state.dataFans->fans(ventSlab.Fan_Index)->simulate(state, FirstHVACIteration, _, _);
    3272              : 
    3273            0 :         if ((ventSlab.coolingCoilPresent) && (ventSlab.coolingCoilSchedValue >= 0.0)) {
    3274            0 :             if (ventSlab.cCoilType == CoolingCoilType::HXAssisted) {
    3275            0 :                 HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
    3276              :                                                                     ventSlab.coolingCoilName,
    3277              :                                                                     FirstHVACIteration,
    3278              :                                                                     HVAC::CompressorOp::On,
    3279              :                                                                     0.0,
    3280            0 :                                                                     ventSlab.coolingCoil_Index,
    3281              :                                                                     HVAC::FanOp::Continuous);
    3282              :             } else {
    3283            0 :                 WaterCoils::SimulateWaterCoilComponents(state, ventSlab.coolingCoilName, FirstHVACIteration, ventSlab.coolingCoil_Index);
    3284              :             }
    3285              :         }
    3286              : 
    3287            0 :         if ((ventSlab.heatingCoilPresent) && (ventSlab.heatingCoilSchedValue >= 0.0)) {
    3288              : 
    3289            0 :             switch (ventSlab.hCoilType) {
    3290              : 
    3291            0 :             case HeatingCoilType::Water: {
    3292              : 
    3293            0 :                 WaterCoils::SimulateWaterCoilComponents(state, ventSlab.heatingCoilName, FirstHVACIteration, ventSlab.heatingCoil_Index);
    3294            0 :                 break;
    3295              :             }
    3296            0 :             case HeatingCoilType::Steam: {
    3297              : 
    3298            0 :                 if (!state.dataVentilatedSlab->HCoilOn) {
    3299            0 :                     QCoilReq = 0.0;
    3300              :                 } else {
    3301            0 :                     int HCoilInAirNode = ventSlab.FanOutletNode;
    3302            0 :                     CpAirZn = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(HCoilInAirNode).HumRat);
    3303            0 :                     QCoilReq =
    3304            0 :                         state.dataLoopNodes->Node(HCoilInAirNode).MassFlowRate * CpAirZn * (state.dataLoopNodes->Node(ventSlab.RadInNode).Temp) -
    3305            0 :                         (state.dataLoopNodes->Node(HCoilInAirNode).Temp);
    3306              :                 }
    3307              : 
    3308            0 :                 if (QCoilReq < 0.0) {
    3309            0 :                     QCoilReq = 0.0; // a heating coil can only heat, not cool
    3310              :                 }
    3311              : 
    3312            0 :                 SteamCoils::SimulateSteamCoilComponents(state, ventSlab.heatingCoilName, FirstHVACIteration, ventSlab.heatingCoil_Index, QCoilReq);
    3313            0 :                 break;
    3314              :             }
    3315            0 :             case HeatingCoilType::Electric:
    3316              :             case HeatingCoilType::Gas: {
    3317              : 
    3318            0 :                 if (!state.dataVentilatedSlab->HCoilOn) {
    3319            0 :                     QCoilReq = 0.0;
    3320              :                 } else {
    3321            0 :                     HCoilInAirTemp = state.dataLoopNodes->Node(ventSlab.FanOutletNode).Temp;
    3322            0 :                     HCoilOutAirTemp = state.dataLoopNodes->Node(ventSlab.RadInNode).Temp;
    3323            0 :                     CpAirZn = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(ventSlab.RadInNode).HumRat);
    3324            0 :                     QCoilReq = state.dataLoopNodes->Node(ventSlab.FanOutletNode).MassFlowRate * CpAirZn * (HCoilOutAirTemp - HCoilInAirTemp);
    3325              :                 }
    3326              : 
    3327            0 :                 if (QCoilReq < 0.0) {
    3328            0 :                     QCoilReq = 0.0; // a heating coil can only heat, not cool
    3329              :                 }
    3330              : 
    3331            0 :                 HeatingCoils::SimulateHeatingCoilComponents(
    3332            0 :                     state, ventSlab.heatingCoilName, FirstHVACIteration, QCoilReq, ventSlab.heatingCoil_Index);
    3333            0 :                 break;
    3334              :             }
    3335            0 :             default:
    3336            0 :                 break;
    3337              :             }
    3338              :         }
    3339              : 
    3340            0 :         InletNode = ventSlab.FanOutletNode;
    3341            0 :         OutletNode = ventSlab.RadInNode;
    3342            0 :         AirMassFlow = state.dataLoopNodes->Node(OutletNode).MassFlowRate;
    3343              : 
    3344            0 :         LoadMet = AirMassFlow * (Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(OutletNode).Temp, state.dataLoopNodes->Node(InletNode).HumRat) -
    3345            0 :                                  Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(InletNode).Temp, state.dataLoopNodes->Node(InletNode).HumRat));
    3346            0 :     }
    3347              : 
    3348            3 :     void CalcVentilatedSlabCoilOutput(EnergyPlusData &state,
    3349              :                                       int const Item,           // system index in ventilated slab array
    3350              :                                       Real64 &PowerMet,         // power supplied (W)
    3351              :                                       Real64 &LatOutputProvided // latent capacity supplied (kg/s)
    3352              :     )
    3353              :     {
    3354              : 
    3355              :         // SUBROUTINE INFORMATION:
    3356              :         //       AUTHOR         Young Tae Chae, Rick Strand
    3357              :         //       DATE WRITTEN   June 2008
    3358              :         //       MODIFIED       July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
    3359              :         //       RE-ENGINEERED  July 2015, M.J. Witte, Refactored coil output calcs in to this new routine
    3360              : 
    3361              :         // PURPOSE OF THIS SUBROUTINE:
    3362              :         // This subroutine calculates the output from the coils
    3363              : 
    3364              :         // METHODOLOGY EMPLOYED:
    3365              :         // Calculates the sensible and total enthalpy change from the fan outlet node to the slab inlet node.
    3366              : 
    3367              :         // USING/ALIASING:
    3368            3 :         auto &ventSlab = state.dataVentilatedSlab->VentSlab(Item);
    3369              : 
    3370              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    3371              :         Real64 AirMassFlow; // total mass flow through the system
    3372              :         int FanOutletNode;  // system fan outlet node
    3373              :         int OutletNode;     // air outlet node
    3374              :         Real64 SpecHumOut;  // Specific humidity ratio of outlet air (kg moisture / kg moist air)
    3375              :         Real64 SpecHumIn;   // Specific humidity ratio of inlet air (kg moisture / kg moist air)
    3376              :         Real64 QTotUnitOut; // total unit output [watts]
    3377              :         Real64 QUnitOut;    // heating or sens. cooling provided by fan coil unit [watts]
    3378              : 
    3379            3 :         OutletNode = ventSlab.RadInNode;
    3380            3 :         FanOutletNode = ventSlab.FanOutletNode;
    3381            3 :         AirMassFlow = state.dataLoopNodes->Node(OutletNode).MassFlowRate;
    3382              : 
    3383              :         //        QTotUnitOut = AirMassFlow * ( Node( OutletNode ).Enthalpy - Node( FanOutletNode ).Enthalpy );
    3384            3 :         QTotUnitOut = AirMassFlow *
    3385            3 :                       (Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(OutletNode).Temp, state.dataLoopNodes->Node(OutletNode).HumRat) -
    3386            3 :                        Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(FanOutletNode).Temp, state.dataLoopNodes->Node(FanOutletNode).HumRat));
    3387            3 :         QUnitOut = AirMassFlow *
    3388            3 :                    (Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(OutletNode).Temp, state.dataLoopNodes->Node(FanOutletNode).HumRat) -
    3389            3 :                     Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(FanOutletNode).Temp, state.dataLoopNodes->Node(FanOutletNode).HumRat));
    3390              :         // Limit sensible <= total when cooling (which is negative, so use max)
    3391            3 :         QUnitOut = max(QUnitOut, QTotUnitOut);
    3392              : 
    3393              :         // Report variables...
    3394            3 :         ventSlab.HeatCoilPower = max(0.0, QUnitOut);
    3395            3 :         ventSlab.SensCoolCoilPower = std::abs(min(0.0, QUnitOut));
    3396            3 :         ventSlab.TotCoolCoilPower = std::abs(min(0.0, QTotUnitOut));
    3397            3 :         ventSlab.LateCoolCoilPower = ventSlab.TotCoolCoilPower - ventSlab.SensCoolCoilPower;
    3398            3 :         ventSlab.ElecFanPower = (ventSlab.Fan_Index == 0) ? 0.0 : state.dataFans->fans(ventSlab.Fan_Index)->totalPower;
    3399              : 
    3400            3 :         ventSlab.AirMassFlowRate = AirMassFlow;
    3401              : 
    3402            3 :         SpecHumOut = state.dataLoopNodes->Node(OutletNode).HumRat;
    3403            3 :         SpecHumIn = state.dataLoopNodes->Node(FanOutletNode).HumRat;
    3404            3 :         LatOutputProvided = AirMassFlow * (SpecHumOut - SpecHumIn); // Latent rate (kg/s), dehumid = negative
    3405            3 :         PowerMet = QUnitOut;
    3406            3 :     }
    3407              : 
    3408            0 :     void CalcVentilatedSlabRadComps(EnergyPlusData &state,
    3409              :                                     int const Item,                                // System index in ventilated slab array
    3410              :                                     [[maybe_unused]] bool const FirstHVACIteration // flag for 1st HVAV iteration in the time step !unused1208
    3411              :     )
    3412              :     {
    3413              : 
    3414              :         // SUBROUTINE INFORMATION:
    3415              :         //       AUTHOR         Young Tae Chae, Rick Strand
    3416              :         //       DATE WRITTEN   June 2008
    3417              :         //       MODIFIED       Sep 2011 LKL/BG - resimulate only zones needing it for Radiant systems
    3418              : 
    3419              :         // PURPOSE OF THIS SUBROUTINE:
    3420              :         // This subroutine launches the individual component simulations.
    3421              :         // This is called either when the system is off to carry null conditions
    3422              :         // through the system or during control iterations to continue updating
    3423              :         // what is going on within the system.
    3424              : 
    3425              :         // METHODOLOGY EMPLOYED:
    3426              :         // Simply calls the different components in order.  Only slight wrinkles
    3427              :         // here are that the Ventilated Slab has it's own outside air mixed and
    3428              :         // that a cooling coil must be present in order to call a cooling coil
    3429              :         // simulation.  Other than that, the subroutine is very straightforward.
    3430              : 
    3431              :         // Using/Aliasing
    3432            0 :         auto &ventSlab = state.dataVentilatedSlab->VentSlab(Item);
    3433              : 
    3434              :         // SUBROUTINE PARAMETER DEFINITIONS:
    3435            0 :         Real64 constexpr CondDeltaTemp(0.001); // How close the surface temperatures can get to the dewpoint temperature
    3436              :         // of a space before the radiant cooling system shuts off the flow.
    3437            0 :         Real64 constexpr ZeroSystemResp(0.1); // Response below which the system response is really zero
    3438            0 :         Real64 constexpr TempCheckLimit(0.1); // Maximum allowed temperature difference between outlet temperature calculations
    3439            0 :         static std::string const CurrentModuleObject("ZoneHVAC:VentilatedSlab");
    3440              : 
    3441              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    3442              :         Real64 CpAirZn;        // Intermediate calculational variable for specific heat of air
    3443              :         Real64 DewPointTemp;   // Dew-point temperature based on the zone air conditions
    3444              :         Real64 EpsMdotCpAirZn; // Epsilon (heat exchanger terminology) times water mass flow rate times water specific heat
    3445              :         Real64 Mdot;           // Intermediate calculation variable for mass flow rate in a surface within the radiant system
    3446              :         int RadSurfNum;        // DO loop counter for the surfaces that comprise a particular radiant system
    3447              :         // unused0309  INTEGER  :: RadSurfNum4    ! DO loop counter for the surfaces that comprise a particular radiant system
    3448              : 
    3449              :         int SurfNum; // Index for radiant surface in Surface derived type
    3450              :         // unused0309  INTEGER  :: RadSurfNumNum
    3451              :         Real64 TotalVentSlabRadPower; // Total heat source/sink to radiant system
    3452              :         Real64 AirOutletTempCheck;    // Radiant system air outlet temperature (calculated from mixing all outlet streams together)
    3453              :         Real64 AirTempIn;             // Temperature of the air entering the radiant system, in C
    3454              :         Real64 Ca;                    // Coefficients to relate the inlet air temperature to the heat source
    3455              :         Real64 Cb;
    3456              :         Real64 Cc;
    3457              :         Real64 Cd;
    3458              :         Real64 Ce;
    3459              :         Real64 Cf;
    3460              :         Real64 Cg;
    3461              :         Real64 Ch;
    3462              :         Real64 Ci;
    3463              :         Real64 Cj;
    3464              :         Real64 Ck;
    3465              :         Real64 Cl;
    3466              :         // For more info on Ca through Cl, refer Constant Flow Radiant System
    3467              :         // For Phase 3
    3468              :         Real64 CNumDS;
    3469              :         Real64 CLengDS;
    3470              :         Real64 CDiaDS;
    3471              :         Real64 FlowFrac;
    3472              :         Real64 MSlabAirInTemp;
    3473              : 
    3474            0 :         if (state.dataVentilatedSlab->FirstTimeFlag) {
    3475            0 :             state.dataVentilatedSlab->AirTempOut.allocate(state.dataVentilatedSlab->MaxCloNumOfSurfaces);
    3476            0 :             state.dataVentilatedSlab->FirstTimeFlag = false;
    3477              :         }
    3478              : 
    3479            0 :         int SlabInNode = ventSlab.RadInNode;
    3480            0 :         int FanOutletNode = ventSlab.FanOutletNode;
    3481            0 :         int OAInletNode = ventSlab.OutsideAirNode;
    3482            0 :         int MixoutNode = ventSlab.OAMixerOutNode;
    3483            0 :         int ReturnAirNode = ventSlab.ReturnAirNode;
    3484            0 :         int ZoneAirInNode = ventSlab.ZoneAirInNode;
    3485              : 
    3486              :         // Set the conditions on the air side inlet
    3487            0 :         int ZoneNum = ventSlab.ZonePtr;
    3488            0 :         Real64 ZoneMult = double(state.dataHeatBal->Zone(ZoneNum).Multiplier * state.dataHeatBal->Zone(ZoneNum).ListMultiplier);
    3489            0 :         Real64 AirMassFlow = state.dataLoopNodes->Node(ventSlab.RadInNode).MassFlowRate / ZoneMult;
    3490            0 :         auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
    3491              : 
    3492            0 :         if (state.dataVentilatedSlab->OperatingMode == HeatingMode) {
    3493              : 
    3494            0 :             if ((!ventSlab.heatingCoilPresent) || (ventSlab.heatingCoilSchedValue <= 0.0)) {
    3495              : 
    3496            0 :                 AirTempIn = state.dataLoopNodes->Node(FanOutletNode).Temp;
    3497            0 :                 state.dataLoopNodes->Node(SlabInNode).Temp =
    3498            0 :                     state.dataLoopNodes->Node(FanOutletNode).Temp; // If coil not available or running, then coil in and out temps same
    3499              : 
    3500              :             } else {
    3501              : 
    3502            0 :                 AirTempIn = state.dataLoopNodes->Node(SlabInNode).Temp;
    3503              :             }
    3504              :         }
    3505              : 
    3506            0 :         if (state.dataVentilatedSlab->OperatingMode == CoolingMode) {
    3507              : 
    3508            0 :             if ((!ventSlab.coolingCoilPresent) || (ventSlab.coolingCoilSchedValue <= 0.0)) {
    3509              : 
    3510            0 :                 AirTempIn = state.dataLoopNodes->Node(FanOutletNode).Temp;
    3511            0 :                 state.dataLoopNodes->Node(SlabInNode).Temp =
    3512            0 :                     state.dataLoopNodes->Node(FanOutletNode).Temp; // If coil not available or running, then coil in and out temps same
    3513              : 
    3514              :             } else {
    3515              : 
    3516            0 :                 AirTempIn = state.dataLoopNodes->Node(SlabInNode).Temp;
    3517              :             }
    3518              :         }
    3519              : 
    3520            0 :         if (AirMassFlow <= 0.0) {
    3521              :             // No flow or below minimum allowed so there is no heat source/sink
    3522              :             // This is possible with a mismatch between system and plant operation
    3523              :             // or a slight mismatch between zone and system controls.  This is not
    3524              :             // necessarily a "problem" so this exception is necessary in the code.
    3525              : 
    3526            0 :             for (RadSurfNum = 1; RadSurfNum <= ventSlab.NumOfSurfaces; ++RadSurfNum) {
    3527            0 :                 SurfNum = ventSlab.SurfacePtr(RadSurfNum);
    3528            0 :                 state.dataHeatBalFanSys->QRadSysSource(SurfNum) = 0.0;
    3529            0 :                 if (state.dataSurface->Surface(SurfNum).ExtBoundCond > 0 && state.dataSurface->Surface(SurfNum).ExtBoundCond != SurfNum) {
    3530            0 :                     state.dataHeatBalFanSys->QRadSysSource(state.dataSurface->Surface(SurfNum).ExtBoundCond) =
    3531              :                         0.0; // Also zero the other side of an interzone
    3532              :                 }
    3533              :             }
    3534              : 
    3535            0 :             ventSlab.SlabOutTemp = ventSlab.SlabInTemp;
    3536              : 
    3537              :             // zero out node flows
    3538            0 :             state.dataLoopNodes->Node(SlabInNode).MassFlowRate = 0.0;
    3539            0 :             state.dataLoopNodes->Node(FanOutletNode).MassFlowRate = 0.0;
    3540            0 :             state.dataLoopNodes->Node(OAInletNode).MassFlowRate = 0.0;
    3541            0 :             state.dataLoopNodes->Node(MixoutNode).MassFlowRate = 0.0;
    3542            0 :             state.dataLoopNodes->Node(ReturnAirNode).MassFlowRate = 0.0;
    3543            0 :             state.dataLoopNodes->Node(FanOutletNode).Temp = state.dataLoopNodes->Node(SlabInNode).Temp;
    3544            0 :             AirMassFlow = 0.0;
    3545              :         }
    3546              : 
    3547            0 :         if (AirMassFlow > 0.0) {
    3548              : 
    3549            0 :             if ((ventSlab.SysConfg == VentilatedSlabConfig::SlabOnly) || (ventSlab.SysConfg == VentilatedSlabConfig::SlabAndZone)) {
    3550              : 
    3551            0 :                 for (RadSurfNum = 1; RadSurfNum <= ventSlab.NumOfSurfaces; ++RadSurfNum) {
    3552            0 :                     SurfNum = ventSlab.SurfacePtr(RadSurfNum);
    3553              :                     // Determine the heat exchanger "effectiveness" term
    3554            0 :                     EpsMdotCpAirZn = CalcVentSlabHXEffectTerm(state,
    3555              :                                                               Item,
    3556              :                                                               AirTempIn,
    3557              :                                                               AirMassFlow,
    3558            0 :                                                               ventSlab.SurfaceFlowFrac(RadSurfNum),
    3559              :                                                               ventSlab.CoreLength,
    3560              :                                                               ventSlab.CoreDiameter,
    3561              :                                                               ventSlab.CoreNumbers);
    3562              : 
    3563              :                     // Obtain the heat balance coefficients and calculate the intermediate coefficients
    3564              :                     // linking the inlet air temperature to the heat source/sink to the radiant system.
    3565              :                     // The coefficients are based on the Constant Flow Radiation System.
    3566              : 
    3567            0 :                     int ConstrNum = state.dataSurface->Surface(SurfNum).Construction;
    3568            0 :                     auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    3569              : 
    3570            0 :                     Ca = state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum);
    3571            0 :                     Cb = state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum);
    3572            0 :                     Cc = state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum);
    3573              : 
    3574            0 :                     Cd = state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum);
    3575            0 :                     Ce = state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum);
    3576            0 :                     Cf = state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum);
    3577              : 
    3578            0 :                     Cg = state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum);
    3579            0 :                     Ch = double(thisConstruct.CTFTSourceQ[0]);
    3580            0 :                     Ci = double(thisConstruct.CTFTSourceIn[0]);
    3581            0 :                     Cj = double(thisConstruct.CTFTSourceOut[0]);
    3582              : 
    3583            0 :                     Ck = Cg + ((Ci * (Ca + Cb * Cd) + Cj * (Cd + Ce * Ca)) / (1.0 - Ce * Cb));
    3584            0 :                     Cl = Ch + ((Ci * (Cc + Cb * Cf) + Cj * (Cf + Ce * Cc)) / (1.0 - Ce * Cb));
    3585              : 
    3586            0 :                     Mdot = AirMassFlow * ventSlab.SurfaceFlowFrac(RadSurfNum);
    3587            0 :                     CpAirZn = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(ventSlab.RadInNode).HumRat);
    3588              : 
    3589            0 :                     state.dataHeatBalFanSys->QRadSysSource(SurfNum) = ventSlab.CoreNumbers * EpsMdotCpAirZn * (AirTempIn - Ck) /
    3590            0 :                                                                       (1.0 + (EpsMdotCpAirZn * Cl / state.dataSurface->Surface(SurfNum).Area));
    3591              : 
    3592            0 :                     if (state.dataSurface->Surface(SurfNum).ExtBoundCond > 0 && state.dataSurface->Surface(SurfNum).ExtBoundCond != SurfNum) {
    3593            0 :                         state.dataHeatBalFanSys->QRadSysSource(state.dataSurface->Surface(SurfNum).ExtBoundCond) =
    3594            0 :                             state.dataHeatBalFanSys->QRadSysSource(SurfNum);
    3595              :                     }
    3596              :                     // Also set the other side of an interzone!
    3597            0 :                     state.dataVentilatedSlab->AirTempOut(RadSurfNum) =
    3598            0 :                         AirTempIn - (state.dataHeatBalFanSys->QRadSysSource(SurfNum) / (Mdot * CpAirZn));
    3599              : 
    3600              :                     // "Temperature Comparison" Cut-off:
    3601              :                     // Check to see whether or not the system should really be running.  If
    3602              :                     // QRadSysSource is negative when we are in heating mode or QRadSysSource
    3603              :                     // is positive when we are in cooling mode, then the radiant system will
    3604              :                     // be doing the opposite of its intention.  In this case, the flow rate
    3605              :                     // is set to zero to avoid heating in cooling mode or cooling in heating
    3606              :                     // mode.
    3607              : 
    3608            0 :                     if (((state.dataVentilatedSlab->OperatingMode == HeatingMode) && (state.dataHeatBalFanSys->QRadSysSource(SurfNum) <= 0.0)) ||
    3609            0 :                         ((state.dataVentilatedSlab->OperatingMode == CoolingMode) && (state.dataHeatBalFanSys->QRadSysSource(SurfNum) >= 0.0))) {
    3610              : 
    3611              :                         // IF (.not. WarmupFlag) THEN
    3612              :                         //   TempComparisonErrorCount = TempComparisonErrorCount + 1
    3613              :                         //   IF (TempComparisonErrorCount <= NumOfVentSlabs) THEN
    3614              :                         //     CALL ShowWarningError(state, 'Radaint Heat exchange is negative in Heating Mode or posive in Cooling Mode')
    3615              :                         //     CALL ShowContinueError(state, 'Flow to the following ventilated slab will be shut-off to avoid heating in cooling mode
    3616              :                         //     or cooling &
    3617              :                         //                             in heating mode')
    3618              :                         //     CALL ShowContinueError(state, 'Ventilated Slab Name = '//TRIM(VentSlab(Item)%Name))
    3619              :                         //     CALL ShowContinueError(state, 'All node temperature are reseted at the ventilated slab surface temperature = '// &
    3620              :                         //                            RoundSigDigits(TH(VentSlab(Item)%SurfacePtr(RadSurfNum),1,2),2))
    3621              :                         //     CALL ShowContinueErrorTimeStamp(state, ' ')
    3622              :                         //   ELSE
    3623              :                         //     CALL ShowRecurringWarningErrorAtEnd(state, 'Ventilated Slab ['//TRIM(VentSlab(Item)%Name)//  &
    3624              :                         //                  '] Temperature Comparison Error shut-off occurrence continues.',  &
    3625              :                         //                  VentSlab(Item)%CondErrCount)
    3626              :                         //   END IF
    3627              :                         // END IF
    3628              : 
    3629            0 :                         state.dataLoopNodes->Node(SlabInNode).MassFlowRate = 0.0;
    3630            0 :                         state.dataLoopNodes->Node(FanOutletNode).MassFlowRate = 0.0;
    3631            0 :                         state.dataLoopNodes->Node(OAInletNode).MassFlowRate = 0.0;
    3632            0 :                         state.dataLoopNodes->Node(MixoutNode).MassFlowRate = 0.0;
    3633            0 :                         state.dataLoopNodes->Node(ReturnAirNode).MassFlowRate = 0.0;
    3634            0 :                         AirMassFlow = 0.0;
    3635              : 
    3636            0 :                         for (int RadSurfNum2 = 1; RadSurfNum2 <= ventSlab.NumOfSurfaces; ++RadSurfNum2) {
    3637            0 :                             int SurfNum2 = ventSlab.SurfacePtr(RadSurfNum2);
    3638            0 :                             state.dataHeatBalFanSys->QRadSysSource(SurfNum2) = 0.0;
    3639            0 :                             if (state.dataSurface->Surface(SurfNum2).ExtBoundCond > 0 &&
    3640            0 :                                 state.dataSurface->Surface(SurfNum2).ExtBoundCond != SurfNum2) {
    3641            0 :                                 state.dataHeatBalFanSys->QRadSysSource(state.dataSurface->Surface(SurfNum2).ExtBoundCond) =
    3642              :                                     0.0; // Also zero the other side of an interzone
    3643              :                             }
    3644              : 
    3645            0 :                             if (ventSlab.SysConfg == VentilatedSlabConfig::SlabOnly) {
    3646              :                                 //            state.dataLoopNodes->Node(Returnairnode)%Temp = MAT(Zonenum)
    3647            0 :                                 state.dataLoopNodes->Node(ReturnAirNode).Temp =
    3648            0 :                                     state.dataHeatBalSurf->SurfInsideTempHist(1)(ventSlab.SurfacePtr(RadSurfNum));
    3649            0 :                                 state.dataLoopNodes->Node(FanOutletNode).Temp = state.dataLoopNodes->Node(ReturnAirNode).Temp;
    3650            0 :                                 state.dataLoopNodes->Node(SlabInNode).Temp = state.dataLoopNodes->Node(FanOutletNode).Temp;
    3651            0 :                             } else if (ventSlab.SysConfg == VentilatedSlabConfig::SlabAndZone) {
    3652            0 :                                 state.dataLoopNodes->Node(ReturnAirNode).Temp = thisZoneHB.MAT;
    3653            0 :                                 state.dataLoopNodes->Node(SlabInNode).Temp = state.dataLoopNodes->Node(ReturnAirNode).Temp;
    3654            0 :                                 state.dataLoopNodes->Node(FanOutletNode).Temp = state.dataLoopNodes->Node(SlabInNode).Temp;
    3655            0 :                                 state.dataLoopNodes->Node(ZoneAirInNode).Temp = state.dataLoopNodes->Node(SlabInNode).Temp;
    3656              :                             }
    3657              :                         }
    3658            0 :                         break; // outer do loop
    3659              :                     }
    3660              : 
    3661              :                     // Condensation Cut-off:
    3662              :                     // Check to see whether there are any surface temperatures within the radiant system that have
    3663              :                     // dropped below the dew-point temperature.  If so, we need to shut off this radiant system.
    3664              :                     // A safety parameter is added (hardwired parameter) to avoid getting too close to condensation
    3665              :                     // conditions.
    3666              : 
    3667            0 :                     if (state.dataVentilatedSlab->OperatingMode == CoolingMode) {
    3668            0 :                         DewPointTemp = Psychrometrics::PsyTdpFnWPb(state, thisZoneHB.airHumRat, state.dataEnvrn->OutBaroPress);
    3669            0 :                         for (int RadSurfNum2 = 1; RadSurfNum2 <= ventSlab.NumOfSurfaces; ++RadSurfNum2) {
    3670            0 :                             if (state.dataHeatBalSurf->SurfInsideTempHist(1)(ventSlab.SurfacePtr(RadSurfNum2)) < (DewPointTemp + CondDeltaTemp)) {
    3671              :                                 // Condensation warning--must shut off radiant system
    3672            0 :                                 state.dataLoopNodes->Node(SlabInNode).MassFlowRate = 0.0;
    3673            0 :                                 state.dataLoopNodes->Node(FanOutletNode).MassFlowRate = 0.0;
    3674            0 :                                 state.dataLoopNodes->Node(OAInletNode).MassFlowRate = 0.0;
    3675            0 :                                 state.dataLoopNodes->Node(MixoutNode).MassFlowRate = 0.0;
    3676            0 :                                 state.dataLoopNodes->Node(ReturnAirNode).MassFlowRate = 0.0;
    3677            0 :                                 state.dataLoopNodes->Node(FanOutletNode).Temp = state.dataLoopNodes->Node(SlabInNode).Temp;
    3678            0 :                                 AirMassFlow = 0.0;
    3679            0 :                                 for (int RadSurfNum3 = 1; RadSurfNum3 <= ventSlab.NumOfSurfaces; ++RadSurfNum3) {
    3680            0 :                                     int SurfNum2 = ventSlab.SurfacePtr(RadSurfNum3);
    3681            0 :                                     state.dataHeatBalFanSys->QRadSysSource(SurfNum2) = 0.0;
    3682            0 :                                     if (state.dataSurface->Surface(SurfNum2).ExtBoundCond > 0 &&
    3683            0 :                                         state.dataSurface->Surface(SurfNum2).ExtBoundCond != SurfNum2) {
    3684            0 :                                         state.dataHeatBalFanSys->QRadSysSource(state.dataSurface->Surface(SurfNum2).ExtBoundCond) =
    3685              :                                             0.0; // Also zero the other side of an interzone
    3686              :                                     }
    3687              :                                 }
    3688              :                                 // Produce a warning message so that user knows the system was shut-off due to potential for condensation
    3689            0 :                                 if (!state.dataGlobal->WarmupFlag) {
    3690            0 :                                     ++state.dataVentilatedSlab->CondensationErrorCount;
    3691              : 
    3692            0 :                                     if (ventSlab.CondErrIndex == 0) {
    3693            0 :                                         ShowWarningMessage(state, format("{} [{}]", cMO_VentilatedSlab, ventSlab.Name));
    3694            0 :                                         ShowContinueError(
    3695              :                                             state,
    3696            0 :                                             format("Surface [{}] temperature below dew-point temperature--potential for condensation exists",
    3697            0 :                                                    state.dataSurface->Surface(ventSlab.SurfacePtr(RadSurfNum2)).Name));
    3698            0 :                                         ShowContinueError(state, "Flow to the ventilated slab system will be shut-off to avoid condensation");
    3699            0 :                                         ShowContinueError(state,
    3700            0 :                                                           format("Predicted radiant system surface temperature = {:.2R}",
    3701            0 :                                                                  state.dataHeatBalSurf->SurfInsideTempHist(1)(ventSlab.SurfacePtr(RadSurfNum2))));
    3702            0 :                                         ShowContinueError(
    3703            0 :                                             state, format("Zone dew-point temperature + safety factor delta= {:.2R}", DewPointTemp + CondDeltaTemp));
    3704            0 :                                         ShowContinueErrorTimeStamp(state, "");
    3705              :                                     }
    3706            0 :                                     if (state.dataVentilatedSlab->CondensationErrorCount == 1) {
    3707            0 :                                         ShowContinueError(
    3708            0 :                                             state, format("Note that there is a {:.4R} C safety built-in to the shut-off criteria", CondDeltaTemp));
    3709            0 :                                         ShowContinueError(state, "Note also that this affects all surfaces that are part of this system");
    3710              :                                     }
    3711            0 :                                     ShowRecurringWarningErrorAtEnd(state,
    3712            0 :                                                                    cMO_VentilatedSlab + " [" + ventSlab.Name +
    3713              :                                                                        "] condensation shut-off occurrence continues.",
    3714            0 :                                                                    ventSlab.CondErrIndex,
    3715              :                                                                    DewPointTemp,
    3716              :                                                                    DewPointTemp,
    3717              :                                                                    _,
    3718              :                                                                    "C",
    3719              :                                                                    "C");
    3720              :                                 }
    3721            0 :                                 break; // outer do loop
    3722              :                             }
    3723              :                         }
    3724              :                     }
    3725              :                 }
    3726              : 
    3727              :                 // Total Radiant Power
    3728            0 :                 AirOutletTempCheck = 0.0;
    3729            0 :                 TotalVentSlabRadPower = 0.0;
    3730            0 :                 for (RadSurfNum = 1; RadSurfNum <= ventSlab.NumOfSurfaces; ++RadSurfNum) {
    3731            0 :                     SurfNum = ventSlab.SurfacePtr(RadSurfNum);
    3732            0 :                     TotalVentSlabRadPower += state.dataHeatBalFanSys->QRadSysSource(SurfNum);
    3733            0 :                     AirOutletTempCheck += (ventSlab.SurfaceFlowFrac(RadSurfNum) * state.dataVentilatedSlab->AirTempOut(RadSurfNum));
    3734              :                 }
    3735            0 :                 TotalVentSlabRadPower *= ZoneMult;
    3736              : 
    3737              :                 // Return Air temp Check
    3738            0 :                 if (ventSlab.SysConfg == VentilatedSlabConfig::SlabOnly) {
    3739            0 :                     if (AirMassFlow > 0.0) {
    3740            0 :                         CpAirZn = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(ventSlab.RadInNode).HumRat);
    3741            0 :                         state.dataLoopNodes->Node(ReturnAirNode).Temp =
    3742            0 :                             state.dataLoopNodes->Node(SlabInNode).Temp - (TotalVentSlabRadPower / (AirMassFlow * CpAirZn));
    3743            0 :                         if ((std::abs(state.dataLoopNodes->Node(ReturnAirNode).Temp - AirOutletTempCheck) > TempCheckLimit) &&
    3744            0 :                             (std::abs(TotalVentSlabRadPower) > ZeroSystemResp)) {
    3745              : 
    3746            0 :                             if (!state.dataGlobal->WarmupFlag) {
    3747            0 :                                 ++state.dataVentilatedSlab->EnergyImbalanceErrorCount;
    3748            0 :                                 if (ventSlab.EnrgyImbalErrIndex == 0) {
    3749            0 :                                     ShowWarningMessage(state, format("{} [{}]", cMO_VentilatedSlab, ventSlab.Name));
    3750            0 :                                     ShowContinueError(state, "Ventilated Slab (slab only type) air outlet temperature calculation mismatch.");
    3751            0 :                                     ShowContinueError(state,
    3752              :                                                       "This should not happen as it indicates a potential energy imbalance in the calculations.");
    3753            0 :                                     ShowContinueError(state, "However, it could also result from improper input for the ventilated slab or");
    3754            0 :                                     ShowContinueError(state, "illogical control temperatures.  Check your input for this ventilated slab and");
    3755            0 :                                     ShowContinueError(state, "also look at the internal data shown below.");
    3756            0 :                                     ShowContinueError(state,
    3757            0 :                                                       format("Predicted return air temperature [C] from the overall energy balance = {:.4R}",
    3758            0 :                                                              state.dataLoopNodes->Node(ReturnAirNode).Temp));
    3759            0 :                                     ShowContinueError(state,
    3760            0 :                                                       format("Predicted return air temperature [C] from the slab section energy balances = {:.4R}",
    3761              :                                                              AirOutletTempCheck));
    3762            0 :                                     ShowContinueError(state,
    3763            0 :                                                       format("Total energy rate (power) [W] added to the slab = {:.4R}", TotalVentSlabRadPower));
    3764            0 :                                     ShowContinueErrorTimeStamp(state, "");
    3765              :                                 }
    3766            0 :                                 ShowRecurringWarningErrorAtEnd(state,
    3767            0 :                                                                cMO_VentilatedSlab + " [" + ventSlab.Name +
    3768              :                                                                    "] temperature calculation mismatch occurrence continues.",
    3769            0 :                                                                ventSlab.EnrgyImbalErrIndex);
    3770              :                             }
    3771              :                         }
    3772              :                     } else {
    3773            0 :                         state.dataLoopNodes->Node(ReturnAirNode).Temp = state.dataLoopNodes->Node(SlabInNode).Temp;
    3774              :                     }
    3775              :                 }
    3776              : 
    3777            0 :                 if (ventSlab.SysConfg == VentilatedSlabConfig::SlabAndZone) {
    3778            0 :                     if (AirMassFlow > 0.0) {
    3779            0 :                         state.dataLoopNodes->Node(ZoneAirInNode).Temp =
    3780            0 :                             state.dataLoopNodes->Node(SlabInNode).Temp - (TotalVentSlabRadPower / (AirMassFlow * CpAirZn));
    3781            0 :                         if ((std::abs(state.dataLoopNodes->Node(ZoneAirInNode).Temp - AirOutletTempCheck) > TempCheckLimit) &&
    3782            0 :                             (std::abs(TotalVentSlabRadPower) > ZeroSystemResp)) {
    3783              : 
    3784            0 :                             if (!state.dataGlobal->WarmupFlag) {
    3785            0 :                                 ++state.dataVentilatedSlab->EnergyImbalanceErrorCount;
    3786            0 :                                 if (ventSlab.EnrgyImbalErrIndex == 0) {
    3787            0 :                                     ShowWarningMessage(state, format("{} [{}]", cMO_VentilatedSlab, ventSlab.Name));
    3788            0 :                                     ShowContinueError(state, "Ventilated Slab (slab only type) air outlet temperature calculation mismatch.");
    3789            0 :                                     ShowContinueError(state,
    3790              :                                                       "This should not happen as it indicates a potential energy imbalance in the calculations.");
    3791            0 :                                     ShowContinueError(state, "However, it could also result from improper input for the ventilated slab or");
    3792            0 :                                     ShowContinueError(state, "illogical control temperatures.  Check your input for this ventilated slab and");
    3793            0 :                                     ShowContinueError(state, "also look at the internal data shown below.");
    3794            0 :                                     ShowContinueError(state,
    3795            0 :                                                       format("Predicted return air temperature [C] from the overall energy balance = {:.4R}",
    3796            0 :                                                              state.dataLoopNodes->Node(ReturnAirNode).Temp));
    3797            0 :                                     ShowContinueError(state,
    3798            0 :                                                       format("Predicted return air temperature [C] from the slab section energy balances = {:.4R}",
    3799              :                                                              AirOutletTempCheck));
    3800            0 :                                     ShowContinueError(state,
    3801            0 :                                                       format("Total energy rate (power) [W] added to the slab = {:.4R}", TotalVentSlabRadPower));
    3802            0 :                                     ShowContinueErrorTimeStamp(state, "");
    3803              :                                 }
    3804            0 :                                 ShowRecurringWarningErrorAtEnd(state,
    3805            0 :                                                                cMO_VentilatedSlab + " [" + ventSlab.Name +
    3806              :                                                                    "] temperature calculation mismatch occurrence continues.",
    3807            0 :                                                                ventSlab.EnrgyImbalErrIndex);
    3808              :                             }
    3809              :                         }
    3810              :                         //       IF ((.NOT. FirstHVACIteration) .AND. &
    3811              :                         //          (ABS(Node(ReturnAirNode)%Temp-MAT(Zonenum)) > VentSlabAirTempToler))THEN
    3812              :                         //          NeedtoIterate = .TRUE.
    3813              :                         //      END IF
    3814              :                         //         state.dataLoopNodes->Node(ReturnAirNode)%Temp = MAT(Zonenum)
    3815              :                     } else {
    3816            0 :                         state.dataLoopNodes->Node(ZoneAirInNode).Temp = state.dataLoopNodes->Node(SlabInNode).Temp;
    3817            0 :                         state.dataLoopNodes->Node(ReturnAirNode).Temp = thisZoneHB.MAT;
    3818              :                     }
    3819              :                 }
    3820              : 
    3821              :                 // Now that we have the source/sink term, we must redo the heat balances to obtain
    3822              :                 // the new SumHATsurf value for the zone.  Note that the difference between the new
    3823              :                 // SumHATsurf and the value originally calculated by the heat balance with a zero
    3824              :                 // source for all radiant systems in the zone is the load met by the system (approximately).
    3825            0 :                 HeatBalanceSurfaceManager::CalcHeatBalanceOutsideSurf(state, ZoneNum);
    3826            0 :                 HeatBalanceSurfaceManager::CalcHeatBalanceInsideSurf(state, ZoneNum);
    3827              : 
    3828              :             } // SYSCONFIG. SLABONLY&SLABANDZONE
    3829              : 
    3830            0 :             if (ventSlab.SysConfg == VentilatedSlabConfig::SeriesSlabs) {
    3831              : 
    3832            0 :                 for (RadSurfNum = 1; RadSurfNum <= ventSlab.NumOfSurfaces; ++RadSurfNum) {
    3833              : 
    3834            0 :                     CNumDS = ventSlab.CNumbers(RadSurfNum);
    3835            0 :                     CLengDS = ventSlab.CLength(RadSurfNum);  // for check
    3836            0 :                     CDiaDS = ventSlab.CDiameter(RadSurfNum); // for check
    3837            0 :                     FlowFrac = 1.0;
    3838              : 
    3839            0 :                     SurfNum = ventSlab.SurfacePtr(RadSurfNum);
    3840              : 
    3841              :                     // Determine the heat exchanger "effectiveness" term
    3842            0 :                     EpsMdotCpAirZn = CalcVentSlabHXEffectTerm(state, Item, AirTempIn, AirMassFlow, FlowFrac, CLengDS, CDiaDS, CNumDS);
    3843              : 
    3844              :                     // Obtain the heat balance coefficients and calculate the intermediate coefficients
    3845              :                     // linking the inlet air temperature to the heat source/sink to the radiant system.
    3846              :                     // The coefficients are based on the Constant Flow Radiation System.
    3847              : 
    3848            0 :                     int ConstrNum = state.dataSurface->Surface(SurfNum).Construction;
    3849              : 
    3850            0 :                     Ca = state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum);
    3851            0 :                     Cb = state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum);
    3852            0 :                     Cc = state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum);
    3853              : 
    3854            0 :                     Cd = state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum);
    3855            0 :                     Ce = state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum);
    3856            0 :                     Cf = state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum);
    3857              : 
    3858            0 :                     Cg = state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum);
    3859            0 :                     Ch = double(state.dataConstruction->Construct(ConstrNum).CTFTSourceQ[0]);
    3860            0 :                     Ci = double(state.dataConstruction->Construct(ConstrNum).CTFTSourceIn[0]);
    3861            0 :                     Cj = double(state.dataConstruction->Construct(ConstrNum).CTFTSourceOut[0]);
    3862              : 
    3863            0 :                     Ck = Cg + ((Ci * (Ca + Cb * Cd) + Cj * (Cd + Ce * Ca)) / (1.0 - Ce * Cb));
    3864            0 :                     Cl = Ch + ((Ci * (Cc + Cb * Cf) + Cj * (Cf + Ce * Cc)) / (1.0 - Ce * Cb));
    3865              : 
    3866            0 :                     Mdot = AirMassFlow * FlowFrac;
    3867            0 :                     CpAirZn = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(ventSlab.RadInNode).HumRat);
    3868              : 
    3869            0 :                     state.dataHeatBalFanSys->QRadSysSource(SurfNum) =
    3870            0 :                         CNumDS * EpsMdotCpAirZn * (AirTempIn - Ck) / (1.0 + (EpsMdotCpAirZn * Cl / state.dataSurface->Surface(SurfNum).Area));
    3871              : 
    3872            0 :                     if (state.dataSurface->Surface(SurfNum).ExtBoundCond > 0 && state.dataSurface->Surface(SurfNum).ExtBoundCond != SurfNum) {
    3873            0 :                         state.dataHeatBalFanSys->QRadSysSource(state.dataSurface->Surface(SurfNum).ExtBoundCond) =
    3874            0 :                             state.dataHeatBalFanSys->QRadSysSource(SurfNum);
    3875              :                     }
    3876              :                     // Also set the other side of an interzone!
    3877              : 
    3878            0 :                     state.dataVentilatedSlab->AirTempOut(RadSurfNum) =
    3879            0 :                         AirTempIn - (state.dataHeatBalFanSys->QRadSysSource(SurfNum) / (Mdot * CpAirZn));
    3880            0 :                     AirTempIn = state.dataVentilatedSlab->AirTempOut(RadSurfNum);
    3881              :                     // "Temperature Comparison" Cut-off:
    3882              :                     // Check to see whether or not the system should really be running.  If
    3883              :                     // QRadSysSource is negative when we are in heating mode or QRadSysSource
    3884              :                     // is positive when we are in cooling mode, then the radiant system will
    3885              :                     // be doing the opposite of its intention.  In this case, the flow rate
    3886              :                     // is set to zero to avoid heating in cooling mode or cooling in heating
    3887              :                     // mode.
    3888              : 
    3889            0 :                     if (RadSurfNum == 1) {
    3890            0 :                         if (((state.dataVentilatedSlab->OperatingMode == HeatingMode) && (state.dataHeatBalFanSys->QRadSysSource(SurfNum) <= 0.0)) ||
    3891            0 :                             ((state.dataVentilatedSlab->OperatingMode == CoolingMode) && (state.dataHeatBalFanSys->QRadSysSource(SurfNum) >= 0.0))) {
    3892            0 :                             state.dataLoopNodes->Node(SlabInNode).MassFlowRate = 0.0;
    3893            0 :                             state.dataLoopNodes->Node(FanOutletNode).MassFlowRate = 0.0;
    3894            0 :                             state.dataLoopNodes->Node(OAInletNode).MassFlowRate = 0.0;
    3895            0 :                             state.dataLoopNodes->Node(MixoutNode).MassFlowRate = 0.0;
    3896            0 :                             state.dataLoopNodes->Node(ReturnAirNode).MassFlowRate = 0.0;
    3897            0 :                             AirMassFlow = 0.0;
    3898              : 
    3899            0 :                             for (int RadSurfNum2 = 1; RadSurfNum2 <= ventSlab.NumOfSurfaces; ++RadSurfNum2) {
    3900            0 :                                 int SurfNum2 = ventSlab.SurfacePtr(RadSurfNum2);
    3901            0 :                                 state.dataHeatBalFanSys->QRadSysSource(SurfNum2) = 0.0;
    3902            0 :                                 if (state.dataSurface->Surface(SurfNum2).ExtBoundCond > 0 &&
    3903            0 :                                     state.dataSurface->Surface(SurfNum2).ExtBoundCond != SurfNum2) {
    3904            0 :                                     state.dataHeatBalFanSys->QRadSysSource(state.dataSurface->Surface(SurfNum2).ExtBoundCond) =
    3905              :                                         0.0; // Also zero the other side of an interzone
    3906              :                                 }
    3907              :                             }
    3908            0 :                             state.dataLoopNodes->Node(ReturnAirNode).Temp = state.dataHeatBalSurf->SurfInsideTempHist(1)(ventSlab.SurfacePtr(1));
    3909            0 :                             state.dataLoopNodes->Node(FanOutletNode).Temp = state.dataLoopNodes->Node(ReturnAirNode).Temp;
    3910            0 :                             state.dataLoopNodes->Node(SlabInNode).Temp = state.dataLoopNodes->Node(FanOutletNode).Temp;
    3911              :                             // Each Internal node is reseted at the surface temperature
    3912              : 
    3913            0 :                             break; // outer do loop
    3914              :                         }
    3915              :                     }
    3916              :                     // Condensation Cut-off:
    3917              :                     // Check to see whether there are any surface temperatures within the radiant system that have
    3918              :                     // dropped below the dew-point temperature.  If so, we need to shut off this radiant system.
    3919              :                     // A safety parameter is added (hardwired parameter) to avoid getting too close to condensation
    3920              :                     // conditions.
    3921              : 
    3922            0 :                     if (state.dataVentilatedSlab->OperatingMode == CoolingMode) {
    3923            0 :                         DewPointTemp =
    3924            0 :                             Psychrometrics::PsyTdpFnWPb(state,
    3925            0 :                                                         state.dataZoneTempPredictorCorrector->zoneHeatBalance(ventSlab.ZPtr(RadSurfNum)).airHumRat,
    3926            0 :                                                         state.dataEnvrn->OutBaroPress);
    3927            0 :                         for (int RadSurfNum2 = 1; RadSurfNum2 <= ventSlab.NumOfSurfaces; ++RadSurfNum2) {
    3928            0 :                             if (state.dataHeatBalSurf->SurfInsideTempHist(1)(ventSlab.SurfacePtr(RadSurfNum2)) < (DewPointTemp + CondDeltaTemp)) {
    3929              :                                 // Condensation warning--must shut off radiant system
    3930            0 :                                 state.dataLoopNodes->Node(SlabInNode).MassFlowRate = 0.0;
    3931            0 :                                 state.dataLoopNodes->Node(FanOutletNode).MassFlowRate = 0.0;
    3932            0 :                                 state.dataLoopNodes->Node(OAInletNode).MassFlowRate = 0.0;
    3933            0 :                                 state.dataLoopNodes->Node(MixoutNode).MassFlowRate = 0.0;
    3934            0 :                                 state.dataLoopNodes->Node(ReturnAirNode).MassFlowRate = 0.0;
    3935            0 :                                 state.dataLoopNodes->Node(FanOutletNode).Temp = state.dataLoopNodes->Node(SlabInNode).Temp;
    3936            0 :                                 AirMassFlow = 0.0;
    3937            0 :                                 for (int RadSurfNum3 = 1; RadSurfNum3 <= ventSlab.NumOfSurfaces; ++RadSurfNum3) {
    3938            0 :                                     int SurfNum2 = ventSlab.SurfacePtr(RadSurfNum3);
    3939            0 :                                     state.dataHeatBalFanSys->QRadSysSource(SurfNum2) = 0.0;
    3940            0 :                                     if (state.dataSurface->Surface(SurfNum2).ExtBoundCond > 0 &&
    3941            0 :                                         state.dataSurface->Surface(SurfNum2).ExtBoundCond != SurfNum2) {
    3942            0 :                                         state.dataHeatBalFanSys->QRadSysSource(state.dataSurface->Surface(SurfNum2).ExtBoundCond) =
    3943              :                                             0.0; // Also zero the other side of an interzone
    3944              :                                     }
    3945              :                                 }
    3946              :                                 // Produce a warning message so that user knows the system was shut-off due to potential for condensation
    3947            0 :                                 if (!state.dataGlobal->WarmupFlag) {
    3948            0 :                                     ++state.dataVentilatedSlab->CondensationErrorCount;
    3949            0 :                                     if (ventSlab.CondErrIndex == 0) {
    3950            0 :                                         ShowWarningMessage(state, format("{} [{}]", cMO_VentilatedSlab, ventSlab.Name));
    3951            0 :                                         ShowContinueError(
    3952              :                                             state,
    3953            0 :                                             format("Surface [{}] temperature below dew-point temperature--potential for condensation exists",
    3954            0 :                                                    state.dataSurface->Surface(ventSlab.SurfacePtr(RadSurfNum2)).Name));
    3955            0 :                                         ShowContinueError(state, "Flow to the ventilated slab system will be shut-off to avoid condensation");
    3956            0 :                                         ShowContinueError(state,
    3957            0 :                                                           format("Predicted radiant system surface temperature = {:.2R}",
    3958            0 :                                                                  state.dataHeatBalSurf->SurfInsideTempHist(1)(ventSlab.SurfacePtr(RadSurfNum2))));
    3959            0 :                                         ShowContinueError(
    3960            0 :                                             state, format("Zone dew-point temperature + safety factor delta= {:.2R}", DewPointTemp + CondDeltaTemp));
    3961            0 :                                         ShowContinueErrorTimeStamp(state, "");
    3962              :                                     }
    3963            0 :                                     if (state.dataVentilatedSlab->CondensationErrorCount == 1) {
    3964            0 :                                         ShowContinueError(
    3965            0 :                                             state, format("Note that there is a {:.4R} C safety built-in to the shut-off criteria", CondDeltaTemp));
    3966            0 :                                         ShowContinueError(state, "Note also that this affects all surfaces that are part of this system");
    3967              :                                     }
    3968            0 :                                     ShowRecurringWarningErrorAtEnd(state,
    3969            0 :                                                                    cMO_VentilatedSlab + " [" + ventSlab.Name +
    3970              :                                                                        "] condensation shut-off occurrence continues.",
    3971            0 :                                                                    ventSlab.CondErrIndex,
    3972              :                                                                    DewPointTemp,
    3973              :                                                                    DewPointTemp,
    3974              :                                                                    _,
    3975              :                                                                    "C",
    3976              :                                                                    "C");
    3977              :                                 }
    3978            0 :                                 break; // outer do loop
    3979              :                             }
    3980              :                         }
    3981              :                     }
    3982              :                 }
    3983              : 
    3984              :                 // Total Radiant Power
    3985            0 :                 AirOutletTempCheck = 0.0;
    3986            0 :                 TotalVentSlabRadPower = 0.0;
    3987            0 :                 for (RadSurfNum = 1; RadSurfNum <= ventSlab.NumOfSurfaces; ++RadSurfNum) {
    3988            0 :                     SurfNum = ventSlab.SurfacePtr(RadSurfNum);
    3989            0 :                     TotalVentSlabRadPower += state.dataHeatBalFanSys->QRadSysSource(SurfNum);
    3990            0 :                     AirOutletTempCheck = state.dataVentilatedSlab->AirTempOut(RadSurfNum);
    3991              :                 }
    3992            0 :                 TotalVentSlabRadPower *= ZoneMult;
    3993              : 
    3994              :                 // Internal Node Temperature Check
    3995              : 
    3996            0 :                 MSlabAirInTemp = state.dataLoopNodes->Node(SlabInNode).Temp;
    3997            0 :                 bool ErrorsFound = false; // Set to true if errors in input, fatal at end of routine
    3998              : 
    3999            0 :                 for (RadSurfNum = 1; RadSurfNum <= ventSlab.NumOfSurfaces; ++RadSurfNum) {
    4000            0 :                     std::string SlabName = ventSlab.SurfaceName(RadSurfNum);
    4001            0 :                     std::string MSlabIn = ventSlab.SlabIn(RadSurfNum);
    4002            0 :                     std::string MSlabOut = ventSlab.SlabOut(RadSurfNum);
    4003            0 :                     ventSlab.MSlabInNode = NodeInputManager::GetOnlySingleNode(state,
    4004              :                                                                                MSlabIn,
    4005              :                                                                                ErrorsFound,
    4006              :                                                                                DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
    4007              :                                                                                SlabName,
    4008              :                                                                                DataLoopNode::NodeFluidType::Air,
    4009              :                                                                                DataLoopNode::ConnectionType::Internal,
    4010              :                                                                                NodeInputManager::CompFluidStream::Primary,
    4011              :                                                                                DataLoopNode::ObjectIsNotParent);
    4012            0 :                     ventSlab.MSlabOutNode = NodeInputManager::GetOnlySingleNode(state,
    4013              :                                                                                 MSlabOut,
    4014              :                                                                                 ErrorsFound,
    4015              :                                                                                 DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
    4016              :                                                                                 SlabName,
    4017              :                                                                                 DataLoopNode::NodeFluidType::Air,
    4018              :                                                                                 DataLoopNode::ConnectionType::Internal,
    4019              :                                                                                 NodeInputManager::CompFluidStream::Primary,
    4020              :                                                                                 DataLoopNode::ObjectIsNotParent);
    4021            0 :                     int MSlabInletNode = ventSlab.MSlabInNode;
    4022            0 :                     int MSlabOutletNode = ventSlab.MSlabOutNode;
    4023            0 :                     SurfNum = ventSlab.SurfacePtr(RadSurfNum);
    4024              : 
    4025            0 :                     if (AirMassFlow > 0.0) {
    4026              : 
    4027            0 :                         CpAirZn = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(ventSlab.RadInNode).HumRat);
    4028              : 
    4029            0 :                         state.dataLoopNodes->Node(MSlabInletNode).Temp = MSlabAirInTemp;
    4030            0 :                         state.dataLoopNodes->Node(MSlabOutletNode).Temp = state.dataLoopNodes->Node(MSlabInletNode).Temp -
    4031            0 :                                                                           (state.dataHeatBalFanSys->QRadSysSource(SurfNum) / (AirMassFlow * CpAirZn));
    4032            0 :                         MSlabAirInTemp = state.dataLoopNodes->Node(MSlabOutletNode).Temp;
    4033              :                     } else {
    4034            0 :                         state.dataLoopNodes->Node(MSlabInletNode).Temp = state.dataLoopNodes->Node(ReturnAirNode).Temp;
    4035            0 :                         state.dataLoopNodes->Node(MSlabOutletNode).Temp = state.dataLoopNodes->Node(MSlabInletNode).Temp;
    4036              :                     }
    4037            0 :                 }
    4038              : 
    4039              :                 // Return Air temp Check
    4040            0 :                 if (AirMassFlow > 0.0) {
    4041              : 
    4042            0 :                     CpAirZn = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(ventSlab.RadInNode).HumRat);
    4043            0 :                     state.dataLoopNodes->Node(ReturnAirNode).Temp =
    4044            0 :                         state.dataLoopNodes->Node(SlabInNode).Temp - (TotalVentSlabRadPower / (AirMassFlow * CpAirZn));
    4045              : 
    4046            0 :                     if ((std::abs(state.dataLoopNodes->Node(ReturnAirNode).Temp - AirOutletTempCheck) > TempCheckLimit) &&
    4047            0 :                         (std::abs(TotalVentSlabRadPower) > ZeroSystemResp)) { // Return air temperature check did not match calculated temp
    4048              : 
    4049            0 :                         if (!state.dataGlobal->WarmupFlag) {
    4050            0 :                             ++state.dataVentilatedSlab->EnergyImbalanceErrorCount;
    4051            0 :                             if (ventSlab.EnrgyImbalErrIndex == 0) {
    4052            0 :                                 ShowWarningMessage(state, format("{} [{}]", cMO_VentilatedSlab, ventSlab.Name));
    4053            0 :                                 ShowContinueError(state, "Ventilated Slab (slab only type) air outlet temperature calculation mismatch.");
    4054            0 :                                 ShowContinueError(state, "This should not happen as it indicates a potential energy imbalance in the calculations.");
    4055            0 :                                 ShowContinueError(state, "However, it could also result from improper input for the ventilated slab or");
    4056            0 :                                 ShowContinueError(state, "illogical control temperatures.  Check your input for this ventilated slab and");
    4057            0 :                                 ShowContinueError(state, "also look at the internal data shown below.");
    4058            0 :                                 ShowContinueError(state,
    4059            0 :                                                   format("Predicted return air temperature [C] from the overall energy balance = {:.4R}",
    4060            0 :                                                          state.dataLoopNodes->Node(ReturnAirNode).Temp));
    4061            0 :                                 ShowContinueError(state,
    4062            0 :                                                   format("Predicted return air temperature [C] from the slab section energy balances = {:.4R}",
    4063              :                                                          AirOutletTempCheck));
    4064            0 :                                 ShowContinueError(state, format("Total energy rate (power) [W] added to the slab = {:.4R}", TotalVentSlabRadPower));
    4065            0 :                                 ShowContinueErrorTimeStamp(state, "");
    4066              :                             }
    4067            0 :                             ShowRecurringWarningErrorAtEnd(state,
    4068            0 :                                                            cMO_VentilatedSlab + " [" + ventSlab.Name +
    4069              :                                                                "] temperature calculation mismatch occurrence continues.",
    4070            0 :                                                            ventSlab.EnrgyImbalErrIndex);
    4071              :                         }
    4072              :                     }
    4073              : 
    4074              :                 } else {
    4075            0 :                     state.dataLoopNodes->Node(ReturnAirNode).Temp = state.dataLoopNodes->Node(SlabInNode).Temp;
    4076              :                 }
    4077              : 
    4078              :                 // Now that we have the source/sink term, we must redo the heat balances to obtain
    4079              :                 // the new SumHATsurf value for the zone.  Note that the difference between the new
    4080              :                 // SumHATsurf and the value originally calculated by the heat balance with a zero
    4081              :                 // source for all radiant systems in the zone is the load met by the system (approximately).
    4082              : 
    4083            0 :                 HeatBalanceSurfaceManager::CalcHeatBalanceOutsideSurf(state);
    4084            0 :                 HeatBalanceSurfaceManager::CalcHeatBalanceInsideSurf(state);
    4085              : 
    4086              :             } // SeriesSlabs
    4087              : 
    4088              :         } //(AirMassFlow > 0.0d0)
    4089            0 :     }
    4090              : 
    4091            0 :     void SimVentSlabOAMixer(EnergyPlusData &state, int const Item) // System index in Ventilated Slab array
    4092              :     {
    4093              : 
    4094              :         // SUBROUTINE INFORMATION:
    4095              :         //       AUTHOR         Rick Strand
    4096              :         //       DATE WRITTEN   May 2000
    4097              : 
    4098              :         // PURPOSE OF THIS SUBROUTINE:
    4099              :         // This responsibility of this subroutine is to set the air flow rates
    4100              :         // through the mixing box portion of the Ventilated Slab and then perform
    4101              :         // an energy balance to arrive at outlet conditions which then would
    4102              :         // serve as inlet conditions to the coils (or outlet conditions for
    4103              :         // the device).  There is some question as to whether this needs to be
    4104              :         // called every time the coils and fan are called since how the fans and
    4105              :         // coil operate won't presumable change how the mixer operates.  The
    4106              :         // method in which this routine is called is slightly cleaner though
    4107              :         // from a code readability standpoint though less efficient.
    4108              : 
    4109              :         // METHODOLOGY EMPLOYED:
    4110              :         // The OAMassFlowRate has already been calculated in the main control
    4111              :         // algorithm.  Use this flow rate to establish all of the other flow
    4112              :         // rates and perform an energy balance on the mixing of the return and
    4113              :         // outdoor air streams.
    4114              : 
    4115              :         // Using/Aliasing
    4116            0 :         auto const &ventSlab = state.dataVentilatedSlab->VentSlab(Item);
    4117              : 
    4118              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    4119              :         Real64 OAFraction; // Outside air fraction of inlet air
    4120              : 
    4121            0 :         int AirRelNode = ventSlab.AirReliefNode;      // relief air node number in ventilated slab loop
    4122            0 :         int InletNode = ventSlab.ReturnAirNode;       // inlet node number for ventilated slab loop
    4123            0 :         int OAMixOutNode = ventSlab.OAMixerOutNode;   // outside air mixer outlet node for ventilated slab loop
    4124            0 :         int OutsideAirNode = ventSlab.OutsideAirNode; // outside air node number in ventilated slab loop
    4125              : 
    4126              :         // "Resolve" the air flow rates...
    4127              : 
    4128            0 :         state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate = state.dataVentilatedSlab->OAMassFlowRate;
    4129            0 :         state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMinAvail = state.dataVentilatedSlab->OAMassFlowRate;
    4130            0 :         state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMaxAvail = state.dataVentilatedSlab->OAMassFlowRate;
    4131              : 
    4132            0 :         state.dataLoopNodes->Node(AirRelNode).MassFlowRate = state.dataVentilatedSlab->OAMassFlowRate;
    4133            0 :         state.dataLoopNodes->Node(AirRelNode).MassFlowRateMinAvail = state.dataVentilatedSlab->OAMassFlowRate;
    4134            0 :         state.dataLoopNodes->Node(AirRelNode).MassFlowRateMaxAvail = state.dataVentilatedSlab->OAMassFlowRate;
    4135              : 
    4136            0 :         state.dataLoopNodes->Node(OAMixOutNode).MassFlowRate = state.dataLoopNodes->Node(InletNode).MassFlowRate;
    4137            0 :         state.dataLoopNodes->Node(OAMixOutNode).MassFlowRateMinAvail = state.dataLoopNodes->Node(InletNode).MassFlowRate;
    4138            0 :         state.dataLoopNodes->Node(OAMixOutNode).MassFlowRateMaxAvail = state.dataLoopNodes->Node(InletNode).MassFlowRate;
    4139              : 
    4140              :         // "Inlet" conditions for InletNode and OutsideAirNode have already
    4141              :         // been set elsewhere so we just need to set the "outlet" conditions
    4142            0 :         state.dataLoopNodes->Node(AirRelNode).Temp = state.dataLoopNodes->Node(InletNode).Temp;
    4143            0 :         state.dataLoopNodes->Node(AirRelNode).Press = state.dataLoopNodes->Node(InletNode).Press;
    4144            0 :         state.dataLoopNodes->Node(AirRelNode).HumRat = state.dataLoopNodes->Node(InletNode).HumRat;
    4145            0 :         state.dataLoopNodes->Node(AirRelNode).Enthalpy = state.dataLoopNodes->Node(InletNode).Enthalpy;
    4146              : 
    4147            0 :         if (state.dataLoopNodes->Node(InletNode).MassFlowRate > 0.0) {
    4148              : 
    4149            0 :             OAFraction = state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate / state.dataLoopNodes->Node(InletNode).MassFlowRate;
    4150              : 
    4151              :         } else {
    4152            0 :             OAFraction = 0.0;
    4153              :         }
    4154              : 
    4155            0 :         state.dataLoopNodes->Node(InletNode).Enthalpy =
    4156            0 :             Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(InletNode).Temp, state.dataLoopNodes->Node(InletNode).HumRat);
    4157              : 
    4158              :         // Perform an energy and moisture mass balance on the mixing portion of the OA Mixer of the ventilated slab
    4159            0 :         state.dataLoopNodes->Node(OAMixOutNode).Enthalpy =
    4160            0 :             OAFraction * state.dataLoopNodes->Node(OutsideAirNode).Enthalpy + (1.0 - OAFraction) * state.dataLoopNodes->Node(InletNode).Enthalpy;
    4161            0 :         state.dataLoopNodes->Node(OAMixOutNode).HumRat =
    4162            0 :             OAFraction * state.dataLoopNodes->Node(OutsideAirNode).HumRat + (1.0 - OAFraction) * state.dataLoopNodes->Node(InletNode).HumRat;
    4163              : 
    4164              :         // Find the other key state points based on calculated conditions
    4165            0 :         state.dataLoopNodes->Node(OAMixOutNode).Temp =
    4166            0 :             Psychrometrics::PsyTdbFnHW(state.dataLoopNodes->Node(OAMixOutNode).Enthalpy, state.dataLoopNodes->Node(OAMixOutNode).HumRat);
    4167            0 :         state.dataLoopNodes->Node(OAMixOutNode).Press = state.dataLoopNodes->Node(InletNode).Press;
    4168            0 :     }
    4169              : 
    4170            0 :     void UpdateVentilatedSlab(EnergyPlusData &state,
    4171              :                               int const Item, // Index for the ventilated slab under consideration within the derived types
    4172              :                               [[maybe_unused]] bool const FirstHVACIteration // TRUE if 1st HVAC simulation of system timestep !unused1208
    4173              :     )
    4174              :     {
    4175              : 
    4176              :         // SUBROUTINE INFORMATION:
    4177              :         //       AUTHOR         Young Tae Chae, Rick Strand
    4178              :         //       DATE WRITTEN   November 2000
    4179              : 
    4180              :         // PURPOSE OF THIS SUBROUTINE:
    4181              :         // This subroutine does any updating that needs to be done for low
    4182              :         // temperature radiant heating and cooling systems.  One of the most
    4183              :         // important functions of this routine is to update the average heat
    4184              :         // source/sink for a particular system over the various system time
    4185              :         // steps that make up the zone time step.  For hydronic systems,
    4186              :         // this routine must also set the outlet water conditions.
    4187              : 
    4188              :         // METHODOLOGY EMPLOYED:
    4189              :         // For the source/sink average update, if the system time step elapsed
    4190              :         // is still what it used to be, then either we are still iterating or
    4191              :         // we had to go back and shorten the time step.  As a result, we have
    4192              :         // to subtract out the previous value that we added.  If the system
    4193              :         // time step elapsed is different, then we just need to add the new
    4194              :         // values to the running average.
    4195              : 
    4196              :         // Using/Aliasing
    4197            0 :         Real64 SysTimeElapsed = state.dataHVACGlobal->SysTimeElapsed;
    4198            0 :         Real64 TimeStepSys = state.dataHVACGlobal->TimeStepSys;
    4199            0 :         auto &ventSlab = state.dataVentilatedSlab->VentSlab(Item);
    4200              : 
    4201              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    4202              :         Real64 OAFraction; // Outside air fraction of inlet air
    4203              : 
    4204            0 :         int TotRadSurfaces = ventSlab.NumOfSurfaces;
    4205            0 :         int MixOutNode = ventSlab.OAMixerOutNode; // Node number for the water side outlet of the radiant system
    4206            0 :         int OANode = ventSlab.OutsideAirNode;
    4207            0 :         int AirOutletNode = ventSlab.RadInNode;
    4208            0 :         int FanOutNode = ventSlab.FanOutletNode;
    4209            0 :         Real64 AirMassFlow = state.dataLoopNodes->Node(AirOutletNode).MassFlowRate;
    4210            0 :         int ZoneInletNode = ventSlab.ZoneAirInNode; // Node number for the air side inlet of the ventilated slab
    4211            0 :         Real64 CpAppAir = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(AirOutletNode).HumRat);
    4212            0 :         int AirInletNode = ventSlab.ReturnAirNode; // Node number for the air side inlet of the ventilated slab
    4213              : 
    4214            0 :         for (int RadSurfNum = 1; RadSurfNum <= TotRadSurfaces; ++RadSurfNum) {
    4215              : 
    4216            0 :             int SurfNum = ventSlab.SurfacePtr(RadSurfNum);
    4217              : 
    4218            0 :             if (ventSlab.LastSysTimeElapsed == SysTimeElapsed) {
    4219              :                 // Still iterating or reducing system time step, so subtract old values which were not valid
    4220            0 :                 ventSlab.QRadSysSrcAvg(RadSurfNum) -= ventSlab.LastQRadSysSrc(RadSurfNum) * ventSlab.LastTimeStepSys / state.dataGlobal->TimeStepZone;
    4221              :             }
    4222              : 
    4223              :             // Update the running average and the "last" values with the current values of the appropriate variables
    4224            0 :             ventSlab.QRadSysSrcAvg(RadSurfNum) += state.dataHeatBalFanSys->QRadSysSource(SurfNum) * TimeStepSys / state.dataGlobal->TimeStepZone;
    4225            0 :             ventSlab.LastQRadSysSrc(RadSurfNum) = state.dataHeatBalFanSys->QRadSysSource(SurfNum);
    4226              :         }
    4227            0 :         ventSlab.LastSysTimeElapsed = SysTimeElapsed;
    4228            0 :         ventSlab.LastTimeStepSys = TimeStepSys;
    4229              : 
    4230              :         // First sum up all of the heat sources/sinks associated with this system
    4231            0 :         Real64 TotalHeatSource = 0.0;
    4232            0 :         for (int RadSurfNum = 1; RadSurfNum <= ventSlab.NumOfSurfaces; ++RadSurfNum) {
    4233            0 :             int SurfNum = ventSlab.SurfacePtr(RadSurfNum);
    4234            0 :             TotalHeatSource += state.dataHeatBalFanSys->QRadSysSource(SurfNum);
    4235              :         }
    4236            0 :         int ZoneNum = ventSlab.ZonePtr;
    4237            0 :         int ZoneMult = double(state.dataHeatBal->Zone(ZoneNum).Multiplier * state.dataHeatBal->Zone(ZoneNum).ListMultiplier);
    4238            0 :         TotalHeatSource *= ZoneMult;
    4239              : 
    4240              :         // Update the heating side of things
    4241              : 
    4242            0 :         if ((CpAppAir > 0.0) && (AirMassFlow > 0.0)) {
    4243              : 
    4244            0 :             if ((ventSlab.SysConfg == VentilatedSlabConfig::SlabOnly) || (ventSlab.SysConfg == VentilatedSlabConfig::SeriesSlabs)) {
    4245            0 :                 state.dataLoopNodes->Node(AirInletNode) = state.dataLoopNodes->Node(AirInletNode);
    4246            0 :                 state.dataLoopNodes->Node(AirInletNode).Temp =
    4247            0 :                     state.dataLoopNodes->Node(AirOutletNode).Temp - TotalHeatSource / AirMassFlow / CpAppAir;
    4248            0 :                 state.dataLoopNodes->Node(AirInletNode).MassFlowRate = state.dataLoopNodes->Node(AirOutletNode).MassFlowRate;
    4249            0 :                 state.dataLoopNodes->Node(AirInletNode).HumRat = state.dataLoopNodes->Node(AirOutletNode).HumRat;
    4250              : 
    4251            0 :             } else if (ventSlab.SysConfg == VentilatedSlabConfig::SlabAndZone) {
    4252            0 :                 state.dataLoopNodes->Node(ZoneInletNode) = state.dataLoopNodes->Node(ZoneInletNode);
    4253            0 :                 state.dataLoopNodes->Node(ZoneInletNode).Temp =
    4254            0 :                     state.dataLoopNodes->Node(AirOutletNode).Temp - TotalHeatSource / AirMassFlow / CpAppAir;
    4255            0 :                 state.dataLoopNodes->Node(ZoneInletNode).MassFlowRate = state.dataLoopNodes->Node(AirOutletNode).MassFlowRate;
    4256            0 :                 state.dataLoopNodes->Node(ZoneInletNode).HumRat = state.dataLoopNodes->Node(AirOutletNode).HumRat;
    4257            0 :                 state.dataLoopNodes->Node(ventSlab.ReturnAirNode).Temp = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT;
    4258              :             }
    4259              : 
    4260              :         } else {
    4261            0 :             state.dataLoopNodes->Node(FanOutNode) = state.dataLoopNodes->Node(AirOutletNode);
    4262            0 :             if (ventSlab.SysConfg == VentilatedSlabConfig::SlabAndZone) {
    4263            0 :                 state.dataLoopNodes->Node(ZoneInletNode) = state.dataLoopNodes->Node(AirInletNode);
    4264              :             }
    4265            0 :             for (int const surfNum : ventSlab.SurfacePtr) {
    4266            0 :                 state.dataHeatBalFanSys->QRadSysSource(surfNum) = 0.0;
    4267              :             }
    4268              :         }
    4269              : 
    4270              :         // Resolve mixouttemp
    4271              : 
    4272            0 :         if (state.dataLoopNodes->Node(AirInletNode).MassFlowRate > 0.0) {
    4273              : 
    4274            0 :             OAFraction = state.dataLoopNodes->Node(OANode).MassFlowRate / state.dataLoopNodes->Node(AirInletNode).MassFlowRate;
    4275              : 
    4276              :         } else {
    4277            0 :             OAFraction = 0.0;
    4278              :         }
    4279              : 
    4280            0 :         if (OAFraction <= 0.0) {
    4281              : 
    4282            0 :             state.dataLoopNodes->Node(MixOutNode).HumRat = state.dataLoopNodes->Node(AirInletNode).HumRat;
    4283            0 :             state.dataLoopNodes->Node(MixOutNode).Temp = state.dataLoopNodes->Node(AirInletNode).Temp;
    4284              : 
    4285              :         } else {
    4286              : 
    4287            0 :             state.dataLoopNodes->Node(MixOutNode).Enthalpy =
    4288            0 :                 OAFraction * state.dataLoopNodes->Node(OANode).Enthalpy + (1.0 - OAFraction) * state.dataLoopNodes->Node(AirInletNode).Enthalpy;
    4289            0 :             state.dataLoopNodes->Node(MixOutNode).HumRat =
    4290            0 :                 OAFraction * state.dataLoopNodes->Node(OANode).HumRat + (1.0 - OAFraction) * state.dataLoopNodes->Node(AirInletNode).HumRat;
    4291              : 
    4292            0 :             state.dataLoopNodes->Node(MixOutNode).Temp =
    4293            0 :                 Psychrometrics::PsyTdbFnHW(state.dataLoopNodes->Node(MixOutNode).Enthalpy, state.dataLoopNodes->Node(MixOutNode).HumRat);
    4294              :         }
    4295            0 :     }
    4296              : 
    4297            0 :     Real64 CalcVentSlabHXEffectTerm(EnergyPlusData &state,
    4298              :                                     int const Item,            // Index number of radiant system under consideration
    4299              :                                     Real64 const Temperature,  // Temperature of air entering the radiant system, in C
    4300              :                                     Real64 const AirMassFlow,  // Mass flow rate of water in the radiant system, in kg/s
    4301              :                                     Real64 const FlowFraction, // Mass flow rate fraction for this surface in the radiant system
    4302              :                                     Real64 const CoreLength,   // Length of tubing in the radiant system, in m
    4303              :                                     Real64 const CoreDiameter, // Inside diameter of the tubing in the radiant system, in m
    4304              :                                     Real64 const CoreNumbers)
    4305              :     {
    4306              : 
    4307              :         // SUBROUTINE INFORMATION:
    4308              :         //       AUTHOR         Rick Strand
    4309              :         //       DATE WRITTEN   December 2000
    4310              :         //       MODIFIED       June 2008 (air properties)
    4311              : 
    4312              :         // PURPOSE OF THIS SUBROUTINE:
    4313              :         // This subroutine calculates the radiant system "heat exchanger"
    4314              :         // effectiveness term.  This is equal to the mass flow rate of water
    4315              :         // times the specific heat of water times the effectiveness of
    4316              :         // the heat exchanger (radiant system "coil").
    4317              : 
    4318              :         // METHODOLOGY EMPLOYED:
    4319              :         // Assumes that the only real heat transfer term that we have to
    4320              :         // deal with is the convection from the water to the tube.  The
    4321              :         // other assumptions are that the tube inside surface temperature
    4322              :         // is equal to the "source location temperature" and that it is
    4323              :         // a CONSTANT throughout the radiant system.  This is to make
    4324              :         // the problem more tractable and to fit with other system assumptions
    4325              :         // that were made elsewhere in the radiant system model.
    4326              : 
    4327              :         // REFERENCES:
    4328              :         // Property data for air shown below as parameters taken from
    4329              :         //   Mills, Heat Transfer, Table A.7.
    4330              :         // Heat exchanger information also from Incropera and DeWitt.
    4331              :         // Code based loosely on code from IBLAST program (research version)
    4332              : 
    4333              :         // Using/Aliasing
    4334            0 :         auto &ventSlab = state.dataVentilatedSlab->VentSlab(Item);
    4335              : 
    4336              :         // Return value
    4337              :         Real64 CalcVentSlabHXEffectTerm;
    4338              : 
    4339            0 :         Real64 constexpr MaxLaminarRe(2300.0); // Maximum Reynolds number for laminar flow
    4340            0 :         int constexpr NumOfPropDivisions(13);
    4341            0 :         Real64 constexpr MaxExpPower(50.0); // Maximum power after which EXP argument would be zero for DP variables
    4342              :         static constexpr std::array<Real64, NumOfPropDivisions> Temps = {
    4343              :             1.85, 6.85, 11.85, 16.85, 21.85, 26.85, 31.85, 36.85, 41.85, 46.85, 51.85, 56.85, 61.85}; // Temperature, in C
    4344              :         static constexpr std::array<Real64, NumOfPropDivisions> Mu = {0.0000088,
    4345              :                                                                       0.0000176,
    4346              :                                                                       0.00001781,
    4347              :                                                                       0.00001802,
    4348              :                                                                       0.000018225,
    4349              :                                                                       0.00001843,
    4350              :                                                                       0.00001865,
    4351              :                                                                       0.00001887,
    4352              :                                                                       0.00001908,
    4353              :                                                                       0.00001929,
    4354              :                                                                       0.0000195,
    4355              :                                                                       0.00001971,
    4356              :                                                                       0.00001992}; // Viscosity, in Ns/m2
    4357              : 
    4358              :         static constexpr std::array<Real64, NumOfPropDivisions> Conductivity = {
    4359              :             0.01275, 0.0255, 0.0258, 0.0261, 0.0264, 0.0267, 0.02705, 0.0274, 0.02775, 0.0281, 0.0284, 0.0287, 0.01435}; // Conductivity, in W/mK
    4360              :         static constexpr std::array<Real64, NumOfPropDivisions> Pr = {
    4361              :             0.69, 0.69, 0.69, 0.69, 0.69, 0.69, 0.69, 0.69, 0.69, 0.69, 0.69, 0.69, 0.69}; // Prandtl number (dimensionless)
    4362              : 
    4363              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    4364              :         int Index;
    4365              :         Real64 InterpFrac;
    4366              :         Real64 NuD;
    4367              :         Real64 ReD;
    4368              :         Real64 NTU;
    4369              :         Real64 CpAppAir;
    4370              :         Real64 Kactual;
    4371              :         Real64 MUactual;
    4372              :         Real64 PRactual;
    4373              :         Real64 SysAirMassFlow; // Specific heat of air
    4374              : 
    4375              :         // First find out where we are in the range of temperatures
    4376            0 :         Index = 0;
    4377            0 :         while (Index < NumOfPropDivisions) {
    4378            0 :             if (Temperature < Temps[Index]) {
    4379            0 :                 break; // DO loop
    4380              :             }
    4381            0 :             ++Index;
    4382              :         }
    4383              : 
    4384              :         // Initialize thermal properties of Air
    4385            0 :         if (Index == 0) {
    4386            0 :             MUactual = Mu[Index];
    4387            0 :             Kactual = Conductivity[Index];
    4388            0 :             PRactual = Pr[Index];
    4389            0 :         } else if (Index > NumOfPropDivisions - 1) {
    4390            0 :             Index = NumOfPropDivisions - 1;
    4391            0 :             MUactual = Mu[Index];
    4392            0 :             Kactual = Conductivity[Index];
    4393            0 :             PRactual = Pr[Index];
    4394              :         } else {
    4395            0 :             InterpFrac = (Temperature - Temps[Index - 1]) / (Temps[Index] - Temps[Index - 1]);
    4396            0 :             MUactual = Mu[Index - 1] + InterpFrac * (Mu[Index] - Mu[Index - 1]);
    4397            0 :             Kactual = Conductivity[Index - 1] + InterpFrac * (Conductivity[Index] - Conductivity[Index - 1]);
    4398            0 :             PRactual = Pr[Index - 1] + InterpFrac * (Pr[Index] - Pr[Index - 1]);
    4399              :         }
    4400              :         // arguments are glycol name, temperature, and concentration
    4401            0 :         CpAppAir = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(ventSlab.RadInNode).HumRat);
    4402            0 :         SysAirMassFlow = AirMassFlow / CoreNumbers;
    4403              : 
    4404              :         // Calculate the Reynold's number from RE=(4*Mdot)/(Pi*Mu*Diameter)
    4405            0 :         ReD = 4.0 * SysAirMassFlow * FlowFraction / (Constant::Pi * MUactual * CoreDiameter);
    4406              : 
    4407              :         // Calculate the Nusselt number based on what flow regime one is in
    4408            0 :         if (ReD >= MaxLaminarRe) { // Turbulent flow --> use Colburn equation
    4409              : 
    4410            0 :             NuD = 0.023 * std::pow(ReD, 0.8) * std::pow(PRactual, 1.0 / 3.0);
    4411              : 
    4412              :         } else { // Laminar flow --> use constant surface temperature relation
    4413              : 
    4414            0 :             NuD = 3.66;
    4415              :         }
    4416              : 
    4417              :         // Calculate the NTU parameter
    4418              :         // NTU = UA/[(Mdot*Cp)min]
    4419              :         // where: U = h (convection coefficient) and h = (k)(Nu)/D
    4420              :         //        A = Pi*D*TubeLength
    4421            0 :         NTU = Constant::Pi * Kactual * NuD * CoreLength / (SysAirMassFlow * CpAppAir); // FlowFraction cancels out here
    4422              : 
    4423              :         // Calculate Epsilon*MassFlowRate*Cp
    4424            0 :         if (NTU > MaxExpPower) {
    4425            0 :             CalcVentSlabHXEffectTerm = FlowFraction * SysAirMassFlow * CpAppAir;
    4426              :         } else {
    4427            0 :             CalcVentSlabHXEffectTerm = (1.0 - std::exp(-NTU)) * FlowFraction * SysAirMassFlow * CpAppAir;
    4428              :         }
    4429              : 
    4430            0 :         return CalcVentSlabHXEffectTerm;
    4431              :     }
    4432              : 
    4433            0 :     void ReportVentilatedSlab(EnergyPlusData &state, int const Item) // Index for the ventilated slab under consideration within the derived types
    4434              :     {
    4435              : 
    4436              :         // SUBROUTINE INFORMATION:
    4437              :         //       AUTHOR         Rick Strand
    4438              :         //       DATE WRITTEN   November 2000
    4439              : 
    4440              :         // PURPOSE OF THIS SUBROUTINE:
    4441              :         // This subroutine simply produces output for the low temperature radiant system.
    4442              : 
    4443              :         // Using/Aliasing
    4444            0 :         Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
    4445            0 :         auto &ventSlab = state.dataVentilatedSlab->VentSlab(Item);
    4446              : 
    4447              :         // Slab Part
    4448            0 :         Real64 TotalVentSlabRadPower = 0.0; // Total source/sink power for the radiant system (sum of all surfaces of the system)
    4449              : 
    4450            0 :         for (int RadSurfNum = 1; RadSurfNum <= ventSlab.NumOfSurfaces; ++RadSurfNum) {
    4451            0 :             int SurfNum = ventSlab.SurfacePtr(RadSurfNum);
    4452            0 :             TotalVentSlabRadPower += state.dataHeatBalFanSys->QRadSysSource(SurfNum);
    4453              :         }
    4454            0 :         Real64 ZoneMult = double(state.dataHeatBal->Zone(ventSlab.ZonePtr).Multiplier * state.dataHeatBal->Zone(ventSlab.ZonePtr).ListMultiplier);
    4455            0 :         TotalVentSlabRadPower *= ZoneMult;
    4456            0 :         ventSlab.RadHeatingPower = 0.0;
    4457            0 :         ventSlab.RadCoolingPower = 0.0;
    4458              : 
    4459            0 :         if (TotalVentSlabRadPower >= 0.01) {
    4460              : 
    4461            0 :             ventSlab.RadHeatingPower = +TotalVentSlabRadPower;
    4462              :         } else {
    4463              : 
    4464            0 :             ventSlab.RadCoolingPower = -TotalVentSlabRadPower;
    4465              :         }
    4466              : 
    4467            0 :         ventSlab.RadHeatingEnergy = ventSlab.RadHeatingPower * TimeStepSysSec;
    4468            0 :         ventSlab.RadCoolingEnergy = ventSlab.RadCoolingPower * TimeStepSysSec;
    4469              : 
    4470              :         // Coil Part
    4471            0 :         ventSlab.HeatCoilEnergy = ventSlab.HeatCoilPower * TimeStepSysSec;
    4472            0 :         ventSlab.SensCoolCoilEnergy = ventSlab.SensCoolCoilPower * TimeStepSysSec;
    4473            0 :         ventSlab.LateCoolCoilEnergy = ventSlab.LateCoolCoilPower * TimeStepSysSec;
    4474            0 :         ventSlab.TotCoolCoilEnergy = ventSlab.TotCoolCoilPower * TimeStepSysSec;
    4475            0 :         ventSlab.ElecFanEnergy = ventSlab.ElecFanPower * TimeStepSysSec;
    4476              : 
    4477            0 :         if ((ventSlab.SysConfg == VentilatedSlabConfig::SlabOnly) || (ventSlab.SysConfg == VentilatedSlabConfig::SeriesSlabs)) {
    4478            0 :             ventSlab.SlabInTemp = state.dataLoopNodes->Node(ventSlab.RadInNode).Temp;
    4479            0 :             ventSlab.SlabOutTemp = state.dataLoopNodes->Node(ventSlab.ReturnAirNode).Temp;
    4480              : 
    4481            0 :         } else if (ventSlab.SysConfg == VentilatedSlabConfig::SlabAndZone) {
    4482            0 :             ventSlab.SlabInTemp = state.dataLoopNodes->Node(ventSlab.RadInNode).Temp;
    4483            0 :             ventSlab.ZoneInletTemp = state.dataLoopNodes->Node(ventSlab.ZoneAirInNode).Temp;
    4484            0 :             ventSlab.SlabOutTemp = state.dataLoopNodes->Node(ventSlab.ReturnAirNode).Temp;
    4485              :         }
    4486              : 
    4487            0 :         ventSlab.ReturnAirTemp = state.dataLoopNodes->Node(ventSlab.ReturnAirNode).Temp;
    4488            0 :         ventSlab.FanOutletTemp = state.dataLoopNodes->Node(ventSlab.FanOutletNode).Temp;
    4489              : 
    4490            0 :         if (ventSlab.FirstPass) { // reset sizing flags so other zone equipment can size normally
    4491            0 :             if (!state.dataGlobal->SysSizingCalc) {
    4492            0 :                 DataSizing::resetHVACSizingGlobals(state, state.dataSize->CurZoneEqNum, 0, ventSlab.FirstPass);
    4493              :             }
    4494              :         }
    4495            0 :     }
    4496              : 
    4497            1 :     int getVentilatedSlabIndex(EnergyPlusData &state, std::string_view CompName)
    4498              :     {
    4499            1 :         if (state.dataVentilatedSlab->GetInputFlag) {
    4500            0 :             GetVentilatedSlabInput(state);
    4501            0 :             state.dataVentilatedSlab->GetInputFlag = false;
    4502              :         }
    4503              : 
    4504            1 :         for (int VentSlabNum = 1; VentSlabNum <= state.dataVentilatedSlab->NumOfVentSlabs; ++VentSlabNum) {
    4505            1 :             if (Util::SameString(state.dataVentilatedSlab->VentSlab(VentSlabNum).Name, CompName)) {
    4506            1 :                 return VentSlabNum;
    4507              :             }
    4508              :         }
    4509              : 
    4510            0 :         return 0;
    4511              :     }
    4512              :     //*****************************************************************************************
    4513              : 
    4514              : } // namespace VentilatedSlab
    4515              : 
    4516              : } // namespace EnergyPlus
        

Generated by: LCOV version 2.0-1