LCOV - code coverage report
Current view: top level - EnergyPlus - ChilledCeilingPanelSimple.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 515 822 62.7 %
Date: 2024-08-24 18:31:18 Functions: 11 11 100.0 %

          Line data    Source code
       1             : // EnergyPlus, Copyright (c) 1996-2024, The Board of Trustees of the University of Illinois,
       2             : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3             : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4             : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5             : // contributors. All rights reserved.
       6             : //
       7             : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8             : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9             : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10             : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11             : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12             : //
      13             : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14             : // provided that the following conditions are met:
      15             : //
      16             : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17             : //     conditions and the following disclaimer.
      18             : //
      19             : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20             : //     conditions and the following disclaimer in the documentation and/or other materials
      21             : //     provided with the distribution.
      22             : //
      23             : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24             : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25             : //     used to endorse or promote products derived from this software without specific prior
      26             : //     written permission.
      27             : //
      28             : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29             : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30             : //     reference solely to the software portion of its product, Licensee must refer to the
      31             : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32             : //     obtained under this License and may not use a different name for the software. Except as
      33             : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34             : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35             : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36             : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37             : //
      38             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39             : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40             : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41             : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42             : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43             : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45             : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46             : // POSSIBILITY OF SUCH DAMAGE.
      47             : 
      48             : // C++ Headers
      49             : #include <cmath>
      50             : 
      51             : // ObjexxFCL Headers
      52             : #include <ObjexxFCL/Array.functions.hh>
      53             : #include <ObjexxFCL/Fmath.hh>
      54             : 
      55             : // EnergyPlus Headers
      56             : #include <EnergyPlus/Autosizing/CoolingCapacitySizing.hh>
      57             : #include <EnergyPlus/BranchNodeConnections.hh>
      58             : #include <EnergyPlus/ChilledCeilingPanelSimple.hh>
      59             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      60             : #include <EnergyPlus/DataEnvironment.hh>
      61             : #include <EnergyPlus/DataHVACGlobals.hh>
      62             : #include <EnergyPlus/DataHeatBalFanSys.hh>
      63             : #include <EnergyPlus/DataHeatBalSurface.hh>
      64             : #include <EnergyPlus/DataHeatBalance.hh>
      65             : #include <EnergyPlus/DataIPShortCuts.hh>
      66             : #include <EnergyPlus/DataSizing.hh>
      67             : #include <EnergyPlus/DataSurfaces.hh>
      68             : #include <EnergyPlus/DataZoneEnergyDemands.hh>
      69             : #include <EnergyPlus/DataZoneEquipment.hh>
      70             : #include <EnergyPlus/FluidProperties.hh>
      71             : #include <EnergyPlus/GeneralRoutines.hh>
      72             : #include <EnergyPlus/HeatBalanceIntRadExchange.hh>
      73             : #include <EnergyPlus/HeatBalanceSurfaceManager.hh>
      74             : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      75             : #include <EnergyPlus/NodeInputManager.hh>
      76             : #include <EnergyPlus/OutputProcessor.hh>
      77             : #include <EnergyPlus/Plant/DataPlant.hh>
      78             : #include <EnergyPlus/PlantUtilities.hh>
      79             : #include <EnergyPlus/Psychrometrics.hh>
      80             : #include <EnergyPlus/ScheduleManager.hh>
      81             : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
      82             : 
      83             : namespace EnergyPlus::CoolingPanelSimple {
      84             : 
      85             : // Module -- (ref: Object: ZoneHVAC:CoolingPanel:RadiantConvective:Water)
      86             : 
      87             : // Module containing the routines dealing with the simple (chilled ceiling) cooling panels
      88             : 
      89             : // MODULE INFORMATION:
      90             : //       AUTHOR         Rick Strand
      91             : //       DATE WRITTEN   Aug 2014
      92             : 
      93             : // PURPOSE OF THIS MODULE:
      94             : // The purpose of this module is to simulate simple chilled ceiling panels.  It is similar to
      95             : // hot water radiant/convective baseboard units and the code for this model used that model as
      96             : // a starting point.
      97             : 
      98             : // REFERENCES:
      99             : // Existing code for hot water baseboard models (radiant-convective variety)
     100             : 
     101             : // USE STATEMENTS:
     102             : // MODULE PARAMETER DEFINITIONS
     103             : std::string const cCMO_CoolingPanel_Simple("ZoneHVAC:CoolingPanel:RadiantConvective:Water");
     104             : 
     105       22415 : void SimCoolingPanel(
     106             :     EnergyPlusData &state, std::string const &EquipName, int const ControlledZoneNum, bool const FirstHVACIteration, Real64 &PowerMet, int &CompIndex)
     107             : {
     108             : 
     109             :     // SUBROUTINE INFORMATION:
     110             :     //       AUTHOR         Rick Strand
     111             :     //       DATE WRITTEN   Aug 2014
     112             : 
     113             :     // PURPOSE OF THIS SUBROUTINE:
     114             :     // This subroutine simulates the simple cooling (chilled ceiling) panel.  It borrows heavily
     115             :     // from the hot water radiant-convective baseboard model code.
     116             : 
     117             :     // REFERENCES:
     118             :     // Existing code for hot water baseboard models (radiant-convective variety)
     119             : 
     120             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     121             :     int CoolingPanelNum; // Index of unit in baseboard array
     122             :     Real64 QZnReq;       // Zone load not yet satisfied
     123             :     Real64 MaxWaterFlow;
     124             :     Real64 MinWaterFlow;
     125             : 
     126       22415 :     if (state.dataChilledCeilingPanelSimple->GetInputFlag) {
     127           4 :         GetCoolingPanelInput(state);
     128           4 :         state.dataChilledCeilingPanelSimple->GetInputFlag = false;
     129             :     }
     130             : 
     131             :     // Find the correct Baseboard Equipment
     132       22415 :     if (CompIndex == 0) {
     133           4 :         CoolingPanelNum = Util::FindItemInList(EquipName,
     134           4 :                                                state.dataChilledCeilingPanelSimple->CoolingPanel,
     135             :                                                &CoolingPanelParams::Name,
     136           4 :                                                (int)state.dataChilledCeilingPanelSimple->CoolingPanel.size());
     137           4 :         if (CoolingPanelNum == 0) {
     138           0 :             ShowFatalError(state, format("SimCoolingPanelSimple: Unit not found={}", EquipName));
     139             :         }
     140           4 :         CompIndex = CoolingPanelNum;
     141             :     } else {
     142       22411 :         CoolingPanelNum = CompIndex;
     143       22411 :         if (CoolingPanelNum > (int)state.dataChilledCeilingPanelSimple->CoolingPanel.size() || CoolingPanelNum < 1) {
     144           0 :             ShowFatalError(state,
     145           0 :                            format("SimCoolingPanelSimple:  Invalid CompIndex passed={}, Number of Units={}, Entered Unit name={}",
     146             :                                   CoolingPanelNum,
     147           0 :                                   (int)state.dataChilledCeilingPanelSimple->CoolingPanel.size(),
     148             :                                   EquipName));
     149             :         }
     150       22411 :         if (state.dataChilledCeilingPanelSimple->CoolingPanel(CoolingPanelNum).CheckEquipName) {
     151           4 :             if (EquipName != state.dataChilledCeilingPanelSimple->CoolingPanel(CoolingPanelNum).Name) {
     152           0 :                 ShowFatalError(state,
     153           0 :                                format("SimCoolingPanelSimple: Invalid CompIndex passed={}, Unit name={}, stored Unit Name for that index={}",
     154             :                                       CoolingPanelNum,
     155             :                                       EquipName,
     156           0 :                                       state.dataChilledCeilingPanelSimple->CoolingPanel(CoolingPanelNum).Name));
     157             :             }
     158           4 :             state.dataChilledCeilingPanelSimple->CoolingPanel(CoolingPanelNum).CheckEquipName = false;
     159             :         }
     160             :     }
     161             : 
     162       22415 :     if (CompIndex > 0) {
     163             : 
     164       22415 :         auto &thisCP(state.dataChilledCeilingPanelSimple->CoolingPanel(CoolingPanelNum));
     165             : 
     166       22415 :         InitCoolingPanel(state, CoolingPanelNum, ControlledZoneNum, FirstHVACIteration);
     167             : 
     168       22415 :         QZnReq = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlledZoneNum).RemainingOutputReqToCoolSP;
     169             : 
     170             :         // On the first HVAC iteration the system values are given to the controller, but after that
     171             :         // the demand limits are in place and there needs to be feedback to the Zone Equipment
     172       22415 :         if (FirstHVACIteration) {
     173       10287 :             MaxWaterFlow = thisCP.WaterMassFlowRateMax;
     174       10287 :             MinWaterFlow = 0.0;
     175             :         } else {
     176       12128 :             MaxWaterFlow = state.dataLoopNodes->Node(thisCP.WaterInletNode).MassFlowRateMaxAvail;
     177       12128 :             MinWaterFlow = state.dataLoopNodes->Node(thisCP.WaterInletNode).MassFlowRateMinAvail;
     178             :         }
     179             : 
     180       22415 :         switch (thisCP.EquipType) {
     181       22415 :         case DataPlant::PlantEquipmentType::CoolingPanel_Simple: { // 'ZoneHVAC:CoolingPanel:RadiantConvective:Water'
     182       22415 :             thisCP.CalcCoolingPanel(state, CoolingPanelNum);
     183       22415 :         } break;
     184           0 :         default: {
     185           0 :             ShowSevereError(
     186             :                 state,
     187           0 :                 format("SimCoolingPanelSimple: Errors in CoolingPanel={}", state.dataChilledCeilingPanelSimple->CoolingPanel(CoolingPanelNum).Name));
     188           0 :             ShowContinueError(
     189             :                 state,
     190           0 :                 format("Invalid or unimplemented equipment type={}", state.dataChilledCeilingPanelSimple->CoolingPanel(CoolingPanelNum).EquipType));
     191           0 :             ShowFatalError(state, "Preceding condition causes termination.");
     192           0 :         } break;
     193             :         }
     194             : 
     195       22415 :         PowerMet = thisCP.TotPower;
     196             : 
     197       22415 :         UpdateCoolingPanel(state, CoolingPanelNum);
     198             : 
     199       22415 :         state.dataChilledCeilingPanelSimple->CoolingPanel(CoolingPanelNum).ReportCoolingPanel(state);
     200             : 
     201             :     } else {
     202           0 :         ShowFatalError(state, format("SimCoolingPanelSimple: Unit not found={}", EquipName));
     203             :     }
     204       22415 : }
     205             : 
     206           4 : void GetCoolingPanelInput(EnergyPlusData &state)
     207             : {
     208             : 
     209             :     // SUBROUTINE INFORMATION:
     210             :     //       AUTHOR         Rick Strand
     211             :     //       DATE WRITTEN   Aug 2014
     212             : 
     213             :     // PURPOSE OF THIS SUBROUTINE:
     214             :     // This subroutine gets the input for the simple cooling panel units.
     215             : 
     216             :     // METHODOLOGY EMPLOYED:
     217             :     // Standard input processor calls--started from Daeho's radiant-convective water baseboard model.
     218             : 
     219             :     // SUBROUTINE PARAMETER DEFINITIONS:
     220             :     static constexpr std::string_view RoutineName("GetCoolingPanelInput:");
     221           4 :     Real64 constexpr MaxFraction(1.0);
     222           4 :     Real64 constexpr MinFraction(0.0);
     223           4 :     Real64 constexpr MaxWaterTempAvg(30.0);       // Maximum limit of average water temperature in degree C
     224           4 :     Real64 constexpr MinWaterTempAvg(0.0);        // Minimum limit of average water temperature in degree C
     225           4 :     Real64 constexpr MaxWaterFlowRate(10.0);      // Maximum limit of water volume flow rate in m3/s
     226           4 :     Real64 constexpr MinWaterFlowRate(0.00001);   // Minimum limit of water volume flow rate in m3/s
     227           4 :     Real64 constexpr WaterMassFlowDefault(0.063); // Default water mass flow rate in kg/s
     228           4 :     int constexpr MinDistribSurfaces(1);          // Minimum number of surfaces that a baseboard heater can radiate to
     229           4 :     Real64 constexpr MinThrottlingRange(0.5);     // Smallest throttling range allowed in degrees Celsius
     230             :     static constexpr std::string_view MeanAirTemperature("MeanAirTemperature");
     231             :     static constexpr std::string_view MeanRadiantTemperature("MeanRadiantTemperature");
     232             :     static constexpr std::string_view OperativeTemperature("OperativeTemperature");
     233             :     static constexpr std::string_view OutsideAirDryBulbTemperature("OutdoorDryBulbTemperature");
     234             :     static constexpr std::string_view OutsideAirWetBulbTemperature("OutdoorWetBulbTemperature");
     235             :     static constexpr std::string_view ZoneTotalLoad("ZoneTotalLoad");
     236             :     static constexpr std::string_view ZoneConvectiveLoad("ZoneConvectiveLoad");
     237             :     static constexpr std::string_view Off("Off");
     238             :     static constexpr std::string_view SimpleOff("SimpleOff");
     239             :     static constexpr std::string_view VariableOff("VariableOff");
     240             : 
     241             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     242             :     int NumAlphas;  // Number of Alphas for each GetobjectItem call
     243             :     int NumNumbers; // Number of Numbers for each GetobjectItem call
     244             :     int SurfNum;    // Surface number Do loop counter
     245             :     int IOStat;
     246           4 :     bool ErrorsFound(false); // If errors detected in input
     247           4 :     int NumCoolingPanels = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCMO_CoolingPanel_Simple);
     248             : 
     249             :     // Count total number of baseboard units
     250             : 
     251           4 :     state.dataChilledCeilingPanelSimple->CoolingPanel.allocate(NumCoolingPanels);
     252             : 
     253             :     // Get the data from the user input related to cooling panels
     254           8 :     for (int CoolingPanelNum = 1; CoolingPanelNum <= NumCoolingPanels; ++CoolingPanelNum) {
     255             : 
     256           8 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     257             :                                                                  cCMO_CoolingPanel_Simple,
     258             :                                                                  CoolingPanelNum,
     259           4 :                                                                  state.dataIPShortCut->cAlphaArgs,
     260             :                                                                  NumAlphas,
     261           4 :                                                                  state.dataIPShortCut->rNumericArgs,
     262             :                                                                  NumNumbers,
     263             :                                                                  IOStat,
     264           4 :                                                                  state.dataIPShortCut->lNumericFieldBlanks,
     265           4 :                                                                  state.dataIPShortCut->lAlphaFieldBlanks,
     266           4 :                                                                  state.dataIPShortCut->cAlphaFieldNames,
     267           4 :                                                                  state.dataIPShortCut->cNumericFieldNames);
     268             : 
     269           4 :         state.dataChilledCeilingPanelSimple->CoolingPanel(CoolingPanelNum).FieldNames.allocate(NumNumbers);
     270           4 :         state.dataChilledCeilingPanelSimple->CoolingPanel(CoolingPanelNum).FieldNames = "";
     271           4 :         state.dataChilledCeilingPanelSimple->CoolingPanel(CoolingPanelNum).FieldNames = state.dataIPShortCut->cNumericFieldNames;
     272             : 
     273           4 :         if (CoolingPanelNum > 1) {
     274           0 :             for (int CoolPanelNumI = 2; CoolPanelNumI <= NumCoolingPanels; ++CoolPanelNumI) {
     275           0 :                 if (state.dataIPShortCut->cAlphaArgs(1) == state.dataChilledCeilingPanelSimple->CoolingPanel(CoolPanelNumI).Name) {
     276           0 :                     ErrorsFound = true;
     277           0 :                     ShowSevereError(state,
     278           0 :                                     format("{} is used as a name for more than one simple COOLING PANEL.", state.dataIPShortCut->cAlphaArgs(1)));
     279           0 :                     ShowContinueError(state, "This is not allowed.");
     280             :                 }
     281             :             }
     282             :         }
     283             : 
     284           4 :         auto &thisCP(state.dataChilledCeilingPanelSimple->CoolingPanel(CoolingPanelNum));
     285           4 :         thisCP.Name = state.dataIPShortCut->cAlphaArgs(1);                     // Name of this simple cooling panel
     286           4 :         thisCP.EquipType = DataPlant::PlantEquipmentType::CoolingPanel_Simple; //'ZoneHVAC:CoolingPanel:RadiantConvective:Water'
     287             : 
     288             :         // Get schedule
     289           4 :         thisCP.Schedule = state.dataIPShortCut->cAlphaArgs(2);
     290           4 :         if (state.dataIPShortCut->lAlphaFieldBlanks(2)) {
     291           0 :             thisCP.SchedPtr = ScheduleManager::ScheduleAlwaysOn;
     292             :         } else {
     293           4 :             thisCP.SchedPtr = ScheduleManager::GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(2));
     294           4 :             if (thisCP.SchedPtr == 0) {
     295           0 :                 ShowSevereError(state,
     296           0 :                                 format("{}{}=\"{}\", {}=\"{}\" not found.",
     297             :                                        RoutineName,
     298             :                                        cCMO_CoolingPanel_Simple,
     299           0 :                                        state.dataIPShortCut->cAlphaArgs(1),
     300           0 :                                        state.dataIPShortCut->cAlphaFieldNames(2),
     301           0 :                                        state.dataIPShortCut->cAlphaArgs(2)));
     302           0 :                 ErrorsFound = true;
     303             :             }
     304             :         }
     305             : 
     306             :         // Get inlet node number
     307           4 :         thisCP.WaterInletNode = NodeInputManager::GetOnlySingleNode(state,
     308           4 :                                                                     state.dataIPShortCut->cAlphaArgs(3),
     309             :                                                                     ErrorsFound,
     310             :                                                                     DataLoopNode::ConnectionObjectType::ZoneHVACCoolingPanelRadiantConvectiveWater,
     311           4 :                                                                     state.dataIPShortCut->cAlphaArgs(1),
     312             :                                                                     DataLoopNode::NodeFluidType::Water,
     313             :                                                                     DataLoopNode::ConnectionType::Inlet,
     314             :                                                                     NodeInputManager::CompFluidStream::Primary,
     315             :                                                                     DataLoopNode::ObjectIsNotParent);
     316             : 
     317             :         // Get outlet node number
     318           4 :         thisCP.WaterOutletNode = NodeInputManager::GetOnlySingleNode(state,
     319           4 :                                                                      state.dataIPShortCut->cAlphaArgs(4),
     320             :                                                                      ErrorsFound,
     321             :                                                                      DataLoopNode::ConnectionObjectType::ZoneHVACCoolingPanelRadiantConvectiveWater,
     322           4 :                                                                      state.dataIPShortCut->cAlphaArgs(1),
     323             :                                                                      DataLoopNode::NodeFluidType::Water,
     324             :                                                                      DataLoopNode::ConnectionType::Outlet,
     325             :                                                                      NodeInputManager::CompFluidStream::Primary,
     326             :                                                                      DataLoopNode::ObjectIsNotParent);
     327           8 :         BranchNodeConnections::TestCompSet(state,
     328             :                                            cCMO_CoolingPanel_Simple,
     329           4 :                                            state.dataIPShortCut->cAlphaArgs(1),
     330           4 :                                            state.dataIPShortCut->cAlphaArgs(3),
     331           4 :                                            state.dataIPShortCut->cAlphaArgs(4),
     332             :                                            "Chilled Water Nodes");
     333             : 
     334           4 :         thisCP.RatedWaterTemp = state.dataIPShortCut->rNumericArgs(1);
     335           4 :         if (thisCP.RatedWaterTemp > MaxWaterTempAvg + 0.001) {
     336           0 :             ShowWarningError(state,
     337           0 :                              format("{}{}=\"{}\", {} was higher than the allowable maximum.",
     338             :                                     RoutineName,
     339             :                                     cCMO_CoolingPanel_Simple,
     340           0 :                                     state.dataIPShortCut->cAlphaArgs(1),
     341           0 :                                     state.dataIPShortCut->cNumericFieldNames(1)));
     342           0 :             ShowContinueError(state, format("...reset to maximum value=[{:.2R}].", MaxWaterTempAvg));
     343           0 :             thisCP.RatedWaterTemp = MaxWaterTempAvg;
     344           4 :         } else if (thisCP.RatedWaterTemp < MinWaterTempAvg - 0.001) {
     345           0 :             ShowWarningError(state,
     346           0 :                              format("{}{}=\"{}\", {} was lower than the allowable minimum.",
     347             :                                     RoutineName,
     348             :                                     cCMO_CoolingPanel_Simple,
     349           0 :                                     state.dataIPShortCut->cAlphaArgs(1),
     350           0 :                                     state.dataIPShortCut->cNumericFieldNames(1)));
     351           0 :             ShowContinueError(state, format("...reset to minimum value=[{:.2R}].", MinWaterTempAvg));
     352           0 :             thisCP.RatedWaterTemp = MinWaterTempAvg;
     353             :         }
     354             : 
     355           4 :         thisCP.RatedZoneAirTemp = state.dataIPShortCut->rNumericArgs(2);
     356           4 :         if (thisCP.RatedZoneAirTemp > MaxWaterTempAvg + 0.001) {
     357           0 :             ShowWarningError(state,
     358           0 :                              format("{}{}=\"{}\", {} was higher than the allowable maximum.",
     359             :                                     RoutineName,
     360             :                                     cCMO_CoolingPanel_Simple,
     361           0 :                                     state.dataIPShortCut->cAlphaArgs(1),
     362           0 :                                     state.dataIPShortCut->cNumericFieldNames(2)));
     363           0 :             ShowContinueError(state, format("...reset to maximum value=[{:.2R}].", MaxWaterTempAvg));
     364           0 :             thisCP.RatedZoneAirTemp = MaxWaterTempAvg;
     365           4 :         } else if (thisCP.RatedZoneAirTemp < MinWaterTempAvg - 0.001) {
     366           0 :             ShowWarningError(state,
     367           0 :                              format("{}{}=\"{}\", {} was lower than the allowable minimum.",
     368             :                                     RoutineName,
     369             :                                     cCMO_CoolingPanel_Simple,
     370           0 :                                     state.dataIPShortCut->cAlphaArgs(1),
     371           0 :                                     state.dataIPShortCut->cNumericFieldNames(2)));
     372           0 :             ShowContinueError(state, format("...reset to minimum value=[{:.2R}].", MinWaterTempAvg));
     373           0 :             thisCP.RatedZoneAirTemp = MinWaterTempAvg;
     374             :         }
     375             : 
     376           4 :         thisCP.RatedWaterFlowRate = state.dataIPShortCut->rNumericArgs(3);
     377           4 :         if (thisCP.RatedWaterFlowRate < 0.00001 || thisCP.RatedWaterFlowRate > 10.0) {
     378           0 :             ShowWarningError(state,
     379           0 :                              format("{}{}=\"{}\", {} is an invalid Standard Water mass flow rate.",
     380             :                                     RoutineName,
     381             :                                     cCMO_CoolingPanel_Simple,
     382           0 :                                     state.dataIPShortCut->cAlphaArgs(1),
     383           0 :                                     state.dataIPShortCut->cNumericFieldNames(2)));
     384           0 :             ShowContinueError(state, format("...reset to a default value=[{:.1R}].", WaterMassFlowDefault));
     385           0 :             thisCP.RatedWaterFlowRate = WaterMassFlowDefault;
     386             :         }
     387             : 
     388           4 :         if (Util::SameString(state.dataIPShortCut->cAlphaArgs(5), "CoolingDesignCapacity")) {
     389           2 :             thisCP.CoolingCapMethod = DataSizing::CoolingDesignCapacity;
     390           2 :             if (!state.dataIPShortCut->lNumericFieldBlanks(4)) {
     391           2 :                 thisCP.ScaledCoolingCapacity = state.dataIPShortCut->rNumericArgs(4);
     392           2 :                 if (thisCP.ScaledCoolingCapacity < 0.0 && thisCP.ScaledCoolingCapacity != DataSizing::AutoSize) {
     393           0 :                     ShowSevereError(state, format("{} = {}", cCMO_CoolingPanel_Simple, thisCP.Name));
     394           0 :                     ShowContinueError(
     395           0 :                         state, format("Illegal {} = {:.7T}", state.dataIPShortCut->cNumericFieldNames(4), state.dataIPShortCut->rNumericArgs(4)));
     396           0 :                     ErrorsFound = true;
     397             :                 }
     398             :             } else {
     399           0 :                 if ((!state.dataIPShortCut->lAlphaFieldBlanks(6)) || (!state.dataIPShortCut->lAlphaFieldBlanks(7))) {
     400           0 :                     ShowSevereError(state, format("{} = {}", cCMO_CoolingPanel_Simple, thisCP.Name));
     401           0 :                     ShowContinueError(state,
     402           0 :                                       format("Input for {} = {}", state.dataIPShortCut->cAlphaFieldNames(5), state.dataIPShortCut->cAlphaArgs(5)));
     403           0 :                     ShowContinueError(state, format("Blank field not allowed for {}", state.dataIPShortCut->cNumericFieldNames(4)));
     404           0 :                     ErrorsFound = true;
     405             :                 }
     406             :             }
     407           2 :         } else if (Util::SameString(state.dataIPShortCut->cAlphaArgs(5), "CapacityPerFloorArea")) {
     408           1 :             thisCP.CoolingCapMethod = DataSizing::CapacityPerFloorArea;
     409           1 :             if (!state.dataIPShortCut->lNumericFieldBlanks(5)) {
     410           1 :                 thisCP.ScaledCoolingCapacity = state.dataIPShortCut->rNumericArgs(5);
     411           1 :                 if (thisCP.ScaledCoolingCapacity < 0.0) {
     412           0 :                     ShowSevereError(state, format("{} = {}", cCMO_CoolingPanel_Simple, thisCP.Name));
     413           0 :                     ShowContinueError(state,
     414           0 :                                       format("Input for {} = {}", state.dataIPShortCut->cAlphaFieldNames(5), state.dataIPShortCut->cAlphaArgs(5)));
     415           0 :                     ShowContinueError(
     416           0 :                         state, format("Illegal {} = {:.7T}", state.dataIPShortCut->cNumericFieldNames(5), state.dataIPShortCut->rNumericArgs(5)));
     417           0 :                     ErrorsFound = true;
     418           1 :                 } else if (thisCP.ScaledCoolingCapacity == DataSizing::AutoSize) {
     419           0 :                     ShowSevereError(state, format("{} = {}", cCMO_CoolingPanel_Simple, thisCP.Name));
     420           0 :                     ShowContinueError(state,
     421           0 :                                       format("Input for {} = {}", state.dataIPShortCut->cAlphaFieldNames(5), state.dataIPShortCut->cAlphaArgs(5)));
     422           0 :                     ShowContinueError(state, format("Illegal {} = Autosize", state.dataIPShortCut->cNumericFieldNames(5)));
     423           0 :                     ErrorsFound = true;
     424             :                 }
     425             :             } else {
     426           0 :                 ShowSevereError(state, format("{} = {}", cCMO_CoolingPanel_Simple, thisCP.Name));
     427           0 :                 ShowContinueError(state, format("Input for {} = {}", state.dataIPShortCut->cAlphaFieldNames(5), state.dataIPShortCut->cAlphaArgs(5)));
     428           0 :                 ShowContinueError(state, format("Blank field not allowed for {}", state.dataIPShortCut->cNumericFieldNames(5)));
     429           0 :                 ErrorsFound = true;
     430             :             }
     431           1 :         } else if (Util::SameString(state.dataIPShortCut->cAlphaArgs(5), "FractionOfAutosizedCoolingCapacity")) {
     432           1 :             thisCP.CoolingCapMethod = DataSizing::FractionOfAutosizedCoolingCapacity;
     433           1 :             if (!state.dataIPShortCut->lNumericFieldBlanks(6)) {
     434           1 :                 thisCP.ScaledCoolingCapacity = state.dataIPShortCut->rNumericArgs(6);
     435           1 :                 if (thisCP.ScaledCoolingCapacity < 0.0) {
     436           0 :                     ShowSevereError(state, format("{} = {}", cCMO_CoolingPanel_Simple, thisCP.Name));
     437           0 :                     ShowContinueError(
     438           0 :                         state, format("Illegal {} = {:.7T}", state.dataIPShortCut->cNumericFieldNames(6), state.dataIPShortCut->rNumericArgs(6)));
     439           0 :                     ErrorsFound = true;
     440             :                 }
     441             :             } else {
     442           0 :                 ShowSevereError(state, format("{} = {}", cCMO_CoolingPanel_Simple, thisCP.Name));
     443           0 :                 ShowContinueError(state, format("Input for {} = {}", state.dataIPShortCut->cAlphaFieldNames(5), state.dataIPShortCut->cAlphaArgs(5)));
     444           0 :                 ShowContinueError(state, format("Blank field not allowed for {}", state.dataIPShortCut->cNumericFieldNames(6)));
     445           0 :                 ErrorsFound = true;
     446             :             }
     447             :         } else {
     448           0 :             ShowSevereError(state, format("{} = {}", cCMO_CoolingPanel_Simple, thisCP.Name));
     449           0 :             ShowContinueError(state, format("Illegal {} = {}", state.dataIPShortCut->cAlphaFieldNames(5), state.dataIPShortCut->cAlphaArgs(5)));
     450           0 :             ErrorsFound = true;
     451             :         }
     452             : 
     453           4 :         thisCP.WaterVolFlowRateMax = state.dataIPShortCut->rNumericArgs(7);
     454           4 :         if ((thisCP.WaterVolFlowRateMax <= MinWaterFlowRate) && thisCP.WaterVolFlowRateMax != DataSizing::AutoSize) {
     455           0 :             ShowWarningError(state,
     456           0 :                              format("{}{}=\"{}\", {} was less than the allowable minimum.",
     457             :                                     RoutineName,
     458             :                                     cCMO_CoolingPanel_Simple,
     459           0 :                                     state.dataIPShortCut->cAlphaArgs(1),
     460           0 :                                     state.dataIPShortCut->cNumericFieldNames(7)));
     461           0 :             ShowContinueError(state, format("...reset to minimum value=[{:.2R}].", MinWaterFlowRate));
     462           0 :             thisCP.WaterVolFlowRateMax = MinWaterFlowRate;
     463           4 :         } else if (thisCP.WaterVolFlowRateMax > MaxWaterFlowRate) {
     464           0 :             ShowWarningError(state,
     465           0 :                              format("{}{}=\"{}\", {} was higher than the allowable maximum.",
     466             :                                     RoutineName,
     467             :                                     cCMO_CoolingPanel_Simple,
     468           0 :                                     state.dataIPShortCut->cAlphaArgs(1),
     469           0 :                                     state.dataIPShortCut->cNumericFieldNames(7)));
     470           0 :             ShowContinueError(state, format("...reset to maximum value=[{:.2R}].", MaxWaterFlowRate));
     471           0 :             thisCP.WaterVolFlowRateMax = MaxWaterFlowRate;
     472             :         }
     473             : 
     474             :         // Process the temperature control type
     475           4 :         if (Util::SameString(state.dataIPShortCut->cAlphaArgs(6), MeanAirTemperature)) {
     476           3 :             thisCP.controlType = ClgPanelCtrlType::MAT;
     477           1 :         } else if (Util::SameString(state.dataIPShortCut->cAlphaArgs(6), MeanRadiantTemperature)) {
     478           0 :             thisCP.controlType = ClgPanelCtrlType::MRT;
     479           1 :         } else if (Util::SameString(state.dataIPShortCut->cAlphaArgs(6), OperativeTemperature)) {
     480           0 :             thisCP.controlType = ClgPanelCtrlType::Operative;
     481           1 :         } else if (Util::SameString(state.dataIPShortCut->cAlphaArgs(6), OutsideAirDryBulbTemperature)) {
     482           0 :             thisCP.controlType = ClgPanelCtrlType::ODB;
     483           1 :         } else if (Util::SameString(state.dataIPShortCut->cAlphaArgs(6), OutsideAirWetBulbTemperature)) {
     484           0 :             thisCP.controlType = ClgPanelCtrlType::OWB;
     485           1 :         } else if (Util::SameString(state.dataIPShortCut->cAlphaArgs(6), ZoneTotalLoad)) {
     486           1 :             thisCP.controlType = ClgPanelCtrlType::ZoneTotalLoad;
     487           0 :         } else if (Util::SameString(state.dataIPShortCut->cAlphaArgs(6), ZoneConvectiveLoad)) {
     488           0 :             thisCP.controlType = ClgPanelCtrlType::ZoneConvectiveLoad;
     489             :         } else {
     490           0 :             ShowWarningError(state, format("Invalid {} ={}", state.dataIPShortCut->cAlphaFieldNames(6), state.dataIPShortCut->cAlphaArgs(6)));
     491           0 :             ShowContinueError(state, format("Occurs in {} = {}", RoutineName, state.dataIPShortCut->cAlphaArgs(1)));
     492           0 :             ShowContinueError(state, "Control reset to MAT control for this Simple Cooling Panel.");
     493           0 :             thisCP.controlType = ClgPanelCtrlType::MAT;
     494             :         }
     495             : 
     496           4 :         thisCP.ColdThrottlRange = state.dataIPShortCut->rNumericArgs(8);
     497           4 :         if (thisCP.ColdThrottlRange < MinThrottlingRange) {
     498           0 :             ShowWarningError(state, format("{}Cooling throttling range too small, reset to 0.5", cCMO_CoolingPanel_Simple));
     499           0 :             ShowContinueError(state, format("Occurs in Cooling Panel={}", thisCP.Name));
     500           0 :             thisCP.ColdThrottlRange = MinThrottlingRange;
     501             :         }
     502             : 
     503           4 :         thisCP.ColdSetptSched = state.dataIPShortCut->cAlphaArgs(7);
     504           4 :         thisCP.ColdSetptSchedPtr = ScheduleManager::GetScheduleIndex(state, thisCP.ColdSetptSched);
     505           4 :         if ((thisCP.ColdSetptSchedPtr == 0) && (!state.dataIPShortCut->lAlphaFieldBlanks(7))) {
     506           0 :             ShowSevereError(state, format("{} not found: {}", state.dataIPShortCut->cAlphaFieldNames(7), thisCP.ColdSetptSched));
     507           0 :             ShowContinueError(state, format("Occurs in {} = {}", RoutineName, state.dataIPShortCut->cAlphaArgs(1)));
     508           0 :             ErrorsFound = true;
     509             :         }
     510             : 
     511           4 :         if (Util::SameString(state.dataIPShortCut->cAlphaArgs(8), Off)) {
     512           3 :             thisCP.CondCtrlType = CondCtrl::NONE;
     513           1 :         } else if (Util::SameString(state.dataIPShortCut->cAlphaArgs(8), SimpleOff)) {
     514           0 :             thisCP.CondCtrlType = CondCtrl::SIMPLEOFF;
     515           1 :         } else if (Util::SameString(state.dataIPShortCut->cAlphaArgs(8), VariableOff)) {
     516           1 :             thisCP.CondCtrlType = CondCtrl::VARIEDOFF;
     517             :         } else {
     518           0 :             thisCP.CondCtrlType = CondCtrl::SIMPLEOFF;
     519             :         }
     520             : 
     521           4 :         thisCP.CondDewPtDeltaT = state.dataIPShortCut->rNumericArgs(9);
     522             : 
     523           4 :         thisCP.FracRadiant = state.dataIPShortCut->rNumericArgs(10);
     524           4 :         if (thisCP.FracRadiant < MinFraction) {
     525           0 :             ShowWarningError(state,
     526           0 :                              format("{}{}=\"{}\", {} was lower than the allowable minimum.",
     527             :                                     RoutineName,
     528             :                                     cCMO_CoolingPanel_Simple,
     529           0 :                                     state.dataIPShortCut->cAlphaArgs(1),
     530           0 :                                     state.dataIPShortCut->cNumericFieldNames(10)));
     531           0 :             ShowContinueError(state, format("...reset to minimum value=[{:.2R}].", MinFraction));
     532           0 :             thisCP.FracRadiant = MinFraction;
     533             :         }
     534           4 :         if (thisCP.FracRadiant > MaxFraction) {
     535           0 :             ShowWarningError(state,
     536           0 :                              format("{}{}=\"{}\", {} was higher than the allowable maximum.",
     537             :                                     RoutineName,
     538             :                                     cCMO_CoolingPanel_Simple,
     539           0 :                                     state.dataIPShortCut->cAlphaArgs(1),
     540           0 :                                     state.dataIPShortCut->cNumericFieldNames(10)));
     541           0 :             ShowContinueError(state, format("...reset to maximum value=[{:.2R}].", MaxFraction));
     542           0 :             thisCP.FracRadiant = MaxFraction;
     543             :         }
     544             : 
     545             :         // Remaining fraction is added to the zone as convective heat transfer
     546           4 :         if (thisCP.FracRadiant > MaxFraction) {
     547           0 :             ShowWarningError(state,
     548           0 :                              format("{}{}=\"{}\", Fraction Radiant was higher than the allowable maximum.",
     549             :                                     RoutineName,
     550             :                                     cCMO_CoolingPanel_Simple,
     551           0 :                                     state.dataIPShortCut->cAlphaArgs(1)));
     552           0 :             thisCP.FracRadiant = MaxFraction;
     553           0 :             thisCP.FracConvect = 0.0;
     554             :         } else {
     555           4 :             thisCP.FracConvect = 1.0 - thisCP.FracRadiant;
     556             :         }
     557             : 
     558           4 :         thisCP.FracDistribPerson = state.dataIPShortCut->rNumericArgs(11);
     559           4 :         if (thisCP.FracDistribPerson < MinFraction) {
     560           0 :             ShowWarningError(state,
     561           0 :                              format("{}{}=\"{}\", {} was lower than the allowable minimum.",
     562             :                                     RoutineName,
     563             :                                     cCMO_CoolingPanel_Simple,
     564           0 :                                     state.dataIPShortCut->cAlphaArgs(1),
     565           0 :                                     state.dataIPShortCut->cNumericFieldNames(11)));
     566           0 :             ShowContinueError(state, format("...reset to minimum value=[{:.3R}].", MinFraction));
     567           0 :             thisCP.FracDistribPerson = MinFraction;
     568             :         }
     569           4 :         if (thisCP.FracDistribPerson > MaxFraction) {
     570           0 :             ShowWarningError(state,
     571           0 :                              format("{}{}=\"{}\", {} was higher than the allowable maximum.",
     572             :                                     RoutineName,
     573             :                                     cCMO_CoolingPanel_Simple,
     574           0 :                                     state.dataIPShortCut->cAlphaArgs(1),
     575           0 :                                     state.dataIPShortCut->cNumericFieldNames(11)));
     576           0 :             ShowContinueError(state, format("...reset to maximum value=[{:.3R}].", MaxFraction));
     577           0 :             thisCP.FracDistribPerson = MaxFraction;
     578             :         }
     579             : 
     580           4 :         thisCP.TotSurfToDistrib = NumNumbers - 11;
     581           4 :         if ((thisCP.TotSurfToDistrib < MinDistribSurfaces) && (thisCP.FracRadiant > MinFraction)) {
     582           0 :             ShowSevereError(state,
     583           0 :                             format("{}{}=\"{}\", the number of surface/radiant fraction groups entered was less than the allowable minimum.",
     584             :                                    RoutineName,
     585             :                                    cCMO_CoolingPanel_Simple,
     586           0 :                                    state.dataIPShortCut->cAlphaArgs(1)));
     587           0 :             ShowContinueError(state, format("...the minimum that must be entered=[{}].", MinDistribSurfaces));
     588           0 :             ErrorsFound = true;
     589           0 :             thisCP.TotSurfToDistrib = 0; // error
     590             :         }
     591             : 
     592           4 :         thisCP.SurfaceName.allocate(thisCP.TotSurfToDistrib);
     593           4 :         thisCP.SurfaceName = "";
     594           4 :         thisCP.SurfacePtr.allocate(thisCP.TotSurfToDistrib);
     595           4 :         thisCP.SurfacePtr = 0;
     596           4 :         thisCP.FracDistribToSurf.allocate(thisCP.TotSurfToDistrib);
     597           4 :         thisCP.FracDistribToSurf = 0.0;
     598             : 
     599             :         // search zone equipment list structure for zone index
     600          28 :         for (int ctrlZone = 1; ctrlZone <= state.dataGlobal->NumOfZones; ++ctrlZone) {
     601          56 :             for (int zoneEquipTypeNum = 1; zoneEquipTypeNum <= state.dataZoneEquip->ZoneEquipList(ctrlZone).NumOfEquipTypes; ++zoneEquipTypeNum) {
     602          36 :                 if (state.dataZoneEquip->ZoneEquipList(ctrlZone).EquipType(zoneEquipTypeNum) == DataZoneEquipment::ZoneEquipType::CoolingPanel &&
     603           4 :                     state.dataZoneEquip->ZoneEquipList(ctrlZone).EquipName(zoneEquipTypeNum) == thisCP.Name) {
     604           4 :                     thisCP.ZonePtr = ctrlZone;
     605             :                 }
     606             :             }
     607             :         }
     608           4 :         if (thisCP.ZonePtr <= 0) {
     609           0 :             ShowSevereError(state, format("{}{}=\"{}\" is not on any ZoneHVAC:EquipmentList.", RoutineName, cCMO_CoolingPanel_Simple, thisCP.Name));
     610           0 :             ErrorsFound = true;
     611           0 :             continue;
     612             :         }
     613             : 
     614           4 :         Real64 AllFracsSummed = thisCP.FracDistribPerson;
     615          16 :         for (SurfNum = 1; SurfNum <= thisCP.TotSurfToDistrib; ++SurfNum) {
     616          12 :             thisCP.SurfaceName(SurfNum) = state.dataIPShortCut->cAlphaArgs(SurfNum + 8);
     617          12 :             thisCP.SurfacePtr(SurfNum) = HeatBalanceIntRadExchange::GetRadiantSystemSurface(
     618          12 :                 state, cCMO_CoolingPanel_Simple, thisCP.Name, thisCP.ZonePtr, thisCP.SurfaceName(SurfNum), ErrorsFound);
     619          12 :             thisCP.FracDistribToSurf(SurfNum) = state.dataIPShortCut->rNumericArgs(SurfNum + 11);
     620          12 :             if (thisCP.FracDistribToSurf(SurfNum) > MaxFraction) {
     621           0 :                 ShowWarningError(state,
     622           0 :                                  format("{}{}=\"{}\", {}was greater than the allowable maximum.",
     623             :                                         RoutineName,
     624             :                                         cCMO_CoolingPanel_Simple,
     625           0 :                                         state.dataIPShortCut->cAlphaArgs(1),
     626           0 :                                         state.dataIPShortCut->cNumericFieldNames(SurfNum + 8)));
     627           0 :                 ShowContinueError(state, format("...reset to maximum value=[{:.2R}].", MaxFraction));
     628           0 :                 thisCP.TotSurfToDistrib = MaxFraction;
     629             :             }
     630          12 :             if (thisCP.FracDistribToSurf(SurfNum) < MinFraction) {
     631           0 :                 ShowWarningError(state,
     632           0 :                                  format("{}{}=\"{}\", {}was less than the allowable minimum.",
     633             :                                         RoutineName,
     634             :                                         cCMO_CoolingPanel_Simple,
     635           0 :                                         state.dataIPShortCut->cAlphaArgs(1),
     636           0 :                                         state.dataIPShortCut->cNumericFieldNames(SurfNum + 8)));
     637           0 :                 ShowContinueError(state, format("...reset to maximum value=[{:.2R}].", MinFraction));
     638           0 :                 thisCP.TotSurfToDistrib = MinFraction;
     639             :             }
     640          12 :             if (thisCP.SurfacePtr(SurfNum) != 0) {
     641          12 :                 state.dataSurface->surfIntConv(thisCP.SurfacePtr(SurfNum)).getsRadiantHeat = true;
     642          12 :                 state.dataSurface->allGetsRadiantHeatSurfaceList.emplace_back(thisCP.SurfacePtr(SurfNum));
     643             :             }
     644             : 
     645          12 :             AllFracsSummed += thisCP.FracDistribToSurf(SurfNum);
     646             :         } // Surfaces
     647             : 
     648           4 :         if (AllFracsSummed > (MaxFraction + 0.01)) {
     649           0 :             ShowSevereError(state,
     650           0 :                             format("{}{}=\"{}\", Summed radiant fractions for people + surface groups > 1.0",
     651             :                                    RoutineName,
     652             :                                    cCMO_CoolingPanel_Simple,
     653           0 :                                    state.dataIPShortCut->cAlphaArgs(1)));
     654           0 :             ErrorsFound = true;
     655             :         }
     656           4 :         if ((AllFracsSummed < (MaxFraction - 0.01)) &&
     657           0 :             (thisCP.FracRadiant > MinFraction)) { // User didn't distribute all of the | radiation warn that some will be lost
     658           0 :             ShowSevereError(state,
     659           0 :                             format("{}{}=\"{}\", Summed radiant fractions for people + surface groups < 1.0",
     660             :                                    RoutineName,
     661             :                                    cCMO_CoolingPanel_Simple,
     662           0 :                                    state.dataIPShortCut->cAlphaArgs(1)));
     663           0 :             ShowContinueError(state, "This would result in some of the radiant energy delivered by the high temp radiant heater being lost.");
     664           0 :             ShowContinueError(state, format("The sum of all radiation fractions to surfaces = {:.5T}", (AllFracsSummed - thisCP.FracDistribPerson)));
     665           0 :             ShowContinueError(state, format("The radiant fraction to people = {:.5T}", thisCP.FracDistribPerson));
     666           0 :             ShowContinueError(state, format("So, all radiant fractions including surfaces and people = {:.5T}", AllFracsSummed));
     667           0 :             ShowContinueError(state,
     668           0 :                               format("This means that the fraction of radiant energy that would be lost from the high temperature radiant heater "
     669             :                                      "would be = {:.5T}",
     670           0 :                                      (1.0 - AllFracsSummed)));
     671           0 :             ShowContinueError(state,
     672           0 :                               format("Please check and correct this so that all radiant energy is accounted for in {} = {}",
     673             :                                      cCMO_CoolingPanel_Simple,
     674           0 :                                      state.dataIPShortCut->cAlphaArgs(1)));
     675           0 :             ErrorsFound = true;
     676             :         }
     677             :     }
     678             : 
     679           4 :     if (ErrorsFound) {
     680           0 :         ShowFatalError(state, format("{}{}Errors found getting input. Program terminates.", RoutineName, cCMO_CoolingPanel_Simple));
     681             :     }
     682             : 
     683             :     // Setup Report variables for the Coils
     684           8 :     for (int CoolingPanelNum = 1; CoolingPanelNum <= NumCoolingPanels; ++CoolingPanelNum) {
     685             :         // CurrentModuleObject='ZoneHVAC:CoolingPanel:RadiantConvective:Water'
     686           4 :         auto &thisCP = state.dataChilledCeilingPanelSimple->CoolingPanel(CoolingPanelNum);
     687           8 :         SetupOutputVariable(state,
     688             :                             "Cooling Panel Total Cooling Rate",
     689             :                             Constant::Units::W,
     690           4 :                             thisCP.Power,
     691             :                             OutputProcessor::TimeStepType::System,
     692             :                             OutputProcessor::StoreType::Average,
     693           4 :                             thisCP.Name);
     694           8 :         SetupOutputVariable(state,
     695             :                             "Cooling Panel Total System Cooling Rate",
     696             :                             Constant::Units::W,
     697           4 :                             thisCP.TotPower,
     698             :                             OutputProcessor::TimeStepType::System,
     699             :                             OutputProcessor::StoreType::Average,
     700           4 :                             thisCP.Name);
     701           8 :         SetupOutputVariable(state,
     702             :                             "Cooling Panel Convective Cooling Rate",
     703             :                             Constant::Units::W,
     704           4 :                             thisCP.ConvPower,
     705             :                             OutputProcessor::TimeStepType::System,
     706             :                             OutputProcessor::StoreType::Average,
     707           4 :                             thisCP.Name);
     708           8 :         SetupOutputVariable(state,
     709             :                             "Cooling Panel Radiant Cooling Rate",
     710             :                             Constant::Units::W,
     711           4 :                             thisCP.RadPower,
     712             :                             OutputProcessor::TimeStepType::System,
     713             :                             OutputProcessor::StoreType::Average,
     714           4 :                             thisCP.Name);
     715             : 
     716           8 :         SetupOutputVariable(state,
     717             :                             "Cooling Panel Total Cooling Energy",
     718             :                             Constant::Units::J,
     719           4 :                             thisCP.Energy,
     720             :                             OutputProcessor::TimeStepType::System,
     721             :                             OutputProcessor::StoreType::Sum,
     722           4 :                             thisCP.Name,
     723             :                             Constant::eResource::EnergyTransfer,
     724             :                             OutputProcessor::Group::HVAC,
     725             :                             OutputProcessor::EndUseCat::CoolingPanel);
     726           8 :         SetupOutputVariable(state,
     727             :                             "Cooling Panel Total System Cooling Energy",
     728             :                             Constant::Units::J,
     729           4 :                             thisCP.TotEnergy,
     730             :                             OutputProcessor::TimeStepType::System,
     731             :                             OutputProcessor::StoreType::Sum,
     732           4 :                             thisCP.Name,
     733             :                             Constant::eResource::EnergyTransfer,
     734             :                             OutputProcessor::Group::HVAC,
     735             :                             OutputProcessor::EndUseCat::CoolingPanel);
     736           8 :         SetupOutputVariable(state,
     737             :                             "Cooling Panel Convective Cooling Energy",
     738             :                             Constant::Units::J,
     739           4 :                             thisCP.ConvEnergy,
     740             :                             OutputProcessor::TimeStepType::System,
     741             :                             OutputProcessor::StoreType::Sum,
     742           4 :                             thisCP.Name);
     743           8 :         SetupOutputVariable(state,
     744             :                             "Cooling Panel Radiant Cooling Energy",
     745             :                             Constant::Units::J,
     746           4 :                             thisCP.RadEnergy,
     747             :                             OutputProcessor::TimeStepType::System,
     748             :                             OutputProcessor::StoreType::Sum,
     749           4 :                             thisCP.Name);
     750             : 
     751           8 :         SetupOutputVariable(state,
     752             :                             "Cooling Panel Water Mass Flow Rate",
     753             :                             Constant::Units::kg_s,
     754           4 :                             thisCP.WaterMassFlowRate,
     755             :                             OutputProcessor::TimeStepType::System,
     756             :                             OutputProcessor::StoreType::Average,
     757           4 :                             thisCP.Name);
     758           8 :         SetupOutputVariable(state,
     759             :                             "Cooling Panel Water Inlet Temperature",
     760             :                             Constant::Units::C,
     761           4 :                             thisCP.WaterInletTemp,
     762             :                             OutputProcessor::TimeStepType::System,
     763             :                             OutputProcessor::StoreType::Average,
     764           4 :                             thisCP.Name);
     765           8 :         SetupOutputVariable(state,
     766             :                             "Cooling Panel Water Outlet Temperature",
     767             :                             Constant::Units::C,
     768           4 :                             thisCP.WaterOutletTemp,
     769             :                             OutputProcessor::TimeStepType::System,
     770             :                             OutputProcessor::StoreType::Average,
     771           4 :                             thisCP.Name);
     772             :     }
     773           4 : }
     774             : 
     775       22415 : void InitCoolingPanel(EnergyPlusData &state, int const CoolingPanelNum, int const ControlledZoneNum, bool const FirstHVACIteration)
     776             : {
     777             : 
     778             :     // SUBROUTINE INFORMATION:
     779             :     //       AUTHOR         Rick Strand
     780             :     //       DATE WRITTEN   Sept 2014
     781             : 
     782             :     // PURPOSE OF THIS SUBROUTINE:
     783             :     // This subroutine initializes the cooling panel units, and determines the UA values during simulation.
     784             : 
     785             :     // METHODOLOGY EMPLOYED:
     786             :     // The initialization subrotines borrowed from other sources and heat exchanger formulation for cooling panel.
     787             : 
     788             :     // REFERENCES:
     789             :     // Incropera and DeWitt, Fundamentals of Heat and Mass Transfer
     790             : 
     791             :     // SUBROUTINE PARAMETER DEFINITIONS:
     792             :     static constexpr std::string_view RoutineName("ChilledCeilingPanelSimple:InitCoolingPanel");
     793             : 
     794             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     795             :     Real64 rho; // local fluid density
     796             :     Real64 Cp;  // local fluid specific heat
     797             : 
     798       22415 :     auto &thisCP = state.dataChilledCeilingPanelSimple->CoolingPanel(CoolingPanelNum);
     799       22415 :     auto &ThisInNode = state.dataLoopNodes->Node(thisCP.WaterInletNode);
     800             : 
     801       22415 :     if (thisCP.ZonePtr <= 0) thisCP.ZonePtr = ControlledZoneNum;
     802             : 
     803             :     // Need to check all units to see if they are on ZoneHVAC:EquipmentList or issue warning
     804       22415 :     if (!thisCP.ZoneEquipmentListChecked && state.dataZoneEquip->ZoneEquipInputsFilled) {
     805           4 :         thisCP.ZoneEquipmentListChecked = true;
     806           4 :         if (!DataZoneEquipment::CheckZoneEquipmentList(state, cCMO_CoolingPanel_Simple, thisCP.Name)) {
     807           0 :             ShowSevereError(state,
     808           0 :                             format("InitCoolingPanel: Unit=[{},{}] is not on any ZoneHVAC:EquipmentList.  It will not be simulated.",
     809             :                                    cCMO_CoolingPanel_Simple,
     810           0 :                                    thisCP.Name));
     811             :         }
     812             :     }
     813             : 
     814       22415 :     if (thisCP.SetLoopIndexFlag) {
     815           4 :         if (allocated(state.dataPlnt->PlantLoop)) {
     816           4 :             bool errFlag = false;
     817           4 :             PlantUtilities::ScanPlantLoopsForObject(state, thisCP.Name, thisCP.EquipType, thisCP.plantLoc, errFlag, _, _, _, _, _);
     818           4 :             if (errFlag) {
     819           0 :                 ShowFatalError(state, "InitCoolingPanel: Program terminated for previous conditions.");
     820             :             }
     821           4 :             thisCP.SetLoopIndexFlag = false;
     822             :         }
     823             :     }
     824             : 
     825       22415 :     if (!state.dataGlobal->SysSizingCalc) {
     826       22411 :         if (thisCP.MySizeFlagCoolPanel && !thisCP.SetLoopIndexFlag) {
     827             :             // for each cooling panel do the sizing once.
     828           4 :             SizeCoolingPanel(state, CoolingPanelNum);
     829           4 :             thisCP.MySizeFlagCoolPanel = false;
     830             : 
     831             :             // set design mass flow rates
     832           4 :             if (thisCP.WaterInletNode > 0) {
     833           4 :                 rho = FluidProperties::GetDensityGlycol(state,
     834           4 :                                                         state.dataPlnt->PlantLoop(thisCP.plantLoc.loopNum).FluidName,
     835             :                                                         Constant::CWInitConvTemp,
     836           4 :                                                         state.dataPlnt->PlantLoop(thisCP.plantLoc.loopNum).FluidIndex,
     837             :                                                         RoutineName);
     838           4 :                 thisCP.WaterMassFlowRateMax = rho * thisCP.WaterVolFlowRateMax;
     839           4 :                 PlantUtilities::InitComponentNodes(state, 0.0, thisCP.WaterMassFlowRateMax, thisCP.WaterInletNode, thisCP.WaterOutletNode);
     840             :             }
     841             :         }
     842             :     }
     843             : 
     844             :     // Do the Begin Environment initializations
     845       22415 :     if (state.dataGlobal->BeginEnvrnFlag && thisCP.MyEnvrnFlag) {
     846             :         // Initialize
     847             : 
     848          24 :         rho = FluidProperties::GetDensityGlycol(state,
     849          24 :                                                 state.dataPlnt->PlantLoop(thisCP.plantLoc.loopNum).FluidName,
     850             :                                                 Constant::InitConvTemp,
     851          24 :                                                 state.dataPlnt->PlantLoop(thisCP.plantLoc.loopNum).FluidIndex,
     852             :                                                 RoutineName);
     853             : 
     854          24 :         thisCP.WaterMassFlowRateMax = rho * thisCP.WaterVolFlowRateMax;
     855             : 
     856          24 :         PlantUtilities::InitComponentNodes(state, 0.0, thisCP.WaterMassFlowRateMax, thisCP.WaterInletNode, thisCP.WaterOutletNode);
     857             : 
     858          24 :         ThisInNode.Temp = 7.0;
     859             : 
     860          24 :         Cp = FluidProperties::GetSpecificHeatGlycol(state,
     861          24 :                                                     state.dataPlnt->PlantLoop(thisCP.plantLoc.loopNum).FluidName,
     862             :                                                     ThisInNode.Temp,
     863          24 :                                                     state.dataPlnt->PlantLoop(thisCP.plantLoc.loopNum).FluidIndex,
     864             :                                                     RoutineName);
     865             : 
     866          24 :         ThisInNode.Enthalpy = Cp * ThisInNode.Temp;
     867          24 :         ThisInNode.Quality = 0.0;
     868          24 :         ThisInNode.Press = 0.0;
     869          24 :         ThisInNode.HumRat = 0.0;
     870             : 
     871          24 :         thisCP.ZeroCPSourceSumHATsurf = 0.0;
     872          24 :         thisCP.CoolingPanelSource = 0.0;
     873          24 :         thisCP.CoolingPanelSrcAvg = 0.0;
     874          24 :         thisCP.LastCoolingPanelSrc = 0.0;
     875          24 :         thisCP.LastSysTimeElapsed = 0.0;
     876          24 :         thisCP.LastTimeStepSys = 0.0;
     877             : 
     878          24 :         thisCP.MyEnvrnFlag = false;
     879             :     }
     880             : 
     881       22415 :     if (!state.dataGlobal->BeginEnvrnFlag) {
     882       22285 :         thisCP.MyEnvrnFlag = true;
     883             :     }
     884             : 
     885       22415 :     if (state.dataGlobal->BeginTimeStepFlag && FirstHVACIteration) {
     886        8108 :         int ZoneNum = thisCP.ZonePtr;
     887        8108 :         thisCP.ZeroCPSourceSumHATsurf = state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state);
     888        8108 :         thisCP.CoolingPanelSrcAvg = 0.0;
     889        8108 :         thisCP.LastCoolingPanelSrc = 0.0;
     890        8108 :         thisCP.LastSysTimeElapsed = 0.0;
     891        8108 :         thisCP.LastTimeStepSys = 0.0;
     892             :     }
     893             : 
     894             :     // Do the every time step initializations
     895       22415 :     thisCP.WaterMassFlowRate = ThisInNode.MassFlowRate;
     896       22415 :     thisCP.WaterInletTemp = ThisInNode.Temp;
     897       22415 :     thisCP.WaterInletEnthalpy = ThisInNode.Enthalpy;
     898       22415 :     thisCP.TotPower = 0.0;
     899       22415 :     thisCP.Power = 0.0;
     900       22415 :     thisCP.ConvPower = 0.0;
     901       22415 :     thisCP.RadPower = 0.0;
     902       22415 :     thisCP.TotEnergy = 0.0;
     903       22415 :     thisCP.Energy = 0.0;
     904       22415 :     thisCP.ConvEnergy = 0.0;
     905       22415 :     thisCP.RadEnergy = 0.0;
     906       22415 : }
     907             : 
     908           4 : void SizeCoolingPanel(EnergyPlusData &state, int const CoolingPanelNum)
     909             : {
     910             :     // SUBROUTINE INFORMATION:
     911             :     //       AUTHOR         Rick Strand
     912             :     //       DATE WRITTEN   Sept 2016
     913             : 
     914             :     // PURPOSE OF THIS SUBROUTINE:
     915             :     // This subroutine sizes the simple chilled ceiling panel.  The process used here
     916             :     // was derived from the low temperature radiant system model and adapted for
     917             :     // cooling only.
     918             : 
     919             :     // SUBROUTINE PARAMETER DEFINITIONS:
     920             :     static constexpr std::string_view RoutineName("SizeCoolingPanel");
     921             : 
     922             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     923           4 :     bool ErrorsFound(false); // If errors detected in input
     924           4 :     bool IsAutoSize(false);  // Indicator to autosize
     925             :     Real64 DesCoilLoad;      // design autosized or user specified capacity
     926             :     Real64 TempSize;         // autosized value of coil input field
     927             :     Real64 rho;
     928             :     Real64 Cp;
     929           4 :     Real64 WaterVolFlowMaxCoolDes(0.0);  // Design chilled water flow for reporting
     930           4 :     Real64 WaterVolFlowMaxCoolUser(0.0); // User hard-sized chilled water flow for reporting
     931             : 
     932           4 :     DesCoilLoad = 0.0;
     933           4 :     state.dataSize->DataScalableCapSizingON = false;
     934             : 
     935           4 :     auto &thisCP(state.dataChilledCeilingPanelSimple->CoolingPanel(CoolingPanelNum));
     936             : 
     937           4 :     std::string_view const CompType = "ZoneHVAC:CoolingPanel:RadiantConvective:Water";
     938           4 :     std::string_view const CompName = thisCP.Name;
     939             : 
     940           4 :     IsAutoSize = false;
     941           4 :     if (thisCP.ScaledCoolingCapacity == DataSizing::AutoSize) {
     942           1 :         IsAutoSize = true;
     943             :     }
     944             : 
     945           4 :     if (state.dataSize->CurZoneEqNum > 0) {
     946             : 
     947           4 :         auto &zoneEqSizing = state.dataSize->ZoneEqSizing(state.dataSize->CurZoneEqNum);
     948           4 :         int SizingMethod = HVAC::CoolingCapacitySizing;
     949           4 :         bool PrintFlag = true; // TRUE when sizing information is reported in the eio file
     950           4 :         bool errorsFound = false;
     951           4 :         int CapSizingMethod = thisCP.CoolingCapMethod;
     952           4 :         zoneEqSizing.SizingMethod(SizingMethod) = CapSizingMethod;
     953             : 
     954           4 :         if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) { // simulation continue
     955           0 :             if (CapSizingMethod == DataSizing::CoolingDesignCapacity && thisCP.ScaledCoolingCapacity > 0.0) {
     956           0 :                 TempSize = thisCP.ScaledCoolingCapacity;
     957           0 :                 CoolingCapacitySizer sizerCoolingCapacity;
     958           0 :                 sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
     959           0 :                 DesCoilLoad = sizerCoolingCapacity.size(state, TempSize, errorsFound);
     960           0 :             } else if (CapSizingMethod == DataSizing::CapacityPerFloorArea) {
     961           0 :                 state.dataSize->DataScalableCapSizingON = true;
     962           0 :                 TempSize = thisCP.ScaledCoolingCapacity * state.dataHeatBal->Zone(thisCP.ZonePtr).FloorArea;
     963           0 :                 CoolingCapacitySizer sizerCoolingCapacity;
     964           0 :                 sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
     965           0 :                 DesCoilLoad = sizerCoolingCapacity.size(state, TempSize, errorsFound);
     966           0 :                 state.dataSize->DataScalableCapSizingON = false;
     967           0 :             } else if (CapSizingMethod == DataSizing::FractionOfAutosizedCoolingCapacity) {
     968           0 :                 if (thisCP.WaterVolFlowRateMax == DataSizing::AutoSize) {
     969           0 :                     ShowSevereError(state, format("{}: auto-sizing cannot be done for {} = {}\".", RoutineName, CompType, thisCP.Name));
     970           0 :                     ShowContinueError(state,
     971             :                                       "The \"SimulationControl\" object must have the field \"Do Zone Sizing Calculation\" set to Yes when the "
     972             :                                       "Cooling Design Capacity Method = \"FractionOfAutosizedCoolingCapacity\".");
     973           0 :                     ErrorsFound = true;
     974             :                 }
     975             :             }
     976             :         } else { // Autosize or hard-size with sizing run
     977           4 :             if (CapSizingMethod == DataSizing::CoolingDesignCapacity || CapSizingMethod == DataSizing::CapacityPerFloorArea ||
     978             :                 CapSizingMethod == DataSizing::FractionOfAutosizedCoolingCapacity) {
     979           4 :                 if (CapSizingMethod == DataSizing::CoolingDesignCapacity) {
     980           2 :                     if (state.dataSize->ZoneSizingRunDone) {
     981           2 :                         CheckZoneSizing(state, CompType, CompName);
     982           4 :                         state.dataSize->DataConstantUsedForSizing =
     983           2 :                             state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).NonAirSysDesCoolLoad;
     984           2 :                         state.dataSize->DataFractionUsedForSizing = 1.0;
     985             :                     }
     986           2 :                     TempSize = thisCP.ScaledCoolingCapacity;
     987           2 :                 } else if (CapSizingMethod == DataSizing::CapacityPerFloorArea) {
     988           1 :                     if (state.dataSize->ZoneSizingRunDone) {
     989           1 :                         CheckZoneSizing(state, CompType, CompName);
     990           1 :                         zoneEqSizing.CoolingCapacity = true;
     991           1 :                         zoneEqSizing.DesCoolingLoad = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).NonAirSysDesCoolLoad;
     992             :                     }
     993           1 :                     TempSize = thisCP.ScaledCoolingCapacity * state.dataHeatBal->Zone(thisCP.ZonePtr).FloorArea;
     994           1 :                     state.dataSize->DataScalableCapSizingON = true;
     995           1 :                 } else if (CapSizingMethod == DataSizing::FractionOfAutosizedCoolingCapacity) {
     996           1 :                     CheckZoneSizing(state, CompType, CompName);
     997           1 :                     zoneEqSizing.CoolingCapacity = true;
     998           1 :                     zoneEqSizing.DesCoolingLoad = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).NonAirSysDesCoolLoad;
     999           1 :                     TempSize = zoneEqSizing.DesCoolingLoad * thisCP.ScaledCoolingCapacity;
    1000           1 :                     state.dataSize->DataScalableCapSizingON = true;
    1001             : 
    1002             :                 } else {
    1003           0 :                     TempSize = thisCP.ScaledCoolingCapacity;
    1004             :                 }
    1005           4 :                 CoolingCapacitySizer sizerCoolingCapacity;
    1006           4 :                 sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    1007           4 :                 DesCoilLoad = sizerCoolingCapacity.size(state, TempSize, errorsFound);
    1008           4 :                 state.dataSize->DataConstantUsedForSizing = 0.0;
    1009           4 :                 state.dataSize->DataFractionUsedForSizing = 0.0;
    1010           4 :                 state.dataSize->DataScalableCapSizingON = false;
    1011           4 :             } else {
    1012           0 :                 DesCoilLoad = 0.0;
    1013             :             }
    1014             :         }
    1015             :         // finally cooling capacity is saved in this variable
    1016           4 :         thisCP.ScaledCoolingCapacity = DesCoilLoad;
    1017             :     }
    1018             : 
    1019           4 :     IsAutoSize = false;
    1020           4 :     if (thisCP.WaterVolFlowRateMax == DataSizing::AutoSize) {
    1021           1 :         IsAutoSize = true;
    1022             :     }
    1023           4 :     if (state.dataSize->CurZoneEqNum > 0) {
    1024           4 :         if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) { // simulation continue
    1025           0 :             if (thisCP.WaterVolFlowRateMax > 0.0) {
    1026           0 :                 BaseSizer::reportSizerOutput(
    1027             :                     state, CompType, thisCP.Name, "User-Specified Maximum Cold Water Flow [m3/s]", thisCP.WaterVolFlowRateMax);
    1028             :             }
    1029             :         } else { // Autosize or hard-size with sizing run
    1030           4 :             if (thisCP.WaterInletNode > 0 && thisCP.WaterOutletNode > 0) {
    1031             :                 int PltSizCoolNum =
    1032           4 :                     PlantUtilities::MyPlantSizingIndex(state, CompType, thisCP.Name, thisCP.WaterInletNode, thisCP.WaterOutletNode, ErrorsFound);
    1033           4 :                 if (PltSizCoolNum > 0) {
    1034           4 :                     if (DesCoilLoad >= HVAC::SmallLoad) {
    1035           4 :                         rho = FluidProperties::GetDensityGlycol(state,
    1036           4 :                                                                 state.dataPlnt->PlantLoop(thisCP.plantLoc.loopNum).FluidName,
    1037             :                                                                 5.,
    1038           4 :                                                                 state.dataPlnt->PlantLoop(thisCP.plantLoc.loopNum).FluidIndex,
    1039             :                                                                 RoutineName);
    1040           4 :                         Cp = FluidProperties::GetSpecificHeatGlycol(state,
    1041           4 :                                                                     state.dataPlnt->PlantLoop(thisCP.plantLoc.loopNum).FluidName,
    1042             :                                                                     5.0,
    1043           4 :                                                                     state.dataPlnt->PlantLoop(thisCP.plantLoc.loopNum).FluidIndex,
    1044             :                                                                     RoutineName);
    1045           4 :                         WaterVolFlowMaxCoolDes = DesCoilLoad / (state.dataSize->PlantSizData(PltSizCoolNum).DeltaT * Cp * rho);
    1046             :                     } else {
    1047           0 :                         WaterVolFlowMaxCoolDes = 0.0;
    1048             :                     }
    1049             :                 } else {
    1050           0 :                     ShowSevereError(state, "Autosizing of water flow requires a cooling loop Sizing:Plant object");
    1051           0 :                     ShowContinueError(state, format("Occurs in ZoneHVAC:CoolingPanel:RadiantConvective:Water Object={}", thisCP.Name));
    1052             :                 }
    1053             :             }
    1054             : 
    1055           4 :             if (IsAutoSize) {
    1056           1 :                 thisCP.WaterVolFlowRateMax = WaterVolFlowMaxCoolDes;
    1057           1 :                 BaseSizer::reportSizerOutput(state, CompType, thisCP.Name, "Design Size Maximum Cold Water Flow [m3/s]", WaterVolFlowMaxCoolDes);
    1058             :             } else { // hard-size with sizing data
    1059           3 :                 if (thisCP.WaterVolFlowRateMax > 0.0 && WaterVolFlowMaxCoolDes > 0.0) {
    1060           3 :                     WaterVolFlowMaxCoolUser = thisCP.WaterVolFlowRateMax;
    1061           3 :                     BaseSizer::reportSizerOutput(state,
    1062             :                                                  CompType,
    1063             :                                                  thisCP.Name,
    1064             :                                                  "Design Size Maximum Cold Water Flow [m3/s]",
    1065             :                                                  WaterVolFlowMaxCoolDes,
    1066             :                                                  "User-Specified Maximum Cold Water Flow [m3/s]",
    1067             :                                                  WaterVolFlowMaxCoolUser);
    1068           3 :                     if (state.dataGlobal->DisplayExtraWarnings) {
    1069           0 :                         if ((std::abs(WaterVolFlowMaxCoolDes - WaterVolFlowMaxCoolUser) / WaterVolFlowMaxCoolUser) >
    1070           0 :                             state.dataSize->AutoVsHardSizingThreshold) {
    1071           0 :                             ShowMessage(state,
    1072           0 :                                         format("SizeCoolingPanel: Potential issue with equipment sizing for "
    1073             :                                                "ZoneHVAC:CoolingPanel:RadiantConvective:Water = \"{}\".",
    1074           0 :                                                thisCP.Name));
    1075           0 :                             ShowContinueError(state, format("User-Specified Maximum Cool Water Flow of {:.5R} [m3/s]", WaterVolFlowMaxCoolUser));
    1076           0 :                             ShowContinueError(state,
    1077           0 :                                               format("differs from Design Size Maximum Cool Water Flow of {:.5R} [m3/s]", WaterVolFlowMaxCoolDes));
    1078           0 :                             ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    1079           0 :                             ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    1080             :                         }
    1081             :                     }
    1082             :                 }
    1083             :             }
    1084             :         }
    1085             :     }
    1086             : 
    1087           4 :     PlantUtilities::RegisterPlantCompDesignFlow(state, thisCP.WaterInletNode, thisCP.WaterVolFlowRateMax);
    1088             : 
    1089           4 :     if (!thisCP.SizeCoolingPanelUA(state)) {
    1090           0 :         ShowFatalError(state, "SizeCoolingPanelUA: Program terminated for previous conditions.");
    1091             :     }
    1092           4 : }
    1093             : 
    1094           4 : bool CoolingPanelParams::SizeCoolingPanelUA(EnergyPlusData &state)
    1095             : {
    1096             : 
    1097             :     // SUBROUTINE INFORMATION:
    1098             :     //       AUTHOR         Rick Strand
    1099             :     //       DATE WRITTEN   June 2017
    1100             : 
    1101             :     // PURPOSE OF THIS SUBROUTINE:
    1102             :     // This subroutine sizes UA value for the simple chilled ceiling panel.
    1103             : 
    1104             :     // These initializations are mainly the calculation of the UA value for the heat exchanger formulation of the simple cooling panel
    1105             :     Real64 RatCapToTheoMax; // Ratio of unit capacity to theoretical maximum output based on rated parameters
    1106             : 
    1107           4 :     Real64 constexpr Cp = 4120.0; // Just an approximation, don't need to get an exact number
    1108           4 :     Real64 const MDot = this->RatedWaterFlowRate;
    1109           4 :     Real64 const MDotXCp = Cp * MDot;
    1110           4 :     Real64 const Qrated = this->ScaledCoolingCapacity;
    1111           4 :     Real64 const Tinletr = this->RatedWaterTemp;
    1112           4 :     Real64 const Tzoner = this->RatedZoneAirTemp;
    1113             : 
    1114           4 :     if (Tinletr >= Tzoner) {
    1115           0 :         ShowSevereError(state,
    1116           0 :                         format("SizeCoolingPanelUA: Unit=[{},{}] has a rated water temperature that is higher than the rated zone temperature.",
    1117             :                                cCMO_CoolingPanel_Simple,
    1118           0 :                                this->Name));
    1119           0 :         ShowContinueError(state,
    1120             :                           "Such a situation would not lead to cooling and thus the rated water or zone temperature or both should be adjusted.");
    1121           0 :         this->UA = 1.0;
    1122           0 :         return false;
    1123             :     }
    1124             : 
    1125           4 :     if ((Tzoner - Tinletr) < 0.5) {
    1126           0 :         RatCapToTheoMax = std::abs(Qrated) / (MDotXCp * 0.5); // Avoid a divide by zero error
    1127             :     } else {
    1128           4 :         RatCapToTheoMax = std::abs(Qrated) / (MDotXCp * std::abs(Tinletr - Tzoner));
    1129             :     }
    1130           4 :     if ((RatCapToTheoMax < 1.1) && (RatCapToTheoMax > 0.9999)) {
    1131             :         // close to unity with some graciousness given in case the approximation of Cp causes a problem
    1132           0 :         RatCapToTheoMax = 0.9999;
    1133           4 :     } else if (RatCapToTheoMax >= 1.1) {
    1134           0 :         ShowSevereError(state,
    1135           0 :                         format("SizeCoolingPanelUA: Unit=[{},{}] has a cooling capacity that is greater than the maximum possible value.",
    1136             :                                cCMO_CoolingPanel_Simple,
    1137           0 :                                this->Name));
    1138           0 :         ShowContinueError(state, "The result of this is that a UA value is impossible to calculate.");
    1139           0 :         ShowContinueError(state, "Check the rated input for temperatures, flow, and capacity for this unit.");
    1140           0 :         ShowContinueError(state, "The ratio of the capacity to the rated theoretical maximum must be less than unity.");
    1141           0 :         ShowContinueError(state,
    1142             :                           "The most likely cause for this is probably either the capacity (whether autosized or hardwired) being too high, the "
    1143             :                           "rated flow being too low, rated temperatures being too close to each other, or all of those reasons.");
    1144           0 :         ShowContinueError(state,
    1145             :                           "Compare the rated capacity in your input to the product of the rated mass flow rate, Cp of water, and the difference "
    1146             :                           "between the rated temperatures.");
    1147           0 :         ShowContinueError(
    1148             :             state, "If the rated capacity is higher than this product, then the cooling panel would violate the Second Law of Thermodynamics.");
    1149           0 :         this->UA = 1.0;
    1150           0 :         return false;
    1151             :     }
    1152             : 
    1153           4 :     this->UA = -MDotXCp * log(1.0 - RatCapToTheoMax);
    1154           4 :     if (this->UA <= 0.0) {
    1155           0 :         ShowSevereError(state,
    1156           0 :                         format("SizeCoolingPanelUA: Unit=[{},{}] has a zero or negative calculated UA value.", cCMO_CoolingPanel_Simple, this->Name));
    1157           0 :         ShowContinueError(state,
    1158             :                           "This is not allowed.  Please check the rated input parameters for this device to ensure that the values are correct.");
    1159           0 :         return false;
    1160             :     }
    1161             : 
    1162           4 :     return true;
    1163             : }
    1164             : 
    1165       22415 : void CoolingPanelParams::CalcCoolingPanel(EnergyPlusData &state, int const CoolingPanelNum)
    1166             : {
    1167             :     // SUBROUTINE INFORMATION:
    1168             :     //       AUTHOR         Rick Strand
    1169             :     //       DATE WRITTEN   Sept 2014
    1170             : 
    1171             :     // PURPOSE OF THIS SUBROUTINE:
    1172             :     // This subroutine calculates both the convective and radiant heat transfer rate
    1173             :     // for the simple cooling panel.  The process used here was derived from the hot
    1174             :     // water baseboard radiant/convective heater and adapted for cooling.
    1175             : 
    1176             :     // REFERENCES:
    1177             :     // Existing code for hot water baseboard models (radiant-convective variety)
    1178             :     // Incropera and DeWitt, Fundamentals of Heat and Mass Transfer
    1179             : 
    1180             :     // SUBROUTINE PARAMETER DEFINITIONS:
    1181       22415 :     Real64 constexpr MinFrac(0.0005); // Minimum fraction that delivers radiant heats to surfaces
    1182       22415 :     int constexpr Maxiter(20);        // Maximum number of iterations to achieve tolerance
    1183       22415 :     Real64 constexpr IterTol(0.005);  // Tolerance of 0.5%
    1184             :     static constexpr std::string_view RoutineName("CalcCoolingPanel");
    1185             : 
    1186             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1187             :     Real64 RadHeat;
    1188             :     Real64 CoolingPanelCool;
    1189             :     Real64 waterMassFlowRate;
    1190             :     Real64 CapacitanceWater;
    1191             :     Real64 NTU;
    1192             :     Real64 Effectiveness;
    1193             :     Real64 Cp;
    1194             :     Real64 MCpEpsAct;
    1195             :     Real64 MCpEpsLow;
    1196             :     Real64 MCpEpsHigh;
    1197             :     Real64 MdotLow;
    1198             :     Real64 MdotHigh;
    1199             :     Real64 FracGuess;
    1200             :     Real64 MdotGuess;
    1201             :     Real64 MCpEpsGuess;
    1202             :     Real64 ControlTemp;
    1203             :     Real64 SetPointTemp;
    1204             :     Real64 OffTempCool;
    1205             :     Real64 FullOnTempCool;
    1206             :     Real64 MassFlowFrac;
    1207             :     Real64 LoadMet;
    1208             :     bool CoolingPanelOn;
    1209             :     Real64 waterOutletTemp;
    1210             : 
    1211       22415 :     int ZoneNum = this->ZonePtr;
    1212       22415 :     Real64 QZnReq = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).RemainingOutputReqToCoolSP;
    1213       22415 :     Real64 waterInletTemp = this->WaterInletTemp;
    1214       22415 :     Real64 waterMassFlowRateMax = this->WaterMassFlowRateMax;
    1215       22415 :     Real64 Xr = this->FracRadiant;
    1216             : 
    1217       22415 :     if (ScheduleManager::GetCurrentScheduleValue(state, this->SchedPtr) > 0) {
    1218       22415 :         CoolingPanelOn = true;
    1219             :     } else {
    1220           0 :         CoolingPanelOn = false;
    1221             :     }
    1222             :     // Calculate the "zone" temperature for determining the output of the cooling panel
    1223       22415 :     auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
    1224       22415 :     Real64 Tzone = Xr * thisZoneHB.MRT + ((1.0 - Xr) * thisZoneHB.MAT);
    1225             : 
    1226             :     // Logical controls: if the WaterInletTemperature is higher than Tzone, do not run the panel
    1227       22415 :     if (waterInletTemp >= Tzone) CoolingPanelOn = false;
    1228             : 
    1229             :     // Condensation Controls based on dewpoint temperature of the zone.
    1230             :     // The assumption here is that condensation might take place if the inlet water temperature
    1231             :     // is below the dewpoint temperature of the space.  This assumption is made because we are
    1232             :     // probably dealing with a metal panel and the surface temperature of the panel will be very
    1233             :     // close to the inlet water temperature in certain places.  Thus, if the water inlet temperature
    1234             :     // is below the dewpoint temperature, then we might have condensation.  We need to deal with this
    1235             :     // possibility based on the user selected method.  The good news here is that we don't have to
    1236             :     // iterate like in the low temperature radiant systems because the inlet water condition is known
    1237             :     // not calculated.  So, we can deal with this upfront rather than after calculation and then more
    1238             :     // iteration.
    1239             :     Real64 DewPointTemp =
    1240       22415 :         Psychrometrics::PsyTdpFnWPb(state, state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).airHumRat, state.dataEnvrn->OutBaroPress);
    1241             : 
    1242       22415 :     if (waterInletTemp < (DewPointTemp + this->CondDewPtDeltaT) && (CoolingPanelOn)) {
    1243             : 
    1244             :         // Condensation is possible so invoke the three possible ways of handling this based on the user's choice...
    1245             : 
    1246       11446 :         if (this->CondCtrlType == CondCtrl::NONE) {
    1247             :             // Condensation control is "off" which means don't do anything, simply let it run and ignore condensation
    1248        3555 :         } else if (this->CondCtrlType == CondCtrl::SIMPLEOFF) {
    1249             :             // For "simple off", simply turn the simple cooling panel off to avoid condensation
    1250           0 :             waterMassFlowRate = 0.0;
    1251           0 :             CoolingPanelOn = false;
    1252             :             // Produce a warning message so that user knows the system was shut-off due to potential for condensation
    1253           0 :             if (!state.dataGlobal->WarmupFlag) {
    1254           0 :                 if (this->CondErrIndex == 0) { // allow errors up to number of radiant systems
    1255           0 :                     ShowWarningMessage(state,
    1256           0 :                                        format("{} [{}] inlet water temperature below dew-point temperature--potential for condensation exists",
    1257             :                                               cCMO_CoolingPanel_Simple,
    1258           0 :                                               this->Name));
    1259           0 :                     ShowContinueError(state, "Flow to the simple cooling panel will be shut-off to avoid condensation");
    1260           0 :                     ShowContinueError(state, format("Water inlet temperature = {:.2R}", waterInletTemp));
    1261           0 :                     ShowContinueError(state, format("Zone dew-point temperature + safety delta T= {:.2R}", DewPointTemp + this->CondDewPtDeltaT));
    1262           0 :                     ShowContinueErrorTimeStamp(state, "");
    1263           0 :                     ShowContinueError(state,
    1264           0 :                                       format("Note that a {:.4R} C safety was chosen in the input for the shut-off criteria", this->CondDewPtDeltaT));
    1265             :                 }
    1266           0 :                 ShowRecurringWarningErrorAtEnd(state,
    1267           0 :                                                cCMO_CoolingPanel_Simple + " [" + this->Name + "] condensation shut-off occurrence continues.",
    1268           0 :                                                this->CondErrIndex,
    1269             :                                                DewPointTemp,
    1270             :                                                DewPointTemp,
    1271             :                                                _,
    1272             :                                                "C",
    1273             :                                                "C");
    1274             :             }
    1275             : 
    1276        3555 :         } else if (this->CondCtrlType == CondCtrl::VARIEDOFF) {
    1277             :             // Varied off is the most complex because it tries to run by reducing the inlet temperature
    1278             :             // As a result of this, there is some bypass/recirculation that has to take place.
    1279             :             // We might not have enough flow rate to meet whatever load we have, but at least
    1280             :             // the system is still running at some partial load and avoiding condensation.
    1281        3555 :             waterInletTemp = DewPointTemp + this->CondDewPtDeltaT;
    1282             :         }
    1283             :     }
    1284             : 
    1285             :     // The next IF block is to find the mass flow rate based on what type of control the user has requested.  Load based controls
    1286             :     // vary the flow to meet the zone load calculated by the user-defined thermostat.  Temperature based controls vary the flow
    1287             :     // based on a comparison between the control temperature and the setpoint schedule and throttling range.
    1288             : 
    1289       22415 :     if ((this->controlType == ClgPanelCtrlType::ZoneTotalLoad) || (this->controlType == ClgPanelCtrlType::ZoneConvectiveLoad)) {
    1290             : 
    1291        5271 :         if (QZnReq < -HVAC::SmallLoad && !state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum) && (CoolingPanelOn)) {
    1292             : 
    1293        1060 :             Cp = FluidProperties::GetSpecificHeatGlycol(state,
    1294        1060 :                                                         state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    1295             :                                                         waterInletTemp,
    1296        1060 :                                                         state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    1297             :                                                         RoutineName);
    1298             : 
    1299             :             // Find the actual load: this parameter modifies what the response of the system should be.  For total load control, the system tries
    1300             :             // to meet the QZnReq.  For convective load control, the convective output of the device equals QZnReq which means that the load on
    1301             :             // the panel is higher as is its output.  Total load control will miss the setpoint temperature but will likely get there with time.
    1302             :             // Convective load control will hit the setpoint short term better but will result in overcooling in the long run probably.
    1303        1060 :             if (this->controlType == ClgPanelCtrlType::ZoneConvectiveLoad) {
    1304           0 :                 QZnReq = QZnReq / this->FracConvect;
    1305             :             }
    1306             : 
    1307             :             // Now for a small amount of iteration.  Try to find the value of mass flow rate that will come the closest to giving
    1308             :             // the proper value for MCpEpsAct.  Limit iterations to avoid too much time wasting.
    1309        1060 :             MCpEpsAct = QZnReq / (waterInletTemp - Tzone);
    1310        1060 :             MCpEpsLow = 0.0;
    1311        1060 :             MdotLow = 0.0;
    1312        1060 :             MCpEpsHigh = waterMassFlowRateMax * Cp * (1.0 - exp(-this->UA / (waterMassFlowRateMax * Cp)));
    1313        1060 :             MdotHigh = waterMassFlowRateMax;
    1314        1060 :             if (MCpEpsAct <= MCpEpsLow) {
    1315           0 :                 MCpEpsAct = MCpEpsLow;
    1316           0 :                 waterMassFlowRate = 0.0;
    1317           0 :                 state.dataLoopNodes->Node(this->WaterInletNode).MassFlowRate = 0.0;
    1318           0 :                 CoolingPanelOn = false;
    1319        1060 :             } else if (MCpEpsAct >= MCpEpsHigh) {
    1320         512 :                 MCpEpsAct = MCpEpsHigh;
    1321         512 :                 waterMassFlowRate = waterMassFlowRateMax;
    1322         512 :                 state.dataLoopNodes->Node(this->WaterInletNode).MassFlowRate = waterMassFlowRateMax;
    1323             :             } else {
    1324         548 :                 for (int iter = 1; iter <= Maxiter; ++iter) {
    1325         548 :                     FracGuess = (MCpEpsAct - MCpEpsLow) / (MCpEpsHigh - MCpEpsLow);
    1326         548 :                     MdotGuess = MdotHigh * FracGuess;
    1327         548 :                     MCpEpsGuess = MdotGuess * Cp * (1.0 - exp(-this->UA / (MdotGuess * Cp)));
    1328         548 :                     if (MCpEpsGuess <= MCpEpsAct) {
    1329           0 :                         MCpEpsLow = MCpEpsGuess;
    1330           0 :                         MdotLow = MdotGuess;
    1331             :                     } else { // MCpEpsGuess > MCpEpsAct
    1332         548 :                         MCpEpsHigh = MCpEpsGuess;
    1333         548 :                         MdotHigh = MdotGuess;
    1334             :                     }
    1335         548 :                     if (((MCpEpsAct - MCpEpsGuess) / MCpEpsAct) <= IterTol) {
    1336         548 :                         waterMassFlowRate = MdotGuess;
    1337         548 :                         state.dataLoopNodes->Node(this->WaterInletNode).MassFlowRate = waterMassFlowRate;
    1338         548 :                         break;
    1339             :                     }
    1340             :                 }
    1341             :             }
    1342             : 
    1343             :         } else {
    1344        4211 :             CoolingPanelOn = false;
    1345             :         }
    1346             : 
    1347        5271 :     } else { // temperature control rather than zone load control
    1348             : 
    1349       17144 :         if (CoolingPanelOn) {
    1350             : 
    1351       17144 :             ControlTemp = this->getCoolingPanelControlTemp(state, ZoneNum);
    1352             : 
    1353       17144 :             SetPointTemp = ScheduleManager::GetCurrentScheduleValue(state, this->ColdSetptSchedPtr);
    1354       17144 :             OffTempCool = SetPointTemp - 0.5 * this->ColdThrottlRange;
    1355       17144 :             FullOnTempCool = SetPointTemp + 0.5 * this->ColdThrottlRange;
    1356             : 
    1357       17144 :             if (ControlTemp <= OffTempCool) {
    1358       13329 :                 MassFlowFrac = 0.0;
    1359       13329 :                 CoolingPanelOn = false;
    1360        3815 :             } else if (ControlTemp >= FullOnTempCool) {
    1361           0 :                 MassFlowFrac = 1.0;
    1362             :             } else {
    1363        3815 :                 MassFlowFrac = (ControlTemp - OffTempCool) / this->ColdThrottlRange;
    1364        3815 :                 if (MassFlowFrac < MinFrac) MassFlowFrac = MinFrac;
    1365             :             }
    1366             : 
    1367       17144 :             waterMassFlowRate = MassFlowFrac * waterMassFlowRateMax;
    1368             :         }
    1369             :     }
    1370             : 
    1371       22415 :     if (CoolingPanelOn) {
    1372        4875 :         PlantUtilities::SetComponentFlowRate(state, waterMassFlowRate, this->WaterInletNode, this->WaterOutletNode, this->plantLoc);
    1373        4875 :         if (waterMassFlowRate <= 0.0) CoolingPanelOn = false;
    1374             :     }
    1375             : 
    1376       22415 :     if (CoolingPanelOn) {
    1377             :         // Now simulate the system...
    1378        4872 :         Cp = FluidProperties::GetSpecificHeatGlycol(state,
    1379        4872 :                                                     state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    1380             :                                                     waterInletTemp,
    1381        4872 :                                                     state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    1382             :                                                     RoutineName);
    1383        4872 :         Effectiveness = 1.0 - exp(-this->UA / (waterMassFlowRate * Cp));
    1384        4872 :         if (Effectiveness <= 0.0) {
    1385           0 :             Effectiveness = 0.0;
    1386        4872 :         } else if (Effectiveness >= 1.0) {
    1387          36 :             Effectiveness = 1.0;
    1388             :         }
    1389        4872 :         CoolingPanelCool = (Effectiveness)*waterMassFlowRate * Cp * (waterInletTemp - Tzone);
    1390        4872 :         waterOutletTemp = this->WaterInletTemp - (CoolingPanelCool / (waterMassFlowRate * Cp));
    1391        4872 :         RadHeat = CoolingPanelCool * this->FracRadiant;
    1392        4872 :         state.dataChilledCeilingPanelSimple->CoolingPanel(CoolingPanelNum).CoolingPanelSource = RadHeat;
    1393             : 
    1394        4872 :         if (this->FracRadiant <= MinFrac) {
    1395           0 :             LoadMet = CoolingPanelCool;
    1396             :         } else {
    1397             : 
    1398             :             // Now, distribute the radiant energy of all systems to the appropriate surfaces, to people, and the air
    1399        4872 :             DistributeCoolingPanelRadGains(state);
    1400             :             // Now "simulate" the system by recalculating the heat balances
    1401        4872 :             HeatBalanceSurfaceManager::CalcHeatBalanceOutsideSurf(state, ZoneNum);
    1402             : 
    1403        4872 :             HeatBalanceSurfaceManager::CalcHeatBalanceInsideSurf(state, ZoneNum);
    1404             : 
    1405             :             // Here an assumption is made regarding radiant heat transfer to people.
    1406             :             // While the radiant heat transfer to people array will be used by the thermal comfort
    1407             :             // routines, the energy transfer to people would get lost from the perspective
    1408             :             // of the heat balance.  So, to avoid this net loss of energy which clearly
    1409             :             // gets added to the zones, we must account for it somehow.  This assumption
    1410             :             // that all energy radiated to people is converted to convective energy is
    1411             :             // not very precise, but at least it conserves energy. The system impact to heat balance
    1412             :             // should include this.
    1413        4872 :             LoadMet = (state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state) - this->ZeroCPSourceSumHATsurf) + (CoolingPanelCool * this->FracConvect) +
    1414        4872 :                       (RadHeat * this->FracDistribPerson);
    1415             :         }
    1416        4872 :         this->WaterOutletEnthalpy = this->WaterInletEnthalpy - CoolingPanelCool / waterMassFlowRate;
    1417             : 
    1418             :     } else { // cooling panel off
    1419       17543 :         CapacitanceWater = 0.0;
    1420       17543 :         NTU = 0.0;
    1421       17543 :         Effectiveness = 0.0;
    1422       17543 :         waterOutletTemp = waterInletTemp;
    1423       17543 :         CoolingPanelCool = 0.0;
    1424       17543 :         LoadMet = 0.0;
    1425       17543 :         RadHeat = 0.0;
    1426       17543 :         waterMassFlowRate = 0.0;
    1427       17543 :         this->CoolingPanelSource = 0.0;
    1428       17543 :         this->WaterOutletEnthalpy = this->WaterInletEnthalpy;
    1429             :     }
    1430             : 
    1431       22415 :     this->WaterOutletTemp = waterOutletTemp;
    1432       22415 :     this->WaterMassFlowRate = waterMassFlowRate;
    1433       22415 :     this->TotPower = LoadMet;
    1434       22415 :     this->Power = CoolingPanelCool;
    1435       22415 :     this->ConvPower = CoolingPanelCool - RadHeat;
    1436       22415 :     this->RadPower = RadHeat;
    1437       22415 : }
    1438             : 
    1439       17144 : Real64 CoolingPanelParams::getCoolingPanelControlTemp(EnergyPlusData &state, int const ZoneNum) const
    1440             : {
    1441             : 
    1442             :     // SUBROUTINE INFORMATION:
    1443             :     //       AUTHOR         Rick Strand
    1444             :     //       DATE WRITTEN   July 2016
    1445             : 
    1446             :     // METHODOLOGY EMPLOYED:
    1447             :     // This subroutine sets the control temperature for the simple cooling panel.
    1448             : 
    1449             :     // Using/Aliasing
    1450             : 
    1451       17144 :     switch (this->controlType) {
    1452       17144 :     case ClgPanelCtrlType::MAT: {
    1453       17144 :         return state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT;
    1454             :     } break;
    1455           0 :     case ClgPanelCtrlType::MRT: {
    1456           0 :         return state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MRT;
    1457             :     } break;
    1458           0 :     case ClgPanelCtrlType::Operative: {
    1459           0 :         return 0.5 * (state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT +
    1460           0 :                       state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MRT);
    1461             :     } break;
    1462           0 :     case ClgPanelCtrlType::ODB: {
    1463           0 :         return state.dataHeatBal->Zone(ZoneNum).OutDryBulbTemp;
    1464             :     } break;
    1465           0 :     case ClgPanelCtrlType::OWB: {
    1466           0 :         return state.dataHeatBal->Zone(ZoneNum).OutWetBulbTemp;
    1467             :     } break;
    1468           0 :     default: { // Should never get here
    1469           0 :         assert(false);
    1470             :         return -99990; // Compiler wants a return value for every path, so give an invalid value
    1471             :     } break;
    1472             :     }
    1473             : }
    1474             : 
    1475       22415 : void UpdateCoolingPanel(EnergyPlusData &state, int const CoolingPanelNum)
    1476             : {
    1477             : 
    1478             :     // SUBROUTINE INFORMATION:
    1479             :     //       AUTHOR         Rick Strand
    1480             :     //       DATE WRITTEN   Sept 2014
    1481             :     //                      February 2001
    1482             :     //       MODIFIED       Aug 2007 Daeho Kang (Add the update of radiant source)
    1483             : 
    1484             :     // REFERENCES:
    1485             :     // Existing code for hot water baseboard models (radiant-convective variety)
    1486             : 
    1487             :     // Using/Aliasing
    1488       22415 :     Real64 SysTimeElapsed = state.dataHVACGlobal->SysTimeElapsed;
    1489       22415 :     Real64 TimeStepSys = state.dataHVACGlobal->TimeStepSys;
    1490       22415 :     auto &thisCP(state.dataChilledCeilingPanelSimple->CoolingPanel(CoolingPanelNum));
    1491             : 
    1492             :     // First, update the running average if necessary...
    1493       22415 :     if (thisCP.LastSysTimeElapsed == SysTimeElapsed) {
    1494       21210 :         thisCP.CoolingPanelSrcAvg -= thisCP.LastCoolingPanelSrc * thisCP.LastTimeStepSys / state.dataGlobal->TimeStepZone;
    1495             :     }
    1496             :     // Update the running average and the "last" values with the current values of the appropriate variables
    1497       22415 :     thisCP.CoolingPanelSrcAvg += thisCP.CoolingPanelSource * TimeStepSys / state.dataGlobal->TimeStepZone;
    1498             : 
    1499       22415 :     thisCP.LastCoolingPanelSrc = thisCP.CoolingPanelSource;
    1500       22415 :     thisCP.LastSysTimeElapsed = SysTimeElapsed;
    1501       22415 :     thisCP.LastTimeStepSys = TimeStepSys;
    1502             : 
    1503       22415 :     int WaterInletNode = thisCP.WaterInletNode;
    1504       22415 :     int WaterOutletNode = thisCP.WaterOutletNode;
    1505             : 
    1506       22415 :     auto &ThisInNode(state.dataLoopNodes->Node(WaterInletNode));
    1507       22415 :     auto &ThisOutNode(state.dataLoopNodes->Node(WaterOutletNode));
    1508             : 
    1509             :     // Set the outlet water nodes for the panel
    1510       22415 :     PlantUtilities::SafeCopyPlantNode(state, WaterInletNode, WaterOutletNode);
    1511       22415 :     ThisOutNode.Temp = thisCP.WaterOutletTemp;
    1512       22415 :     ThisOutNode.Enthalpy = thisCP.WaterOutletEnthalpy;
    1513       22415 :     ThisInNode.MassFlowRate = thisCP.WaterMassFlowRate;
    1514       22415 :     ThisOutNode.MassFlowRate = thisCP.WaterMassFlowRate;
    1515       22415 :     ThisInNode.MassFlowRateMax = thisCP.WaterMassFlowRateMax;
    1516       22415 :     ThisOutNode.MassFlowRateMax = thisCP.WaterMassFlowRateMax;
    1517       22415 : }
    1518             : 
    1519     2804482 : void UpdateCoolingPanelSourceValAvg(EnergyPlusData &state,
    1520             :                                     bool &CoolingPanelSysOn) // .TRUE. if the radiant system has run this zone time step
    1521             : {
    1522             : 
    1523             :     // SUBROUTINE INFORMATION:
    1524             :     //       AUTHOR         Rick Strand
    1525             :     //       DATE WRITTEN   Sept 2014
    1526             : 
    1527             :     // PURPOSE OF THIS SUBROUTINE:
    1528             :     // To transfer the average value of the heat source over the entire
    1529             :     // zone time step back to the heat balance routines so that the heat
    1530             :     // balance algorithms can simulate one last time with the average source
    1531             :     // to maintain some reasonable amount of continuity and energy balance
    1532             :     // in the temperature and flux histories.
    1533             : 
    1534             :     // METHODOLOGY EMPLOYED:
    1535             :     // All of the record keeping for the average term is done in the Update
    1536             :     // routine so the only other thing that this subroutine does is check to
    1537             :     // see if the system was even on.  If any average term is non-zero, then
    1538             :     // one or more of the radiant systems was running.
    1539             : 
    1540             :     // REFERENCES:
    1541             :     // Existing code for hot water baseboard models (radiant-convective variety)
    1542             : 
    1543     2804482 :     CoolingPanelSysOn = false;
    1544             : 
    1545             :     // If this was never allocated, then there are no radiant systems in this input file (just RETURN)
    1546     2804482 :     if (!allocated(state.dataChilledCeilingPanelSimple->CoolingPanel)) return;
    1547             : 
    1548             :     // If it was allocated, then we have to check to see if this was running at all...
    1549       14471 :     for (int CoolingPanelNum = 1; CoolingPanelNum <= (int)state.dataChilledCeilingPanelSimple->CoolingPanel.size(); ++CoolingPanelNum) {
    1550        8112 :         if (state.dataChilledCeilingPanelSimple->CoolingPanel(CoolingPanelNum).CoolingPanelSrcAvg != 0.0) {
    1551        1753 :             CoolingPanelSysOn = true;
    1552        1753 :             break; // DO loop
    1553             :         }
    1554             :     }
    1555             : 
    1556       16224 :     for (auto &cp : state.dataChilledCeilingPanelSimple->CoolingPanel) {
    1557        8112 :         cp.CoolingPanelSource = cp.CoolingPanelSrcAvg;
    1558             :     }
    1559             : 
    1560        8112 :     DistributeCoolingPanelRadGains(state); // CoolingPanelRadSource has been modified so we need to redistribute gains
    1561             : }
    1562             : 
    1563       12984 : void DistributeCoolingPanelRadGains(EnergyPlusData &state)
    1564             : {
    1565             : 
    1566             :     // SUBROUTINE INFORMATION:
    1567             :     //       AUTHOR         Rick Strand
    1568             :     //       DATE WRITTEN   Sept 2014
    1569             : 
    1570             :     // PURPOSE OF THIS SUBROUTINE:
    1571             :     // To distribute the gains from the hot water basebaord heater
    1572             :     // as specified in the user input file.  This includes distribution
    1573             :     // of long wavelength radiant gains to surfaces and "people."
    1574             : 
    1575             :     // METHODOLOGY EMPLOYED:
    1576             :     // We must cycle through all of the radiant systems because each
    1577             :     // surface could feel the effect of more than one radiant system.
    1578             :     // Note that the energy radiated to people is assumed to affect them
    1579             :     // but them it is assumed to be convected to the air.
    1580             : 
    1581             :     // REFERENCES:
    1582             :     // Existing code for hot water baseboard models (radiant-convective variety)
    1583             : 
    1584             :     // SUBROUTINE PARAMETER DEFINITIONS:
    1585       12984 :     Real64 constexpr SmallestArea(0.001); // Smallest area in meters squared (to avoid a divide by zero)
    1586             : 
    1587             :     // Initialize arrays
    1588       25968 :     for (auto &thisCP : state.dataChilledCeilingPanelSimple->CoolingPanel) {
    1589       51936 :         for (int radSurfNum = 1; radSurfNum <= thisCP.TotSurfToDistrib; ++radSurfNum) {
    1590       38952 :             int surfNum = thisCP.SurfacePtr(radSurfNum);
    1591       38952 :             state.dataHeatBalFanSys->surfQRadFromHVAC(surfNum).CoolingPanel = 0.0;
    1592             :         }
    1593             :     }
    1594       12984 :     state.dataHeatBalFanSys->ZoneQCoolingPanelToPerson = 0.0;
    1595             : 
    1596       25968 :     for (auto &thisCP : state.dataChilledCeilingPanelSimple->CoolingPanel) {
    1597       12984 :         int ZoneNum = thisCP.ZonePtr;
    1598       12984 :         if (ZoneNum <= 0) continue;
    1599       12984 :         state.dataHeatBalFanSys->ZoneQCoolingPanelToPerson(ZoneNum) += thisCP.CoolingPanelSource * thisCP.FracDistribPerson;
    1600             : 
    1601       51936 :         for (int RadSurfNum = 1; RadSurfNum <= thisCP.TotSurfToDistrib; ++RadSurfNum) {
    1602       38952 :             int SurfNum = thisCP.SurfacePtr(RadSurfNum);
    1603       38952 :             auto &ThisSurf(state.dataSurface->Surface(SurfNum));
    1604       38952 :             if (ThisSurf.Area > SmallestArea) {
    1605       38952 :                 Real64 ThisSurfIntensity = (thisCP.CoolingPanelSource * thisCP.FracDistribToSurf(RadSurfNum) / ThisSurf.Area);
    1606       38952 :                 state.dataHeatBalFanSys->surfQRadFromHVAC(SurfNum).CoolingPanel += ThisSurfIntensity;
    1607             :                 // CR 8074, trap for excessive intensity (throws off surface balance )
    1608       38952 :                 if (ThisSurfIntensity > DataHeatBalFanSys::MaxRadHeatFlux) {
    1609           0 :                     ShowSevereError(state, "DistributeCoolingPanelRadGains:  excessive thermal radiation heat flux intensity detected");
    1610           0 :                     ShowContinueError(state, format("Surface = {}", ThisSurf.Name));
    1611           0 :                     ShowContinueError(state, format("Surface area = {:.3R} [m2]", ThisSurf.Area));
    1612           0 :                     ShowContinueError(state, format("Occurs in {} = {}", cCMO_CoolingPanel_Simple, thisCP.Name));
    1613           0 :                     ShowContinueError(state, format("Radiation intensity = {:.2R} [W/m2]", ThisSurfIntensity));
    1614           0 :                     ShowContinueError(state, format("Assign a larger surface area or more surfaces in {}", cCMO_CoolingPanel_Simple));
    1615           0 :                     ShowFatalError(state, "DistributeCoolingPanelRadGains:  excessive thermal radiation heat flux intensity detected");
    1616             :                 }
    1617             :             } else {
    1618           0 :                 ShowSevereError(state, "DistributeCoolingPanelRadGains:  surface not large enough to receive thermal radiation heat flux");
    1619           0 :                 ShowContinueError(state, format("Surface = {}", ThisSurf.Name));
    1620           0 :                 ShowContinueError(state, format("Surface area = {:.3R} [m2]", ThisSurf.Area));
    1621           0 :                 ShowContinueError(state, format("Occurs in {} = {}", cCMO_CoolingPanel_Simple, thisCP.Name));
    1622           0 :                 ShowContinueError(state, format("Assign a larger surface area or more surfaces in {}", cCMO_CoolingPanel_Simple));
    1623           0 :                 ShowFatalError(state, "DistributeCoolingPanelRadGains:  surface not large enough to receive thermal radiation heat flux");
    1624             :             }
    1625             :         }
    1626             :     }
    1627       12984 : }
    1628             : 
    1629       22415 : void CoolingPanelParams::ReportCoolingPanel(EnergyPlusData &state)
    1630             : {
    1631             : 
    1632             :     // SUBROUTINE INFORMATION:
    1633             :     //       AUTHOR         Rick Strand
    1634             :     //       DATE WRITTEN   Aug 2014
    1635             : 
    1636             :     // REFERENCES:
    1637             :     // Existing code for hot water baseboard models (radiant-convective variety)
    1638             : 
    1639       22415 :     Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
    1640             : 
    1641             :     // All of the power numbers are negative for cooling.  This is because they will have a negative
    1642             :     // or cooling impact on the surfaces/zones.  However, the output variables are noted as cooling.
    1643             :     // So, their sign should be positive if actually cooling and we need to reverse the sign here.
    1644             :     // This should not have an impact on any of the internal variables or the heat balances because
    1645             :     // those use other variables.
    1646       22415 :     this->TotPower = -this->TotPower;
    1647       22415 :     this->Power = -this->Power;
    1648       22415 :     this->ConvPower = -this->ConvPower;
    1649       22415 :     this->RadPower = -this->RadPower;
    1650             : 
    1651       22415 :     this->TotEnergy = this->TotPower * TimeStepSysSec;
    1652       22415 :     this->Energy = this->Power * TimeStepSysSec;
    1653       22415 :     this->ConvEnergy = this->ConvPower * TimeStepSysSec;
    1654       22415 :     this->RadEnergy = this->RadPower * TimeStepSysSec;
    1655       22415 : }
    1656             : 
    1657             : } // namespace EnergyPlus::CoolingPanelSimple

Generated by: LCOV version 1.14