LCOV - code coverage report
Current view: top level - EnergyPlus - LowTempRadiantSystem.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 76.3 % 3024 2308
Test Date: 2025-06-02 07:23:51 Functions: 100.0 % 29 29

            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 <cassert>
      50              : #include <cmath>
      51              : 
      52              : // ObjexxFCL Headers
      53              : #include <ObjexxFCL/Array.functions.hh>
      54              : #include <ObjexxFCL/Fmath.hh>
      55              : 
      56              : // EnergyPlus Headers
      57              : #include <EnergyPlus/Autosizing/CoolingCapacitySizing.hh>
      58              : #include <EnergyPlus/Autosizing/HeatingCapacitySizing.hh>
      59              : #include <EnergyPlus/BranchNodeConnections.hh>
      60              : #include <EnergyPlus/Construction.hh>
      61              : #include <EnergyPlus/Data/EnergyPlusData.hh>
      62              : #include <EnergyPlus/DataBranchAirLoopPlant.hh>
      63              : #include <EnergyPlus/DataEnvironment.hh>
      64              : #include <EnergyPlus/DataHVACGlobals.hh>
      65              : #include <EnergyPlus/DataHeatBalFanSys.hh>
      66              : #include <EnergyPlus/DataHeatBalSurface.hh>
      67              : #include <EnergyPlus/DataHeatBalance.hh>
      68              : #include <EnergyPlus/DataLoopNode.hh>
      69              : #include <EnergyPlus/DataSizing.hh>
      70              : #include <EnergyPlus/DataSurfaceLists.hh>
      71              : #include <EnergyPlus/DataSurfaces.hh>
      72              : #include <EnergyPlus/DataZoneEquipment.hh>
      73              : #include <EnergyPlus/EMSManager.hh>
      74              : #include <EnergyPlus/FluidProperties.hh>
      75              : #include <EnergyPlus/General.hh>
      76              : #include <EnergyPlus/GeneralRoutines.hh>
      77              : #include <EnergyPlus/GlobalNames.hh>
      78              : #include <EnergyPlus/HeatBalanceSurfaceManager.hh>
      79              : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      80              : #include <EnergyPlus/LowTempRadiantSystem.hh>
      81              : #include <EnergyPlus/NodeInputManager.hh>
      82              : #include <EnergyPlus/OutputProcessor.hh>
      83              : #include <EnergyPlus/Plant/Enums.hh>
      84              : #include <EnergyPlus/PlantUtilities.hh>
      85              : #include <EnergyPlus/Psychrometrics.hh>
      86              : #include <EnergyPlus/ScheduleManager.hh>
      87              : #include <EnergyPlus/UtilityRoutines.hh>
      88              : #include <EnergyPlus/WeatherManager.hh>
      89              : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
      90              : 
      91              : namespace EnergyPlus {
      92              : 
      93              : namespace LowTempRadiantSystem {
      94              : 
      95              :     // Module containing the routines dealing with the low temperature radiant systems
      96              : 
      97              :     // MODULE INFORMATION:
      98              :     //       AUTHOR         Rick Strand
      99              :     //       DATE WRITTEN   November 2000
     100              :     //       MODIFIED       Rick Strand March 2001 (additional controls, etc.)
     101              :     //                      Rick Strand July 2003 (added constant flow hydronic system)
     102              :     //                      B. Griffith Sept 2010, plant upgrades, generalize fluid properties
     103              :     //                      Rick Strand August 2011 (improved condensation handling)
     104              : 
     105              :     // PURPOSE OF THIS MODULE:
     106              :     // The purpose of this module is to simulate low temperature radiant systems.
     107              :     // It is the intention of this module to cover all types of low temperature
     108              :     // radiant systems: wall, ceiling, floor, heating, cooling, panels, etc.
     109              : 
     110              :     // METHODOLOGY EMPLOYED:
     111              :     // Based on work done in IBLAST, this model has been revised for the structure
     112              :     // of EnergyPlus.  It is still based on the QTF formulation of heat transfer
     113              :     // through building elements with embedded heat sources/sinks.  Note that due
     114              :     // to the fact that a radiant system is both a building heat transfer element
     115              :     // and a controllable system that some iteration between the system and the
     116              :     // surface heat balance routine is necessary.
     117              :     // REFERENCES:
     118              :     // IBLAST-QTF research program, completed in January 1995 (unreleased)
     119              :     // Strand, R.K. 1995. "Heat Source Transfer Functions and Their Application to
     120              :     //   Low Temperature Radiant Heating Systems", Ph.D. dissertation, University
     121              :     //   of Illinois at Urbana-Champaign, Department of Mechanical and Industrial
     122              :     //   Engineering.
     123              :     // Seem, J.E. 1986. "Heat Transfer in Buildings", Ph.D. dissertation, University
     124              :     //   of Wisconsin-Madison.
     125              : 
     126              :     // OTHER NOTES: This module contains three different types of radiant system
     127              :     // models: (a) variable flow hydronic heating/cooling radiant system;
     128              :     // (b) constant flow, variable controlled temperature heating/cooling radiant
     129              :     // system; (c) electric resistance heating radiant system.  Systems (a) and
     130              :     // (b) are hydronic systems--one which varies hydronic flow as the key control
     131              :     // parameter (a) and one which varies the inlet hydronic temperature while
     132              :     // keeping the flow rate through the radiant system constant (b).  In system
     133              :     // (b), the injection rate from the main water loop is varied to obtain the
     134              :     // proper inlet temperature.
     135              : 
     136              :     // USE STATEMENTS:
     137              :     // Use statements for data only modules
     138              :     // Using/Aliasing
     139              :     using HVAC::SmallLoad;
     140              :     using Psychrometrics::PsyTdpFnWPb;
     141              : 
     142              :     // Data
     143              :     // MODULE PARAMETER DEFINITIONS:
     144              :     // System types:
     145              :     constexpr std::string_view cHydronicSystem("ZoneHVAC:LowTemperatureRadiant:VariableFlow");
     146              :     constexpr std::string_view cConstantFlowSystem("ZoneHVAC:LowTemperatureRadiant:ConstantFlow");
     147              : 
     148              :     // DERIVED TYPE DEFINITIONS:
     149              : 
     150              :     // MODULE VARIABLE DECLARATIONS:
     151              :     // Standard, run-of-the-mill variables...
     152              : 
     153              :     // Object Data
     154              :     constexpr std::array<std::string_view, (int)CtrlType::Num> ctrlTypeNames = {"MeanAirTemperature",
     155              :                                                                                 "MeanRadiantTemperature",
     156              :                                                                                 "OperativeTemperature",
     157              :                                                                                 "OutdoorDryBulbTemperature",
     158              :                                                                                 "OutdoorWetBulbTemperature",
     159              :                                                                                 "SurfaceFaceTemperature",
     160              :                                                                                 "SurfaceInteriorTemperature",
     161              :                                                                                 "RunningMeanOutdoorDryBulbTemperature"};
     162              :     constexpr std::array<std::string_view, (int)CtrlType::Num> ctrlTypeNamesUC = {"MEANAIRTEMPERATURE",
     163              :                                                                                   "MEANRADIANTTEMPERATURE",
     164              :                                                                                   "OPERATIVETEMPERATURE",
     165              :                                                                                   "OUTDOORDRYBULBTEMPERATURE",
     166              :                                                                                   "OUTDOORWETBULBTEMPERATURE",
     167              :                                                                                   "SURFACEFACETEMPERATURE",
     168              :                                                                                   "SURFACEINTERIORTEMPERATURE",
     169              :                                                                                   "RUNNINGMEANOUTDOORDRYBULBTEMPERATURE"};
     170              : 
     171              :     constexpr std::array<std::string_view, (int)SetpointType::Num> setpointTypeNames = {"HalfFlowPower", "ZeroFlowPower"};
     172              :     constexpr std::array<std::string_view, (int)SetpointType::Num> setpointTypeNamesUC = {"HALFFLOWPOWER", "ZEROFLOWPOWER"};
     173              : 
     174              :     constexpr std::array<std::string_view, (int)FluidToSlabHeatTransferType::Num> fluidToSlabHeatTransferTypeNames = {"ConvectionOnly",
     175              :                                                                                                                       "ISOStandard"};
     176              :     constexpr std::array<std::string_view, (int)FluidToSlabHeatTransferType::Num> fluidToSlabHeatTransferTypeNamesUC = {"CONVECTIONONLY",
     177              :                                                                                                                         "ISOSTANDARD"};
     178              : 
     179              :     constexpr std::array<std::string_view, (int)CondCtrlType::Num> condCtrlTypeNamesUC = {"OFF", "SIMPLEOFF", "VARIABLEOFF"};
     180              : 
     181              :     constexpr std::array<std::string_view, (int)CircuitCalc::Num> circuitCalcNames = {"OnePerSurface", "CalculateFromCircuitLength"};
     182              :     constexpr std::array<std::string_view, (int)CircuitCalc::Num> circuitCalcNamesUC = {"ONEPERSURFACE", "CALCULATEFROMCIRCUITLENGTH"};
     183              : 
     184       666848 :     void SimLowTempRadiantSystem(EnergyPlusData &state,
     185              :                                  std::string_view CompName,     // name of the low temperature radiant system
     186              :                                  bool const FirstHVACIteration, // TRUE if 1st HVAC simulation of system timestep
     187              :                                  Real64 &LoadMet,               // load met by the radiant system, in Watts
     188              :                                  int &CompIndex)
     189              :     {
     190              : 
     191              :         // SUBROUTINE INFORMATION:
     192              :         //       AUTHOR         Rick Strand
     193              :         //       DATE WRITTEN   November 2000
     194              : 
     195              :         // Using/Aliasing
     196              : 
     197              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     198              :         int RadSysNum;         // Radiant system number/index in local derived types
     199              :         SystemType systemType; // Type of radiant system: hydronic, constant flow, or electric
     200       666848 :         bool InitErrorFound(false);
     201              : 
     202       666848 :         if (state.dataLowTempRadSys->GetInputFlag) {
     203           29 :             GetLowTempRadiantSystem(state);
     204           29 :             state.dataLowTempRadSys->GetInputFlag = false;
     205              :         }
     206              : 
     207              :         // Find the correct Low Temp Radiant System
     208       666848 :         if (CompIndex == 0) {
     209           82 :             RadSysNum = Util::FindItemInList(CompName, state.dataLowTempRadSys->RadSysTypes);
     210           82 :             if (RadSysNum == 0) {
     211            0 :                 ShowFatalError(state, format("SimLowTempRadiantSystem: Unit not found={}", CompName));
     212              :             }
     213           82 :             CompIndex = RadSysNum;
     214           82 :             systemType = state.dataLowTempRadSys->RadSysTypes(RadSysNum).systemType;
     215           82 :             switch (systemType) {
     216           46 :             case SystemType::Hydronic: {
     217           46 :                 state.dataLowTempRadSys->RadSysTypes(RadSysNum).CompIndex = Util::FindItemInList(CompName, state.dataLowTempRadSys->HydrRadSys);
     218           46 :             } break;
     219           27 :             case SystemType::ConstantFlow: {
     220           27 :                 state.dataLowTempRadSys->RadSysTypes(RadSysNum).CompIndex = Util::FindItemInList(CompName, state.dataLowTempRadSys->CFloRadSys);
     221           27 :             } break;
     222            9 :             case SystemType::Electric: {
     223            9 :                 state.dataLowTempRadSys->RadSysTypes(RadSysNum).CompIndex = Util::FindItemInList(CompName, state.dataLowTempRadSys->ElecRadSys);
     224            9 :             } break;
     225            0 :             default:
     226            0 :                 break;
     227              :             }
     228              :         } else {
     229       666766 :             RadSysNum = CompIndex;
     230       666766 :             systemType = state.dataLowTempRadSys->RadSysTypes(RadSysNum).systemType;
     231       666766 :             if (RadSysNum > state.dataLowTempRadSys->TotalNumOfRadSystems || RadSysNum < 1) {
     232            0 :                 ShowFatalError(state,
     233            0 :                                format("SimLowTempRadiantSystem:  Invalid CompIndex passed={}, Number of Units={}, Entered Unit name={}",
     234              :                                       RadSysNum,
     235            0 :                                       state.dataLowTempRadSys->TotalNumOfRadSystems,
     236              :                                       CompName));
     237              :             }
     238       666766 :             if (state.dataLowTempRadSys->CheckEquipName(RadSysNum)) {
     239           82 :                 if (CompName != state.dataLowTempRadSys->RadSysTypes(RadSysNum).Name) {
     240            0 :                     ShowFatalError(state,
     241            0 :                                    format("SimLowTempRadiantSystem: Invalid CompIndex passed={}, Unit name={}, stored Unit Name for that index={}",
     242              :                                           RadSysNum,
     243              :                                           CompName,
     244            0 :                                           state.dataLowTempRadSys->RadSysTypes(RadSysNum).Name));
     245              :                 }
     246           82 :                 state.dataLowTempRadSys->CheckEquipName(RadSysNum) = false;
     247              :             }
     248              :         }
     249              : 
     250       666848 :         InitLowTempRadiantSystem(state, FirstHVACIteration, state.dataLowTempRadSys->RadSysTypes(RadSysNum).CompIndex, systemType, InitErrorFound);
     251       666848 :         if (InitErrorFound) {
     252            0 :             ShowFatalError(state,
     253              :                            "InitLowTempRadiantSystem: Preceding error is not allowed to proceed with the simulation.  Correct this input problem.");
     254              :         }
     255              : 
     256              :         // Simulate, update, and report based on the type of radiant system
     257              :         {
     258              :             RadiantSystemBaseData *baseSystem;
     259       666848 :             if (systemType == SystemType::Hydronic) {
     260       366056 :                 baseSystem = &state.dataLowTempRadSys->HydrRadSys(state.dataLowTempRadSys->RadSysTypes(RadSysNum).CompIndex);
     261       300792 :             } else if (systemType == SystemType::ConstantFlow) {
     262       221733 :                 baseSystem = &state.dataLowTempRadSys->CFloRadSys(state.dataLowTempRadSys->RadSysTypes(RadSysNum).CompIndex);
     263        79059 :             } else if (systemType == SystemType::Electric) {
     264        79059 :                 baseSystem = &state.dataLowTempRadSys->ElecRadSys(state.dataLowTempRadSys->RadSysTypes(RadSysNum).CompIndex);
     265              :             } else {
     266            0 :                 ShowFatalError(state, format("SimLowTempRadiantSystem: Illegal system type for system {}", CompName));
     267              :             }
     268              : 
     269       666848 :             if ((systemType == SystemType::Hydronic) || (systemType == SystemType::ConstantFlow) || (systemType == SystemType::Electric)) {
     270       666848 :                 baseSystem->calculateLowTemperatureRadiantSystem(state, LoadMet);
     271       666848 :                 baseSystem->updateLowTemperatureRadiantSystemSurfaces(state);
     272       666848 :                 baseSystem->updateLowTemperatureRadiantSystem(state); // Nothing to update for electric systems
     273       666848 :                 baseSystem->reportLowTemperatureRadiantSystem(state);
     274              :             }
     275              :         }
     276       666848 :     }
     277              : 
     278           29 :     void GetLowTempRadiantSystem(EnergyPlusData &state)
     279              :     {
     280              : 
     281              :         // SUBROUTINE INFORMATION:
     282              :         //       AUTHOR         Rick Strand
     283              :         //       DATE WRITTEN   November 2000
     284              :         //       MODIFIED       August 2003 (added constant flow system, made input extensible)
     285              : 
     286              :         // PURPOSE OF THIS SUBROUTINE:
     287              :         // This subroutine reads the input for low temperature radiant systems
     288              :         // from the user input file.  This will contain all of the information
     289              :         // needed to simulate a low temperature radiant system.
     290              : 
     291              :         // Using/Aliasing
     292              :         using BranchNodeConnections::TestCompSet;
     293              :         using DataSizing::AutoSize;
     294              :         using DataSizing::CapacityPerFloorArea;
     295              :         using DataSizing::CoolingDesignCapacity;
     296              :         using DataSizing::FractionOfAutosizedCoolingCapacity;
     297              :         using DataSizing::FractionOfAutosizedHeatingCapacity;
     298              :         using DataSizing::HeatingDesignCapacity;
     299              : 
     300              :         using NodeInputManager::GetOnlySingleNode;
     301              :         using namespace DataLoopNode;
     302              :         using namespace DataSurfaceLists;
     303              : 
     304              :         // SUBROUTINE PARAMETER DEFINITIONS:
     305           29 :         constexpr std::string_view RoutineName("GetLowTempRadiantSystem: "); // include trailing blank space
     306           29 :         constexpr std::string_view routineName = "GetLowTempRadiantSystem";
     307              : 
     308           29 :         int constexpr iHeatCAPMAlphaNum(5);             // get input index to Low Temperature Radiant system heating capacity sizing method
     309           29 :         int constexpr iHeatDesignCapacityNumericNum(1); // get input index to Low Temperature Radiant system electric heating capacity
     310           29 :         int constexpr iHeatCapacityPerFloorAreaNumericNum(
     311              :             2); // get input index to Low Temperature Radiant system electric heating capacity per floor area sizing
     312           29 :         int constexpr iHeatFracOfAutosizedCapacityNumericNum(
     313              :             3); //  get input index to Low Temperature Radiant system electric heating capacity sizing as fraction of autosized heating capacity
     314              : 
     315              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     316           29 :         std::string CurrentModuleObject;       // for ease in getting objects
     317           29 :         Array1D_string Alphas;                 // Alpha items for object
     318           29 :         Array1D_string cAlphaFields;           // Alpha field names
     319           29 :         Array1D_string cNumericFields;         // Numeric field names
     320           29 :         Array1D_bool AssignedAsRadiantSurface; // Set to true when a surface is part of a radiant system
     321              :         int CheckSurfNum;                      // Surface number to check to see if it has already been used by a radiant system
     322           29 :         bool ErrorsFound(false);               // Set to true if errors in input, fatal at end of routine
     323              :         int IOStatus;                          // Used in GetObjectItem
     324              :         int Item;                              // Item to be "gotten"
     325              :         int MaxAlphas;                         // Maximum number of alphas for these input keywords
     326              :         int MaxNumbers;                        // Maximum number of numbers for these input keywords
     327           29 :         Array1D<Real64> Numbers;               // Numeric items for object
     328              :         int NumAlphas;                         // Number of Alphas for each GetObjectItem call
     329              :         int NumArgs;                           // Unused variable that is part of a subroutine call
     330              :         int NumNumbers;                        // Number of Numbers for each GetObjectItem call
     331              :         int SurfListNum;                       // Index within the SurfList derived type for a surface list name
     332              :         int SurfNum;                           // DO loop counter for surfaces
     333              :         int BaseNum;                           // Temporary number for creating RadiantSystemTypes structure
     334           29 :         Array1D_bool lAlphaBlanks;             // Logical array, alpha field input BLANK = .TRUE.
     335           29 :         Array1D_bool lNumericBlanks;           // Logical array, numeric field input BLANK = .TRUE.
     336              : 
     337           29 :         auto &Zone = state.dataHeatBal->Zone;
     338           29 :         auto &Surface = state.dataSurface->Surface;
     339              : 
     340           29 :         Array1D_string VarFlowRadDesignNames;
     341           29 :         Array1D_string CFlowRadDesignNames;
     342              : 
     343           29 :         MaxAlphas = 0;
     344           29 :         MaxNumbers = 0;
     345              : 
     346           29 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
     347              :             state, "ZoneHVAC:LowTemperatureRadiant:VariableFlow:Design", NumArgs, NumAlphas, NumNumbers);
     348           29 :         MaxAlphas = max(MaxAlphas, NumAlphas);
     349           29 :         MaxNumbers = max(MaxNumbers, NumNumbers);
     350              : 
     351           29 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
     352              :             state, "ZoneHVAC:LowTemperatureRadiant:ConstantFlow:Design", NumArgs, NumAlphas, NumNumbers);
     353           29 :         MaxAlphas = max(MaxAlphas, NumAlphas);
     354           29 :         MaxNumbers = max(MaxNumbers, NumNumbers);
     355              : 
     356           29 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
     357              :             state, "ZoneHVAC:LowTemperatureRadiant:VariableFlow", NumArgs, NumAlphas, NumNumbers);
     358           29 :         MaxAlphas = max(MaxAlphas, NumAlphas);
     359           29 :         MaxNumbers = max(MaxNumbers, NumNumbers);
     360              : 
     361           29 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
     362              :             state, "ZoneHVAC:LowTemperatureRadiant:ConstantFlow", NumArgs, NumAlphas, NumNumbers);
     363           29 :         MaxAlphas = max(MaxAlphas, NumAlphas);
     364           29 :         MaxNumbers = max(MaxNumbers, NumNumbers);
     365              : 
     366           29 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
     367              :             state, "ZoneHVAC:LowTemperatureRadiant:Electric", NumArgs, NumAlphas, NumNumbers);
     368           29 :         MaxAlphas = max(MaxAlphas, NumAlphas);
     369           29 :         MaxNumbers = max(MaxNumbers, NumNumbers);
     370              : 
     371           29 :         Alphas.allocate(MaxAlphas);
     372           29 :         Numbers.dimension(MaxNumbers, 0.0);
     373           29 :         cAlphaFields.allocate(MaxAlphas);
     374           29 :         cNumericFields.allocate(MaxNumbers);
     375           29 :         lAlphaBlanks.dimension(MaxAlphas, true);
     376           29 :         lNumericBlanks.dimension(MaxNumbers, true);
     377              : 
     378           58 :         state.dataLowTempRadSys->NumOfHydrLowTempRadSys =
     379           29 :             state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneHVAC:LowTemperatureRadiant:VariableFlow");
     380           58 :         state.dataLowTempRadSys->NumOfCFloLowTempRadSys =
     381           29 :             state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneHVAC:LowTemperatureRadiant:ConstantFlow");
     382           58 :         state.dataLowTempRadSys->NumOfElecLowTempRadSys =
     383           29 :             state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneHVAC:LowTemperatureRadiant:Electric");
     384              : 
     385           58 :         state.dataLowTempRadSys->NumOfHydrLowTempRadSysDes =
     386           29 :             state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneHVAC:LowTemperatureRadiant:VariableFlow:Design");
     387           58 :         state.dataLowTempRadSys->NumOfCFloLowTempRadSysDes =
     388           29 :             state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneHVAC:LowTemperatureRadiant:ConstantFlow:Design");
     389              : 
     390           29 :         state.dataLowTempRadSys->TotalNumOfRadSystems = state.dataLowTempRadSys->NumOfHydrLowTempRadSys +
     391           29 :                                                         state.dataLowTempRadSys->NumOfElecLowTempRadSys +
     392           29 :                                                         state.dataLowTempRadSys->NumOfCFloLowTempRadSys;
     393           29 :         state.dataLowTempRadSys->RadSysTypes.allocate(state.dataLowTempRadSys->TotalNumOfRadSystems);
     394           29 :         state.dataLowTempRadSys->LowTempRadUniqueNames.reserve(static_cast<unsigned>(state.dataLowTempRadSys->TotalNumOfRadSystems));
     395           29 :         state.dataLowTempRadSys->CheckEquipName.dimension(state.dataLowTempRadSys->TotalNumOfRadSystems, true);
     396              : 
     397           29 :         state.dataLowTempRadSys->HydrRadSys.allocate(state.dataLowTempRadSys->NumOfHydrLowTempRadSys);
     398           29 :         if (state.dataLowTempRadSys->NumOfHydrLowTempRadSys > 0) {
     399           17 :             auto *water = Fluid::GetWater(state);
     400           17 :             if (water == nullptr) {
     401            0 :                 ShowSevereError(state, "Hydronic radiant systems: no water property data found in input");
     402            0 :                 ErrorsFound = true;
     403              :             }
     404              : 
     405           63 :             for (auto &e : state.dataLowTempRadSys->HydrRadSys) {
     406           46 :                 e.water = water;
     407              :             }
     408              :         }
     409              : 
     410           29 :         state.dataLowTempRadSys->CFloRadSys.allocate(state.dataLowTempRadSys->NumOfCFloLowTempRadSys);
     411           29 :         if (state.dataLowTempRadSys->NumOfCFloLowTempRadSys > 0) {
     412            9 :             auto *water = Fluid::GetWater(state);
     413            9 :             if (water == nullptr) {
     414            0 :                 ShowSevereError(state, "Constant flow radiant systems: no water property data found in input");
     415            0 :                 ErrorsFound = true;
     416              :             }
     417              : 
     418           36 :             for (auto &e : state.dataLowTempRadSys->CFloRadSys) {
     419           27 :                 e.water = water;
     420              :             }
     421              :         }
     422              : 
     423           29 :         state.dataLowTempRadSys->ElecRadSys.allocate(state.dataLowTempRadSys->NumOfElecLowTempRadSys);
     424           29 :         state.dataLowTempRadSys->ElecRadSysNumericFields.allocate(state.dataLowTempRadSys->NumOfElecLowTempRadSys);
     425              : 
     426           29 :         state.dataLowTempRadSys->HydronicRadiantSysNumericFields.allocate(state.dataLowTempRadSys->NumOfHydrLowTempRadSys);
     427           29 :         state.dataLowTempRadSys->HydronicRadiantSysDesign.allocate(state.dataLowTempRadSys->NumOfHydrLowTempRadSysDes);
     428           29 :         VarFlowRadDesignNames.allocate(state.dataLowTempRadSys->NumOfHydrLowTempRadSysDes);
     429              : 
     430           29 :         state.dataLowTempRadSys->CflowRadiantSysDesign.allocate(state.dataLowTempRadSys->NumOfCFloLowTempRadSysDes);
     431           29 :         CFlowRadDesignNames.allocate(state.dataLowTempRadSys->NumOfCFloLowTempRadSysDes);
     432              : 
     433              :         // make sure data is gotten for surface lists
     434           29 :         GetNumberOfSurfaceLists(state);
     435              : 
     436              :         // Obtain all of the design data related to hydronic low temperature radiant systems...
     437           29 :         CurrentModuleObject = "ZoneHVAC:LowTemperatureRadiant:VariableFlow:Design";
     438           60 :         for (Item = 1; Item <= state.dataLowTempRadSys->NumOfHydrLowTempRadSysDes; ++Item) {
     439              : 
     440           31 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     441              :                                                                      CurrentModuleObject,
     442              :                                                                      Item,
     443              :                                                                      Alphas,
     444              :                                                                      NumAlphas,
     445              :                                                                      Numbers,
     446              :                                                                      NumNumbers,
     447              :                                                                      IOStatus,
     448              :                                                                      lNumericBlanks,
     449              :                                                                      lAlphaBlanks,
     450              :                                                                      cAlphaFields,
     451              :                                                                      cNumericFields);
     452              : 
     453           31 :             ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
     454              : 
     455           31 :             state.dataLowTempRadSys->HydronicRadiantSysDesign(Item).FieldNames.allocate(NumNumbers);
     456           31 :             state.dataLowTempRadSys->HydronicRadiantSysDesign(Item).FieldNames = "";
     457           31 :             state.dataLowTempRadSys->HydronicRadiantSysDesign(Item).FieldNames = cNumericFields;
     458           31 :             GlobalNames::VerifyUniqueInterObjectName(
     459           62 :                 state, state.dataLowTempRadSys->LowTempRadUniqueNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
     460              : 
     461           31 :             auto &thisRadSysDesign = state.dataLowTempRadSys->HydronicRadiantSysDesign(Item);
     462              : 
     463              :             // General user input data
     464           31 :             thisRadSysDesign.designName = Alphas(1);
     465              : 
     466           31 :             if (lAlphaBlanks(2)) {
     467            0 :                 thisRadSysDesign.FluidToSlabHeatTransfer = FluidToSlabHeatTransferType::ConvectionOnly;
     468           31 :             } else if ((thisRadSysDesign.FluidToSlabHeatTransfer = static_cast<FluidToSlabHeatTransferType>(
     469           31 :                             getEnumValue(fluidToSlabHeatTransferTypeNamesUC, Alphas(2)))) == FluidToSlabHeatTransferType::Invalid) {
     470            0 :                 ShowWarningInvalidKey(state, eoh, cAlphaFields(2), Alphas(2), "ConvectionOnly");
     471            0 :                 thisRadSysDesign.FluidToSlabHeatTransfer = FluidToSlabHeatTransferType::ConvectionOnly;
     472              :             }
     473              : 
     474           31 :             thisRadSysDesign.TubeDiameterInner = Numbers(1);
     475           31 :             thisRadSysDesign.TubeDiameterOuter = Numbers(2);
     476              : 
     477           31 :             thisRadSysDesign.VarFlowTubeConductivity = Numbers(3);
     478              : 
     479              :             // Process the temperature control type
     480           31 :             if (lAlphaBlanks(3)) {
     481            0 :                 thisRadSysDesign.VarFlowControlType = CtrlType::MAT;
     482           31 :             } else if ((thisRadSysDesign.VarFlowControlType = static_cast<CtrlType>(getEnumValue(ctrlTypeNamesUC, Alphas(3)))) == CtrlType::Invalid) {
     483            0 :                 ShowWarningInvalidKey(state, eoh, cAlphaFields(3), Alphas(3), "MeanAirTemperature");
     484            0 :                 thisRadSysDesign.VarFlowControlType = CtrlType::MAT;
     485              :             }
     486              : 
     487              :             // Process the setpoint type
     488           31 :             if (lAlphaBlanks(4)) {
     489            0 :                 thisRadSysDesign.VarFlowSetpointType = SetpointType::HalfFlowPower;
     490           31 :             } else if ((thisRadSysDesign.VarFlowSetpointType = static_cast<SetpointType>(getEnumValue(setpointTypeNamesUC, Alphas(4)))) ==
     491              :                        SetpointType::Invalid) {
     492            0 :                 ShowWarningInvalidKey(state, eoh, cAlphaFields(4), Alphas(4), "HalfFlowPower");
     493            0 :                 thisRadSysDesign.VarFlowSetpointType = SetpointType::HalfFlowPower;
     494              :             }
     495              : 
     496              :             // Refactor everything below to Alphas as HCMethod, etc
     497              : 
     498              :             // Determine Low Temp Radiant heating design capacity sizing method
     499           31 :             thisRadSysDesign.DesignHeatingCapMethodInput = Alphas(5);
     500           31 :             if (Util::SameString(thisRadSysDesign.DesignHeatingCapMethodInput, "HeatingDesignCapacity")) {
     501           29 :                 thisRadSysDesign.DesignHeatingCapMethod = HeatingDesignCapacity;
     502            2 :             } else if (Util::SameString(thisRadSysDesign.DesignHeatingCapMethodInput, "CapacityPerFloorArea")) {
     503            1 :                 thisRadSysDesign.DesignHeatingCapMethod = CapacityPerFloorArea;
     504            1 :                 if (!lNumericBlanks(4)) {
     505            1 :                     thisRadSysDesign.DesignScaledHeatingCapacity = Numbers(4);
     506            1 :                     if (thisRadSysDesign.DesignScaledHeatingCapacity <= 0.0) {
     507            0 :                         ShowSevereError(state, format("{} = {}", CurrentModuleObject, thisRadSysDesign.designName));
     508            0 :                         ShowContinueError(state, format("Input for {} = {}", cAlphaFields(5), thisRadSysDesign.DesignHeatingCapMethodInput));
     509            0 :                         ShowContinueError(state, format("Illegal {} = {:.7T}", cNumericFields(4), Numbers(4)));
     510            0 :                         ErrorsFound = true;
     511            1 :                     } else if (thisRadSysDesign.DesignScaledHeatingCapacity == AutoSize) {
     512            0 :                         ShowSevereError(state, format("{} = {}", CurrentModuleObject, thisRadSysDesign.designName));
     513            0 :                         ShowContinueError(state, format("Input for {} = {}", cAlphaFields(5), thisRadSysDesign.DesignHeatingCapMethodInput));
     514            0 :                         ShowContinueError(state, format("Illegal {} = Autosize", cNumericFields(4)));
     515            0 :                         ErrorsFound = true;
     516              :                     }
     517              :                 } else {
     518            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, thisRadSysDesign.Name));
     519            0 :                     ShowContinueError(state, format("Input for {} = {}", cAlphaFields(5), thisRadSysDesign.DesignHeatingCapMethodInput));
     520            0 :                     ShowContinueError(state, format("Blank field not allowed for {}", cNumericFields(4)));
     521            0 :                     ErrorsFound = true;
     522              :                 }
     523            1 :             } else if (Util::SameString(thisRadSysDesign.DesignHeatingCapMethodInput, "FractionOfAutosizedHeatingCapacity")) {
     524            1 :                 thisRadSysDesign.DesignHeatingCapMethod = FractionOfAutosizedHeatingCapacity;
     525            1 :                 if (!lNumericBlanks(5)) {
     526            1 :                     thisRadSysDesign.DesignScaledHeatingCapacity = Numbers(5);
     527            1 :                     if (thisRadSysDesign.DesignScaledHeatingCapacity < 0.0) {
     528            0 :                         ShowSevereError(state, format("{} = {}", CurrentModuleObject, thisRadSysDesign.designName));
     529            0 :                         ShowContinueError(state, format("Illegal {} = {:.7T}", cNumericFields(5), Numbers(5)));
     530            0 :                         ErrorsFound = true;
     531              :                     }
     532              :                 } else {
     533            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, thisRadSysDesign.designName));
     534            0 :                     ShowContinueError(state, format("Input for {} = {}", cAlphaFields(5), thisRadSysDesign.DesignHeatingCapMethodInput));
     535            0 :                     ShowContinueError(state, format("Blank field not allowed for {}", cNumericFields(5)));
     536            0 :                     ErrorsFound = true;
     537              :                 }
     538              :             } else {
     539            0 :                 ShowSevereError(state, format("{} = {}", CurrentModuleObject, thisRadSysDesign.designName));
     540            0 :                 ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(5), thisRadSysDesign.DesignHeatingCapMethodInput));
     541            0 :                 ErrorsFound = true;
     542              :             }
     543              : 
     544           31 :             thisRadSysDesign.HotThrottlRange = Numbers(6);
     545              : 
     546           31 :             if (lAlphaBlanks(6)) {
     547           31 :             } else if ((thisRadSysDesign.heatSetptSched = Sched::GetSchedule(state, Alphas(6))) == nullptr) {
     548            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(6), Alphas(6));
     549            0 :                 ErrorsFound = true;
     550              :             }
     551              : 
     552              :             // Determine Low Temp Radiant cooling design capacity sizing method
     553           31 :             thisRadSysDesign.DesignCoolingCapMethodInput = Alphas(7);
     554           31 :             if (Util::SameString(thisRadSysDesign.DesignCoolingCapMethodInput, "CoolingDesignCapacity")) {
     555           29 :                 thisRadSysDesign.DesignCoolingCapMethod = CoolingDesignCapacity;
     556            2 :             } else if (Util::SameString(thisRadSysDesign.DesignCoolingCapMethodInput, "CapacityPerFloorArea")) {
     557            1 :                 thisRadSysDesign.DesignCoolingCapMethod = CapacityPerFloorArea;
     558            1 :                 if (!lNumericBlanks(7)) {
     559            1 :                     thisRadSysDesign.DesignScaledCoolingCapacity = Numbers(7);
     560            1 :                     if (thisRadSysDesign.DesignScaledCoolingCapacity <= 0.0) {
     561            0 :                         ShowSevereError(state, format("{} = {}", CurrentModuleObject, thisRadSysDesign.designName));
     562            0 :                         ShowContinueError(state, format("Input for {} = {}", cAlphaFields(7), thisRadSysDesign.DesignCoolingCapMethodInput));
     563            0 :                         ShowContinueError(state, format("Illegal {} = {:.7T}", cNumericFields(7), thisRadSysDesign.DesignScaledCoolingCapacity));
     564            0 :                         ErrorsFound = true;
     565            1 :                     } else if (thisRadSysDesign.DesignScaledCoolingCapacity == AutoSize) {
     566            0 :                         ShowSevereError(state, format("{} = {}", CurrentModuleObject, thisRadSysDesign.designName));
     567            0 :                         ShowContinueError(state, format("Input for {} = {}", cAlphaFields(7), thisRadSysDesign.DesignCoolingCapMethodInput));
     568            0 :                         ShowContinueError(state, format("Illegal {} = Autosize", cNumericFields(7)));
     569            0 :                         ErrorsFound = true;
     570              :                     }
     571              :                 } else {
     572            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, thisRadSysDesign.designName));
     573            0 :                     ShowContinueError(state, format("Input for {} = {}", cAlphaFields(7), thisRadSysDesign.DesignCoolingCapMethodInput));
     574            0 :                     ShowContinueError(state, format("Blank field not allowed for {}", cNumericFields(7)));
     575            0 :                     ErrorsFound = true;
     576              :                 }
     577            1 :             } else if (Util::SameString(thisRadSysDesign.DesignCoolingCapMethodInput, "FractionOfAutosizedCoolingCapacity")) {
     578            1 :                 thisRadSysDesign.DesignCoolingCapMethod = FractionOfAutosizedCoolingCapacity;
     579            1 :                 if (!lNumericBlanks(8)) {
     580            1 :                     thisRadSysDesign.DesignScaledCoolingCapacity = Numbers(8);
     581            1 :                     if (thisRadSysDesign.DesignScaledCoolingCapacity < 0.0) {
     582            0 :                         ShowSevereError(state, format("{} = {}", CurrentModuleObject, thisRadSysDesign.designName));
     583            0 :                         ShowContinueError(state, format("Illegal {} = {:.7T}", cNumericFields(8), Numbers(8)));
     584            0 :                         ErrorsFound = true;
     585              :                     }
     586              :                 } else {
     587            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, thisRadSysDesign.designName));
     588            0 :                     ShowContinueError(state, format("Input for {} = {}", cAlphaFields(7), thisRadSysDesign.DesignCoolingCapMethodInput));
     589            0 :                     ShowContinueError(state, format("Blank field not allowed for {}", cNumericFields(8)));
     590            0 :                     ErrorsFound = true;
     591              :                 }
     592              :             } else {
     593            0 :                 ShowSevereError(state, format("{} = {}", CurrentModuleObject, thisRadSysDesign.designName));
     594            0 :                 ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(7), thisRadSysDesign.DesignCoolingCapMethodInput));
     595            0 :                 ErrorsFound = true;
     596              :             }
     597              : 
     598           31 :             thisRadSysDesign.ColdThrottlRange = Numbers(9);
     599              : 
     600           31 :             if (lAlphaBlanks(8)) {
     601           30 :             } else if ((thisRadSysDesign.coolSetptSched = Sched::GetSchedule(state, Alphas(8))) == nullptr) {
     602            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(8), Alphas(8));
     603            0 :                 ErrorsFound = true;
     604              :             }
     605              : 
     606           31 :             if (lAlphaBlanks(9)) {
     607           17 :                 thisRadSysDesign.condCtrlType = CondCtrlType::SimpleOff;
     608           14 :             } else if ((thisRadSysDesign.condCtrlType = static_cast<CondCtrlType>(getEnumValue(condCtrlTypeNamesUC, Alphas(9)))) ==
     609              :                        CondCtrlType::Invalid) {
     610            0 :                 ShowWarningInvalidKey(state, eoh, cAlphaFields(9), Alphas(9), "SimpleOff");
     611            0 :                 thisRadSysDesign.condCtrlType = CondCtrlType::SimpleOff;
     612              :             }
     613              : 
     614           31 :             thisRadSysDesign.CondDewPtDeltaT = Numbers(10);
     615              : 
     616           31 :             if (lAlphaBlanks(10)) {
     617            3 :             } else if ((thisRadSysDesign.changeoverDelaySched = Sched::GetSchedule(state, Alphas(10))) == nullptr) {
     618            0 :                 ShowWarningItemNotFound(state, eoh, cAlphaFields(10), Alphas(10), "No changeover delay will be used for this radiant system.");
     619              :             }
     620              : 
     621           31 :             VarFlowRadDesignNames(Item) = Alphas(1);
     622              :         }
     623              : 
     624              :         // Obtain all of the user data related to hydronic low temperature radiant systems...
     625           29 :         BaseNum = 0;
     626           29 :         CurrentModuleObject = "ZoneHVAC:LowTemperatureRadiant:VariableFlow";
     627           75 :         for (Item = 1; Item <= state.dataLowTempRadSys->NumOfHydrLowTempRadSys; ++Item) {
     628              : 
     629           46 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     630              :                                                                      CurrentModuleObject,
     631              :                                                                      Item,
     632              :                                                                      Alphas,
     633              :                                                                      NumAlphas,
     634              :                                                                      Numbers,
     635              :                                                                      NumNumbers,
     636              :                                                                      IOStatus,
     637              :                                                                      lNumericBlanks,
     638              :                                                                      lAlphaBlanks,
     639              :                                                                      cAlphaFields,
     640              :                                                                      cNumericFields);
     641              : 
     642           46 :             ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
     643              : 
     644           46 :             state.dataLowTempRadSys->HydronicRadiantSysNumericFields(Item).FieldNames.allocate(NumNumbers);
     645           46 :             state.dataLowTempRadSys->HydronicRadiantSysNumericFields(Item).FieldNames = "";
     646           46 :             state.dataLowTempRadSys->HydronicRadiantSysNumericFields(Item).FieldNames = cNumericFields;
     647           46 :             GlobalNames::VerifyUniqueInterObjectName(
     648           92 :                 state, state.dataLowTempRadSys->LowTempRadUniqueNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
     649              : 
     650           46 :             ++BaseNum;
     651           46 :             state.dataLowTempRadSys->RadSysTypes(BaseNum).Name = Alphas(1);
     652           46 :             state.dataLowTempRadSys->RadSysTypes(BaseNum).systemType = SystemType::Hydronic;
     653              : 
     654           46 :             auto &thisRadSys = state.dataLowTempRadSys->HydrRadSys(Item);
     655              : 
     656              :             // General user input data
     657           46 :             thisRadSys.Name = Alphas(1);
     658              : 
     659           46 :             thisRadSys.designObjectName = Alphas(2);
     660           46 :             thisRadSys.DesignObjectPtr = Util::FindItemInList(thisRadSys.designObjectName, VarFlowRadDesignNames);
     661           46 :             VarFlowRadDesignData variableFlowDesignDataObject{state.dataLowTempRadSys->HydronicRadiantSysDesign(
     662           46 :                 thisRadSys.DesignObjectPtr)}; // Contains the data for variable flow hydronic systems
     663              : 
     664           46 :             if (lAlphaBlanks(3)) {
     665            0 :                 thisRadSys.availSched = Sched::GetScheduleAlwaysOn(state);
     666           46 :             } else if ((thisRadSys.availSched = Sched::GetSchedule(state, Alphas(3))) == nullptr) {
     667            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(3), Alphas(3));
     668            0 :                 ErrorsFound = true;
     669              :             }
     670              : 
     671           46 :             thisRadSys.ZoneName = Alphas(4);
     672           46 :             thisRadSys.ZonePtr = Util::FindItemInList(Alphas(4), Zone);
     673           46 :             if (thisRadSys.ZonePtr == 0) {
     674            0 :                 ShowSevereError(state, format("{}Invalid {} = {}", RoutineName, cAlphaFields(3), Alphas(4)));
     675            0 :                 ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, Alphas(1)));
     676            0 :                 ErrorsFound = true;
     677              :             }
     678              : 
     679           46 :             thisRadSys.SurfListName = Alphas(5);
     680           46 :             SurfListNum = 0;
     681           46 :             if (state.dataSurfLists->NumOfSurfaceLists > 0) {
     682            4 :                 SurfListNum = Util::FindItemInList(thisRadSys.SurfListName, state.dataSurfLists->SurfList);
     683              :             }
     684           46 :             if (SurfListNum > 0) { // Found a valid surface list
     685            3 :                 thisRadSys.NumOfSurfaces = state.dataSurfLists->SurfList(SurfListNum).NumOfSurfaces;
     686            3 :                 thisRadSys.SurfacePtr.allocate(thisRadSys.NumOfSurfaces);
     687            3 :                 thisRadSys.SurfaceName.allocate(thisRadSys.NumOfSurfaces);
     688            3 :                 thisRadSys.SurfaceFrac.allocate(thisRadSys.NumOfSurfaces);
     689            3 :                 thisRadSys.NumCircuits.allocate(thisRadSys.NumOfSurfaces);
     690           18 :                 for (SurfNum = 1; SurfNum <= state.dataSurfLists->SurfList(SurfListNum).NumOfSurfaces; ++SurfNum) {
     691           15 :                     thisRadSys.SurfacePtr(SurfNum) = state.dataSurfLists->SurfList(SurfListNum).SurfPtr(SurfNum);
     692           15 :                     thisRadSys.SurfaceName(SurfNum) = state.dataSurfLists->SurfList(SurfListNum).SurfName(SurfNum);
     693           15 :                     thisRadSys.SurfaceFrac(SurfNum) = state.dataSurfLists->SurfList(SurfListNum).SurfFlowFrac(SurfNum);
     694           15 :                     if (thisRadSys.SurfacePtr(SurfNum) > 0) {
     695           15 :                         state.dataSurface->surfIntConv(thisRadSys.SurfacePtr(SurfNum)).hasActiveInIt = true;
     696              :                     }
     697              :                 }
     698              :             } else { // User entered a single surface name rather than a surface list
     699           43 :                 thisRadSys.NumOfSurfaces = 1;
     700           43 :                 thisRadSys.SurfacePtr.allocate(thisRadSys.NumOfSurfaces);
     701           43 :                 thisRadSys.SurfaceName.allocate(thisRadSys.NumOfSurfaces);
     702           43 :                 thisRadSys.SurfaceFrac.allocate(thisRadSys.NumOfSurfaces);
     703           43 :                 thisRadSys.NumCircuits.allocate(thisRadSys.NumOfSurfaces);
     704           43 :                 thisRadSys.SurfaceName(1) = thisRadSys.SurfListName;
     705           43 :                 thisRadSys.SurfacePtr(1) = Util::FindItemInList(thisRadSys.SurfaceName(1), Surface);
     706           43 :                 thisRadSys.SurfaceFrac(1) = 1.0;
     707           43 :                 thisRadSys.NumCircuits(1) = 0.0;
     708              :                 // Error checking for single surfaces
     709           43 :                 if (thisRadSys.SurfacePtr(1) == 0) {
     710            0 :                     ShowSevereError(state, format("{}Invalid {} = {}", RoutineName, cAlphaFields(5), Alphas(5)));
     711            0 :                     ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, Alphas(1)));
     712            0 :                     ErrorsFound = true;
     713           43 :                 } else if (state.dataSurface->SurfIsRadSurfOrVentSlabOrPool(thisRadSys.SurfacePtr(1))) {
     714            0 :                     ShowSevereError(state, format("{}{}=\"{}\", Invalid Surface", RoutineName, CurrentModuleObject, Alphas(1)));
     715            0 :                     ShowContinueError(state,
     716            0 :                                       format("{}=\"{}\" has been used in another radiant system or ventilated slab.", cAlphaFields(5), Alphas(5)));
     717            0 :                     ErrorsFound = true;
     718              :                 }
     719           43 :                 if (thisRadSys.SurfacePtr(1) != 0) {
     720           43 :                     state.dataSurface->surfIntConv(thisRadSys.SurfacePtr(1)).hasActiveInIt = true;
     721           43 :                     state.dataSurface->surfIntConv(thisRadSys.SurfacePtr(1)).hasActiveInIt = true; // Ummmm ... what?
     722              :                 }
     723              :             }
     724              : 
     725              :             // Error checking for zones and construction information
     726           46 :             thisRadSys.errorCheckZonesAndConstructions(state, ErrorsFound);
     727              : 
     728           46 :             thisRadSys.TubeLength = Numbers(1);
     729              : 
     730              :             // Determine Low Temp Radiant heating design capacity sizing method
     731           46 :             if (variableFlowDesignDataObject.DesignHeatingCapMethod == HeatingDesignCapacity) {
     732           44 :                 thisRadSys.HeatingCapMethod = HeatingDesignCapacity;
     733           44 :                 if (!lNumericBlanks(2)) {
     734           44 :                     thisRadSys.ScaledHeatingCapacity = Numbers(2);
     735           44 :                     if (thisRadSys.ScaledHeatingCapacity < 0.0 && thisRadSys.ScaledHeatingCapacity != AutoSize) {
     736            0 :                         ShowSevereError(state, format("{} = {}", CurrentModuleObject, thisRadSys.Name));
     737            0 :                         ShowContinueError(state, format("Illegal {} = {:.7T}", cNumericFields(2), Numbers(2)));
     738            0 :                         ErrorsFound = true;
     739              :                     }
     740              :                 } else {
     741            0 :                     if ((!lAlphaBlanks(6)) || (!lAlphaBlanks(7))) {
     742            0 :                         ShowSevereError(state, format("{} = {}", CurrentModuleObject, thisRadSys.Name));
     743            0 :                         ShowContinueError(state, "Input for Heating Design Capacity Method = HeatingDesignCapacity");
     744            0 :                         ShowContinueError(state, format("Blank field not allowed for {}", cNumericFields(2)));
     745            0 :                         ErrorsFound = true;
     746              :                     }
     747              :                 }
     748            2 :             } else if (variableFlowDesignDataObject.DesignHeatingCapMethod == CapacityPerFloorArea) {
     749            1 :                 thisRadSys.HeatingCapMethod = CapacityPerFloorArea;
     750            1 :                 thisRadSys.ScaledHeatingCapacity = variableFlowDesignDataObject.DesignScaledHeatingCapacity;
     751            1 :             } else if (variableFlowDesignDataObject.DesignHeatingCapMethod == FractionOfAutosizedHeatingCapacity) {
     752            1 :                 thisRadSys.HeatingCapMethod = FractionOfAutosizedHeatingCapacity;
     753            1 :                 thisRadSys.ScaledHeatingCapacity = variableFlowDesignDataObject.DesignScaledHeatingCapacity;
     754              :             }
     755              : 
     756              :             // Heating user input data
     757           46 :             thisRadSys.WaterVolFlowMaxHeat = Numbers(3);
     758              : 
     759           46 :             thisRadSys.HotWaterInNode = GetOnlySingleNode(state,
     760           46 :                                                           Alphas(6),
     761              :                                                           ErrorsFound,
     762              :                                                           DataLoopNode::ConnectionObjectType::ZoneHVACLowTemperatureRadiantVariableFlow,
     763           46 :                                                           Alphas(1),
     764              :                                                           DataLoopNode::NodeFluidType::Water,
     765              :                                                           DataLoopNode::ConnectionType::Inlet,
     766              :                                                           NodeInputManager::CompFluidStream::Primary,
     767              :                                                           ObjectIsNotParent);
     768              : 
     769           46 :             thisRadSys.HotWaterOutNode = GetOnlySingleNode(state,
     770           46 :                                                            Alphas(7),
     771              :                                                            ErrorsFound,
     772              :                                                            DataLoopNode::ConnectionObjectType::ZoneHVACLowTemperatureRadiantVariableFlow,
     773           46 :                                                            Alphas(1),
     774              :                                                            DataLoopNode::NodeFluidType::Water,
     775              :                                                            DataLoopNode::ConnectionType::Outlet,
     776              :                                                            NodeInputManager::CompFluidStream::Primary,
     777              :                                                            ObjectIsNotParent);
     778              : 
     779           46 :             if ((!lAlphaBlanks(6)) || (!lAlphaBlanks(7))) {
     780           92 :                 TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(6), Alphas(7), "Hot Water Nodes");
     781              :             }
     782           52 :             if ((thisRadSys.WaterVolFlowMaxHeat == AutoSize) &&
     783            6 :                 (lAlphaBlanks(6) || lAlphaBlanks(7) || (thisRadSys.HotWaterInNode <= 0) || (thisRadSys.HotWaterOutNode <= 0) ||
     784            6 :                  (variableFlowDesignDataObject.heatSetptSched == nullptr))) {
     785            0 :                 ShowSevereError(state, "Hydronic radiant systems may not be autosized without specification of nodes or schedules.");
     786            0 :                 ShowContinueError(state, format("Occurs in {} (heating input) = {}", CurrentModuleObject, Alphas(1)));
     787            0 :                 ErrorsFound = true;
     788              :             }
     789              : 
     790              :             // Determine Low Temp Radiant cooling design capacity sizing method
     791           46 :             if (variableFlowDesignDataObject.DesignCoolingCapMethod == CoolingDesignCapacity) {
     792           44 :                 thisRadSys.CoolingCapMethod = CoolingDesignCapacity;
     793           44 :                 if (!lNumericBlanks(4)) {
     794           44 :                     thisRadSys.ScaledCoolingCapacity = Numbers(4);
     795           44 :                     if (thisRadSys.ScaledCoolingCapacity < 0.0 && thisRadSys.ScaledCoolingCapacity != AutoSize) {
     796            0 :                         ShowSevereError(state, format("{} = {}", CurrentModuleObject, thisRadSys.Name));
     797            0 :                         ShowContinueError(state, format("Illegal {} = {:.7T}", cNumericFields(4), Numbers(4)));
     798            0 :                         ErrorsFound = true;
     799              :                     }
     800              :                 } else {
     801            0 :                     if ((!lAlphaBlanks(8)) || (!lAlphaBlanks(9))) {
     802            0 :                         ShowSevereError(state, format("{} = {}", CurrentModuleObject, thisRadSys.Name));
     803            0 :                         ShowContinueError(state, "Input for Cooling Design Capacity Method = CoolingDesignCapacity");
     804            0 :                         ShowContinueError(state, format("Blank field not allowed for {}", cNumericFields(4)));
     805            0 :                         ErrorsFound = true;
     806              :                     }
     807              :                 }
     808            2 :             } else if (variableFlowDesignDataObject.DesignCoolingCapMethod == CapacityPerFloorArea) {
     809            1 :                 thisRadSys.CoolingCapMethod = CapacityPerFloorArea;
     810            1 :                 thisRadSys.ScaledCoolingCapacity = variableFlowDesignDataObject.DesignScaledCoolingCapacity;
     811            1 :             } else if (variableFlowDesignDataObject.DesignCoolingCapMethod == FractionOfAutosizedCoolingCapacity) {
     812            1 :                 thisRadSys.CoolingCapMethod = FractionOfAutosizedCoolingCapacity;
     813            1 :                 thisRadSys.ScaledCoolingCapacity = variableFlowDesignDataObject.DesignScaledCoolingCapacity;
     814              :             }
     815              : 
     816              :             // Cooling user input data
     817           46 :             thisRadSys.WaterVolFlowMaxCool = Numbers(5);
     818              : 
     819           46 :             thisRadSys.ColdWaterInNode = GetOnlySingleNode(state,
     820           46 :                                                            Alphas(8),
     821              :                                                            ErrorsFound,
     822              :                                                            DataLoopNode::ConnectionObjectType::ZoneHVACLowTemperatureRadiantVariableFlow,
     823           46 :                                                            Alphas(1),
     824              :                                                            DataLoopNode::NodeFluidType::Water,
     825              :                                                            DataLoopNode::ConnectionType::Inlet,
     826              :                                                            NodeInputManager::CompFluidStream::Secondary,
     827              :                                                            ObjectIsNotParent);
     828              : 
     829           46 :             thisRadSys.ColdWaterOutNode = GetOnlySingleNode(state,
     830           46 :                                                             Alphas(9),
     831              :                                                             ErrorsFound,
     832              :                                                             DataLoopNode::ConnectionObjectType::ZoneHVACLowTemperatureRadiantVariableFlow,
     833           46 :                                                             Alphas(1),
     834              :                                                             DataLoopNode::NodeFluidType::Water,
     835              :                                                             DataLoopNode::ConnectionType::Outlet,
     836              :                                                             NodeInputManager::CompFluidStream::Secondary,
     837              :                                                             ObjectIsNotParent);
     838              : 
     839           46 :             if ((!lAlphaBlanks(8)) || (!lAlphaBlanks(9))) {
     840           86 :                 TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(8), Alphas(9), "Chilled Water Nodes");
     841              :             }
     842              : 
     843           46 :             if (lAlphaBlanks(10)) {
     844           46 :                 thisRadSys.NumCircCalcMethod = CircuitCalc::OneCircuit;
     845            0 :             } else if ((thisRadSys.NumCircCalcMethod = static_cast<CircuitCalc>(getEnumValue(circuitCalcNamesUC, Alphas(10)))) ==
     846              :                        CircuitCalc::Invalid) {
     847            0 :                 ShowWarningInvalidKey(state, eoh, cAlphaFields(10), Alphas(10), "OnePerSurface");
     848            0 :                 thisRadSys.NumCircCalcMethod = CircuitCalc::OneCircuit;
     849              :             }
     850              : 
     851           46 :             thisRadSys.changeoverDelaySched = variableFlowDesignDataObject.changeoverDelaySched;
     852              : 
     853           46 :             thisRadSys.CircLength = Numbers(6);
     854              : 
     855           52 :             if ((thisRadSys.WaterVolFlowMaxCool == AutoSize) &&
     856            6 :                 (variableFlowDesignDataObject.DesignCoolingCapMethod == 0 || lAlphaBlanks(8) || lAlphaBlanks(9) ||
     857            6 :                  (thisRadSys.ColdWaterInNode <= 0) || (thisRadSys.ColdWaterOutNode <= 0) ||
     858            6 :                  (variableFlowDesignDataObject.coolSetptSched == nullptr))) {
     859            0 :                 ShowSevereError(state, "Hydronic radiant systems may not be autosized without specification of nodes or schedules");
     860            0 :                 ShowContinueError(state, format("Occurs in {} (cooling input) ={}", CurrentModuleObject, Alphas(1)));
     861            0 :                 ErrorsFound = true;
     862              :             }
     863           46 :         }
     864              : 
     865              :         // Obtain all of the design data related to Constant flow low temperature radiant systems...
     866           29 :         CurrentModuleObject = "ZoneHVAC:LowTemperatureRadiant:ConstantFlow:Design";
     867           52 :         for (Item = 1; Item <= state.dataLowTempRadSys->NumOfCFloLowTempRadSysDes; ++Item) {
     868              : 
     869           23 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     870              :                                                                      CurrentModuleObject,
     871              :                                                                      Item,
     872              :                                                                      Alphas,
     873              :                                                                      NumAlphas,
     874              :                                                                      Numbers,
     875              :                                                                      NumNumbers,
     876              :                                                                      IOStatus,
     877              :                                                                      lNumericBlanks,
     878              :                                                                      lAlphaBlanks,
     879              :                                                                      cAlphaFields,
     880              :                                                                      cNumericFields);
     881              : 
     882           23 :             ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
     883              : 
     884           23 :             state.dataLowTempRadSys->CflowRadiantSysDesign(Item).FieldNames.allocate(NumNumbers);
     885           23 :             state.dataLowTempRadSys->CflowRadiantSysDesign(Item).FieldNames = "";
     886           23 :             state.dataLowTempRadSys->CflowRadiantSysDesign(Item).FieldNames = cNumericFields;
     887           23 :             GlobalNames::VerifyUniqueInterObjectName(
     888           46 :                 state, state.dataLowTempRadSys->LowTempRadUniqueNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
     889              : 
     890           23 :             auto &thisRadSysDesign = state.dataLowTempRadSys->CflowRadiantSysDesign(Item);
     891              : 
     892              :             // General user input data
     893           23 :             thisRadSysDesign.designName = Alphas(1);
     894              : 
     895           23 :             if (lAlphaBlanks(2)) {
     896            0 :                 thisRadSysDesign.FluidToSlabHeatTransfer = FluidToSlabHeatTransferType::ConvectionOnly;
     897           23 :             } else if ((thisRadSysDesign.FluidToSlabHeatTransfer = static_cast<FluidToSlabHeatTransferType>(
     898           23 :                             getEnumValue(fluidToSlabHeatTransferTypeNamesUC, Alphas(2)))) == FluidToSlabHeatTransferType::Invalid) {
     899            0 :                 ShowWarningInvalidKey(state, eoh, cAlphaFields(2), Alphas(2), "ConvectionOnly");
     900            0 :                 thisRadSysDesign.FluidToSlabHeatTransfer = FluidToSlabHeatTransferType::ConvectionOnly;
     901              :             }
     902              : 
     903           23 :             thisRadSysDesign.TubeDiameterInner = Numbers(1);
     904           23 :             thisRadSysDesign.TubeDiameterOuter = Numbers(2);
     905           23 :             thisRadSysDesign.ConstFlowTubeConductivity = Numbers(3);
     906              : 
     907              :             // Process the temperature control type
     908           23 :             if (lAlphaBlanks(3)) {
     909            0 :                 thisRadSysDesign.ConstFlowControlType = CtrlType::MAT;
     910           23 :             } else if ((thisRadSysDesign.ConstFlowControlType = static_cast<CtrlType>(getEnumValue(ctrlTypeNamesUC, Alphas(3)))) ==
     911              :                        CtrlType::Invalid) {
     912            0 :                 ShowWarningInvalidKey(state, eoh, cAlphaFields(3), Alphas(3), "MeanAirTemperature");
     913            0 :                 thisRadSysDesign.ConstFlowControlType = CtrlType::MAT;
     914           23 :             } else if (thisRadSysDesign.ConstFlowControlType == CtrlType::RunningMeanODB) {
     915            3 :                 state.dataLowTempRadSys->anyRadiantSystemUsingRunningMeanAverage = true;
     916              :             }
     917              : 
     918           23 :             thisRadSysDesign.runningMeanOutdoorAirTemperatureWeightingFactor = Numbers(4);
     919           23 :             thisRadSysDesign.MotorEffic = Numbers(5);
     920           23 :             thisRadSysDesign.FracMotorLossToFluid = Numbers(6);
     921              : 
     922           23 :             if (lAlphaBlanks(4)) {
     923            1 :                 thisRadSysDesign.condCtrlType = CondCtrlType::SimpleOff;
     924           22 :             } else if ((thisRadSysDesign.condCtrlType = static_cast<CondCtrlType>(getEnumValue(condCtrlTypeNamesUC, Alphas(4)))) ==
     925              :                        CondCtrlType::Invalid) {
     926            0 :                 ShowWarningInvalidKey(state, eoh, cAlphaFields(4), Alphas(4), "SimpleOff");
     927            0 :                 thisRadSysDesign.condCtrlType = CondCtrlType::SimpleOff;
     928              :             }
     929              : 
     930           23 :             thisRadSysDesign.CondDewPtDeltaT = Numbers(7);
     931              : 
     932           23 :             if (lAlphaBlanks(5)) {
     933            3 :             } else if ((thisRadSysDesign.changeoverDelaySched = Sched::GetSchedule(state, Alphas(5))) == nullptr) {
     934            0 :                 ShowWarningItemNotFound(state, eoh, cAlphaFields(5), Alphas(5), "No changeover delay will be used for this radiant system.");
     935              :             }
     936           23 :             CFlowRadDesignNames(Item) = Alphas(1);
     937              :         }
     938              : 
     939              :         // Obtain all of the user data related to constant flow (hydronic) low temperature radiant systems...
     940           29 :         CurrentModuleObject = "ZoneHVAC:LowTemperatureRadiant:ConstantFlow";
     941           56 :         for (Item = 1; Item <= state.dataLowTempRadSys->NumOfCFloLowTempRadSys; ++Item) {
     942              : 
     943           27 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     944              :                                                                      CurrentModuleObject,
     945              :                                                                      Item,
     946              :                                                                      Alphas,
     947              :                                                                      NumAlphas,
     948              :                                                                      Numbers,
     949              :                                                                      NumNumbers,
     950              :                                                                      IOStatus,
     951              :                                                                      lNumericBlanks,
     952              :                                                                      lAlphaBlanks,
     953              :                                                                      cAlphaFields,
     954              :                                                                      cNumericFields);
     955              : 
     956           27 :             ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
     957              : 
     958           27 :             GlobalNames::VerifyUniqueInterObjectName(
     959           54 :                 state, state.dataLowTempRadSys->LowTempRadUniqueNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
     960           27 :             ++BaseNum;
     961           27 :             state.dataLowTempRadSys->RadSysTypes(BaseNum).Name = Alphas(1);
     962           27 :             state.dataLowTempRadSys->RadSysTypes(BaseNum).systemType = SystemType::ConstantFlow;
     963              : 
     964              :             // General user input data
     965           27 :             auto &thisCFloSys = state.dataLowTempRadSys->CFloRadSys(Item);
     966              : 
     967           27 :             thisCFloSys.Name = Alphas(1);
     968           27 :             thisCFloSys.designObjectName = Alphas(2);
     969           27 :             thisCFloSys.DesignObjectPtr = Util::FindItemInList(thisCFloSys.designObjectName, CFlowRadDesignNames);
     970              :             ConstantFlowRadDesignData ConstantFlowRadDesignDataObject{
     971           27 :                 state.dataLowTempRadSys->CflowRadiantSysDesign(thisCFloSys.DesignObjectPtr)}; // Contains the data for variable flow hydronic systems
     972              : 
     973           27 :             if (lAlphaBlanks(3)) {
     974            0 :                 thisCFloSys.availSched = Sched::GetScheduleAlwaysOn(state);
     975           27 :             } else if ((thisCFloSys.availSched = Sched::GetSchedule(state, Alphas(3))) == nullptr) {
     976            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(3), Alphas(3));
     977            0 :                 ErrorsFound = true;
     978              :             }
     979              : 
     980           27 :             thisCFloSys.ZoneName = Alphas(4);
     981           27 :             thisCFloSys.ZonePtr = Util::FindItemInList(Alphas(4), Zone);
     982           27 :             if (thisCFloSys.ZonePtr == 0) {
     983            0 :                 ShowSevereError(state, format("{}Invalid {} = {}", RoutineName, cAlphaFields(4), Alphas(4)));
     984            0 :                 ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, Alphas(1)));
     985            0 :                 ErrorsFound = true;
     986              :             }
     987              : 
     988           27 :             thisCFloSys.SurfListName = Alphas(5);
     989           27 :             SurfListNum = 0;
     990           27 :             if (state.dataSurfLists->NumOfSurfaceLists > 0) {
     991            0 :                 SurfListNum = Util::FindItemInList(thisCFloSys.SurfListName, state.dataSurfLists->SurfList);
     992              :             }
     993           27 :             if (SurfListNum > 0) { // Found a valid surface list
     994            0 :                 thisCFloSys.NumOfSurfaces = state.dataSurfLists->SurfList(SurfListNum).NumOfSurfaces;
     995            0 :                 thisCFloSys.SurfacePtr.allocate(thisCFloSys.NumOfSurfaces);
     996            0 :                 thisCFloSys.SurfaceName.allocate(thisCFloSys.NumOfSurfaces);
     997            0 :                 thisCFloSys.SurfaceFrac.allocate(thisCFloSys.NumOfSurfaces);
     998            0 :                 thisCFloSys.NumCircuits.allocate(thisCFloSys.NumOfSurfaces);
     999            0 :                 state.dataLowTempRadSys->MaxCloNumOfSurfaces = max(state.dataLowTempRadSys->MaxCloNumOfSurfaces, thisCFloSys.NumOfSurfaces);
    1000            0 :                 for (SurfNum = 1; SurfNum <= state.dataSurfLists->SurfList(SurfListNum).NumOfSurfaces; ++SurfNum) {
    1001            0 :                     thisCFloSys.SurfacePtr(SurfNum) = state.dataSurfLists->SurfList(SurfListNum).SurfPtr(SurfNum);
    1002            0 :                     thisCFloSys.SurfaceName(SurfNum) = state.dataSurfLists->SurfList(SurfListNum).SurfName(SurfNum);
    1003            0 :                     thisCFloSys.SurfaceFrac(SurfNum) = state.dataSurfLists->SurfList(SurfListNum).SurfFlowFrac(SurfNum);
    1004            0 :                     thisCFloSys.NumCircuits(SurfNum) = 0.0;
    1005            0 :                     if (thisCFloSys.SurfacePtr(SurfNum) != 0) {
    1006            0 :                         state.dataSurface->surfIntConv(thisCFloSys.SurfacePtr(SurfNum)).hasActiveInIt = true;
    1007              :                     }
    1008              :                 }
    1009              :             } else { // User entered a single surface name rather than a surface list
    1010           27 :                 thisCFloSys.NumOfSurfaces = 1;
    1011           27 :                 thisCFloSys.SurfacePtr.allocate(thisCFloSys.NumOfSurfaces);
    1012           27 :                 thisCFloSys.SurfaceName.allocate(thisCFloSys.NumOfSurfaces);
    1013           27 :                 thisCFloSys.SurfaceFrac.allocate(thisCFloSys.NumOfSurfaces);
    1014           27 :                 thisCFloSys.NumCircuits.allocate(thisCFloSys.NumOfSurfaces);
    1015           27 :                 state.dataLowTempRadSys->MaxCloNumOfSurfaces = max(state.dataLowTempRadSys->MaxCloNumOfSurfaces, thisCFloSys.NumOfSurfaces);
    1016           27 :                 thisCFloSys.SurfaceName(1) = thisCFloSys.SurfListName;
    1017           27 :                 thisCFloSys.SurfacePtr(1) = Util::FindItemInList(thisCFloSys.SurfaceName(1), Surface);
    1018           27 :                 thisCFloSys.SurfaceFrac(1) = 1.0;
    1019           27 :                 thisCFloSys.NumCircuits(1) = 0.0;
    1020              :                 // Error checking for single surfaces
    1021           27 :                 if (thisCFloSys.SurfacePtr(1) == 0) {
    1022            0 :                     ShowSevereError(state, format("{}Invalid {} = {}", RoutineName, cAlphaFields(4), Alphas(4)));
    1023            0 :                     ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    1024            0 :                     ErrorsFound = true;
    1025           27 :                 } else if (state.dataSurface->SurfIsRadSurfOrVentSlabOrPool(thisCFloSys.SurfacePtr(1))) {
    1026            0 :                     ShowSevereError(state, format("{}{}=\"{}\", Invalid Surface", RoutineName, CurrentModuleObject, Alphas(1)));
    1027            0 :                     ShowContinueError(state,
    1028            0 :                                       format("{}=\"{}\" has been used in another radiant system or ventilated slab.", cAlphaFields(5), Alphas(5)));
    1029            0 :                     ErrorsFound = true;
    1030              :                 }
    1031           27 :                 if (thisCFloSys.SurfacePtr(1) != 0) {
    1032           27 :                     state.dataSurface->surfIntConv(thisCFloSys.SurfacePtr(1)).hasActiveInIt = true;
    1033           27 :                     state.dataSurface->SurfIsRadSurfOrVentSlabOrPool(thisCFloSys.SurfacePtr(1)) = true;
    1034              :                 }
    1035              :             }
    1036              : 
    1037              :             // Error checking for zones and construction information
    1038           27 :             thisCFloSys.errorCheckZonesAndConstructions(state, ErrorsFound);
    1039              : 
    1040           27 :             thisCFloSys.TubeLength = Numbers(1);
    1041              : 
    1042              :             // Process pump input for constant flow (hydronic) radiant system
    1043           27 :             thisCFloSys.WaterVolFlowMax = Numbers(2);
    1044              : 
    1045           27 :             if (lAlphaBlanks(6)) {
    1046            0 :             } else if ((thisCFloSys.volFlowSched = Sched::GetSchedule(state, Alphas(6))) == nullptr) {
    1047            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(6), Alphas(6));
    1048            0 :                 ErrorsFound = true;
    1049              :             }
    1050           27 :             thisCFloSys.NomPumpHead = Numbers(3);
    1051           27 :             thisCFloSys.NomPowerUse = Numbers(4);
    1052              : 
    1053              :             // Heating user input data
    1054           27 :             thisCFloSys.HotWaterInNode = GetOnlySingleNode(state,
    1055           27 :                                                            Alphas(7),
    1056              :                                                            ErrorsFound,
    1057              :                                                            DataLoopNode::ConnectionObjectType::ZoneHVACLowTemperatureRadiantConstantFlow,
    1058           27 :                                                            Alphas(1),
    1059              :                                                            DataLoopNode::NodeFluidType::Water,
    1060              :                                                            DataLoopNode::ConnectionType::Inlet,
    1061              :                                                            NodeInputManager::CompFluidStream::Primary,
    1062              :                                                            ObjectIsNotParent);
    1063              : 
    1064           27 :             thisCFloSys.HotWaterOutNode = GetOnlySingleNode(state,
    1065           27 :                                                             Alphas(8),
    1066              :                                                             ErrorsFound,
    1067              :                                                             DataLoopNode::ConnectionObjectType::ZoneHVACLowTemperatureRadiantConstantFlow,
    1068           27 :                                                             Alphas(1),
    1069              :                                                             DataLoopNode::NodeFluidType::Water,
    1070              :                                                             DataLoopNode::ConnectionType::Outlet,
    1071              :                                                             NodeInputManager::CompFluidStream::Primary,
    1072              :                                                             ObjectIsNotParent);
    1073              : 
    1074           27 :             if ((!lAlphaBlanks(7)) || (!lAlphaBlanks(8))) {
    1075           54 :                 TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(7), Alphas(8), "Hot Water Nodes");
    1076              :             }
    1077              : 
    1078           27 :             if (lAlphaBlanks(9)) {
    1079           27 :             } else if ((thisCFloSys.hotWaterHiTempSched = Sched::GetSchedule(state, Alphas(9))) == nullptr) {
    1080            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(9), Alphas(9));
    1081            0 :                 ErrorsFound = true;
    1082              :             }
    1083              : 
    1084           27 :             if (lAlphaBlanks(10)) {
    1085           27 :             } else if ((thisCFloSys.hotWaterLoTempSched = Sched::GetSchedule(state, Alphas(10))) == nullptr) {
    1086            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(10), Alphas(10));
    1087            0 :                 ErrorsFound = true;
    1088              :             }
    1089              : 
    1090              :             // This may look like a weird thing to do, but it's equivalent to a nested if and also uses less nesting
    1091           27 :             if (lAlphaBlanks(11)) {
    1092           27 :             } else if ((thisCFloSys.hotCtrlHiTempSched = Sched::GetSchedule(state, Alphas(11))) == nullptr) {
    1093            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(11), Alphas(11));
    1094            0 :                 ErrorsFound = true;
    1095              :             }
    1096              : 
    1097           27 :             if (lAlphaBlanks(12)) {
    1098           27 :             } else if ((thisCFloSys.hotCtrlLoTempSched = Sched::GetSchedule(state, Alphas(12))) == nullptr) {
    1099            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(12), Alphas(12));
    1100            0 :                 ErrorsFound = true;
    1101              :             }
    1102              : 
    1103              :             // Cooling user input data
    1104           27 :             thisCFloSys.ColdWaterInNode = GetOnlySingleNode(state,
    1105           27 :                                                             Alphas(13),
    1106              :                                                             ErrorsFound,
    1107              :                                                             DataLoopNode::ConnectionObjectType::ZoneHVACLowTemperatureRadiantConstantFlow,
    1108           27 :                                                             Alphas(1),
    1109              :                                                             DataLoopNode::NodeFluidType::Water,
    1110              :                                                             DataLoopNode::ConnectionType::Inlet,
    1111              :                                                             NodeInputManager::CompFluidStream::Secondary,
    1112              :                                                             ObjectIsNotParent);
    1113              : 
    1114           27 :             thisCFloSys.ColdWaterOutNode = GetOnlySingleNode(state,
    1115           27 :                                                              Alphas(14),
    1116              :                                                              ErrorsFound,
    1117              :                                                              DataLoopNode::ConnectionObjectType::ZoneHVACLowTemperatureRadiantConstantFlow,
    1118           27 :                                                              Alphas(1),
    1119              :                                                              DataLoopNode::NodeFluidType::Water,
    1120              :                                                              DataLoopNode::ConnectionType::Outlet,
    1121              :                                                              NodeInputManager::CompFluidStream::Secondary,
    1122              :                                                              ObjectIsNotParent);
    1123              : 
    1124           27 :             if ((!lAlphaBlanks(13)) || (!lAlphaBlanks(14))) {
    1125           48 :                 TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(13), Alphas(14), "Chilled Water Nodes");
    1126              :             }
    1127              : 
    1128           27 :             if (lAlphaBlanks(15)) {
    1129           24 :             } else if ((thisCFloSys.coldWaterHiTempSched = Sched::GetSchedule(state, Alphas(15))) == nullptr) {
    1130            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(15), Alphas(15));
    1131            0 :                 ErrorsFound = true;
    1132              :             }
    1133              : 
    1134           27 :             if (lAlphaBlanks(16)) {
    1135           24 :             } else if ((thisCFloSys.coldWaterLoTempSched = Sched::GetSchedule(state, Alphas(16))) == nullptr) {
    1136            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(16), Alphas(16));
    1137            0 :                 ErrorsFound = true;
    1138              :             }
    1139              : 
    1140           27 :             if (lAlphaBlanks(17)) {
    1141           24 :             } else if ((thisCFloSys.coldCtrlHiTempSched = Sched::GetSchedule(state, Alphas(17))) == nullptr) {
    1142            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(17), Alphas(17));
    1143            0 :                 ErrorsFound = true;
    1144              :             }
    1145              : 
    1146           27 :             if (lAlphaBlanks(18)) {
    1147           24 :             } else if ((thisCFloSys.coldCtrlLoTempSched = Sched::GetSchedule(state, Alphas(18))) == nullptr) {
    1148            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(18), Alphas(18));
    1149            0 :                 ErrorsFound = true;
    1150              :             }
    1151              : 
    1152           27 :             if (lAlphaBlanks(19)) {
    1153           27 :                 thisCFloSys.NumCircCalcMethod = CircuitCalc::OneCircuit;
    1154            0 :             } else if ((thisCFloSys.NumCircCalcMethod = static_cast<CircuitCalc>(getEnumValue(circuitCalcNamesUC, Alphas(19)))) ==
    1155              :                        CircuitCalc::Invalid) {
    1156            0 :                 ShowWarningInvalidKey(state, eoh, cAlphaFields(19), Alphas(19), "OnePerSurface");
    1157            0 :                 thisCFloSys.NumCircCalcMethod = CircuitCalc::OneCircuit;
    1158              :             }
    1159              : 
    1160           27 :             thisCFloSys.changeoverDelaySched = ConstantFlowRadDesignDataObject.changeoverDelaySched;
    1161              : 
    1162           27 :             thisCFloSys.CircLength = Numbers(5);
    1163           27 :         }
    1164              : 
    1165              :         // Obtain all of the user data related to electric low temperature radiant systems...
    1166           29 :         CurrentModuleObject = "ZoneHVAC:LowTemperatureRadiant:Electric";
    1167              : 
    1168           38 :         for (Item = 1; Item <= state.dataLowTempRadSys->NumOfElecLowTempRadSys; ++Item) {
    1169              : 
    1170            9 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1171              :                                                                      CurrentModuleObject,
    1172              :                                                                      Item,
    1173              :                                                                      Alphas,
    1174              :                                                                      NumAlphas,
    1175              :                                                                      Numbers,
    1176              :                                                                      NumNumbers,
    1177              :                                                                      IOStatus,
    1178              :                                                                      lNumericBlanks,
    1179              :                                                                      lAlphaBlanks,
    1180              :                                                                      cAlphaFields,
    1181              :                                                                      cNumericFields);
    1182              : 
    1183            9 :             ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
    1184              : 
    1185            9 :             state.dataLowTempRadSys->ElecRadSysNumericFields(Item).FieldNames.allocate(NumNumbers);
    1186            9 :             state.dataLowTempRadSys->ElecRadSysNumericFields(Item).FieldNames = "";
    1187            9 :             state.dataLowTempRadSys->ElecRadSysNumericFields(Item).FieldNames = cNumericFields;
    1188              : 
    1189            9 :             GlobalNames::VerifyUniqueInterObjectName(
    1190           18 :                 state, state.dataLowTempRadSys->LowTempRadUniqueNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
    1191            9 :             ++BaseNum;
    1192            9 :             state.dataLowTempRadSys->RadSysTypes(BaseNum).Name = Alphas(1);
    1193            9 :             state.dataLowTempRadSys->RadSysTypes(BaseNum).systemType = SystemType::Electric;
    1194              : 
    1195              :             // General user input data
    1196            9 :             auto &thisElecSys = state.dataLowTempRadSys->ElecRadSys(Item);
    1197              : 
    1198            9 :             thisElecSys.Name = Alphas(1);
    1199              : 
    1200            9 :             if (lAlphaBlanks(2)) {
    1201            0 :                 thisElecSys.availSched = Sched::GetScheduleAlwaysOn(state);
    1202            9 :             } else if ((thisElecSys.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
    1203            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
    1204            0 :                 ErrorsFound = true;
    1205              :             }
    1206              : 
    1207            9 :             thisElecSys.ZoneName = Alphas(3);
    1208            9 :             thisElecSys.ZonePtr = Util::FindItemInList(Alphas(3), Zone);
    1209            9 :             if (thisElecSys.ZonePtr == 0) {
    1210            0 :                 ShowSevereError(state, format("{}Invalid {} = {}", RoutineName, cAlphaFields(3), Alphas(3)));
    1211            0 :                 ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    1212            0 :                 ErrorsFound = true;
    1213              :             }
    1214              : 
    1215            9 :             thisElecSys.SurfListName = Alphas(4);
    1216            9 :             SurfListNum = 0;
    1217            9 :             if (state.dataSurfLists->NumOfSurfaceLists > 0) {
    1218            0 :                 SurfListNum = Util::FindItemInList(thisElecSys.SurfListName, state.dataSurfLists->SurfList);
    1219              :             }
    1220            9 :             if (SurfListNum > 0) { // Found a valid surface list
    1221            0 :                 thisElecSys.NumOfSurfaces = state.dataSurfLists->SurfList(SurfListNum).NumOfSurfaces;
    1222            0 :                 thisElecSys.SurfacePtr.allocate(thisElecSys.NumOfSurfaces);
    1223            0 :                 thisElecSys.SurfaceName.allocate(thisElecSys.NumOfSurfaces);
    1224            0 :                 thisElecSys.SurfaceFrac.allocate(thisElecSys.NumOfSurfaces);
    1225            0 :                 for (SurfNum = 1; SurfNum <= state.dataSurfLists->SurfList(SurfListNum).NumOfSurfaces; ++SurfNum) {
    1226            0 :                     thisElecSys.SurfacePtr(SurfNum) = state.dataSurfLists->SurfList(SurfListNum).SurfPtr(SurfNum);
    1227            0 :                     thisElecSys.SurfaceName(SurfNum) = state.dataSurfLists->SurfList(SurfListNum).SurfName(SurfNum);
    1228            0 :                     thisElecSys.SurfaceFrac(SurfNum) = state.dataSurfLists->SurfList(SurfListNum).SurfFlowFrac(SurfNum);
    1229              :                 }
    1230              :             } else { // User entered a single surface name rather than a surface list
    1231            9 :                 thisElecSys.NumOfSurfaces = 1;
    1232            9 :                 thisElecSys.SurfacePtr.allocate(thisElecSys.NumOfSurfaces);
    1233            9 :                 thisElecSys.SurfaceName.allocate(thisElecSys.NumOfSurfaces);
    1234            9 :                 thisElecSys.SurfaceFrac.allocate(thisElecSys.NumOfSurfaces);
    1235            9 :                 thisElecSys.SurfaceName(1) = thisElecSys.SurfListName;
    1236            9 :                 thisElecSys.SurfacePtr(1) = Util::FindItemInList(thisElecSys.SurfaceName(1), Surface);
    1237            9 :                 thisElecSys.SurfaceFrac(1) = 1.0;
    1238              :                 // Error checking for single surfaces
    1239            9 :                 if (thisElecSys.SurfacePtr(1) == 0) {
    1240            0 :                     ShowSevereError(state, format("{}Invalid {} = {}", RoutineName, cAlphaFields(4), Alphas(4)));
    1241            0 :                     ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    1242            0 :                     ErrorsFound = true;
    1243            9 :                 } else if (state.dataSurface->SurfIsRadSurfOrVentSlabOrPool(thisElecSys.SurfacePtr(1))) {
    1244            0 :                     ShowSevereError(state, format("{}{}=\"{}\", Invalid Surface", RoutineName, CurrentModuleObject, Alphas(1)));
    1245            0 :                     ShowContinueError(state,
    1246            0 :                                       format("{}=\"{}\" has been used in another radiant system or ventilated slab.", cAlphaFields(4), Alphas(4)));
    1247            0 :                     ErrorsFound = true;
    1248              :                 }
    1249            9 :                 if (thisElecSys.SurfacePtr(1) != 0) {
    1250            9 :                     state.dataSurface->SurfIsRadSurfOrVentSlabOrPool(state.dataLowTempRadSys->ElecRadSys(Item).SurfacePtr(1)) = true;
    1251              :                 }
    1252              :             }
    1253              : 
    1254              :             // Error checking for zones and construction information
    1255            9 :             thisElecSys.errorCheckZonesAndConstructions(state, ErrorsFound);
    1256              : 
    1257              :             // Heating user input data
    1258              :             // Determine Low Temp Radiant heating design capacity sizing method
    1259            9 :             if (Util::SameString(Alphas(iHeatCAPMAlphaNum), "HeatingDesignCapacity")) {
    1260            5 :                 thisElecSys.HeatingCapMethod = HeatingDesignCapacity;
    1261            5 :                 if (!lNumericBlanks(iHeatDesignCapacityNumericNum)) {
    1262            5 :                     thisElecSys.ScaledHeatingCapacity = Numbers(iHeatDesignCapacityNumericNum);
    1263            5 :                     thisElecSys.MaxElecPower = thisElecSys.ScaledHeatingCapacity;
    1264            5 :                     if (thisElecSys.ScaledHeatingCapacity < 0.0 && thisElecSys.ScaledHeatingCapacity != AutoSize) {
    1265            0 :                         ShowSevereError(state, format("{} = {}", CurrentModuleObject, thisElecSys.Name));
    1266            0 :                         ShowContinueError(
    1267              :                             state,
    1268            0 :                             format("Illegal {} = {:.7T}", cNumericFields(iHeatDesignCapacityNumericNum), Numbers(iHeatDesignCapacityNumericNum)));
    1269            0 :                         ErrorsFound = true;
    1270              :                     }
    1271              :                 } else {
    1272            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, thisElecSys.Name));
    1273            0 :                     ShowContinueError(state, format("Input for {} = {}", cAlphaFields(iHeatCAPMAlphaNum), Alphas(iHeatCAPMAlphaNum)));
    1274            0 :                     ShowContinueError(state, format("Blank field not allowed for {}", cNumericFields(iHeatDesignCapacityNumericNum)));
    1275            0 :                     ErrorsFound = true;
    1276              :                 }
    1277            4 :             } else if (Util::SameString(Alphas(iHeatCAPMAlphaNum), "CapacityPerFloorArea")) {
    1278            2 :                 thisElecSys.HeatingCapMethod = CapacityPerFloorArea;
    1279            2 :                 if (!lNumericBlanks(iHeatCapacityPerFloorAreaNumericNum)) {
    1280            2 :                     thisElecSys.ScaledHeatingCapacity = Numbers(iHeatCapacityPerFloorAreaNumericNum);
    1281            2 :                     thisElecSys.MaxElecPower = thisElecSys.ScaledHeatingCapacity;
    1282            2 :                     if (thisElecSys.ScaledHeatingCapacity <= 0.0) {
    1283            0 :                         ShowSevereError(state, format("{} = {}", CurrentModuleObject, thisElecSys.Name));
    1284            0 :                         ShowContinueError(state, format("Input for {} = {}", cAlphaFields(iHeatCAPMAlphaNum), Alphas(iHeatCAPMAlphaNum)));
    1285            0 :                         ShowContinueError(state,
    1286            0 :                                           format("Illegal {} = {:.7T}",
    1287              :                                                  cNumericFields(iHeatCapacityPerFloorAreaNumericNum),
    1288              :                                                  Numbers(iHeatCapacityPerFloorAreaNumericNum)));
    1289            0 :                         ErrorsFound = true;
    1290            2 :                     } else if (thisElecSys.ScaledHeatingCapacity == AutoSize) {
    1291            0 :                         ShowSevereError(state, format("{} = {}", CurrentModuleObject, thisElecSys.Name));
    1292            0 :                         ShowContinueError(state, format("Input for {} = {}", cAlphaFields(iHeatCAPMAlphaNum), Alphas(iHeatCAPMAlphaNum)));
    1293            0 :                         ShowContinueError(state, format("Illegal {} = Autosize", cNumericFields(iHeatCapacityPerFloorAreaNumericNum)));
    1294            0 :                         ErrorsFound = true;
    1295              :                     }
    1296              :                 } else {
    1297            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, thisElecSys.Name));
    1298            0 :                     ShowContinueError(state, format("Input for {} = {}", cAlphaFields(iHeatCAPMAlphaNum), Alphas(iHeatCAPMAlphaNum)));
    1299            0 :                     ShowContinueError(state, format("Blank field not allowed for {}", cNumericFields(iHeatCapacityPerFloorAreaNumericNum)));
    1300            0 :                     ErrorsFound = true;
    1301              :                 }
    1302            2 :             } else if (Util::SameString(Alphas(iHeatCAPMAlphaNum), "FractionOfAutosizedHeatingCapacity")) {
    1303            2 :                 thisElecSys.HeatingCapMethod = FractionOfAutosizedHeatingCapacity;
    1304            2 :                 if (!lNumericBlanks(iHeatFracOfAutosizedCapacityNumericNum)) {
    1305            2 :                     thisElecSys.ScaledHeatingCapacity = Numbers(iHeatFracOfAutosizedCapacityNumericNum);
    1306            2 :                     thisElecSys.MaxElecPower = thisElecSys.ScaledHeatingCapacity;
    1307            2 :                     if (thisElecSys.ScaledHeatingCapacity < 0.0) {
    1308            0 :                         ShowSevereError(state, format("{} = {}", CurrentModuleObject, thisElecSys.Name));
    1309            0 :                         ShowContinueError(state,
    1310            0 :                                           format("Illegal {} = {:.7T}",
    1311              :                                                  cNumericFields(iHeatFracOfAutosizedCapacityNumericNum),
    1312              :                                                  Numbers(iHeatFracOfAutosizedCapacityNumericNum)));
    1313            0 :                         ErrorsFound = true;
    1314              :                     }
    1315              :                 } else {
    1316            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, thisElecSys.Name));
    1317            0 :                     ShowContinueError(state, format("Input for {} = {}", cAlphaFields(iHeatCAPMAlphaNum), Alphas(iHeatCAPMAlphaNum)));
    1318            0 :                     ShowContinueError(state, format("Blank field not allowed for {}", cNumericFields(iHeatFracOfAutosizedCapacityNumericNum)));
    1319            0 :                     ErrorsFound = true;
    1320              :                 }
    1321              :             } else {
    1322            0 :                 ShowSevereError(state, format("{} = {}", CurrentModuleObject, thisElecSys.Name));
    1323            0 :                 ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(iHeatCAPMAlphaNum), Alphas(iHeatCAPMAlphaNum)));
    1324            0 :                 ErrorsFound = true;
    1325              :             }
    1326              : 
    1327              :             // Process the temperature control type
    1328            9 :             if (lAlphaBlanks(6)) {
    1329            0 :                 thisElecSys.controlType = CtrlType::MAT;
    1330            9 :             } else if ((thisElecSys.controlType = static_cast<CtrlType>(getEnumValue(ctrlTypeNamesUC, Alphas(6)))) == CtrlType::Invalid) {
    1331            0 :                 ShowWarningInvalidKey(state, eoh, cAlphaFields(6), Alphas(6), "MeanAirTemperature");
    1332            0 :                 thisElecSys.controlType = CtrlType::MAT;
    1333              :             }
    1334              : 
    1335              :             // Process the setpoint type
    1336            9 :             if (lAlphaBlanks(7)) {
    1337            0 :                 thisElecSys.setpointType = SetpointType::HalfFlowPower;
    1338            9 :             } else if ((thisElecSys.setpointType = static_cast<SetpointType>(getEnumValue(setpointTypeNamesUC, Alphas(7)))) ==
    1339              :                        SetpointType::Invalid) {
    1340            0 :                 ShowWarningInvalidKey(state, eoh, cAlphaFields(7), Alphas(7), "HalfFlowPower");
    1341            0 :                 thisElecSys.setpointType = SetpointType::HalfFlowPower;
    1342              :             }
    1343              : 
    1344            9 :             thisElecSys.ThrottlRange = Numbers(4);
    1345              : 
    1346            9 :             if (lAlphaBlanks(8)) {
    1347            0 :                 ShowSevereEmptyField(state, eoh, cAlphaFields(8));
    1348            0 :                 ErrorsFound = true;
    1349            9 :             } else if ((thisElecSys.setptSched = Sched::GetSchedule(state, Alphas(8))) == nullptr) {
    1350            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(8), Alphas(8));
    1351            0 :                 ErrorsFound = true;
    1352              :             }
    1353              :         }
    1354              : 
    1355              :         // Check to see if any surface is included in more than one radiant system.  This is not allowed
    1356              :         // and thus indicative that there is an error in the input file.  This is to make sure that two
    1357              :         // different radiant systems are competing for the same surface.  Allowing this to happen would
    1358              :         // result in lost energy somewhere and the situation really is not physically possible anyway.
    1359           29 :         AssignedAsRadiantSurface.dimension(state.dataSurface->TotSurfaces, false);
    1360              : 
    1361           75 :         for (Item = 1; Item <= state.dataLowTempRadSys->NumOfHydrLowTempRadSys; ++Item) {
    1362          104 :             for (SurfNum = 1; SurfNum <= state.dataLowTempRadSys->HydrRadSys(Item).NumOfSurfaces; ++SurfNum) {
    1363           58 :                 CheckSurfNum = state.dataLowTempRadSys->HydrRadSys(Item).SurfacePtr(SurfNum);
    1364           58 :                 if (CheckSurfNum == 0) {
    1365            0 :                     continue;
    1366              :                 }
    1367           58 :                 if (AssignedAsRadiantSurface(CheckSurfNum)) {
    1368            0 :                     ShowSevereError(
    1369            0 :                         state, format("Surface {} is referenced by more than one radiant system--this is not allowed", Surface(CheckSurfNum).Name));
    1370            0 :                     ErrorsFound = true;
    1371              :                 } else {
    1372           58 :                     AssignedAsRadiantSurface(CheckSurfNum) = true;
    1373              :                 }
    1374              :                 // Also check the other side of interzone partitions
    1375           58 :                 if ((Surface(CheckSurfNum).ExtBoundCond > 0) && (Surface(CheckSurfNum).ExtBoundCond != CheckSurfNum)) {
    1376            1 :                     if (AssignedAsRadiantSurface(Surface(CheckSurfNum).ExtBoundCond)) {
    1377            0 :                         ShowSevereError(state,
    1378            0 :                                         format("Interzone surface {} is referenced by more than one radiant system--this is not allowed",
    1379            0 :                                                Surface(Surface(CheckSurfNum).ExtBoundCond).Name));
    1380            0 :                         ErrorsFound = true;
    1381              :                     } else {
    1382            1 :                         AssignedAsRadiantSurface(Surface(CheckSurfNum).ExtBoundCond) = true;
    1383              :                     }
    1384              :                 }
    1385              :             }
    1386              :         }
    1387              : 
    1388           56 :         for (Item = 1; Item <= state.dataLowTempRadSys->NumOfCFloLowTempRadSys; ++Item) {
    1389           54 :             for (SurfNum = 1; SurfNum <= state.dataLowTempRadSys->CFloRadSys(Item).NumOfSurfaces; ++SurfNum) {
    1390           27 :                 CheckSurfNum = state.dataLowTempRadSys->CFloRadSys(Item).SurfacePtr(SurfNum);
    1391           27 :                 if (CheckSurfNum == 0) {
    1392            0 :                     continue;
    1393              :                 }
    1394           27 :                 if (AssignedAsRadiantSurface(CheckSurfNum)) {
    1395            0 :                     ShowSevereError(
    1396            0 :                         state, format("Surface {} is referenced by more than one radiant system--this is not allowed", Surface(CheckSurfNum).Name));
    1397            0 :                     ErrorsFound = true;
    1398              :                 } else {
    1399           27 :                     AssignedAsRadiantSurface(CheckSurfNum) = true;
    1400              :                 }
    1401              :                 // Also check the other side of interzone partitions
    1402           27 :                 if ((Surface(CheckSurfNum).ExtBoundCond > 0) && (Surface(CheckSurfNum).ExtBoundCond != CheckSurfNum)) {
    1403            0 :                     if (AssignedAsRadiantSurface(Surface(CheckSurfNum).ExtBoundCond)) {
    1404            0 :                         ShowSevereError(state,
    1405            0 :                                         format("Interzone surface {} is referenced by more than one radiant system--this is not allowed",
    1406            0 :                                                Surface(Surface(CheckSurfNum).ExtBoundCond).Name));
    1407            0 :                         ErrorsFound = true;
    1408              :                     } else {
    1409            0 :                         AssignedAsRadiantSurface(Surface(CheckSurfNum).ExtBoundCond) = true;
    1410              :                     }
    1411              :                 }
    1412              :             }
    1413              :         }
    1414              : 
    1415           38 :         for (Item = 1; Item <= state.dataLowTempRadSys->NumOfElecLowTempRadSys; ++Item) {
    1416           18 :             for (SurfNum = 1; SurfNum <= state.dataLowTempRadSys->ElecRadSys(Item).NumOfSurfaces; ++SurfNum) {
    1417            9 :                 CheckSurfNum = state.dataLowTempRadSys->ElecRadSys(Item).SurfacePtr(SurfNum);
    1418            9 :                 if (CheckSurfNum == 0) {
    1419            0 :                     continue;
    1420              :                 }
    1421            9 :                 if (AssignedAsRadiantSurface(CheckSurfNum)) {
    1422            0 :                     ShowSevereError(
    1423            0 :                         state, format("Surface {} is referenced by more than one radiant system--this is not allowed", Surface(CheckSurfNum).Name));
    1424            0 :                     ErrorsFound = true;
    1425              :                 } else {
    1426            9 :                     AssignedAsRadiantSurface(CheckSurfNum) = true;
    1427              :                 }
    1428              :                 // Also check the other side of interzone partitions
    1429            9 :                 if ((Surface(CheckSurfNum).ExtBoundCond > 0) && (Surface(CheckSurfNum).ExtBoundCond != CheckSurfNum)) {
    1430            0 :                     if (AssignedAsRadiantSurface(Surface(CheckSurfNum).ExtBoundCond)) {
    1431            0 :                         ShowSevereError(state,
    1432            0 :                                         format("Interzone surface {} is referenced by more than one radiant system--this is not allowed",
    1433            0 :                                                Surface(Surface(CheckSurfNum).ExtBoundCond).Name));
    1434            0 :                         ErrorsFound = true;
    1435              :                     } else {
    1436            0 :                         AssignedAsRadiantSurface(Surface(CheckSurfNum).ExtBoundCond) = true;
    1437              :                     }
    1438              :                 }
    1439              :             }
    1440              :         }
    1441              : 
    1442           29 :         AssignedAsRadiantSurface.deallocate();
    1443           29 :         Alphas.deallocate();
    1444           29 :         Numbers.deallocate();
    1445           29 :         cAlphaFields.deallocate();
    1446           29 :         cNumericFields.deallocate();
    1447           29 :         lAlphaBlanks.deallocate();
    1448           29 :         lNumericBlanks.deallocate();
    1449              : 
    1450           29 :         if (ErrorsFound) {
    1451            0 :             ShowFatalError(state, format("{}Errors found in input. Preceding conditions cause termination.", RoutineName));
    1452              :         }
    1453              : 
    1454              :         // Set up the output variables for low temperature radiant systems
    1455              :         // ZoneHVAC:LowTemperatureRadiant:VariableFlow (HydrRadSys)
    1456           75 :         for (Item = 1; Item <= state.dataLowTempRadSys->NumOfHydrLowTempRadSys; ++Item) {
    1457              : 
    1458           46 :             auto &thisHydrSys = state.dataLowTempRadSys->HydrRadSys(Item);
    1459              : 
    1460           92 :             SetupOutputVariable(state,
    1461              :                                 "Zone Radiant HVAC Heating Rate",
    1462              :                                 Constant::Units::W,
    1463           46 :                                 thisHydrSys.HeatPower,
    1464              :                                 OutputProcessor::TimeStepType::System,
    1465              :                                 OutputProcessor::StoreType::Average,
    1466           46 :                                 thisHydrSys.Name);
    1467           92 :             SetupOutputVariable(state,
    1468              :                                 "Zone Radiant HVAC Heating Energy",
    1469              :                                 Constant::Units::J,
    1470           46 :                                 thisHydrSys.HeatEnergy,
    1471              :                                 OutputProcessor::TimeStepType::System,
    1472              :                                 OutputProcessor::StoreType::Sum,
    1473           46 :                                 thisHydrSys.Name,
    1474              :                                 Constant::eResource::EnergyTransfer,
    1475              :                                 OutputProcessor::Group::HVAC,
    1476              :                                 OutputProcessor::EndUseCat::HeatingCoils);
    1477           92 :             SetupOutputVariable(state,
    1478              :                                 "Zone Radiant HVAC Heating Fluid Energy",
    1479              :                                 Constant::Units::J,
    1480           46 :                                 thisHydrSys.HeatEnergy,
    1481              :                                 OutputProcessor::TimeStepType::System,
    1482              :                                 OutputProcessor::StoreType::Sum,
    1483           46 :                                 thisHydrSys.Name,
    1484              :                                 Constant::eResource::PlantLoopHeatingDemand,
    1485              :                                 OutputProcessor::Group::HVAC,
    1486              :                                 OutputProcessor::EndUseCat::HeatingCoils);
    1487           92 :             SetupOutputVariable(state,
    1488              :                                 "Zone Radiant HVAC Cooling Rate",
    1489              :                                 Constant::Units::W,
    1490           46 :                                 thisHydrSys.CoolPower,
    1491              :                                 OutputProcessor::TimeStepType::System,
    1492              :                                 OutputProcessor::StoreType::Average,
    1493           46 :                                 thisHydrSys.Name);
    1494              : 
    1495           92 :             SetupOutputVariable(state,
    1496              :                                 "Zone Radiant HVAC Cooling Energy",
    1497              :                                 Constant::Units::J,
    1498           46 :                                 thisHydrSys.CoolEnergy,
    1499              :                                 OutputProcessor::TimeStepType::System,
    1500              :                                 OutputProcessor::StoreType::Sum,
    1501           46 :                                 thisHydrSys.Name,
    1502              :                                 Constant::eResource::EnergyTransfer,
    1503              :                                 OutputProcessor::Group::HVAC,
    1504              :                                 OutputProcessor::EndUseCat::CoolingCoils);
    1505           92 :             SetupOutputVariable(state,
    1506              :                                 "Zone Radiant HVAC Cooling Fluid Energy",
    1507              :                                 Constant::Units::J,
    1508           46 :                                 thisHydrSys.CoolEnergy,
    1509              :                                 OutputProcessor::TimeStepType::System,
    1510              :                                 OutputProcessor::StoreType::Sum,
    1511           46 :                                 thisHydrSys.Name,
    1512              :                                 Constant::eResource::PlantLoopCoolingDemand,
    1513              :                                 OutputProcessor::Group::HVAC,
    1514              :                                 OutputProcessor::EndUseCat::CoolingCoils);
    1515           92 :             SetupOutputVariable(state,
    1516              :                                 "Zone Radiant HVAC Mass Flow Rate",
    1517              :                                 Constant::Units::kg_s,
    1518           46 :                                 thisHydrSys.WaterMassFlowRate,
    1519              :                                 OutputProcessor::TimeStepType::System,
    1520              :                                 OutputProcessor::StoreType::Average,
    1521           46 :                                 thisHydrSys.Name);
    1522           92 :             SetupOutputVariable(state,
    1523              :                                 "Zone Radiant HVAC Inlet Temperature",
    1524              :                                 Constant::Units::C,
    1525           46 :                                 thisHydrSys.WaterInletTemp,
    1526              :                                 OutputProcessor::TimeStepType::System,
    1527              :                                 OutputProcessor::StoreType::Average,
    1528           46 :                                 thisHydrSys.Name);
    1529           92 :             SetupOutputVariable(state,
    1530              :                                 "Zone Radiant HVAC Outlet Temperature",
    1531              :                                 Constant::Units::C,
    1532           46 :                                 thisHydrSys.WaterOutletTemp,
    1533              :                                 OutputProcessor::TimeStepType::System,
    1534              :                                 OutputProcessor::StoreType::Average,
    1535           46 :                                 thisHydrSys.Name);
    1536           92 :             SetupOutputVariable(state,
    1537              :                                 "Zone Radiant HVAC Moisture Condensation Time",
    1538              :                                 Constant::Units::s,
    1539           46 :                                 thisHydrSys.CondCausedTimeOff,
    1540              :                                 OutputProcessor::TimeStepType::System,
    1541              :                                 OutputProcessor::StoreType::Sum,
    1542           46 :                                 thisHydrSys.Name);
    1543           46 :             SetupOutputVariable(state,
    1544              :                                 "Zone Radiant HVAC Operation Mode",
    1545              :                                 Constant::Units::None,
    1546           46 :                                 (int &)thisHydrSys.opMode,
    1547              :                                 OutputProcessor::TimeStepType::System,
    1548              :                                 OutputProcessor::StoreType::Average,
    1549           46 :                                 thisHydrSys.Name);
    1550           46 :             if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
    1551            0 :                 SetupEMSInternalVariable(state,
    1552              :                                          "Hydronic Low Temp Radiant Design Water Volume Flow Rate for Heating",
    1553              :                                          thisHydrSys.Name,
    1554              :                                          "[m3/s]",
    1555            0 :                                          thisHydrSys.WaterVolFlowMaxHeat);
    1556            0 :                 SetupEMSInternalVariable(state,
    1557              :                                          "Hydronic Low Temp Radiant Design Water Volume Flow Rate for Cooling",
    1558              :                                          thisHydrSys.Name,
    1559              :                                          "[m3/s]",
    1560            0 :                                          thisHydrSys.WaterVolFlowMaxCool);
    1561            0 :                 SetupEMSActuator(state,
    1562              :                                  "Hydronic Low Temp Radiant",
    1563              :                                  thisHydrSys.Name,
    1564              :                                  "Water Mass Flow Rate",
    1565              :                                  "[kg/s]",
    1566            0 :                                  thisHydrSys.EMSOverrideOnWaterMdot,
    1567            0 :                                  thisHydrSys.EMSWaterMdotOverrideValue);
    1568              :             }
    1569              :         }
    1570              : 
    1571              :         // Set up the output variables for low temperature radiant systems
    1572              :         // ZoneHVAC:LowTemperatureRadiant:ConstantFlow (CFloRadSys)
    1573           56 :         for (Item = 1; Item <= state.dataLowTempRadSys->NumOfCFloLowTempRadSys; ++Item) {
    1574              : 
    1575           27 :             auto &thisCFloSys = state.dataLowTempRadSys->CFloRadSys(Item);
    1576              : 
    1577           54 :             SetupOutputVariable(state,
    1578              :                                 "Zone Radiant HVAC Heating Rate",
    1579              :                                 Constant::Units::W,
    1580           27 :                                 thisCFloSys.HeatPower,
    1581              :                                 OutputProcessor::TimeStepType::System,
    1582              :                                 OutputProcessor::StoreType::Average,
    1583           27 :                                 thisCFloSys.Name);
    1584           54 :             SetupOutputVariable(state,
    1585              :                                 "Zone Radiant HVAC Heating Energy",
    1586              :                                 Constant::Units::J,
    1587           27 :                                 thisCFloSys.HeatEnergy,
    1588              :                                 OutputProcessor::TimeStepType::System,
    1589              :                                 OutputProcessor::StoreType::Sum,
    1590           27 :                                 thisCFloSys.Name,
    1591              :                                 Constant::eResource::EnergyTransfer,
    1592              :                                 OutputProcessor::Group::HVAC,
    1593              :                                 OutputProcessor::EndUseCat::HeatingCoils);
    1594           54 :             SetupOutputVariable(state,
    1595              :                                 "Zone Radiant HVAC Heating Fluid Heat Transfer Energy",
    1596              :                                 Constant::Units::J,
    1597           27 :                                 thisCFloSys.HeatEnergy,
    1598              :                                 OutputProcessor::TimeStepType::System,
    1599              :                                 OutputProcessor::StoreType::Sum,
    1600           27 :                                 thisCFloSys.Name,
    1601              :                                 Constant::eResource::PlantLoopHeatingDemand,
    1602              :                                 OutputProcessor::Group::HVAC,
    1603              :                                 OutputProcessor::EndUseCat::HeatingCoils);
    1604           54 :             SetupOutputVariable(state,
    1605              :                                 "Zone Radiant HVAC Cooling Rate",
    1606              :                                 Constant::Units::W,
    1607           27 :                                 thisCFloSys.CoolPower,
    1608              :                                 OutputProcessor::TimeStepType::System,
    1609              :                                 OutputProcessor::StoreType::Average,
    1610           27 :                                 thisCFloSys.Name);
    1611           54 :             SetupOutputVariable(state,
    1612              :                                 "Zone Radiant HVAC Cooling Energy",
    1613              :                                 Constant::Units::J,
    1614           27 :                                 thisCFloSys.CoolEnergy,
    1615              :                                 OutputProcessor::TimeStepType::System,
    1616              :                                 OutputProcessor::StoreType::Sum,
    1617           27 :                                 thisCFloSys.Name,
    1618              :                                 Constant::eResource::EnergyTransfer,
    1619              :                                 OutputProcessor::Group::HVAC,
    1620              :                                 OutputProcessor::EndUseCat::CoolingCoils);
    1621           54 :             SetupOutputVariable(state,
    1622              :                                 "Zone Radiant HVAC Cooling Fluid Heat Transfer Energy",
    1623              :                                 Constant::Units::J,
    1624           27 :                                 thisCFloSys.CoolEnergy,
    1625              :                                 OutputProcessor::TimeStepType::System,
    1626              :                                 OutputProcessor::StoreType::Sum,
    1627           27 :                                 thisCFloSys.Name,
    1628              :                                 Constant::eResource::PlantLoopCoolingDemand,
    1629              :                                 OutputProcessor::Group::HVAC,
    1630              :                                 OutputProcessor::EndUseCat::CoolingCoils);
    1631           54 :             SetupOutputVariable(state,
    1632              :                                 "Zone Radiant HVAC Mass Flow Rate",
    1633              :                                 Constant::Units::kg_s,
    1634           27 :                                 thisCFloSys.WaterMassFlowRate,
    1635              :                                 OutputProcessor::TimeStepType::System,
    1636              :                                 OutputProcessor::StoreType::Average,
    1637           27 :                                 thisCFloSys.Name);
    1638           54 :             SetupOutputVariable(state,
    1639              :                                 "Zone Radiant HVAC Injection Mass Flow Rate",
    1640              :                                 Constant::Units::kg_s,
    1641           27 :                                 thisCFloSys.WaterInjectionRate,
    1642              :                                 OutputProcessor::TimeStepType::System,
    1643              :                                 OutputProcessor::StoreType::Average,
    1644           27 :                                 thisCFloSys.Name);
    1645           54 :             SetupOutputVariable(state,
    1646              :                                 "Zone Radiant HVAC Recirculation Mass Flow Rate",
    1647              :                                 Constant::Units::kg_s,
    1648           27 :                                 thisCFloSys.WaterRecircRate,
    1649              :                                 OutputProcessor::TimeStepType::System,
    1650              :                                 OutputProcessor::StoreType::Average,
    1651           27 :                                 thisCFloSys.Name);
    1652           54 :             SetupOutputVariable(state,
    1653              :                                 "Zone Radiant HVAC Inlet Temperature",
    1654              :                                 Constant::Units::C,
    1655           27 :                                 thisCFloSys.WaterInletTemp,
    1656              :                                 OutputProcessor::TimeStepType::System,
    1657              :                                 OutputProcessor::StoreType::Average,
    1658           27 :                                 thisCFloSys.Name);
    1659           54 :             SetupOutputVariable(state,
    1660              :                                 "Zone Radiant HVAC Outlet Temperature",
    1661              :                                 Constant::Units::C,
    1662           27 :                                 thisCFloSys.WaterOutletTemp,
    1663              :                                 OutputProcessor::TimeStepType::System,
    1664              :                                 OutputProcessor::StoreType::Average,
    1665           27 :                                 thisCFloSys.Name);
    1666           54 :             SetupOutputVariable(state,
    1667              :                                 "Zone Radiant HVAC Pump Inlet Temperature",
    1668              :                                 Constant::Units::C,
    1669           27 :                                 thisCFloSys.PumpInletTemp,
    1670              :                                 OutputProcessor::TimeStepType::System,
    1671              :                                 OutputProcessor::StoreType::Average,
    1672           27 :                                 thisCFloSys.Name);
    1673           54 :             SetupOutputVariable(state,
    1674              :                                 "Zone Radiant HVAC Pump Electricity Rate",
    1675              :                                 Constant::Units::W,
    1676           27 :                                 thisCFloSys.PumpPower,
    1677              :                                 OutputProcessor::TimeStepType::System,
    1678              :                                 OutputProcessor::StoreType::Average,
    1679           27 :                                 thisCFloSys.Name);
    1680           54 :             SetupOutputVariable(state,
    1681              :                                 "Zone Radiant HVAC Pump Electricity Energy",
    1682              :                                 Constant::Units::J,
    1683           27 :                                 thisCFloSys.PumpEnergy,
    1684              :                                 OutputProcessor::TimeStepType::System,
    1685              :                                 OutputProcessor::StoreType::Sum,
    1686           27 :                                 thisCFloSys.Name,
    1687              :                                 Constant::eResource::Electricity,
    1688              :                                 OutputProcessor::Group::Plant,
    1689              :                                 OutputProcessor::EndUseCat::Pumps);
    1690           54 :             SetupOutputVariable(state,
    1691              :                                 "Zone Radiant HVAC Pump Mass Flow Rate",
    1692              :                                 Constant::Units::kg_s,
    1693           27 :                                 thisCFloSys.PumpMassFlowRate,
    1694              :                                 OutputProcessor::TimeStepType::System,
    1695              :                                 OutputProcessor::StoreType::Average,
    1696           27 :                                 thisCFloSys.Name);
    1697           54 :             SetupOutputVariable(state,
    1698              :                                 "Zone Radiant HVAC Pump Fluid Heat Gain Rate",
    1699              :                                 Constant::Units::W,
    1700           27 :                                 thisCFloSys.PumpHeattoFluid,
    1701              :                                 OutputProcessor::TimeStepType::System,
    1702              :                                 OutputProcessor::StoreType::Average,
    1703           27 :                                 thisCFloSys.Name);
    1704           54 :             SetupOutputVariable(state,
    1705              :                                 "Zone Radiant HVAC Pump Fluid Heat Gain Energy",
    1706              :                                 Constant::Units::J,
    1707           27 :                                 thisCFloSys.PumpHeattoFluidEnergy,
    1708              :                                 OutputProcessor::TimeStepType::System,
    1709              :                                 OutputProcessor::StoreType::Sum,
    1710           27 :                                 thisCFloSys.Name);
    1711           54 :             SetupOutputVariable(state,
    1712              :                                 "Zone Radiant HVAC Moisture Condensation Time",
    1713              :                                 Constant::Units::s,
    1714           27 :                                 thisCFloSys.CondCausedTimeOff,
    1715              :                                 OutputProcessor::TimeStepType::System,
    1716              :                                 OutputProcessor::StoreType::Sum,
    1717           27 :                                 thisCFloSys.Name);
    1718           27 :             SetupOutputVariable(state,
    1719              :                                 "Zone Radiant HVAC Operation Mode",
    1720              :                                 Constant::Units::None,
    1721           27 :                                 (int &)thisCFloSys.opMode,
    1722              :                                 OutputProcessor::TimeStepType::System,
    1723              :                                 OutputProcessor::StoreType::Average,
    1724           27 :                                 thisCFloSys.Name);
    1725           27 :             if (state.dataLowTempRadSys->anyRadiantSystemUsingRunningMeanAverage) {
    1726            6 :                 SetupOutputVariable(state,
    1727              :                                     "Zone Radiant HVAC Running Mean Outdoor Dry-Bulb Temperature",
    1728              :                                     Constant::Units::C,
    1729            3 :                                     thisCFloSys.todayRunningMeanOutdoorDryBulbTemperature,
    1730              :                                     OutputProcessor::TimeStepType::System,
    1731              :                                     OutputProcessor::StoreType::Average,
    1732            3 :                                     thisCFloSys.Name);
    1733            6 :                 SetupOutputVariable(state,
    1734              :                                     "Zone Radiant HVAC Previous Day Running Mean Outdoor Dry-Bulb Temperature",
    1735              :                                     Constant::Units::C,
    1736            3 :                                     thisCFloSys.yesterdayRunningMeanOutdoorDryBulbTemperature,
    1737              :                                     OutputProcessor::TimeStepType::System,
    1738              :                                     OutputProcessor::StoreType::Average,
    1739            3 :                                     thisCFloSys.Name);
    1740            6 :                 SetupOutputVariable(state,
    1741              :                                     "Zone Radiant HVAC Previous Day Average Outdoor Dry-Bulb Temperature",
    1742              :                                     Constant::Units::C,
    1743            3 :                                     thisCFloSys.yesterdayAverageOutdoorDryBulbTemperature,
    1744              :                                     OutputProcessor::TimeStepType::System,
    1745              :                                     OutputProcessor::StoreType::Average,
    1746            3 :                                     thisCFloSys.Name);
    1747              :             }
    1748           27 :             if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
    1749            0 :                 SetupEMSInternalVariable(
    1750            0 :                     state, "Constant Flow Low Temp Radiant Design Water Mass Flow Rate", thisCFloSys.Name, "[m3/s]", thisCFloSys.WaterVolFlowMax);
    1751            0 :                 SetupEMSActuator(state,
    1752              :                                  "Constant Flow Low Temp Radiant",
    1753              :                                  thisCFloSys.Name,
    1754              :                                  "Water Mass Flow Rate",
    1755              :                                  "[kg/s]",
    1756            0 :                                  thisCFloSys.EMSOverrideOnWaterMdot,
    1757            0 :                                  thisCFloSys.EMSWaterMdotOverrideValue);
    1758              :             }
    1759              :         }
    1760              : 
    1761           38 :         for (Item = 1; Item <= state.dataLowTempRadSys->NumOfElecLowTempRadSys; ++Item) {
    1762              :             // Set up the output variables for low temperature radiant systems
    1763              :             // ZoneHVAC:LowTemperatureRadiant:Electric (ElecRadSys)
    1764              : 
    1765            9 :             auto &thisElecSys = state.dataLowTempRadSys->ElecRadSys(Item);
    1766              : 
    1767           18 :             SetupOutputVariable(state,
    1768              :                                 "Zone Radiant HVAC Electricity Rate",
    1769              :                                 Constant::Units::W,
    1770            9 :                                 thisElecSys.ElecPower,
    1771              :                                 OutputProcessor::TimeStepType::System,
    1772              :                                 OutputProcessor::StoreType::Average,
    1773            9 :                                 thisElecSys.Name);
    1774           18 :             SetupOutputVariable(state,
    1775              :                                 "Zone Radiant HVAC Electricity Energy",
    1776              :                                 Constant::Units::J,
    1777            9 :                                 thisElecSys.ElecEnergy,
    1778              :                                 OutputProcessor::TimeStepType::System,
    1779              :                                 OutputProcessor::StoreType::Sum,
    1780            9 :                                 thisElecSys.Name,
    1781              :                                 Constant::eResource::Electricity,
    1782              :                                 OutputProcessor::Group::HVAC,
    1783              :                                 OutputProcessor::EndUseCat::Heating);
    1784           18 :             SetupOutputVariable(state,
    1785              :                                 "Zone Radiant HVAC Heating Rate",
    1786              :                                 Constant::Units::W,
    1787            9 :                                 thisElecSys.HeatPower,
    1788              :                                 OutputProcessor::TimeStepType::System,
    1789              :                                 OutputProcessor::StoreType::Average,
    1790            9 :                                 thisElecSys.Name);
    1791           18 :             SetupOutputVariable(state,
    1792              :                                 "Zone Radiant HVAC Heating Energy",
    1793              :                                 Constant::Units::J,
    1794            9 :                                 thisElecSys.HeatEnergy,
    1795              :                                 OutputProcessor::TimeStepType::System,
    1796              :                                 OutputProcessor::StoreType::Sum,
    1797            9 :                                 thisElecSys.Name,
    1798              :                                 Constant::eResource::EnergyTransfer,
    1799              :                                 OutputProcessor::Group::HVAC,
    1800              :                                 OutputProcessor::EndUseCat::HeatingCoils);
    1801              :         }
    1802           29 :     }
    1803              : 
    1804           82 :     void RadiantSystemBaseData::errorCheckZonesAndConstructions(EnergyPlusData &state, bool &errorsFound)
    1805              :     {
    1806           82 :         auto &Zone = state.dataHeatBal->Zone;
    1807           82 :         auto &Surface = state.dataSurface->Surface;
    1808              : 
    1809           82 :         Real64 zoneMultipliers = 0.0;
    1810           82 :         Real64 zoneMultipliersSurface = 0.0;
    1811           82 :         Real64 zoneMultiplersTolerance = 0.001;
    1812          176 :         for (int SurfNum = 1; SurfNum <= this->NumOfSurfaces; ++SurfNum) {
    1813              : 
    1814           94 :             if (this->SurfacePtr(SurfNum) == 0) {
    1815            0 :                 continue; // invalid surface -- detected earlier
    1816              :             }
    1817              : 
    1818           94 :             if (state.dataGlobal->DisplayExtraWarnings) {
    1819              :                 // check zone numbers--ok if they are not the same
    1820              :                 // group warning issued earlier, show detailed warning here
    1821            0 :                 if (Surface(this->SurfacePtr(SurfNum)).Zone != this->ZonePtr) {
    1822            0 :                     ShowWarningError(state,
    1823              :                                      "A surface referenced in a Low Temperature Radiant System is not in same zone as the radiant system itself");
    1824            0 :                     ShowContinueError(state, format("Surface = {}", Surface(this->SurfacePtr(SurfNum)).Name));
    1825            0 :                     ShowContinueError(state,
    1826            0 :                                       format("Surface in Zone = {}. Radiant System in Zone = {}",
    1827            0 :                                              Zone(Surface(this->SurfacePtr(SurfNum)).Zone).Name,
    1828            0 :                                              this->ZoneName));
    1829            0 :                     ShowContinueError(state, format("Occurs in Low Temperature Radiant System = {}", this->Name));
    1830            0 :                     ShowContinueError(state, "If this is intentionally a radiant system with surfaces in more than one thermal zone,");
    1831            0 :                     ShowContinueError(state, "then ignore this warning message.  Otherwise, check the surfaces in this radiant system.");
    1832              :                 }
    1833              :             }
    1834              : 
    1835              :             // check zone multipliers--these must be the same
    1836           94 :             if (SurfNum == 1) {
    1837           82 :                 zoneMultipliers = double(Zone(this->ZonePtr).Multiplier) * double(Zone(this->ZonePtr).ListMultiplier);
    1838              :             }
    1839           94 :             zoneMultipliersSurface = double(Zone(Surface(this->SurfacePtr(SurfNum)).Zone).Multiplier) *
    1840           94 :                                      double(Zone(Surface(this->SurfacePtr(SurfNum)).Zone).ListMultiplier);
    1841           94 :             if (std::abs(zoneMultipliers - zoneMultipliersSurface) > zoneMultiplersTolerance) {
    1842            0 :                 ShowSevereError(state, "The zone multipliers are not the same for all surfaces contained in this radiant system");
    1843            0 :                 ShowContinueError(state, "This is not allowed and must be fixed for the simulation to run.");
    1844            0 :                 ShowContinueError(state, format("Occurs in Low Temperature Radiant System = {}", this->Name));
    1845            0 :                 errorsFound = true;
    1846              :             }
    1847              : 
    1848              :             // make sure that this construction is defined with a source/sink--this must be the case or it can't serve as a radiant system surface
    1849           94 :             if (!state.dataConstruction->Construct(Surface(this->SurfacePtr(SurfNum)).Construction).SourceSinkPresent) {
    1850            0 :                 ShowSevereError(state, "Construction referenced in Radiant System Surface does not have a source/sink present");
    1851            0 :                 ShowContinueError(state,
    1852            0 :                                   format("Surface name= {}  Construction name = {}",
    1853            0 :                                          Surface(this->SurfacePtr(SurfNum)).Name,
    1854            0 :                                          state.dataConstruction->Construct(Surface(this->SurfacePtr(SurfNum)).Construction).Name));
    1855            0 :                 ShowContinueError(state, "Construction needs to be referenced by a \"ConstructionProperty:InternalHeatSource\" object.");
    1856            0 :                 errorsFound = true;
    1857              :             }
    1858              :         }
    1859           82 :     }
    1860              : 
    1861       666848 :     void InitLowTempRadiantSystem(EnergyPlusData &state,
    1862              :                                   bool const FirstHVACIteration, // TRUE if 1st HVAC simulation of system timestep
    1863              :                                   int const RadSysNum, // Index for the low temperature radiant system under consideration within the derived types
    1864              :                                   SystemType const systemType, // Type of radiant system: hydronic, constant flow, or electric
    1865              :                                   bool &InitErrorsFound)
    1866              :     {
    1867              : 
    1868              :         // SUBROUTINE INFORMATION:
    1869              :         //       AUTHOR         Rick Strand
    1870              :         //       DATE WRITTEN   November 2000
    1871              : 
    1872              :         // Using/Aliasing
    1873              : 
    1874              :         using DataSizing::AutoSize;
    1875              :         using DataZoneEquipment::CheckZoneEquipmentList;
    1876              : 
    1877              :         using PlantUtilities::InitComponentNodes;
    1878              :         using PlantUtilities::ScanPlantLoopsForObject;
    1879              :         using PlantUtilities::SetComponentFlowRate;
    1880              : 
    1881              :         // SUBROUTINE PARAMETER DEFINITIONS:
    1882       666848 :         Real64 constexpr ZeroTol(0.0000001); // Smallest non-zero value allowed
    1883       666848 :         constexpr std::string_view RoutineName("InitLowTempRadiantSystem");
    1884              : 
    1885              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1886              :         Real64 CurrentFlowSchedule; // Schedule value for flow fraction in a constant flow radiant system
    1887              :         Real64 TotalEffic;          // Intermediate calculation variable for total pump efficiency
    1888              :         Real64 mdot;                // local fluid mass flow rate
    1889              :         Real64 rho;                 // local fluid density
    1890              :         bool errFlag;
    1891              : 
    1892       666848 :         InitErrorsFound = false;
    1893              : 
    1894       666848 :         auto const &Surface = state.dataSurface->Surface;
    1895              : 
    1896       666848 :         if (state.dataLowTempRadSys->MyOneTimeFlag) {
    1897           29 :             state.dataLowTempRadSys->MyEnvrnFlagHydr.allocate(state.dataLowTempRadSys->NumOfHydrLowTempRadSys);
    1898           29 :             state.dataLowTempRadSys->MyEnvrnFlagCFlo.allocate(state.dataLowTempRadSys->NumOfCFloLowTempRadSys);
    1899           29 :             state.dataLowTempRadSys->MyEnvrnFlagElec.allocate(state.dataLowTempRadSys->NumOfElecLowTempRadSys);
    1900           29 :             state.dataLowTempRadSys->MyPlantScanFlagHydr.allocate(state.dataLowTempRadSys->NumOfHydrLowTempRadSys);
    1901           29 :             state.dataLowTempRadSys->MyPlantScanFlagCFlo.allocate(state.dataLowTempRadSys->NumOfCFloLowTempRadSys);
    1902           29 :             state.dataLowTempRadSys->MyPlantScanFlagHydr = true;
    1903           29 :             state.dataLowTempRadSys->MyPlantScanFlagCFlo = true;
    1904           29 :             state.dataLowTempRadSys->MyEnvrnFlagHydr = true;
    1905           29 :             state.dataLowTempRadSys->MyEnvrnFlagCFlo = true;
    1906           29 :             state.dataLowTempRadSys->MyEnvrnFlagElec = true;
    1907           29 :             state.dataLowTempRadSys->MyOneTimeFlag = false;
    1908              :         }
    1909              : 
    1910       666848 :         if (state.dataLowTempRadSys->FirstTimeInit) {
    1911              : 
    1912           75 :             for (auto &thisLTRSys : state.dataLowTempRadSys->HydrRadSys) {
    1913           46 :                 thisLTRSys.QRadSysSrcAvg.dimension(thisLTRSys.NumOfSurfaces, 0.0);
    1914           46 :                 thisLTRSys.LastQRadSysSrc.dimension(thisLTRSys.NumOfSurfaces, 0.0);
    1915           46 :                 thisLTRSys.LastSysTimeElapsed = 0.0;
    1916           46 :                 thisLTRSys.LastTimeStepSys = 0.0;
    1917              :             }
    1918           56 :             for (auto &thisCFLTRSys : state.dataLowTempRadSys->CFloRadSys) {
    1919           27 :                 thisCFLTRSys.QRadSysSrcAvg.dimension(thisCFLTRSys.NumOfSurfaces, 0.0);
    1920           27 :                 thisCFLTRSys.LastQRadSysSrc.dimension(thisCFLTRSys.NumOfSurfaces, 0.0);
    1921           27 :                 thisCFLTRSys.LastSysTimeElapsed = 0.0;
    1922           27 :                 thisCFLTRSys.LastTimeStepSys = 0.0;
    1923              :             }
    1924           38 :             for (auto &thisELTRSys : state.dataLowTempRadSys->ElecRadSys) {
    1925            9 :                 thisELTRSys.QRadSysSrcAvg.dimension(thisELTRSys.NumOfSurfaces, 0.0);
    1926            9 :                 thisELTRSys.LastQRadSysSrc.dimension(thisELTRSys.NumOfSurfaces, 0.0);
    1927            9 :                 thisELTRSys.LastSysTimeElapsed = 0.0;
    1928            9 :                 thisELTRSys.LastTimeStepSys = 0.0;
    1929              :             }
    1930           29 :             state.dataLowTempRadSys->MySizeFlagHydr.allocate(state.dataLowTempRadSys->NumOfHydrLowTempRadSys);
    1931           29 :             state.dataLowTempRadSys->MySizeFlagCFlo.allocate(state.dataLowTempRadSys->NumOfCFloLowTempRadSys);
    1932           29 :             state.dataLowTempRadSys->MySizeFlagElec.allocate(state.dataLowTempRadSys->NumOfElecLowTempRadSys);
    1933           29 :             state.dataLowTempRadSys->MySizeFlagHydr = true;
    1934           29 :             state.dataLowTempRadSys->MySizeFlagCFlo = true;
    1935           29 :             state.dataLowTempRadSys->MySizeFlagElec = true;
    1936              : 
    1937              :             // Initialize total areas and ZeroLTRSource for all radiant systems
    1938           75 :             for (auto &thisHRadSys : state.dataLowTempRadSys->HydrRadSys) {
    1939           46 :                 thisHRadSys.ZeroLTRSourceSumHATsurf = 0.0;
    1940           46 :                 thisHRadSys.TotalSurfaceArea = 0.0;
    1941          104 :                 for (int SurfNum = 1; SurfNum <= thisHRadSys.NumOfSurfaces; ++SurfNum) {
    1942           58 :                     thisHRadSys.TotalSurfaceArea += Surface(thisHRadSys.SurfacePtr(SurfNum)).Area;
    1943              :                 }
    1944              :             }
    1945           56 :             for (auto &thisCFLRadSys : state.dataLowTempRadSys->CFloRadSys) {
    1946           27 :                 thisCFLRadSys.ZeroLTRSourceSumHATsurf = 0.0;
    1947           27 :                 thisCFLRadSys.TotalSurfaceArea = 0.0;
    1948           54 :                 for (int SurfNum = 1; SurfNum <= thisCFLRadSys.NumOfSurfaces; ++SurfNum) {
    1949           27 :                     thisCFLRadSys.TotalSurfaceArea += Surface(thisCFLRadSys.SurfacePtr(SurfNum)).Area;
    1950              :                 }
    1951              :             }
    1952           38 :             for (auto &thisERadSys : state.dataLowTempRadSys->ElecRadSys) {
    1953            9 :                 thisERadSys.ZeroLTRSourceSumHATsurf = 0.0;
    1954            9 :                 thisERadSys.TotalSurfaceArea = 0.0;
    1955           18 :                 for (int SurfNum = 1; SurfNum <= thisERadSys.NumOfSurfaces; ++SurfNum) {
    1956            9 :                     thisERadSys.TotalSurfaceArea += Surface(thisERadSys.SurfacePtr(SurfNum)).Area;
    1957              :                 }
    1958              :             }
    1959              : 
    1960           29 :             Real64 MotorEffic(0.0);
    1961           29 :             if (systemType == SystemType::ConstantFlow) {
    1962              :                 // Is there a reason why we were making a copy of this object?
    1963            9 :                 MotorEffic =
    1964            9 :                     state.dataLowTempRadSys->CflowRadiantSysDesign(state.dataLowTempRadSys->CFloRadSys(RadSysNum).DesignObjectPtr).MotorEffic;
    1965              :             }
    1966              : 
    1967              :             // Check pump parameters for constant flow hydronic radiant systems
    1968           56 :             for (auto &thisCFLRadSys : state.dataLowTempRadSys->CFloRadSys) {
    1969              :                 // Calculate the efficiency for each pump: The calculation
    1970              :                 // is based on the PMPSIM code in the ASHRAE Secondary Toolkit
    1971           27 :                 if ((thisCFLRadSys.NomPowerUse > ZeroTol) && (MotorEffic > ZeroTol) && (thisCFLRadSys.WaterVolFlowMax != AutoSize)) {
    1972           26 :                     TotalEffic = thisCFLRadSys.WaterVolFlowMax * thisCFLRadSys.NomPumpHead / thisCFLRadSys.NomPowerUse;
    1973           26 :                     thisCFLRadSys.PumpEffic = TotalEffic / MotorEffic;
    1974           26 :                     constexpr std::string_view fmt = "Check input.  Calc Pump Efficiency={:.5R}% {}, for pump in radiant system {}";
    1975           26 :                     Real64 pumpEfficiency = thisCFLRadSys.PumpEffic * 100.0;
    1976           26 :                     if (thisCFLRadSys.PumpEffic < 0.50) {
    1977            3 :                         ShowWarningError(state, format(fmt, pumpEfficiency, "which is less than 50%", thisCFLRadSys.Name));
    1978           23 :                     } else if ((thisCFLRadSys.PumpEffic > 0.95) && (thisCFLRadSys.PumpEffic <= 1.0)) {
    1979            0 :                         ShowWarningError(state, format(fmt, pumpEfficiency, "is approaching 100%", thisCFLRadSys.Name));
    1980           23 :                     } else if (thisCFLRadSys.PumpEffic > 1.0) {
    1981            0 :                         ShowSevereError(state, format(fmt, pumpEfficiency, "which is bigger than 100%", thisCFLRadSys.Name));
    1982            0 :                         InitErrorsFound = true;
    1983              :                     }
    1984           26 :                 } else {
    1985              :                     // Autosize is not an error but it does not need to check pump efficiency here
    1986            1 :                     if (thisCFLRadSys.WaterVolFlowMax != AutoSize) {
    1987            0 :                         ShowSevereError(state,
    1988            0 :                                         format("Check input.  Pump nominal power and motor efficiency cannot be 0, for pump={}", thisCFLRadSys.Name));
    1989            0 :                         InitErrorsFound = true;
    1990              :                     }
    1991              :                 }
    1992              :             }
    1993              : 
    1994           29 :             state.dataLowTempRadSys->FirstTimeInit = false;
    1995              :         }
    1996              : 
    1997       666848 :         if (systemType == SystemType::Hydronic) {
    1998       366056 :             if (state.dataLowTempRadSys->MyPlantScanFlagHydr(RadSysNum) && allocated(state.dataPlnt->PlantLoop)) {
    1999           46 :                 errFlag = false;
    2000           46 :                 if (state.dataLowTempRadSys->HydrRadSys(RadSysNum).HotWaterInNode > 0) {
    2001          138 :                     ScanPlantLoopsForObject(state,
    2002           46 :                                             state.dataLowTempRadSys->HydrRadSys(RadSysNum).Name,
    2003              :                                             DataPlant::PlantEquipmentType::LowTempRadiant_VarFlow,
    2004           46 :                                             state.dataLowTempRadSys->HydrRadSys(RadSysNum).HWPlantLoc,
    2005              :                                             errFlag,
    2006              :                                             _,
    2007              :                                             _,
    2008              :                                             _,
    2009           46 :                                             state.dataLowTempRadSys->HydrRadSys(RadSysNum).HotWaterInNode,
    2010              :                                             _);
    2011           46 :                     if (errFlag) {
    2012            0 :                         ShowFatalError(state, "InitLowTempRadiantSystem: Program terminated due to previous condition(s).");
    2013              :                     }
    2014              :                 }
    2015           46 :                 if (state.dataLowTempRadSys->HydrRadSys(RadSysNum).ColdWaterInNode > 0) {
    2016          129 :                     ScanPlantLoopsForObject(state,
    2017           43 :                                             state.dataLowTempRadSys->HydrRadSys(RadSysNum).Name,
    2018              :                                             DataPlant::PlantEquipmentType::LowTempRadiant_VarFlow,
    2019           43 :                                             state.dataLowTempRadSys->HydrRadSys(RadSysNum).CWPlantLoc,
    2020              :                                             errFlag,
    2021              :                                             _,
    2022              :                                             _,
    2023              :                                             _,
    2024           43 :                                             state.dataLowTempRadSys->HydrRadSys(RadSysNum).ColdWaterInNode,
    2025              :                                             _);
    2026           43 :                     if (errFlag) {
    2027            0 :                         ShowFatalError(state, "InitLowTempRadiantSystem: Program terminated due to previous condition(s).");
    2028              :                     }
    2029              :                 }
    2030           46 :                 state.dataLowTempRadSys->MyPlantScanFlagHydr(RadSysNum) = false;
    2031       366010 :             } else if (state.dataLowTempRadSys->MyPlantScanFlagHydr(RadSysNum) && !state.dataGlobal->AnyPlantInModel) {
    2032            0 :                 state.dataLowTempRadSys->MyPlantScanFlagHydr(RadSysNum) = false;
    2033              :             }
    2034              : 
    2035       300792 :         } else if (systemType == SystemType::ConstantFlow) {
    2036       221733 :             if (state.dataLowTempRadSys->MyPlantScanFlagCFlo(RadSysNum) && allocated(state.dataPlnt->PlantLoop)) {
    2037           27 :                 errFlag = false;
    2038           27 :                 if (state.dataLowTempRadSys->CFloRadSys(RadSysNum).HotWaterInNode > 0) {
    2039           81 :                     ScanPlantLoopsForObject(state,
    2040           27 :                                             state.dataLowTempRadSys->CFloRadSys(RadSysNum).Name,
    2041              :                                             DataPlant::PlantEquipmentType::LowTempRadiant_ConstFlow,
    2042           27 :                                             state.dataLowTempRadSys->CFloRadSys(RadSysNum).HWPlantLoc,
    2043              :                                             errFlag,
    2044              :                                             _,
    2045              :                                             _,
    2046              :                                             _,
    2047           27 :                                             state.dataLowTempRadSys->CFloRadSys(RadSysNum).HotWaterInNode,
    2048              :                                             _);
    2049           27 :                     if (errFlag) {
    2050            0 :                         ShowFatalError(state, "InitLowTempRadiantSystem: Program terminated due to previous condition(s).");
    2051              :                     }
    2052              :                 }
    2053           27 :                 if (state.dataLowTempRadSys->CFloRadSys(RadSysNum).ColdWaterInNode > 0) {
    2054           72 :                     ScanPlantLoopsForObject(state,
    2055           24 :                                             state.dataLowTempRadSys->CFloRadSys(RadSysNum).Name,
    2056              :                                             DataPlant::PlantEquipmentType::LowTempRadiant_ConstFlow,
    2057           24 :                                             state.dataLowTempRadSys->CFloRadSys(RadSysNum).CWPlantLoc,
    2058              :                                             errFlag,
    2059              :                                             _,
    2060              :                                             _,
    2061              :                                             _,
    2062           24 :                                             state.dataLowTempRadSys->CFloRadSys(RadSysNum).ColdWaterInNode,
    2063              :                                             _);
    2064           24 :                     if (errFlag) {
    2065            0 :                         ShowFatalError(state, "InitLowTempRadiantSystem: Program terminated due to previous condition(s).");
    2066              :                     }
    2067              :                 }
    2068           27 :                 state.dataLowTempRadSys->MyPlantScanFlagCFlo(RadSysNum) = false;
    2069       221706 :             } else if (state.dataLowTempRadSys->MyPlantScanFlagCFlo(RadSysNum) && !state.dataGlobal->AnyPlantInModel) {
    2070            0 :                 state.dataLowTempRadSys->MyPlantScanFlagCFlo(RadSysNum) = false;
    2071              :             }
    2072              :         }
    2073              : 
    2074              :         // need to check all units to see if they are on Zone Equipment List or issue warning
    2075       666848 :         if (!state.dataLowTempRadSys->ZoneEquipmentListChecked && state.dataZoneEquip->ZoneEquipInputsFilled) {
    2076           29 :             state.dataLowTempRadSys->ZoneEquipmentListChecked = true;
    2077          111 :             for (auto &thisRadSys : state.dataLowTempRadSys->RadSysTypes) {
    2078           82 :                 switch (thisRadSys.systemType) {
    2079           46 :                 case SystemType::Hydronic: {
    2080           46 :                     if (CheckZoneEquipmentList(state, "ZoneHVAC:LowTemperatureRadiant:VariableFlow", thisRadSys.Name)) {
    2081           46 :                         continue;
    2082              :                     }
    2083            0 :                     ShowSevereError(state,
    2084            0 :                                     format("InitLowTempRadiantSystem: Unit=[ZoneHVAC:LowTemperatureRadiant:VariableFlow,{}] is not on any "
    2085              :                                            "ZoneHVAC:EquipmentList.  It will not be simulated.",
    2086            0 :                                            thisRadSys.Name));
    2087            0 :                 } break;
    2088           27 :                 case SystemType::ConstantFlow: {
    2089           27 :                     if (CheckZoneEquipmentList(state, "ZoneHVAC:LowTemperatureRadiant:ConstantFlow", thisRadSys.Name)) {
    2090           27 :                         continue;
    2091              :                     }
    2092            0 :                     ShowSevereError(state,
    2093            0 :                                     format("InitLowTempRadiantSystem: Unit=[ZoneHVAC:LowTemperatureRadiant:ConstantFlow,{}] is not on any "
    2094              :                                            "ZoneHVAC:EquipmentList.  It will not be simulated.",
    2095            0 :                                            thisRadSys.Name));
    2096            0 :                 } break;
    2097            9 :                 case SystemType::Electric: {
    2098            9 :                     if (CheckZoneEquipmentList(state, "ZoneHVAC:LowTemperatureRadiant:Electric", thisRadSys.Name)) {
    2099            9 :                         continue;
    2100              :                     }
    2101            0 :                     ShowSevereError(state,
    2102            0 :                                     format("InitLowTempRadiantSystem: Unit=[ZoneHVAC:LowTemperatureRadiant:Electric,{}] is not on any "
    2103              :                                            "ZoneHVAC:EquipmentList.  It will not be simulated.",
    2104            0 :                                            thisRadSys.Name));
    2105            0 :                 } break;
    2106            0 :                 default: { // Illegal system, but checked earlier
    2107            0 :                 } break;
    2108              :                 }
    2109              :             }
    2110              :         }
    2111              : 
    2112       666848 :         if (!state.dataGlobal->SysSizingCalc && (systemType == SystemType::Hydronic)) {
    2113       366010 :             if (state.dataLowTempRadSys->MySizeFlagHydr(RadSysNum) && !state.dataLowTempRadSys->MyPlantScanFlagHydr(RadSysNum)) {
    2114              :                 // for each radiant system do the sizing once.
    2115           46 :                 SizeLowTempRadiantSystem(state, RadSysNum, systemType);
    2116           46 :                 state.dataLowTempRadSys->MySizeFlagHydr(RadSysNum) = false;
    2117              : 
    2118           46 :                 Sched::Schedule *coldSetptSched = nullptr, *hotSetptSched = nullptr;
    2119           46 :                 if (systemType == SystemType::Hydronic) {
    2120           46 :                     VarFlowRadDesignData variableFlowDesignDataObject{state.dataLowTempRadSys->HydronicRadiantSysDesign(
    2121           46 :                         state.dataLowTempRadSys->HydrRadSys(RadSysNum).DesignObjectPtr)}; // Contains the data for variable flow hydronic systems;
    2122           46 :                     coldSetptSched = variableFlowDesignDataObject.coolSetptSched;
    2123           46 :                     hotSetptSched = variableFlowDesignDataObject.heatSetptSched;
    2124           46 :                 }
    2125              : 
    2126              :                 // Can this system actually do cooling?
    2127           46 :                 if ((state.dataLowTempRadSys->HydrRadSys(RadSysNum).WaterVolFlowMaxCool > 0.0) &&
    2128           43 :                     (state.dataLowTempRadSys->HydrRadSys(RadSysNum).ColdWaterInNode > 0) &&
    2129           89 :                     (state.dataLowTempRadSys->HydrRadSys(RadSysNum).ColdWaterOutNode > 0) && (coldSetptSched != nullptr)) {
    2130           43 :                     state.dataLowTempRadSys->HydrRadSys(RadSysNum).CoolingSystem = true;
    2131              :                 }
    2132              : 
    2133              :                 // Can this system actually do heating?
    2134           46 :                 if ((state.dataLowTempRadSys->HydrRadSys(RadSysNum).WaterVolFlowMaxHeat > 0.0) &&
    2135           46 :                     (state.dataLowTempRadSys->HydrRadSys(RadSysNum).HotWaterInNode > 0) &&
    2136           92 :                     (state.dataLowTempRadSys->HydrRadSys(RadSysNum).HotWaterOutNode > 0) && (hotSetptSched != nullptr)) {
    2137           46 :                     state.dataLowTempRadSys->HydrRadSys(RadSysNum).HeatingSystem = true;
    2138              :                 }
    2139              : 
    2140              :                 // set design mass flow rates
    2141           46 :                 if (state.dataLowTempRadSys->HydrRadSys(RadSysNum).HotWaterInNode > 0) {
    2142           46 :                     rho = state.dataPlnt->PlantLoop(state.dataLowTempRadSys->HydrRadSys(RadSysNum).HWPlantLoc.loopNum)
    2143           46 :                               .glycol->getDensity(state, Constant::HWInitConvTemp, RoutineName);
    2144           46 :                     state.dataLowTempRadSys->HydrRadSys(RadSysNum).WaterFlowMaxHeat =
    2145           46 :                         rho * state.dataLowTempRadSys->HydrRadSys(RadSysNum).WaterVolFlowMaxHeat;
    2146          138 :                     InitComponentNodes(state,
    2147              :                                        0.0,
    2148           46 :                                        state.dataLowTempRadSys->HydrRadSys(RadSysNum).WaterFlowMaxHeat,
    2149           46 :                                        state.dataLowTempRadSys->HydrRadSys(RadSysNum).HotWaterInNode,
    2150           46 :                                        state.dataLowTempRadSys->HydrRadSys(RadSysNum).HotWaterOutNode);
    2151              :                 }
    2152           46 :                 if (state.dataLowTempRadSys->HydrRadSys(RadSysNum).ColdWaterInNode > 0) {
    2153           43 :                     rho = state.dataPlnt->PlantLoop(state.dataLowTempRadSys->HydrRadSys(RadSysNum).CWPlantLoc.loopNum)
    2154           43 :                               .glycol->getDensity(state, Constant::CWInitConvTemp, RoutineName);
    2155           43 :                     state.dataLowTempRadSys->HydrRadSys(RadSysNum).WaterFlowMaxCool =
    2156           43 :                         rho * state.dataLowTempRadSys->HydrRadSys(RadSysNum).WaterVolFlowMaxCool;
    2157          129 :                     InitComponentNodes(state,
    2158              :                                        0.0,
    2159           43 :                                        state.dataLowTempRadSys->HydrRadSys(RadSysNum).WaterFlowMaxCool,
    2160           43 :                                        state.dataLowTempRadSys->HydrRadSys(RadSysNum).ColdWaterInNode,
    2161           43 :                                        state.dataLowTempRadSys->HydrRadSys(RadSysNum).ColdWaterOutNode);
    2162              :                 }
    2163              :             }
    2164              :         }
    2165              : 
    2166       666848 :         if (!state.dataGlobal->SysSizingCalc && (systemType == SystemType::ConstantFlow)) {
    2167       221730 :             if (state.dataLowTempRadSys->MySizeFlagCFlo(RadSysNum) && !state.dataLowTempRadSys->MyPlantScanFlagCFlo(RadSysNum)) {
    2168              :                 // for each radiant system do the sizing once.
    2169           27 :                 SizeLowTempRadiantSystem(state, RadSysNum, systemType);
    2170              : 
    2171              :                 // set design mass flow rates
    2172           27 :                 if (state.dataLowTempRadSys->CFloRadSys(RadSysNum).HotWaterInNode > 0) {
    2173           27 :                     rho = state.dataPlnt->PlantLoop(state.dataLowTempRadSys->CFloRadSys(RadSysNum).HWPlantLoc.loopNum)
    2174           27 :                               .glycol->getDensity(state, Constant::HWInitConvTemp, RoutineName);
    2175           27 :                     state.dataLowTempRadSys->CFloRadSys(RadSysNum).HotDesignWaterMassFlowRate =
    2176           27 :                         rho * state.dataLowTempRadSys->CFloRadSys(RadSysNum).WaterVolFlowMax;
    2177           81 :                     InitComponentNodes(state,
    2178              :                                        0.0,
    2179           27 :                                        state.dataLowTempRadSys->CFloRadSys(RadSysNum).HotDesignWaterMassFlowRate,
    2180           27 :                                        state.dataLowTempRadSys->CFloRadSys(RadSysNum).HotWaterInNode,
    2181           27 :                                        state.dataLowTempRadSys->CFloRadSys(RadSysNum).HotWaterOutNode);
    2182              :                 }
    2183           27 :                 if (state.dataLowTempRadSys->CFloRadSys(RadSysNum).ColdWaterInNode > 0) {
    2184           24 :                     rho = state.dataPlnt->PlantLoop(state.dataLowTempRadSys->CFloRadSys(RadSysNum).CWPlantLoc.loopNum)
    2185           24 :                               .glycol->getDensity(state, Constant::CWInitConvTemp, RoutineName);
    2186           24 :                     state.dataLowTempRadSys->CFloRadSys(RadSysNum).ColdDesignWaterMassFlowRate =
    2187           24 :                         rho * state.dataLowTempRadSys->CFloRadSys(RadSysNum).WaterVolFlowMax;
    2188           72 :                     InitComponentNodes(state,
    2189              :                                        0.0,
    2190           24 :                                        state.dataLowTempRadSys->CFloRadSys(RadSysNum).ColdDesignWaterMassFlowRate,
    2191           24 :                                        state.dataLowTempRadSys->CFloRadSys(RadSysNum).ColdWaterInNode,
    2192           24 :                                        state.dataLowTempRadSys->CFloRadSys(RadSysNum).ColdWaterOutNode);
    2193              :                 }
    2194           27 :                 state.dataLowTempRadSys->MySizeFlagCFlo(RadSysNum) = false;
    2195              :             }
    2196              :         }
    2197              : 
    2198       666848 :         if (!state.dataGlobal->SysSizingCalc && (systemType == SystemType::Electric)) {
    2199        79053 :             if (state.dataLowTempRadSys->MySizeFlagElec(RadSysNum)) {
    2200              :                 // for each radiant system do the sizing once.
    2201            9 :                 SizeLowTempRadiantSystem(state, RadSysNum, systemType);
    2202            9 :                 state.dataLowTempRadSys->MySizeFlagElec(RadSysNum) = false;
    2203              :             }
    2204              :         }
    2205              : 
    2206       666848 :         if (state.dataGlobal->BeginEnvrnFlag && state.dataLowTempRadSys->MyEnvrnFlagGeneral) {
    2207          160 :             if (systemType == SystemType::Hydronic) {
    2208           89 :                 auto &thisLTR = state.dataLowTempRadSys->HydrRadSys(RadSysNum);
    2209           89 :                 thisLTR.ZeroLTRSourceSumHATsurf = 0.0;
    2210           89 :                 thisLTR.QRadSysSrcAvg = 0.0;
    2211           89 :                 thisLTR.LastQRadSysSrc = 0.0;
    2212           89 :                 thisLTR.LastSysTimeElapsed = 0.0;
    2213           89 :                 thisLTR.LastTimeStepSys = 0.0;
    2214           71 :             } else if (systemType == SystemType::ConstantFlow) {
    2215           56 :                 auto &thisLTR = state.dataLowTempRadSys->CFloRadSys(RadSysNum);
    2216           56 :                 thisLTR.ZeroLTRSourceSumHATsurf = 0.0;
    2217           56 :                 thisLTR.QRadSysSrcAvg = 0.0;
    2218           56 :                 thisLTR.LastQRadSysSrc = 0.0;
    2219           56 :                 thisLTR.LastSysTimeElapsed = 0.0;
    2220           56 :                 thisLTR.LastTimeStepSys = 0.0;
    2221           15 :             } else if (systemType == SystemType::Electric) {
    2222           15 :                 auto &thisLTR = state.dataLowTempRadSys->ElecRadSys(RadSysNum);
    2223           15 :                 thisLTR.ZeroLTRSourceSumHATsurf = 0.0;
    2224           15 :                 thisLTR.QRadSysSrcAvg = 0.0;
    2225           15 :                 thisLTR.LastQRadSysSrc = 0.0;
    2226           15 :                 thisLTR.LastSysTimeElapsed = 0.0;
    2227           15 :                 thisLTR.LastTimeStepSys = 0.0;
    2228              :             }
    2229          160 :             state.dataLowTempRadSys->MyEnvrnFlagGeneral = false;
    2230              :         }
    2231       666848 :         if (!state.dataGlobal->BeginEnvrnFlag) {
    2232       664095 :             state.dataLowTempRadSys->MyEnvrnFlagGeneral = true;
    2233              :         }
    2234              : 
    2235              :         // If we are at the beginning of a new environment OR the warmup period is done and the simulation is starting,
    2236              :         // then the various changeover variables need to be reset so that we are starting from scratch.
    2237      1332092 :         if ((state.dataGlobal->BeginEnvrnFlag && FirstHVACIteration) ||
    2238       665244 :             (!state.dataGlobal->WarmupFlag && state.dataGlobal->BeginDayFlag && FirstHVACIteration && state.dataGlobal->DayOfSim == 1)) {
    2239              :             // Reset values related to changeover
    2240         1792 :             if (systemType == SystemType::Hydronic) {
    2241         1000 :                 state.dataLowTempRadSys->HydrRadSys(RadSysNum).lastOpMode = OpMode::None;
    2242         1000 :                 state.dataLowTempRadSys->HydrRadSys(RadSysNum).lastDayOfSim = 0;
    2243         1000 :                 state.dataLowTempRadSys->HydrRadSys(RadSysNum).lastHourOfDay = 0;
    2244         1000 :                 state.dataLowTempRadSys->HydrRadSys(RadSysNum).lastTimeStep = 0;
    2245              :             }
    2246         1792 :             if (systemType == SystemType::ConstantFlow) {
    2247          642 :                 state.dataLowTempRadSys->CFloRadSys(RadSysNum).lastOpMode = OpMode::None;
    2248          642 :                 state.dataLowTempRadSys->CFloRadSys(RadSysNum).lastDayOfSim = 0;
    2249          642 :                 state.dataLowTempRadSys->CFloRadSys(RadSysNum).lastHourOfDay = 0;
    2250          642 :                 state.dataLowTempRadSys->CFloRadSys(RadSysNum).lastTimeStep = 0;
    2251              :             }
    2252              :         }
    2253              : 
    2254       666848 :         if (systemType == SystemType::Hydronic) {
    2255       366056 :             if (state.dataGlobal->BeginEnvrnFlag && state.dataLowTempRadSys->MyEnvrnFlagHydr(RadSysNum)) {
    2256          242 :                 state.dataLowTempRadSys->HydrRadSys(RadSysNum).HeatPower = 0.0;
    2257          242 :                 state.dataLowTempRadSys->HydrRadSys(RadSysNum).HeatEnergy = 0.0;
    2258          242 :                 state.dataLowTempRadSys->HydrRadSys(RadSysNum).CoolPower = 0.0;
    2259          242 :                 state.dataLowTempRadSys->HydrRadSys(RadSysNum).CoolEnergy = 0.0;
    2260          242 :                 state.dataLowTempRadSys->HydrRadSys(RadSysNum).WaterInletTemp = 0.0;
    2261          242 :                 state.dataLowTempRadSys->HydrRadSys(RadSysNum).WaterOutletTemp = 0.0;
    2262          242 :                 state.dataLowTempRadSys->HydrRadSys(RadSysNum).WaterMassFlowRate = 0.0;
    2263              : 
    2264          242 :                 if (!state.dataLowTempRadSys->MyPlantScanFlagHydr(RadSysNum)) {
    2265          242 :                     if (state.dataLowTempRadSys->HydrRadSys(RadSysNum).HotWaterInNode > 0) {
    2266          726 :                         InitComponentNodes(state,
    2267              :                                            0.0,
    2268          242 :                                            state.dataLowTempRadSys->HydrRadSys(RadSysNum).WaterFlowMaxHeat,
    2269          242 :                                            state.dataLowTempRadSys->HydrRadSys(RadSysNum).HotWaterInNode,
    2270          242 :                                            state.dataLowTempRadSys->HydrRadSys(RadSysNum).HotWaterOutNode);
    2271              :                     }
    2272          242 :                     if (state.dataLowTempRadSys->HydrRadSys(RadSysNum).ColdWaterInNode > 0) {
    2273          681 :                         InitComponentNodes(state,
    2274              :                                            0.0,
    2275          227 :                                            state.dataLowTempRadSys->HydrRadSys(RadSysNum).WaterFlowMaxCool,
    2276          227 :                                            state.dataLowTempRadSys->HydrRadSys(RadSysNum).ColdWaterInNode,
    2277          227 :                                            state.dataLowTempRadSys->HydrRadSys(RadSysNum).ColdWaterOutNode);
    2278              :                     }
    2279              :                 }
    2280          242 :                 state.dataLowTempRadSys->MyEnvrnFlagHydr(RadSysNum) = false;
    2281              :             }
    2282              :         } // NumOfHydrLowTempRadSys > 0
    2283       666848 :         if (!state.dataGlobal->BeginEnvrnFlag && systemType == SystemType::Hydronic) {
    2284       364488 :             state.dataLowTempRadSys->MyEnvrnFlagHydr(RadSysNum) = true;
    2285              :         }
    2286              : 
    2287       666848 :         if (systemType == SystemType::ConstantFlow) {
    2288       221733 :             if (state.dataGlobal->BeginEnvrnFlag && state.dataLowTempRadSys->MyEnvrnFlagCFlo(RadSysNum)) {
    2289          168 :                 state.dataLowTempRadSys->CFloRadSys(RadSysNum).WaterInletTemp = 0.0;
    2290          168 :                 state.dataLowTempRadSys->CFloRadSys(RadSysNum).WaterOutletTemp = 0.0;
    2291          168 :                 state.dataLowTempRadSys->CFloRadSys(RadSysNum).PumpInletTemp = 0.0;
    2292          168 :                 state.dataLowTempRadSys->CFloRadSys(RadSysNum).WaterMassFlowRate = 0.0;
    2293          168 :                 state.dataLowTempRadSys->CFloRadSys(RadSysNum).WaterInjectionRate = 0.0;
    2294          168 :                 state.dataLowTempRadSys->CFloRadSys(RadSysNum).WaterRecircRate = 0.0;
    2295          168 :                 state.dataLowTempRadSys->CFloRadSys(RadSysNum).HeatPower = 0.0;
    2296          168 :                 state.dataLowTempRadSys->CFloRadSys(RadSysNum).HeatEnergy = 0.0;
    2297          168 :                 state.dataLowTempRadSys->CFloRadSys(RadSysNum).CoolPower = 0.0;
    2298          168 :                 state.dataLowTempRadSys->CFloRadSys(RadSysNum).CoolEnergy = 0.0;
    2299          168 :                 state.dataLowTempRadSys->CFloRadSys(RadSysNum).PumpPower = 0.0;
    2300          168 :                 state.dataLowTempRadSys->CFloRadSys(RadSysNum).PumpMassFlowRate = 0.0;
    2301          168 :                 state.dataLowTempRadSys->CFloRadSys(RadSysNum).PumpHeattoFluid = 0.0;
    2302              : 
    2303          168 :                 if (!state.dataLowTempRadSys->MyPlantScanFlagCFlo(RadSysNum)) {
    2304          168 :                     if (state.dataLowTempRadSys->CFloRadSys(RadSysNum).HotWaterInNode > 0) {
    2305          504 :                         InitComponentNodes(state,
    2306              :                                            0.0,
    2307          168 :                                            state.dataLowTempRadSys->CFloRadSys(RadSysNum).HotDesignWaterMassFlowRate,
    2308          168 :                                            state.dataLowTempRadSys->CFloRadSys(RadSysNum).HotWaterInNode,
    2309          168 :                                            state.dataLowTempRadSys->CFloRadSys(RadSysNum).HotWaterOutNode);
    2310              :                     }
    2311          168 :                     if (state.dataLowTempRadSys->CFloRadSys(RadSysNum).ColdWaterInNode > 0) {
    2312          459 :                         InitComponentNodes(state,
    2313              :                                            0.0,
    2314          153 :                                            state.dataLowTempRadSys->CFloRadSys(RadSysNum).ColdDesignWaterMassFlowRate,
    2315          153 :                                            state.dataLowTempRadSys->CFloRadSys(RadSysNum).ColdWaterInNode,
    2316          153 :                                            state.dataLowTempRadSys->CFloRadSys(RadSysNum).ColdWaterOutNode);
    2317              :                     }
    2318              :                 }
    2319          168 :                 state.dataLowTempRadSys->MyEnvrnFlagCFlo(RadSysNum) = false;
    2320              :             }
    2321              : 
    2322       221733 :             if (state.dataLowTempRadSys->anyRadiantSystemUsingRunningMeanAverage) {
    2323        26424 :                 if (state.dataGlobal->BeginDayFlag && state.dataLowTempRadSys->CFloRadSys(RadSysNum).setRunningMeanValuesAtBeginningOfDay) {
    2324           78 :                     state.dataLowTempRadSys->CFloRadSys(RadSysNum).calculateRunningMeanAverageTemperature(state, RadSysNum);
    2325           78 :                     state.dataLowTempRadSys->CFloRadSys(RadSysNum).setRunningMeanValuesAtBeginningOfDay = false; // only set these once per system
    2326        26346 :                 } else if (!state.dataGlobal->BeginDayFlag && !state.dataLowTempRadSys->CFloRadSys(RadSysNum).setRunningMeanValuesAtBeginningOfDay) {
    2327           78 :                     state.dataLowTempRadSys->CFloRadSys(RadSysNum).setRunningMeanValuesAtBeginningOfDay =
    2328              :                         true; // reset so that the next time BeginDayFlag is true this can get set
    2329              :                 }
    2330              :             }
    2331              : 
    2332              :         } // NumOfCFloLowTempRadSys > 0
    2333       666848 :         if (!state.dataGlobal->BeginEnvrnFlag && systemType == SystemType::ConstantFlow) {
    2334       220767 :             state.dataLowTempRadSys->MyEnvrnFlagCFlo(RadSysNum) = true;
    2335              :         }
    2336              : 
    2337       666848 :         if (systemType == SystemType::Electric) {
    2338        79059 :             if (state.dataGlobal->BeginEnvrnFlag && state.dataLowTempRadSys->MyEnvrnFlagElec(RadSysNum)) {
    2339           45 :                 state.dataLowTempRadSys->ElecRadSys(RadSysNum).HeatPower = 0.0;
    2340           45 :                 state.dataLowTempRadSys->ElecRadSys(RadSysNum).HeatEnergy = 0.0;
    2341           45 :                 state.dataLowTempRadSys->ElecRadSys(RadSysNum).ElecPower = 0.0;
    2342           45 :                 state.dataLowTempRadSys->ElecRadSys(RadSysNum).ElecEnergy = 0.0;
    2343              :             }
    2344        79059 :             state.dataLowTempRadSys->MyEnvrnFlagElec(RadSysNum) = false;
    2345              :         }
    2346       666848 :         if (!state.dataGlobal->BeginEnvrnFlag && systemType == SystemType::Electric) {
    2347        78840 :             state.dataLowTempRadSys->MyEnvrnFlagElec(RadSysNum) = true;
    2348              :         }
    2349              : 
    2350       666848 :         if (systemType == SystemType::ConstantFlow) {
    2351              : 
    2352              :             // Can this system actually do heating?
    2353       221733 :             if ((state.dataLowTempRadSys->CFloRadSys(RadSysNum).WaterVolFlowMax > 0.0) &&
    2354       221732 :                 (state.dataLowTempRadSys->CFloRadSys(RadSysNum).HotWaterInNode > 0) &&
    2355       221732 :                 (state.dataLowTempRadSys->CFloRadSys(RadSysNum).HotWaterOutNode > 0) &&
    2356       221732 :                 (state.dataLowTempRadSys->CFloRadSys(RadSysNum).hotWaterHiTempSched != nullptr) &&
    2357       221732 :                 (state.dataLowTempRadSys->CFloRadSys(RadSysNum).hotWaterLoTempSched != nullptr) &&
    2358       665197 :                 (state.dataLowTempRadSys->CFloRadSys(RadSysNum).hotCtrlHiTempSched != nullptr) &&
    2359       221732 :                 (state.dataLowTempRadSys->CFloRadSys(RadSysNum).hotCtrlLoTempSched != nullptr)) {
    2360       221732 :                 state.dataLowTempRadSys->CFloRadSys(RadSysNum).HeatingSystem = true;
    2361              :             }
    2362              : 
    2363              :             // Can this system actually do cooling?
    2364       221733 :             if ((state.dataLowTempRadSys->CFloRadSys(RadSysNum).WaterVolFlowMax > 0.0) &&
    2365       221732 :                 (state.dataLowTempRadSys->CFloRadSys(RadSysNum).ColdWaterInNode > 0) &&
    2366       208097 :                 (state.dataLowTempRadSys->CFloRadSys(RadSysNum).ColdWaterOutNode > 0) &&
    2367       208097 :                 (state.dataLowTempRadSys->CFloRadSys(RadSysNum).coldWaterHiTempSched != nullptr) &&
    2368       208097 :                 (state.dataLowTempRadSys->CFloRadSys(RadSysNum).coldWaterLoTempSched != nullptr) &&
    2369       651562 :                 (state.dataLowTempRadSys->CFloRadSys(RadSysNum).coldCtrlHiTempSched != nullptr) &&
    2370       208097 :                 (state.dataLowTempRadSys->CFloRadSys(RadSysNum).coldCtrlLoTempSched != nullptr)) {
    2371       208097 :                 state.dataLowTempRadSys->CFloRadSys(RadSysNum).CoolingSystem = true;
    2372              :             }
    2373              :         }
    2374              : 
    2375       666848 :         if (state.dataGlobal->BeginTimeStepFlag && FirstHVACIteration) { // This is the first pass through in a particular time step
    2376              : 
    2377       254744 :             switch (systemType) {
    2378       140501 :             case SystemType::Hydronic: {
    2379       140501 :                 int ZoneNum = state.dataLowTempRadSys->HydrRadSys(RadSysNum).ZonePtr;
    2380       140501 :                 auto &thisLTR = state.dataLowTempRadSys->HydrRadSys(RadSysNum);
    2381       140501 :                 thisLTR.ZeroLTRSourceSumHATsurf =
    2382       140501 :                     state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state); // Set this to figure what part of the load the radiant system meets
    2383       140501 :                 thisLTR.QRadSysSrcAvg = 0.0;                            // Initialize this variable to zero (radiant system defaults to off)
    2384       140501 :                 thisLTR.LastQRadSysSrc = 0.0;     // At the start of a time step, reset to zero so average calculation can begin again
    2385       140501 :                 thisLTR.LastSysTimeElapsed = 0.0; // At the start of a time step, reset to zero so average calculation can begin again
    2386       140501 :                 thisLTR.LastTimeStepSys = 0.0; // At the start of a time step, reset to zero so average calculation can begin again                }
    2387       140501 :             } break;
    2388        81915 :             case SystemType::ConstantFlow: {
    2389        81915 :                 int ZoneNum = state.dataLowTempRadSys->CFloRadSys(RadSysNum).ZonePtr;
    2390        81915 :                 auto &thisLTR = state.dataLowTempRadSys->CFloRadSys(RadSysNum);
    2391        81915 :                 thisLTR.ZeroLTRSourceSumHATsurf =
    2392        81915 :                     state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state); // Set this to figure what part of the load the radiant system meets
    2393        81915 :                 thisLTR.QRadSysSrcAvg = 0.0;                            // Initialize this variable to zero (radiant system defaults to off)
    2394        81915 :                 thisLTR.LastQRadSysSrc = 0.0;     // At the start of a time step, reset to zero so average calculation can begin again
    2395        81915 :                 thisLTR.LastSysTimeElapsed = 0.0; // At the start of a time step, reset to zero so average calculation can begin again
    2396        81915 :                 thisLTR.LastTimeStepSys = 0.0; // At the start of a time step, reset to zero so average calculation can begin again                }
    2397        81915 :             } break;
    2398        32328 :             case SystemType::Electric: {
    2399        32328 :                 int ZoneNum = state.dataLowTempRadSys->ElecRadSys(RadSysNum).ZonePtr;
    2400        32328 :                 auto &thisLTR = state.dataLowTempRadSys->ElecRadSys(RadSysNum);
    2401        32328 :                 thisLTR.ZeroLTRSourceSumHATsurf =
    2402        32328 :                     state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state); // Set this to figure what part of the load the radiant system meets
    2403        32328 :                 thisLTR.QRadSysSrcAvg = 0.0;                            // Initialize this variable to zero (radiant system defaults to off)
    2404        32328 :                 thisLTR.LastQRadSysSrc = 0.0;     // At the start of a time step, reset to zero so average calculation can begin again
    2405        32328 :                 thisLTR.LastSysTimeElapsed = 0.0; // At the start of a time step, reset to zero so average calculation can begin again
    2406        32328 :                 thisLTR.LastTimeStepSys = 0.0; // At the start of a time step, reset to zero so average calculation can begin again                }
    2407        32328 :             } break;
    2408            0 :             default: {
    2409            0 :                 ShowSevereError(state, "Radiant system entered without specification of type: electric, constant flow, or hydronic?");
    2410            0 :                 ShowContinueError(state, format("Occurs in Radiant System={}", state.dataLowTempRadSys->HydrRadSys(RadSysNum).Name));
    2411            0 :                 ShowFatalError(state, "Preceding condition causes termination.");
    2412            0 :             } break;
    2413              :             }
    2414              : 
    2415              :         } // ...for first pass through in a particular time step.
    2416              : 
    2417       666848 :         switch (systemType) {
    2418              : 
    2419       366056 :         case SystemType::Hydronic: {
    2420              : 
    2421              :             // Initialize the appropriate node data
    2422       366056 :             if (state.dataLowTempRadSys->HydrRadSys(RadSysNum).HeatingSystem) {
    2423       366010 :                 mdot = 0.0;
    2424       732020 :                 SetComponentFlowRate(state,
    2425              :                                      mdot,
    2426       366010 :                                      state.dataLowTempRadSys->HydrRadSys(RadSysNum).HotWaterInNode,
    2427       366010 :                                      state.dataLowTempRadSys->HydrRadSys(RadSysNum).HotWaterOutNode,
    2428       366010 :                                      state.dataLowTempRadSys->HydrRadSys(RadSysNum).HWPlantLoc);
    2429              :             }
    2430       366056 :             if (state.dataLowTempRadSys->HydrRadSys(RadSysNum).CoolingSystem) {
    2431       351205 :                 mdot = 0.0;
    2432       702410 :                 SetComponentFlowRate(state,
    2433              :                                      mdot,
    2434       351205 :                                      state.dataLowTempRadSys->HydrRadSys(RadSysNum).ColdWaterInNode,
    2435       351205 :                                      state.dataLowTempRadSys->HydrRadSys(RadSysNum).ColdWaterOutNode,
    2436       351205 :                                      state.dataLowTempRadSys->HydrRadSys(RadSysNum).CWPlantLoc);
    2437              :             }
    2438       366056 :             if (state.dataLowTempRadSys->HydrRadSys(RadSysNum).opMode != OpMode::None && FirstHVACIteration) {
    2439       124999 :                 state.dataLowTempRadSys->HydrRadSys(RadSysNum).updateOperatingModeHistory(state);
    2440              :             }
    2441              : 
    2442       366056 :         } break;
    2443              : 
    2444       221733 :         case SystemType::ConstantFlow: {
    2445       221733 :             state.dataLowTempRadSys->CFloRadSys(RadSysNum).WaterMassFlowRate = 0.0;
    2446              :             // Initialize the appropriate node data
    2447       221733 :             if (state.dataLowTempRadSys->CFloRadSys(RadSysNum).HeatingSystem) {
    2448       221732 :                 if (state.dataLowTempRadSys->CFloRadSys(RadSysNum).volFlowSched != nullptr) {
    2449            0 :                     CurrentFlowSchedule = state.dataLowTempRadSys->CFloRadSys(RadSysNum).volFlowSched->getCurrentVal();
    2450              :                 } else {
    2451       221732 :                     CurrentFlowSchedule = 1.0; // Allow user to avoid putting in a schedule (defaults to constant flow at all times)
    2452              :                 }
    2453       221732 :                 if (CurrentFlowSchedule > 1.0) {
    2454            0 :                     CurrentFlowSchedule = 1.0; // Do not allow more flow than design maximum
    2455              :                 }
    2456       221732 :                 if (CurrentFlowSchedule < 0.0) {
    2457            0 :                     CurrentFlowSchedule = 0.0; // Do not allow negative flow
    2458              :                 }
    2459              : 
    2460       221732 :                 state.dataLowTempRadSys->CFloRadSys(RadSysNum).HotWaterMassFlowRate =
    2461       221732 :                     state.dataLowTempRadSys->CFloRadSys(RadSysNum).HotDesignWaterMassFlowRate * CurrentFlowSchedule;
    2462              : 
    2463       221732 :                 if (state.dataLowTempRadSys->CFloRadSys(RadSysNum).EMSOverrideOnWaterMdot) {
    2464            0 :                     state.dataLowTempRadSys->CFloRadSys(RadSysNum).HotWaterMassFlowRate =
    2465            0 :                         state.dataLowTempRadSys->CFloRadSys(RadSysNum).EMSWaterMdotOverrideValue;
    2466              :                 }
    2467              : 
    2468       221732 :                 if (state.dataLowTempRadSys->CFloRadSys(RadSysNum).HotWaterInNode > 0) {
    2469       665196 :                     SetComponentFlowRate(state,
    2470       221732 :                                          state.dataLowTempRadSys->CFloRadSys(RadSysNum).HotWaterMassFlowRate,
    2471       221732 :                                          state.dataLowTempRadSys->CFloRadSys(RadSysNum).HotWaterInNode,
    2472       221732 :                                          state.dataLowTempRadSys->CFloRadSys(RadSysNum).HotWaterOutNode,
    2473       221732 :                                          state.dataLowTempRadSys->CFloRadSys(RadSysNum).HWPlantLoc);
    2474              :                 }
    2475              :             }
    2476       221733 :             if (state.dataLowTempRadSys->CFloRadSys(RadSysNum).CoolingSystem) {
    2477       208097 :                 if (state.dataLowTempRadSys->CFloRadSys(RadSysNum).volFlowSched != nullptr) {
    2478            0 :                     CurrentFlowSchedule = state.dataLowTempRadSys->CFloRadSys(RadSysNum).volFlowSched->getCurrentVal();
    2479              :                 } else {
    2480       208097 :                     CurrentFlowSchedule = 1.0; // Allow user to avoid putting in a schedule (defaults to constant flow at all times)
    2481              :                 }
    2482       208097 :                 if (CurrentFlowSchedule > 1.0) {
    2483            0 :                     CurrentFlowSchedule = 1.0; // Do not allow more flow than design maximum
    2484              :                 }
    2485       208097 :                 if (CurrentFlowSchedule < 0.0) {
    2486            0 :                     CurrentFlowSchedule = 0.0; // Do not allow negative flow
    2487              :                 }
    2488       208097 :                 state.dataLowTempRadSys->CFloRadSys(RadSysNum).ChWaterMassFlowRate =
    2489       208097 :                     state.dataLowTempRadSys->CFloRadSys(RadSysNum).ColdDesignWaterMassFlowRate * CurrentFlowSchedule;
    2490              : 
    2491       208097 :                 if (state.dataLowTempRadSys->CFloRadSys(RadSysNum).EMSOverrideOnWaterMdot) {
    2492            0 :                     state.dataLowTempRadSys->CFloRadSys(RadSysNum).ChWaterMassFlowRate =
    2493            0 :                         state.dataLowTempRadSys->CFloRadSys(RadSysNum).EMSWaterMdotOverrideValue;
    2494              :                 }
    2495              : 
    2496       208097 :                 if (state.dataLowTempRadSys->CFloRadSys(RadSysNum).ColdWaterInNode > 0) {
    2497       624291 :                     SetComponentFlowRate(state,
    2498       208097 :                                          state.dataLowTempRadSys->CFloRadSys(RadSysNum).ChWaterMassFlowRate,
    2499       208097 :                                          state.dataLowTempRadSys->CFloRadSys(RadSysNum).ColdWaterInNode,
    2500       208097 :                                          state.dataLowTempRadSys->CFloRadSys(RadSysNum).ColdWaterOutNode,
    2501       208097 :                                          state.dataLowTempRadSys->CFloRadSys(RadSysNum).CWPlantLoc);
    2502              :                 }
    2503              :             }
    2504       221733 :             if (state.dataLowTempRadSys->CFloRadSys(RadSysNum).opMode != OpMode::None && FirstHVACIteration) {
    2505        82756 :                 state.dataLowTempRadSys->CFloRadSys(RadSysNum).updateOperatingModeHistory(state);
    2506              :             }
    2507              : 
    2508       221733 :         } break;
    2509        79059 :         case SystemType::Electric: {
    2510        79059 :             state.dataLowTempRadSys->ElecRadSys(RadSysNum).opMode = OpMode::None;
    2511        79059 :         } break;
    2512            0 :         default:
    2513            0 :             break;
    2514              :         }
    2515       666848 :     }
    2516              : 
    2517       207755 :     void HydronicSystemBaseData::updateOperatingModeHistory(EnergyPlusData &state)
    2518              :     {
    2519              :         // Since this is only called when the operating mode is something other than "not operating",
    2520              :         // the status from the previous system time step is what it did in the last or previous time step.
    2521              :         // So, we can update the last status of the system using this information before resetting things
    2522              :         // to "not operating".
    2523       207755 :         this->lastOpMode = this->opMode;
    2524              : 
    2525       207755 :         if (state.dataGlobal->BeginDayFlag) {
    2526              :             // The begin day flag is set which mean this is the first time step of the day.
    2527              :             // This also means that the previous time step was the last time step of yesterday.
    2528              :             // So, the day should be the previous day, the hour should be the last hour of the
    2529              :             // day, and the time step should be the last time step.
    2530         1328 :             this->lastDayOfSim = state.dataGlobal->DayOfSim - 1;
    2531         1328 :             this->lastHourOfDay = Constant::iHoursInDay;
    2532         1328 :             this->lastTimeStep = state.dataGlobal->TimeStepsInHour;
    2533       206427 :         } else if (state.dataGlobal->BeginHourFlag) {
    2534              :             // It's not the beginning of the day but it is the beginning of an hour other than
    2535              :             // the first hour.  This means that the previous time step was the previous hour of
    2536              :             // today in the last time step.  So, the day should be the current day, the hour should
    2537              :             // be the previous hour, and the time step should be the last time step.
    2538        36217 :             this->lastDayOfSim = state.dataGlobal->DayOfSim;
    2539        36217 :             this->lastHourOfDay = state.dataGlobal->HourOfDay - 1;
    2540        36217 :             this->lastTimeStep = state.dataGlobal->TimeStepsInHour;
    2541       170210 :         } else if (state.dataGlobal->BeginTimeStepFlag) {
    2542              :             // It's neither the beginning of the day nor the beginning of an hour but it is the start
    2543              :             // of a time step other than the first time step in the hour.  So, the day should be the
    2544              :             // current day, the hour should be the current hour, and the time step should be the
    2545              :             // previous time step.
    2546       142397 :             this->lastDayOfSim = state.dataGlobal->DayOfSim;
    2547       142397 :             this->lastHourOfDay = state.dataGlobal->HourOfDay;
    2548       142397 :             this->lastTimeStep = state.dataGlobal->TimeStep - 1;
    2549              :         } else {
    2550              :             // It's not the beginning of the day, hour, or time step so the "last" value is simply the
    2551              :             // same as the current value.  Note that these parameters only track down to the zone time
    2552              :             // step level and will make decisions based on that.
    2553        27813 :             this->lastDayOfSim = state.dataGlobal->DayOfSim;
    2554        27813 :             this->lastHourOfDay = state.dataGlobal->HourOfDay;
    2555        27813 :             this->lastTimeStep = state.dataGlobal->TimeStep;
    2556              :         }
    2557              : 
    2558              :         // Now go ahead and reset the operating mode (this will be set to something else if the system is running)
    2559       207755 :         this->opMode = OpMode::None;
    2560       207755 :     }
    2561              : 
    2562       572468 :     void HydronicSystemBaseData::setOperatingModeBasedOnChangeoverDelay(EnergyPlusData &state)
    2563              :     {
    2564       572468 :         if (this->lastOpMode == OpMode::None) {
    2565        19883 :             return; // this should only happen at the beginning of a simulation (at the start of warmup and the actual simulation)
    2566              :         }
    2567              :         // so let things proceed with whatever the system wants to do
    2568              : 
    2569       552585 :         if (this->opMode == OpMode::None) {
    2570        76387 :             return; // always let it turn off
    2571              :         }
    2572              : 
    2573       476198 :         if (this->opMode == this->lastOpMode) {
    2574       467504 :             return; // always let it continue to operating in the same mode
    2575              :         }
    2576              : 
    2577         8694 :         if (this->changeoverDelaySched == nullptr) {
    2578         1278 :             return; // user not requesting any delays (no schedule entered) so let it do whatever is requested
    2579              :         }
    2580              : 
    2581         7416 :         Real64 currentChangeoverDelay = this->changeoverDelaySched->getCurrentVal();
    2582         7416 :         if (currentChangeoverDelay <= 0.0) {
    2583            0 :             return; // delay is zero so let it do whatever it requested
    2584              :         }
    2585              : 
    2586              :         // At this point, the radiant system is trying to switch modes from the previous time step, the user is requesting a delay in the changeover,
    2587              :         // and the requested delay is greater than zero.  Calculate what the current time is in hours from the start of the simulation
    2588         7416 :         Real64 timeCurrent = 24.0 * float(state.dataGlobal->DayOfSim - 1) + float(state.dataGlobal->HourOfDay - 1) +
    2589         7416 :                              float(state.dataGlobal->TimeStep - 1) / float(state.dataGlobal->TimeStepsInHour);
    2590         7416 :         Real64 timeLast = 24.0 * float(this->lastDayOfSim - 1) + float(this->lastHourOfDay - 1) +
    2591         7416 :                           float(this->lastTimeStep - 1) / float(state.dataGlobal->TimeStepsInHour);
    2592         7416 :         Real64 actualTimeDifference = timeCurrent - timeLast;
    2593              : 
    2594              :         // If the time difference is not longer than the user delay, then the system should not switch modes and needs to be turned off.
    2595         7416 :         if (actualTimeDifference <= currentChangeoverDelay) {
    2596         7416 :             this->opMode = OpMode::None;
    2597              :         }
    2598              : 
    2599              :         // Note: if the time difference is greater than the user delay request, then go ahead and keep the operating mode needed (don't do anything).
    2600              :     }
    2601              : 
    2602           82 :     void SizeLowTempRadiantSystem(EnergyPlusData &state,
    2603              :                                   int const RadSysNum, // Index for the low temperature radiant system under consideration within the derived types
    2604              :                                   SystemType const systemType // Type of radiant system: hydronic, constant flow, or electric
    2605              :     )
    2606              :     {
    2607              : 
    2608              :         // SUBROUTINE INFORMATION:
    2609              :         //       AUTHOR         Fred Buhl
    2610              :         //       DATE WRITTEN   February 2002
    2611              :         //       MODIFIED       August 2013 Daeho Kang, add component sizing table entries
    2612              :         //                      August 2014 Bereket Nigusse, added scalable sizing
    2613              :         //                      March 2014 Daeho Kang, add constant flow system autosizing
    2614              : 
    2615              :         // PURPOSE OF THIS SUBROUTINE:
    2616              :         // This subroutine is for sizing low temperature radiant components for which flow rates
    2617              :         // and tube length or max electric power have not been specified in the input
    2618              : 
    2619              :         // METHODOLOGY EMPLOYED:
    2620              :         // Obtains flow rates from the zone sizing arrays and plant sizing data. Maximum electric
    2621              :         // power is set to the design heat load. Tube length is calculated by rule-of-thumb from
    2622              :         // the surface area.
    2623              : 
    2624              :         // Using/Aliasing
    2625              :         using namespace DataSizing;
    2626              :         using HVAC::AutoCalculateSizing;
    2627              :         using HVAC::CoolingCapacitySizing;
    2628              :         using HVAC::HeatingCapacitySizing;
    2629              : 
    2630              :         using PlantUtilities::MyPlantSizingIndex;
    2631              :         using PlantUtilities::RegisterPlantCompDesignFlow;
    2632              : 
    2633              :         // SUBROUTINE PARAMETER DEFINITIONS:
    2634           82 :         constexpr std::string_view RoutineName("SizeLowTempRadiantSystem");
    2635              : 
    2636              :         enum class OperatingMode
    2637              :         {
    2638              :             Invalid = -1,
    2639              :             OFF,
    2640              :             ClgHtg,
    2641              :             ClgOnly,
    2642              :             HtgOnly,
    2643              :             Num
    2644              :         };
    2645              : 
    2646              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2647           82 :         int PltSizHeatNum(0);    // index of plant sizing object for 1st heating loop
    2648           82 :         int PltSizCoolNum(0);    // index of plant sizing object for 1st cooling loop
    2649              :         int SurfNum;             // surface index in radiant system data structure
    2650           82 :         bool ErrorsFound(false); // If errors detected in input
    2651              :         Real64 rho;
    2652              :         Real64 Cp;
    2653           82 :         bool IsAutoSize(false);              // Indicator to autosize
    2654           82 :         Real64 WaterVolFlowMaxHeatDes(0.0);  // Design hot water flow for reporting
    2655           82 :         Real64 WaterVolFlowMaxHeatUser(0.0); // User hard-sized hot water flow for
    2656           82 :         Real64 WaterVolFlowMaxCoolDes(0.0);  // Design chilled water flow for reporting
    2657           82 :         Real64 WaterVolFlowMaxCoolUser(0.0); // User hard-sized chilled water flow for reporting
    2658           82 :         Real64 TubeLengthDes(0.0);           // Design tube length for reporting
    2659           82 :         Real64 TubeLengthUser(0.0);          // User hard-sized tube length for reporting
    2660           82 :         std::string CompName;                // component name
    2661           82 :         std::string CompType;                // component type
    2662           82 :         std::string SizingString;            // input field sizing description (e.g., Nominal Capacity)
    2663              :         Real64 TempSize;                     // autosized value of coil input field
    2664              :         int FieldNum;                        // IDD numeric field number where input field description is found
    2665              :         bool PrintFlag;                      // TRUE when sizing information is reported in the eio file
    2666              :         int CapSizingMethod;        // capacity sizing methods (HeatingDesignCapacity, CapacityPerFloorArea, FractionOfAutosizedCoolingCapacity, and
    2667              :                                     // FractionOfAutosizedHeatingCapacity )
    2668              :         Real64 DesCoilLoad;         // design autosized or user specified capacity
    2669              :         Real64 WaterVolFlowMaxDes;  // Design water volume flow rate for reporting
    2670              :         Real64 WaterVolFlowMaxUser; // User hard-sized water volume flow rate for reporting
    2671              : 
    2672           82 :         DesCoilLoad = 0.0;
    2673           82 :         state.dataSize->DataScalableCapSizingON = false;
    2674           82 :         state.dataSize->DataFracOfAutosizedHeatingCapacity = 1.0;
    2675              : 
    2676           82 :         auto const &Zone = state.dataHeatBal->Zone;
    2677              : 
    2678           82 :         if (systemType == SystemType::Electric) {
    2679              : 
    2680            9 :             if (state.dataLowTempRadSys->ElecRadSys(RadSysNum).MaxElecPower == AutoSize) {
    2681            2 :                 IsAutoSize = true;
    2682              :             }
    2683              : 
    2684            9 :             if (state.dataSize->CurZoneEqNum > 0) {
    2685            9 :                 auto &zoneEqSizing = state.dataSize->ZoneEqSizing(state.dataSize->CurZoneEqNum);
    2686              : 
    2687            9 :                 CompType = "ZoneHVAC:LowTemperatureRadiant:Electric";
    2688            9 :                 CompName = state.dataLowTempRadSys->ElecRadSys(RadSysNum).Name;
    2689            9 :                 int SizingMethod = HeatingCapacitySizing;
    2690            9 :                 FieldNum = 1;
    2691            9 :                 PrintFlag = true;
    2692            9 :                 SizingString = state.dataLowTempRadSys->ElecRadSysNumericFields(RadSysNum).FieldNames(FieldNum) + " [W]";
    2693            9 :                 CapSizingMethod = state.dataLowTempRadSys->ElecRadSys(RadSysNum).HeatingCapMethod;
    2694            9 :                 zoneEqSizing.SizingMethod(SizingMethod) = CapSizingMethod;
    2695              : 
    2696            9 :                 if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) { // simulation continue
    2697            3 :                     if (CapSizingMethod == HeatingDesignCapacity && state.dataLowTempRadSys->ElecRadSys(RadSysNum).ScaledHeatingCapacity > 0.0) {
    2698            3 :                         TempSize = state.dataLowTempRadSys->ElecRadSys(RadSysNum).ScaledHeatingCapacity;
    2699            3 :                         bool errorsFound = false;
    2700            3 :                         HeatingCapacitySizer sizerHeatingCapacity;
    2701            3 :                         sizerHeatingCapacity.overrideSizingString(SizingString);
    2702            3 :                         sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    2703            3 :                         DesCoilLoad = sizerHeatingCapacity.size(state, TempSize, errorsFound);
    2704            3 :                     } else if (CapSizingMethod == CapacityPerFloorArea) {
    2705            0 :                         state.dataSize->DataScalableCapSizingON = true;
    2706            0 :                         TempSize = state.dataLowTempRadSys->ElecRadSys(RadSysNum).ScaledHeatingCapacity *
    2707            0 :                                    Zone(state.dataLowTempRadSys->ElecRadSys(RadSysNum).ZonePtr).FloorArea;
    2708            0 :                         bool errorsFound = false;
    2709            0 :                         HeatingCapacitySizer sizerHeatingCapacity;
    2710            0 :                         sizerHeatingCapacity.overrideSizingString(SizingString);
    2711            0 :                         sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    2712            0 :                         DesCoilLoad = sizerHeatingCapacity.size(state, TempSize, errorsFound);
    2713            0 :                         state.dataSize->DataScalableCapSizingON = false;
    2714            0 :                         state.dataLowTempRadSys->ElecRadSys(RadSysNum).MaxElecPower = TempSize;
    2715            0 :                     } else if (CapSizingMethod == FractionOfAutosizedHeatingCapacity) {
    2716            0 :                         ShowSevereError(state,
    2717            0 :                                         format("{}: auto-sizing cannot be done for {} = {}\".",
    2718              :                                                RoutineName,
    2719              :                                                CompType,
    2720            0 :                                                state.dataLowTempRadSys->ElecRadSys(RadSysNum).Name));
    2721            0 :                         ShowContinueError(state,
    2722              :                                           "The \"SimulationControl\" object must have the field \"Do Zone Sizing Calculation\" set to Yes when the "
    2723              :                                           "Heating Design Capacity Method = \"FractionOfAutosizedHeatingCapacity\".");
    2724            0 :                         ErrorsFound = true;
    2725              :                     }
    2726              :                 } else {
    2727            6 :                     if (CapSizingMethod == HeatingDesignCapacity || CapSizingMethod == CapacityPerFloorArea ||
    2728              :                         CapSizingMethod == FractionOfAutosizedHeatingCapacity) {
    2729            6 :                         if (CapSizingMethod == HeatingDesignCapacity) {
    2730            2 :                             if (state.dataSize->ZoneSizingRunDone) {
    2731            2 :                                 CheckZoneSizing(state, CompType, CompName);
    2732            4 :                                 state.dataSize->DataConstantUsedForSizing =
    2733            2 :                                     state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).NonAirSysDesHeatLoad;
    2734            2 :                                 state.dataSize->DataFractionUsedForSizing = 1.0;
    2735              :                             }
    2736            2 :                             if (state.dataLowTempRadSys->ElecRadSys(RadSysNum).ScaledHeatingCapacity == AutoSize) {
    2737            2 :                                 TempSize = AutoSize;
    2738              :                             } else {
    2739            0 :                                 TempSize = state.dataLowTempRadSys->ElecRadSys(RadSysNum).ScaledHeatingCapacity;
    2740              :                             }
    2741            4 :                         } else if (CapSizingMethod == CapacityPerFloorArea) {
    2742            2 :                             if (state.dataSize->ZoneSizingRunDone) {
    2743            2 :                                 CheckZoneSizing(state, CompType, CompName);
    2744            2 :                                 zoneEqSizing.HeatingCapacity = true;
    2745            2 :                                 zoneEqSizing.DesHeatingLoad = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).NonAirSysDesHeatLoad;
    2746              :                             }
    2747            2 :                             TempSize = state.dataLowTempRadSys->ElecRadSys(RadSysNum).ScaledHeatingCapacity *
    2748            2 :                                        Zone(state.dataLowTempRadSys->ElecRadSys(RadSysNum).ZonePtr).FloorArea;
    2749            2 :                             state.dataSize->DataScalableCapSizingON = true;
    2750              : 
    2751            2 :                         } else if (CapSizingMethod == FractionOfAutosizedHeatingCapacity) {
    2752            2 :                             CheckZoneSizing(state, CompType, CompName);
    2753            2 :                             zoneEqSizing.HeatingCapacity = true;
    2754            2 :                             zoneEqSizing.DesHeatingLoad = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).NonAirSysDesHeatLoad;
    2755            2 :                             TempSize = zoneEqSizing.DesHeatingLoad * state.dataLowTempRadSys->ElecRadSys(RadSysNum).ScaledHeatingCapacity;
    2756            2 :                             state.dataSize->DataScalableCapSizingON = true;
    2757              :                         } else {
    2758            0 :                             TempSize = state.dataLowTempRadSys->ElecRadSys(RadSysNum).ScaledHeatingCapacity;
    2759              :                         }
    2760            6 :                         HeatingCapacitySizer sizerHeatingCapacity;
    2761            6 :                         sizerHeatingCapacity.overrideSizingString(SizingString);
    2762            6 :                         sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    2763            6 :                         state.dataLowTempRadSys->ElecRadSys(RadSysNum).MaxElecPower = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
    2764            6 :                         state.dataSize->DataConstantUsedForSizing = 0.0;
    2765            6 :                         state.dataSize->DataFractionUsedForSizing = 0.0;
    2766            6 :                         state.dataSize->DataScalableCapSizingON = false;
    2767            6 :                     }
    2768              :                 }
    2769              :             }
    2770              : 
    2771           73 :         } else if (systemType == SystemType::Hydronic) {
    2772              : 
    2773           46 :             CompType = "ZoneHVAC:LowTemperatureRadiant:VariableFlow";
    2774           46 :             CompName = state.dataLowTempRadSys->HydrRadSys(RadSysNum).Name;
    2775              : 
    2776           46 :             IsAutoSize = false;
    2777           46 :             if (state.dataLowTempRadSys->HydrRadSys(RadSysNum).ScaledHeatingCapacity == AutoSize) {
    2778           44 :                 IsAutoSize = true;
    2779              :             }
    2780              : 
    2781           46 :             if (state.dataSize->CurZoneEqNum > 0) {
    2782           46 :                 auto &zoneEqSizing = state.dataSize->ZoneEqSizing(state.dataSize->CurZoneEqNum);
    2783              : 
    2784           46 :                 int SizingMethod = HeatingCapacitySizing;
    2785           46 :                 FieldNum = 2;
    2786           46 :                 PrintFlag = true;
    2787           46 :                 SizingString = state.dataLowTempRadSys->HydronicRadiantSysNumericFields(RadSysNum).FieldNames(FieldNum) + " [W]";
    2788           46 :                 CapSizingMethod = state.dataLowTempRadSys->HydrRadSys(RadSysNum).HeatingCapMethod;
    2789           46 :                 zoneEqSizing.SizingMethod(SizingMethod) = CapSizingMethod;
    2790              : 
    2791           46 :                 if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) { // simulation continue
    2792            0 :                     if (CapSizingMethod == HeatingDesignCapacity && state.dataLowTempRadSys->HydrRadSys(RadSysNum).ScaledHeatingCapacity > 0.0) {
    2793            0 :                         TempSize = state.dataLowTempRadSys->HydrRadSys(RadSysNum).ScaledHeatingCapacity;
    2794            0 :                         bool errorsFound = false;
    2795            0 :                         HeatingCapacitySizer sizerHeatingCapacity;
    2796            0 :                         sizerHeatingCapacity.overrideSizingString(SizingString);
    2797            0 :                         sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    2798            0 :                         DesCoilLoad = sizerHeatingCapacity.size(state, TempSize, errorsFound);
    2799            0 :                     } else if (CapSizingMethod == CapacityPerFloorArea) {
    2800            0 :                         state.dataSize->DataScalableCapSizingON = true;
    2801            0 :                         TempSize = state.dataLowTempRadSys->HydrRadSys(RadSysNum).ScaledHeatingCapacity *
    2802            0 :                                    Zone(state.dataLowTempRadSys->HydrRadSys(RadSysNum).ZonePtr).FloorArea;
    2803            0 :                         HeatingCapacitySizer sizerHeatingCapacity;
    2804            0 :                         sizerHeatingCapacity.overrideSizingString(SizingString);
    2805            0 :                         sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    2806            0 :                         DesCoilLoad = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
    2807            0 :                         state.dataSize->DataScalableCapSizingON = false;
    2808            0 :                     } else if (CapSizingMethod == FractionOfAutosizedHeatingCapacity) {
    2809            0 :                         if (state.dataLowTempRadSys->HydrRadSys(RadSysNum).WaterVolFlowMaxHeat == AutoSize) {
    2810            0 :                             ShowSevereError(state,
    2811            0 :                                             format("{}: auto-sizing cannot be done for {} = {}\".",
    2812              :                                                    RoutineName,
    2813              :                                                    CompType,
    2814            0 :                                                    state.dataLowTempRadSys->HydrRadSys(RadSysNum).Name));
    2815            0 :                             ShowContinueError(state,
    2816              :                                               "The \"SimulationControl\" object must have the field \"Do Zone Sizing Calculation\" set to Yes when "
    2817              :                                               "the Heating Design Capacity Method = \"FractionOfAutosizedHeatingCapacity\".");
    2818            0 :                             ErrorsFound = true;
    2819              :                         }
    2820              :                     }
    2821              :                 } else { // Autosize or hard-size with sizing run
    2822           46 :                     if (CapSizingMethod == HeatingDesignCapacity || CapSizingMethod == CapacityPerFloorArea ||
    2823              :                         CapSizingMethod == FractionOfAutosizedHeatingCapacity) {
    2824           46 :                         if (CapSizingMethod == HeatingDesignCapacity) {
    2825           44 :                             if (state.dataSize->ZoneSizingRunDone) {
    2826           44 :                                 CheckZoneSizing(state, CompType, CompName);
    2827           88 :                                 state.dataSize->DataConstantUsedForSizing =
    2828           44 :                                     state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).NonAirSysDesHeatLoad;
    2829           44 :                                 state.dataSize->DataFractionUsedForSizing = 1.0;
    2830              :                             }
    2831           44 :                             if (state.dataLowTempRadSys->HydrRadSys(RadSysNum).ScaledHeatingCapacity == AutoSize) {
    2832           44 :                                 TempSize = AutoSize;
    2833              :                             } else {
    2834            0 :                                 TempSize = state.dataLowTempRadSys->HydrRadSys(RadSysNum).ScaledHeatingCapacity;
    2835              :                             }
    2836            2 :                         } else if (CapSizingMethod == CapacityPerFloorArea) {
    2837            1 :                             if (state.dataSize->ZoneSizingRunDone) {
    2838            1 :                                 CheckZoneSizing(state, CompType, CompName);
    2839            1 :                                 zoneEqSizing.HeatingCapacity = true;
    2840            1 :                                 zoneEqSizing.DesHeatingLoad = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).NonAirSysDesHeatLoad;
    2841              :                             }
    2842            1 :                             TempSize = state.dataLowTempRadSys->HydrRadSys(RadSysNum).ScaledHeatingCapacity *
    2843            1 :                                        Zone(state.dataLowTempRadSys->HydrRadSys(RadSysNum).ZonePtr).FloorArea;
    2844            1 :                             state.dataSize->DataScalableCapSizingON = true;
    2845            1 :                         } else if (CapSizingMethod == FractionOfAutosizedHeatingCapacity) {
    2846            1 :                             CheckZoneSizing(state, CompType, CompName);
    2847            1 :                             zoneEqSizing.HeatingCapacity = true;
    2848            1 :                             zoneEqSizing.DesHeatingLoad = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).NonAirSysDesHeatLoad;
    2849            1 :                             TempSize = zoneEqSizing.DesHeatingLoad * state.dataLowTempRadSys->HydrRadSys(RadSysNum).ScaledHeatingCapacity;
    2850            1 :                             state.dataSize->DataScalableCapSizingON = true;
    2851              :                         } else {
    2852            0 :                             TempSize = state.dataLowTempRadSys->HydrRadSys(RadSysNum).ScaledHeatingCapacity;
    2853              :                         }
    2854           46 :                         HeatingCapacitySizer sizerHeatingCapacity;
    2855           46 :                         sizerHeatingCapacity.overrideSizingString(SizingString);
    2856           46 :                         sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    2857           46 :                         DesCoilLoad = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
    2858           46 :                         state.dataSize->DataConstantUsedForSizing = 0.0;
    2859           46 :                         state.dataSize->DataFractionUsedForSizing = 0.0;
    2860           46 :                         state.dataSize->DataScalableCapSizingON = false;
    2861           46 :                     } else {
    2862            0 :                         DesCoilLoad = 0.0;
    2863              :                     }
    2864              :                 }
    2865              :                 // finally heating capacity is saved in this variable
    2866           46 :                 state.dataLowTempRadSys->HydrRadSys(RadSysNum).ScaledHeatingCapacity = DesCoilLoad;
    2867              :             }
    2868              : 
    2869           46 :             IsAutoSize = false;
    2870           46 :             if (state.dataLowTempRadSys->HydrRadSys(RadSysNum).WaterVolFlowMaxHeat == AutoSize) {
    2871            6 :                 IsAutoSize = true;
    2872              :             }
    2873              : 
    2874           46 :             if (state.dataSize->CurZoneEqNum > 0) {
    2875           46 :                 if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) { // simulation continue
    2876            0 :                     if (state.dataLowTempRadSys->HydrRadSys(RadSysNum).WaterVolFlowMaxHeat > 0.0) {
    2877            0 :                         BaseSizer::reportSizerOutput(state,
    2878              :                                                      CompType,
    2879            0 :                                                      state.dataLowTempRadSys->HydrRadSys(RadSysNum).Name,
    2880              :                                                      "User-Specified Maximum Hot Water Flow [m3/s]",
    2881            0 :                                                      state.dataLowTempRadSys->HydrRadSys(RadSysNum).WaterVolFlowMaxHeat);
    2882              :                     }
    2883              :                 } else { // Autosize or hard-size with sizing run
    2884           92 :                     if (state.dataLowTempRadSys->HydrRadSys(RadSysNum).HotWaterInNode > 0 &&
    2885           46 :                         state.dataLowTempRadSys->HydrRadSys(RadSysNum).HotWaterOutNode > 0) {
    2886           46 :                         PltSizHeatNum = MyPlantSizingIndex(state,
    2887              :                                                            CompType,
    2888           46 :                                                            state.dataLowTempRadSys->HydrRadSys(RadSysNum).Name,
    2889           46 :                                                            state.dataLowTempRadSys->HydrRadSys(RadSysNum).HotWaterInNode,
    2890           46 :                                                            state.dataLowTempRadSys->HydrRadSys(RadSysNum).HotWaterOutNode,
    2891              :                                                            ErrorsFound);
    2892           46 :                         if (PltSizHeatNum > 0) {
    2893           46 :                             if (DesCoilLoad >= SmallLoad) {
    2894           43 :                                 rho = state.dataPlnt->PlantLoop(state.dataLowTempRadSys->HydrRadSys(RadSysNum).HWPlantLoc.loopNum)
    2895           43 :                                           .glycol->getDensity(state, Constant::HWInitConvTemp, RoutineName);
    2896           43 :                                 Cp = state.dataPlnt->PlantLoop(state.dataLowTempRadSys->HydrRadSys(RadSysNum).HWPlantLoc.loopNum)
    2897           43 :                                          .glycol->getSpecificHeat(state, Constant::HWInitConvTemp, RoutineName);
    2898           43 :                                 WaterVolFlowMaxHeatDes = DesCoilLoad / (state.dataSize->PlantSizData(PltSizHeatNum).DeltaT * Cp * rho);
    2899              :                             } else {
    2900            3 :                                 WaterVolFlowMaxHeatDes = 0.0;
    2901              :                             }
    2902              :                         } else {
    2903            0 :                             ShowSevereError(state, "Autosizing of water flow requires a heating loop Sizing:Plant object");
    2904            0 :                             ShowContinueError(state,
    2905            0 :                                               format("Occurs in ZoneHVAC:LowTemperatureRadiant:VariableFlow Object={}",
    2906            0 :                                                      state.dataLowTempRadSys->HydrRadSys(RadSysNum).Name));
    2907            0 :                             ErrorsFound = true;
    2908              :                         }
    2909              :                     }
    2910              : 
    2911           46 :                     if (IsAutoSize) {
    2912            6 :                         state.dataLowTempRadSys->HydrRadSys(RadSysNum).WaterVolFlowMaxHeat = WaterVolFlowMaxHeatDes;
    2913           12 :                         BaseSizer::reportSizerOutput(state,
    2914              :                                                      CompType,
    2915            6 :                                                      state.dataLowTempRadSys->HydrRadSys(RadSysNum).Name,
    2916              :                                                      "Design Size Maximum Hot Water Flow [m3/s]",
    2917              :                                                      WaterVolFlowMaxHeatDes);
    2918              :                     } else { // hard-size with sizing data
    2919           40 :                         if (state.dataLowTempRadSys->HydrRadSys(RadSysNum).WaterVolFlowMaxHeat > 0.0 && WaterVolFlowMaxHeatDes > 0.0) {
    2920           37 :                             WaterVolFlowMaxHeatUser = state.dataLowTempRadSys->HydrRadSys(RadSysNum).WaterVolFlowMaxHeat;
    2921           74 :                             BaseSizer::reportSizerOutput(state,
    2922              :                                                          CompType,
    2923           37 :                                                          state.dataLowTempRadSys->HydrRadSys(RadSysNum).Name,
    2924              :                                                          "Design Size Maximum Hot Water Flow [m3/s]",
    2925              :                                                          WaterVolFlowMaxHeatDes,
    2926              :                                                          "User-Specified Maximum Hot Water Flow [m3/s]",
    2927              :                                                          WaterVolFlowMaxHeatUser);
    2928           37 :                             if (state.dataGlobal->DisplayExtraWarnings) {
    2929            0 :                                 if ((std::abs(WaterVolFlowMaxHeatDes - WaterVolFlowMaxHeatUser) / WaterVolFlowMaxHeatUser) >
    2930            0 :                                     state.dataSize->AutoVsHardSizingThreshold) {
    2931            0 :                                     ShowMessage(state,
    2932            0 :                                                 format("SizeLowTempRadiantSystem: Potential issue with equipment sizing for "
    2933              :                                                        "ZoneHVAC:LowTemperatureRadiant:VariableFlow = \"{}\".",
    2934            0 :                                                        state.dataLowTempRadSys->HydrRadSys(RadSysNum).Name));
    2935            0 :                                     ShowContinueError(state,
    2936            0 :                                                       format("User-Specified Maximum Hot Water Flow of {:.5R} [m3/s]", WaterVolFlowMaxHeatUser));
    2937            0 :                                     ShowContinueError(
    2938            0 :                                         state, format("differs from Design Size Maximum Hot Water Flow of {:.5R} [m3/s]", WaterVolFlowMaxHeatDes));
    2939            0 :                                     ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    2940            0 :                                     ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    2941              :                                 }
    2942              :                             }
    2943              :                         }
    2944              :                     }
    2945              :                 }
    2946              :             }
    2947              : 
    2948           46 :             IsAutoSize = false;
    2949           46 :             if (state.dataLowTempRadSys->HydrRadSys(RadSysNum).ScaledCoolingCapacity == AutoSize) {
    2950           44 :                 IsAutoSize = true;
    2951              :             }
    2952              : 
    2953           46 :             if (state.dataSize->CurZoneEqNum > 0) {
    2954           46 :                 auto &zoneEqSizing = state.dataSize->ZoneEqSizing(state.dataSize->CurZoneEqNum);
    2955              : 
    2956           46 :                 int SizingMethod = CoolingCapacitySizing;
    2957           46 :                 FieldNum = 4;
    2958           46 :                 PrintFlag = true;
    2959           46 :                 SizingString = state.dataLowTempRadSys->HydronicRadiantSysNumericFields(RadSysNum).FieldNames(FieldNum) + " [W]";
    2960           46 :                 CapSizingMethod = state.dataLowTempRadSys->HydrRadSys(RadSysNum).CoolingCapMethod;
    2961           46 :                 zoneEqSizing.SizingMethod(SizingMethod) = CapSizingMethod;
    2962              : 
    2963           46 :                 if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) { // simulation continue
    2964            0 :                     if (CapSizingMethod == CoolingDesignCapacity && state.dataLowTempRadSys->HydrRadSys(RadSysNum).ScaledCoolingCapacity > 0.0) {
    2965            0 :                         TempSize = state.dataLowTempRadSys->HydrRadSys(RadSysNum).ScaledCoolingCapacity;
    2966            0 :                         CoolingCapacitySizer sizerCoolingCapacity;
    2967            0 :                         sizerCoolingCapacity.overrideSizingString(SizingString);
    2968            0 :                         sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    2969            0 :                         DesCoilLoad = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
    2970            0 :                     } else if (CapSizingMethod == CapacityPerFloorArea) {
    2971            0 :                         state.dataSize->DataScalableCapSizingON = true;
    2972            0 :                         TempSize = state.dataLowTempRadSys->HydrRadSys(RadSysNum).ScaledCoolingCapacity *
    2973            0 :                                    Zone(state.dataLowTempRadSys->HydrRadSys(RadSysNum).ZonePtr).FloorArea;
    2974            0 :                         CoolingCapacitySizer sizerCoolingCapacity;
    2975            0 :                         sizerCoolingCapacity.overrideSizingString(SizingString);
    2976            0 :                         sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    2977            0 :                         DesCoilLoad = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
    2978            0 :                         state.dataSize->DataScalableCapSizingON = false;
    2979            0 :                     } else if (CapSizingMethod == FractionOfAutosizedCoolingCapacity) {
    2980            0 :                         if (state.dataLowTempRadSys->HydrRadSys(RadSysNum).WaterVolFlowMaxCool == AutoSize) {
    2981            0 :                             ShowSevereError(state,
    2982            0 :                                             format("{}: auto-sizing cannot be done for {} = {}\".",
    2983              :                                                    RoutineName,
    2984              :                                                    CompType,
    2985            0 :                                                    state.dataLowTempRadSys->HydrRadSys(RadSysNum).Name));
    2986            0 :                             ShowContinueError(state,
    2987              :                                               "The \"SimulationControl\" object must have the field \"Do Zone Sizing Calculation\" set to Yes when "
    2988              :                                               "the Cooling Design Capacity Method = \"FractionOfAutosizedCoolingCapacity\".");
    2989            0 :                             ErrorsFound = true;
    2990              :                         }
    2991              :                     }
    2992              :                 } else { // Autosize or hard-size with sizing run
    2993           46 :                     if (CapSizingMethod == CoolingDesignCapacity || CapSizingMethod == CapacityPerFloorArea ||
    2994              :                         CapSizingMethod == FractionOfAutosizedCoolingCapacity) {
    2995           46 :                         if (CapSizingMethod == CoolingDesignCapacity) {
    2996           44 :                             if (state.dataSize->ZoneSizingRunDone) {
    2997           44 :                                 CheckZoneSizing(state, CompType, CompName);
    2998           88 :                                 state.dataSize->DataConstantUsedForSizing =
    2999           44 :                                     state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).NonAirSysDesCoolLoad;
    3000           44 :                                 state.dataSize->DataFractionUsedForSizing = 1.0;
    3001              :                             }
    3002           44 :                             if (state.dataLowTempRadSys->HydrRadSys(RadSysNum).ScaledCoolingCapacity == AutoSize) {
    3003           44 :                                 TempSize = AutoSize;
    3004              :                             } else {
    3005            0 :                                 TempSize = state.dataLowTempRadSys->HydrRadSys(RadSysNum).ScaledCoolingCapacity;
    3006              :                             }
    3007            2 :                         } else if (CapSizingMethod == CapacityPerFloorArea) {
    3008            1 :                             if (state.dataSize->ZoneSizingRunDone) {
    3009            1 :                                 CheckZoneSizing(state, CompType, CompName);
    3010            1 :                                 zoneEqSizing.CoolingCapacity = true;
    3011            1 :                                 zoneEqSizing.DesCoolingLoad = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).NonAirSysDesCoolLoad;
    3012              :                             }
    3013            1 :                             TempSize = state.dataLowTempRadSys->HydrRadSys(RadSysNum).ScaledCoolingCapacity *
    3014            1 :                                        Zone(state.dataLowTempRadSys->HydrRadSys(RadSysNum).ZonePtr).FloorArea;
    3015            1 :                             state.dataSize->DataScalableCapSizingON = true;
    3016            1 :                         } else if (CapSizingMethod == FractionOfAutosizedCoolingCapacity) {
    3017            1 :                             CheckZoneSizing(state, CompType, CompName);
    3018            1 :                             zoneEqSizing.CoolingCapacity = true;
    3019            1 :                             zoneEqSizing.DesCoolingLoad = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).NonAirSysDesCoolLoad;
    3020            1 :                             TempSize = zoneEqSizing.DesCoolingLoad * state.dataLowTempRadSys->HydrRadSys(RadSysNum).ScaledCoolingCapacity;
    3021            1 :                             state.dataSize->DataScalableCapSizingON = true;
    3022              : 
    3023              :                         } else {
    3024            0 :                             TempSize = state.dataLowTempRadSys->HydrRadSys(RadSysNum).ScaledCoolingCapacity;
    3025              :                         }
    3026           46 :                         CoolingCapacitySizer sizerCoolingCapacity;
    3027           46 :                         sizerCoolingCapacity.overrideSizingString(SizingString);
    3028           46 :                         sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    3029           46 :                         DesCoilLoad = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
    3030           46 :                         state.dataSize->DataConstantUsedForSizing = 0.0;
    3031           46 :                         state.dataSize->DataFractionUsedForSizing = 0.0;
    3032           46 :                         state.dataSize->DataScalableCapSizingON = false;
    3033           46 :                     } else {
    3034            0 :                         DesCoilLoad = 0.0;
    3035              :                     }
    3036              :                 }
    3037              :                 // finally cooling capacity is saved in this variable
    3038           46 :                 state.dataLowTempRadSys->HydrRadSys(RadSysNum).ScaledCoolingCapacity = DesCoilLoad;
    3039              :             }
    3040              : 
    3041           46 :             IsAutoSize = false;
    3042           46 :             if (state.dataLowTempRadSys->HydrRadSys(RadSysNum).WaterVolFlowMaxCool == AutoSize) {
    3043            6 :                 IsAutoSize = true;
    3044              :             }
    3045           46 :             if (state.dataSize->CurZoneEqNum > 0) {
    3046           46 :                 if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) { // simulation continue
    3047            0 :                     if (state.dataLowTempRadSys->HydrRadSys(RadSysNum).WaterVolFlowMaxCool > 0.0) {
    3048            0 :                         BaseSizer::reportSizerOutput(state,
    3049              :                                                      CompType,
    3050            0 :                                                      state.dataLowTempRadSys->HydrRadSys(RadSysNum).Name,
    3051              :                                                      "User-Specified Maximum Cold Water Flow [m3/s]",
    3052            0 :                                                      state.dataLowTempRadSys->HydrRadSys(RadSysNum).WaterVolFlowMaxCool);
    3053              :                     }
    3054              :                 } else { // Autosize or hard-size with sizing run
    3055           89 :                     if (state.dataLowTempRadSys->HydrRadSys(RadSysNum).ColdWaterInNode > 0 &&
    3056           43 :                         state.dataLowTempRadSys->HydrRadSys(RadSysNum).ColdWaterOutNode > 0) {
    3057           43 :                         PltSizCoolNum = MyPlantSizingIndex(state,
    3058              :                                                            CompType,
    3059           43 :                                                            state.dataLowTempRadSys->HydrRadSys(RadSysNum).Name,
    3060           43 :                                                            state.dataLowTempRadSys->HydrRadSys(RadSysNum).ColdWaterInNode,
    3061           43 :                                                            state.dataLowTempRadSys->HydrRadSys(RadSysNum).ColdWaterOutNode,
    3062              :                                                            ErrorsFound);
    3063           43 :                         if (PltSizCoolNum > 0) {
    3064           43 :                             if (DesCoilLoad >= SmallLoad) {
    3065           40 :                                 rho = state.dataPlnt->PlantLoop(state.dataLowTempRadSys->HydrRadSys(RadSysNum).CWPlantLoc.loopNum)
    3066           40 :                                           .glycol->getDensity(state, Constant::CWInitConvTemp, RoutineName);
    3067           40 :                                 Cp = state.dataPlnt->PlantLoop(state.dataLowTempRadSys->HydrRadSys(RadSysNum).CWPlantLoc.loopNum)
    3068           40 :                                          .glycol->getSpecificHeat(state, Constant::CWInitConvTemp, RoutineName);
    3069           40 :                                 WaterVolFlowMaxCoolDes = DesCoilLoad / (state.dataSize->PlantSizData(PltSizCoolNum).DeltaT * Cp * rho);
    3070              :                             } else {
    3071            3 :                                 WaterVolFlowMaxCoolDes = 0.0;
    3072              :                             }
    3073              :                         } else {
    3074            0 :                             ShowSevereError(state, "Autosizing of water flow requires a cooling loop Sizing:Plant object");
    3075            0 :                             ShowContinueError(state,
    3076            0 :                                               format("Occurs in ZoneHVAC:LowTemperatureRadiant:VariableFlow Object={}",
    3077            0 :                                                      state.dataLowTempRadSys->HydrRadSys(RadSysNum).Name));
    3078            0 :                             ErrorsFound = true;
    3079              :                         }
    3080              :                     }
    3081              : 
    3082           46 :                     if (IsAutoSize) {
    3083            6 :                         state.dataLowTempRadSys->HydrRadSys(RadSysNum).WaterVolFlowMaxCool = WaterVolFlowMaxCoolDes;
    3084           12 :                         BaseSizer::reportSizerOutput(state,
    3085              :                                                      CompType,
    3086            6 :                                                      state.dataLowTempRadSys->HydrRadSys(RadSysNum).Name,
    3087              :                                                      "Design Size Maximum Cold Water Flow [m3/s]",
    3088              :                                                      WaterVolFlowMaxCoolDes);
    3089              :                     } else { // hard-size with sizing data
    3090           40 :                         if (state.dataLowTempRadSys->HydrRadSys(RadSysNum).WaterVolFlowMaxCool > 0.0 && WaterVolFlowMaxCoolDes > 0.0) {
    3091           34 :                             WaterVolFlowMaxCoolUser = state.dataLowTempRadSys->HydrRadSys(RadSysNum).WaterVolFlowMaxCool;
    3092           68 :                             BaseSizer::reportSizerOutput(state,
    3093              :                                                          CompType,
    3094           34 :                                                          state.dataLowTempRadSys->HydrRadSys(RadSysNum).Name,
    3095              :                                                          "Design Size Maximum Cold Water Flow [m3/s]",
    3096              :                                                          WaterVolFlowMaxCoolDes,
    3097              :                                                          "User-Specified Maximum Cold Water Flow [m3/s]",
    3098              :                                                          WaterVolFlowMaxCoolUser);
    3099           34 :                             if (state.dataGlobal->DisplayExtraWarnings) {
    3100            0 :                                 if ((std::abs(WaterVolFlowMaxCoolDes - WaterVolFlowMaxCoolUser) / WaterVolFlowMaxCoolUser) >
    3101            0 :                                     state.dataSize->AutoVsHardSizingThreshold) {
    3102            0 :                                     ShowMessage(state,
    3103            0 :                                                 format("SizeLowTempRadiantSystem: Potential issue with equipment sizing for "
    3104              :                                                        "ZoneHVAC:LowTemperatureRadiant:VariableFlow = \"{}\".",
    3105            0 :                                                        state.dataLowTempRadSys->HydrRadSys(RadSysNum).Name));
    3106            0 :                                     ShowContinueError(state,
    3107            0 :                                                       format("User-Specified Maximum Cool Water Flow of {:.5R} [m3/s]", WaterVolFlowMaxCoolUser));
    3108            0 :                                     ShowContinueError(
    3109            0 :                                         state, format("differs from Design Size Maximum Cool Water Flow of {:.5R} [m3/s]", WaterVolFlowMaxCoolDes));
    3110            0 :                                     ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    3111            0 :                                     ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    3112              :                                 }
    3113              :                             }
    3114              :                         }
    3115              :                     }
    3116              :                 }
    3117              :             }
    3118              : 
    3119           46 :             IsAutoSize = false;
    3120           46 :             if (state.dataLowTempRadSys->HydrRadSys(RadSysNum).TubeLength == AutoSize) {
    3121            6 :                 IsAutoSize = true;
    3122              :             }
    3123           46 :             if (state.dataSize->CurZoneEqNum > 0) {
    3124           46 :                 if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) { // simulation continue
    3125            0 :                     if (state.dataLowTempRadSys->HydrRadSys(RadSysNum).TubeLength > 0.0) {
    3126            0 :                         BaseSizer::reportSizerOutput(state,
    3127              :                                                      CompType,
    3128            0 :                                                      state.dataLowTempRadSys->HydrRadSys(RadSysNum).Name,
    3129              :                                                      "User-Specified Hydronic Tubing Length [m]",
    3130            0 :                                                      state.dataLowTempRadSys->HydrRadSys(RadSysNum).TubeLength);
    3131              :                     }
    3132              :                 } else { // Autosize or hard-size with sizing run
    3133              :                     // CheckZoneSizing is not required here because the tube length calculation is not dependent on zone sizing calculation results
    3134           46 :                     TubeLengthDes = state.dataLowTempRadSys->HydrRadSys(RadSysNum).sizeRadiantSystemTubeLength(state);
    3135           46 :                     if (IsAutoSize) {
    3136            6 :                         state.dataLowTempRadSys->HydrRadSys(RadSysNum).TubeLength = TubeLengthDes;
    3137           12 :                         BaseSizer::reportSizerOutput(state,
    3138              :                                                      CompType,
    3139            6 :                                                      state.dataLowTempRadSys->HydrRadSys(RadSysNum).Name,
    3140              :                                                      "Design Size Hydronic Tubing Length [m]",
    3141              :                                                      TubeLengthDes);
    3142              :                     } else { // hard-size with sizing data
    3143           40 :                         if (state.dataLowTempRadSys->HydrRadSys(RadSysNum).TubeLength > 0.0 && TubeLengthDes > 0.0) {
    3144           40 :                             TubeLengthUser = state.dataLowTempRadSys->HydrRadSys(RadSysNum).TubeLength;
    3145           80 :                             BaseSizer::reportSizerOutput(state,
    3146              :                                                          CompType,
    3147           40 :                                                          state.dataLowTempRadSys->HydrRadSys(RadSysNum).Name,
    3148              :                                                          "Design Size Hydronic Tubing Length [m]",
    3149              :                                                          TubeLengthDes,
    3150              :                                                          "User-Specified Hydronic Tubing Length [m]",
    3151              :                                                          TubeLengthUser);
    3152           40 :                             if (state.dataGlobal->DisplayExtraWarnings) {
    3153            0 :                                 if ((std::abs(TubeLengthDes - TubeLengthUser) / TubeLengthUser) > state.dataSize->AutoVsHardSizingThreshold) {
    3154            0 :                                     ShowMessage(state,
    3155            0 :                                                 format("SizeLowTempRadiantSystem: Potential issue with equipment sizing for "
    3156              :                                                        "ZoneHVAC:LowTemperatureRadiant:VariableFlow = \"{}\".",
    3157            0 :                                                        state.dataLowTempRadSys->HydrRadSys(RadSysNum).Name));
    3158            0 :                                     ShowContinueError(state, format("User-Specified Hydronic Tubing Length of {:.5R} [m]", TubeLengthUser));
    3159            0 :                                     ShowContinueError(state, format("differs from Design Size Hydronic Tubing Length of {:.5R} [m]", TubeLengthDes));
    3160            0 :                                     ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    3161            0 :                                     ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    3162              :                                 }
    3163              :                             }
    3164              :                         }
    3165              :                     }
    3166              :                 }
    3167              :             }
    3168              : 
    3169          104 :             for (SurfNum = 1; SurfNum <= state.dataLowTempRadSys->HydrRadSys(RadSysNum).NumOfSurfaces; ++SurfNum) {
    3170           58 :                 if (state.dataLowTempRadSys->HydrRadSys(RadSysNum).NumCircCalcMethod == CircuitCalc::CalculateFromLength) {
    3171            0 :                     state.dataLowTempRadSys->HydrRadSys(RadSysNum).NumCircuits(SurfNum) =
    3172            0 :                         (state.dataLowTempRadSys->HydrRadSys(RadSysNum).SurfaceFrac(SurfNum) *
    3173            0 :                          state.dataLowTempRadSys->HydrRadSys(RadSysNum).TubeLength) /
    3174            0 :                         state.dataLowTempRadSys->HydrRadSys(RadSysNum).CircLength;
    3175            0 :                     state.dataLowTempRadSys->HydrRadSys(RadSysNum).NumCircuits(SurfNum) =
    3176            0 :                         max(state.dataLowTempRadSys->HydrRadSys(RadSysNum).NumCircuits(SurfNum), 1.0);
    3177              :                 } else {
    3178           58 :                     state.dataLowTempRadSys->HydrRadSys(RadSysNum).NumCircuits(SurfNum) = 1.0;
    3179              :                 }
    3180              :             }
    3181              : 
    3182           92 :             RegisterPlantCompDesignFlow(state,
    3183           46 :                                         state.dataLowTempRadSys->HydrRadSys(RadSysNum).HotWaterInNode,
    3184           46 :                                         state.dataLowTempRadSys->HydrRadSys(RadSysNum).WaterVolFlowMaxHeat);
    3185           92 :             RegisterPlantCompDesignFlow(state,
    3186           46 :                                         state.dataLowTempRadSys->HydrRadSys(RadSysNum).ColdWaterInNode,
    3187           46 :                                         state.dataLowTempRadSys->HydrRadSys(RadSysNum).WaterVolFlowMaxCool);
    3188              : 
    3189           27 :         } else if (systemType == SystemType::ConstantFlow) {
    3190              : 
    3191           27 :             CompType = "ZoneHVAC:LowTemperatureRadiant:ConstantFlow";
    3192           27 :             CompName = state.dataLowTempRadSys->CFloRadSys(RadSysNum).Name;
    3193              : 
    3194              :             // Why is this not the same thing as the other OpMode enumeration? In the .hh file?
    3195              :             OperatingMode OpMode; // System operating mode
    3196              : 
    3197              :             // Check which operating system it is
    3198           27 :             int HeatNode = state.dataLowTempRadSys->CFloRadSys(RadSysNum).HotWaterInNode;
    3199           27 :             int CoolNode = state.dataLowTempRadSys->CFloRadSys(RadSysNum).ColdWaterInNode;
    3200           27 :             if (HeatNode > 0 && CoolNode > 0) {
    3201           24 :                 OpMode = OperatingMode::ClgHtg;
    3202            3 :             } else if (HeatNode > 0 && CoolNode <= 0) {
    3203            3 :                 OpMode = OperatingMode::HtgOnly;
    3204            0 :             } else if (CoolNode > 0 && HeatNode <= 0) {
    3205            0 :                 OpMode = OperatingMode::ClgOnly;
    3206              :             } else {
    3207            0 :                 OpMode = OperatingMode::OFF; // It shouldn't happen here
    3208              :             }
    3209              : 
    3210           27 :             if (state.dataLowTempRadSys->CFloRadSys(RadSysNum).WaterVolFlowMax == AutoSize) {
    3211            1 :                 IsAutoSize = true;
    3212              :             }
    3213              : 
    3214           27 :             if (state.dataSize->CurZoneEqNum > 0) {
    3215           27 :                 if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) { // simulation continue
    3216           24 :                     if (state.dataLowTempRadSys->CFloRadSys(RadSysNum).WaterVolFlowMax > 0.0) {
    3217           48 :                         BaseSizer::reportSizerOutput(state,
    3218              :                                                      CompType,
    3219           24 :                                                      state.dataLowTempRadSys->CFloRadSys(RadSysNum).Name,
    3220              :                                                      "User-Specified Maximum Water Flow [m3/s]",
    3221           24 :                                                      state.dataLowTempRadSys->CFloRadSys(RadSysNum).WaterVolFlowMax);
    3222              :                     }
    3223              :                 } else { // Autosize or hard-size with sizing run
    3224            3 :                     CheckZoneSizing(state, CompType, state.dataLowTempRadSys->CFloRadSys(RadSysNum).Name);
    3225              :                     // Estimate hot water and chilled water flows
    3226              :                     // Index only if it provides heating to avoid severe error
    3227            3 :                     if (OpMode == OperatingMode::ClgHtg || OpMode == OperatingMode::HtgOnly) {
    3228            3 :                         PltSizHeatNum = MyPlantSizingIndex(state,
    3229              :                                                            CompType,
    3230            3 :                                                            state.dataLowTempRadSys->CFloRadSys(RadSysNum).Name,
    3231            3 :                                                            state.dataLowTempRadSys->CFloRadSys(RadSysNum).HotWaterInNode,
    3232            3 :                                                            state.dataLowTempRadSys->CFloRadSys(RadSysNum).HotWaterOutNode,
    3233              :                                                            ErrorsFound);
    3234              :                     }
    3235            3 :                     if (PltSizHeatNum > 0) {
    3236            3 :                         if (state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).NonAirSysDesHeatLoad >= SmallLoad) {
    3237            3 :                             rho = state.dataPlnt->PlantLoop(state.dataLowTempRadSys->CFloRadSys(RadSysNum).HWPlantLoc.loopNum)
    3238            3 :                                       .glycol->getDensity(state, Constant::HWInitConvTemp, "SizeLowTempRadiantSystem");
    3239            3 :                             Cp = state.dataPlnt->PlantLoop(state.dataLowTempRadSys->CFloRadSys(RadSysNum).HWPlantLoc.loopNum)
    3240            3 :                                      .glycol->getSpecificHeat(state, Constant::HWInitConvTemp, "SizeLowTempRadiantSystem");
    3241            3 :                             WaterVolFlowMaxHeatDes = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).NonAirSysDesHeatLoad /
    3242            3 :                                                      (state.dataSize->PlantSizData(PltSizHeatNum).DeltaT * Cp * rho);
    3243              :                         } else {
    3244            0 :                             WaterVolFlowMaxHeatDes = 0.0;
    3245              :                         }
    3246              :                     } else {
    3247            0 :                         if (OpMode == OperatingMode::ClgHtg || OpMode == OperatingMode::HtgOnly) {
    3248            0 :                             ShowSevereError(state, "Autosizing of water flow requires a heating loop Sizing:Plant object");
    3249            0 :                             ShowContinueError(state,
    3250            0 :                                               format("Occurs in ZoneHVAC:LowTemperatureRadiant:ConstantFlow Object={}",
    3251            0 :                                                      state.dataLowTempRadSys->CFloRadSys(RadSysNum).Name));
    3252            0 :                             ErrorsFound = true;
    3253              :                         }
    3254              :                     }
    3255              : 
    3256              :                     // Index only if it provides cooling system to avoid severe error
    3257            3 :                     if (OpMode == OperatingMode::ClgHtg || OpMode == OperatingMode::ClgOnly) {
    3258            3 :                         PltSizCoolNum = MyPlantSizingIndex(state,
    3259              :                                                            CompType,
    3260            3 :                                                            state.dataLowTempRadSys->CFloRadSys(RadSysNum).Name,
    3261            3 :                                                            state.dataLowTempRadSys->CFloRadSys(RadSysNum).ColdWaterInNode,
    3262            3 :                                                            state.dataLowTempRadSys->CFloRadSys(RadSysNum).ColdWaterOutNode,
    3263              :                                                            ErrorsFound);
    3264              :                     }
    3265            3 :                     if (PltSizCoolNum > 0) {
    3266            3 :                         if (state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).NonAirSysDesCoolLoad >= SmallLoad) {
    3267            3 :                             rho = state.dataPlnt->PlantLoop(state.dataLowTempRadSys->CFloRadSys(RadSysNum).CWPlantLoc.loopNum)
    3268            3 :                                       .glycol->getDensity(state, Constant::CWInitConvTemp, "SizeLowTempRadiantSystem");
    3269            3 :                             Cp = state.dataPlnt->PlantLoop(state.dataLowTempRadSys->CFloRadSys(RadSysNum).CWPlantLoc.loopNum)
    3270            3 :                                      .glycol->getSpecificHeat(state, Constant::CWInitConvTemp, "SizeLowTempRadiantSystem");
    3271            3 :                             WaterVolFlowMaxCoolDes = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).NonAirSysDesCoolLoad /
    3272            3 :                                                      (state.dataSize->PlantSizData(PltSizCoolNum).DeltaT * Cp * rho);
    3273              :                         } else {
    3274            0 :                             WaterVolFlowMaxCoolDes = 0.0;
    3275              :                         }
    3276              :                     } else {
    3277            0 :                         if (OpMode == OperatingMode::ClgHtg || OpMode == OperatingMode::ClgOnly) {
    3278            0 :                             ShowSevereError(state, "Autosizing of water flow requires a cooling loop Sizing:Plant object");
    3279            0 :                             ShowContinueError(state,
    3280            0 :                                               format("Occurs in ZoneHVAC:LowTemperatureRadiant:ConstantFlow Object={}",
    3281            0 :                                                      state.dataLowTempRadSys->CFloRadSys(RadSysNum).Name));
    3282            0 :                             ErrorsFound = true;
    3283              :                         }
    3284              :                     }
    3285              : 
    3286              :                     // Determine maximum water flow rate depending upon system type
    3287            3 :                     if (OpMode == OperatingMode::ClgHtg) {
    3288            3 :                         WaterVolFlowMaxDes = std::max(WaterVolFlowMaxHeatDes, WaterVolFlowMaxCoolDes);
    3289            0 :                     } else if (OpMode == OperatingMode::ClgOnly) {
    3290            0 :                         WaterVolFlowMaxDes = WaterVolFlowMaxCoolDes;
    3291            0 :                     } else if (OpMode == OperatingMode::HtgOnly) {
    3292            0 :                         WaterVolFlowMaxDes = WaterVolFlowMaxHeatDes;
    3293              :                     } else {
    3294            0 :                         WaterVolFlowMaxDes = 0.0;
    3295              :                     }
    3296              : 
    3297            3 :                     if (IsAutoSize) {
    3298            1 :                         state.dataLowTempRadSys->CFloRadSys(RadSysNum).WaterVolFlowMax = WaterVolFlowMaxDes;
    3299            2 :                         BaseSizer::reportSizerOutput(state,
    3300              :                                                      CompType,
    3301            1 :                                                      state.dataLowTempRadSys->CFloRadSys(RadSysNum).Name,
    3302              :                                                      "Design Size Maximum Water Flow [m3/s]",
    3303              :                                                      WaterVolFlowMaxDes);
    3304              :                     } else { // hard-size with sizing data
    3305            2 :                         if (state.dataLowTempRadSys->CFloRadSys(RadSysNum).WaterVolFlowMax > 0.0 && WaterVolFlowMaxDes > 0.0) {
    3306            2 :                             WaterVolFlowMaxUser = state.dataLowTempRadSys->CFloRadSys(RadSysNum).WaterVolFlowMax;
    3307            4 :                             BaseSizer::reportSizerOutput(state,
    3308              :                                                          CompType,
    3309            2 :                                                          state.dataLowTempRadSys->CFloRadSys(RadSysNum).Name,
    3310              :                                                          "Design Size Maximum Water Flow [m3/s]",
    3311              :                                                          WaterVolFlowMaxDes,
    3312              :                                                          "User-Specified Maximum Water Flow [m3/s]",
    3313              :                                                          WaterVolFlowMaxUser);
    3314            2 :                             if (state.dataGlobal->DisplayExtraWarnings) {
    3315            0 :                                 if ((std::abs(WaterVolFlowMaxDes - WaterVolFlowMaxUser) / WaterVolFlowMaxUser) >
    3316            0 :                                     state.dataSize->AutoVsHardSizingThreshold) {
    3317            0 :                                     ShowMessage(state,
    3318            0 :                                                 format("SizeLowTempRadiantSystem: Potential issue with equipment sizing for "
    3319              :                                                        "ZoneHVAC:LowTemperatureRadiant:ConstantFlow = \" {}\".",
    3320            0 :                                                        state.dataLowTempRadSys->CFloRadSys(RadSysNum).Name));
    3321            0 :                                     ShowContinueError(state, format("User-Specified Maximum Water Flow of {:.5R} [m3/s]", WaterVolFlowMaxUser));
    3322            0 :                                     ShowContinueError(state,
    3323            0 :                                                       format("differs from Design Size Maximum Water Flow of {:.5R} [m3/s]", WaterVolFlowMaxDes));
    3324            0 :                                     ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    3325            0 :                                     ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    3326              :                                 }
    3327              :                             }
    3328              :                         }
    3329              :                     }
    3330              :                 }
    3331              :             }
    3332              : 
    3333           27 :             IsAutoSize = false;
    3334           27 :             if (state.dataLowTempRadSys->CFloRadSys(RadSysNum).TubeLength == AutoSize) {
    3335            1 :                 IsAutoSize = true;
    3336              :             }
    3337              : 
    3338           27 :             if (state.dataSize->CurZoneEqNum > 0) {
    3339           27 :                 if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) { // simulation continue
    3340           24 :                     if (state.dataLowTempRadSys->CFloRadSys(RadSysNum).TubeLength > 0.0) {
    3341           48 :                         BaseSizer::reportSizerOutput(state,
    3342              :                                                      "ZoneHVAC:LowTemperatureRadiant:ConstantFlow",
    3343           24 :                                                      state.dataLowTempRadSys->CFloRadSys(RadSysNum).Name,
    3344              :                                                      "User-Specified Hydronic Tubing Length [m]",
    3345           24 :                                                      state.dataLowTempRadSys->CFloRadSys(RadSysNum).TubeLength);
    3346              :                     }
    3347              :                 } else { // Autosize or hard-size with sizing run
    3348              :                     // CheckZoneSizing is not required here because the tube length calculation is not dependent on zone sizing calculation results
    3349            3 :                     TubeLengthDes = state.dataLowTempRadSys->CFloRadSys(RadSysNum).sizeRadiantSystemTubeLength(state);
    3350            3 :                     if (IsAutoSize) {
    3351            1 :                         state.dataLowTempRadSys->CFloRadSys(RadSysNum).TubeLength = TubeLengthDes;
    3352            2 :                         BaseSizer::reportSizerOutput(state,
    3353              :                                                      "ZoneHVAC:LowTemperatureRadiant:ConstantFlow",
    3354            1 :                                                      state.dataLowTempRadSys->CFloRadSys(RadSysNum).Name,
    3355              :                                                      "Design Size Hydronic Tubing Length [m]",
    3356              :                                                      TubeLengthDes);
    3357              :                     } else { // hard-size with sizing data
    3358            2 :                         if (state.dataLowTempRadSys->CFloRadSys(RadSysNum).TubeLength > 0.0 && TubeLengthDes > 0.0) {
    3359            2 :                             TubeLengthUser = state.dataLowTempRadSys->CFloRadSys(RadSysNum).TubeLength;
    3360            4 :                             BaseSizer::reportSizerOutput(state,
    3361              :                                                          "ZoneHVAC:LowTemperatureRadiant:ConstantFlow",
    3362            2 :                                                          state.dataLowTempRadSys->CFloRadSys(RadSysNum).Name,
    3363              :                                                          "Design Size Hydronic Tubing Length [m]",
    3364              :                                                          TubeLengthDes,
    3365              :                                                          "User-Specified Hydronic Tubing Length [m]",
    3366              :                                                          TubeLengthUser);
    3367            2 :                             if (state.dataGlobal->DisplayExtraWarnings) {
    3368            0 :                                 if ((std::abs(TubeLengthDes - TubeLengthUser) / TubeLengthUser) > state.dataSize->AutoVsHardSizingThreshold) {
    3369            0 :                                     ShowMessage(state,
    3370            0 :                                                 format("SizeLowTempRadiantSystem: Potential issue with equipment sizing for "
    3371              :                                                        "ZoneHVAC:LowTemperatureRadiant:ConstantFlow = \" {}\".",
    3372            0 :                                                        state.dataLowTempRadSys->CFloRadSys(RadSysNum).Name));
    3373            0 :                                     ShowContinueError(state, format("User-Specified Hydronic Tubing Length of {:.5R} [m]", TubeLengthUser));
    3374            0 :                                     ShowContinueError(state, format("differs from Design Size Hydronic Tubing Length of {:.5R} [m]", TubeLengthDes));
    3375            0 :                                     ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    3376            0 :                                     ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    3377              :                                 }
    3378              :                             }
    3379              :                         }
    3380              :                     }
    3381              :                 }
    3382              :             }
    3383              : 
    3384           54 :             for (SurfNum = 1; SurfNum <= state.dataLowTempRadSys->CFloRadSys(RadSysNum).NumOfSurfaces; ++SurfNum) {
    3385           27 :                 if (state.dataLowTempRadSys->CFloRadSys(RadSysNum).NumCircCalcMethod == CircuitCalc::CalculateFromLength) {
    3386            0 :                     state.dataLowTempRadSys->CFloRadSys(RadSysNum).NumCircuits(SurfNum) =
    3387            0 :                         (state.dataLowTempRadSys->CFloRadSys(RadSysNum).SurfaceFrac(SurfNum) *
    3388            0 :                          state.dataLowTempRadSys->CFloRadSys(RadSysNum).TubeLength) /
    3389            0 :                         state.dataLowTempRadSys->CFloRadSys(RadSysNum).CircLength;
    3390            0 :                     state.dataLowTempRadSys->CFloRadSys(RadSysNum).NumCircuits(SurfNum) =
    3391            0 :                         max(state.dataLowTempRadSys->CFloRadSys(RadSysNum).NumCircuits(SurfNum), 1.0);
    3392              :                 } else {
    3393           27 :                     state.dataLowTempRadSys->CFloRadSys(RadSysNum).NumCircuits(SurfNum) = 1.0;
    3394              :                 }
    3395              :             }
    3396           27 :             if (state.dataLowTempRadSys->CFloRadSys(RadSysNum).HotWaterInNode > 0) {
    3397           54 :                 RegisterPlantCompDesignFlow(state,
    3398           27 :                                             state.dataLowTempRadSys->CFloRadSys(RadSysNum).HotWaterInNode,
    3399           27 :                                             state.dataLowTempRadSys->CFloRadSys(RadSysNum).WaterVolFlowMax);
    3400              :             }
    3401           27 :             if (state.dataLowTempRadSys->CFloRadSys(RadSysNum).ColdWaterInNode > 0) {
    3402           48 :                 RegisterPlantCompDesignFlow(state,
    3403           24 :                                             state.dataLowTempRadSys->CFloRadSys(RadSysNum).ColdWaterInNode,
    3404           24 :                                             state.dataLowTempRadSys->CFloRadSys(RadSysNum).WaterVolFlowMax);
    3405              :             }
    3406              :         }
    3407              : 
    3408           82 :         if (ErrorsFound) {
    3409            0 :             ShowFatalError(state, "Preceding sizing errors cause program termination");
    3410              :         }
    3411           82 :     }
    3412              : 
    3413           49 :     Real64 HydronicSystemBaseData::sizeRadiantSystemTubeLength(EnergyPlusData &state)
    3414              :     {
    3415              : 
    3416              :         // SUBROUTINE INFORMATION:
    3417              :         //       AUTHOR         Rick Strand
    3418              :         //       DATE WRITTEN   August 2017
    3419              : 
    3420              :         // PURPOSE OF THIS SUBROUTINE:
    3421              :         // This subroutine figures out the tube length based on the spacing of tubes.
    3422              :         // For single surface systems, this is fairly easy as there is only one spacing
    3423              :         // to deal with.  For multi-surface systems, more work is necessary because each
    3424              :         // surface could use a different spacing.
    3425              : 
    3426              :         // Return value
    3427              :         Real64 sizeRadiantSystemTubeLength;
    3428              : 
    3429           49 :         Real64 tubeLength(0.0); // temporary holding place for the function calculation
    3430              : 
    3431          110 :         for (int surfNum = 1; surfNum <= this->NumOfSurfaces; ++surfNum) {
    3432           61 :             auto &thisHydrSysSurf = state.dataSurface->Surface(this->SurfacePtr(surfNum));
    3433           61 :             auto const &thisHydrSpacing = state.dataConstruction->Construct(thisHydrSysSurf.Construction).ThicknessPerpend;
    3434           61 :             if ((thisHydrSpacing > 0.005) && (thisHydrSpacing < 0.5)) { // limit allowable spacing to between 1cm and 1m
    3435           61 :                 tubeLength += thisHydrSysSurf.Area / (2.0 * thisHydrSpacing);
    3436              :             } else { // if not in allowable limit, default back to 0.15m (15cm or 6 inches)
    3437            0 :                 tubeLength += thisHydrSysSurf.Area / 0.15;
    3438              :             }
    3439              :         }
    3440              : 
    3441           49 :         sizeRadiantSystemTubeLength = tubeLength;
    3442           49 :         return sizeRadiantSystemTubeLength;
    3443              :     }
    3444              : 
    3445       366056 :     void VariableFlowRadiantSystemData::calculateLowTemperatureRadiantSystem(EnergyPlusData &state,
    3446              :                                                                              Real64 &LoadMet) // load met by the radiant system, in Watts
    3447              :     {
    3448              : 
    3449              :         // SUBROUTINE INFORMATION:
    3450              :         //       AUTHOR         Rick Strand
    3451              :         //       DATE WRITTEN   November 2000
    3452              : 
    3453              :         // PURPOSE OF THIS SUBROUTINE:
    3454              :         // This subroutine does all of the stuff that is necessary to simulate
    3455              :         // a low temperature hydronic radiant heating/cooling system.  Calls are
    3456              :         // made to appropriate subroutines either in this module or outside of it.
    3457              : 
    3458              :         // METHODOLOGY EMPLOYED:
    3459              :         // Follows the methods used by many other pieces of zone equipment.
    3460              :         // Much like a water coil, a hydronic system will use the ControlCompOutput
    3461              :         // routine to determine what fraction of capacity the unit should be
    3462              :         // functioning at by controlling the flow rate of water to the element.
    3463              : 
    3464              :         // REFERENCES:
    3465              :         // Other EnergyPlus modules
    3466              :         // IBLAST-QTF research program, completed in January 1995 (unreleased)
    3467              :         // Strand, R.K. 1995. "Heat Source Transfer Functions and Their Application to
    3468              :         //   Low Temperature Radiant Heating Systems", Ph.D. dissertation, University
    3469              :         //   of Illinois at Urbana-Champaign, Department of Mechanical and Industrial
    3470              :         //   Engineering.
    3471              :         // Seem, J.E. 1986. "Heat Transfer in Buildings", Ph.D. dissertation, University
    3472              :         //   of Wisconsin-Madison.
    3473              : 
    3474              :         // Using/Aliasing
    3475              :         using DataHeatBalance::ZoneData;
    3476              :         using HVAC::SmallLoad;
    3477              :         using PlantUtilities::SetComponentFlowRate;
    3478              : 
    3479              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    3480              :         Real64 ActWaterFlow; // actual water flow for heating or cooling [kg/sec]
    3481              :         Real64 ControlTemp;  // temperature of whatever is controlling the radiant system
    3482              :         Real64 MassFlowFrac; // fraction of the maximum water flow rate as determined by the control algorithm
    3483              :         Real64 MaxWaterFlow; // maximum water flow for heating or cooling [kg/sec]
    3484              :         Real64 OffTempCool;  // temperature at which the flow rate throttles back to zero for cooling
    3485              :         Real64 OffTempHeat;  // temperature at which the flow rate throttles back to zero for heating
    3486              :         Real64 mdot;         // local temporary for fluid mass flow rate
    3487              :         bool SysRunning;     // True when system is running
    3488              : 
    3489              :         VarFlowRadDesignData variableFlowDesignDataObject =                           // Is this intended to be a copy?
    3490       366056 :             state.dataLowTempRadSys->HydronicRadiantSysDesign(this->DesignObjectPtr); // Contains the data for variable flow hydronic systems
    3491              : 
    3492       366056 :         MaxWaterFlow = 0.0;
    3493       366056 :         ActWaterFlow = 0.0;
    3494       366056 :         this->opMode = OpMode::None;
    3495       366056 :         SysRunning = true;
    3496              : 
    3497       366056 :         if (this->availSched->getCurrentVal() <= 0) {
    3498              : 
    3499              :             // Unit is off or has no load upon it; set the flow rates to zero and then
    3500              :             // simulate the components with the no flow conditions
    3501        15426 :             for (int SurfNum = 1; SurfNum <= this->NumOfSurfaces; ++SurfNum) {
    3502         7713 :                 int SurfNum2 = this->SurfacePtr(SurfNum);
    3503         7713 :                 auto &surface = state.dataSurface->Surface(SurfNum2);
    3504         7713 :                 state.dataHeatBalFanSys->QRadSysSource(SurfNum2) = 0.0;
    3505         7713 :                 if (surface.ExtBoundCond > 0 && surface.ExtBoundCond != SurfNum2) {
    3506            0 :                     state.dataHeatBalFanSys->QRadSysSource(surface.ExtBoundCond) = 0.0; // Also zero the other side of an interzone
    3507              :                 }
    3508              :             }
    3509         7713 :             if (this->HeatingSystem) {
    3510         7710 :                 mdot = 0.0;
    3511         7710 :                 SetComponentFlowRate(state, mdot, this->HotWaterInNode, this->HotWaterOutNode, this->HWPlantLoc);
    3512              :             }
    3513         7713 :             if (this->CoolingSystem) {
    3514            0 :                 mdot = 0.0;
    3515            0 :                 SetComponentFlowRate(state, mdot, this->ColdWaterInNode, this->ColdWaterOutNode, this->CWPlantLoc);
    3516              :             }
    3517              :         } else { // Unit might be on-->this section is intended to control the water mass flow rate being
    3518              :             // sent to the radiant system
    3519              : 
    3520       358343 :             ControlTemp = this->setRadiantSystemControlTemperature(state, variableFlowDesignDataObject.VarFlowControlType);
    3521              : 
    3522       358343 :             if (variableFlowDesignDataObject.heatSetptSched != nullptr) {
    3523              :                 //                OffTempHeat = this->setOffTemperatureLowTemperatureRadiantSystem(state, this->HotSetptSchedPtr,
    3524              :                 //                this->HotThrottlRange);
    3525              :                 Real64 a;
    3526       358343 :                 a = variableFlowDesignDataObject.HotThrottlRange; // Why are we doing this?
    3527       358343 :                 OffTempHeat = this->setOffTemperatureLowTemperatureRadiantSystem(state,
    3528       358343 :                                                                                  variableFlowDesignDataObject.heatSetptSched,
    3529              :                                                                                  variableFlowDesignDataObject.HotThrottlRange,
    3530              :                                                                                  variableFlowDesignDataObject.VarFlowSetpointType);
    3531              :             } else { // This system is not capable of heating, set OffTempHeat to something really low
    3532            0 :                 OffTempHeat = state.dataLowTempRadSys->LowTempHeating;
    3533              :             }
    3534       358343 :             if (variableFlowDesignDataObject.coolSetptSched != nullptr) {
    3535       351248 :                 OffTempCool = this->setOffTemperatureLowTemperatureRadiantSystem(state,
    3536       351248 :                                                                                  variableFlowDesignDataObject.coolSetptSched,
    3537       351248 :                                                                                  -variableFlowDesignDataObject.ColdThrottlRange,
    3538              :                                                                                  variableFlowDesignDataObject.VarFlowSetpointType);
    3539              :             } else { // This system is not capable of cooling, set OffTempCool to something really high
    3540         7095 :                 OffTempCool = state.dataLowTempRadSys->HighTempCooling;
    3541              :             }
    3542              : 
    3543              :             // Check for an illogical condition where a user enters controls that could
    3544              :             // potentially be heating or cooling at a particular control temperature
    3545       358343 :             if (OffTempHeat > OffTempCool) {
    3546            0 :                 MassFlowFrac = 0.0;
    3547            0 :                 ShowSevereError(state, format("Overlapping heating and cooling control temps in radiant system: {}", this->Name));
    3548            0 :                 ShowFatalError(state, "Preceding condition causes termination.");
    3549              : 
    3550              :             } else { // Temperatures for heating and cooling do not overlap--calculate the mass flow fraction
    3551              : 
    3552       358343 :                 if (ControlTemp < OffTempHeat && this->HeatingSystem) { // Heating mode
    3553       154356 :                     this->opMode = OpMode::Heat;
    3554       203987 :                 } else if (ControlTemp > OffTempCool && this->CoolingSystem) { // Cooling mode
    3555       140407 :                     this->opMode = OpMode::Cool;
    3556              :                 }
    3557              : 
    3558       358343 :                 this->setOperatingModeBasedOnChangeoverDelay(state);
    3559              : 
    3560       358343 :                 if (this->opMode == OpMode::Heat) {
    3561       151202 :                     MaxWaterFlow = this->WaterFlowMaxHeat;
    3562       151202 :                     MassFlowFrac = this->calculateOperationalFraction(OffTempHeat, ControlTemp, variableFlowDesignDataObject.HotThrottlRange);
    3563       207141 :                 } else if (this->opMode == OpMode::Cool) {
    3564       139753 :                     MaxWaterFlow = this->WaterFlowMaxCool;
    3565       139753 :                     MassFlowFrac = this->calculateOperationalFraction(OffTempCool, ControlTemp, variableFlowDesignDataObject.ColdThrottlRange);
    3566              :                 } else {
    3567        67388 :                     MassFlowFrac = 0.0;
    3568              :                 }
    3569              :             }
    3570              : 
    3571              :             // Calculate and limit the water flow rate
    3572       358343 :             ActWaterFlow = MassFlowFrac * MaxWaterFlow;
    3573       358343 :             if (ActWaterFlow < DataBranchAirLoopPlant::MassFlowTolerance) {
    3574        67388 :                 ActWaterFlow = 0.0;
    3575              :             }
    3576       358343 :             if (this->EMSOverrideOnWaterMdot) {
    3577            0 :                 ActWaterFlow = this->EMSWaterMdotOverrideValue;
    3578              :             }
    3579              : 
    3580       358343 :             if (this->opMode == OpMode::Heat) {
    3581       151202 :                 if (this->HeatingSystem) {
    3582       151202 :                     SetComponentFlowRate(state, ActWaterFlow, this->HotWaterInNode, this->HotWaterOutNode, this->HWPlantLoc);
    3583              :                 } else { // not heating system
    3584            0 :                     SysRunning = false;
    3585              :                 }
    3586       207141 :             } else if (this->opMode == OpMode::Cool) {
    3587       139753 :                 if (this->CoolingSystem) {
    3588       139753 :                     SetComponentFlowRate(state, ActWaterFlow, this->ColdWaterInNode, this->ColdWaterOutNode, this->CWPlantLoc);
    3589              :                 } else { // not cooling system
    3590            0 :                     SysRunning = false;
    3591              :                 }
    3592              :             }
    3593              : 
    3594              :             // Now simulate the system...
    3595       358343 :             if (((this->opMode == OpMode::Heat) || (this->opMode == OpMode::Cool)) && SysRunning) {
    3596       290955 :                 this->calculateLowTemperatureRadiantSystemComponents(state, LoadMet, SystemType::Hydronic);
    3597              :             }
    3598              :         }
    3599       366056 :     }
    3600              : 
    3601       290955 :     void VariableFlowRadiantSystemData::calculateLowTemperatureRadiantSystemComponents(
    3602              :         EnergyPlusData &state,
    3603              :         Real64 &LoadMet,
    3604              :         SystemType const typeOfRadiantSystem) // Load met by the low temperature radiant system, in Watts
    3605              :     {
    3606              : 
    3607              :         // SUBROUTINE INFORMATION:
    3608              :         //       AUTHOR         Rick Strand
    3609              :         //       DATE WRITTEN   November 2000
    3610              :         //       MODIFIED       Sep 2011 LKL/BG - resimulate only zones needing it for Radiant systems
    3611              : 
    3612              :         // PURPOSE OF THIS SUBROUTINE:
    3613              :         // This subroutine solves the radiant system based on how much water is (and
    3614              :         // the conditions of the water) supplied to the radiant system.
    3615              : 
    3616              :         // METHODOLOGY EMPLOYED:
    3617              :         // Use heat exchanger formulas to obtain the heat source/sink for the radiant
    3618              :         // system based on the inlet conditions and flow rate of water.  Once that is
    3619              :         // determined, recalculate the surface heat balances to reflect this heat
    3620              :         // addition/subtraction.  The load met by the system is determined by the
    3621              :         // difference between the convection from all surfaces in the zone when
    3622              :         // there was no radiant system output and with a source/sink added.
    3623              : 
    3624              :         // REFERENCES:
    3625              :         // IBLAST-QTF research program, completed in January 1995 (unreleased)
    3626              :         // Strand, R.K. 1995. "Heat Source Transfer Functions and Their Application to
    3627              :         //   Low Temperature Radiant Heating Systems", Ph.D. dissertation, University
    3628              :         //   of Illinois at Urbana-Champaign, Department of Mechanical and Industrial
    3629              :         //   Engineering.
    3630              : 
    3631       290955 :         auto &Zone = state.dataHeatBal->Zone;
    3632              : 
    3633              :         // Using/Aliasing
    3634              :         using PlantUtilities::SetComponentFlowRate;
    3635              : 
    3636              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    3637              :         Real64 DewPointTemp;      // Dew-point temperature based on the zone air conditions
    3638              :         Real64 EpsMdotCp;         // Epsilon (heat exchanger terminology) times water mass flow rate times water specific heat
    3639              :         Real64 FullWaterMassFlow; // Original water mass flow rate before reducing the flow for condensation concerns
    3640              :         Real64 LowestRadSurfTemp; // Lowest surface temperature of a radiant system (when condensation is a concern)
    3641              :         Real64 PredictedCondTemp; // Temperature at which condensation is predicted (includes user parameter)
    3642              :         Real64 ReductionFrac;     // Fraction that the flow should be reduced to avoid condensation
    3643              :         Real64 SysWaterMassFlow;  // System level water mass flow rate (includes effect of zone multiplier)
    3644              :         Real64 WaterMassFlow;     // Water mass flow rate in the radiant system, kg/s
    3645              :         int WaterNodeIn;          // Node number of the water entering the radiant system
    3646              :         Real64 WaterTempIn;       // Temperature of the water entering the radiant system, in C
    3647              :         Real64 ZeroFlowSurfTemp;  // Temperature of radiant surface when flow is zero
    3648              :         int ZoneNum;              // Zone pointer for this radiant system
    3649              : 
    3650              :         VarFlowRadDesignData variableFlowDesignDataObject =                           // Is this intended to be a deep copy?
    3651       290955 :             state.dataLowTempRadSys->HydronicRadiantSysDesign(this->DesignObjectPtr); // Contains the data for variable flow hydronic systems
    3652              : 
    3653       290955 :         auto &Surface = state.dataSurface->Surface;
    3654              : 
    3655              :         Real64 Ca; // Coefficients to relate the inlet water temperature to the heat source
    3656              :         Real64 Cb;
    3657              :         Real64 Cc;
    3658              :         Real64 Cd;
    3659              :         Real64 Ce;
    3660              :         Real64 Cf;
    3661              :         Real64 Cg;
    3662              :         Real64 Ch;
    3663              :         Real64 Ci;
    3664              :         Real64 Cj;
    3665              :         Real64 Ck;
    3666              :         Real64 Cl;
    3667              :         // For more info on Ca through Cl, see comments below
    3668              : 
    3669              :         // First, apply heat exchanger logic to find the heat source/sink to the system.
    3670              :         // This involves finding out the heat transfer characteristics of the hydronic
    3671              :         // loop and then applying the equations derived on pp. 113-118 of the dissertation.
    3672              : 
    3673              :         // Set the conditions on the water side inlet
    3674       290955 :         switch (this->opMode) {
    3675       151202 :         case OpMode::Heat: {
    3676       151202 :             WaterNodeIn = this->HotWaterInNode;
    3677       151202 :         } break;
    3678       139753 :         case OpMode::Cool: {
    3679       139753 :             WaterNodeIn = this->ColdWaterInNode;
    3680       139753 :         } break;
    3681            0 :         default: {
    3682            0 :             WaterNodeIn = 0; // Suppress uninitialized warning
    3683            0 :             ShowSevereError(state, "Illegal low temperature radiant system operating mode");
    3684            0 :             ShowContinueError(state, format("Occurs in Radiant System={}", this->Name));
    3685            0 :             ShowFatalError(state, "Preceding condition causes termination.");
    3686            0 :         } break;
    3687              :         }
    3688       290955 :         ZoneNum = this->ZonePtr;
    3689       290955 :         SysWaterMassFlow = state.dataLoopNodes->Node(WaterNodeIn).MassFlowRate;
    3690       290955 :         WaterMassFlow = state.dataLoopNodes->Node(WaterNodeIn).MassFlowRate / double(Zone(ZoneNum).Multiplier * Zone(ZoneNum).ListMultiplier);
    3691       290955 :         WaterTempIn = state.dataLoopNodes->Node(WaterNodeIn).Temp;
    3692              : 
    3693       290955 :         if (WaterMassFlow <= 0.0) {
    3694              :             // No flow or below minimum allowed so there is no heat source/sink
    3695              :             // This is possible with a mismatch between system and plant operation
    3696              :             // or a slight mismatch between zone and system controls.  This is not
    3697              :             // necessarily a "problem" so this exception is necessary in the code.
    3698           72 :             for (int RadSurfNum = 1; RadSurfNum <= this->NumOfSurfaces; ++RadSurfNum) {
    3699           36 :                 int SurfNum = this->SurfacePtr(RadSurfNum);
    3700           36 :                 state.dataHeatBalFanSys->QRadSysSource(SurfNum) = 0.0;
    3701           36 :                 if (Surface(SurfNum).ExtBoundCond > 0 && Surface(SurfNum).ExtBoundCond != SurfNum) {
    3702            0 :                     state.dataHeatBalFanSys->QRadSysSource(Surface(SurfNum).ExtBoundCond) = 0.0; // Also zero the other side of an interzone
    3703              :                 }
    3704              :             }
    3705              : 
    3706              :         } else {
    3707              : 
    3708       607630 :             for (int RadSurfNum = 1; RadSurfNum <= this->NumOfSurfaces; ++RadSurfNum) {
    3709              : 
    3710       316711 :                 int SurfNum = this->SurfacePtr(RadSurfNum);
    3711              :                 // Determine the heat exchanger "effectiveness" term
    3712              : 
    3713      1266844 :                 EpsMdotCp = calculateHXEffectivenessTerm(state,
    3714              :                                                          SurfNum,
    3715              :                                                          WaterTempIn,
    3716              :                                                          WaterMassFlow,
    3717       316711 :                                                          this->SurfaceFrac(RadSurfNum),
    3718       316711 :                                                          this->NumCircuits(RadSurfNum),
    3719              :                                                          this->DesignObjectPtr,
    3720              :                                                          typeOfRadiantSystem);
    3721              : 
    3722              :                 // Obtain the heat balance coefficients and calculate the intermediate coefficients
    3723              :                 // linking the inlet water temperature to the heat source/sink to the radiant system.
    3724              :                 // The coefficients are based on the following development...
    3725              :                 // The heat balance equations at the outside and inside surfaces are of the form:
    3726              :                 //   Tinside  = Ca + Cb*Toutside + Cc*q"
    3727              :                 //   Toutside = Cd + Ce*Tinside  + Cf*q"
    3728              :                 //   Tsource  = Cg + Ch*q"       + Ci*Tinside + Cj*Toutside
    3729              :                 // where:
    3730              :                 //   Tinside is the temperature at the inside surface
    3731              :                 //   Toutside is the temperature at the outside surface
    3732              :                 //   Tsource is the temperature within the radiant system at the location of the source/sink
    3733              :                 //   Ca is all of the other terms in the inside heat balance (solar, LW exchange, conduction history terms, etc.)
    3734              :                 //   Cb is the current cross CTF term
    3735              :                 //   Cc is the QTF inside term for the current heat source/sink
    3736              :                 //   Cd is all of the other terms in the outside heat balance (solar, LW exchange, conduction history terms, etc.)
    3737              :                 //   Ce is the current cross CTF term (should be equal to Cb)
    3738              :                 //   Cf is the QTF outside term for the current heat source/sink
    3739              :                 //   Cg is the summation of all temperature and source history terms at the source/sink location
    3740              :                 //   Ch is the QTF term at the source/sink location for the current heat source/sink
    3741              :                 //   Ci is the CTF inside term for the current inside surface temperature
    3742              :                 //   Cj is the CTF outside term for the current outside surface temperature
    3743              :                 // Note that it is necessary to not use "slow conduction" assumptions because the
    3744              :                 // source/sink has an impact on BOTH the inside and outside surface heat balances.
    3745              :                 // Hence the more general formulation.
    3746              :                 // The first two T equations above can be solved to remove the other surface temperature.
    3747              :                 // This results in the following equations:
    3748              :                 //   Tinside  = Ca + Cb*(Cd + Ce*Tinside + Cf*q") + Cc*q"   or...
    3749              :                 //   Tinside  = (Ca + Cb*Cd + (Cc+Cb*Cf)*q") / (1 - Ce*Cb)
    3750              :                 //   Toutside = Cd + Ce*(Ca + Cb*Toutside + Cc*q") + Cf*q"  or...
    3751              :                 //   Toutside = (Cd + Ce*Ca + (Cf+Ce*Cc)*q") / (1 - Ce*Cb)
    3752              :                 // Substituting the new equations for Tinside and Toutside as a function of C and q"
    3753              :                 // into the equation for Tsource...
    3754              :                 //   Tsource  = Cg + Ch*q" + Ci*((Ca + Cb*Cd + (Cc+Cb*Cf)*q") / (1 - Ce*Cb)) &
    3755              :                 //                         + Cj*((Cd + Ce*Ca + (Cf+Ce*Cc)*q") / (1 - Ce*Cb))
    3756              :                 // Or rearranging this to get Tsource as a function of q", we get...
    3757              :                 //   Tsource  =  Cg + ((Ci*(Ca + Cb*Cd) + Cj*(Cd + Ce*Ca))/(1-Ce*Cb)) &
    3758              :                 //             +(Ch + ((Ci*(Cc + Cb*Cf) + Cj*(Cf + Ce*Cc))/(1-Ce*Cb)))*q"
    3759              :                 // Or in a slightly simpler form...
    3760              :                 //   Tsource  = Ck + Cl*q"
    3761              :                 // where:
    3762              :                 //   Ck = Cg + ((Ci*(Ca + Cb*Cd) + Cj*(Cd + Ce*Ca))/(1-Ce*Cb))
    3763              :                 //   Cl = Ch + ((Ci*(Cc + Cb*Cf) + Cj*(Cf + Ce*Cc))/(1-Ce*Cb))
    3764              :                 // Note also that from heat exchanger "algebra", we have:
    3765              :                 //   q = epsilon*qmax    and    qmax = Mdot*Cp*(Twaterin-Tsource)
    3766              :                 // So...
    3767              :                 //   q" = q/Area = (epsilon*Mdot*Cp/Area)*(Twaterin-Tsource)
    3768              :                 // Or rearranging this equation:
    3769              :                 //   Tsource = -(q"*A/(epsilon*Mdot*Cp)) + Twaterin
    3770              :                 // Setting this equation equal to the other equation for Tsource a couple lines up
    3771              :                 // and rearranging to solve for q"...
    3772              :                 //   q" = (Twaterin - Ck) / (Cl + (A/(epsilon*Mdot*Cp))
    3773              :                 // or
    3774              :                 //   q  = (Twaterin - Ck) / ((Cl/A) + (1/epsilon*Mdot*Cp))
    3775              :                 // or
    3776              :                 //   q  = epsilon*Mdot*Cp*(Twaterin - Ck) / (1+(epsilon*Mdot*Cp*Cl/A))
    3777              :                 // which is the desired result, that is the heat source or sink to the radiant
    3778              :                 // system as a function of the water inlet temperature (flow rate is also in there
    3779              :                 // as well as all of the heat balance terms "hidden" in Ck and Cl).
    3780       316711 :                 int ConstrNum = Surface(SurfNum).Construction;
    3781       316711 :                 auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    3782              : 
    3783       316711 :                 if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF) {
    3784              : 
    3785       202723 :                     Ca = state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum);
    3786       202723 :                     Cb = state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum);
    3787       202723 :                     Cc = state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum);
    3788              : 
    3789       202723 :                     Cd = state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum);
    3790       202723 :                     Ce = state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum);
    3791       202723 :                     Cf = state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum);
    3792              : 
    3793       202723 :                     Cg = state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum);
    3794       202723 :                     Ch = thisConstruct.CTFTSourceQ[0];
    3795       202723 :                     Ci = thisConstruct.CTFTSourceIn[0];
    3796       202723 :                     Cj = thisConstruct.CTFTSourceOut[0];
    3797              : 
    3798       202723 :                     Ck = Cg + ((Ci * (Ca + Cb * Cd) + Cj * (Cd + Ce * Ca)) / (1.0 - Ce * Cb));
    3799       202723 :                     Cl = Ch + ((Ci * (Cc + Cb * Cf) + Cj * (Cf + Ce * Cc)) / (1.0 - Ce * Cb));
    3800              : 
    3801       202723 :                     state.dataHeatBalFanSys->QRadSysSource(SurfNum) =
    3802       202723 :                         EpsMdotCp * (WaterTempIn - Ck) / (1.0 + (EpsMdotCp * Cl / Surface(SurfNum).Area));
    3803              : 
    3804       113988 :                 } else if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
    3805              : 
    3806       113988 :                     state.dataHeatBalFanSys->QRadSysSource(SurfNum) = EpsMdotCp * (WaterTempIn - state.dataHeatBalFanSys->TCondFDSourceNode(SurfNum));
    3807              :                 }
    3808              : 
    3809       316711 :                 if (Surface(SurfNum).ExtBoundCond > 0 && Surface(SurfNum).ExtBoundCond != SurfNum) {
    3810         4708 :                     state.dataHeatBalFanSys->QRadSysSource(Surface(SurfNum).ExtBoundCond) =
    3811         4708 :                         state.dataHeatBalFanSys->QRadSysSource(SurfNum); // Also set the other side of an interzone
    3812              :                 }
    3813              :             }
    3814              : 
    3815              :             // "Temperature Comparison" Cut-off:
    3816       595782 :             for (int RadSurfNum = 1; RadSurfNum <= this->NumOfSurfaces; ++RadSurfNum) {
    3817              :                 // Check to see whether or not the system should really be running.  If
    3818              :                 // QRadSysSource is negative when we are in heating mode or QRadSysSource
    3819              :                 // is positive when we are in cooling mode, then the radiant system will
    3820              :                 // be doing the opposite of its intention.  In this case, the flow rate
    3821              :                 // is set to zero to avoid heating in cooling mode or cooling in heating
    3822              :                 // mode.
    3823       316711 :                 int SurfNum = this->SurfacePtr(RadSurfNum);
    3824              : 
    3825       633422 :                 if (((this->opMode == OpMode::Heat) && (state.dataHeatBalFanSys->QRadSysSource(SurfNum) <= 0.0)) ||
    3826       316711 :                     ((this->opMode == OpMode::Cool) && (state.dataHeatBalFanSys->QRadSysSource(SurfNum) >= 0.0))) {
    3827        11848 :                     WaterMassFlow = 0.0;
    3828        11848 :                     if (this->opMode == OpMode::Heat) {
    3829            0 :                         SetComponentFlowRate(state, WaterMassFlow, this->HotWaterInNode, this->HotWaterOutNode, this->HWPlantLoc);
    3830              : 
    3831        11848 :                     } else if (this->opMode == OpMode::Cool) {
    3832        11848 :                         SetComponentFlowRate(state, WaterMassFlow, this->ColdWaterInNode, this->ColdWaterOutNode, this->CWPlantLoc);
    3833              :                     }
    3834        11848 :                     this->WaterMassFlowRate = WaterMassFlow;
    3835        11848 :                     this->opMode = OpMode::None;
    3836              : 
    3837        23696 :                     for (int RadSurfNum2 = 1; RadSurfNum2 <= this->NumOfSurfaces; ++RadSurfNum2) {
    3838        11848 :                         int SurfNum2 = this->SurfacePtr(RadSurfNum2);
    3839        11848 :                         state.dataHeatBalFanSys->QRadSysSource(SurfNum2) = 0.0;
    3840        11848 :                         if (Surface(SurfNum2).ExtBoundCond > 0 && Surface(SurfNum2).ExtBoundCond != SurfNum2) {
    3841            0 :                             state.dataHeatBalFanSys->QRadSysSource(Surface(SurfNum2).ExtBoundCond) = 0.0; // Also zero the other side of an interzone
    3842              :                         }
    3843              :                     }
    3844        11848 :                     break; // outer do loop
    3845              :                 }
    3846              :             }
    3847              : 
    3848              :             // Condensation Cut-off:
    3849              :             // Check to see whether there are any surface temperatures within the radiant system that have
    3850              :             // dropped below the dew-point temperature.  If so, we need to shut off this radiant system.
    3851              :             // A safety parameter is added (hardwired parameter) to avoid getting too close to condensation
    3852              :             // conditions.
    3853       290919 :             this->CondCausedShutDown = false;
    3854       290919 :             DewPointTemp =
    3855       290919 :                 PsyTdpFnWPb(state, state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).airHumRat, state.dataEnvrn->OutBaroPress);
    3856              : 
    3857       290919 :             if ((this->opMode == OpMode::Cool) && (variableFlowDesignDataObject.condCtrlType == CondCtrlType::SimpleOff)) {
    3858              : 
    3859       151519 :                 for (int RadSurfNum2 = 1; RadSurfNum2 <= this->NumOfSurfaces; ++RadSurfNum2) {
    3860        81528 :                     if (state.dataHeatBalSurf->SurfInsideTempHist(1)(this->SurfacePtr(RadSurfNum2)) <
    3861        81528 :                         (DewPointTemp + variableFlowDesignDataObject.CondDewPtDeltaT)) {
    3862              :                         // Condensation warning--must shut off radiant system
    3863         4925 :                         this->CondCausedShutDown = true;
    3864         4925 :                         WaterMassFlow = 0.0;
    3865         4925 :                         this->opMode = OpMode::None;
    3866         4925 :                         SetComponentFlowRate(state, WaterMassFlow, this->ColdWaterInNode, this->ColdWaterOutNode, this->CWPlantLoc);
    3867         4925 :                         this->WaterMassFlowRate = WaterMassFlow;
    3868         9850 :                         for (int RadSurfNum3 = 1; RadSurfNum3 <= this->NumOfSurfaces; ++RadSurfNum3) {
    3869         4925 :                             int SurfNum2 = this->SurfacePtr(RadSurfNum3);
    3870         4925 :                             state.dataHeatBalFanSys->QRadSysSource(SurfNum2) = 0.0;
    3871         4925 :                             if (Surface(SurfNum2).ExtBoundCond > 0 && Surface(SurfNum2).ExtBoundCond != SurfNum2) {
    3872            0 :                                 state.dataHeatBalFanSys->QRadSysSource(Surface(SurfNum2).ExtBoundCond) =
    3873              :                                     0.0; // Also zero the other side of an interzone
    3874              :                             }
    3875              :                         }
    3876              :                         // Produce a warning message so that user knows the system was shut-off due to potential for condensation
    3877         4925 :                         if (!state.dataGlobal->WarmupFlag) {
    3878          727 :                             if (this->CondErrIndex == 0) { // allow errors up to number of radiant systems
    3879           10 :                                 ShowWarningMessage(state, format("{} [{}]", cHydronicSystem, this->Name));
    3880           20 :                                 ShowContinueError(state,
    3881           20 :                                                   format("Surface [{}] temperature below dew-point temperature--potential for condensation exists",
    3882           10 :                                                          Surface(this->SurfacePtr(RadSurfNum2)).Name));
    3883           20 :                                 ShowContinueError(state, "Flow to the radiant system will be shut-off to avoid condensation");
    3884           20 :                                 ShowContinueError(state,
    3885           20 :                                                   format("Predicted radiant system surface temperature = {:.2R}",
    3886           10 :                                                          state.dataHeatBalSurf->SurfInsideTempHist(1)(this->SurfacePtr(RadSurfNum2))));
    3887           20 :                                 ShowContinueError(state,
    3888           20 :                                                   format("Zone dew-point temperature + safety delta T= {:.2R}",
    3889           10 :                                                          DewPointTemp + variableFlowDesignDataObject.CondDewPtDeltaT));
    3890           20 :                                 ShowContinueErrorTimeStamp(state, "");
    3891           20 :                                 ShowContinueError(state,
    3892           20 :                                                   format("Note that a {:.4R} C safety was chosen in the input for the shut-off criteria",
    3893              :                                                          variableFlowDesignDataObject.CondDewPtDeltaT));
    3894           30 :                                 ShowContinueError(state, "Note also that this affects all surfaces that are part of this radiant system");
    3895              :                             }
    3896         5816 :                             ShowRecurringWarningErrorAtEnd(state,
    3897         1454 :                                                            format("{} [{}] condensation shut-off occurrence continues.", cHydronicSystem, this->Name),
    3898          727 :                                                            this->CondErrIndex,
    3899              :                                                            DewPointTemp,
    3900              :                                                            DewPointTemp,
    3901              :                                                            _,
    3902              :                                                            "C",
    3903              :                                                            "C");
    3904              :                         }
    3905         4925 :                         break; // outer do loop
    3906              :                     }
    3907              :                 }
    3908              : 
    3909       290919 :             } else if ((this->opMode == OpMode::Cool) && (variableFlowDesignDataObject.condCtrlType == CondCtrlType::None)) {
    3910              : 
    3911        91090 :                 for (int RadSurfNum2 = 1; RadSurfNum2 <= this->NumOfSurfaces; ++RadSurfNum2) {
    3912        46477 :                     if (state.dataHeatBalSurf->SurfInsideTempHist(1)(this->SurfacePtr(RadSurfNum2)) < DewPointTemp) {
    3913              :                         // Condensation occurring but user does not want to shut radiant system off ever
    3914        19131 :                         this->CondCausedShutDown = true;
    3915              :                     }
    3916              :                 }
    3917              : 
    3918       216003 :             } else if ((this->opMode == OpMode::Cool) && (variableFlowDesignDataObject.condCtrlType == CondCtrlType::VariedOff)) {
    3919              : 
    3920         8346 :                 LowestRadSurfTemp = 999.9;
    3921         8346 :                 int CondSurfNum = 0;
    3922        16692 :                 for (int RadSurfNum2 = 1; RadSurfNum2 <= this->NumOfSurfaces; ++RadSurfNum2) {
    3923         8346 :                     if (state.dataHeatBalSurf->SurfInsideTempHist(1)(this->SurfacePtr(RadSurfNum2)) <
    3924         8346 :                         (DewPointTemp + variableFlowDesignDataObject.CondDewPtDeltaT)) {
    3925         4015 :                         if (state.dataHeatBalSurf->SurfInsideTempHist(1)(this->SurfacePtr(RadSurfNum2)) < LowestRadSurfTemp) {
    3926         4015 :                             LowestRadSurfTemp = state.dataHeatBalSurf->SurfInsideTempHist(1)(this->SurfacePtr(RadSurfNum2));
    3927         4015 :                             CondSurfNum = RadSurfNum2;
    3928              :                         }
    3929              :                     }
    3930              :                 }
    3931              : 
    3932         8346 :                 if (CondSurfNum > 0) { // Condensation predicted so let's deal with it
    3933              :                     // Process here is: turn everything off and see what the resulting surface temperature is for
    3934              :                     // the surface that was causing the lowest temperature.  Then, interpolate to find the flow that
    3935              :                     // would still allow the system to operate without producing condensation.  Rerun the heat balance
    3936              :                     // and recheck for condensation.  If condensation still exists, shut everything down.  This avoids
    3937              :                     // excessive iteration and still makes an attempt to vary the flow rate.
    3938              :                     // First, shut everything off...
    3939         4015 :                     FullWaterMassFlow = WaterMassFlow;
    3940         4015 :                     WaterMassFlow = 0.0;
    3941         4015 :                     SetComponentFlowRate(state, WaterMassFlow, this->ColdWaterInNode, this->ColdWaterOutNode, this->CWPlantLoc);
    3942         4015 :                     this->WaterMassFlowRate = WaterMassFlow;
    3943         8030 :                     for (int RadSurfNum3 = 1; RadSurfNum3 <= this->NumOfSurfaces; ++RadSurfNum3) {
    3944         4015 :                         int SurfNum2 = this->SurfacePtr(RadSurfNum3);
    3945         4015 :                         state.dataHeatBalFanSys->QRadSysSource(SurfNum2) = 0.0;
    3946         4015 :                         if (Surface(SurfNum2).ExtBoundCond > 0 && Surface(SurfNum2).ExtBoundCond != SurfNum2) {
    3947            0 :                             state.dataHeatBalFanSys->QRadSysSource(Surface(SurfNum2).ExtBoundCond) = 0.0; // Also zero the other side of an interzone
    3948              :                         }
    3949              :                     }
    3950              :                     // Redo the heat balances since we have changed the heat source (set it to zero)
    3951         4015 :                     HeatBalanceSurfaceManager::CalcHeatBalanceOutsideSurf(state, ZoneNum);
    3952         4015 :                     HeatBalanceSurfaceManager::CalcHeatBalanceInsideSurf(state, ZoneNum);
    3953              :                     // Now check all of the surface temperatures.  If any potentially have condensation, leave the system off.
    3954         8030 :                     for (int RadSurfNum2 = 1; RadSurfNum2 <= this->NumOfSurfaces; ++RadSurfNum2) {
    3955         4015 :                         if (state.dataHeatBalSurf->SurfInsideTempHist(1)(this->SurfacePtr(RadSurfNum2)) <
    3956         4015 :                             (DewPointTemp + variableFlowDesignDataObject.CondDewPtDeltaT)) {
    3957            0 :                             this->CondCausedShutDown = true;
    3958              :                         }
    3959              :                     }
    3960              :                     // If the system does not need to be shut down, then let's see if we can vary the flow based
    3961              :                     // on the lowest temperature surface from before.  This will use interpolation to try a new
    3962              :                     // flow rate.
    3963         4015 :                     if (!this->CondCausedShutDown) {
    3964         4015 :                         PredictedCondTemp = DewPointTemp + variableFlowDesignDataObject.CondDewPtDeltaT;
    3965         4015 :                         ZeroFlowSurfTemp = state.dataHeatBalSurf->SurfInsideTempHist(1)(this->SurfacePtr(CondSurfNum));
    3966         4015 :                         ReductionFrac = (ZeroFlowSurfTemp - PredictedCondTemp) / std::abs(ZeroFlowSurfTemp - LowestRadSurfTemp);
    3967         4015 :                         if (ReductionFrac < 0.0) {
    3968            0 :                             ReductionFrac = 0.0; // Shouldn't happen as the above check should have screened this out
    3969              :                         }
    3970         4015 :                         if (ReductionFrac > 1.0) {
    3971            0 :                             ReductionFrac = 1.0; // Shouldn't happen either because condensation doesn't exist then
    3972              :                         }
    3973         4015 :                         WaterMassFlow = ReductionFrac * FullWaterMassFlow;
    3974         4015 :                         SysWaterMassFlow = double(Zone(ZoneNum).Multiplier * Zone(ZoneNum).ListMultiplier) * WaterMassFlow;
    3975              :                         // Got a new reduced flow rate that should work...reset loop variable and resimulate the system
    3976         4015 :                         SetComponentFlowRate(state, SysWaterMassFlow, this->ColdWaterInNode, this->ColdWaterOutNode, this->CWPlantLoc);
    3977         4015 :                         this->WaterMassFlowRate = SysWaterMassFlow;
    3978              : 
    3979              :                         // Go through all of the surfaces again with the new flow rate...
    3980         8030 :                         for (int RadSurfNum3 = 1; RadSurfNum3 <= this->NumOfSurfaces; ++RadSurfNum3) {
    3981         4015 :                             int SurfNum = this->SurfacePtr(RadSurfNum3);
    3982              :                             // Determine the heat exchanger "effectiveness" term
    3983              : 
    3984        16060 :                             EpsMdotCp = calculateHXEffectivenessTerm(state,
    3985              :                                                                      SurfNum,
    3986              :                                                                      WaterTempIn,
    3987              :                                                                      WaterMassFlow,
    3988         4015 :                                                                      this->SurfaceFrac(RadSurfNum3),
    3989         4015 :                                                                      this->NumCircuits(RadSurfNum3),
    3990              :                                                                      this->DesignObjectPtr,
    3991              :                                                                      typeOfRadiantSystem);
    3992              : 
    3993         4015 :                             int ConstrNum = Surface(SurfNum).Construction;
    3994         4015 :                             auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    3995         4015 :                             if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF) {
    3996              :                                 // For documentation on coefficients, see code earlier in this subroutine
    3997         4015 :                                 Ca = state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum);
    3998         4015 :                                 Cb = state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum);
    3999         4015 :                                 Cc = state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum);
    4000         4015 :                                 Cd = state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum);
    4001         4015 :                                 Ce = state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum);
    4002         4015 :                                 Cf = state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum);
    4003         4015 :                                 Cg = state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum);
    4004         4015 :                                 Ch = thisConstruct.CTFTSourceQ[0];
    4005         4015 :                                 Ci = thisConstruct.CTFTSourceIn[0];
    4006         4015 :                                 Cj = thisConstruct.CTFTSourceOut[0];
    4007         4015 :                                 Ck = Cg + ((Ci * (Ca + Cb * Cd) + Cj * (Cd + Ce * Ca)) / (1.0 - Ce * Cb));
    4008         4015 :                                 Cl = Ch + ((Ci * (Cc + Cb * Cf) + Cj * (Cf + Ce * Cc)) / (1.0 - Ce * Cb));
    4009         4015 :                                 state.dataHeatBalFanSys->QRadSysSource(SurfNum) =
    4010         4015 :                                     EpsMdotCp * (WaterTempIn - Ck) / (1.0 + (EpsMdotCp * Cl / Surface(SurfNum).Area));
    4011            0 :                             } else if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
    4012            0 :                                 state.dataHeatBalFanSys->QRadSysSource(SurfNum) =
    4013            0 :                                     EpsMdotCp * (WaterTempIn - state.dataHeatBalFanSys->TCondFDSourceNode(SurfNum));
    4014              :                             }
    4015         4015 :                             if (Surface(SurfNum).ExtBoundCond > 0 && Surface(SurfNum).ExtBoundCond != SurfNum) {
    4016            0 :                                 state.dataHeatBalFanSys->QRadSysSource(Surface(SurfNum).ExtBoundCond) =
    4017            0 :                                     state.dataHeatBalFanSys->QRadSysSource(SurfNum); // Also set the other side of an interzone
    4018              :                             }
    4019              :                         }
    4020              : 
    4021              :                         // Redo the heat balances since we have changed the heat source
    4022         4015 :                         HeatBalanceSurfaceManager::CalcHeatBalanceOutsideSurf(state, ZoneNum);
    4023         4015 :                         HeatBalanceSurfaceManager::CalcHeatBalanceInsideSurf(state, ZoneNum);
    4024              : 
    4025              :                         // Check for condensation one more time.  If no condensation, we are done.  If there is
    4026              :                         // condensation, shut things down and be done.
    4027         8030 :                         for (int RadSurfNum2 = 1; RadSurfNum2 <= this->NumOfSurfaces; ++RadSurfNum2) {
    4028         4015 :                             if (this->CondCausedShutDown) {
    4029            0 :                                 break;
    4030              :                             }
    4031         4015 :                             if (state.dataHeatBalSurf->SurfInsideTempHist(1)(this->SurfacePtr(RadSurfNum2)) < (PredictedCondTemp)) {
    4032              :                                 // Condensation still present--must shut off radiant system
    4033         3868 :                                 this->CondCausedShutDown = true;
    4034         3868 :                                 WaterMassFlow = 0.0;
    4035         3868 :                                 this->opMode = OpMode::None;
    4036         3868 :                                 SetComponentFlowRate(state, WaterMassFlow, this->ColdWaterInNode, this->ColdWaterOutNode, this->CWPlantLoc);
    4037         3868 :                                 this->WaterMassFlowRate = WaterMassFlow;
    4038         7736 :                                 for (int RadSurfNum3 = 1; RadSurfNum3 <= this->NumOfSurfaces; ++RadSurfNum3) {
    4039         3868 :                                     int SurfNum2 = this->SurfacePtr(RadSurfNum3);
    4040         3868 :                                     state.dataHeatBalFanSys->QRadSysSource(SurfNum2) = 0.0;
    4041         3868 :                                     if (Surface(SurfNum2).ExtBoundCond > 0 && Surface(SurfNum2).ExtBoundCond != SurfNum2) {
    4042            0 :                                         state.dataHeatBalFanSys->QRadSysSource(Surface(SurfNum2).ExtBoundCond) =
    4043              :                                             0.0; // Also zero the other side of an interzone
    4044              :                                     }
    4045              :                                 }
    4046              :                             }
    4047              :                         }
    4048              :                     }
    4049              : 
    4050         4015 :                     if (this->CondCausedShutDown) {
    4051              :                         // Produce a warning message so that user knows the system was shut-off due to potential for condensation
    4052         3868 :                         if (!state.dataGlobal->WarmupFlag) {
    4053          571 :                             if (this->CondErrIndex == 0) { // allow errors up to number of radiant systems
    4054            2 :                                 ShowWarningMessage(state, format("{} [{}]", cHydronicSystem, this->Name));
    4055            4 :                                 ShowContinueError(state,
    4056            4 :                                                   format("Surface [{}] temperature below dew-point temperature--potential for condensation exists",
    4057            2 :                                                          Surface(this->SurfacePtr(CondSurfNum)).Name));
    4058            4 :                                 ShowContinueError(state, "Flow to the radiant system will be shut-off to avoid condensation");
    4059            4 :                                 ShowContinueError(state,
    4060            4 :                                                   format("Predicted radiant system surface temperature = {:.2R}",
    4061            2 :                                                          state.dataHeatBalSurf->SurfInsideTempHist(1)(this->SurfacePtr(CondSurfNum))));
    4062            4 :                                 ShowContinueError(state,
    4063            4 :                                                   format("Zone dew-point temperature + safety delta T= {:.2R}",
    4064            2 :                                                          DewPointTemp + variableFlowDesignDataObject.CondDewPtDeltaT));
    4065            4 :                                 ShowContinueErrorTimeStamp(state, "");
    4066            4 :                                 ShowContinueError(state,
    4067            4 :                                                   format("Note that a {:.4R} C safety was chosen in the input for the shut-off criteria",
    4068              :                                                          variableFlowDesignDataObject.CondDewPtDeltaT));
    4069            6 :                                 ShowContinueError(state, "Note also that this affects all surfaces that are part of this radiant system");
    4070              :                             }
    4071         4568 :                             ShowRecurringWarningErrorAtEnd(state,
    4072         1142 :                                                            format("{} [{}] condensation shut-off occurrence continues.", cHydronicSystem, this->Name),
    4073          571 :                                                            this->CondErrIndex,
    4074              :                                                            DewPointTemp,
    4075              :                                                            DewPointTemp,
    4076              :                                                            _,
    4077              :                                                            "C",
    4078              :                                                            "C");
    4079              :                         }
    4080              :                     }
    4081              :                 } // Condensation Predicted in Variable Shut-Off Control Type
    4082              :             } // In cooling mode and one of the condensation control types
    4083              :         } // There was a non-zero flow
    4084              : 
    4085              :         // Now that we have the source/sink term, we must redo the heat balances to obtain
    4086              :         // the new SumHATsurf value for the zone.  Note that the difference between the new
    4087              :         // SumHATsurf and the value originally calculated by the heat balance with a zero
    4088              :         // source for all radiant systems in the zone is the load met by the system (approximately).
    4089       290955 :         HeatBalanceSurfaceManager::CalcHeatBalanceOutsideSurf(state, ZoneNum);
    4090       290955 :         HeatBalanceSurfaceManager::CalcHeatBalanceInsideSurf(state, ZoneNum);
    4091              : 
    4092       290955 :         LoadMet = state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state) - this->ZeroLTRSourceSumHATsurf;
    4093       290955 :     }
    4094              : 
    4095       221733 :     void ConstantFlowRadiantSystemData::calculateLowTemperatureRadiantSystem(EnergyPlusData &state,
    4096              :                                                                              Real64 &LoadMet) // load met by the radiant system, in Watts
    4097              :     {
    4098              : 
    4099              :         // SUBROUTINE INFORMATION:
    4100              :         //       AUTHOR         Rick Strand
    4101              :         //       DATE WRITTEN   August 2003
    4102              : 
    4103              :         // PURPOSE OF THIS SUBROUTINE:
    4104              :         // This subroutine does all of the stuff that is necessary to simulate
    4105              :         // a constant flow low temperature hydronic radiant heating/cooling system.
    4106              :         // Calls are made to appropriate subroutines either in this module or
    4107              :         // outside of it.
    4108              : 
    4109              :         // METHODOLOGY EMPLOYED:
    4110              :         // Similar in many aspects to the hydronic (variable flow) radiant system
    4111              :         // except that flow rate through the radiant system is constant (based on
    4112              :         // the user schedule) and the inlet temperature is varied by injecting
    4113              :         // more or less fluid from the main loop to achieve the desired inlet
    4114              :         // temperature.
    4115              : 
    4116              :         // REFERENCES:
    4117              :         // Other EnergyPlus modules
    4118              :         // IBLAST-QTF research program, completed in January 1995 (unreleased)
    4119              :         // Strand, R.K. 1995. "Heat Source Transfer Functions and Their Application to
    4120              :         //   Low Temperature Radiant Heating Systems", Ph.D. dissertation, University
    4121              :         //   of Illinois at Urbana-Champaign, Department of Mechanical and Industrial
    4122              :         //   Engineering.
    4123              :         // Seem, J.E. 1986. "Heat Transfer in Buildings", Ph.D. dissertation, University
    4124              :         //   of Wisconsin-Madison.
    4125              : 
    4126              :         // Using/Aliasing
    4127              :         using DataHeatBalance::ZoneData;
    4128              :         using HVAC::SmallLoad;
    4129              :         using PlantUtilities::SetComponentFlowRate;
    4130              : 
    4131              :         // SUBROUTINE PARAMETER DEFINITIONS:
    4132       221733 :         Real64 constexpr LowCpFluidValue(100.0); // lowest allowed Cp fluid value (to avoid dividing by zero) [J/kg-K]
    4133       221733 :         constexpr std::string_view RoutineName("CalcLowTempCFloRadiantSystem");
    4134              : 
    4135              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    4136              :         Real64 CpFluid;         // Specific heat of the fluid in the radiant system
    4137              :         Real64 InjectFlowRate;  // Calculated injection flow rate that will meet the inlet temperature requirement
    4138              :         Real64 OffTempCool;     // temperature at which the cooling shuts down
    4139              :         Real64 OffTempHeat;     // temperature at which the heating shuts down
    4140              :         Real64 PumpPartLoadRat; // Pump part load ratio (based on user schedule, or 1.0 for no schedule)
    4141              :         Real64 PumpTempRise;    // Temperature rise of the fluid as it passes through the pump
    4142              :         Real64 RadInTemp;       // "Desired" radiant system water inlet temperature [Celsius]
    4143              :         Real64 SetPointTemp;    // temperature that will be used to control the radiant system [Celsius]
    4144              :         Real64 SetPointTempHi;  // Current high point in setpoint temperature range
    4145              :         Real64 SetPointTempLo;  // Current low point in setpoint temperature range
    4146              :         Real64 ShaftPower;      // Amount of power expended at the pump shaft
    4147              :         bool SysRunning;        // TRUE when the system is running
    4148              :         Real64 SysWaterInTemp;  // Fluid temperature supplied from the loop
    4149              :         Real64 WaterTempHi;     // Current high point in water temperature range
    4150              :         Real64 WaterTempLo;     // Current low point in water temperature range
    4151              :         Real64 mdot;            // local temporary for water mass flow rate kg/s
    4152              : 
    4153              :         ConstantFlowRadDesignData ConstantFlowDesignDataObject =                   // Once again, is this supposed to be a deep copy?
    4154       221733 :             state.dataLowTempRadSys->CflowRadiantSysDesign(this->DesignObjectPtr); // Contains the data for variable flow hydronic systems
    4155              : 
    4156              :         // initialize local variables
    4157       221733 :         SysRunning = true; // default to running and turn off only if not running
    4158       221733 :         state.dataLowTempRadSys->VarOffCond = false;
    4159              : 
    4160       221733 :         if (this->availSched->getCurrentVal() <= 0) {
    4161         7608 :             SysRunning = false;
    4162              :         }
    4163              : 
    4164       221733 :         if (SysRunning) { // Unit is probably on-->this section is intended to control the water
    4165              :             // mass flow rate being sent to the radiant system
    4166              : 
    4167              :             // Set the current setpoint temperature (same procedure for either heating or cooling)
    4168              : 
    4169       214125 :             SetPointTemp = this->setRadiantSystemControlTemperature(state, ConstantFlowDesignDataObject.ConstFlowControlType);
    4170              : 
    4171              :             // Avoid problems when there is no heating or cooling control because the system only cools or heats
    4172       214125 :             if (this->hotCtrlHiTempSched != nullptr) {
    4173       214125 :                 OffTempHeat = this->hotCtrlHiTempSched->getCurrentVal();
    4174              :             } else {
    4175            0 :                 OffTempHeat = state.dataLowTempRadSys->LowTempHeating;
    4176              :             }
    4177       214125 :             if (this->coldCtrlLoTempSched != nullptr) {
    4178       208098 :                 OffTempCool = this->coldCtrlLoTempSched->getCurrentVal();
    4179              :             } else {
    4180         6027 :                 OffTempCool = state.dataLowTempRadSys->HighTempCooling;
    4181              :             }
    4182              : 
    4183       214125 :             if (SetPointTemp < OffTempHeat && this->HeatingSystem) { // Heating mode
    4184        72716 :                 this->opMode = OpMode::Heat;
    4185       141409 :             } else if (SetPointTemp > OffTempCool && this->CoolingSystem) { // Cooling mode
    4186       113868 :                 this->opMode = OpMode::Cool;
    4187              :             }
    4188              : 
    4189       214125 :             this->setOperatingModeBasedOnChangeoverDelay(state);
    4190              : 
    4191              :             // Now actually decide what to do based on the setpoint temperature in relation to the control temperatures
    4192       214125 :             if (this->opMode == OpMode::Heat) { // HEATING MODE
    4193              : 
    4194        69897 :                 this->WaterMassFlowRate = this->HotWaterMassFlowRate;
    4195              : 
    4196        69897 :                 if (!this->HeatingSystem) {
    4197              : 
    4198            0 :                     SysRunning = false; // Can't heat unless it's a heating system
    4199              : 
    4200              :                 } else { // It is a heating system so set all of the values for controls
    4201              : 
    4202        69897 :                     SetPointTempHi = this->hotCtrlHiTempSched->getCurrentVal();
    4203        69897 :                     SetPointTempLo = this->hotCtrlLoTempSched->getCurrentVal();
    4204        69897 :                     if (SetPointTempHi < SetPointTempLo) {
    4205            0 :                         ShowSevereError(state, format("Heating setpoint temperature mismatch in{}", this->Name));
    4206            0 :                         ShowContinueError(state, "High setpoint temperature is less than low setpoint temperature--check your schedule input");
    4207            0 :                         ShowFatalError(state, "Preceding condition causes termination.");
    4208              :                     }
    4209              : 
    4210        69897 :                     WaterTempHi = this->hotWaterHiTempSched->getCurrentVal();
    4211        69897 :                     WaterTempLo = this->hotWaterLoTempSched->getCurrentVal();
    4212        69897 :                     if (WaterTempHi < WaterTempLo) {
    4213            0 :                         ShowSevereError(state, format("Heating water temperature mismatch in{}", this->Name));
    4214            0 :                         ShowContinueError(state, "High water temperature is less than low water temperature--check your schedule input");
    4215            0 :                         ShowFatalError(state, "Preceding condition causes termination.");
    4216              :                     }
    4217              : 
    4218        69897 :                     if (SetPointTemp >= SetPointTempHi) {
    4219              :                         // System is above high heating setpoint so we should be able to turn the system off
    4220          137 :                         RadInTemp = WaterTempLo;
    4221          137 :                         SysRunning = false;
    4222        69760 :                     } else if (SetPointTemp <= SetPointTempLo) {
    4223              :                         // System is running with its highest inlet temperature
    4224        12651 :                         RadInTemp = WaterTempHi;
    4225              :                     } else {
    4226              :                         // Interpolate to obtain the current radiant system inlet temperature
    4227        57109 :                         RadInTemp = WaterTempHi - (WaterTempHi - WaterTempLo) * (SetPointTemp - SetPointTempLo) / (SetPointTempHi - SetPointTempLo);
    4228              :                     }
    4229              :                 }
    4230              : 
    4231       144228 :             } else if (this->opMode == OpMode::Cool) { // COOLING MODE
    4232              : 
    4233       113849 :                 this->WaterMassFlowRate = this->ChWaterMassFlowRate;
    4234              : 
    4235       113849 :                 if (!this->CoolingSystem) {
    4236              : 
    4237            0 :                     SysRunning = false; // Can't cool unless it's a cooling system
    4238              : 
    4239              :                 } else { // It is a cooling system so set all of the values for controls
    4240              : 
    4241       113849 :                     SetPointTempHi = this->coldCtrlHiTempSched->getCurrentVal();
    4242       113849 :                     SetPointTempLo = this->coldCtrlLoTempSched->getCurrentVal();
    4243       113849 :                     if (SetPointTempHi < SetPointTempLo) {
    4244            0 :                         ShowSevereError(state, format("Cooling setpoint temperature mismatch in{}", this->Name));
    4245            0 :                         ShowContinueError(state, "High setpoint temperature is less than low setpoint temperature--check your schedule input");
    4246            0 :                         ShowFatalError(state, "Preceding condition causes termination.");
    4247              :                     }
    4248              : 
    4249       113849 :                     WaterTempHi = this->coldWaterHiTempSched->getCurrentVal();
    4250       113849 :                     WaterTempLo = this->coldWaterLoTempSched->getCurrentVal();
    4251       113849 :                     if (WaterTempHi < WaterTempLo) {
    4252            0 :                         ShowSevereError(state, format("Cooling water temperature mismatch in{}", this->Name));
    4253            0 :                         ShowContinueError(state, "High water temperature is less than low water temperature--check your schedule input");
    4254            0 :                         ShowFatalError(state, "Preceding condition causes termination.");
    4255              :                     }
    4256              : 
    4257       113849 :                     if (SetPointTemp <= SetPointTempLo) {
    4258              :                         // System is below low cooling setpoint so we should be able to turn the system off
    4259          633 :                         RadInTemp = WaterTempHi;
    4260          633 :                         SysRunning = false;
    4261       113216 :                     } else if (SetPointTemp >= SetPointTempHi) {
    4262              :                         // System is running with its lowest inlet temperature
    4263        53811 :                         RadInTemp = WaterTempLo;
    4264              :                     } else {
    4265              :                         // Interpolate to obtain the current radiant system inlet temperature
    4266        59405 :                         RadInTemp = WaterTempHi - (WaterTempHi - WaterTempLo) * (SetPointTemp - SetPointTempLo) / (SetPointTempHi - SetPointTempLo);
    4267              :                     }
    4268              :                 }
    4269              : 
    4270              :             } else { // System is not running because the setpoint temperature is in the "deadband"
    4271              : 
    4272        30379 :                 RadInTemp = SetPointTemp;
    4273        30379 :                 SysRunning = false;
    4274              :             }
    4275              :         }
    4276              : 
    4277       221733 :         if (SysRunning) {
    4278       182976 :             CpFluid = this->water->getSpecificHeat(state, RadInTemp, RoutineName);
    4279              :         }
    4280              : 
    4281       221733 :         if ((!SysRunning) || (CpFluid < LowCpFluidValue)) {
    4282              :             // Unit is off or has no load upon it OR CpFluid value is "zero" so
    4283              :             // set the flow rates to zero and then simulate the components with
    4284              :             // the no flow conditions
    4285        38757 :             this->opMode = OpMode::None;
    4286        38757 :             this->WaterMassFlowRate = 0.0;
    4287        38757 :             this->WaterInjectionRate = 0.0;
    4288        38757 :             this->WaterRecircRate = 0.0;
    4289        38757 :             this->HeatPower = 0.0;
    4290        38757 :             this->CoolPower = 0.0;
    4291        38757 :             this->PumpPower = 0.0;
    4292        38757 :             this->PumpMassFlowRate = 0.0;
    4293        38757 :             this->PumpHeattoFluid = 0.0;
    4294              : 
    4295        77514 :             for (int SurfNum = 1; SurfNum <= this->NumOfSurfaces; ++SurfNum) {
    4296        38757 :                 int SurfNum2 = this->SurfacePtr(SurfNum);
    4297        38757 :                 auto &surface = state.dataSurface->Surface(SurfNum2);
    4298        38757 :                 state.dataHeatBalFanSys->QRadSysSource(SurfNum2) = 0.0;
    4299        38757 :                 if (surface.ExtBoundCond > 0 && surface.ExtBoundCond != SurfNum2) {
    4300            0 :                     state.dataHeatBalFanSys->QRadSysSource(surface.ExtBoundCond) = 0.0; // Also zero the other side of an interzone
    4301              :                 }
    4302              :             }
    4303              : 
    4304              :             // turn off flow requests made during init because it is not actually running
    4305        38757 :             if (this->CWPlantLoc.loopNum > 0) {
    4306        31149 :                 mdot = 0.0;
    4307        31149 :                 SetComponentFlowRate(state, mdot, this->ColdWaterInNode, this->ColdWaterOutNode, this->CWPlantLoc);
    4308              :             }
    4309        38757 :             if (this->HWPlantLoc.loopNum > 0) {
    4310        38757 :                 mdot = 0.0;
    4311        38757 :                 SetComponentFlowRate(state, mdot, this->HotWaterInNode, this->HotWaterOutNode, this->HWPlantLoc);
    4312              :             }
    4313        38757 :         } else {            // (SysRunning) so simulate the system...
    4314              :             bool Iteration; // FALSE when a normal solution, TRUE when it is a solution where we must also find the inlet temp
    4315              :             int LoopInNode; // Node on the loop that is the inlet to the constant flow radiant system
    4316              : 
    4317              :             // Determine pump flow rate and pump heat addition
    4318       182976 :             this->PumpMassFlowRate = this->WaterMassFlowRate; // Set in InitLowTempRadiantSystem
    4319       182976 :             PumpPartLoadRat = (this->volFlowSched != nullptr) ? this->volFlowSched->getCurrentVal() : 1.0;
    4320              : 
    4321       182976 :             this->PumpPower = PumpPartLoadRat * this->NomPowerUse;
    4322       182976 :             ShaftPower = this->PumpPower * ConstantFlowDesignDataObject.MotorEffic;
    4323              :             // This adds the pump heat based on User input for the pump (same as in Pump module)
    4324              :             // We assume that all of the heat ends up in the fluid eventually since this is a closed loop.
    4325       182976 :             this->PumpHeattoFluid = ShaftPower + ((this->PumpPower - ShaftPower) * ConstantFlowDesignDataObject.FracMotorLossToFluid);
    4326       182976 :             if (this->PumpMassFlowRate > 0.0) {
    4327       182910 :                 PumpTempRise = this->PumpHeattoFluid / (this->PumpMassFlowRate * CpFluid);
    4328              :             } else {
    4329           66 :                 PumpTempRise = 0.0;
    4330              :             }
    4331              : 
    4332       365952 :             state.dataLowTempRadSys->LoopReqTemp =
    4333       182976 :                 RadInTemp - PumpTempRise; // Temperature required at the inlet of the pump to meet the temperature request
    4334              : 
    4335       182976 :             if (this->opMode == OpMode::Heat) {
    4336              : 
    4337              :                 // in heating mode so shut down cold water flow request
    4338        69760 :                 if (this->CWPlantLoc.loopNum > 0) {
    4339        63733 :                     mdot = 0.0;
    4340        63733 :                     SetComponentFlowRate(state, mdot, this->ColdWaterInNode, this->ColdWaterOutNode, this->CWPlantLoc);
    4341              :                 }
    4342        69760 :                 LoopInNode = this->HotWaterInNode;
    4343        69760 :                 auto const &hotNode = state.dataLoopNodes->Node(LoopInNode);
    4344        69760 :                 SysWaterInTemp = hotNode.Temp;
    4345        69760 :                 Iteration = false;
    4346              : 
    4347        69760 :                 if ((SysWaterInTemp >= state.dataLowTempRadSys->LoopReqTemp) && (hotNode.MassFlowRateMaxAvail >= this->WaterMassFlowRate)) {
    4348              :                     // Case 1: Adequate temperature and flow
    4349              :                     // Best condition--loop inlet temperature greater than requested and we have enough flow.
    4350              :                     // So, proceed assuming the RadInTemp requested by the controls and then figure out the
    4351              :                     // mixing after the outlet radiant temperature is calculated.
    4352        69760 :                     this->WaterInletTemp = RadInTemp;
    4353        69760 :                     this->calculateLowTemperatureRadiantSystemComponents(state, LoopInNode, Iteration, LoadMet, SystemType::ConstantFlow);
    4354              : 
    4355              :                     // We now have inlet and outlet temperatures--we still need to set the flow rates
    4356        69760 :                     if ((SysWaterInTemp - this->WaterOutletTemp) != 0.0) { // protect divide by zero
    4357        69760 :                         this->WaterInjectionRate =
    4358        69760 :                             (this->WaterMassFlowRate * (this->WaterInletTemp - this->WaterOutletTemp) / (SysWaterInTemp - this->WaterOutletTemp)) -
    4359        69760 :                             (this->PumpHeattoFluid / (CpFluid * (SysWaterInTemp - this->WaterOutletTemp)));
    4360              :                     } else {
    4361            0 :                         this->WaterInjectionRate = this->WaterMassFlowRate;
    4362              :                     }
    4363        69760 :                     this->WaterRecircRate = this->WaterMassFlowRate - this->WaterInjectionRate;
    4364              : 
    4365            0 :                 } else if ((SysWaterInTemp < state.dataLowTempRadSys->LoopReqTemp) && (hotNode.MassFlowRateMaxAvail >= this->WaterMassFlowRate)) {
    4366              :                     // Case 2: Adequate flow but temperature too low
    4367              :                     // Only thing to do is to reset the inlet temperature and assume that the loop will supply
    4368              :                     // the entire flow to the component (no recirculation but potentially some bypass for the
    4369              :                     // overall loop).  There is no way we can meet the control temperature so don't even try.
    4370            0 :                     this->WaterInletTemp = SysWaterInTemp + PumpTempRise;
    4371            0 :                     this->calculateLowTemperatureRadiantSystemComponents(state, LoopInNode, Iteration, LoadMet, SystemType::ConstantFlow);
    4372              : 
    4373              :                     // We now have inlet and outlet temperatures--we still need to set the flow rates
    4374            0 :                     if ((SysWaterInTemp - this->WaterOutletTemp) != 0.0) { // protect divide by zero
    4375            0 :                         this->WaterInjectionRate =
    4376            0 :                             (this->WaterMassFlowRate * (this->WaterInletTemp - this->WaterOutletTemp) / (SysWaterInTemp - this->WaterOutletTemp)) -
    4377            0 :                             (this->PumpHeattoFluid / (CpFluid * (SysWaterInTemp - this->WaterOutletTemp)));
    4378              :                     } else {
    4379            0 :                         this->WaterInjectionRate = this->WaterMassFlowRate;
    4380              :                     }
    4381            0 :                     if (this->WaterInjectionRate > this->WaterMassFlowRate) {
    4382            0 :                         this->WaterInjectionRate = this->WaterMassFlowRate;
    4383              :                     }
    4384            0 :                     this->WaterRecircRate = 0.0; // by definition
    4385              : 
    4386            0 :                 } else if ((SysWaterInTemp >= state.dataLowTempRadSys->LoopReqTemp) && (hotNode.MassFlowRateMaxAvail < this->WaterMassFlowRate)) {
    4387              :                     // Case 3: Adequate temperature but loop flow is less than component flow
    4388              :                     // This case might work out, but there is no guarantee that there is enough loop flow to
    4389              :                     // mix with the recirculation flow and still provide a high enough temperature.  First
    4390              :                     // step is to try the inlet temperature and flow rate as in Case 1.  If we can obtain
    4391              :                     // the proper temperature inlet to the radiant system, then we are done.  If not, we
    4392              :                     // have to repeat the solution for an unknown inlet temperature and a known recirculation
    4393              :                     // rate.
    4394            0 :                     this->WaterInletTemp = RadInTemp;
    4395            0 :                     this->calculateLowTemperatureRadiantSystemComponents(state, LoopInNode, Iteration, LoadMet, SystemType::ConstantFlow);
    4396              : 
    4397              :                     // Now see if we can really get that desired into temperature (RadInTemp) by solving
    4398              :                     // for the flow that is injected from the loop.  A heat balance for the mixer that relates
    4399              :                     // the important quantities is:
    4400              :                     //   Mdotradsys*Cp*Tradsysin = Mdotloop*Cp*Tloop + (Mdotradsys-Mdotloop)*Cp*Tradsysout + PumpHeat
    4401              :                     // or rearranging to get the injection flow (Mdotloop):
    4402              :                     //   Mdotloop = Mdotcomp*(Tradsysin-Tradsysout)/(Tloop-Tradsysout) - PumpHeat/(Cp*(Tloop-Tradsysout))
    4403              :                     // If Mdotloop from this equation is greater that the loop flow rate (Node%MassFlowRate),
    4404              :                     // then we cannot meet the inlet temperature and we have to "iterate" through the
    4405              :                     // alternate solution.
    4406            0 :                     if ((SysWaterInTemp - this->WaterOutletTemp) != 0.0) { // protect divide by zero
    4407            0 :                         InjectFlowRate =
    4408            0 :                             (this->WaterMassFlowRate * (this->WaterInletTemp - this->WaterOutletTemp) / (SysWaterInTemp - this->WaterOutletTemp)) -
    4409            0 :                             (this->PumpHeattoFluid / (CpFluid * (SysWaterInTemp - this->WaterOutletTemp)));
    4410              :                     } else {
    4411            0 :                         InjectFlowRate = this->WaterMassFlowRate;
    4412              :                     }
    4413            0 :                     if (InjectFlowRate > hotNode.MassFlowRateMaxAvail) {
    4414              :                         // We didn't have enough flow from the loop to meet our inlet temperature request.
    4415              :                         // So, set the injection rate to the loop flow and calculate the recirculation flow.
    4416              :                         // Then, resimulate the radiant system using these values (it will obtain the actual
    4417              :                         // inlet temperature that results from this).
    4418            0 :                         this->WaterInjectionRate = hotNode.MassFlowRateMaxAvail;
    4419            0 :                         this->WaterRecircRate = this->WaterMassFlowRate - this->WaterInjectionRate;
    4420            0 :                         this->WaterInletTemp = SysWaterInTemp + PumpTempRise;
    4421            0 :                         Iteration = true;
    4422            0 :                         this->calculateLowTemperatureRadiantSystemComponents(state, LoopInNode, Iteration, LoadMet, SystemType::ConstantFlow);
    4423              :                     } else {
    4424            0 :                         this->WaterInjectionRate = InjectFlowRate;
    4425            0 :                         this->WaterRecircRate = this->WaterMassFlowRate - this->WaterInjectionRate;
    4426              :                     }
    4427              : 
    4428            0 :                 } else if ((SysWaterInTemp < state.dataLowTempRadSys->LoopReqTemp) && (hotNode.MassFlowRateMaxAvail < this->WaterMassFlowRate)) {
    4429              :                     // Case 4: Temperature too low and loop flow is less than component flow
    4430              :                     // Worst condition--can't meet the temperature request at all.  Only thing to do is to
    4431              :                     // set the loop flow and recirculation rate (known) and solve for the inlet temperature
    4432              :                     // using the "iteration" solution scheme from "Case 3B" above
    4433            0 :                     this->WaterInjectionRate = hotNode.MassFlowRateMaxAvail;
    4434            0 :                     this->WaterRecircRate = this->WaterMassFlowRate - this->WaterInjectionRate;
    4435            0 :                     this->WaterInletTemp = SysWaterInTemp + PumpTempRise;
    4436            0 :                     Iteration = true;
    4437            0 :                     this->calculateLowTemperatureRadiantSystemComponents(state, LoopInNode, Iteration, LoadMet, SystemType::ConstantFlow);
    4438              :                 }
    4439              : 
    4440       113216 :             } else if (this->opMode == OpMode::Cool) {
    4441              : 
    4442              :                 // in cooling mode so shut down heating water flow request
    4443       113216 :                 if (this->HWPlantLoc.loopNum > 0) {
    4444       113216 :                     mdot = 0.0;
    4445       113216 :                     SetComponentFlowRate(state, mdot, this->HotWaterInNode, this->HotWaterOutNode, this->HWPlantLoc);
    4446              :                 }
    4447       113216 :                 LoopInNode = this->ColdWaterInNode;
    4448       113216 :                 auto const &coldNode = state.dataLoopNodes->Node(LoopInNode);
    4449       113216 :                 SysWaterInTemp = coldNode.Temp;
    4450       113216 :                 state.dataLowTempRadSys->CFloCondIterNum = 1;
    4451       348002 :                 while ((state.dataLowTempRadSys->CFloCondIterNum <= 1) ||
    4452       117393 :                        ((state.dataLowTempRadSys->CFloCondIterNum <= 2) && (ConstantFlowDesignDataObject.condCtrlType == CondCtrlType::VariedOff) &&
    4453        13834 :                         (state.dataLowTempRadSys->VarOffCond))) {
    4454       117393 :                     Iteration = false;
    4455              : 
    4456       117393 :                     if ((SysWaterInTemp <= state.dataLowTempRadSys->LoopReqTemp) && (coldNode.MassFlowRateMaxAvail >= this->WaterMassFlowRate)) {
    4457              :                         // Case 1: Adequate temperature and flow
    4458              :                         // Best condition--loop inlet temperature lower than requested and we have enough flow.
    4459              :                         // So, proceed assuming the RadInTemp requested by the controls and then figure out the
    4460              :                         // mixing after the outlet radiant temperature is calculated.
    4461              : 
    4462              :                         // This condition can also happen when state.dataLowTempRadSys->LoopReqTemp has been reset  to dewpoint for condensation
    4463              :                         // control
    4464        82724 :                         if (!state.dataLowTempRadSys->VarOffCond) {
    4465        78547 :                             this->WaterInletTemp = RadInTemp;
    4466              :                         } else {
    4467         4177 :                             this->WaterInletTemp = state.dataLowTempRadSys->LoopReqTemp;
    4468              :                         }
    4469        82724 :                         this->calculateLowTemperatureRadiantSystemComponents(state, LoopInNode, Iteration, LoadMet, SystemType::ConstantFlow);
    4470              : 
    4471              :                         // We now have inlet and outlet temperatures--we still need to set the flow rates
    4472        82724 :                         if ((SysWaterInTemp - this->WaterOutletTemp) != 0.0) { // protect div by zero
    4473        82722 :                             this->WaterInjectionRate = (this->WaterMassFlowRate * (this->WaterInletTemp - this->WaterOutletTemp) /
    4474        82722 :                                                         (SysWaterInTemp - this->WaterOutletTemp)) -
    4475        82722 :                                                        (this->PumpHeattoFluid / (CpFluid * (SysWaterInTemp - this->WaterOutletTemp)));
    4476              :                         } else {
    4477            2 :                             this->WaterInjectionRate = this->WaterMassFlowRate;
    4478              :                         }
    4479        82724 :                         this->WaterRecircRate = this->WaterMassFlowRate - this->WaterInjectionRate;
    4480              : 
    4481        69338 :                     } else if ((SysWaterInTemp > state.dataLowTempRadSys->LoopReqTemp) &&
    4482        34669 :                                (coldNode.MassFlowRateMaxAvail >= this->WaterMassFlowRate)) {
    4483              :                         // Case 2: Adequate flow but temperature too high
    4484              :                         // Only thing to do is to reset the inlet temperature and assume that the loop will supply
    4485              :                         // the entire flow to the component (no recirculation but potentially some bypass for the
    4486              :                         // overall loop).  There is no way we can meet the control temperature so don't even try.
    4487        34669 :                         this->WaterInletTemp = SysWaterInTemp + PumpTempRise;
    4488        34669 :                         this->calculateLowTemperatureRadiantSystemComponents(state, LoopInNode, Iteration, LoadMet, SystemType::ConstantFlow);
    4489              : 
    4490              :                         // We now have inlet and outlet temperatures--we still need to set the flow rates
    4491        34669 :                         if ((SysWaterInTemp - this->WaterOutletTemp) != 0.0) { // protect div by zero
    4492        34666 :                             this->WaterInjectionRate = (this->WaterMassFlowRate * (this->WaterInletTemp - this->WaterOutletTemp) /
    4493        34666 :                                                         (SysWaterInTemp - this->WaterOutletTemp)) -
    4494        34666 :                                                        (this->PumpHeattoFluid / (CpFluid * (SysWaterInTemp - this->WaterOutletTemp)));
    4495              :                         } else { // no temp change present, set injection rate to full flow
    4496            3 :                             this->WaterInjectionRate = this->WaterMassFlowRate;
    4497              :                         }
    4498        34669 :                         if (this->WaterInjectionRate > this->WaterMassFlowRate) {
    4499         5322 :                             this->WaterInjectionRate = this->WaterMassFlowRate;
    4500              :                         }
    4501        34669 :                         this->WaterRecircRate = 0.0; // by definition
    4502              : 
    4503            0 :                     } else if ((SysWaterInTemp <= state.dataLowTempRadSys->LoopReqTemp) &&
    4504            0 :                                (coldNode.MassFlowRateMaxAvail < this->WaterMassFlowRate)) {
    4505              :                         // Case 3: Adequate temperature but loop flow is less than component flow
    4506              :                         // This case might work out, but there is no guarantee that there is enough loop flow to
    4507              :                         // mix with the recirculation flow and still provide a high enough temperature.  First
    4508              :                         // step is to try the inlet temperature and flow rate as in Case 1.  If we can obtain
    4509              :                         // the proper temperature inlet to the radiant system, then we are done.  If not, we
    4510              :                         // have to repeat the solution for an unknown inlet temperature and a known recirculation
    4511              :                         // rate.
    4512              :                         // This condition might happen when state.dataLowTempRadSys->LoopReqTemp has been reset  to dewpoint for condensation control
    4513            0 :                         if (!state.dataLowTempRadSys->VarOffCond) {
    4514            0 :                             this->WaterInletTemp = RadInTemp;
    4515              :                         } else {
    4516            0 :                             this->WaterInletTemp = state.dataLowTempRadSys->LoopReqTemp;
    4517              :                         }
    4518            0 :                         this->calculateLowTemperatureRadiantSystemComponents(state, LoopInNode, Iteration, LoadMet, SystemType::ConstantFlow);
    4519              : 
    4520              :                         // Now see if we can really get that desired into temperature (RadInTemp) by solving
    4521              :                         // for the flow that is injected from the loop.  A heat balance for the mixer that relates
    4522              :                         // the important quantities is:
    4523              :                         //   Mdotradsys*Cp*Tradsysin = Mdotloop*Cp*Tloop + (Mdotradsys-Mdotloop)*Cp*Tradsysout + PumpHeat
    4524              :                         // or rearranging to get the injection flow (Mdotloop):
    4525              :                         //   Mdotloop = Mdotcomp*(Tradsysin-Tradsysout)/(Tloop-Tradsysout) - PumpHeat/(Cp*(Tloop-Tradsysout))
    4526              :                         // If Mdotloop from this equation is greater that the loop flow rate (Node%MassFlowRate),
    4527              :                         // then we cannot meet the inlet temperature and we have to "iterate" through the
    4528              :                         // alternate solution.
    4529            0 :                         if ((SysWaterInTemp - this->WaterOutletTemp) != 0.0) { // protect div by zero
    4530            0 :                             InjectFlowRate = (this->WaterMassFlowRate * (this->WaterInletTemp - this->WaterOutletTemp) /
    4531            0 :                                               (SysWaterInTemp - this->WaterOutletTemp)) -
    4532            0 :                                              (this->PumpHeattoFluid / (CpFluid * (SysWaterInTemp - this->WaterOutletTemp)));
    4533              :                         } else {
    4534            0 :                             InjectFlowRate = this->WaterMassFlowRate;
    4535              :                         }
    4536            0 :                         if (InjectFlowRate > coldNode.MassFlowRateMaxAvail) {
    4537              :                             // We didn't have enough flow from the loop to meet our inlet temperature request.
    4538              :                             // So, set the injection rate to the loop flow and calculate the recirculation flow.
    4539              :                             // Then, resimulate the radiant system using these values (it will obtain the actual
    4540              :                             // inlet temperature that results from this).
    4541            0 :                             this->WaterInjectionRate = coldNode.MassFlowRateMaxAvail;
    4542            0 :                             this->WaterRecircRate = this->WaterMassFlowRate - this->WaterInjectionRate;
    4543            0 :                             this->WaterInletTemp = SysWaterInTemp + PumpTempRise;
    4544            0 :                             Iteration = true;
    4545            0 :                             this->calculateLowTemperatureRadiantSystemComponents(state, LoopInNode, Iteration, LoadMet, SystemType::ConstantFlow);
    4546              :                         } else {
    4547            0 :                             this->WaterInjectionRate = InjectFlowRate;
    4548            0 :                             this->WaterRecircRate = this->WaterMassFlowRate - this->WaterInjectionRate;
    4549              :                         }
    4550              : 
    4551            0 :                     } else if ((SysWaterInTemp > state.dataLowTempRadSys->LoopReqTemp) && (coldNode.MassFlowRateMaxAvail < this->WaterMassFlowRate)) {
    4552              :                         // Case 4: Temperature too low and loop flow is less than component flow
    4553              :                         // Worst condition--can't meet the temperature request at all.  Only thing to do is to
    4554              :                         // set the loop flow and recirculation rate (known) and solve for the inlet temperature
    4555              :                         // using the "iteration" solution scheme from "Case 3B" above
    4556            0 :                         this->WaterInjectionRate = coldNode.MassFlowRateMaxAvail;
    4557            0 :                         this->WaterRecircRate = this->WaterMassFlowRate - this->WaterInjectionRate;
    4558            0 :                         this->WaterInletTemp = SysWaterInTemp + PumpTempRise;
    4559            0 :                         Iteration = true;
    4560            0 :                         this->calculateLowTemperatureRadiantSystemComponents(state, LoopInNode, Iteration, LoadMet, SystemType::ConstantFlow);
    4561              :                     }
    4562              : 
    4563       117393 :                     ++state.dataLowTempRadSys->CFloCondIterNum;
    4564              :                 }
    4565              : 
    4566              :             } // Operating mode (heating or cooling)
    4567              : 
    4568              :             // Case when system has been shut down because of condensation issues or other limitations:
    4569       182976 :             if (this->WaterMassFlowRate < DataBranchAirLoopPlant::MassFlowTolerance) {
    4570         8801 :                 this->WaterMassFlowRate = 0.0;
    4571         8801 :                 this->WaterInjectionRate = 0.0;
    4572         8801 :                 this->WaterRecircRate = 0.0;
    4573         8801 :                 this->PumpMassFlowRate = 0.0;
    4574         8801 :                 this->opMode = OpMode::None;
    4575              :             }
    4576              : 
    4577              :             // There are some cases when the pump heat is actually enough to provide all the heating that the system needs.
    4578              :             // In this case, the water injection flow rate will come back as a slightly negative number.  Reset it to zero
    4579              :             // and just recirculate all the flow through the local loop.
    4580       182976 :             if (this->WaterInjectionRate < 0.0) {
    4581           33 :                 this->WaterInjectionRate = 0.0;
    4582           33 :                 this->WaterRecircRate = this->WaterMassFlowRate;
    4583              :             }
    4584              : 
    4585              :             // Error check, just in case
    4586       182976 :             if (this->WaterRecircRate < 0.0) {
    4587            0 :                 ShowWarningError(state, "Flow mismatch in radiant system--result will be an energy imbalance--should not get this error");
    4588            0 :                 ShowContinueErrorTimeStamp(state, format("WaterRecircRate={:.2T}, in Radiant System={},", this->WaterRecircRate, this->Name));
    4589            0 :                 this->WaterRecircRate = 0.0;
    4590            0 :                 this->WaterInjectionRate = this->WaterMassFlowRate;
    4591              :             }
    4592              : 
    4593              :         } // System running mode (yes or no)
    4594       221733 :     }
    4595              : 
    4596       187153 :     void ConstantFlowRadiantSystemData::calculateLowTemperatureRadiantSystemComponents(
    4597              :         EnergyPlusData &state,
    4598              :         int const MainLoopNodeIn, // Node number on main loop of the inlet node to the radiant system
    4599              :         bool const Iteration,     // FALSE for the regular solution, TRUE when we had to loop back
    4600              :         Real64 &LoadMet,          // Load met by the low temperature radiant system, in Watts
    4601              :         SystemType const typeOfRadiantSystem)
    4602              :     {
    4603              : 
    4604              :         // SUBROUTINE INFORMATION:
    4605              :         //       AUTHOR         Rick Strand
    4606              :         //       DATE WRITTEN   August 2003
    4607              :         //       MODIFIED       Sep 2011 LKL/BG - resimulate only zones needing it for Radiant systems
    4608              : 
    4609              :         // PURPOSE OF THIS SUBROUTINE:
    4610              :         // This subroutine solves the radiant system based on how much water is (and
    4611              :         // the conditions of the water) supplied to the radiant system.  The purpose
    4612              :         // of this subroutine is similar to CalcLowTempHydrRadSysComps except that
    4613              :         // it solves this for a constant flow hydronic radiant system.
    4614              : 
    4615              :         // METHODOLOGY EMPLOYED:
    4616              :         // Use heat exchanger formulas to obtain the heat source/sink for the radiant
    4617              :         // system based on the inlet conditions and flow rate of water.  Once that is
    4618              :         // determined, recalculate the surface heat balances to reflect this heat
    4619              :         // addition/subtraction.  The load met by the system is determined by the
    4620              :         // difference between the convection from all surfaces in the zone when
    4621              :         // there was no radiant system output and with a source/sink added.
    4622              : 
    4623              :         // REFERENCES:
    4624              :         // IBLAST-QTF research program, completed in January 1995 (unreleased)
    4625              :         // Strand, R.K. 1995. "Heat Source Transfer Functions and Their Application to
    4626              :         //   Low Temperature Radiant Heating Systems", Ph.D. dissertation, University
    4627              :         //   of Illinois at Urbana-Champaign, Department of Mechanical and Industrial
    4628              :         //   Engineering.
    4629              : 
    4630       187153 :         auto &Zone = state.dataHeatBal->Zone;
    4631              : 
    4632              :         // Using/Aliasing
    4633              :         using PlantUtilities::SetComponentFlowRate;
    4634              : 
    4635              :         // SUBROUTINE PARAMETER DEFINITIONS:
    4636       187153 :         Real64 constexpr TempCheckLimit(0.1); // Maximum allowed temperature difference between outlet temperature calculations
    4637       187153 :         Real64 constexpr ZeroSystemResp(0.1); // Response below which the system response is really zero
    4638       187153 :         constexpr std::string_view RoutineName("CalcLowTempCFloRadSysComps");
    4639              : 
    4640              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    4641              :         Real64 Cp;                    // Intermediate calculational variable for specific heat of water
    4642              :         Real64 DewPointTemp;          // Dew-point temperature based on the zone air conditions
    4643              :         Real64 EpsMdotCp;             // Epsilon (heat exchanger terminology) times water mass flow rate times water specific heat
    4644              :         Real64 LoopTerm;              // Intermeidate calculation variable for determining the water inlet temperature
    4645              :         Real64 Mdot;                  // Intermediate calculation variable for mass flow rate in a surface within the radiant system
    4646              :         Real64 RecircTerm;            // Intermeidate calculation variable for determining the water inlet temperature
    4647              :         Real64 SumFlowFracCkCm;       // Summation of surface flow fraction, Ck, and Cm product for each surface in the system
    4648              :         Real64 SumFlowFracOneMinusCm; // Summation of surface flow fraction times (1-Cm) for each surface in the radiant system
    4649              :         Real64 TotalRadSysPower;      // Total heat source/sink to radiant system
    4650              :         Real64 TwiCoeff;              // Intermeidate calculation variable for determining the water inlet temperature
    4651              :         Real64 WaterMassFlow;         // Water mass flow rate in the radiant system, kg/s
    4652              :         Real64 WaterOutletTempCheck;  // Radiant system water outlet temperature (calculated from mixing all outlet streams together)
    4653              :         Real64 WaterTempIn;           // Temperature of the water entering the radiant system, in C
    4654              :         int ZoneNum;                  // number of zone being served
    4655              :         Real64 ZoneMult;              // Zone multiplier for this system
    4656              : 
    4657              :         ConstantFlowRadDesignData ConstantFlowDesignDataObject =                   // I repeat myself
    4658       187153 :             state.dataLowTempRadSys->CflowRadiantSysDesign(this->DesignObjectPtr); // Contains the data for variable flow hydronic systems
    4659       187153 :         auto &Surface = state.dataSurface->Surface;
    4660              : 
    4661              :         Real64 Ca; // Coefficients to relate the inlet water temperature to the heat source
    4662              :         Real64 Cb;
    4663              :         Real64 Cc;
    4664              :         Real64 Cd;
    4665              :         Real64 Ce;
    4666              :         Real64 Cf;
    4667              :         Real64 Cg;
    4668              :         Real64 Ch;
    4669              :         Real64 Ci;
    4670              :         Real64 Cj;
    4671              :         Real64 Ck;
    4672              :         Real64 Cl;
    4673              :         // For more info on Ca through Cl, see comments below
    4674              : 
    4675              :         // First, apply heat exchanger logic to find the heat source/sink to the system.
    4676              :         // This involves finding out the heat transfer characteristics of the hydronic
    4677              :         // loop and then applying the equations derived on pp. 113-118 of the dissertation.
    4678       187153 :         if (state.dataLowTempRadSys->FirstTimeFlag) {
    4679            9 :             state.dataLowTempRadSys->Ckj.allocate(state.dataLowTempRadSys->MaxCloNumOfSurfaces);
    4680            9 :             state.dataLowTempRadSys->Cmj.allocate(state.dataLowTempRadSys->MaxCloNumOfSurfaces);
    4681            9 :             state.dataLowTempRadSys->WaterTempOut.allocate(state.dataLowTempRadSys->MaxCloNumOfSurfaces);
    4682            9 :             state.dataLowTempRadSys->FirstTimeFlag = false;
    4683              :         }
    4684              : 
    4685       187153 :         state.dataLowTempRadSys->Ckj = 0.0;
    4686       187153 :         state.dataLowTempRadSys->Cmj = 0.0;
    4687       187153 :         state.dataLowTempRadSys->WaterTempOut = this->WaterInletTemp;
    4688              : 
    4689       187153 :         ZoneNum = this->ZonePtr;
    4690       187153 :         ZoneMult = double(Zone(ZoneNum).Multiplier * Zone(ZoneNum).ListMultiplier);
    4691       187153 :         WaterMassFlow = this->WaterMassFlowRate / ZoneMult;
    4692       187153 :         WaterTempIn = this->WaterInletTemp;
    4693              : 
    4694       187153 :         if (WaterMassFlow <= 0.0) {
    4695              :             // No flow or below minimum allowed so there is no heat source/sink
    4696              :             // This is possible with a mismatch between system and plant operation
    4697              :             // or a slight mismatch between zone and system controls.  This is not
    4698              :             // necessarily a "problem" so this exception is necessary in the code.
    4699          132 :             for (int RadSurfNum = 1; RadSurfNum <= this->NumOfSurfaces; ++RadSurfNum) {
    4700           66 :                 int SurfNum = this->SurfacePtr(RadSurfNum);
    4701           66 :                 state.dataHeatBalFanSys->QRadSysSource(SurfNum) = 0.0;
    4702           66 :                 if (Surface(SurfNum).ExtBoundCond > 0 && Surface(SurfNum).ExtBoundCond != SurfNum) {
    4703            0 :                     state.dataHeatBalFanSys->QRadSysSource(Surface(SurfNum).ExtBoundCond) = 0.0; // Also zero the other side of an interzone
    4704              :                 }
    4705              :             }
    4706              : 
    4707           66 :             this->WaterOutletTemp = this->WaterInletTemp;
    4708              : 
    4709              :         } else {
    4710              : 
    4711       374174 :             for (int RadSurfNum = 1; RadSurfNum <= this->NumOfSurfaces; ++RadSurfNum) {
    4712       187087 :                 int SurfNum = this->SurfacePtr(RadSurfNum);
    4713              :                 // Determine the heat exchanger "effectiveness" term
    4714              : 
    4715       748348 :                 EpsMdotCp = calculateHXEffectivenessTerm(state,
    4716              :                                                          SurfNum,
    4717              :                                                          WaterTempIn,
    4718              :                                                          WaterMassFlow,
    4719       187087 :                                                          this->SurfaceFrac(RadSurfNum),
    4720       187087 :                                                          this->NumCircuits(RadSurfNum),
    4721              :                                                          this->DesignObjectPtr,
    4722              :                                                          typeOfRadiantSystem);
    4723              : 
    4724              :                 // Obtain the heat balance coefficients and calculate the intermediate coefficients
    4725              :                 // linking the inlet water temperature to the heat source/sink to the radiant system.
    4726              :                 // The coefficients are based on the following development...
    4727              :                 // The heat balance equations at the outside and inside surfaces are of the form:
    4728              :                 //   Tinside  = Ca + Cb*Toutside + Cc*q"
    4729              :                 //   Toutside = Cd + Ce*Tinside  + Cf*q"
    4730              :                 //   Tsource  = Cg + Ch*q"       + Ci*Tinside + Cj*Toutside
    4731              :                 // where:
    4732              :                 //   Tinside is the temperature at the inside surface
    4733              :                 //   Toutside is the temperature at the outside surface
    4734              :                 //   Tsource is the temperature within the radiant system at the location of the source/sink
    4735              :                 //   Ca is all of the other terms in the inside heat balance (solar, LW exchange, conduction history terms, etc.)
    4736              :                 //   Cb is the current cross CTF term
    4737              :                 //   Cc is the QTF inside term for the current heat source/sink
    4738              :                 //   Cd is all of the other terms in the outside heat balance (solar, LW exchange, conduction history terms, etc.)
    4739              :                 //   Ce is the current cross CTF term (should be equal to Cb)
    4740              :                 //   Cf is the QTF outside term for the current heat source/sink
    4741              :                 //   Cg is the summation of all temperature and source history terms at the source/sink location
    4742              :                 //   Ch is the QTF term at the source/sink location for the current heat source/sink
    4743              :                 //   Ci is the CTF inside term for the current inside surface temperature
    4744              :                 //   Cj is the CTF outside term for the current outside surface temperature
    4745              :                 // Note that it is necessary to not use "slow conduction" assumptions because the
    4746              :                 // source/sink has an impact on BOTH the inside and outside surface heat balances.
    4747              :                 // Hence the more general formulation.
    4748              :                 // The first two T equations above can be solved to remove the other surface temperature.
    4749              :                 // This results in the following equations:
    4750              :                 //   Tinside  = Ca + Cb*(Cd + Ce*Tinside + Cf*q") + Cc*q"   or...
    4751              :                 //   Tinside  = (Ca + Cb*Cd + (Cc+Cb*Cf)*q") / (1 - Ce*Cb)
    4752              :                 //   Toutside = Cd + Ce*(Ca + Cb*Toutside + Cc*q") + Cf*q"  or...
    4753              :                 //   Toutside = (Cd + Ce*Ca + (Cf+Ce*Cc)*q") / (1 - Ce*Cb)
    4754              :                 // Substituting the new equations for Tinside and Toutside as a function of C and q"
    4755              :                 // into the equation for Tsource...
    4756              :                 //   Tsource  = Cg + Ch*q" + Ci*((Ca + Cb*Cd + (Cc+Cb*Cf)*q") / (1 - Ce*Cb)) &
    4757              :                 //                         + Cj*((Cd + Ce*Ca + (Cf+Ce*Cc)*q") / (1 - Ce*Cb))
    4758              :                 // Or rearranging this to get Tsource as a function of q", we get...
    4759              :                 //   Tsource  =  Cg + ((Ci*(Ca + Cb*Cd) + Cj*(Cd + Ce*Ca))/(1-Ce*Cb)) &
    4760              :                 //             +(Ch + ((Ci*(Cc + Cb*Cf) + Cj*(Cf + Ce*Cc))/(1-Ce*Cb)))*q"
    4761              :                 // Or in a slightly simpler form...
    4762              :                 //   Tsource  = Ck + Cl*q"
    4763              :                 // where:
    4764              :                 //   Ck = Cg + ((Ci*(Ca + Cb*Cd) + Cj*(Cd + Ce*Ca))/(1-Ce*Cb))
    4765              :                 //   Cl = Ch + ((Ci*(Cc + Cb*Cf) + Cj*(Cf + Ce*Cc))/(1-Ce*Cb))
    4766              :                 // Note also that from heat exchanger "algebra", we have:
    4767              :                 //   q = epsilon*qmax    and    qmax = Mdot*Cp*(Twaterin-Tsource)
    4768              :                 // So...
    4769              :                 //   q" = q/Area = (epsilon*Mdot*Cp/Area)*(Twaterin-Tsource)
    4770              :                 // Or rearranging this equation:
    4771              :                 //   Tsource = -(q"*A/(epsilon*Mdot*Cp)) + Twaterin
    4772              :                 // Setting this equation equal to the other equation for Tsource a couple lines up
    4773              :                 // and rearranging to solve for q"...
    4774              :                 //   q" = (Twaterin - Ck) / (Cl + (A/(epsilon*Mdot*Cp))
    4775              :                 // or
    4776              :                 //   q  = (Twaterin - Ck) / ((Cl/A) + (1/epsilon*Mdot*Cp))
    4777              :                 // or
    4778              :                 //   q  = epsilon*Mdot*Cp*(Twaterin - Ck) / (1+(epsilon*Mdot*Cp*Cl/A))
    4779              :                 // which is the desired result, that is the heat source or sink to the radiant
    4780              :                 // system as a function of the water inlet temperature (flow rate is also in there
    4781              :                 // as well as all of the heat balance terms "hidden" in Ck and Cl).
    4782              : 
    4783       187087 :                 int ConstrNum = Surface(SurfNum).Construction;
    4784       187087 :                 auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    4785              : 
    4786       187087 :                 Ca = state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum);
    4787       187087 :                 Cb = state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum);
    4788       187087 :                 Cc = state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum);
    4789              : 
    4790       187087 :                 Cd = state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum);
    4791       187087 :                 Ce = state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum);
    4792       187087 :                 Cf = state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum);
    4793              : 
    4794       187087 :                 Cg = state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum);
    4795       187087 :                 Ch = thisConstruct.CTFTSourceQ[0];
    4796       187087 :                 Ci = thisConstruct.CTFTSourceIn[0];
    4797       187087 :                 Cj = thisConstruct.CTFTSourceOut[0];
    4798              : 
    4799       187087 :                 Ck = Cg + ((Ci * (Ca + Cb * Cd) + Cj * (Cd + Ce * Ca)) / (1.0 - Ce * Cb));
    4800       187087 :                 Cl = Ch + ((Ci * (Cc + Cb * Cf) + Cj * (Cf + Ce * Cc)) / (1.0 - Ce * Cb));
    4801              : 
    4802       187087 :                 Mdot = WaterMassFlow * this->SurfaceFrac(RadSurfNum);
    4803       187087 :                 Cp = this->water->getSpecificHeat(state, WaterTempIn, RoutineName);
    4804              : 
    4805       187087 :                 if (!Iteration) {
    4806              : 
    4807       187087 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF) {
    4808       150349 :                         state.dataHeatBalFanSys->QRadSysSource(SurfNum) =
    4809       150349 :                             EpsMdotCp * (WaterTempIn - Ck) / (1.0 + (EpsMdotCp * Cl / Surface(SurfNum).Area));
    4810              :                     }
    4811              : 
    4812       187087 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
    4813        36738 :                         state.dataHeatBalFanSys->QRadSysSource(SurfNum) =
    4814        36738 :                             EpsMdotCp * (WaterTempIn - state.dataHeatBalFanSys->TCondFDSourceNode(SurfNum));
    4815              :                     }
    4816              : 
    4817       187087 :                     if (Surface(SurfNum).ExtBoundCond > 0 && Surface(SurfNum).ExtBoundCond != SurfNum) {
    4818            0 :                         state.dataHeatBalFanSys->QRadSysSource(Surface(SurfNum).ExtBoundCond) =
    4819            0 :                             state.dataHeatBalFanSys->QRadSysSource(SurfNum); // Also set the other side of an interzone
    4820              :                     }
    4821       187087 :                     state.dataLowTempRadSys->WaterTempOut(RadSurfNum) = WaterTempIn - (state.dataHeatBalFanSys->QRadSysSource(SurfNum) / (Mdot * Cp));
    4822              :                 } else { // (Iteration)
    4823              :                     // In this case, we did not know the inlet temperature directly and have
    4824              :                     // to figure it out as part of the solution.  Thus, we have to do a little
    4825              :                     // more algebra.
    4826              :                     // The last equation in the previous block was:
    4827              :                     //   q = epsilon*Mdot*Cp*(Twaterin - Ck) / (1+(epsilon*Mdot*Cp*Cl/A))
    4828              :                     // which combines with:
    4829              :                     //   q = Mdot*Cp*(Twaterin - Twaterout,j)
    4830              :                     // so that:
    4831              :                     //   (Twaterin - Twaterout.j) = epsilon*(Twaterin - Ck) / (1+(epsilon*Mdot*Cp*Cl/A))
    4832              :                     // Let:
    4833              :                     //   Cm = epsilonj / (1+(epsilonj*Mdot,j*Cp*Cl,j/A))
    4834              :                     // for each surface in the radiant system.  This results in:
    4835              :                     //   (Twaterin - Twaterout,j) = Cm,j*(Twaterin - Ck,j)
    4836              :                     // Or:
    4837              :                     //   Twaterout,j = (1 - Cm,j)*Twaterin + Cm,j*Ck,j
    4838              :                     // This holds for each surface that is part of the radiant system (j).  To get the
    4839              :                     // overall outlet temperature, we have to do a mixing calculation after all of the
    4840              :                     // surfaces have been simulated:
    4841              :                     //   Twaterout = SUM(Fractionj*Twaterout,j)
    4842              :                     // We also have to solve an energy balance at the mixing valve and add in pump heat.
    4843              :                     // The energy balance at the mixing valve relates the loop inlet temperature (Tloopin)
    4844              :                     // and the overall outlet temperature (Twaterout):
    4845              :                     //   Tpumpin = (Mdotloop/Mdotradsys)*Tloopin + (Mdotrecirc/Mdotradsys)*Twaterout
    4846              :                     // This can then be related to the inlet water temperature to the radiant system
    4847              :                     // after pump heat has been taken into account:
    4848              :                     //   Twaterin = (Mdotloop/Mdotradsys)*Tloopin + (Mdotrecirc/Mdotradsys)*Twaterout + PumpHeat/(Mdotradsys*Cp)
    4849              :                     // Pluggin in the definition of Twaterout (sum equation above) and then the definition
    4850              :                     // of each individual Twaterout,j equation (which is solely a function of Twaterin
    4851              :                     // and coefficients), we can obtain an equation for Twaterin that consists of all
    4852              :                     // known quantities.  This requires us to calculate Ck,j and Cm,j for all the radiant
    4853              :                     // surfaces in the system first and then coming up with a calculation for Twaterin.
    4854              :                     // After than, individual Twaterout,j can be calculated along with QRadSysSource.
    4855            0 :                     state.dataLowTempRadSys->Ckj(RadSurfNum) = Ck;
    4856            0 :                     state.dataLowTempRadSys->Cmj(RadSurfNum) = (EpsMdotCp / (Mdot * Cp)) / (1.0 + (EpsMdotCp * Cl / Surface(SurfNum).Area));
    4857              : 
    4858            0 :                     if (RadSurfNum == this->NumOfSurfaces) { // Last one so we can now do the other calculations
    4859              :                         // Equation for Twaterin is:
    4860              :                         //   Twaterin = (LoopTerm + RecircTerm)/(TwiCoeff)
    4861              :                         // where:
    4862              :                         //   LoopTerm   = (Mdotloop/Mdotradsys)*Tloopin + PumpHeat/(Mdotradsys*Cp)
    4863              :                         //   RecircTerm = (Mdotrecirc/Mdotradsys)*SUM(FlowFracj*Ck,j*Cm,j)
    4864              :                         //   TwiCoeff   = 1 - (Mdotrecirc/Mdotradsys)*SUM(FlowFracj*(1 - Cm,j))
    4865            0 :                         SumFlowFracCkCm = 0.0;
    4866            0 :                         SumFlowFracOneMinusCm = 0.0;
    4867            0 :                         for (int RadSurfNum2 = 1; RadSurfNum2 <= this->NumOfSurfaces; ++RadSurfNum2) {
    4868            0 :                             SumFlowFracCkCm += (this->SurfaceFrac(RadSurfNum2) * state.dataLowTempRadSys->Ckj(RadSurfNum) *
    4869            0 :                                                 state.dataLowTempRadSys->Cmj(RadSurfNum2));
    4870            0 :                             SumFlowFracOneMinusCm += (this->SurfaceFrac(RadSurfNum2) * (1.0 - state.dataLowTempRadSys->Cmj(RadSurfNum2)));
    4871              :                         }
    4872              : 
    4873            0 :                         LoopTerm = (this->WaterInjectionRate / this->WaterMassFlowRate) * state.dataLoopNodes->Node(MainLoopNodeIn).Temp +
    4874            0 :                                    (this->PumpHeattoFluid / (this->WaterMassFlowRate * Cp));
    4875              : 
    4876            0 :                         RecircTerm = (this->WaterRecircRate / this->WaterMassFlowRate) * SumFlowFracCkCm;
    4877              : 
    4878            0 :                         TwiCoeff = 1.0 - (this->WaterRecircRate / this->WaterMassFlowRate) * SumFlowFracOneMinusCm;
    4879              : 
    4880            0 :                         WaterTempIn = (LoopTerm + RecircTerm) / (TwiCoeff);
    4881              : 
    4882            0 :                         this->WaterInletTemp = WaterTempIn;
    4883              : 
    4884            0 :                         for (int RadSurfNum2 = 1; RadSurfNum2 <= this->NumOfSurfaces; ++RadSurfNum2) {
    4885            0 :                             state.dataLowTempRadSys->WaterTempOut(RadSurfNum2) =
    4886            0 :                                 WaterTempIn * (1.0 - state.dataLowTempRadSys->Cmj(RadSurfNum2)) +
    4887            0 :                                 (state.dataLowTempRadSys->Ckj(RadSurfNum2) * state.dataLowTempRadSys->Cmj(RadSurfNum2));
    4888            0 :                             Mdot = WaterMassFlow * this->SurfaceFrac(RadSurfNum2);
    4889            0 :                             int SurfNum2 = this->SurfacePtr(RadSurfNum2);
    4890            0 :                             state.dataHeatBalFanSys->QRadSysSource(SurfNum2) =
    4891            0 :                                 Mdot * Cp * (WaterTempIn - state.dataLowTempRadSys->WaterTempOut(RadSurfNum2));
    4892            0 :                             if (Surface(SurfNum2).ExtBoundCond > 0 && Surface(SurfNum2).ExtBoundCond != SurfNum2) {
    4893            0 :                                 state.dataHeatBalFanSys->QRadSysSource(Surface(SurfNum2).ExtBoundCond) =
    4894            0 :                                     state.dataHeatBalFanSys->QRadSysSource(SurfNum2); // Also set the other side of an interzone
    4895              :                             }
    4896              :                         }
    4897              :                     }
    4898              :                 }
    4899              :             }
    4900              : 
    4901       373721 :             for (int RadSurfNum = 1; RadSurfNum <= this->NumOfSurfaces; ++RadSurfNum) {
    4902       187087 :                 int SurfNum = this->SurfacePtr(RadSurfNum);
    4903              :                 // "Temperature Comparison" Cut-off:
    4904              :                 // Check to see whether or not the system should really be running.  If
    4905              :                 // QRadSysSource is negative when we are in heating mode or QRadSysSource
    4906              :                 // is positive when we are in cooling mode, then the radiant system will
    4907              :                 // be doing the opposite of its intention.  In this case, the flow rate
    4908              :                 // is set to zero to avoid heating in cooling mode or cooling in heating
    4909              :                 // mode.
    4910       373721 :                 if (((this->opMode == OpMode::Heat) && (state.dataHeatBalFanSys->QRadSysSource(SurfNum) <= 0.0)) ||
    4911       186634 :                     ((this->opMode == OpMode::Cool) && (state.dataHeatBalFanSys->QRadSysSource(SurfNum) >= 0.0))) {
    4912          453 :                     WaterMassFlow = 0.0;
    4913          453 :                     if (this->opMode == OpMode::Heat) {
    4914          453 :                         SetComponentFlowRate(state, WaterMassFlow, this->HotWaterInNode, this->HotWaterOutNode, this->HWPlantLoc);
    4915            0 :                     } else if (this->opMode == OpMode::Cool) {
    4916            0 :                         SetComponentFlowRate(state, WaterMassFlow, this->ColdWaterInNode, this->ColdWaterOutNode, this->CWPlantLoc);
    4917              :                     }
    4918          453 :                     this->WaterMassFlowRate = WaterMassFlow;
    4919          453 :                     this->opMode = OpMode::None;
    4920          906 :                     for (int RadSurfNum2 = 1; RadSurfNum2 <= this->NumOfSurfaces; ++RadSurfNum2) {
    4921          453 :                         int SurfNum2 = this->SurfacePtr(RadSurfNum2);
    4922          453 :                         state.dataHeatBalFanSys->QRadSysSource(SurfNum2) = 0.0;
    4923          453 :                         if (Surface(SurfNum2).ExtBoundCond > 0 && Surface(SurfNum2).ExtBoundCond != SurfNum2) {
    4924            0 :                             state.dataHeatBalFanSys->QRadSysSource(Surface(SurfNum2).ExtBoundCond) = 0.0; // Also zero the other side of an interzone
    4925              :                         }
    4926              :                     }
    4927          453 :                     break; // outer do loop
    4928              :                 }
    4929              :             }
    4930              :             // Condensation Cut-off:
    4931              :             // Check to see whether there are any surface temperatures within the radiant system that have
    4932              :             // dropped below the dew-point temperature.  If so, we need to shut off this radiant system.
    4933              :             // A safety parameter is added (hardwired parameter) to avoid getting too close to condensation
    4934              :             // conditions.
    4935       187087 :             this->CondCausedShutDown = false;
    4936       187087 :             DewPointTemp =
    4937       187087 :                 PsyTdpFnWPb(state, state.dataZoneTempPredictorCorrector->zoneHeatBalance(this->ZonePtr).airHumRat, state.dataEnvrn->OutBaroPress);
    4938              : 
    4939       187087 :             if ((this->opMode == OpMode::Cool) && (ConstantFlowDesignDataObject.condCtrlType == CondCtrlType::SimpleOff)) {
    4940              : 
    4941        44105 :                 for (int RadSurfNum2 = 1; RadSurfNum2 <= this->NumOfSurfaces; ++RadSurfNum2) {
    4942        24118 :                     if (state.dataHeatBalSurf->SurfInsideTempHist(1)(this->SurfacePtr(RadSurfNum2)) <
    4943        24118 :                         (DewPointTemp + ConstantFlowDesignDataObject.CondDewPtDeltaT)) {
    4944              :                         // Condensation warning--must shut off radiant system
    4945         4131 :                         this->CondCausedShutDown = true;
    4946         4131 :                         WaterMassFlow = 0.0;
    4947         4131 :                         this->opMode = OpMode::None;
    4948         4131 :                         SetComponentFlowRate(state, WaterMassFlow, this->ColdWaterInNode, this->ColdWaterOutNode, this->CWPlantLoc);
    4949         4131 :                         this->WaterMassFlowRate = WaterMassFlow;
    4950         8262 :                         for (int RadSurfNum3 = 1; RadSurfNum3 <= this->NumOfSurfaces; ++RadSurfNum3) {
    4951         4131 :                             int SurfNum2 = this->SurfacePtr(RadSurfNum3);
    4952         4131 :                             state.dataHeatBalFanSys->QRadSysSource(SurfNum2) = 0.0;
    4953         4131 :                             if (Surface(SurfNum2).ExtBoundCond > 0 && Surface(SurfNum2).ExtBoundCond != SurfNum2) {
    4954            0 :                                 state.dataHeatBalFanSys->QRadSysSource(Surface(SurfNum2).ExtBoundCond) =
    4955              :                                     0.0; // Also zero the other side of an interzone
    4956              :                             }
    4957              :                         }
    4958              :                         // Produce a warning message so that user knows the system was shut-off due to potential for condensation
    4959         4131 :                         if (!state.dataGlobal->WarmupFlag) {
    4960          582 :                             if (this->CondErrIndex == 0) { // allow errors up to number of radiant systems
    4961            2 :                                 ShowWarningMessage(state, format("{} [{}]", cConstantFlowSystem, this->Name));
    4962            4 :                                 ShowContinueError(state,
    4963            4 :                                                   format("Surface [{}] temperature below dew-point temperature--potential for condensation exists",
    4964            2 :                                                          Surface(this->SurfacePtr(RadSurfNum2)).Name));
    4965            4 :                                 ShowContinueError(state, "Flow to the radiant system will be shut-off to avoid condensation");
    4966            4 :                                 ShowContinueError(state,
    4967            4 :                                                   format("Predicted radiant system surface temperature = {:.2R}",
    4968            2 :                                                          state.dataHeatBalSurf->SurfInsideTempHist(1)(this->SurfacePtr(RadSurfNum2))));
    4969            4 :                                 ShowContinueError(state,
    4970            4 :                                                   format("Zone dew-point temperature + safety delta T= {:.2R}",
    4971            2 :                                                          DewPointTemp + ConstantFlowDesignDataObject.CondDewPtDeltaT));
    4972            4 :                                 ShowContinueErrorTimeStamp(state, "");
    4973            4 :                                 ShowContinueError(state,
    4974            4 :                                                   format("Note that a {:.4R} C safety was chosen in the input for the shut-off criteria",
    4975              :                                                          ConstantFlowDesignDataObject.CondDewPtDeltaT));
    4976            6 :                                 ShowContinueError(state, "Note also that this affects all surfaces that are part of this radiant system");
    4977              :                             }
    4978         4656 :                             ShowRecurringWarningErrorAtEnd(
    4979              :                                 state,
    4980         1164 :                                 format("{} [{}] condensation shut-off occurrence continues.", cConstantFlowSystem, this->Name),
    4981          582 :                                 this->CondErrIndex,
    4982              :                                 DewPointTemp,
    4983              :                                 DewPointTemp,
    4984              :                                 _,
    4985              :                                 "C",
    4986              :                                 "C");
    4987              :                         }
    4988         4131 :                         break; // outer do loop
    4989              :                     }
    4990              :                 }
    4991              : 
    4992       187087 :             } else if ((this->opMode == OpMode::Cool) && (ConstantFlowDesignDataObject.condCtrlType == CondCtrlType::None)) {
    4993              : 
    4994       150468 :                 for (int RadSurfNum2 = 1; RadSurfNum2 <= this->NumOfSurfaces; ++RadSurfNum2) {
    4995        75234 :                     if (state.dataHeatBalSurf->SurfInsideTempHist(1)(this->SurfacePtr(RadSurfNum2)) < DewPointTemp) {
    4996              :                         // Condensation occurring but user does not want to shut radiant system off ever
    4997        36362 :                         this->CondCausedShutDown = true;
    4998              :                     }
    4999              :                 }
    5000              : 
    5001       162969 :             } else if ((this->opMode == OpMode::Cool) && (ConstantFlowDesignDataObject.condCtrlType == CondCtrlType::VariedOff)) {
    5002              : 
    5003        31867 :                 for (int RadSurfNum2 = 1; RadSurfNum2 <= this->NumOfSurfaces; ++RadSurfNum2) {
    5004        18009 :                     if (state.dataHeatBalSurf->SurfInsideTempHist(1)(this->SurfacePtr(RadSurfNum2)) <
    5005        18009 :                         (DewPointTemp + ConstantFlowDesignDataObject.CondDewPtDeltaT)) {
    5006         8328 :                         state.dataLowTempRadSys->VarOffCond = true;
    5007         8328 :                         if (state.dataLowTempRadSys->CFloCondIterNum >= 2) {
    5008              :                             // We have already iterated once so now we must shut off radiant system
    5009         4151 :                             this->CondCausedShutDown = true;
    5010         4151 :                             WaterMassFlow = 0.0;
    5011         4151 :                             this->opMode = OpMode::None;
    5012         4151 :                             SetComponentFlowRate(state, WaterMassFlow, this->ColdWaterInNode, this->ColdWaterOutNode, this->CWPlantLoc);
    5013         4151 :                             this->WaterMassFlowRate = WaterMassFlow;
    5014         8302 :                             for (int RadSurfNum3 = 1; RadSurfNum3 <= this->NumOfSurfaces; ++RadSurfNum3) {
    5015         4151 :                                 int SurfNum2 = this->SurfacePtr(RadSurfNum3);
    5016         4151 :                                 state.dataHeatBalFanSys->QRadSysSource(SurfNum2) = 0.0;
    5017         4151 :                                 if (Surface(SurfNum2).ExtBoundCond > 0 && Surface(SurfNum2).ExtBoundCond != SurfNum2) {
    5018            0 :                                     state.dataHeatBalFanSys->QRadSysSource(Surface(SurfNum2).ExtBoundCond) =
    5019              :                                         0.0; // Also zero the other side of an interzone
    5020              :                                 }
    5021              :                             }
    5022              :                             // Produce a warning message so that user knows the system was shut-off due to potential for condensation
    5023         4151 :                             if (!state.dataGlobal->WarmupFlag) {
    5024          577 :                                 if (this->CondErrIndex == 0) { // allow errors up to number of radiant systems
    5025            2 :                                     ShowWarningMessage(state, format("{} [{}]", cConstantFlowSystem, this->Name));
    5026            4 :                                     ShowContinueError(
    5027              :                                         state,
    5028            4 :                                         format("Surface [{}] temperature below dew-point temperature--potential for condensation exists",
    5029            2 :                                                Surface(this->SurfacePtr(RadSurfNum2)).Name));
    5030            4 :                                     ShowContinueError(state, "Flow to the radiant system will be shut-off to avoid condensation");
    5031            4 :                                     ShowContinueError(state,
    5032            4 :                                                       format("Predicted radiant system surface temperature = {:.2R}",
    5033            2 :                                                              state.dataHeatBalSurf->SurfInsideTempHist(1)(this->SurfacePtr(RadSurfNum2))));
    5034            4 :                                     ShowContinueError(state,
    5035            4 :                                                       format("Zone dew-point temperature + safety delta T= {:.2R}",
    5036            2 :                                                              DewPointTemp + ConstantFlowDesignDataObject.CondDewPtDeltaT));
    5037            4 :                                     ShowContinueErrorTimeStamp(state, "");
    5038            4 :                                     ShowContinueError(state,
    5039            4 :                                                       format("Note that a {:.4R} C safety was chosen in the input for the shut-off criteria",
    5040              :                                                              ConstantFlowDesignDataObject.CondDewPtDeltaT));
    5041            6 :                                     ShowContinueError(state, "Note also that this affects all surfaces that are part of this radiant system");
    5042              :                                 }
    5043         4616 :                                 ShowRecurringWarningErrorAtEnd(
    5044              :                                     state,
    5045         1154 :                                     format("{} [{}] condensation shut-off occurrence continues.", cConstantFlowSystem, this->Name),
    5046          577 :                                     this->CondErrIndex,
    5047              :                                     DewPointTemp,
    5048              :                                     DewPointTemp,
    5049              :                                     _,
    5050              :                                     "C",
    5051              :                                     "C");
    5052              :                             }
    5053         4151 :                             break; // outer do loop
    5054              :                         } else {   // (First iteration--reset loop required temperature and try again to avoid condensation)
    5055         4177 :                             state.dataLowTempRadSys->LoopReqTemp = DewPointTemp + ConstantFlowDesignDataObject.CondDewPtDeltaT;
    5056              :                         }
    5057              :                     }
    5058              :                 }
    5059              :             }
    5060              : 
    5061              :             // Determine radiant system outlet temperature (two ways to calculate--use as a check)
    5062       187087 :             WaterOutletTempCheck = 0.0;
    5063       187087 :             TotalRadSysPower = 0.0;
    5064       374174 :             for (int RadSurfNum = 1; RadSurfNum <= this->NumOfSurfaces; ++RadSurfNum) {
    5065       187087 :                 int SurfNum = this->SurfacePtr(RadSurfNum);
    5066       187087 :                 TotalRadSysPower += state.dataHeatBalFanSys->QRadSysSource(SurfNum);
    5067       187087 :                 WaterOutletTempCheck += (this->SurfaceFrac(RadSurfNum) * state.dataLowTempRadSys->WaterTempOut(RadSurfNum));
    5068              :             }
    5069       187087 :             TotalRadSysPower *= ZoneMult;
    5070              : 
    5071       187087 :             if (this->WaterMassFlowRate > 0.0) {
    5072       178352 :                 Cp = this->water->getSpecificHeat(state, WaterTempIn, RoutineName);
    5073       178352 :                 this->WaterOutletTemp = this->WaterInletTemp - (TotalRadSysPower / (this->WaterMassFlowRate * Cp));
    5074       178352 :                 if ((std::abs(this->WaterOutletTemp - WaterOutletTempCheck) > TempCheckLimit) && (std::abs(TotalRadSysPower) > ZeroSystemResp)) {
    5075              :                     // If the total system power is zero, that means we have shut down and the temperatures won't match because of that
    5076            0 :                     ShowWarningError(state, "Radiant system water outlet temperature calculation mismatch--this should not happen");
    5077              :                 }
    5078              :             } else {
    5079         8735 :                 this->WaterOutletTemp = this->WaterInletTemp;
    5080              :             }
    5081              :         }
    5082              : 
    5083              :         // Now that we have the source/sink term(s), we must redo the heat balances to obtain
    5084              :         // the new SumHATsurf value for the zone.  Note that the difference between the new
    5085              :         // SumHATsurf and the value originally calculated by the heat balance with a zero
    5086              :         // source for all radiant systems in the zone is the load met by the system (approximately).
    5087       187153 :         HeatBalanceSurfaceManager::CalcHeatBalanceOutsideSurf(state, ZoneNum);
    5088       187153 :         HeatBalanceSurfaceManager::CalcHeatBalanceInsideSurf(state, ZoneNum);
    5089              : 
    5090       187153 :         LoadMet = state.dataHeatBal->Zone(this->ZonePtr).sumHATsurf(state) - this->ZeroLTRSourceSumHATsurf;
    5091       187153 :     }
    5092              :     // TODO Write unit tests for baseboard
    5093           78 :     void ConstantFlowRadiantSystemData::calculateRunningMeanAverageTemperature(EnergyPlusData &state, int RadSysNum)
    5094              :     {
    5095              :         // This routine grabs the current weather data since it is currently available at this point in the simulation.  Note, however,
    5096              :         // that the formula that calculates the running mean average (dry-bulb) temperature uses the values from "yesterday".  So, today's
    5097              :         // values are calculated and then shifted at the beginning of the next day to the tomorrow variables.  It is these tomorrow variables
    5098              :         // that are then used in the formula.  So, that is why some of the assignments are done in the order that they are in below.
    5099              : 
    5100           78 :         ConstantFlowRadDesignData constantFlowDesignDataObject{state.dataLowTempRadSys->CflowRadiantSysDesign(
    5101           78 :             state.dataLowTempRadSys->CFloRadSys(RadSysNum).DesignObjectPtr)}; // Contains the data for constant flow hydronic systems
    5102              : 
    5103           78 :         if (state.dataGlobal->DayOfSim == 1 && state.dataGlobal->WarmupFlag) {
    5104              :             // there is no "history" here--assume everything that came before was the same (this applies to design days also--weather is always the
    5105              :             // same
    5106           24 :             this->todayAverageOutdoorDryBulbTemperature = this->calculateCurrentDailyAverageODB(state);
    5107           24 :             this->yesterdayAverageOutdoorDryBulbTemperature = this->todayAverageOutdoorDryBulbTemperature;
    5108           24 :             this->todayRunningMeanOutdoorDryBulbTemperature = this->todayAverageOutdoorDryBulbTemperature;
    5109           24 :             this->yesterdayRunningMeanOutdoorDryBulbTemperature = this->todayAverageOutdoorDryBulbTemperature;
    5110           54 :         } else if (!state.dataGlobal->WarmupFlag && state.dataGlobal->NumOfDayInEnvrn > 1) {
    5111              :             // This is an environment with more than one day (non-design day) so...
    5112              :             // First update yesterday's information using what was previously calculated for "today"
    5113            0 :             this->yesterdayAverageOutdoorDryBulbTemperature = this->todayAverageOutdoorDryBulbTemperature;
    5114            0 :             this->yesterdayRunningMeanOutdoorDryBulbTemperature = this->todayRunningMeanOutdoorDryBulbTemperature;
    5115              :             // Now update the running mean and average outdoor air temperatures
    5116            0 :             this->todayRunningMeanOutdoorDryBulbTemperature =
    5117            0 :                 (1.0 - constantFlowDesignDataObject.runningMeanOutdoorAirTemperatureWeightingFactor) *
    5118            0 :                     this->yesterdayAverageOutdoorDryBulbTemperature +
    5119            0 :                 constantFlowDesignDataObject.runningMeanOutdoorAirTemperatureWeightingFactor * this->yesterdayRunningMeanOutdoorDryBulbTemperature;
    5120            0 :             this->todayAverageOutdoorDryBulbTemperature = this->calculateCurrentDailyAverageODB(state);
    5121              :         }
    5122           78 :     }
    5123              : 
    5124           24 :     Real64 ConstantFlowRadiantSystemData::calculateCurrentDailyAverageODB(EnergyPlusData &state)
    5125              :     {
    5126           24 :         Real64 sum = 0.0;
    5127          600 :         for (int hourNumber = 1; hourNumber <= Constant::iHoursInDay; ++hourNumber) {
    5128         4032 :             for (int timeStepNumber = 1; timeStepNumber <= state.dataGlobal->TimeStepsInHour; ++timeStepNumber) {
    5129         3456 :                 sum += state.dataWeather->wvarsHrTsToday(timeStepNumber, hourNumber).OutDryBulbTemp;
    5130              :             }
    5131              :         }
    5132           24 :         return sum / (Constant::rHoursInDay * state.dataGlobal->TimeStepsInHour);
    5133              :     }
    5134              : 
    5135        79059 :     void ElectricRadiantSystemData::calculateLowTemperatureRadiantSystem(EnergyPlusData &state,
    5136              :                                                                          Real64 &LoadMet) // load met by the radiant system, in Watts
    5137              :     {
    5138              : 
    5139              :         // SUBROUTINE INFORMATION:
    5140              :         //       AUTHOR         Rick Strand
    5141              :         //       DATE WRITTEN   November 2000
    5142              :         //       MODIFIED       Sep 2011 LKL/BG - resimulate only zones needing it for Radiant systems
    5143              : 
    5144              :         // PURPOSE OF THIS SUBROUTINE:
    5145              :         // This subroutine does all of the stuff that is necessary to simulate
    5146              :         // a low temperature electric radiant heating system.  Calls are made to
    5147              :         // appropriate subroutines either in this module or outside of it.
    5148              : 
    5149              :         // METHODOLOGY EMPLOYED:
    5150              :         // Follows the methods used by many other pieces of zone equipment except
    5151              :         // that we are controlling the electrical input to the building element's
    5152              :         // resistance heating wires.  Note that cooling is not allowed for such
    5153              :         // a system.
    5154              : 
    5155              :         // REFERENCES:
    5156              :         // Other EnergyPlus modules
    5157              :         // IBLAST-QTF research program, completed in January 1995 (unreleased)
    5158              :         // Strand, R.K. 1995. "Heat Source Transfer Functions and Their Application to
    5159              :         //   Low Temperature Radiant Heating Systems", Ph.D. dissertation, University
    5160              :         //   of Illinois at Urbana-Champaign, Department of Mechanical and Industrial
    5161              :         //   Engineering.
    5162              :         // Seem, J.E. 1986. "Heat Transfer in Buildings", Ph.D. dissertation, University
    5163              :         //   of Wisconsin-Madison.
    5164              : 
    5165              :         // Using/Aliasing
    5166              :         using DataHeatBalance::ZoneData;
    5167              :         using HVAC::SmallLoad;
    5168              : 
    5169              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    5170              :         Real64 ControlTemp; // Temperature of the parameter that is controlling the radiant system
    5171              :         Real64 HeatFrac;    // fraction of maximum electrical heat input to radiant system [dimensionless]
    5172              :         Real64 OffTemp;     // Temperature above which the radiant system should be completely off [C]
    5173              :         int RadSurfNum;     // number of surface that is the radiant system
    5174              :         int SurfNum;        // intermediate variable for surface number in Surface derived type
    5175              :         int ZoneNum;        // number of zone being served
    5176              : 
    5177              :         // initialize local variables
    5178        79059 :         ZoneNum = this->ZonePtr;
    5179        79059 :         HeatFrac = 0.0;
    5180        79059 :         auto &Surface = state.dataSurface->Surface;
    5181              : 
    5182        79059 :         if (this->availSched->getCurrentVal() <= 0.0) {
    5183              : 
    5184              :             // Unit is off; set the heat source terms to zero
    5185        82788 :             for (RadSurfNum = 1; RadSurfNum <= this->NumOfSurfaces; ++RadSurfNum) {
    5186        41394 :                 SurfNum = this->SurfacePtr(RadSurfNum);
    5187        41394 :                 state.dataHeatBalFanSys->QRadSysSource(SurfNum) = 0.0;
    5188        41394 :                 if (Surface(SurfNum).ExtBoundCond > 0 && Surface(SurfNum).ExtBoundCond != SurfNum) {
    5189            0 :                     state.dataHeatBalFanSys->QRadSysSource(Surface(SurfNum).ExtBoundCond) = 0.0; // Also zero the other side of an interzone
    5190              :                 }
    5191              :             }
    5192              : 
    5193              :         } else { // Unit might be on-->this section is intended to determine whether the controls say
    5194              :             // that the unit should be on or not
    5195              : 
    5196              :             // Determine the current setpoint temperature and the temperature at which the unit should be completely off
    5197        37665 :             OffTemp = this->setOffTemperatureLowTemperatureRadiantSystem(state, this->setptSched, this->ThrottlRange, this->setpointType);
    5198              : 
    5199              :             // Determine the control temperature--what the setpoint/offtemp is being compared to for unit operation
    5200              : 
    5201        37665 :             ControlTemp = this->setRadiantSystemControlTemperature(state, controlType);
    5202              : 
    5203        37665 :             if (ControlTemp < OffTemp) { // HEATING MODE
    5204              : 
    5205        29353 :                 this->opMode = OpMode::Heat;
    5206              : 
    5207        29353 :                 HeatFrac = this->calculateOperationalFraction(OffTemp, ControlTemp, this->ThrottlRange);
    5208              : 
    5209              :                 // Set the heat source for the low temperature electric radiant system
    5210        58706 :                 for (RadSurfNum = 1; RadSurfNum <= this->NumOfSurfaces; ++RadSurfNum) {
    5211        29353 :                     SurfNum = this->SurfacePtr(RadSurfNum);
    5212        29353 :                     state.dataHeatBalFanSys->QRadSysSource(SurfNum) = HeatFrac * this->MaxElecPower * this->SurfaceFrac(RadSurfNum);
    5213        29353 :                     if (Surface(SurfNum).ExtBoundCond > 0 && Surface(SurfNum).ExtBoundCond != SurfNum) {
    5214            0 :                         state.dataHeatBalFanSys->QRadSysSource(Surface(SurfNum).ExtBoundCond) =
    5215            0 :                             state.dataHeatBalFanSys->QRadSysSource(SurfNum); // Also set the other side of an interzone
    5216              :                     }
    5217              :                 }
    5218              : 
    5219              :                 // Now "simulate" the system by recalculating the heat balances
    5220        29353 :                 HeatBalanceSurfaceManager::CalcHeatBalanceOutsideSurf(state, ZoneNum);
    5221        29353 :                 HeatBalanceSurfaceManager::CalcHeatBalanceInsideSurf(state, ZoneNum);
    5222              : 
    5223        29353 :                 LoadMet = state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state) - this->ZeroLTRSourceSumHATsurf;
    5224              : 
    5225              :             } else { //  OFF or COOLING MODE (not allowed for an electric low temperature radiant system), turn it off
    5226              : 
    5227        16624 :                 for (RadSurfNum = 1; RadSurfNum <= this->NumOfSurfaces; ++RadSurfNum) {
    5228         8312 :                     SurfNum = this->SurfacePtr(RadSurfNum);
    5229         8312 :                     state.dataHeatBalFanSys->QRadSysSource(SurfNum) = 0.0;
    5230         8312 :                     if (Surface(SurfNum).ExtBoundCond > 0 && Surface(SurfNum).ExtBoundCond != SurfNum) {
    5231            0 :                         state.dataHeatBalFanSys->QRadSysSource(Surface(SurfNum).ExtBoundCond) = 0.0; // Also zero the other side of an interzone
    5232              :                     }
    5233              :                 }
    5234              :             }
    5235              :         }
    5236        79059 :     }
    5237              : 
    5238       666848 :     void RadiantSystemBaseData::updateLowTemperatureRadiantSystemSurfaces(EnergyPlusData &state)
    5239              :     {
    5240              : 
    5241              :         // The purpose of this routine is to update the average heat source/sink for a particular system over the various system time
    5242              :         // steps that make up the zone time step.  For hydronic systems, this routine must also set the outlet water conditions.
    5243              :         // For the source/sink average update, if the system time step elapsed is still what it used to be, then either we are still
    5244              :         // iterating orwe had to go back and shorten the time step.  As a result, we have to subtract out the previous value that we
    5245              :         // added.  If the system time step elapsed is different, then we just need to add the new values to the running average.
    5246              : 
    5247       666848 :         Real64 TimeStepSys = state.dataHVACGlobal->TimeStepSys;
    5248       666848 :         Real64 SysTimeElapsed = state.dataHVACGlobal->SysTimeElapsed;
    5249       666848 :         Real64 TimeStepZone = state.dataGlobal->TimeStepZone;
    5250              : 
    5251      1373860 :         for (int radSurfNum = 1; radSurfNum <= this->NumOfSurfaces; ++radSurfNum) {
    5252              : 
    5253       707012 :             int surfNum = this->SurfacePtr(radSurfNum);
    5254              : 
    5255       707012 :             if (this->LastSysTimeElapsed == SysTimeElapsed) {
    5256              :                 // Still iterating or reducing system time step, so subtract old values which were
    5257              :                 // not valid
    5258       649209 :                 this->QRadSysSrcAvg(radSurfNum) -= this->LastQRadSysSrc(radSurfNum) * this->LastTimeStepSys / TimeStepZone;
    5259              :             }
    5260              : 
    5261              :             // Update the running average and the "last" values with the current values of the appropriate variables
    5262       707012 :             this->QRadSysSrcAvg(radSurfNum) += state.dataHeatBalFanSys->QRadSysSource(surfNum) * TimeStepSys / TimeStepZone;
    5263       707012 :             this->LastQRadSysSrc(radSurfNum) = state.dataHeatBalFanSys->QRadSysSource(surfNum);
    5264              :         }
    5265       666848 :         this->LastSysTimeElapsed = SysTimeElapsed;
    5266       666848 :         this->LastTimeStepSys = TimeStepSys;
    5267       666848 :     }
    5268              : 
    5269       366056 :     void VariableFlowRadiantSystemData::updateLowTemperatureRadiantSystem(EnergyPlusData &state)
    5270              :     {
    5271              : 
    5272              :         // Using/Aliasing
    5273              :         using PlantUtilities::SafeCopyPlantNode;
    5274              :         using PlantUtilities::SetComponentFlowRate;
    5275              : 
    5276              :         // SUBROUTINE PARAMETER DEFINITIONS:
    5277       366056 :         constexpr std::string_view RoutineName("UpdateVariableFlowSystem");
    5278              : 
    5279              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    5280              :         Real64 cpWater;       // Specific heat of water
    5281              :         int waterInletNode;   // Node number for the water side inlet of the radiant system
    5282              :         Real64 waterMassFlow; // Flow rate of water in the radiant system
    5283              :         int waterOutletNode;  // Node number for the water side outlet of the radiant system
    5284              : 
    5285       366056 :         auto &Zone = state.dataHeatBal->Zone;
    5286       366056 :         auto &Node = state.dataLoopNodes->Node;
    5287              : 
    5288              :         // For a hydronic system, calculate the water side outlet conditions and set the
    5289              :         // appropriate conditions on the correct HVAC node.
    5290              : 
    5291              :         // First sum up all of the heat sources/sinks associated with this system
    5292       366056 :         Real64 TotalHeatSource(0.0); // Total heat source or sink for a particular radiant system (sum of all surface source/sinks)
    5293       772276 :         for (int radSurfNum = 1; radSurfNum <= this->NumOfSurfaces; ++radSurfNum) {
    5294       406220 :             TotalHeatSource += state.dataHeatBalFanSys->QRadSysSource(this->SurfacePtr(radSurfNum));
    5295              :         }
    5296       366056 :         TotalHeatSource *= double(Zone(this->ZonePtr).Multiplier * Zone(this->ZonePtr).ListMultiplier);
    5297              : 
    5298              :         // Update the heating side of things
    5299       366056 :         if (this->HeatingSystem) {
    5300              : 
    5301       366010 :             waterInletNode = this->HotWaterInNode;
    5302       366010 :             waterOutletNode = this->HotWaterOutNode;
    5303       366010 :             waterMassFlow = Node(waterInletNode).MassFlowRate;
    5304              : 
    5305       366010 :             cpWater = state.dataPlnt->PlantLoop(this->HWPlantLoc.loopNum).glycol->getSpecificHeat(state, Node(waterInletNode).Temp, RoutineName);
    5306              : 
    5307       366010 :             if (this->opMode == OpMode::Heat) {
    5308       151202 :                 if ((cpWater > 0.0) && (waterMassFlow > 0.0)) {
    5309       151196 :                     SafeCopyPlantNode(state, waterInletNode, waterOutletNode);
    5310       151196 :                     Node(waterOutletNode).Temp = Node(waterInletNode).Temp - TotalHeatSource / waterMassFlow / cpWater;
    5311              :                 } else {
    5312            6 :                     SafeCopyPlantNode(state, waterInletNode, waterOutletNode);
    5313              :                 }
    5314              : 
    5315              :             } else { // OpMode::Cool or not on
    5316       214808 :                 SafeCopyPlantNode(state, waterInletNode, waterOutletNode);
    5317              :             }
    5318              : 
    5319       366010 :             this->checkForOutOfRangeTemperatureResult(state, Node(waterOutletNode).Temp, Node(waterInletNode).Temp);
    5320              :         }
    5321              : 
    5322       366056 :         if (this->CoolingSystem) {
    5323              : 
    5324       351205 :             waterInletNode = this->ColdWaterInNode;
    5325       351205 :             waterOutletNode = this->ColdWaterOutNode;
    5326       351205 :             waterMassFlow = Node(waterInletNode).MassFlowRate;
    5327              : 
    5328       351205 :             cpWater = state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).glycol->getSpecificHeat(state, Node(waterInletNode).Temp, RoutineName);
    5329              : 
    5330       351205 :             if (this->opMode == OpMode::Cool) {
    5331       119112 :                 if ((cpWater > 0.0) && (waterMassFlow > 0.0)) {
    5332       119082 :                     SafeCopyPlantNode(state, waterInletNode, waterOutletNode);
    5333       119082 :                     Node(waterOutletNode).Temp = Node(waterInletNode).Temp - TotalHeatSource / waterMassFlow / cpWater;
    5334              :                 } else {
    5335           30 :                     SafeCopyPlantNode(state, waterInletNode, waterOutletNode);
    5336              :                 }
    5337              : 
    5338              :             } else { // OpMode::Heat or not on
    5339       232093 :                 SafeCopyPlantNode(state, waterInletNode, waterOutletNode);
    5340              :             }
    5341              : 
    5342       351205 :             this->checkForOutOfRangeTemperatureResult(state, Node(waterOutletNode).Temp, Node(waterInletNode).Temp);
    5343              :         }
    5344       366056 :     }
    5345              : 
    5346       221733 :     void ConstantFlowRadiantSystemData::updateLowTemperatureRadiantSystem(EnergyPlusData &state)
    5347              :     {
    5348              : 
    5349              :         // Using/Aliasing
    5350              :         using PlantUtilities::SafeCopyPlantNode;
    5351              :         using PlantUtilities::SetComponentFlowRate;
    5352              : 
    5353              :         Real64 bypassMassFlow; // Local bypass for a constant flow radiant system (could have recirculation and/or bypass)
    5354              :         int waterInletNode;    // Node number for the water side inlet of the radiant system
    5355              :         int waterOutletNode;   // Node number for the water side outlet of the radiant system
    5356              : 
    5357              :         // For a constant flow system, calculate the water side outlet conditions
    5358              :         // and set the appropriate conditions on the correct HVAC node.  This may
    5359              :         // require mixing if the main system does not provide all of the flow that
    5360              :         // the local radiant system circulates.
    5361              : 
    5362              :         // Update the heating side of things
    5363       221733 :         if (this->HeatingSystem) {
    5364              : 
    5365       221732 :             waterInletNode = this->HotWaterInNode;
    5366       221732 :             waterOutletNode = this->HotWaterOutNode;
    5367       221732 :             SafeCopyPlantNode(state, waterInletNode, waterOutletNode);
    5368              : 
    5369       221732 :             if (this->opMode == OpMode::Heat) {
    5370              : 
    5371              :                 // Leave the inlet and outlet flow alone (if high enough) and perform a bypass if more flow than needed
    5372        69273 :                 if (state.dataLoopNodes->Node(waterInletNode).MassFlowRate <= this->WaterInjectionRate) {
    5373              :                     // Note that the water injection rate has already been restricted to the maximum available flow
    5374            0 :                     state.dataLoopNodes->Node(waterOutletNode).Temp = this->WaterOutletTemp;
    5375              :                 } else {
    5376              :                     // Loop is providing more flow than needed so perform a local bypass and
    5377              :                     // mix the flows to obtain the proper outlet temperature.  In this case,
    5378              :                     // the mass flow rates on the loop are left alone and the outlet temperature
    5379              :                     // is calculated from a simple steady-steady, steady-flow energy balance.
    5380        69273 :                     bypassMassFlow = state.dataLoopNodes->Node(waterInletNode).MassFlowRate - this->WaterInjectionRate;
    5381        69273 :                     state.dataLoopNodes->Node(waterOutletNode).Temp =
    5382        69273 :                         ((bypassMassFlow * state.dataLoopNodes->Node(waterInletNode).Temp) + (this->WaterInjectionRate * this->WaterOutletTemp)) /
    5383        69273 :                         (state.dataLoopNodes->Node(waterOutletNode).MassFlowRate);
    5384              :                 }
    5385              :             }
    5386       665196 :             this->checkForOutOfRangeTemperatureResult(
    5387       221732 :                 state, state.dataLoopNodes->Node(waterOutletNode).Temp, state.dataLoopNodes->Node(waterInletNode).Temp);
    5388              :         }
    5389              : 
    5390       221733 :         if (this->CoolingSystem) {
    5391              : 
    5392       208097 :             waterInletNode = this->ColdWaterInNode;
    5393       208097 :             waterOutletNode = this->ColdWaterOutNode;
    5394       208097 :             SafeCopyPlantNode(state, waterInletNode, waterOutletNode);
    5395              : 
    5396       208097 :             if (this->opMode == OpMode::Cool) {
    5397              : 
    5398       104902 :                 if (state.dataLoopNodes->Node(waterInletNode).MassFlowRate <= this->WaterInjectionRate) {
    5399              :                     // Note that the water injection rate has already been restricted to the maximum available flow
    5400              : 
    5401        20566 :                     state.dataLoopNodes->Node(waterOutletNode).Temp = this->WaterOutletTemp;
    5402              :                 } else {
    5403              :                     // Loop is providing more flow than needed so perform a local bypass and
    5404              :                     // mix the flows to obtain the proper outlet temperature.  In this case,
    5405              :                     // the mass flow rates on the loop are left alone and the outlet temperature
    5406              :                     // is calculated from a simple steady-steady, steady-flow energy balance.
    5407        84336 :                     bypassMassFlow = state.dataLoopNodes->Node(waterInletNode).MassFlowRate - this->WaterInjectionRate;
    5408        84336 :                     state.dataLoopNodes->Node(waterOutletNode).Temp =
    5409        84336 :                         ((bypassMassFlow * state.dataLoopNodes->Node(waterInletNode).Temp) + (this->WaterInjectionRate * this->WaterOutletTemp)) /
    5410        84336 :                         (state.dataLoopNodes->Node(waterOutletNode).MassFlowRate);
    5411              :                 }
    5412              : 
    5413       314706 :                 this->checkForOutOfRangeTemperatureResult(
    5414       104902 :                     state, state.dataLoopNodes->Node(waterOutletNode).Temp, state.dataLoopNodes->Node(waterInletNode).Temp);
    5415              :             }
    5416              :         }
    5417       221733 :     }
    5418              : 
    5419        79059 :     void ElectricRadiantSystemData::updateLowTemperatureRadiantSystem([[maybe_unused]] EnergyPlusData &state)
    5420              :     { // Dummy routine: no updates are needed for electric radiant systems
    5421        79059 :     }
    5422              : 
    5423      1043849 :     void HydronicSystemBaseData::checkForOutOfRangeTemperatureResult(EnergyPlusData &state, Real64 const outletTemp, Real64 const inletTemp)
    5424              :     {
    5425              : 
    5426              :         // SUBROUTINE INFORMATION:
    5427              :         //       AUTHOR         B. Griffith
    5428              :         //       DATE WRITTEN   March 2013
    5429              : 
    5430              :         // PURPOSE OF THIS SUBROUTINE:
    5431              :         // check for crazy, out of range temperature results for fluid leaving radiant system
    5432              : 
    5433              :         // Using/Aliasing
    5434              : 
    5435      1043849 :         Real64 constexpr upperRangeLimit(500.0);  // high error trigger limit for when model is not working
    5436      1043849 :         Real64 constexpr lowerRangeLimit(-300.0); // Low error trigger limit for when model is not working
    5437              : 
    5438      1043849 :         if (outletTemp < lowerRangeLimit) {
    5439            0 :             state.dataLowTempRadSys->warnTooLow = true;
    5440              :         }
    5441              : 
    5442      1043849 :         if (outletTemp > upperRangeLimit) {
    5443            0 :             state.dataLowTempRadSys->warnTooHigh = true;
    5444              :         }
    5445              : 
    5446      1043849 :         if (state.dataLowTempRadSys->warnTooLow || state.dataLowTempRadSys->warnTooHigh) {
    5447            0 :             if (state.dataLowTempRadSys->warnTooLow) {
    5448            0 :                 if (this->OutRangeLoErrorCount == 0) {
    5449            0 :                     ShowSevereMessage(state, "UpdateLowTempRadiantSystem: model result for fluid outlet temperature is not physical.");
    5450            0 :                     ShowContinueError(state, format("Occurs for radiant system name = {}", this->Name));
    5451            0 :                     ShowContinueError(state, format("Calculated radiant system outlet temperature = {:.3R} [C]", outletTemp));
    5452            0 :                     ShowContinueError(state, format("Radiant system inlet temperature = {:.3R} [C]", inletTemp));
    5453            0 :                     ShowContinueError(
    5454              :                         state, "A possible cause is that the materials used in the internal source construction are not compatible with the model.");
    5455              :                 }
    5456            0 :                 ShowRecurringSevereErrorAtEnd(
    5457              :                     state,
    5458            0 :                     "UpdateLowTempRadiantSystem: Detected low out of range outlet temperature result for radiant system name =" + this->Name,
    5459            0 :                     this->OutRangeLoErrorCount,
    5460              :                     outletTemp,
    5461              :                     outletTemp);
    5462              :             }
    5463              : 
    5464            0 :             if (state.dataLowTempRadSys->warnTooHigh) {
    5465            0 :                 if (this->OutRangeHiErrorCount == 0) {
    5466            0 :                     ShowSevereMessage(state, "UpdateLowTempRadiantSystem: model result for fluid outlet temperature is not physical.");
    5467            0 :                     ShowContinueError(state, format("Occurs for radiant system name = {}", this->Name));
    5468            0 :                     ShowContinueError(state, format("Calculated radiant system outlet temperature = {:.3R} [C]", outletTemp));
    5469            0 :                     ShowContinueError(state, format("Radiant system inlet temperature = {:.3R} [C]", inletTemp));
    5470            0 :                     ShowContinueError(
    5471              :                         state, "A possible cause is that the materials used in the internal source construction are not compatible with the model.");
    5472              :                 }
    5473            0 :                 ShowRecurringSevereErrorAtEnd(
    5474              :                     state,
    5475            0 :                     "UpdateLowTempRadiantSystem: Detected high out of range outlet temperature result radiant system name =" + this->Name,
    5476            0 :                     this->OutRangeHiErrorCount,
    5477              :                     outletTemp,
    5478              :                     outletTemp);
    5479              :             }
    5480              :         }
    5481      1043849 :     }
    5482              : 
    5483       610133 :     Real64 RadiantSystemBaseData::setRadiantSystemControlTemperature(EnergyPlusData &state, CtrlType TempControlType)
    5484              :     {
    5485       610133 :         auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(this->ZonePtr);
    5486       610133 :         switch (TempControlType) {
    5487       472548 :         case CtrlType::MAT:
    5488       472548 :             return thisZoneHB.MAT;
    5489        24689 :         case CtrlType::MRT:
    5490        24689 :             return thisZoneHB.MRT;
    5491        24733 :         case CtrlType::Operative:
    5492        24733 :             return 0.5 * (thisZoneHB.MAT + thisZoneHB.MRT);
    5493        16292 :         case CtrlType::ODB:
    5494        16292 :             return state.dataHeatBal->Zone(this->ZonePtr).OutDryBulbTemp;
    5495        14123 :         case CtrlType::OWB:
    5496        14123 :             return state.dataHeatBal->Zone(this->ZonePtr).OutWetBulbTemp;
    5497        15662 :         case CtrlType::SurfFaceTemp:
    5498        15662 :             return state.dataHeatBalSurf->SurfTempIn(this->SurfacePtr(1)); // Grabs the inside face temperature of the first surface in the list
    5499        15662 :         case CtrlType::SurfIntTemp:
    5500        15662 :             return state.dataHeatBalSurf->SurfTempUserLoc(
    5501        15662 :                 this->SurfacePtr(1)); // Grabs the temperature inside the slab at the location specified by the user
    5502        26424 :         case CtrlType::RunningMeanODB:
    5503        26424 :             return this->todayRunningMeanOutdoorDryBulbTemperature;
    5504            0 :         default:
    5505            0 :             ShowSevereError(state, format("Illegal control type in low temperature radiant system or it's design object: {}", this->Name));
    5506            0 :             ShowFatalError(state, "Preceding condition causes termination.");
    5507            0 :             return 0.0; // hush the compiler
    5508              :         }
    5509              :     }
    5510              : 
    5511              :     Real64
    5512       320308 :     RadiantSystemBaseData::calculateOperationalFraction(Real64 const offTemperature, Real64 const controlTemperature, Real64 const throttlingRange)
    5513              :     {
    5514       320308 :         Real64 temperatureDifference = std::abs(offTemperature - controlTemperature);
    5515       320308 :         if (temperatureDifference <= 0.0) {
    5516            0 :             return 0.0; // No temperature difference--turn things off (set to zero); technically shouldn't happen
    5517       320308 :         } else if (throttlingRange < 0.001) {
    5518         8452 :             return 1.0; // Throttling range is essentially zero and there is a temperature difference--turn it full on
    5519              :         } else {
    5520              :             // Temperature difference is non-zero and less than the throttling range--calculate the operation fraction, but limit to a maximum of 1.0
    5521       311856 :             return min(temperatureDifference / throttlingRange, 1.0);
    5522              :         }
    5523              :     }
    5524              : 
    5525       747256 :     Real64 RadiantSystemBaseData::setOffTemperatureLowTemperatureRadiantSystem(EnergyPlusData &state,
    5526              :                                                                                Sched::Schedule const *sched,
    5527              :                                                                                const Real64 throttlingRange,
    5528              :                                                                                SetpointType setpointType)
    5529              :     {
    5530       747256 :         Real64 scheduleValue = sched->getCurrentVal();
    5531       747256 :         switch (setpointType) {
    5532       700162 :         case SetpointType::HalfFlowPower:
    5533       700162 :             return scheduleValue + 0.5 * throttlingRange;
    5534        47094 :         case SetpointType::ZeroFlowPower:
    5535        47094 :             return scheduleValue;
    5536            0 :         default:
    5537            0 :             ShowSevereError(state, format("Illegal setpoint type in low temperature radiant system: {}", this->Name));
    5538            0 :             ShowFatalError(state, "Preceding condition causes termination.");
    5539            0 :             return scheduleValue + 0.5 * throttlingRange; // hush the compiler
    5540              :         }
    5541              :     }
    5542              : 
    5543              :     Real64
    5544       507813 :     HydronicSystemBaseData::calculateHXEffectivenessTerm(EnergyPlusData &state,
    5545              :                                                          int const SurfNum,          // Surface number for this particular part of the radiant system
    5546              :                                                          Real64 const Temperature,   // Temperature of water entering the radiant system, in C
    5547              :                                                          Real64 const WaterMassFlow, // Mass flow rate of water in the radiant system, in kg/s
    5548              :                                                          Real64 const FlowFraction,  // Mass flow rate fraction for this surface in the radiant system
    5549              :                                                          Real64 const NumCircs,      // Number of fluid circuits in this surface
    5550              :                                                          int const DesignObjPtr,     // Design Object Pointer
    5551              :                                                          SystemType const typeOfRadiantSystem)
    5552              :     {
    5553              : 
    5554              :         // SUBROUTINE INFORMATION:
    5555              :         //       AUTHOR         Rick Strand
    5556              :         //       DATE WRITTEN   December 2000
    5557              : 
    5558              :         // PURPOSE OF THIS SUBROUTINE:
    5559              :         // This subroutine calculates the radiant system "heat exchanger"
    5560              :         // effectiveness term.  This is equal to the mass flow rate of water
    5561              :         // times the specific heat of water times the effectiveness of
    5562              :         // the heat exchanger (radiant system "coil").
    5563              : 
    5564              :         // METHODOLOGY EMPLOYED:
    5565              :         // Assumes that the only real heat transfer term that we have to
    5566              :         // deal with is the convection from the water to the tube.  The
    5567              :         // other assumptions are that the tube inside surface temperature
    5568              :         // is equal to the "source location temperature" and that it is
    5569              :         // a CONSTANT throughout the radiant system.  This is to make
    5570              :         // the problem more tractable and to fit with other system assumptions
    5571              :         // that were made elsewhere in the radiant system model.
    5572              : 
    5573              :         // REFERENCES:
    5574              :         // Property data for water shown below as parameters taken from
    5575              :         //   Incropera and DeWitt, Introduction to Heat Transfer, Table A.6.
    5576              :         // Heat exchanger information also from Incropera and DeWitt.
    5577              :         // Code based loosely on code from IBLAST program (research version)
    5578              : 
    5579              :         // Return value
    5580              :         Real64 calculateHXEffectivenessTerm;
    5581              : 
    5582              :         // SUBROUTINE PARAMETER DEFINITIONS:
    5583       507813 :         Real64 constexpr MaxLaminarRe(2300.0); // Maximum Reynolds number for laminar flow
    5584       507813 :         int constexpr NumOfPropDivisions(13);
    5585       507813 :         Real64 constexpr MaxExpPower(50.0); // Maximum power after which EXP argument would be zero for DP variables
    5586              :         Array1D<Real64> Temps(NumOfPropDivisions,
    5587       507813 :                               {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
    5588              :         Array1D<Real64> Mu(NumOfPropDivisions,
    5589              :                            {0.001652,
    5590              :                             0.001422,
    5591              :                             0.001225,
    5592              :                             0.00108,
    5593              :                             0.000959,
    5594              :                             0.000855,
    5595              :                             0.000769,
    5596              :                             0.000695,
    5597              :                             0.000631,
    5598              :                             0.000577,
    5599              :                             0.000528,
    5600              :                             0.000489,
    5601       507813 :                             0.000453}); // Viscosity, in Ns/m2
    5602              :         Array1D<Real64> Conductivity(
    5603       507813 :             NumOfPropDivisions, {0.574, 0.582, 0.590, 0.598, 0.606, 0.613, 0.620, 0.628, 0.634, 0.640, 0.645, 0.650, 0.656}); // Conductivity, in W/mK
    5604              :         Array1D<Real64> Pr(NumOfPropDivisions,
    5605       507813 :                            {12.22, 10.26, 8.81, 7.56, 6.62, 5.83, 5.20, 4.62, 4.16, 3.77, 3.42, 3.15, 2.88}); // Prandtl number (dimensionless)
    5606       507813 :         constexpr std::string_view RoutineName("calculateHXEffectivenessTerm");
    5607              : 
    5608              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    5609              :         int Index;
    5610              :         Real64 InterpFrac;
    5611              :         Real64 NuD;
    5612              :         Real64 ReD;
    5613              :         Real64 NTU;
    5614       507813 :         Real64 CpWater(0.0);
    5615              :         Real64 Kactual;
    5616              :         Real64 MUactual;
    5617              :         Real64 PRactual;
    5618              :         Real64 Eff; // HX effectiveness
    5619              : 
    5620       507813 :         FluidToSlabHeatTransferType FluidToSlabHeatTransfer(FluidToSlabHeatTransferType::ConvectionOnly);
    5621       507813 :         Real64 TubeDiameterInner(0.0); // inside tube diameter for embedded tubing (meters)
    5622       507813 :         Real64 TubeDiameterOuter(0.0); // outside tube diameter for embedded tubing (meters)
    5623              : 
    5624       507813 :         if (typeOfRadiantSystem == SystemType::Hydronic) {
    5625              :             VarFlowRadDesignData variableFlowDesignDataObject{
    5626       320726 :                 state.dataLowTempRadSys->HydronicRadiantSysDesign(DesignObjPtr)}; // Contains the data for variable flow hydronic systems
    5627       320726 :             FluidToSlabHeatTransfer = variableFlowDesignDataObject.FluidToSlabHeatTransfer;
    5628       320726 :             TubeDiameterInner = variableFlowDesignDataObject.TubeDiameterInner;
    5629       320726 :             TubeDiameterOuter = variableFlowDesignDataObject.TubeDiameterOuter;
    5630       320726 :         }
    5631       507813 :         if (typeOfRadiantSystem == SystemType::ConstantFlow) {
    5632              :             ConstantFlowRadDesignData constantFlowDesignDataObject{
    5633       187087 :                 state.dataLowTempRadSys->CflowRadiantSysDesign(DesignObjPtr)}; // Contains the data for constant flow hydronic systems
    5634       187087 :             FluidToSlabHeatTransfer = constantFlowDesignDataObject.FluidToSlabHeatTransfer;
    5635       187087 :             TubeDiameterInner = constantFlowDesignDataObject.TubeDiameterInner;
    5636       187087 :             TubeDiameterOuter = constantFlowDesignDataObject.TubeDiameterOuter;
    5637       187087 :         }
    5638              : 
    5639              :         // First find out where we are in the range of temperatures
    5640       507813 :         Index = 1;
    5641      3642347 :         while (Index <= NumOfPropDivisions) {
    5642      3642347 :             if (Temperature < Temps(Index)) {
    5643       507813 :                 break; // DO loop
    5644              :             }
    5645      3134534 :             ++Index;
    5646              :         }
    5647              : 
    5648              :         // Initialize thermal properties of water
    5649       507813 :         if (Index == 1) {
    5650            0 :             MUactual = Mu(Index);
    5651            0 :             Kactual = Conductivity(Index);
    5652            0 :             PRactual = Pr(Index);
    5653       507813 :         } else if (Index > NumOfPropDivisions) {
    5654            0 :             Index = NumOfPropDivisions;
    5655            0 :             MUactual = Mu(Index);
    5656            0 :             Kactual = Conductivity(Index);
    5657            0 :             PRactual = Pr(Index);
    5658              :         } else {
    5659       507813 :             InterpFrac = (Temperature - Temps(Index - 1)) / (Temps(Index) - Temps(Index - 1));
    5660       507813 :             MUactual = Mu(Index - 1) + InterpFrac * (Mu(Index) - Mu(Index - 1));
    5661       507813 :             Kactual = Conductivity(Index - 1) + InterpFrac * (Conductivity(Index) - Conductivity(Index - 1));
    5662       507813 :             PRactual = Pr(Index - 1) + InterpFrac * (Pr(Index) - Pr(Index - 1));
    5663              :         }
    5664              :         // arguments are glycol name, temperature, and concentration
    5665       507813 :         switch (this->opMode) {
    5666       238238 :         case OpMode::Heat: {
    5667       238238 :             CpWater = state.dataPlnt->PlantLoop(this->HWPlantLoc.loopNum).glycol->getSpecificHeat(state, Temperature, RoutineName);
    5668       238238 :         } break;
    5669       269575 :         case OpMode::Cool: {
    5670       269575 :             CpWater = state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).glycol->getSpecificHeat(state, Temperature, RoutineName);
    5671       269575 :         } break;
    5672            0 :         default: {
    5673            0 :             assert(false);
    5674              :         } break;
    5675              :         }
    5676              : 
    5677              :         // Calculate NTU based on the heat transfer model
    5678              : 
    5679       507813 :         if (FluidToSlabHeatTransfer == FluidToSlabHeatTransferType::ISOStandard) {
    5680              : 
    5681        52342 :             Real64 U = this->calculateUFromISOStandard(state, SurfNum, WaterMassFlow * FlowFraction, typeOfRadiantSystem, DesignObjPtr);
    5682              : 
    5683              :             // Calculate the NTU parameter
    5684              :             // NTU = UA/[(Mdot*Cp)min]
    5685              :             // where: U = h (convection coefficient) and h = (k)(Nu)/D
    5686              :             //        A = Constant::Pi()*D*TubeLength
    5687        52342 :             NTU = U * Constant::Pi * TubeDiameterOuter * this->TubeLength / (WaterMassFlow * CpWater); // FlowFraction cancels out here
    5688              :         } else { // (this->FluidToSlabHeatTransfer == FluidToSlabHeatTransferTypes::ConvectionOnly)
    5689              : 
    5690              :             // Calculate the Reynold's number from RE=(4*Mdot)/(Pi*Mu*Diameter)
    5691       455471 :             ReD = 4.0 * WaterMassFlow * FlowFraction / (Constant::Pi * MUactual * TubeDiameterInner * NumCircs);
    5692              : 
    5693              :             // Calculate the Nusselt number based on what flow regime one is in
    5694       455471 :             if (ReD >= MaxLaminarRe) { // Turbulent flow --> use Colburn equation
    5695              : 
    5696       432239 :                 NuD = 0.023 * std::pow(ReD, 0.8) * std::pow(PRactual, 1.0 / 3.0);
    5697              : 
    5698              :             } else { // Laminar flow --> use constant surface temperature relation
    5699              : 
    5700        23232 :                 NuD = 3.66;
    5701              :             }
    5702              : 
    5703              :             // Calculate the NTU parameter
    5704              :             // NTU = UA/[(Mdot*Cp)min]
    5705              :             // where: U = h (convection coefficient) and h = (k)(Nu)/D
    5706              :             //        A = Pi*D*TubeLength
    5707       455471 :             NTU = Constant::Pi * Kactual * NuD * this->TubeLength / (WaterMassFlow * CpWater); // FlowFraction cancels out here
    5708              :         }
    5709              : 
    5710              :         // Calculate Epsilon*MassFlowRate*Cp
    5711       507813 :         if (NTU > MaxExpPower) {
    5712       412748 :             Eff = 1.0;
    5713       412748 :             calculateHXEffectivenessTerm = FlowFraction * WaterMassFlow * CpWater;
    5714              :         } else {
    5715        95065 :             Eff = 1.0 - std::exp(-NTU);
    5716        95065 :             calculateHXEffectivenessTerm = Eff * FlowFraction * WaterMassFlow * CpWater;
    5717              :         }
    5718              : 
    5719       507813 :         return calculateHXEffectivenessTerm;
    5720       507813 :     }
    5721              : 
    5722        52342 :     Real64 HydronicSystemBaseData::calculateUFromISOStandard(EnergyPlusData &state,
    5723              :                                                              int const SurfNum,
    5724              :                                                              Real64 const WaterMassFlow,
    5725              :                                                              SystemType typeOfRadiantSystem,
    5726              :                                                              int const DesignObjPtr // Design Object Pointer
    5727              :     )
    5728              :     {
    5729              :         // Calculates the U-value for a pipe embedded in a radiant system using the information
    5730              :         // from ISO Standard 11855, Part 2 (2012): "Building environment design — Design, dimensioning,
    5731              :         // installation and control of embedded radiant heating and cooling systems — Part 2:
    5732              :         // Determination of the design heating and cooling capacity."  This looks exclusively at the heat transfer
    5733              :         // between the fluid and the inner side of the pipe and heat conduction through the pipe.  The remainder
    5734              :         // of the ISO calculation relates to the slab itself which is modeled using transient heat conduction here
    5735              :         // in EnergyPlus.
    5736              : 
    5737              :         // Return value
    5738              :         Real64 calculateUFromISOStandard;
    5739              : 
    5740        52342 :         int constructionNumber = state.dataSurface->Surface(SurfNum).Construction;
    5741              : 
    5742        52342 :         Real64 TubeDiameterOuter(0.0);
    5743        52342 :         Real64 TubeDiameterInner(0.0);
    5744        52342 :         Real64 TubeConductivity(0.0);
    5745              : 
    5746        52342 :         if (typeOfRadiantSystem == SystemType::Hydronic) {
    5747              :             VarFlowRadDesignData variableFlowDesignDataObject{
    5748        23077 :                 state.dataLowTempRadSys->HydronicRadiantSysDesign(DesignObjPtr)}; // Contains the data for variable flow hydronic systems
    5749        23077 :             TubeDiameterOuter = variableFlowDesignDataObject.TubeDiameterOuter;
    5750        23077 :             TubeDiameterInner = variableFlowDesignDataObject.TubeDiameterInner;
    5751        23077 :             TubeConductivity = variableFlowDesignDataObject.VarFlowTubeConductivity;
    5752        23077 :         }
    5753        52342 :         if (typeOfRadiantSystem == SystemType::ConstantFlow) {
    5754              :             ConstantFlowRadDesignData constantFlowDesignDataObject{
    5755        29265 :                 state.dataLowTempRadSys->CflowRadiantSysDesign(DesignObjPtr)}; // Contains the data for constant flow hydronic systems
    5756        29265 :             TubeDiameterOuter = constantFlowDesignDataObject.TubeDiameterOuter;
    5757        29265 :             TubeDiameterInner = constantFlowDesignDataObject.TubeDiameterInner;
    5758        29265 :             TubeConductivity = constantFlowDesignDataObject.ConstFlowTubeConductivity;
    5759        29265 :         }
    5760              : 
    5761              :         // Fluid resistance to heat transfer, assumes turbulent flow (Equation B5, p. 38 of ISO Standard 11855-2)
    5762        52342 :         Real64 distanceBetweenPipes = 2.0 * state.dataConstruction->Construct(constructionNumber).ThicknessPerpend;
    5763        52342 :         Real64 ratioDiameterToMassFlowLength = TubeDiameterInner / WaterMassFlow / this->TubeLength;
    5764        52342 :         Real64 rFluid = 0.125 / Constant::Pi * std::pow(distanceBetweenPipes, 0.13) * std::pow(ratioDiameterToMassFlowLength, 0.87);
    5765              : 
    5766              :         // Resistance to heat transfer (conduction through the piping material, Equation B6, p. 38 of ISO Standard 11855-2)
    5767        52342 :         Real64 rTube = 0.5 * distanceBetweenPipes * std::log(TubeDiameterOuter / TubeDiameterInner) / Constant::Pi / TubeConductivity;
    5768              : 
    5769        52342 :         calculateUFromISOStandard = 1.0 / (rFluid + rTube);
    5770              : 
    5771        52342 :         return calculateUFromISOStandard;
    5772              :     }
    5773              : 
    5774      2828212 :     void UpdateRadSysSourceValAvg(EnergyPlusData &state,
    5775              :                                   bool &LowTempRadSysOn) // .TRUE. if the radiant system has run this zone time step
    5776              :     {
    5777              : 
    5778              :         // SUBROUTINE INFORMATION:
    5779              :         //       AUTHOR         Rick Strand
    5780              :         //       DATE WRITTEN   November 2000
    5781              : 
    5782              :         // PURPOSE OF THIS SUBROUTINE:
    5783              :         // To transfer the average value of the heat source/sink over the entire
    5784              :         // zone time step back to the heat balance routines so that the heat
    5785              :         // balance algorithms can simulate one last time with the average source
    5786              :         // to maintain some reasonable amount of continuity and energy balance
    5787              :         // in the temperature and flux histories.
    5788              : 
    5789              :         // METHODOLOGY EMPLOYED:
    5790              :         // All of the record keeping for the average term is done in the Update
    5791              :         // routine so the only other thing that this subroutine does is check to
    5792              :         // see if the system was even on.  If any average term is non-zero, then
    5793              :         // one or more of the radiant systems was running.
    5794              : 
    5795              :         // SUBROUTINE PARAMETER DEFINITIONS:
    5796      2828212 :         Real64 constexpr CloseEnough(0.01); // Some arbitrarily small value to avoid zeros and numbers that are almost the same
    5797              : 
    5798              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    5799              :         int SurfNum; // DO loop counter for surface index
    5800              : 
    5801      2828212 :         LowTempRadSysOn = false;
    5802              : 
    5803              :         // If there are no radiant systems in this input file, just RETURN
    5804      2828212 :         if (state.dataLowTempRadSys->TotalNumOfRadSystems == 0) {
    5805      2740564 :             return;
    5806              :         }
    5807              : 
    5808              :         // Now check to see if anything is running and transfer information from the "average" variables to
    5809              :         // the array that will be used within the heat balance.
    5810        87648 :         state.dataHeatBalFanSys->QRadSysSource = 0.0; // Zero this out first
    5811       228201 :         for (int numRadSys = 1; numRadSys <= state.dataLowTempRadSys->NumOfHydrLowTempRadSys; ++numRadSys) {
    5812       140553 :             auto &thisLTR = state.dataLowTempRadSys->HydrRadSys(numRadSys);
    5813       298686 :             for (int numRadSurf = 1; numRadSurf <= thisLTR.NumOfSurfaces; ++numRadSurf) {
    5814       158133 :                 if (thisLTR.QRadSysSrcAvg(numRadSurf) != 0.0) {
    5815       113420 :                     LowTempRadSysOn = true;
    5816              :                 }
    5817       158133 :                 SurfNum = thisLTR.SurfacePtr(numRadSurf);
    5818       158133 :                 state.dataHeatBalFanSys->QRadSysSource(SurfNum) = thisLTR.QRadSysSrcAvg(numRadSurf);
    5819              :             }
    5820              :         }
    5821       169593 :         for (int numRadSys = 1; numRadSys <= state.dataLowTempRadSys->NumOfCFloLowTempRadSys; ++numRadSys) {
    5822        81945 :             auto &thisLTR = state.dataLowTempRadSys->CFloRadSys(numRadSys);
    5823       163890 :             for (int numRadSurf = 1; numRadSurf <= thisLTR.NumOfSurfaces; ++numRadSurf) {
    5824        81945 :                 if (thisLTR.QRadSysSrcAvg(numRadSurf) != 0.0) {
    5825        62968 :                     LowTempRadSysOn = true;
    5826              :                 }
    5827        81945 :                 SurfNum = thisLTR.SurfacePtr(numRadSurf);
    5828        81945 :                 state.dataHeatBalFanSys->QRadSysSource(SurfNum) = thisLTR.QRadSysSrcAvg(numRadSurf);
    5829              :             }
    5830              :         }
    5831       119985 :         for (int numRadSys = 1; numRadSys <= state.dataLowTempRadSys->NumOfElecLowTempRadSys; ++numRadSys) {
    5832        32337 :             auto &thisLTR = state.dataLowTempRadSys->ElecRadSys(numRadSys);
    5833        64674 :             for (int numRadSurf = 1; numRadSurf <= thisLTR.NumOfSurfaces; ++numRadSurf) {
    5834        32337 :                 if (thisLTR.QRadSysSrcAvg(numRadSurf) != 0.0) {
    5835        13256 :                     LowTempRadSysOn = true;
    5836              :                 }
    5837        32337 :                 SurfNum = thisLTR.SurfacePtr(numRadSurf);
    5838        32337 :                 state.dataHeatBalFanSys->QRadSysSource(SurfNum) = thisLTR.QRadSysSrcAvg(numRadSurf);
    5839              :             }
    5840              :         }
    5841              : 
    5842        87648 :         auto const &Surface = state.dataSurface->Surface;
    5843              : 
    5844              :         // For interzone surfaces, QRadSysSource was only updated for the "active" side.  The
    5845              :         // active side would have a non-zero value at this point.  If the numbers differ, then we have to manually update.
    5846      1929609 :         for (SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    5847      1841961 :             if (Surface(SurfNum).ExtBoundCond > 0 && Surface(SurfNum).ExtBoundCond != SurfNum) {
    5848       511686 :                 if (std::abs(state.dataHeatBalFanSys->QRadSysSource(SurfNum) -
    5849       511686 :                              state.dataHeatBalFanSys->QRadSysSource(Surface(SurfNum).ExtBoundCond)) > CloseEnough) { // numbers differ
    5850         2610 :                     if (std::abs(state.dataHeatBalFanSys->QRadSysSource(SurfNum)) >
    5851         1305 :                         std::abs(state.dataHeatBalFanSys->QRadSysSource(Surface(SurfNum).ExtBoundCond))) {
    5852         1305 :                         state.dataHeatBalFanSys->QRadSysSource(Surface(SurfNum).ExtBoundCond) = state.dataHeatBalFanSys->QRadSysSource(SurfNum);
    5853              :                     } else {
    5854            0 :                         state.dataHeatBalFanSys->QRadSysSource(SurfNum) = state.dataHeatBalFanSys->QRadSysSource(Surface(SurfNum).ExtBoundCond);
    5855              :                     }
    5856              :                 }
    5857              :             }
    5858              :         }
    5859              :     }
    5860              : 
    5861       366056 :     void VariableFlowRadiantSystemData::reportLowTemperatureRadiantSystem([[maybe_unused]] EnergyPlusData &state)
    5862              :     {
    5863              : 
    5864       366056 :         auto &Zone = state.dataHeatBal->Zone;
    5865              : 
    5866              :         // Using/Aliasing
    5867       366056 :         Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
    5868              : 
    5869       366056 :         Real64 totalRadSysPower(0.0); // Total source/sink power for the radiant system (sum of all surfaces of the system)
    5870              : 
    5871       772276 :         for (int radSurfNum = 1; radSurfNum <= this->NumOfSurfaces; ++radSurfNum) {
    5872       406220 :             totalRadSysPower += state.dataHeatBalFanSys->QRadSysSource(this->SurfacePtr(radSurfNum));
    5873              :         }
    5874              : 
    5875       366056 :         totalRadSysPower *= double(Zone(this->ZonePtr).Multiplier * Zone(this->ZonePtr).ListMultiplier);
    5876              : 
    5877       366056 :         this->HeatPower = 0.0;
    5878       366056 :         this->CoolPower = 0.0;
    5879              : 
    5880       366056 :         if (this->opMode == OpMode::Heat) {
    5881       151202 :             this->WaterInletTemp = state.dataLoopNodes->Node(this->HotWaterInNode).Temp;
    5882       151202 :             this->WaterOutletTemp = state.dataLoopNodes->Node(this->HotWaterOutNode).Temp;
    5883       151202 :             this->WaterMassFlowRate = state.dataLoopNodes->Node(this->HotWaterInNode).MassFlowRate;
    5884       151202 :             this->HeatPower = totalRadSysPower;
    5885              : 
    5886       214854 :         } else if (this->opMode == OpMode::Cool) {
    5887       119112 :             this->WaterInletTemp = state.dataLoopNodes->Node(this->ColdWaterInNode).Temp;
    5888       119112 :             this->WaterOutletTemp = state.dataLoopNodes->Node(this->ColdWaterOutNode).Temp;
    5889       119112 :             this->WaterMassFlowRate = state.dataLoopNodes->Node(this->ColdWaterInNode).MassFlowRate;
    5890       119112 :             this->CoolPower = -totalRadSysPower;
    5891              : 
    5892              :         } else { // Not Operating: Leave temperatures at previous values
    5893        95742 :             this->WaterMassFlowRate = 0.0;
    5894        95742 :             this->WaterOutletTemp = this->WaterInletTemp;
    5895              :         }
    5896              : 
    5897       366056 :         this->HeatEnergy = this->HeatPower * TimeStepSysSec;
    5898       366056 :         this->CoolEnergy = this->CoolPower * TimeStepSysSec;
    5899              : 
    5900       366056 :         if (this->CondCausedShutDown) {
    5901        32019 :             this->CondCausedTimeOff = TimeStepSysSec;
    5902              :         } else {
    5903       334037 :             this->CondCausedTimeOff = 0.0;
    5904              :         }
    5905       366056 :     }
    5906              : 
    5907       221733 :     void ConstantFlowRadiantSystemData::reportLowTemperatureRadiantSystem(EnergyPlusData &state)
    5908              :     {
    5909              : 
    5910       221733 :         auto &Zone = state.dataHeatBal->Zone;
    5911              : 
    5912              :         // Using/Aliasing
    5913       221733 :         Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
    5914              : 
    5915       221733 :         constexpr std::string_view routineName("ReportConstantFlowSystem");
    5916              :         Real64 cpFluid;               // Specific heat of the fluid in the radiant system
    5917       221733 :         Real64 totalRadSysPower(0.0); // Total source/sink power for the radiant system (sum of all surfaces of the system)
    5918              : 
    5919       443466 :         for (int radSurfNum = 1; radSurfNum <= this->NumOfSurfaces; ++radSurfNum) {
    5920       221733 :             totalRadSysPower += state.dataHeatBalFanSys->QRadSysSource(this->SurfacePtr(radSurfNum));
    5921              :         }
    5922              : 
    5923       221733 :         totalRadSysPower *= double(Zone(this->ZonePtr).Multiplier * Zone(this->ZonePtr).ListMultiplier);
    5924              : 
    5925       221733 :         this->HeatPower = 0.0;
    5926       221733 :         this->CoolPower = 0.0;
    5927              : 
    5928              :         // Note that temperatures have already been set as part of the simulation
    5929              :         // step.  So, they do not need to be calculated here except for the pump
    5930              :         // inlet temperature which was not calculated elsewhere.  If the system is
    5931              :         // not operating, leave the temperatures with their previous values but
    5932              :         // zero out the flow and power quantities (should have already been done
    5933              :         // in another routine, but just in case...).
    5934              : 
    5935       221733 :         if (this->opMode == OpMode::Heat) {
    5936        69273 :             cpFluid = state.dataPlnt->PlantLoop(this->HWPlantLoc.loopNum)
    5937        69273 :                           .glycol->getSpecificHeat(state, state.dataLoopNodes->Node(this->HotWaterInNode).Temp, routineName);
    5938              : 
    5939        69273 :             this->HeatPower = totalRadSysPower;
    5940        69273 :             if (this->PumpMassFlowRate > 0.0) {
    5941        69273 :                 this->PumpInletTemp = this->WaterInletTemp - (this->PumpHeattoFluid / (this->PumpMassFlowRate * cpFluid));
    5942              :             } else {
    5943            0 :                 this->PumpInletTemp = this->WaterInletTemp;
    5944              :             }
    5945              : 
    5946       152460 :         } else if (this->opMode == OpMode::Cool) {
    5947       104902 :             cpFluid = state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum)
    5948       104902 :                           .glycol->getSpecificHeat(state, state.dataLoopNodes->Node(this->ColdWaterInNode).Temp, routineName);
    5949              : 
    5950       104902 :             this->CoolPower = -totalRadSysPower;
    5951       104902 :             this->PumpInletTemp = this->WaterInletTemp - (this->PumpHeattoFluid / (this->PumpMassFlowRate * cpFluid));
    5952              : 
    5953              :         } else { // Not Operating
    5954        47558 :             this->WaterOutletTemp = this->WaterInletTemp;
    5955        47558 :             this->PumpInletTemp = this->WaterInletTemp;
    5956        47558 :             this->WaterMassFlowRate = 0.0;
    5957        47558 :             this->WaterInjectionRate = 0.0;
    5958        47558 :             this->WaterRecircRate = 0.0;
    5959        47558 :             this->HeatPower = 0.0;
    5960        47558 :             this->CoolPower = 0.0;
    5961        47558 :             this->PumpPower = 0.0;
    5962        47558 :             this->PumpMassFlowRate = 0.0;
    5963        47558 :             this->PumpHeattoFluid = 0.0;
    5964              :         }
    5965              : 
    5966       221733 :         this->HeatEnergy = this->HeatPower * TimeStepSysSec;
    5967       221733 :         this->CoolEnergy = this->CoolPower * TimeStepSysSec;
    5968       221733 :         this->PumpEnergy = this->PumpPower * TimeStepSysSec;
    5969       221733 :         this->PumpHeattoFluidEnergy = this->PumpHeattoFluid * TimeStepSysSec;
    5970              : 
    5971       221733 :         if (this->CondCausedShutDown) {
    5972        51257 :             this->CondCausedTimeOff = TimeStepSysSec;
    5973              :         } else {
    5974       170476 :             this->CondCausedTimeOff = 0.0;
    5975              :         }
    5976       221733 :     }
    5977              : 
    5978        79059 :     void ElectricRadiantSystemData::reportLowTemperatureRadiantSystem([[maybe_unused]] EnergyPlusData &state)
    5979              :     {
    5980              : 
    5981        79059 :         auto &Zone = state.dataHeatBal->Zone;
    5982        79059 :         Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
    5983              :         // Using/Aliasing
    5984        79059 :         Real64 totalRadSysPower(0.0); // Total source/sink power for the radiant system (sum of all surfaces of the system)
    5985              : 
    5986       158118 :         for (int radSurfNum = 1; radSurfNum <= this->NumOfSurfaces; ++radSurfNum) {
    5987        79059 :             totalRadSysPower += state.dataHeatBalFanSys->QRadSysSource(this->SurfacePtr(radSurfNum));
    5988              :         }
    5989              : 
    5990        79059 :         totalRadSysPower *= double(Zone(this->ZonePtr).Multiplier * Zone(this->ZonePtr).ListMultiplier);
    5991              : 
    5992        79059 :         this->ElecPower = totalRadSysPower;
    5993        79059 :         this->ElecEnergy = this->ElecPower * TimeStepSysSec;
    5994        79059 :         this->HeatPower = this->ElecPower;
    5995        79059 :         this->HeatEnergy = this->ElecEnergy;
    5996        79059 :     }
    5997              : 
    5998              : } // namespace LowTempRadiantSystem
    5999              : 
    6000              : } // namespace EnergyPlus
        

Generated by: LCOV version 2.0-1