LCOV - code coverage report
Current view: top level - EnergyPlus - HighTempRadiantSystem.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 27.7 % 564 156
Test Date: 2025-05-22 16:09:37 Functions: 30.0 % 10 3

            Line data    Source code
       1              : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
       2              : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3              : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4              : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5              : // contributors. All rights reserved.
       6              : //
       7              : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8              : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9              : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10              : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11              : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12              : //
      13              : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14              : // provided that the following conditions are met:
      15              : //
      16              : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17              : //     conditions and the following disclaimer.
      18              : //
      19              : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20              : //     conditions and the following disclaimer in the documentation and/or other materials
      21              : //     provided with the distribution.
      22              : //
      23              : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24              : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25              : //     used to endorse or promote products derived from this software without specific prior
      26              : //     written permission.
      27              : //
      28              : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29              : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30              : //     reference solely to the software portion of its product, Licensee must refer to the
      31              : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32              : //     obtained under this License and may not use a different name for the software. Except as
      33              : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34              : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35              : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36              : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37              : //
      38              : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39              : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40              : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41              : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42              : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43              : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44              : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45              : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46              : // POSSIBILITY OF SUCH DAMAGE.
      47              : 
      48              : // C++ Headers
      49              : #include <cassert>
      50              : #include <cmath>
      51              : 
      52              : // ObjexxFCL Headers
      53              : #include <ObjexxFCL/Array.functions.hh>
      54              : 
      55              : // EnergyPlus Headers
      56              : #include <EnergyPlus/Autosizing/HeatingCapacitySizing.hh>
      57              : #include <EnergyPlus/Data/EnergyPlusData.hh>
      58              : #include <EnergyPlus/DataGlobalConstants.hh>
      59              : #include <EnergyPlus/DataHVACGlobals.hh>
      60              : #include <EnergyPlus/DataHeatBalFanSys.hh>
      61              : #include <EnergyPlus/DataHeatBalSurface.hh>
      62              : #include <EnergyPlus/DataHeatBalance.hh>
      63              : #include <EnergyPlus/DataIPShortCuts.hh>
      64              : #include <EnergyPlus/DataSurfaces.hh>
      65              : #include <EnergyPlus/DataViewFactorInformation.hh>
      66              : #include <EnergyPlus/DataZoneEquipment.hh>
      67              : #include <EnergyPlus/General.hh>
      68              : #include <EnergyPlus/GeneralRoutines.hh>
      69              : #include <EnergyPlus/HeatBalanceIntRadExchange.hh>
      70              : #include <EnergyPlus/HeatBalanceSurfaceManager.hh>
      71              : #include <EnergyPlus/HighTempRadiantSystem.hh>
      72              : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      73              : #include <EnergyPlus/OutputProcessor.hh>
      74              : #include <EnergyPlus/ScheduleManager.hh>
      75              : #include <EnergyPlus/UtilityRoutines.hh>
      76              : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
      77              : 
      78              : namespace EnergyPlus {
      79              : 
      80              : namespace HighTempRadiantSystem {
      81              : 
      82              :     // Module containing the routines dealing with the high temperature radiant systems
      83              : 
      84              :     // MODULE INFORMATION:
      85              :     //       AUTHOR         Rick Strand
      86              :     //       DATE WRITTEN   February 2001
      87              : 
      88              :     // PURPOSE OF THIS MODULE:
      89              :     // The purpose of this module is to simulate high temperature radiant systems.
      90              :     // It is the intention of this module to cover all types of high temperature
      91              :     // radiant systems (gas and electric)
      92              : 
      93              :     // METHODOLOGY EMPLOYED:
      94              :     // Based on work done in BLAST, the EnergyPlus low temperature radiant system
      95              :     // model, this model has similar inherent challenges that are similar to the
      96              :     // low temperature radiant system.  Because it is a system that directly
      97              :     // effects the surface heat balances, it must be a part of both the heat
      98              :     // balance routines and linked in with the HVAC system.
      99              :     // REFERENCES:
     100              :     // Building Systems Laboratory, BLAST User's Guide/Reference.
     101              :     // Maloney, Dan. 1987. "Development of a radiant heater model and the
     102              :     //   incorporation of thermal comfort considerations into the BLAST
     103              :     //   energy analysis program", M.S. thesis, University of Illinois at
     104              :     //   Urbana-Champaign (Dept. of Mechanical and Industrial Engineering).
     105              : 
     106              :     // MODULE PARAMETER DEFINITIONS:
     107              :     constexpr std::array<std::string_view, static_cast<int>(RadControlType::Num)> radControlTypeNamesUC = {"MEANAIRTEMPERATURE",
     108              :                                                                                                            "MEANRADIANTTEMPERATURE",
     109              :                                                                                                            "OPERATIVETEMPERATURE",
     110              :                                                                                                            "MEANAIRTEMPERATURESETPOINT",
     111              :                                                                                                            "MEANRADIANTTEMPERATURESETPOINT",
     112              :                                                                                                            "OPERATIVETEMPERATURESETPOINT"};
     113              : 
     114            0 :     void SimHighTempRadiantSystem(EnergyPlusData &state,
     115              :                                   std::string_view CompName,     // name of the low temperature radiant system
     116              :                                   bool const FirstHVACIteration, // TRUE if 1st HVAC simulation of system timestep
     117              :                                   Real64 &LoadMet,               // load met by the radiant system, in Watts
     118              :                                   int &CompIndex)
     119              :     {
     120              : 
     121              :         // SUBROUTINE INFORMATION:
     122              :         //       AUTHOR         Rick Strand
     123              :         //       DATE WRITTEN   February 2001
     124              : 
     125              :         // PURPOSE OF THIS SUBROUTINE:
     126              :         // This subroutine is the "manager" for the high temperature radiant
     127              :         // system model.  It is called from the outside and controls the
     128              :         // actions and subroutine calls to lower levels as appropriate.
     129              : 
     130              :         // METHODOLOGY EMPLOYED:
     131              :         // Standard EnergyPlus manager subroutine layout
     132              : 
     133              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     134              :         int RadSysNum; // Radiant system number/index in local derived types
     135              : 
     136            0 :         if (state.dataHighTempRadSys->GetInputFlag) {
     137            0 :             bool ErrorsFoundInGet = false;
     138            0 :             GetHighTempRadiantSystem(state, ErrorsFoundInGet);
     139            0 :             if (ErrorsFoundInGet)
     140            0 :                 ShowFatalError(state, "GetHighTempRadiantSystem: Errors found in input.  Preceding condition(s) cause termination.");
     141            0 :             state.dataHighTempRadSys->GetInputFlag = false;
     142              :         }
     143              : 
     144              :         // Find the correct ZoneHVAC:HighTemperatureRadiant
     145            0 :         if (CompIndex == 0) {
     146            0 :             RadSysNum = Util::FindItemInList(CompName, state.dataHighTempRadSys->HighTempRadSys);
     147            0 :             if (RadSysNum == 0) {
     148            0 :                 ShowFatalError(state, format("SimHighTempRadiantSystem: Unit not found={}", CompName));
     149              :             }
     150            0 :             CompIndex = RadSysNum;
     151              :         } else {
     152            0 :             RadSysNum = CompIndex;
     153            0 :             if (RadSysNum > state.dataHighTempRadSys->NumOfHighTempRadSys || RadSysNum < 1) {
     154            0 :                 ShowFatalError(state,
     155            0 :                                format("SimHighTempRadiantSystem:  Invalid CompIndex passed={}, Number of Units={}, Entered Unit name={}",
     156              :                                       RadSysNum,
     157            0 :                                       state.dataHighTempRadSys->NumOfHighTempRadSys,
     158              :                                       CompName));
     159              :             }
     160            0 :             if (state.dataHighTempRadSys->CheckEquipName(RadSysNum)) {
     161            0 :                 if (CompName != state.dataHighTempRadSys->HighTempRadSys(RadSysNum).Name) {
     162            0 :                     ShowFatalError(state,
     163            0 :                                    format("SimHighTempRadiantSystem: Invalid CompIndex passed={}, Unit name={}, stored Unit Name for that index={}",
     164              :                                           RadSysNum,
     165              :                                           CompName,
     166            0 :                                           state.dataHighTempRadSys->HighTempRadSys(RadSysNum).Name));
     167              :                 }
     168            0 :                 state.dataHighTempRadSys->CheckEquipName(RadSysNum) = false;
     169              :             }
     170              :         }
     171              : 
     172            0 :         InitHighTempRadiantSystem(state, FirstHVACIteration, RadSysNum);
     173              : 
     174            0 :         switch (state.dataHighTempRadSys->HighTempRadSys(RadSysNum).ControlType) {
     175            0 :         case RadControlType::MATControl:
     176              :         case RadControlType::MRTControl:
     177              :         case RadControlType::OperativeControl: {
     178            0 :             CalcHighTempRadiantSystem(state, RadSysNum);
     179            0 :         } break;
     180            0 :         case RadControlType::MATSPControl:
     181              :         case RadControlType::MRTSPControl:
     182              :         case RadControlType::OperativeSPControl: {
     183            0 :             CalcHighTempRadiantSystemSP(state, FirstHVACIteration, RadSysNum);
     184            0 :         } break;
     185            0 :         default:
     186            0 :             break;
     187              :         }
     188              : 
     189            0 :         UpdateHighTempRadiantSystem(state, RadSysNum, LoadMet);
     190              : 
     191            0 :         ReportHighTempRadiantSystem(state, RadSysNum);
     192            0 :     }
     193              : 
     194            1 :     void GetHighTempRadiantSystem(EnergyPlusData &state, bool &ErrorsFound // TRUE if errors are found on processing the input
     195              :     )
     196              :     {
     197              : 
     198              :         // SUBROUTINE INFORMATION:
     199              :         //       AUTHOR         Rick Strand
     200              :         //       DATE WRITTEN   February 2001
     201              : 
     202              :         // PURPOSE OF THIS SUBROUTINE:
     203              :         // This subroutine reads the input for high temperature radiant systems
     204              :         // from the user input file.  This will contain all of the information
     205              :         // needed to simulate a high temperature radiant system.
     206              : 
     207              :         // METHODOLOGY EMPLOYED:
     208              :         // Standard EnergyPlus methodology.
     209              :         static constexpr std::string_view routineName = "GetHighTempRadiantSystem";
     210              : 
     211              :         // SUBROUTINE PARAMETER DEFINITIONS:
     212            1 :         Real64 constexpr MaxCombustionEffic = 1.0;                // Limit the combustion efficiency to perfection
     213            1 :         Real64 constexpr MaxFraction = 1.0;                       // Limit the highest allowed fraction for heat transfer parts
     214            1 :         Real64 constexpr MinCombustionEffic = 0.01;               // Limit the minimum combustion efficiency
     215            1 :         Real64 constexpr MinFraction = 0.0;                       // Limit the lowest allowed fraction for heat transfer parts
     216            1 :         Real64 constexpr MinThrottlingRange = 0.5;                // Smallest throttling range allowed in degrees Celsius
     217            1 :         int constexpr iHeatCAPMAlphaNum = 4;                      // get input index to High Temperature Radiant system heating capacity sizing method
     218            1 :         int constexpr iHeatDesignCapacityNumericNum = 1;          // get input index to High Temperature Radiant system heating capacity
     219            1 :         int constexpr iHeatCapacityPerFloorAreaNumericNum = 2;    // index to High Temperature Radiant system heating capacity per floor area sizing
     220            1 :         int constexpr iHeatFracOfAutosizedCapacityNumericNum = 3; // index to system capacity sizing as fraction of autosized heating capacity
     221              : 
     222              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     223              :         Real64 FracOfRadPotentiallyLost; // Difference between unity and AllFracsSummed for error reporting
     224              :         int IOStatus;                    // Used in GetObjectItem
     225              :         int NumAlphas;                   // Number of Alphas for each GetObjectItem call
     226              :         int NumNumbers;                  // Number of Numbers for each GetObjectItem call
     227              : 
     228              :         // Initializations and allocations
     229            2 :         state.dataHighTempRadSys->NumOfHighTempRadSys =
     230            1 :             state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneHVAC:HighTemperatureRadiant");
     231              : 
     232            1 :         state.dataHighTempRadSys->HighTempRadSys.allocate(state.dataHighTempRadSys->NumOfHighTempRadSys);
     233            1 :         state.dataHighTempRadSys->CheckEquipName.allocate(state.dataHighTempRadSys->NumOfHighTempRadSys);
     234            1 :         state.dataHighTempRadSys->HighTempRadSysNumericFields.allocate(state.dataHighTempRadSys->NumOfHighTempRadSys);
     235            1 :         state.dataHighTempRadSys->CheckEquipName = true;
     236              : 
     237              :         // extensible object, do not need max args because using IPShortCuts
     238            1 :         auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
     239            1 :         cCurrentModuleObject = "ZoneHVAC:HighTemperatureRadiant";
     240              :         // Obtain all of the user data related to high temperature radiant systems...
     241            2 :         for (int Item = 1; Item <= state.dataHighTempRadSys->NumOfHighTempRadSys; ++Item) {
     242            1 :             auto &highTempRadSys = state.dataHighTempRadSys->HighTempRadSys(Item);
     243              : 
     244            2 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     245              :                                                                      cCurrentModuleObject,
     246              :                                                                      Item,
     247            1 :                                                                      state.dataIPShortCut->cAlphaArgs,
     248              :                                                                      NumAlphas,
     249            1 :                                                                      state.dataIPShortCut->rNumericArgs,
     250              :                                                                      NumNumbers,
     251              :                                                                      IOStatus,
     252            1 :                                                                      state.dataIPShortCut->lNumericFieldBlanks,
     253            1 :                                                                      state.dataIPShortCut->lAlphaFieldBlanks,
     254            1 :                                                                      state.dataIPShortCut->cAlphaFieldNames,
     255            1 :                                                                      state.dataIPShortCut->cNumericFieldNames);
     256              : 
     257            1 :             ErrorObjectHeader eoh{routineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)};
     258              : 
     259            1 :             state.dataHighTempRadSys->HighTempRadSysNumericFields(Item).FieldNames.allocate(NumNumbers);
     260            1 :             state.dataHighTempRadSys->HighTempRadSysNumericFields(Item).FieldNames = "";
     261            1 :             state.dataHighTempRadSys->HighTempRadSysNumericFields(Item).FieldNames = state.dataIPShortCut->cNumericFieldNames;
     262              :             // General user input data
     263            1 :             highTempRadSys.Name = state.dataIPShortCut->cAlphaArgs(1);
     264              : 
     265            1 :             if (state.dataIPShortCut->lAlphaFieldBlanks(2)) {
     266            1 :                 highTempRadSys.availSched = Sched::GetScheduleAlwaysOn(state);
     267            0 :             } else if ((highTempRadSys.availSched = Sched::GetSchedule(state, state.dataIPShortCut->cAlphaArgs(2))) == nullptr) {
     268            0 :                 ShowSevereItemNotFound(state, eoh, state.dataIPShortCut->cAlphaFieldNames(2), state.dataIPShortCut->cAlphaArgs(2));
     269            0 :                 ErrorsFound = true;
     270              :             }
     271              : 
     272            1 :             highTempRadSys.ZonePtr = Util::FindItemInList(state.dataIPShortCut->cAlphaArgs(3), state.dataHeatBal->Zone);
     273            1 :             if (highTempRadSys.ZonePtr == 0) {
     274            0 :                 ShowSevereError(state, format("Invalid {} = {}", state.dataIPShortCut->cAlphaFieldNames(3), state.dataIPShortCut->cAlphaArgs(3)));
     275            0 :                 ShowContinueError(state, format("Occurs for {} = {}", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     276            0 :                 ErrorsFound = true;
     277              :             }
     278              : 
     279              :             // state.dataHighTempRadSys->HighTempRadSys( Item ).MaxPowerCapac = state.dataIPShortCut->rNumericArgs( 1 );
     280              : 
     281              :             // Determine High Temp Radiant heating design capacity sizing method
     282            1 :             highTempRadSys.HeatingCapMethod = static_cast<DataSizing::DesignSizingType>(
     283            1 :                 getEnumValue(DataSizing::DesignSizingTypeNamesUC, state.dataIPShortCut->cAlphaArgs(iHeatCAPMAlphaNum)));
     284            1 :             if (highTempRadSys.HeatingCapMethod == DataSizing::DesignSizingType::HeatingDesignCapacity) {
     285            1 :                 if (!state.dataIPShortCut->lNumericFieldBlanks(iHeatDesignCapacityNumericNum)) {
     286            1 :                     highTempRadSys.ScaledHeatingCapacity = state.dataIPShortCut->rNumericArgs(iHeatDesignCapacityNumericNum);
     287            1 :                     if (highTempRadSys.ScaledHeatingCapacity < 0.0 && highTempRadSys.ScaledHeatingCapacity != DataSizing::AutoSize) {
     288            0 :                         ShowSevereError(state, format("{} = {}", cCurrentModuleObject, highTempRadSys.Name));
     289            0 :                         ShowContinueError(state,
     290            0 :                                           format("Illegal {} = {:.7T}",
     291            0 :                                                  state.dataIPShortCut->cNumericFieldNames(iHeatDesignCapacityNumericNum),
     292            0 :                                                  state.dataIPShortCut->rNumericArgs(iHeatDesignCapacityNumericNum)));
     293            0 :                         ErrorsFound = true;
     294              :                     }
     295              :                 } else {
     296            0 :                     ShowSevereError(state, format("{} = {}", cCurrentModuleObject, highTempRadSys.Name));
     297            0 :                     ShowContinueError(state,
     298            0 :                                       format("Input for {} = {}",
     299            0 :                                              state.dataIPShortCut->cAlphaFieldNames(iHeatCAPMAlphaNum),
     300            0 :                                              state.dataIPShortCut->cAlphaArgs(iHeatCAPMAlphaNum)));
     301            0 :                     ShowContinueError(
     302            0 :                         state, format("Blank field not allowed for {}", state.dataIPShortCut->cNumericFieldNames(iHeatDesignCapacityNumericNum)));
     303            0 :                     ErrorsFound = true;
     304              :                 }
     305            0 :             } else if (highTempRadSys.HeatingCapMethod == DataSizing::DesignSizingType::CapacityPerFloorArea) {
     306            0 :                 if (!state.dataIPShortCut->lNumericFieldBlanks(iHeatCapacityPerFloorAreaNumericNum)) {
     307            0 :                     highTempRadSys.ScaledHeatingCapacity = state.dataIPShortCut->rNumericArgs(iHeatCapacityPerFloorAreaNumericNum);
     308            0 :                     if (highTempRadSys.ScaledHeatingCapacity <= 0.0) {
     309            0 :                         ShowSevereError(state, format("{} = {}", cCurrentModuleObject, highTempRadSys.Name));
     310            0 :                         ShowContinueError(state,
     311            0 :                                           format("Input for {} = {}",
     312            0 :                                                  state.dataIPShortCut->cAlphaFieldNames(iHeatCAPMAlphaNum),
     313            0 :                                                  state.dataIPShortCut->cAlphaArgs(iHeatCAPMAlphaNum)));
     314            0 :                         ShowContinueError(state,
     315            0 :                                           format("Illegal {} = {:.7T}",
     316            0 :                                                  state.dataIPShortCut->cNumericFieldNames(iHeatCapacityPerFloorAreaNumericNum),
     317            0 :                                                  state.dataIPShortCut->rNumericArgs(iHeatCapacityPerFloorAreaNumericNum)));
     318            0 :                         ErrorsFound = true;
     319            0 :                     } else if (highTempRadSys.ScaledHeatingCapacity == DataSizing::AutoSize) {
     320            0 :                         ShowSevereError(state, format("{} = {}", cCurrentModuleObject, highTempRadSys.Name));
     321            0 :                         ShowContinueError(state,
     322            0 :                                           format("Input for {} = {}",
     323            0 :                                                  state.dataIPShortCut->cAlphaFieldNames(iHeatCAPMAlphaNum),
     324            0 :                                                  state.dataIPShortCut->cAlphaArgs(iHeatCAPMAlphaNum)));
     325            0 :                         ShowContinueError(
     326            0 :                             state, format("Illegal {} = Autosize", state.dataIPShortCut->cNumericFieldNames(iHeatCapacityPerFloorAreaNumericNum)));
     327            0 :                         ErrorsFound = true;
     328              :                     }
     329              :                 } else {
     330            0 :                     ShowSevereError(state, format("{} = {}", cCurrentModuleObject, highTempRadSys.Name));
     331            0 :                     ShowContinueError(state,
     332            0 :                                       format("Input for {} = {}",
     333            0 :                                              state.dataIPShortCut->cAlphaFieldNames(iHeatCAPMAlphaNum),
     334            0 :                                              state.dataIPShortCut->cAlphaArgs(iHeatCAPMAlphaNum)));
     335            0 :                     ShowContinueError(
     336              :                         state,
     337            0 :                         format("Blank field not allowed for {}", state.dataIPShortCut->cNumericFieldNames(iHeatCapacityPerFloorAreaNumericNum)));
     338            0 :                     ErrorsFound = true;
     339              :                 }
     340            0 :             } else if (highTempRadSys.HeatingCapMethod == DataSizing::DesignSizingType::FractionOfAutosizedHeatingCapacity) {
     341            0 :                 if (!state.dataIPShortCut->lNumericFieldBlanks(iHeatFracOfAutosizedCapacityNumericNum)) {
     342            0 :                     highTempRadSys.ScaledHeatingCapacity = state.dataIPShortCut->rNumericArgs(iHeatFracOfAutosizedCapacityNumericNum);
     343            0 :                     if (highTempRadSys.ScaledHeatingCapacity < 0.0) {
     344            0 :                         ShowSevereError(state, format("{} = {}", cCurrentModuleObject, highTempRadSys.Name));
     345            0 :                         ShowContinueError(state,
     346            0 :                                           format("Illegal {} = {:.7T}",
     347            0 :                                                  state.dataIPShortCut->cNumericFieldNames(iHeatFracOfAutosizedCapacityNumericNum),
     348            0 :                                                  state.dataIPShortCut->rNumericArgs(iHeatFracOfAutosizedCapacityNumericNum)));
     349            0 :                         ErrorsFound = true;
     350              :                     }
     351              :                 } else {
     352            0 :                     ShowSevereError(state, format("{} = {}", cCurrentModuleObject, highTempRadSys.Name));
     353            0 :                     ShowContinueError(state,
     354            0 :                                       format("Input for {} = {}",
     355            0 :                                              state.dataIPShortCut->cAlphaFieldNames(iHeatCAPMAlphaNum),
     356            0 :                                              state.dataIPShortCut->cAlphaArgs(iHeatCAPMAlphaNum)));
     357            0 :                     ShowContinueError(
     358              :                         state,
     359            0 :                         format("Blank field not allowed for {}", state.dataIPShortCut->cNumericFieldNames(iHeatFracOfAutosizedCapacityNumericNum)));
     360            0 :                     ErrorsFound = true;
     361              :                 }
     362              :             }
     363              : 
     364            1 :             highTempRadSys.HeaterType =
     365            1 :                 static_cast<Constant::eResource>(getEnumValue(Constant::eResourceNamesUC, state.dataIPShortCut->cAlphaArgs(5)));
     366              : 
     367            1 :             if (highTempRadSys.HeaterType == Constant::eResource::NaturalGas) {
     368            0 :                 highTempRadSys.CombustionEffic = state.dataIPShortCut->rNumericArgs(4);
     369              :                 // Limit the combustion efficiency to between zero and one...
     370            0 :                 if (highTempRadSys.CombustionEffic < MinCombustionEffic) {
     371            0 :                     highTempRadSys.CombustionEffic = MinCombustionEffic;
     372            0 :                     ShowWarningError(
     373              :                         state,
     374            0 :                         format("{} was less than the allowable minimum, reset to minimum value.", state.dataIPShortCut->cNumericFieldNames(4)));
     375            0 :                     ShowContinueError(state, format("Occurs for {} = {}", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     376              :                 }
     377            0 :                 if (highTempRadSys.CombustionEffic > MaxCombustionEffic) {
     378            0 :                     highTempRadSys.CombustionEffic = MaxCombustionEffic;
     379            0 :                     ShowWarningError(
     380              :                         state,
     381            0 :                         format("{} was greater than the allowable maximum, reset to maximum value.", state.dataIPShortCut->cNumericFieldNames(4)));
     382            0 :                     ShowContinueError(state, format("Occurs for {} = {}", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     383              :                 }
     384              :             } else {
     385            1 :                 highTempRadSys.CombustionEffic = MaxCombustionEffic; // No inefficiency in the heater
     386              :             }
     387              : 
     388            1 :             highTempRadSys.FracRadiant = state.dataIPShortCut->rNumericArgs(5);
     389            1 :             if (highTempRadSys.FracRadiant < MinFraction) {
     390            0 :                 highTempRadSys.FracRadiant = MinFraction;
     391            0 :                 ShowWarningError(
     392            0 :                     state, format("{} was less than the allowable minimum, reset to minimum value.", state.dataIPShortCut->cNumericFieldNames(5)));
     393            0 :                 ShowContinueError(state, format("Occurs for {} = {}", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     394              :             }
     395            1 :             if (highTempRadSys.FracRadiant > MaxFraction) {
     396            0 :                 highTempRadSys.FracRadiant = MaxFraction;
     397            0 :                 ShowWarningError(
     398            0 :                     state, format("{} was greater than the allowable maximum, reset to maximum value.", state.dataIPShortCut->cNumericFieldNames(5)));
     399            0 :                 ShowContinueError(state, format("Occurs for {} = {}", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     400              :             }
     401              : 
     402            1 :             highTempRadSys.FracLatent = state.dataIPShortCut->rNumericArgs(6);
     403            1 :             if (highTempRadSys.FracLatent < MinFraction) {
     404            0 :                 highTempRadSys.FracLatent = MinFraction;
     405            0 :                 ShowWarningError(
     406            0 :                     state, format("{} was less than the allowable minimum, reset to minimum value.", state.dataIPShortCut->cNumericFieldNames(6)));
     407            0 :                 ShowContinueError(state, format("Occurs for {} = {}", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     408              :             }
     409            1 :             if (highTempRadSys.FracLatent > MaxFraction) {
     410            0 :                 highTempRadSys.FracLatent = MaxFraction;
     411            0 :                 ShowWarningError(
     412            0 :                     state, format("{} was greater than the allowable maximum, reset to maximum value.", state.dataIPShortCut->cNumericFieldNames(6)));
     413            0 :                 ShowContinueError(state, format("Occurs for {} = {}", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     414              :             }
     415              : 
     416            1 :             highTempRadSys.FracLost = state.dataIPShortCut->rNumericArgs(7);
     417            1 :             if (highTempRadSys.FracLost < MinFraction) {
     418            0 :                 highTempRadSys.FracLost = MinFraction;
     419            0 :                 ShowWarningError(
     420            0 :                     state, format("{} was less than the allowable minimum, reset to minimum value.", state.dataIPShortCut->cNumericFieldNames(7)));
     421            0 :                 ShowContinueError(state, format("Occurs for {} = {}", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     422              :             }
     423            1 :             if (highTempRadSys.FracLost > MaxFraction) {
     424            0 :                 highTempRadSys.FracLost = MaxFraction;
     425            0 :                 ShowWarningError(
     426            0 :                     state, format("{} was greater than the allowable maximum, reset to maximum value.", state.dataIPShortCut->cNumericFieldNames(7)));
     427            0 :                 ShowContinueError(state, format("Occurs for {} = {}", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     428              :             }
     429              : 
     430              :             // Based on the input for fractions radiant, latent, and lost, determine the fraction convective (remaining fraction)
     431            1 :             Real64 AllFracsSummed = highTempRadSys.FracRadiant + highTempRadSys.FracLatent + highTempRadSys.FracLost;
     432            1 :             if (AllFracsSummed > MaxFraction) {
     433            0 :                 ShowSevereError(state,
     434            0 :                                 format("Fractions radiant, latent, and lost sum up to greater than 1 for{}", state.dataIPShortCut->cAlphaArgs(1)));
     435            0 :                 ShowContinueError(state, format("Occurs for {} = {}", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     436            0 :                 ErrorsFound = true;
     437            0 :                 highTempRadSys.FracConvect = 0.0;
     438              :             } else {
     439            1 :                 highTempRadSys.FracConvect = 1.0 - AllFracsSummed;
     440              :             }
     441              : 
     442              :             // Process the temperature control type
     443            1 :             if (state.dataIPShortCut->lAlphaFieldBlanks(6)) {
     444            0 :                 ShowWarningEmptyField(state, eoh, state.dataIPShortCut->cAlphaFieldNames(6), "OperativeTemperature");
     445            0 :                 highTempRadSys.ControlType = RadControlType::OperativeControl;
     446            1 :             } else if ((highTempRadSys.ControlType = static_cast<RadControlType>(
     447            1 :                             getEnumValue(radControlTypeNamesUC, state.dataIPShortCut->cAlphaArgs(6)))) == RadControlType::Invalid) {
     448            0 :                 ShowSevereInvalidKey(state, eoh, state.dataIPShortCut->cAlphaFieldNames(6), state.dataIPShortCut->cAlphaArgs(6));
     449            0 :                 ErrorsFound = true;
     450              :             }
     451              : 
     452            1 :             highTempRadSys.ThrottlRange = state.dataIPShortCut->rNumericArgs(8);
     453            1 :             if (highTempRadSys.ThrottlRange < MinThrottlingRange) {
     454            0 :                 highTempRadSys.ThrottlRange = 1.0;
     455            0 :                 ShowWarningError(state, format("{} is below the minimum allowed.", state.dataIPShortCut->cNumericFieldNames(8)));
     456            0 :                 ShowContinueError(state, format("Occurs for {} = {}", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     457            0 :                 ShowContinueError(state, "Thus, the throttling range value has been reset to 1.0");
     458              :             }
     459              : 
     460            1 :             if (state.dataIPShortCut->lAlphaFieldBlanks(7)) {
     461            0 :                 ShowSevereEmptyField(state,
     462              :                                      eoh,
     463            0 :                                      state.dataIPShortCut->cAlphaFieldNames(7),
     464            0 :                                      state.dataIPShortCut->cAlphaFieldNames(6),
     465            0 :                                      state.dataIPShortCut->cAlphaArgs(6));
     466            0 :                 ErrorsFound = true;
     467            1 :             } else if ((highTempRadSys.setptSched = Sched::GetSchedule(state, state.dataIPShortCut->cAlphaArgs(7))) == nullptr) {
     468            1 :                 ShowSevereItemNotFound(state, eoh, state.dataIPShortCut->cAlphaFieldNames(7), state.dataIPShortCut->cAlphaArgs(7));
     469            1 :                 ErrorsFound = true;
     470              :             }
     471              : 
     472            1 :             highTempRadSys.FracDistribPerson = state.dataIPShortCut->rNumericArgs(9);
     473            1 :             if (highTempRadSys.FracDistribPerson < MinFraction) {
     474            0 :                 highTempRadSys.FracDistribPerson = MinFraction;
     475            0 :                 ShowWarningError(
     476            0 :                     state, format("{} was less than the allowable minimum, reset to minimum value.", state.dataIPShortCut->cNumericFieldNames(9)));
     477            0 :                 ShowContinueError(state, format("Occurs for {} = {}", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     478              :             }
     479            1 :             if (highTempRadSys.FracDistribPerson > MaxFraction) {
     480            0 :                 highTempRadSys.FracDistribPerson = MaxFraction;
     481            0 :                 ShowWarningError(
     482            0 :                     state, format("{} was greater than the allowable maximum, reset to maximum value.", state.dataIPShortCut->cNumericFieldNames(9)));
     483            0 :                 ShowContinueError(state, format("Occurs for {} = {}", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     484              :             }
     485              : 
     486            1 :             highTempRadSys.TotSurfToDistrib = NumNumbers - 9;
     487              :             //    IF (highTempRadSys%TotSurfToDistrib > MaxDistribSurfaces) THEN
     488              :             //      CALL ShowSevereError(state, 'Trying to distribute radiant energy to too many surfaces for heater
     489              :             //      '//TRIM(state.dataIPShortCut->cAlphaArgs(1))) CALL ShowContinueError(state, 'Occurs for '//TRIM(cCurrentModuleObject)//' =
     490              :             //      '//TRIM(state.dataIPShortCut->cAlphaArgs(1))) ErrorsFound=.TRUE.
     491              :             //    END IF
     492            1 :             highTempRadSys.SurfaceName.allocate(highTempRadSys.TotSurfToDistrib);
     493            1 :             highTempRadSys.SurfacePtr.allocate(highTempRadSys.TotSurfToDistrib);
     494            1 :             highTempRadSys.FracDistribToSurf.allocate(highTempRadSys.TotSurfToDistrib);
     495              : 
     496            1 :             AllFracsSummed = highTempRadSys.FracDistribPerson;
     497            2 :             for (int SurfNum = 1; SurfNum <= highTempRadSys.TotSurfToDistrib; ++SurfNum) {
     498            1 :                 highTempRadSys.SurfaceName(SurfNum) = state.dataIPShortCut->cAlphaArgs(SurfNum + 7);
     499            1 :                 highTempRadSys.SurfacePtr(SurfNum) = HeatBalanceIntRadExchange::GetRadiantSystemSurface(
     500            1 :                     state, cCurrentModuleObject, highTempRadSys.Name, highTempRadSys.ZonePtr, highTempRadSys.SurfaceName(SurfNum), ErrorsFound);
     501            1 :                 highTempRadSys.FracDistribToSurf(SurfNum) = state.dataIPShortCut->rNumericArgs(SurfNum + 9);
     502              :                 // Error trap for fractions that are out of range
     503            1 :                 if (highTempRadSys.FracDistribToSurf(SurfNum) < MinFraction) {
     504            0 :                     highTempRadSys.FracDistribToSurf(SurfNum) = MinFraction;
     505            0 :                     ShowWarningError(state,
     506            0 :                                      format("{} was less than the allowable minimum, reset to minimum value.",
     507            0 :                                             state.dataIPShortCut->cNumericFieldNames(SurfNum + 9)));
     508            0 :                     ShowContinueError(state, format("Occurs for {} = {}", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     509              :                 }
     510            1 :                 if (highTempRadSys.FracDistribToSurf(SurfNum) > MaxFraction) {
     511            0 :                     highTempRadSys.FracDistribToSurf(SurfNum) = MaxFraction;
     512            0 :                     ShowWarningError(state,
     513            0 :                                      format("{} was greater than the allowable maximum, reset to maximum value.",
     514            0 :                                             state.dataIPShortCut->cNumericFieldNames(SurfNum + 9)));
     515            0 :                     ShowContinueError(state, format("Occurs for {} = {}", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     516              :                 }
     517              : 
     518            1 :                 if (highTempRadSys.SurfacePtr(SurfNum) != 0) {
     519            1 :                     state.dataSurface->surfIntConv(highTempRadSys.SurfacePtr(SurfNum)).getsRadiantHeat = true;
     520            1 :                     state.dataSurface->allGetsRadiantHeatSurfaceList.emplace_back(highTempRadSys.SurfacePtr(SurfNum));
     521              :                 }
     522              : 
     523            1 :                 AllFracsSummed += highTempRadSys.FracDistribToSurf(SurfNum);
     524              : 
     525              :             } // ...end of DO loop through surfaces that the heater radiates to.
     526              : 
     527              :             // Error trap if the fractions add up to greater than 1.0
     528            1 :             if (AllFracsSummed > (MaxFraction + 0.01)) {
     529            0 :                 ShowSevereError(
     530              :                     state,
     531            0 :                     format("Fraction of radiation distributed to surfaces sums up to greater than 1 for {}", state.dataIPShortCut->cAlphaArgs(1)));
     532            0 :                 ShowContinueError(state, format("Occurs for {} = {}", cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     533            0 :                 ErrorsFound = true;
     534              :             }
     535            1 :             if (AllFracsSummed < (MaxFraction - 0.01)) { // User didn't distribute all of the radiation warn that some will be lost
     536            1 :                 Real64 TotalFracToSurfs = AllFracsSummed - highTempRadSys.FracDistribPerson;
     537            1 :                 FracOfRadPotentiallyLost = 1.0 - AllFracsSummed;
     538            2 :                 ShowSevereError(state,
     539            2 :                                 format("Fraction of radiation distributed to surfaces and people sums up to less than 1 for {}",
     540            1 :                                        state.dataIPShortCut->cAlphaArgs(1)));
     541            2 :                 ShowContinueError(state, "This would result in some of the radiant energy delivered by the high temp radiant heater being lost.");
     542            1 :                 ShowContinueError(state, format("The sum of all radiation fractions to surfaces = {:.5T}", TotalFracToSurfs));
     543            1 :                 ShowContinueError(state, format("The radiant fraction to people = {:.5T}", highTempRadSys.FracDistribPerson));
     544            1 :                 ShowContinueError(state, format("So, all radiant fractions including surfaces and people = {:.5T}", AllFracsSummed));
     545            2 :                 ShowContinueError(state,
     546            2 :                                   format("This means that the fraction of radiant energy that would be lost from the high temperature radiant heater "
     547              :                                          "would be = {:.5T}",
     548              :                                          FracOfRadPotentiallyLost));
     549            2 :                 ShowContinueError(state,
     550            2 :                                   format("Please check and correct this so that all radiant energy is accounted for in {} = {}",
     551              :                                          cCurrentModuleObject,
     552            1 :                                          state.dataIPShortCut->cAlphaArgs(1)));
     553            1 :                 ErrorsFound = true;
     554              :             }
     555              : 
     556              :         } // ...end of DO loop through all of the high temperature radiant heaters
     557              : 
     558              :         // Set up the output variables for high temperature radiant heaters
     559              :         // cCurrentModuleObject = "ZoneHVAC:HighTemperatureRadiant"
     560            2 :         for (int Item = 1; Item <= state.dataHighTempRadSys->NumOfHighTempRadSys; ++Item) {
     561            1 :             auto &highTempRadSys = state.dataHighTempRadSys->HighTempRadSys(Item);
     562            2 :             SetupOutputVariable(state,
     563              :                                 "Zone Radiant HVAC Heating Rate",
     564              :                                 Constant::Units::W,
     565            1 :                                 highTempRadSys.HeatPower,
     566              :                                 OutputProcessor::TimeStepType::System,
     567              :                                 OutputProcessor::StoreType::Average,
     568            1 :                                 highTempRadSys.Name);
     569            2 :             SetupOutputVariable(state,
     570              :                                 "Zone Radiant HVAC Heating Energy",
     571              :                                 Constant::Units::J,
     572            1 :                                 highTempRadSys.HeatEnergy,
     573              :                                 OutputProcessor::TimeStepType::System,
     574              :                                 OutputProcessor::StoreType::Sum,
     575            1 :                                 highTempRadSys.Name,
     576              :                                 Constant::eResource::EnergyTransfer,
     577              :                                 OutputProcessor::Group::HVAC,
     578              :                                 OutputProcessor::EndUseCat::HeatingCoils);
     579            1 :             if (highTempRadSys.HeaterType == Constant::eResource::NaturalGas) {
     580            0 :                 SetupOutputVariable(state,
     581              :                                     "Zone Radiant HVAC NaturalGas Rate",
     582              :                                     Constant::Units::W,
     583            0 :                                     highTempRadSys.GasPower,
     584              :                                     OutputProcessor::TimeStepType::System,
     585              :                                     OutputProcessor::StoreType::Average,
     586            0 :                                     highTempRadSys.Name);
     587            0 :                 SetupOutputVariable(state,
     588              :                                     "Zone Radiant HVAC NaturalGas Energy",
     589              :                                     Constant::Units::J,
     590            0 :                                     highTempRadSys.GasEnergy,
     591              :                                     OutputProcessor::TimeStepType::System,
     592              :                                     OutputProcessor::StoreType::Sum,
     593            0 :                                     highTempRadSys.Name,
     594              :                                     Constant::eResource::NaturalGas,
     595              :                                     OutputProcessor::Group::HVAC,
     596              :                                     OutputProcessor::EndUseCat::Heating);
     597            1 :             } else if (highTempRadSys.HeaterType == Constant::eResource::Electricity) {
     598            2 :                 SetupOutputVariable(state,
     599              :                                     "Zone Radiant HVAC Electricity Rate",
     600              :                                     Constant::Units::W,
     601            1 :                                     highTempRadSys.ElecPower,
     602              :                                     OutputProcessor::TimeStepType::System,
     603              :                                     OutputProcessor::StoreType::Average,
     604            1 :                                     highTempRadSys.Name);
     605            2 :                 SetupOutputVariable(state,
     606              :                                     "Zone Radiant HVAC Electricity Energy",
     607              :                                     Constant::Units::J,
     608            1 :                                     highTempRadSys.ElecEnergy,
     609              :                                     OutputProcessor::TimeStepType::System,
     610              :                                     OutputProcessor::StoreType::Sum,
     611            1 :                                     highTempRadSys.Name,
     612              :                                     Constant::eResource::Electricity,
     613              :                                     OutputProcessor::Group::HVAC,
     614              :                                     OutputProcessor::EndUseCat::Heating);
     615              :             }
     616              :         }
     617            1 :     }
     618              : 
     619            0 :     void InitHighTempRadiantSystem(EnergyPlusData &state,
     620              :                                    bool const FirstHVACIteration, // TRUE if 1st HVAC simulation of system timestep
     621              :                                    int const RadSysNum // Index for the low temperature radiant system under consideration within the derived types
     622              :     )
     623              :     {
     624              : 
     625              :         // SUBROUTINE INFORMATION:
     626              :         //       AUTHOR         Rick Strand
     627              :         //       DATE WRITTEN   February 2001
     628              : 
     629              :         // PURPOSE OF THIS SUBROUTINE:
     630              :         // This subroutine initializes variables relating to high temperature
     631              :         // radiant heating systems.
     632              : 
     633              :         // METHODOLOGY EMPLOYED:
     634              :         // Simply initializes whatever needs initializing.
     635              : 
     636              :         // Using/Aliasing
     637              :         using DataZoneEquipment::CheckZoneEquipmentList;
     638              : 
     639            0 :         if (state.dataHighTempRadSys->firstTime) {
     640            0 :             state.dataHighTempRadSys->MySizeFlag.dimension(state.dataHighTempRadSys->NumOfHighTempRadSys, true);
     641            0 :             state.dataHighTempRadSys->firstTime = false;
     642              :         }
     643              : 
     644              :         // need to check all units to see if they are on Zone Equipment List or issue warning
     645            0 :         if (!state.dataHighTempRadSys->ZoneEquipmentListChecked && state.dataZoneEquip->ZoneEquipInputsFilled) {
     646            0 :             state.dataHighTempRadSys->ZoneEquipmentListChecked = true;
     647            0 :             for (auto &thisHTRSys : state.dataHighTempRadSys->HighTempRadSys) {
     648            0 :                 if (CheckZoneEquipmentList(state, "ZoneHVAC:HighTemperatureRadiant", thisHTRSys.Name)) continue;
     649            0 :                 ShowSevereError(state,
     650            0 :                                 format("InitHighTempRadiantSystem: Unit=[ZoneHVAC:HighTemperatureRadiant,{}] is not on any ZoneHVAC:EquipmentList.  "
     651              :                                        "It will not be simulated.",
     652            0 :                                        thisHTRSys.Name));
     653              :             }
     654              :         }
     655              : 
     656            0 :         if (!state.dataGlobal->SysSizingCalc && state.dataHighTempRadSys->MySizeFlag(RadSysNum)) {
     657              :             // for each radiant system do the sizing once.
     658            0 :             SizeHighTempRadiantSystem(state, RadSysNum);
     659            0 :             state.dataHighTempRadSys->MySizeFlag(RadSysNum) = false;
     660              :         }
     661              : 
     662            0 :         if (state.dataGlobal->BeginEnvrnFlag && state.dataHighTempRadSys->MyEnvrnFlag) {
     663            0 :             for (auto &thisHTR : state.dataHighTempRadSys->HighTempRadSys) {
     664            0 :                 thisHTR.ZeroHTRSourceSumHATsurf = 0.0;
     665            0 :                 thisHTR.QHTRRadSource = 0.0;
     666            0 :                 thisHTR.QHTRRadSrcAvg = 0.0;
     667            0 :                 thisHTR.LastQHTRRadSrc = 0.0;
     668            0 :                 thisHTR.LastSysTimeElapsed = 0.0;
     669            0 :                 thisHTR.LastTimeStepSys = 0.0;
     670              :             }
     671            0 :             state.dataHighTempRadSys->MyEnvrnFlag = false;
     672              :         }
     673            0 :         if (!state.dataGlobal->BeginEnvrnFlag) {
     674            0 :             state.dataHighTempRadSys->MyEnvrnFlag = true;
     675              :         }
     676              : 
     677            0 :         if (state.dataGlobal->BeginTimeStepFlag && FirstHVACIteration) { // This is the first pass through in a particular time step
     678            0 :             auto &thisHTR = state.dataHighTempRadSys->HighTempRadSys(RadSysNum);
     679            0 :             thisHTR.ZeroHTRSourceSumHATsurf =
     680            0 :                 state.dataHeatBal->Zone(thisHTR.ZonePtr).sumHATsurf(state); // Set this to figure out what part of the load the radiant system meets
     681            0 :             thisHTR.QHTRRadSource = 0.0;                                    // Initialize this variable to zero (radiant system defaults to off)
     682            0 :             thisHTR.QHTRRadSrcAvg = 0.0;                                    // Initialize this variable to zero (radiant system defaults to off)
     683            0 :             thisHTR.LastQHTRRadSrc = 0.0;     // At the beginning of a time step, reset to zero so average calculation can start again
     684            0 :             thisHTR.LastSysTimeElapsed = 0.0; // At the beginning of a time step, reset to zero so average calculation can start again
     685            0 :             thisHTR.LastTimeStepSys = 0.0;    // At the beginning of a time step, reset to zero so average calculation can start again
     686              :         }
     687            0 :     }
     688              : 
     689            1 :     void SizeHighTempRadiantSystem(EnergyPlusData &state, int const RadSysNum)
     690              :     {
     691              : 
     692              :         // SUBROUTINE INFORMATION:
     693              :         //       AUTHOR         Fred Buhl
     694              :         //       DATE WRITTEN   February 2002
     695              :         //       MODIFIED       August 2013 Daeho Kang, add component sizing table entries
     696              :         //                      July 2014, B. Nigusse, added scalable sizing
     697              : 
     698              :         // PURPOSE OF THIS SUBROUTINE:
     699              :         // This subroutine is for sizing high temperature radiant components for which max power input has not been
     700              :         // specified in the input.
     701              : 
     702              :         // METHODOLOGY EMPLOYED:
     703              :         // Obtains design heating load from the zone sizing arrays
     704              : 
     705              :         // Using/Aliasing
     706            1 :         auto &thisHTR = state.dataHighTempRadSys->HighTempRadSys(RadSysNum);
     707              : 
     708              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS
     709              :         Real64 TempSize; // autosized value of coil input field
     710            1 :         state.dataSize->DataScalableCapSizingON = false;
     711              : 
     712            1 :         int const curZoneEqNum = state.dataSize->CurZoneEqNum;
     713              : 
     714            1 :         if (curZoneEqNum > 0) {
     715            1 :             auto &zoneEqSizing = state.dataSize->ZoneEqSizing(curZoneEqNum);
     716              : 
     717            1 :             state.dataSize->DataFracOfAutosizedHeatingCapacity = 1.0;
     718            1 :             state.dataSize->DataZoneNumber = thisHTR.ZonePtr;
     719              :             // Integer representation of sizing method name (e.g., CoolingAirflowSizing, HeatingCapacitySizing, etc.)
     720            1 :             int SizingMethod = HVAC::HeatingCapacitySizing;
     721            1 :             int FieldNum = 1;
     722            1 :             std::string const SizingString = format("{} [W]", state.dataHighTempRadSys->HighTempRadSysNumericFields(RadSysNum).FieldNames(FieldNum));
     723              :             // capacity sizing methods (HeatingDesignCapacity, CapacityPerFloorArea, FractionOfAutosizedCoolingCapacity, and
     724              :             // FractionOfAutosizedHeatingCapacity )
     725            1 :             int CapSizingMethod = static_cast<int>(thisHTR.HeatingCapMethod);
     726            1 :             zoneEqSizing.SizingMethod(SizingMethod) = CapSizingMethod;
     727            1 :             if (CapSizingMethod == DataSizing::HeatingDesignCapacity || CapSizingMethod == DataSizing::CapacityPerFloorArea ||
     728              :                 CapSizingMethod == DataSizing::FractionOfAutosizedHeatingCapacity) {
     729            1 :                 std::string_view const CompType = "ZoneHVAC:HighTemperatureRadiant";
     730            1 :                 std::string_view const CompName = thisHTR.Name;
     731              : 
     732            1 :                 if (CapSizingMethod == DataSizing::HeatingDesignCapacity) {
     733            0 :                     if (thisHTR.ScaledHeatingCapacity == DataSizing::AutoSize) {
     734            0 :                         CheckZoneSizing(state, CompType, CompName);
     735            0 :                         zoneEqSizing.DesHeatingLoad =
     736            0 :                             state.dataSize->FinalZoneSizing(curZoneEqNum).NonAirSysDesHeatLoad / (thisHTR.FracRadiant + thisHTR.FracConvect);
     737              :                     } else {
     738            0 :                         zoneEqSizing.DesHeatingLoad = thisHTR.ScaledHeatingCapacity;
     739              :                     }
     740            0 :                     zoneEqSizing.HeatingCapacity = true;
     741            0 :                     TempSize = zoneEqSizing.DesHeatingLoad;
     742            1 :                 } else if (CapSizingMethod == DataSizing::CapacityPerFloorArea) {
     743            1 :                     zoneEqSizing.HeatingCapacity = true;
     744            1 :                     zoneEqSizing.DesHeatingLoad = thisHTR.ScaledHeatingCapacity * state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
     745            1 :                     TempSize = zoneEqSizing.DesHeatingLoad;
     746            1 :                     state.dataSize->DataScalableCapSizingON = true;
     747            0 :                 } else if (CapSizingMethod == DataSizing::FractionOfAutosizedHeatingCapacity) {
     748            0 :                     CheckZoneSizing(state, CompType, CompName);
     749            0 :                     zoneEqSizing.HeatingCapacity = true;
     750            0 :                     state.dataSize->DataFracOfAutosizedHeatingCapacity = thisHTR.ScaledHeatingCapacity;
     751            0 :                     zoneEqSizing.DesHeatingLoad =
     752            0 :                         state.dataSize->FinalZoneSizing(curZoneEqNum).NonAirSysDesHeatLoad / (thisHTR.FracRadiant + thisHTR.FracConvect);
     753            0 :                     TempSize = DataSizing::AutoSize;
     754            0 :                     state.dataSize->DataScalableCapSizingON = true;
     755              :                 } else {
     756            0 :                     TempSize = thisHTR.ScaledHeatingCapacity;
     757              :                 }
     758            1 :                 bool PrintFlag = true;
     759            1 :                 bool errorsFound = false;
     760            1 :                 constexpr std::string_view RoutineName = "SizeHighTempRadiantSystem";
     761            1 :                 HeatingCapacitySizer sizerHeatingCapacity;
     762            1 :                 sizerHeatingCapacity.overrideSizingString(SizingString);
     763            1 :                 sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
     764            1 :                 thisHTR.MaxPowerCapac = sizerHeatingCapacity.size(state, TempSize, errorsFound);
     765            1 :                 state.dataSize->DataScalableCapSizingON = false;
     766            1 :             }
     767            1 :         }
     768            1 :     }
     769              : 
     770            0 :     void CalcHighTempRadiantSystem(EnergyPlusData &state, int const RadSysNum) // name of the low temperature radiant system
     771              :     {
     772              : 
     773              :         // SUBROUTINE INFORMATION:
     774              :         //       AUTHOR         Rick Strand
     775              :         //       DATE WRITTEN   February 2001
     776              : 
     777              :         // PURPOSE OF THIS SUBROUTINE:
     778              :         // This subroutine does all of the stuff that is necessary to simulate
     779              :         // a high temperature radiant heating system.
     780              : 
     781              :         // METHODOLOGY EMPLOYED:
     782              :         // Follows the methods used by many other pieces of zone equipment except
     783              :         // that we are controlling the input to the heater element.  Note that
     784              :         // cooling is not allowed for such a system.  Controls are very basic at
     785              :         // this point using just a linear interpolation between being off at
     786              :         // one end of the throttling range, fully on at the other end, and varying
     787              :         // linearly in between.
     788              : 
     789              :         // REFERENCES:
     790              :         // Other EnergyPlus modules
     791              :         // Building Systems Laboratory, BLAST User's Guide/Reference.
     792              :         // Fanger, P.O. "Analysis and Applications in Environmental Engineering",
     793              :         //   Danish Technical Press, 1970.
     794              :         // Maloney, Dan. 1987. "Development of a radiant heater model and the
     795              :         //   incorporation of thermal comfort considerations into the BLAST
     796              :         //   energy analysis program", M.S. thesis, University of Illinois at
     797              :         //   Urbana-Champaign (Dept. of Mechanical and Industrial Engineering).
     798              : 
     799              :         // Using/Aliasing
     800            0 :         auto &thisHTR = state.dataHighTempRadSys->HighTempRadSys(RadSysNum);
     801              : 
     802              :         // initialize local variables
     803            0 :         int ZoneNum = thisHTR.ZonePtr;
     804            0 :         Real64 HeatFrac = 0.0; // fraction of maximum energy input to radiant system [dimensionless]
     805              : 
     806            0 :         if (thisHTR.availSched->getCurrentVal() <= 0) {
     807              : 
     808              :             // Unit is off or has no load upon it; set the flow rates to zero and then
     809              :             // simulate the components with the no flow conditions
     810            0 :             thisHTR.QHTRRadSource = 0.0;
     811              : 
     812              :         } else { // Unit might be on-->this section is intended to control the output of the
     813              :             // high temperature radiant heater (temperature controlled)
     814              : 
     815              :             // Determine the current setpoint temperature and the temperature at which the unit should be completely off
     816            0 :             Real64 SetPtTemp = thisHTR.setptSched->getCurrentVal();
     817            0 :             Real64 OffTemp = SetPtTemp + 0.5 * thisHTR.ThrottlRange;
     818            0 :             auto const &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
     819            0 :             Real64 OpTemp = (thisZoneHB.MAT + thisZoneHB.MRT) / 2.0; // Approximate the "operative" temperature
     820              : 
     821              :             // Determine the fraction of maximum power to the unit (limiting the fraction range from zero to unity)
     822            0 :             switch (thisHTR.ControlType) {
     823            0 :             case RadControlType::MATControl: {
     824            0 :                 HeatFrac = (OffTemp - thisZoneHB.MAT) / thisHTR.ThrottlRange;
     825            0 :             } break;
     826            0 :             case RadControlType::MRTControl: {
     827            0 :                 HeatFrac = (OffTemp - thisZoneHB.MRT) / thisHTR.ThrottlRange;
     828            0 :             } break;
     829            0 :             case RadControlType::OperativeControl: {
     830            0 :                 OpTemp = 0.5 * (thisZoneHB.MAT + thisZoneHB.MRT);
     831            0 :                 HeatFrac = (OffTemp - OpTemp) / thisHTR.ThrottlRange;
     832            0 :             } break;
     833            0 :             default:
     834            0 :                 break;
     835              :             }
     836            0 :             if (HeatFrac < 0.0) HeatFrac = 0.0;
     837            0 :             if (HeatFrac > 1.0) HeatFrac = 1.0;
     838              : 
     839              :             // Set the heat source for the high temperature electric radiant system
     840            0 :             thisHTR.QHTRRadSource = HeatFrac * thisHTR.MaxPowerCapac;
     841              :         }
     842            0 :     }
     843              : 
     844            0 :     void CalcHighTempRadiantSystemSP(
     845              :         EnergyPlusData &state,
     846              :         [[maybe_unused]] bool const FirstHVACIteration, // true if this is the first HVAC iteration at this system time step !unused1208
     847              :         int const RadSysNum                             // name of the low temperature radiant system
     848              :     )
     849              :     {
     850              : 
     851              :         // SUBROUTINE INFORMATION:
     852              :         //       AUTHOR         Rick Strand
     853              :         //       DATE WRITTEN   February 2008
     854              :         //       MODIFIED       Sep 2011 LKL/BG - resimulate only zones needing it for Radiant systems
     855              : 
     856              :         // PURPOSE OF THIS SUBROUTINE:
     857              :         // This subroutine does all of the stuff that is necessary to simulate
     858              :         // a high temperature radiant heating system using setpoint temperature control.
     859              : 
     860              :         // METHODOLOGY EMPLOYED:
     861              :         // Follows the methods used by many other pieces of zone equipment except
     862              :         // that we are controlling the input to the heater element.  Note that
     863              :         // cooling is not allowed for such a system.  Controls are very basic and
     864              :         // use an iterative approach to get close to what we need.
     865              : 
     866              :         // REFERENCES:
     867              :         // Other EnergyPlus modules
     868              :         // Building Systems Laboratory, BLAST User's Guide/Reference.
     869              :         // Fanger, P.O. "Analysis and Applications in Environmental Engineering",
     870              :         //   Danish Technical Press, 1970.
     871              :         // Maloney, Dan. 1987. "Development of a radiant heater model and the
     872              :         //   incorporation of thermal comfort considerations into the BLAST
     873              :         //   energy analysis program", M.S. thesis, University of Illinois at
     874              :         //   Urbana-Champaign (Dept. of Mechanical and Industrial Engineering).
     875              : 
     876              :         // Using/Aliasing
     877            0 :         auto &thisHTR = state.dataHighTempRadSys->HighTempRadSys(RadSysNum);
     878              : 
     879              :         // SUBROUTINE PARAMETER DEFINITIONS:
     880            0 :         float const TempConvToler(0.1f); // Temperature controller tries to converge to within 0.1C
     881            0 :         int constexpr MaxIterations(10); // Maximum number of iterations to achieve temperature control
     882              :         // (10 interval halvings achieves control to 0.1% of capacity)
     883              :         // These two parameters are intended to achieve reasonable control
     884              :         // without excessive run times.
     885              : 
     886              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     887            0 :         Real64 ZoneTemp(0.0); // zone temperature (MAT, MRT, or Operative Temperature, depending on control type) [C]
     888              : 
     889              :         // initialize local variables
     890            0 :         int ZoneNum = thisHTR.ZonePtr;
     891            0 :         thisHTR.QHTRRadSource = 0.0;
     892              : 
     893            0 :         if (thisHTR.availSched->getCurrentVal() > 0) {
     894              : 
     895              :             // Unit is scheduled on-->this section is intended to control the output of the
     896              :             // high temperature radiant heater (temperature controlled)
     897              : 
     898              :             // Determine the current setpoint temperature and the temperature at which the unit should be completely off
     899            0 :             Real64 SetPtTemp = thisHTR.setptSched->getCurrentVal();
     900              : 
     901              :             // Now, distribute the radiant energy of all systems to the appropriate
     902              :             // surfaces, to people, and the air; determine the latent portion
     903            0 :             DistributeHTRadGains(state);
     904              : 
     905              :             // Now "simulate" the system by recalculating the heat balances
     906            0 :             HeatBalanceSurfaceManager::CalcHeatBalanceOutsideSurf(state, ZoneNum);
     907            0 :             HeatBalanceSurfaceManager::CalcHeatBalanceInsideSurf(state, ZoneNum);
     908              : 
     909              :             // First determine whether or not the unit should be on
     910              :             // Determine the proper temperature on which to control
     911            0 :             auto const &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
     912            0 :             switch (thisHTR.ControlType) {
     913            0 :             case RadControlType::MATSPControl: {
     914            0 :                 ZoneTemp = thisZoneHB.MAT;
     915            0 :             } break;
     916            0 :             case RadControlType::MRTSPControl: {
     917            0 :                 ZoneTemp = thisZoneHB.MRT;
     918            0 :             } break;
     919            0 :             case RadControlType::OperativeSPControl: {
     920            0 :                 ZoneTemp = 0.5 * (thisZoneHB.MAT + thisZoneHB.MRT);
     921            0 :             } break;
     922            0 :             default: {
     923            0 :                 assert(false);
     924              :             } break;
     925              :             }
     926              : 
     927            0 :             if (ZoneTemp < (SetPtTemp - TempConvToler)) {
     928              : 
     929              :                 // Use simple interval halving to find the best operating fraction to achieve proper temperature control
     930            0 :                 int IterNum = 0;
     931            0 :                 bool ConvergFlag = false;
     932              :                 float HeatFrac; // fraction of maximum energy input to radiant system [dimensionless]
     933            0 :                 float HeatFracMax = 1.0;
     934            0 :                 float HeatFracMin = 0.0;
     935              : 
     936            0 :                 while ((IterNum <= MaxIterations) && (!ConvergFlag)) {
     937              : 
     938              :                     // In the first iteration (IterNum=0), try full capacity and see if that is the best solution
     939            0 :                     if (IterNum == 0) {
     940            0 :                         HeatFrac = 1.0;
     941              :                     } else {
     942            0 :                         HeatFrac = (HeatFracMin + HeatFracMax) / 2.0;
     943              :                     }
     944              : 
     945              :                     // Set the heat source for the high temperature radiant system
     946            0 :                     thisHTR.QHTRRadSource = HeatFrac * thisHTR.MaxPowerCapac;
     947              : 
     948              :                     // Now, distribute the radiant energy of all systems to the appropriate
     949              :                     // surfaces, to people, and the air; determine the latent portion
     950            0 :                     DistributeHTRadGains(state);
     951              : 
     952              :                     // Now "simulate" the system by recalculating the heat balances
     953            0 :                     HeatBalanceSurfaceManager::CalcHeatBalanceOutsideSurf(state, ZoneNum);
     954            0 :                     HeatBalanceSurfaceManager::CalcHeatBalanceInsideSurf(state, ZoneNum);
     955              : 
     956              :                     // Redetermine the current value of the controlling temperature
     957            0 :                     auto const &thisZoneHBMod = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
     958            0 :                     switch (thisHTR.ControlType) {
     959            0 :                     case RadControlType::MATControl: {
     960            0 :                         ZoneTemp = thisZoneHBMod.MAT;
     961            0 :                     } break;
     962            0 :                     case RadControlType::MRTControl: {
     963            0 :                         ZoneTemp = thisZoneHBMod.MRT;
     964            0 :                     } break;
     965            0 :                     case RadControlType::OperativeControl: {
     966            0 :                         ZoneTemp = 0.5 * (thisZoneHBMod.MAT + thisZoneHBMod.MRT);
     967            0 :                     } break;
     968            0 :                     default:
     969            0 :                         break;
     970              :                     }
     971              : 
     972            0 :                     if ((std::abs(ZoneTemp - SetPtTemp)) <= TempConvToler) {
     973              :                         // The radiant heater has controlled the zone temperature to the appropriate level--stop iterating
     974            0 :                         ConvergFlag = true;
     975            0 :                     } else if (ZoneTemp < SetPtTemp) {
     976              :                         // The zone temperature is too low--try increasing the radiant heater output
     977            0 :                         if (IterNum == 0) {
     978              :                             // Heater already at capacity--this is the best that we can do
     979            0 :                             ConvergFlag = true;
     980              :                         } else {
     981            0 :                             HeatFracMin = HeatFrac;
     982              :                         }
     983              :                     } else { // (ZoneTemp > SetPtTemp)
     984              :                         // The zone temperature is too high--try decreasing the radiant heater output
     985            0 :                         if (IterNum > 0) HeatFracMax = HeatFrac;
     986              :                     }
     987              : 
     988            0 :                     ++IterNum;
     989              :                 }
     990              :             }
     991              :         }
     992            0 :     }
     993              : 
     994            0 :     void UpdateHighTempRadiantSystem(EnergyPlusData &state,
     995              :                                      int const RadSysNum, // Index for the low temperature radiant system under consideration within the derived types
     996              :                                      Real64 &LoadMet      // load met by the radiant system, in Watts
     997              :     )
     998              :     {
     999              : 
    1000              :         // SUBROUTINE INFORMATION:
    1001              :         //       AUTHOR         Rick Strand
    1002              :         //       DATE WRITTEN   February 2001
    1003              : 
    1004              :         // PURPOSE OF THIS SUBROUTINE:
    1005              :         // This subroutine does any updating that needs to be done for high
    1006              :         // temperature radiant heating systems.  This routine has two functions.
    1007              :         // First, it needs to keep track of the average high temperature
    1008              :         // radiant source.  The method for doing this is similar to low
    1009              :         // temperature systems except that heat input is kept locally on
    1010              :         // a system basis rather than a surface basis.  This is because a high
    1011              :         // temperature system affects many surfaces while a low temperature
    1012              :         // system directly affects only one surface.  This leads to the second
    1013              :         // function of this subroutine which is to account for the affect of
    1014              :         // all high temperature radiant systems on each surface.  This
    1015              :         // distribution must be "redone" every time to be sure that we have
    1016              :         // properly accounted for all of the systems.
    1017              : 
    1018              :         // METHODOLOGY EMPLOYED:
    1019              :         // For the source average update, if the system time step elapsed is
    1020              :         // still what it used to be, then either we are still iterating or we
    1021              :         // had to go back and shorten the time step.  As a result, we have to
    1022              :         // subtract out the previous value that we added.  If the system time
    1023              :         // step elapsed is different, then we just need to add the new values
    1024              :         // to the running average.
    1025              : 
    1026              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1027              :         int ZoneNum; // Zone index number for the current radiant system
    1028            0 :         Real64 SysTimeElapsed = state.dataHVACGlobal->SysTimeElapsed;
    1029            0 :         Real64 TimeStepSys = state.dataHVACGlobal->TimeStepSys;
    1030            0 :         auto &thisHTR = state.dataHighTempRadSys->HighTempRadSys(RadSysNum);
    1031              : 
    1032              :         // First, update the running average if necessary...
    1033            0 :         if (thisHTR.LastSysTimeElapsed == SysTimeElapsed) {
    1034              :             // Still iterating or reducing system time step, so subtract old values which were
    1035              :             // not valid
    1036            0 :             thisHTR.QHTRRadSrcAvg -= thisHTR.LastQHTRRadSrc * thisHTR.LastTimeStepSys / state.dataGlobal->TimeStepZone;
    1037              :         }
    1038              : 
    1039              :         // Update the running average and the "last" values with the current values of the appropriate variables
    1040            0 :         thisHTR.QHTRRadSrcAvg += thisHTR.QHTRRadSource * TimeStepSys / state.dataGlobal->TimeStepZone;
    1041              : 
    1042            0 :         thisHTR.LastQHTRRadSrc = thisHTR.QHTRRadSource;
    1043            0 :         thisHTR.LastSysTimeElapsed = SysTimeElapsed;
    1044            0 :         thisHTR.LastTimeStepSys = TimeStepSys;
    1045              : 
    1046            0 :         switch (thisHTR.ControlType) {
    1047            0 :         case RadControlType::MATControl:
    1048              :         case RadControlType::MRTControl:
    1049              :         case RadControlType::OperativeControl: {
    1050              :             // Only need to do this for the non-SP controls (SP has already done this enough)
    1051              :             // Now, distribute the radiant energy of all systems to the appropriate
    1052              :             // surfaces, to people, and the air; determine the latent portion
    1053            0 :             DistributeHTRadGains(state);
    1054              : 
    1055              :             // Now "simulate" the system by recalculating the heat balances
    1056            0 :             ZoneNum = thisHTR.ZonePtr;
    1057            0 :             HeatBalanceSurfaceManager::CalcHeatBalanceOutsideSurf(state, ZoneNum);
    1058            0 :             HeatBalanceSurfaceManager::CalcHeatBalanceInsideSurf(state, ZoneNum);
    1059            0 :         } break;
    1060            0 :         default:
    1061            0 :             break;
    1062              :         }
    1063              : 
    1064            0 :         if (thisHTR.QHTRRadSource <= 0.0) {
    1065            0 :             LoadMet = 0.0; // System wasn't running so it can't meet a load
    1066              :         } else {
    1067            0 :             ZoneNum = thisHTR.ZonePtr;
    1068            0 :             LoadMet = (state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state) - thisHTR.ZeroHTRSourceSumHATsurf) +
    1069            0 :                       state.dataHeatBalFanSys->SumConvHTRadSys(ZoneNum);
    1070              :         }
    1071            0 :     }
    1072              : 
    1073       249945 :     void UpdateHTRadSourceValAvg(EnergyPlusData &state, bool &HighTempRadSysOn) // .TRUE. if the radiant system has run this zone time step
    1074              :     {
    1075              : 
    1076              :         // SUBROUTINE INFORMATION:
    1077              :         //       AUTHOR         Rick Strand
    1078              :         //       DATE WRITTEN   February 2001
    1079              : 
    1080              :         // PURPOSE OF THIS SUBROUTINE:
    1081              :         // To transfer the average value of the heat source over the entire
    1082              :         // zone time step back to the heat balance routines so that the heat
    1083              :         // balance algorithms can simulate one last time with the average source
    1084              :         // to maintain some reasonable amount of continuity and energy balance
    1085              :         // in the temperature and flux histories.
    1086              : 
    1087              :         // METHODOLOGY EMPLOYED:
    1088              :         // All of the record keeping for the average term is done in the Update
    1089              :         // routine so the only other thing that this subroutine does is check to
    1090              :         // see if the system was even on.  If any average term is non-zero, then
    1091              :         // one or more of the radiant systems was running.
    1092              : 
    1093       249945 :         HighTempRadSysOn = false;
    1094              : 
    1095              :         // If this was never allocated, then there are no radiant systems in this input file (just RETURN)
    1096       249945 :         if (state.dataHighTempRadSys->NumOfHighTempRadSys == 0) return;
    1097              : 
    1098              :         // If it was allocated, then we have to check to see if this was running at all...
    1099            0 :         for (auto &thisHTR : state.dataHighTempRadSys->HighTempRadSys) {
    1100            0 :             thisHTR.QHTRRadSource = thisHTR.QHTRRadSrcAvg;
    1101            0 :             if (thisHTR.QHTRRadSrcAvg != 0.0) HighTempRadSysOn = true;
    1102              :         }
    1103              : 
    1104            0 :         DistributeHTRadGains(
    1105              :             state); // state.dataHighTempRadSys->HighTempRadSys(RadSysNum).QHTRRadSource has been modified so we need to redistribute gains
    1106              :     }
    1107              : 
    1108            0 :     void DistributeHTRadGains(EnergyPlusData &state)
    1109              :     {
    1110              : 
    1111              :         // SUBROUTINE INFORMATION:
    1112              :         //       AUTHOR         Rick Strand
    1113              :         //       DATE WRITTEN   February 2001
    1114              :         //       MODIFIED       April 2010 Brent Griffith, max limit to protect surface temperature calcs
    1115              : 
    1116              :         // PURPOSE OF THIS SUBROUTINE:
    1117              :         // To distribute the gains from the high temperature radiant heater
    1118              :         // as specified in the user input file.  This includes distribution
    1119              :         // of long wavelength radiant gains to surfaces and "people" as well
    1120              :         // as latent, lost, and convective portions of the total gain.
    1121              : 
    1122              :         // METHODOLOGY EMPLOYED:
    1123              :         // We must cycle through all of the radiant systems because each
    1124              :         // surface could feel the effect of more than one radiant system.
    1125              :         // Note that the energy radiated to people is assumed to affect them
    1126              :         // but them it is assumed to be convected to the air.  This is why
    1127              :         // the convective portion shown below has two parts to it.
    1128              : 
    1129              :         // SUBROUTINE PARAMETER DEFINITIONS:
    1130            0 :         Real64 constexpr SmallestArea = 0.001; // Smallest area in meters squared (to avoid a divide by zero)
    1131              : 
    1132              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1133              :         Real64 ThisSurfIntensity; // temporary for W/m2 term for rad on a surface
    1134              : 
    1135              :         // Using/Aliasing
    1136            0 :         auto &dataHBFS = state.dataHeatBalFanSys;
    1137              : 
    1138              :         // Initialize arrays
    1139            0 :         dataHBFS->SumConvHTRadSys = 0.0;
    1140            0 :         dataHBFS->SumLatentHTRadSys = 0.0;
    1141            0 :         for (auto &thisHTR : state.dataHighTempRadSys->HighTempRadSys) {
    1142            0 :             for (int radSurfNum = 1; radSurfNum <= thisHTR.TotSurfToDistrib; ++radSurfNum) {
    1143            0 :                 int surfNum = thisHTR.SurfacePtr(radSurfNum);
    1144            0 :                 state.dataHeatBalFanSys->surfQRadFromHVAC(surfNum).HTRadSys = 0.0;
    1145              :             }
    1146              :         }
    1147            0 :         dataHBFS->ZoneQHTRadSysToPerson = 0.0;
    1148              : 
    1149            0 :         for (auto &thisHTR : state.dataHighTempRadSys->HighTempRadSys) {
    1150            0 :             int ZoneNum = thisHTR.ZonePtr;
    1151              : 
    1152            0 :             dataHBFS->ZoneQHTRadSysToPerson(ZoneNum) = thisHTR.QHTRRadSource * thisHTR.FracRadiant * thisHTR.FracDistribPerson;
    1153            0 :             dataHBFS->SumConvHTRadSys(ZoneNum) += thisHTR.QHTRRadSource * thisHTR.FracConvect;
    1154            0 :             dataHBFS->SumLatentHTRadSys(ZoneNum) += thisHTR.QHTRRadSource * thisHTR.FracLatent;
    1155              : 
    1156            0 :             for (int RadSurfNum = 1; RadSurfNum <= thisHTR.TotSurfToDistrib; ++RadSurfNum) {
    1157            0 :                 int SurfNum = thisHTR.SurfacePtr(RadSurfNum);
    1158            0 :                 if (state.dataSurface->Surface(SurfNum).Area > SmallestArea) {
    1159            0 :                     ThisSurfIntensity = (thisHTR.QHTRRadSource * thisHTR.FracRadiant * thisHTR.FracDistribToSurf(RadSurfNum) /
    1160            0 :                                          state.dataSurface->Surface(SurfNum).Area);
    1161            0 :                     state.dataHeatBalFanSys->surfQRadFromHVAC(SurfNum).HTRadSys += ThisSurfIntensity;
    1162              : 
    1163            0 :                     if (ThisSurfIntensity > DataHeatBalFanSys::MaxRadHeatFlux) { // CR 8074, trap excessive intensity (throws off surface balance )
    1164            0 :                         ShowSevereError(state, "DistributeHTRadGains:  excessive thermal radiation heat flux intensity detected");
    1165            0 :                         ShowContinueError(state, format("Surface = {}", state.dataSurface->Surface(SurfNum).Name));
    1166            0 :                         ShowContinueError(state, format("Surface area = {:.3R} [m2]", state.dataSurface->Surface(SurfNum).Area));
    1167            0 :                         ShowContinueError(state, format("Occurs in ZoneHVAC:HighTemperatureRadiant = {}", thisHTR.Name));
    1168            0 :                         ShowContinueError(state, format("Radiation intensity = {:.2R} [W/m2]", ThisSurfIntensity));
    1169            0 :                         ShowContinueError(state, "Assign a larger surface area or more surfaces in ZoneHVAC:HighTemperatureRadiant");
    1170            0 :                         ShowFatalError(state, "DistributeHTRadGains:  excessive thermal radiation heat flux intensity detected");
    1171              :                     }
    1172              :                 } else { // small surface
    1173            0 :                     ShowSevereError(state, "DistributeHTRadGains:  surface not large enough to receive thermal radiation heat flux");
    1174            0 :                     ShowContinueError(state, format("Surface = {}", state.dataSurface->Surface(SurfNum).Name));
    1175            0 :                     ShowContinueError(state, format("Surface area = {:.3R} [m2]", state.dataSurface->Surface(SurfNum).Area));
    1176            0 :                     ShowContinueError(state, format("Occurs in ZoneHVAC:HighTemperatureRadiant = {}", thisHTR.Name));
    1177            0 :                     ShowContinueError(state, "Assign a larger surface area or more surfaces in ZoneHVAC:HighTemperatureRadiant");
    1178            0 :                     ShowFatalError(state, "DistributeHTRadGains:  surface not large enough to receive thermal radiation heat flux");
    1179              :                 }
    1180              :             }
    1181              :         }
    1182              : 
    1183              :         // Here an assumption is made regarding radiant heat transfer to people.
    1184              :         // While the ZoneQHTRadSysToPerson array will be used by the thermal comfort
    1185              :         // routines, the energy transfer to people would get lost from the perspective
    1186              :         // of the heat balance.  So, to avoid this net loss of energy which clearly
    1187              :         // gets added to the zones, we must account for it somehow.  This assumption
    1188              :         // that all energy radiated to people is converted to convective energy is
    1189              :         // not very precise, but at least it conserves energy.
    1190            0 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    1191            0 :             dataHBFS->SumConvHTRadSys(ZoneNum) += dataHBFS->ZoneQHTRadSysToPerson(ZoneNum);
    1192              :         }
    1193            0 :     }
    1194              : 
    1195            0 :     void ReportHighTempRadiantSystem(EnergyPlusData &state,
    1196              :                                      int const RadSysNum) // Index for the low temperature radiant system under consideration within the derived types
    1197              :     {
    1198              : 
    1199              :         // SUBROUTINE INFORMATION:
    1200              :         //       AUTHOR         Rick Strand
    1201              :         //       DATE WRITTEN   February 2001
    1202              : 
    1203              :         // PURPOSE OF THIS SUBROUTINE:
    1204              :         // This subroutine simply produces output for the high temperature radiant system.
    1205              : 
    1206              :         // Using/Aliasing
    1207            0 :         Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
    1208            0 :         auto &thisHTR = state.dataHighTempRadSys->HighTempRadSys(RadSysNum);
    1209              : 
    1210            0 :         if (thisHTR.HeaterType == Constant::eResource::NaturalGas) {
    1211            0 :             thisHTR.GasPower = thisHTR.QHTRRadSource / thisHTR.CombustionEffic;
    1212            0 :             thisHTR.GasEnergy = thisHTR.GasPower * TimeStepSysSec;
    1213            0 :             thisHTR.ElecPower = 0.0;
    1214            0 :             thisHTR.ElecEnergy = 0.0;
    1215            0 :         } else if (thisHTR.HeaterType == Constant::eResource::Electricity) {
    1216            0 :             thisHTR.GasPower = 0.0;
    1217            0 :             thisHTR.GasEnergy = 0.0;
    1218            0 :             thisHTR.ElecPower = thisHTR.QHTRRadSource;
    1219            0 :             thisHTR.ElecEnergy = thisHTR.ElecPower * TimeStepSysSec;
    1220              :         } else {
    1221            0 :             ShowWarningError(state, "Someone forgot to add a high temperature radiant heater type to the reporting subroutine");
    1222              :         }
    1223            0 :         thisHTR.HeatPower = thisHTR.QHTRRadSource;
    1224            0 :         thisHTR.HeatEnergy = thisHTR.HeatPower * TimeStepSysSec;
    1225            0 :     }
    1226              : 
    1227              : } // namespace HighTempRadiantSystem
    1228              : 
    1229              : } // namespace EnergyPlus
        

Generated by: LCOV version 2.0-1