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

Generated by: LCOV version 2.0-1