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

Generated by: LCOV version 2.0-1