LCOV - code coverage report
Current view: top level - EnergyPlus - LowTempRadiantSystem.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 2351 3067 76.7 %
Date: 2023-01-17 19:17:23 Functions: 34 34 100.0 %

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

Generated by: LCOV version 1.13