LCOV - code coverage report
Current view: top level - EnergyPlus - LowTempRadiantSystem.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 2384 3100 76.9 %
Date: 2024-08-24 18:31:18 Functions: 32 32 100.0 %

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

Generated by: LCOV version 1.14