LCOV - code coverage report
Current view: top level - EnergyPlus/Coils - CoilCoolingDXCurveFitPerformance.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 261 328 79.6 %
Date: 2023-01-17 19:17:23 Functions: 9 9 100.0 %

          Line data    Source code
       1             : // EnergyPlus, Copyright (c) 1996-2023, The Board of Trustees of the University of Illinois,
       2             : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3             : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4             : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5             : // contributors. All rights reserved.
       6             : //
       7             : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8             : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9             : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10             : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11             : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12             : //
      13             : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14             : // provided that the following conditions are met:
      15             : //
      16             : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17             : //     conditions and the following disclaimer.
      18             : //
      19             : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20             : //     conditions and the following disclaimer in the documentation and/or other materials
      21             : //     provided with the distribution.
      22             : //
      23             : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24             : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25             : //     used to endorse or promote products derived from this software without specific prior
      26             : //     written permission.
      27             : //
      28             : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29             : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30             : //     reference solely to the software portion of its product, Licensee must refer to the
      31             : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32             : //     obtained under this License and may not use a different name for the software. Except as
      33             : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34             : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35             : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36             : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37             : //
      38             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39             : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40             : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41             : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42             : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43             : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45             : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46             : // POSSIBILITY OF SUCH DAMAGE.
      47             : 
      48             : #include <EnergyPlus/Coils/CoilCoolingDXCurveFitPerformance.hh>
      49             : #include <EnergyPlus/CurveManager.hh>
      50             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      51             : #include <EnergyPlus/DataEnvironment.hh>
      52             : #include <EnergyPlus/DataGlobalConstants.hh>
      53             : #include <EnergyPlus/DataHVACGlobals.hh>
      54             : #include <EnergyPlus/DataIPShortCuts.hh>
      55             : #include <EnergyPlus/Fans.hh>
      56             : #include <EnergyPlus/General.hh>
      57             : #include <EnergyPlus/GeneralRoutines.hh>
      58             : #include <EnergyPlus/HVACFan.hh>
      59             : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      60             : #include <EnergyPlus/OutputReportPredefined.hh>
      61             : #include <EnergyPlus/Psychrometrics.hh>
      62             : #include <EnergyPlus/ScheduleManager.hh>
      63             : #include <EnergyPlus/UtilityRoutines.hh>
      64             : 
      65             : using namespace EnergyPlus;
      66             : 
      67          51 : void CoilCoolingDXCurveFitPerformance::instantiateFromInputSpec(EnergyPlus::EnergyPlusData &state,
      68             :                                                                 const CoilCoolingDXCurveFitPerformanceInputSpecification &input_data)
      69             : {
      70             :     static constexpr std::string_view routineName("CoilCoolingDXCurveFitOperatingMode::instantiateFromInputSpec: ");
      71          51 :     bool errorsFound(false);
      72          51 :     this->original_input_specs = input_data;
      73          51 :     this->name = input_data.name;
      74          51 :     this->minOutdoorDrybulb = input_data.minimum_outdoor_dry_bulb_temperature_for_compressor_operation;
      75          51 :     this->maxOutdoorDrybulbForBasin = input_data.maximum_outdoor_dry_bulb_temperature_for_crankcase_heater_operation;
      76          51 :     this->crankcaseHeaterCap = input_data.crankcase_heater_capacity;
      77          51 :     this->normalMode = CoilCoolingDXCurveFitOperatingMode(state, input_data.base_operating_mode_name);
      78          51 :     this->normalMode.oneTimeInit(state); // oneTimeInit does not need to be delayed in this use case
      79          51 :     if (UtilityRoutines::SameString(input_data.capacity_control, "CONTINUOUS")) {
      80           2 :         this->capControlMethod = CapControlMethod::CONTINUOUS;
      81          49 :     } else if (UtilityRoutines::SameString(input_data.capacity_control, "DISCRETE")) {
      82          49 :         this->capControlMethod = CapControlMethod::DISCRETE;
      83             :     } else {
      84           0 :         ShowSevereError(state, std::string{routineName} + this->object_name + "=\"" + this->name + "\", invalid");
      85           0 :         ShowContinueError(state, "...Capacity Control Method=\"" + input_data.capacity_control + "\":");
      86           0 :         ShowContinueError(state, "...must be Discrete or Continuous.");
      87           0 :         errorsFound = true;
      88             :     }
      89          51 :     this->evapCondBasinHeatCap = input_data.basin_heater_capacity;
      90          51 :     this->evapCondBasinHeatSetpoint = input_data.basin_heater_setpoint_temperature;
      91          51 :     if (input_data.basin_heater_operating_schedule_name.empty()) {
      92          51 :         this->evapCondBasinHeatSchedulIndex = DataGlobalConstants::ScheduleAlwaysOn;
      93             :     } else {
      94           0 :         this->evapCondBasinHeatSchedulIndex = ScheduleManager::GetScheduleIndex(state, input_data.basin_heater_operating_schedule_name);
      95             :     }
      96          51 :     if (this->evapCondBasinHeatSchedulIndex == 0) {
      97           0 :         ShowSevereError(state, std::string{routineName} + this->object_name + "=\"" + this->name + "\", invalid");
      98           0 :         ShowContinueError(
      99           0 :             state, "...Evaporative Condenser Basin Heater Operating Schedule Name=\"" + input_data.basin_heater_operating_schedule_name + "\".");
     100           0 :         errorsFound = true;
     101             :     }
     102             : 
     103          51 :     if (!input_data.alternate_operating_mode_name.empty() && input_data.alternate_operating_mode2_name.empty()) {
     104           5 :         this->hasAlternateMode = DataHVACGlobals::coilEnhancedMode;
     105           5 :         this->alternateMode = CoilCoolingDXCurveFitOperatingMode(state, input_data.alternate_operating_mode_name);
     106           5 :         this->alternateMode.oneTimeInit(state); // oneTimeInit does not need to be delayed in this use case
     107             :     }
     108             :     // Validate fuel type input
     109          51 :     bool fuelTypeError(false);
     110          51 :     UtilityRoutines::ValidateFuelTypeWithAssignResourceTypeNum(
     111             :         input_data.compressor_fuel_type, this->compressorFuelTypeForOutput, this->compressorFuelType, fuelTypeError);
     112          51 :     if (fuelTypeError) {
     113           0 :         ShowSevereError(state, std::string{routineName} + this->object_name + "=\"" + this->name + "\", invalid");
     114           0 :         ShowContinueError(state, "...Compressor Fuel Type=\"" + input_data.compressor_fuel_type + "\".");
     115           0 :         errorsFound = true;
     116           0 :         fuelTypeError = false;
     117             :     }
     118             : 
     119          51 :     if (!input_data.alternate_operating_mode2_name.empty() && !input_data.alternate_operating_mode_name.empty()) {
     120           1 :         this->hasAlternateMode = DataHVACGlobals::coilSubcoolReheatMode;
     121           1 :         this->alternateMode = CoilCoolingDXCurveFitOperatingMode(state, input_data.alternate_operating_mode_name);
     122           1 :         this->alternateMode2 = CoilCoolingDXCurveFitOperatingMode(state, input_data.alternate_operating_mode2_name);
     123           1 :         setOperMode(state, this->normalMode, 1);
     124           1 :         setOperMode(state, this->alternateMode, 2);
     125           1 :         setOperMode(state, this->alternateMode2, 3);
     126             :     }
     127             : 
     128          51 :     if (errorsFound) {
     129           0 :         ShowFatalError(
     130           0 :             state, std::string{routineName} + "Errors found in getting " + this->object_name + " input. Preceding condition(s) causes termination.");
     131             :     }
     132          51 : }
     133             : 
     134          51 : CoilCoolingDXCurveFitPerformance::CoilCoolingDXCurveFitPerformance(EnergyPlus::EnergyPlusData &state, const std::string &name_to_find)
     135             : {
     136          51 :     int numPerformances = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CoilCoolingDXCurveFitPerformance::object_name);
     137             :     if (numPerformances <= 0) {
     138             :         // error
     139             :     }
     140          51 :     bool found_it = false;
     141         131 :     for (int perfNum = 1; perfNum <= numPerformances; ++perfNum) {
     142             :         int NumAlphas;  // Number of Alphas for each GetObjectItem call
     143             :         int NumNumbers; // Number of Numbers for each GetObjectItem call
     144             :         int IOStatus;
     145         524 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     146             :                                                                  CoilCoolingDXCurveFitPerformance::object_name,
     147             :                                                                  perfNum,
     148         131 :                                                                  state.dataIPShortCut->cAlphaArgs,
     149             :                                                                  NumAlphas,
     150         131 :                                                                  state.dataIPShortCut->rNumericArgs,
     151             :                                                                  NumNumbers,
     152             :                                                                  IOStatus,
     153             :                                                                  _,
     154         131 :                                                                  state.dataIPShortCut->lAlphaFieldBlanks);
     155         131 :         if (!UtilityRoutines::SameString(name_to_find, state.dataIPShortCut->cAlphaArgs(1))) {
     156          80 :             continue;
     157             :         }
     158          51 :         found_it = true;
     159             : 
     160         102 :         CoilCoolingDXCurveFitPerformanceInputSpecification input_specs;
     161             : 
     162          51 :         input_specs.name = state.dataIPShortCut->cAlphaArgs(1);
     163          51 :         input_specs.crankcase_heater_capacity = state.dataIPShortCut->rNumericArgs(1);
     164          51 :         input_specs.minimum_outdoor_dry_bulb_temperature_for_compressor_operation = state.dataIPShortCut->rNumericArgs(2);
     165          51 :         input_specs.maximum_outdoor_dry_bulb_temperature_for_crankcase_heater_operation = state.dataIPShortCut->rNumericArgs(3);
     166          51 :         if (state.dataIPShortCut->lNumericFieldBlanks(4)) {
     167          49 :             input_specs.unit_internal_static_air_pressure = 0.0;
     168             :         } else {
     169           2 :             input_specs.unit_internal_static_air_pressure = state.dataIPShortCut->rNumericArgs(4);
     170             :         }
     171          51 :         input_specs.capacity_control = state.dataIPShortCut->cAlphaArgs(2);
     172          51 :         input_specs.basin_heater_capacity = state.dataIPShortCut->rNumericArgs(5);
     173          51 :         input_specs.basin_heater_setpoint_temperature = state.dataIPShortCut->rNumericArgs(6);
     174          51 :         input_specs.basin_heater_operating_schedule_name = state.dataIPShortCut->cAlphaArgs(3);
     175          51 :         input_specs.compressor_fuel_type = state.dataIPShortCut->cAlphaArgs(4);
     176          51 :         input_specs.base_operating_mode_name = state.dataIPShortCut->cAlphaArgs(5);
     177          51 :         if (!state.dataIPShortCut->lAlphaFieldBlanks(6)) {
     178           6 :             input_specs.alternate_operating_mode_name = state.dataIPShortCut->cAlphaArgs(6);
     179             :         }
     180          51 :         if (!state.dataIPShortCut->lAlphaFieldBlanks(7)) {
     181           1 :             input_specs.alternate_operating_mode2_name = state.dataIPShortCut->cAlphaArgs(7);
     182             :         }
     183             : 
     184          51 :         this->instantiateFromInputSpec(state, input_specs);
     185          51 :         break;
     186             :     }
     187             : 
     188          51 :     if (!found_it) {
     189           0 :         ShowFatalError(state, "Could not find Coil:Cooling:DX:Performance object with name: " + name_to_find);
     190             :     }
     191          51 : }
     192             : 
     193     4511129 : void CoilCoolingDXCurveFitPerformance::simulate(EnergyPlus::EnergyPlusData &state,
     194             :                                                 const DataLoopNode::NodeData &inletNode,
     195             :                                                 DataLoopNode::NodeData &outletNode,
     196             :                                                 int useAlternateMode,
     197             :                                                 Real64 &PLR,
     198             :                                                 int &speedNum,
     199             :                                                 Real64 &speedRatio,
     200             :                                                 int const fanOpMode,
     201             :                                                 DataLoopNode::NodeData &condInletNode,
     202             :                                                 DataLoopNode::NodeData &condOutletNode,
     203             :                                                 bool const singleMode,
     204             :                                                 Real64 LoadSHR)
     205             : {
     206             :     static constexpr std::string_view RoutineName = "CoilCoolingDXCurveFitPerformance::simulate";
     207     4511129 :     Real64 reportingConstant = state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour;
     208     4511129 :     this->recoveredEnergyRate = 0.0;
     209     4511129 :     this->NormalSHR = 0.0;
     210             : 
     211     4511129 :     if (useAlternateMode == DataHVACGlobals::coilSubcoolReheatMode) {
     212             :         Real64 totalCoolingRate;
     213             :         Real64 sensNorRate;
     214             :         Real64 sensSubRate;
     215             :         Real64 sensRehRate;
     216             :         Real64 latRate;
     217             :         Real64 SysNorSHR;
     218             :         Real64 SysSubSHR;
     219             :         Real64 SysRehSHR;
     220             :         Real64 HumRatNorOut;
     221             :         Real64 TempNorOut;
     222             :         Real64 EnthalpyNorOut;
     223             :         Real64 modeRatio;
     224             : 
     225       76768 :         this->calculate(
     226             :             state, this->normalMode, inletNode, outletNode, PLR, speedNum, speedRatio, fanOpMode, condInletNode, condOutletNode, singleMode);
     227             : 
     228             :         // this->OperatingMode = 1;
     229      153536 :         CalcComponentSensibleLatentOutput(
     230       76768 :             outletNode.MassFlowRate, inletNode.Temp, inletNode.HumRat, outletNode.Temp, outletNode.HumRat, sensNorRate, latRate, totalCoolingRate);
     231       76768 :         if (totalCoolingRate > 1.0E-10) {
     232       25544 :             this->OperatingMode = 1;
     233       25544 :             this->NormalSHR = sensNorRate / totalCoolingRate;
     234       25544 :             this->powerUse = this->normalMode.OpModePower;
     235       25544 :             this->RTF = this->normalMode.OpModeRTF;
     236       25544 :             this->wasteHeatRate = this->normalMode.OpModeWasteHeat;
     237             :         }
     238             : 
     239       76768 :         if ((PLR != 0.0) && (LoadSHR != 0.0)) {
     240        7680 :             if (totalCoolingRate == 0.0) {
     241           0 :                 SysNorSHR = 1.0;
     242             :             } else {
     243        7680 :                 SysNorSHR = sensNorRate / totalCoolingRate;
     244             :             }
     245        7680 :             HumRatNorOut = outletNode.HumRat;
     246        7680 :             TempNorOut = outletNode.Temp;
     247        7680 :             EnthalpyNorOut = outletNode.Enthalpy;
     248        7680 :             this->recoveredEnergyRate = sensNorRate;
     249             : 
     250        7680 :             if (LoadSHR < SysNorSHR) {
     251        4832 :                 outletNode.MassFlowRate = inletNode.MassFlowRate;
     252        4832 :                 this->calculate(state,
     253             :                                 this->alternateMode,
     254             :                                 inletNode,
     255             :                                 outletNode,
     256             :                                 PLR,
     257             :                                 speedNum,
     258             :                                 speedRatio,
     259             :                                 fanOpMode,
     260             :                                 condInletNode,
     261             :                                 condOutletNode,
     262             :                                 singleMode);
     263        9664 :                 CalcComponentSensibleLatentOutput(outletNode.MassFlowRate,
     264        4832 :                                                   inletNode.Temp,
     265        4832 :                                                   inletNode.HumRat,
     266             :                                                   outletNode.Temp,
     267             :                                                   outletNode.HumRat,
     268             :                                                   sensSubRate,
     269             :                                                   latRate,
     270             :                                                   totalCoolingRate);
     271        4832 :                 SysSubSHR = sensSubRate / totalCoolingRate;
     272        4832 :                 if (LoadSHR < SysSubSHR) {
     273        4832 :                     outletNode.MassFlowRate = inletNode.MassFlowRate;
     274        4832 :                     this->calculate(state,
     275             :                                     this->alternateMode2,
     276             :                                     inletNode,
     277             :                                     outletNode,
     278             :                                     PLR,
     279             :                                     speedNum,
     280             :                                     speedRatio,
     281             :                                     fanOpMode,
     282             :                                     condInletNode,
     283             :                                     condOutletNode,
     284             :                                     singleMode);
     285        9664 :                     CalcComponentSensibleLatentOutput(outletNode.MassFlowRate,
     286        4832 :                                                       inletNode.Temp,
     287        4832 :                                                       inletNode.HumRat,
     288             :                                                       outletNode.Temp,
     289             :                                                       outletNode.HumRat,
     290             :                                                       sensRehRate,
     291             :                                                       latRate,
     292             :                                                       totalCoolingRate);
     293        4832 :                     SysRehSHR = sensRehRate / totalCoolingRate;
     294        4832 :                     if (LoadSHR > SysRehSHR) {
     295        4096 :                         modeRatio = (LoadSHR - SysNorSHR) / (SysRehSHR - SysNorSHR);
     296        4096 :                         this->OperatingMode = 3;
     297        4096 :                         outletNode.HumRat = HumRatNorOut * (1.0 - modeRatio) + modeRatio * outletNode.HumRat;
     298        4096 :                         outletNode.Enthalpy = EnthalpyNorOut * (1.0 - modeRatio) + modeRatio * outletNode.Enthalpy;
     299        4096 :                         outletNode.Temp = Psychrometrics::PsyTdbFnHW(outletNode.Enthalpy, outletNode.HumRat);
     300        4096 :                         this->ModeRatio = modeRatio;
     301             :                         // update other reporting terms
     302        4096 :                         this->powerUse = this->normalMode.OpModePower * (1.0 - modeRatio) + modeRatio * this->alternateMode2.OpModePower;
     303        4096 :                         this->RTF = this->normalMode.OpModeRTF * (1.0 - modeRatio) + modeRatio * this->alternateMode2.OpModeRTF;
     304        4096 :                         this->wasteHeatRate = this->normalMode.OpModeWasteHeat * (1.0 - modeRatio) + modeRatio * this->alternateMode2.OpModeWasteHeat;
     305        4096 :                         this->recoveredEnergyRate = (this->recoveredEnergyRate - sensRehRate) * this->ModeRatio;
     306             :                     } else {
     307         736 :                         this->ModeRatio = 1.0;
     308         736 :                         this->OperatingMode = 3;
     309         736 :                         this->recoveredEnergyRate = (this->recoveredEnergyRate - sensRehRate) * this->ModeRatio;
     310             :                     }
     311             :                 } else {
     312           0 :                     modeRatio = (LoadSHR - SysNorSHR) / (SysSubSHR - SysNorSHR);
     313           0 :                     this->OperatingMode = 2;
     314             :                     // process outlet conditions and total output
     315           0 :                     outletNode.HumRat = HumRatNorOut * (1.0 - modeRatio) + modeRatio * outletNode.HumRat;
     316           0 :                     outletNode.Enthalpy = EnthalpyNorOut * (1.0 - modeRatio) + modeRatio * outletNode.Enthalpy;
     317           0 :                     outletNode.Temp = Psychrometrics::PsyTdbFnHW(outletNode.Enthalpy, outletNode.HumRat);
     318           0 :                     this->ModeRatio = modeRatio;
     319             :                     // update other reporting terms
     320           0 :                     this->powerUse = this->normalMode.OpModePower * (1.0 - modeRatio) + modeRatio * this->alternateMode.OpModePower;
     321           0 :                     this->RTF = this->normalMode.OpModeRTF * (1.0 - modeRatio) + modeRatio * this->alternateMode.OpModeRTF;
     322           0 :                     this->wasteHeatRate = this->normalMode.OpModeWasteHeat * (1.0 - modeRatio) + modeRatio * this->alternateMode.OpModeWasteHeat;
     323           0 :                     this->recoveredEnergyRate = (this->recoveredEnergyRate - sensSubRate) * this->ModeRatio;
     324             :                 }
     325             :             } else {
     326        2848 :                 this->ModeRatio = 0.0;
     327        2848 :                 this->OperatingMode = 1;
     328        2848 :                 this->recoveredEnergyRate = 0.0;
     329             :             }
     330             :             // Check for saturation error and modify temperature at constant enthalpy
     331        7680 :             Real64 tsat = Psychrometrics::PsyTsatFnHPb(state, outletNode.Enthalpy, inletNode.Press, RoutineName);
     332        7680 :             if (outletNode.Temp < tsat) {
     333           0 :                 outletNode.Temp = tsat;
     334           0 :                 outletNode.HumRat = Psychrometrics::PsyWFnTdbH(state, tsat, outletNode.Enthalpy);
     335             :             }
     336             :         }
     337     4434361 :     } else if (useAlternateMode == DataHVACGlobals::coilEnhancedMode) {
     338           0 :         this->calculate(
     339             :             state, this->alternateMode, inletNode, outletNode, PLR, speedNum, speedRatio, fanOpMode, condInletNode, condOutletNode, singleMode);
     340           0 :         this->OperatingMode = 2;
     341           0 :         this->powerUse = this->alternateMode.OpModePower;
     342           0 :         this->RTF = this->alternateMode.OpModeRTF;
     343           0 :         this->wasteHeatRate = this->alternateMode.OpModeWasteHeat;
     344             :     } else {
     345     4434361 :         this->calculate(
     346             :             state, this->normalMode, inletNode, outletNode, PLR, speedNum, speedRatio, fanOpMode, condInletNode, condOutletNode, singleMode);
     347     4434361 :         this->OperatingMode = 1;
     348     4434361 :         this->powerUse = this->normalMode.OpModePower;
     349     4434361 :         this->RTF = this->normalMode.OpModeRTF;
     350     4434361 :         this->wasteHeatRate = this->normalMode.OpModeWasteHeat;
     351             :     }
     352             : 
     353             :     // calculate crankcase heater operation
     354     4511129 :     if (state.dataEnvrn->OutDryBulbTemp < this->maxOutdoorDrybulbForBasin) {
     355     1093704 :         this->crankcaseHeaterPower = this->crankcaseHeaterCap;
     356             :     } else {
     357     3417425 :         this->crankcaseHeaterPower = 0.0;
     358             :     }
     359     4511129 :     this->crankcaseHeaterPower = this->crankcaseHeaterPower * (1.0 - this->RTF);
     360     4511129 :     this->crankcaseHeaterElectricityConsumption = this->crankcaseHeaterPower * reportingConstant;
     361             : 
     362             :     // basin heater
     363     4511129 :     if (this->evapCondBasinHeatSchedulIndex > 0) {
     364           0 :         Real64 currentBasinHeaterAvail = ScheduleManager::GetCurrentScheduleValue(state, this->evapCondBasinHeatSchedulIndex);
     365           0 :         if (this->evapCondBasinHeatCap > 0.0 && currentBasinHeaterAvail > 0.0) {
     366           0 :             this->basinHeaterPower = max(0.0, this->evapCondBasinHeatCap * (this->evapCondBasinHeatSetpoint - state.dataEnvrn->OutDryBulbTemp));
     367             :         }
     368             :     } else {
     369             :         // If schedule does not exist, basin heater operates anytime outdoor dry-bulb temp is below setpoint
     370     4511129 :         if (this->evapCondBasinHeatCap > 0.0) {
     371           0 :             this->basinHeaterPower = max(0.0, this->evapCondBasinHeatCap * (this->evapCondBasinHeatSetpoint - state.dataEnvrn->OutDryBulbTemp));
     372             :         }
     373             :     }
     374     4511129 :     this->basinHeaterPower *= (1.0 - this->RTF);
     375     4511129 :     this->electricityConsumption = this->powerUse * reportingConstant;
     376             : 
     377     4511129 :     if (this->compressorFuelType != DataGlobalConstants::ResourceType::Electricity) {
     378           0 :         this->compressorFuelRate = this->powerUse;
     379           0 :         this->compressorFuelConsumption = this->electricityConsumption;
     380             : 
     381             :         // check this after adding parasitic loads
     382           0 :         this->powerUse = 0.0;
     383           0 :         this->electricityConsumption = 0.0;
     384             :     }
     385     4511129 : }
     386             : 
     387          51 : void CoilCoolingDXCurveFitPerformance::size(EnergyPlus::EnergyPlusData &state)
     388             : {
     389          51 :     if (!state.dataGlobal->SysSizingCalc && this->mySizeFlag) {
     390          51 :         this->normalMode.parentName = this->parentName;
     391          51 :         this->normalMode.size(state);
     392          51 :         if (this->hasAlternateMode == DataHVACGlobals::coilEnhancedMode) {
     393           5 :             this->alternateMode.size(state);
     394             :         }
     395          51 :         if (this->hasAlternateMode == DataHVACGlobals::coilSubcoolReheatMode) {
     396           1 :             this->alternateMode.size(state);
     397           1 :             this->alternateMode2.size(state);
     398             :         }
     399          51 :         this->mySizeFlag = false;
     400             :     }
     401          51 : }
     402             : 
     403     4520793 : void CoilCoolingDXCurveFitPerformance::calculate(EnergyPlus::EnergyPlusData &state,
     404             :                                                  CoilCoolingDXCurveFitOperatingMode &currentMode,
     405             :                                                  const DataLoopNode::NodeData &inletNode,
     406             :                                                  DataLoopNode::NodeData &outletNode,
     407             :                                                  Real64 &PLR,
     408             :                                                  int &speedNum,
     409             :                                                  Real64 &speedRatio,
     410             :                                                  int const fanOpMode,
     411             :                                                  DataLoopNode::NodeData &condInletNode,
     412             :                                                  DataLoopNode::NodeData &condOutletNode,
     413             :                                                  bool const singleMode)
     414             : {
     415             : 
     416             :     // calculate the performance at this mode/speed
     417     4520793 :     currentMode.CalcOperatingMode(state, inletNode, outletNode, PLR, speedNum, speedRatio, fanOpMode, condInletNode, condOutletNode, singleMode);
     418     4520793 : }
     419             : 
     420          51 : void CoilCoolingDXCurveFitPerformance::calcStandardRatings210240(EnergyPlus::EnergyPlusData &state)
     421             : {
     422             : 
     423             :     // for now this will provide standard ratings for the coil at the normal mode at speed N
     424             :     // future iterations will extend the inputs to give the user the flexibility to select different standards to
     425             :     // apply and such
     426             : 
     427          51 :     int constexpr NumOfReducedCap(4); // Number of reduced capacity test conditions (100%,75%,50%,and 25%)
     428             : 
     429             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     430          51 :     Real64 TotCapFlowModFac(0.0);                 // Total capacity modifier f(actual flow vs rated flow) for each speed [-]
     431          51 :     Real64 EIRFlowModFac(0.0);                    // EIR modifier f(actual supply air flow vs rated flow) for each speed [-]
     432          51 :     Real64 TotCapTempModFac(0.0);                 // Total capacity modifier (function of entering wetbulb, outside drybulb) [-]
     433          51 :     Real64 EIRTempModFac(0.0);                    // EIR modifier (function of entering wetbulb, outside drybulb) [-]
     434          51 :     Real64 TotCoolingCapAHRI(0.0);                // Total Cooling Coil capacity (gross) at AHRI test conditions [W]
     435          51 :     Real64 NetCoolingCapAHRI(0.0);                // Net Cooling Coil capacity at AHRI TestB conditions, accounting for fan heat [W]
     436          51 :     Real64 NetCoolingCapAHRI2023(0.0);            // Net Cooling Coil capacity at AHRI TestB conditions, accounting for fan heat [W]
     437          51 :     Real64 TotalElecPower(0.0);                   // Net power consumption (Cond Fan+Compressor+Indoor Fan) at AHRI test conditions [W]
     438          51 :     Real64 TotalElecPower2023(0.0);               // Net power consumption (Cond Fan+Compressor+Indoor Fan) at AHRI test conditions [W]
     439          51 :     Real64 TotalElecPowerRated(0.0);              // Net power consumption (Cond Fan+Compressor+Indoor Fan) at Rated test conditions [W]
     440          51 :     Real64 TotalElecPowerRated2023(0.0);          // Net power consumption (Cond Fan+Compressor+Indoor Fan) at Rated test conditions [W]
     441          51 :     Real64 EIR(0.0);                              // Energy Efficiency Ratio at AHRI test conditions for SEER [-]
     442          51 :     Real64 PartLoadFactor(0.0);                   // Part load factor, accounts for thermal lag at compressor startup [-]
     443          51 :     Real64 EERReduced(0.0);                       // EER at reduced capacity test conditions (100%, 75%, 50%, and 25%)
     444          51 :     Real64 ElecPowerReducedCap(0.0);              // Net power consumption (Cond Fan+Compressor) at reduced test condition [W]
     445          51 :     Real64 NetCoolingCapReduced(0.0);             // Net Cooling Coil capacity at reduced conditions, accounting for supply fan heat [W]
     446          51 :     Real64 LoadFactor(0.0);                       // Fractional "on" time for last stage at the desired reduced capacity, (dimensionless)
     447          51 :     Real64 DegradationCoeff(0.0);                 // Degradation coeficient, (dimenssionless)
     448             :     Real64 OutdoorUnitInletAirDryBulbTempReduced; // Outdoor unit entering air dry-bulb temperature at reduced capacity [C]
     449             :     int RedCapNum;                                // Integer counter for reduced capacity
     450             : 
     451             :     // *** SOME CONSTANTS FROM THE STANDARD
     452             :     // The AHRI standard specifies a nominal/default fan electric power consumption per rated air
     453             :     // volume flow rate to account for indoor fan electric power consumption
     454             :     // when the standard tests are conducted on units that do not have an
     455             :     // indoor air circulating fan. Used if user doesn't enter a specific value.
     456          51 :     Real64 constexpr DefaultFanPowerPerEvapAirFlowRate(773.3);     // 365 W/1000 scfm or 773.3 W/(m3/s).
     457          51 :     Real64 constexpr DefaultFanPowerPerEvapAirFlowRate2023(934.4); // 441 W/1000 scfm or 934.4 W/(m3/s).
     458             :     // AHRI Standard 210/240-2008 Performance Test Conditions for Unitary Air-to-Air Air-Conditioning and Heat Pump Equipment
     459          51 :     Real64 constexpr CoolingCoilInletAirWetBulbTempRated(19.44); // 19.44C (67F)  Tests A and B
     460          51 :     Real64 constexpr OutdoorUnitInletAirDryBulbTemp(27.78);      // 27.78C (82F)  Test B (for SEER)
     461          51 :     Real64 constexpr OutdoorUnitInletAirDryBulbTempRated(35.0);  // 35.00C (95F)  Test A (rated capacity)
     462          51 :     Real64 constexpr AirMassFlowRatioRated(1.0);                 // AHRI test is at the design flow rate so AirMassFlowRatio is 1.0
     463          51 :     Real64 constexpr PLRforSEER(0.5);                            // Part-load ratio for SEER calculation (single speed DX cooling coils)
     464             :     static constexpr std::array<Real64, 4> ReducedPLR = {1.0, 0.75, 0.50, 0.25};               // Reduced Capacity part-load conditions
     465             :     static constexpr std::array<Real64, 4> IEERWeightingFactor = {0.020, 0.617, 0.238, 0.125}; // EER Weighting factors (IEER)
     466          51 :     Real64 constexpr OADBTempLowReducedCapacityTest(18.3);                                     // Outdoor air dry-bulb temp in degrees C (65F)
     467             : 
     468             :     // For Single Stage Systems, if the optional CFull and DFull tests are not performed, a
     469             :     // default value of 0.20 shall be used for the cooling Degradation Coefficient
     470          51 :     Real64 constexpr CyclicDegradationCoefficient(0.20); // ANSI/AHRI 210/240 2023 Section 6.1.3.1
     471             : 
     472             :     // some conveniences
     473          51 :     auto &mode = this->normalMode;
     474          51 :     auto &speed = mode.speeds.back();
     475             : 
     476          51 :     Real64 FanPowerPerEvapAirFlowRate = DefaultFanPowerPerEvapAirFlowRate;
     477          51 :     if (speed.rated_evap_fan_power_per_volume_flow_rate > 0.0) {
     478          51 :         FanPowerPerEvapAirFlowRate = speed.rated_evap_fan_power_per_volume_flow_rate;
     479             :     }
     480             : 
     481          51 :     Real64 FanPowerPerEvapAirFlowRate2023 = DefaultFanPowerPerEvapAirFlowRate2023;
     482          51 :     if (speed.rated_evap_fan_power_per_volume_flow_rate_2023 > 0.0) {
     483          51 :         FanPowerPerEvapAirFlowRate2023 = speed.rated_evap_fan_power_per_volume_flow_rate_2023;
     484             :     }
     485             : 
     486          51 :     if (mode.ratedGrossTotalCap > 0.0) {
     487             :         // SEER calculations:
     488          51 :         TotCapFlowModFac = Curve::CurveValue(state, speed.indexCapFFF, AirMassFlowRatioRated);
     489          51 :         TotCapTempModFac = Curve::CurveValue(state, speed.indexCapFT, CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTemp);
     490          51 :         TotCoolingCapAHRI = mode.ratedGrossTotalCap * TotCapTempModFac * TotCapFlowModFac;
     491          51 :         EIRTempModFac = Curve::CurveValue(state, speed.indexEIRFT, CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTemp);
     492          51 :         EIRFlowModFac = Curve::CurveValue(state, speed.indexEIRFFF, AirMassFlowRatioRated);
     493          51 :         if (speed.ratedCOP > 0.0) { // RatedCOP <= 0.0 is trapped in GetInput, but keep this as "safety"
     494          51 :             EIR = EIRTempModFac * EIRFlowModFac / speed.ratedCOP;
     495             :         } else {
     496           0 :             EIR = 0.0;
     497             :         }
     498             : 
     499             :         // Calculate net cooling capacity
     500          51 :         NetCoolingCapAHRI = TotCoolingCapAHRI - FanPowerPerEvapAirFlowRate * mode.ratedEvapAirFlowRate;
     501          51 :         TotalElecPower = EIR * TotCoolingCapAHRI + FanPowerPerEvapAirFlowRate * mode.ratedEvapAirFlowRate;
     502             : 
     503          51 :         NetCoolingCapAHRI2023 = TotCoolingCapAHRI - FanPowerPerEvapAirFlowRate2023 * mode.ratedEvapAirFlowRate;
     504          51 :         TotalElecPower2023 = EIR * TotCoolingCapAHRI + FanPowerPerEvapAirFlowRate2023 * mode.ratedEvapAirFlowRate;
     505             :         // Calculate SEER value from the Energy Efficiency Ratio (EER) at the AHRI test conditions and the part load factor.
     506             :         // First evaluate the Part Load Factor curve at PLR = 0.5 (AHRI Standard 210/240)
     507          51 :         PartLoadFactor = Curve::CurveValue(state, speed.indexPLRFPLF, PLRforSEER);
     508          51 :         if (TotalElecPower > 0.0) {
     509          51 :             this->standardRatingSEER = (NetCoolingCapAHRI / TotalElecPower) * PartLoadFactor;
     510             :         } else {
     511           0 :             this->standardRatingSEER = 0.0;
     512             :         }
     513             : 
     514          51 :         Real64 PartLoadFactorStandard = 1.0 - (1 - PLRforSEER) * CyclicDegradationCoefficient;
     515          51 :         if (TotalElecPower2023 > 0.0) {
     516          51 :             this->standardRatingSEER2_User = (NetCoolingCapAHRI2023 / TotalElecPower2023) * PartLoadFactor;
     517          51 :             this->standardRatingSEER2_Standard = (NetCoolingCapAHRI2023 / TotalElecPower2023) * PartLoadFactorStandard;
     518             :         } else {
     519           0 :             this->standardRatingSEER2_User = 0.0;
     520           0 :             this->standardRatingSEER2_Standard = 0.0;
     521             :         }
     522             : 
     523             :         // EER calculations:
     524             :         // Calculate the net cooling capacity at the rated conditions (19.44C WB and 35.0C DB )
     525          51 :         TotCapTempModFac = Curve::CurveValue(state, speed.indexCapFT, CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempRated);
     526          51 :         this->standardRatingCoolingCapacity =
     527          51 :             mode.ratedGrossTotalCap * TotCapTempModFac * TotCapFlowModFac - FanPowerPerEvapAirFlowRate * mode.ratedEvapAirFlowRate;
     528          51 :         this->standardRatingCoolingCapacity2023 =
     529          51 :             mode.ratedGrossTotalCap * TotCapTempModFac * TotCapFlowModFac - FanPowerPerEvapAirFlowRate2023 * mode.ratedEvapAirFlowRate;
     530             :         // Calculate Energy Efficiency Ratio (EER) at (19.44C WB and 35.0C DB ), ANSI/AHRI Std. 340/360
     531          51 :         EIRTempModFac = Curve::CurveValue(state, speed.indexEIRFT, CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempRated);
     532          51 :         if (speed.ratedCOP > 0.0) {
     533             :             // RatedCOP <= 0.0 is trapped in GetInput, but keep this as "safety"
     534          51 :             EIR = EIRTempModFac * EIRFlowModFac / speed.ratedCOP;
     535             :         } else {
     536           0 :             EIR = 0.0;
     537             :         }
     538          51 :         TotalElecPowerRated =
     539          51 :             EIR * (mode.ratedGrossTotalCap * TotCapTempModFac * TotCapFlowModFac) + FanPowerPerEvapAirFlowRate * mode.ratedEvapAirFlowRate;
     540          51 :         if (TotalElecPowerRated > 0.0) {
     541          51 :             this->standardRatingEER = this->standardRatingCoolingCapacity / TotalElecPowerRated;
     542             :         } else {
     543           0 :             this->standardRatingEER = 0.0;
     544             :         }
     545          51 :         TotalElecPowerRated2023 =
     546          51 :             EIR * (mode.ratedGrossTotalCap * TotCapTempModFac * TotCapFlowModFac) + FanPowerPerEvapAirFlowRate2023 * mode.ratedEvapAirFlowRate;
     547          51 :         if (TotalElecPowerRated2023 > 0.0) {
     548          51 :             this->standardRatingEER2 = this->standardRatingCoolingCapacity2023 / TotalElecPowerRated2023;
     549             :         } else {
     550           0 :             this->standardRatingEER2 = 0.0;
     551             :         }
     552             : 
     553             :         // IEER calculations:
     554          51 :         this->standardRatingIEER = 0.0;
     555             :         // Calculate the net cooling capacity at the rated conditions (19.44C WB and 35.0C DB )
     556          51 :         TotCapTempModFac = Curve::CurveValue(state, speed.indexCapFT, CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempRated);
     557          51 :         this->standardRatingCoolingCapacity =
     558          51 :             mode.ratedGrossTotalCap * TotCapTempModFac * TotCapFlowModFac - FanPowerPerEvapAirFlowRate * mode.ratedEvapAirFlowRate;
     559          51 :         this->standardRatingCoolingCapacity2023 =
     560          51 :             mode.ratedGrossTotalCap * TotCapTempModFac * TotCapFlowModFac - FanPowerPerEvapAirFlowRate2023 * mode.ratedEvapAirFlowRate;
     561         255 :         for (RedCapNum = 0; RedCapNum < NumOfReducedCap; ++RedCapNum) {
     562             :             // get the outdoor air dry bulb temperature for the reduced capacity test conditions
     563         204 :             if (ReducedPLR[RedCapNum] > 0.444) {
     564         153 :                 OutdoorUnitInletAirDryBulbTempReduced = 5.0 + 30.0 * ReducedPLR[RedCapNum];
     565             :             } else {
     566          51 :                 OutdoorUnitInletAirDryBulbTempReduced = OADBTempLowReducedCapacityTest;
     567             :             }
     568         204 :             TotCapTempModFac = Curve::CurveValue(state, speed.indexCapFT, CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempReduced);
     569         204 :             NetCoolingCapReduced =
     570         204 :                 mode.ratedGrossTotalCap * TotCapTempModFac * TotCapFlowModFac - FanPowerPerEvapAirFlowRate * mode.ratedEvapAirFlowRate;
     571         204 :             EIRTempModFac = Curve::CurveValue(state, speed.indexEIRFT, CoolingCoilInletAirWetBulbTempRated, OutdoorUnitInletAirDryBulbTempReduced);
     572         204 :             if (speed.ratedCOP > 0.0) {
     573         204 :                 EIR = EIRTempModFac * EIRFlowModFac / speed.ratedCOP;
     574             :             } else {
     575           0 :                 EIR = 0.0;
     576             :             }
     577         204 :             if (NetCoolingCapReduced > 0.0) {
     578         204 :                 LoadFactor = ReducedPLR[RedCapNum] * this->standardRatingCoolingCapacity / NetCoolingCapReduced;
     579             :             } else {
     580           0 :                 LoadFactor = 1.0;
     581             :             }
     582         204 :             DegradationCoeff = 1.130 - 0.130 * LoadFactor;
     583         204 :             ElecPowerReducedCap = DegradationCoeff * EIR * (mode.ratedGrossTotalCap * TotCapTempModFac * TotCapFlowModFac);
     584         204 :             EERReduced =
     585         204 :                 (LoadFactor * NetCoolingCapReduced) / (LoadFactor * ElecPowerReducedCap + FanPowerPerEvapAirFlowRate * mode.ratedEvapAirFlowRate);
     586         204 :             this->standardRatingIEER += IEERWeightingFactor[RedCapNum] * EERReduced;
     587             :         }
     588             : 
     589             :     } else {
     590           0 :         ShowSevereError(state,
     591           0 :                         "Standard Ratings: Coil:Cooling:DX " + this->name + // TODO: Use dynamic COIL TYPE and COIL INSTANCE name later
     592             :                             " has zero rated total cooling capacity. Standard ratings cannot be calculated.");
     593             :     }
     594          51 : }
     595             : 
     596           3 : void CoilCoolingDXCurveFitPerformance::setOperMode(EnergyPlus::EnergyPlusData &state, CoilCoolingDXCurveFitOperatingMode &currentMode, int const mode)
     597             : {
     598             :     // set parent mode for each speed
     599             :     int numSpeeds;
     600           3 :     bool errorsFound = false;
     601             : 
     602           3 :     numSpeeds = (int)currentMode.speeds.size();
     603           6 :     for (int speedNum = 0; speedNum < numSpeeds; speedNum++) {
     604           3 :         currentMode.speeds[speedNum].parentOperatingMode = mode;
     605           3 :         if (mode == 2) {
     606           1 :             if (currentMode.speeds[speedNum].indexSHRFT == 0) {
     607           0 :                 ShowSevereError(state, currentMode.speeds[speedNum].object_name + "=\"" + currentMode.speeds[speedNum].name + "\", Curve check:");
     608           0 :                 ShowContinueError(state,
     609             :                                   "The input of Sensible Heat Ratio Modifier Function of Temperature Curve Name is required, but not available for "
     610             :                                   "SubcoolReheat mode. Please input");
     611           0 :                 errorsFound = true;
     612             :             }
     613           1 :             if (currentMode.speeds[speedNum].indexSHRFFF == 0) {
     614           0 :                 ShowSevereError(state, currentMode.speeds[speedNum].object_name + "=\"" + currentMode.speeds[speedNum].name + "\", Curve check:");
     615           0 :                 ShowContinueError(state,
     616             :                                   "The input of Sensible Heat Ratio Modifier Function of Flow Fraction Curve Name is required, but not available for "
     617             :                                   "SubcoolReheat mode. Please input");
     618           0 :                 errorsFound = true;
     619             :             }
     620             :         }
     621           3 :         if (mode == 3) {
     622           1 :             if (currentMode.speeds[speedNum].indexSHRFT == 0) {
     623           0 :                 ShowSevereError(state, currentMode.speeds[speedNum].object_name + "=\"" + currentMode.speeds[speedNum].name + "\", Curve check:");
     624           0 :                 ShowContinueError(state,
     625             :                                   "The input of Sensible Heat Ratio Modifier Function of Temperature Curve Name is required, but not available for "
     626             :                                   "SubcoolReheat mode. Please input");
     627           0 :                 errorsFound = true;
     628             :             }
     629           1 :             if (currentMode.speeds[speedNum].indexSHRFFF == 0) {
     630           0 :                 ShowSevereError(state, currentMode.speeds[speedNum].object_name + "=\"" + currentMode.speeds[speedNum].name + "\", Curve check:");
     631           0 :                 ShowContinueError(state,
     632             :                                   "The input of Sensible Heat Ratio Modifier Function of Flow Fraction Curve Name is required, but not available for "
     633             :                                   "SubcoolReheat mode. Please input");
     634           0 :                 errorsFound = true;
     635             :             }
     636             :         }
     637             :     }
     638           3 :     if (errorsFound) {
     639           0 :         ShowFatalError(state,
     640           0 :                        "CoilCoolingDXCurveFitPerformance: Errors found in getting " + this->object_name +
     641             :                            " input. Preceding condition(s) causes termination.");
     642             :     }
     643        2316 : }

Generated by: LCOV version 1.13