LCOV - code coverage report
Current view: top level - EnergyPlus - Pumps.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 68.5 % 1131 775
Test Date: 2025-06-02 07:23:51 Functions: 88.9 % 9 8

            Line data    Source code
       1              : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
       2              : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3              : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4              : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5              : // contributors. All rights reserved.
       6              : //
       7              : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8              : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9              : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10              : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11              : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12              : //
      13              : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14              : // provided that the following conditions are met:
      15              : //
      16              : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17              : //     conditions and the following disclaimer.
      18              : //
      19              : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20              : //     conditions and the following disclaimer in the documentation and/or other materials
      21              : //     provided with the distribution.
      22              : //
      23              : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24              : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25              : //     used to endorse or promote products derived from this software without specific prior
      26              : //     written permission.
      27              : //
      28              : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29              : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30              : //     reference solely to the software portion of its product, Licensee must refer to the
      31              : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32              : //     obtained under this License and may not use a different name for the software. Except as
      33              : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34              : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35              : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36              : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37              : //
      38              : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39              : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40              : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41              : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42              : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43              : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44              : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45              : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46              : // POSSIBILITY OF SUCH DAMAGE.
      47              : 
      48              : // C++ Headers
      49              : #include <cassert>
      50              : #include <cmath>
      51              : 
      52              : // ObjexxFCL Headers
      53              : #include <ObjexxFCL/Array.functions.hh>
      54              : // #include <ObjexxFCL/Fmath.hh>
      55              : 
      56              : // EnergyPlus Headers
      57              : #include <EnergyPlus/Autosizing/Base.hh>
      58              : #include <EnergyPlus/BranchNodeConnections.hh>
      59              : #include <EnergyPlus/CurveManager.hh>
      60              : #include <EnergyPlus/Data/EnergyPlusData.hh>
      61              : #include <EnergyPlus/DataBranchAirLoopPlant.hh>
      62              : #include <EnergyPlus/DataHVACGlobals.hh>
      63              : #include <EnergyPlus/DataHeatBalance.hh>
      64              : #include <EnergyPlus/DataIPShortCuts.hh>
      65              : #include <EnergyPlus/DataLoopNode.hh>
      66              : #include <EnergyPlus/DataSizing.hh>
      67              : #include <EnergyPlus/EMSManager.hh>
      68              : #include <EnergyPlus/FluidProperties.hh>
      69              : #include <EnergyPlus/General.hh>
      70              : #include <EnergyPlus/GlobalNames.hh>
      71              : #include <EnergyPlus/HeatBalanceInternalHeatGains.hh>
      72              : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      73              : #include <EnergyPlus/NodeInputManager.hh>
      74              : #include <EnergyPlus/OutputProcessor.hh>
      75              : #include <EnergyPlus/OutputReportPredefined.hh>
      76              : #include <EnergyPlus/Plant/DataPlant.hh>
      77              : #include <EnergyPlus/PlantPressureSystem.hh>
      78              : #include <EnergyPlus/PlantUtilities.hh>
      79              : #include <EnergyPlus/Pumps.hh>
      80              : #include <EnergyPlus/ScheduleManager.hh>
      81              : #include <EnergyPlus/UtilityRoutines.hh>
      82              : 
      83              : namespace EnergyPlus::Pumps {
      84              : 
      85              : // MODULE INFORMATION:
      86              : //       AUTHOR         Dan Fisher
      87              : //       DATE WRITTEN   Sept 1998
      88              : //       MODIFIED       July 2001, Richard Liesen
      89              : //                      July 2001, Rick Strand (new "local" pump control method)
      90              : //                      Feb 2005, Rahul Chillar(added condensate pump for steam systems)
      91              : //                      Jan 2006, Sankaranarayanan (Added pump banks to the library of pumps)
      92              : //                      May 2009, Brent Griffith (added support for EMS override of massflow)
      93              : //                      Aug 2010, Edwin Lee (refactored code, significant clean-up)
      94              : //       RE-ENGINEERED  na
      95              : 
      96              : // PURPOSE OF THIS MODULE:
      97              : // Encapsulates the data and algorithms to simulate pumps.
      98              : 
      99              : // REFERENCES:
     100              : // HVAC 2 Toolkit:  A Toolkit for Secondary HVAC System
     101              : // Energy Calculations, ASHRAE, 1993, pp2-10 to 2-15
     102              : 
     103              : // Using/Aliasing
     104              : using DataLoopNode::ObjectIsNotParent;
     105              : using HVAC::SmallWaterVolFlow;
     106              : 
     107              : static constexpr std::array<std::string_view, static_cast<int>(PumpType::Num)> pumpTypeIDFNames = {
     108              :     "Pump:VariableSpeed", "Pump:ConstantSpeed", "Pump:VariableSpeed:Condensate", "HeaderedPumps:VariableSpeed", "HeaderedPumps:ConstantSpeed"};
     109              : 
     110     56466326 : void SimPumps(EnergyPlusData &state,
     111              :               std::string const &PumpName, // Name of pump to be managed
     112              :               int const LoopNum,           // Plant loop number
     113              :               Real64 const FlowRequest,    // requested flow from adjacent demand side
     114              :               bool &PumpRunning,           // .TRUE. if the loop pump is actually operating
     115              :               int &PumpIndex,
     116              :               Real64 &PumpHeat)
     117              : {
     118              : 
     119              :     // SUBROUTINE INFORMATION:
     120              :     //       AUTHOR         Rick Strand
     121              :     //       DATE WRITTEN   July 2001
     122              :     //       MODIFIED       na
     123              :     //       RE-ENGINEERED  na
     124              : 
     125              :     // PURPOSE OF THIS SUBROUTINE:
     126              :     // This subroutine manages the pump operation based on the type of
     127              :     // pump and the pump controls (continuous, intermittent, etc.).  The
     128              :     // result of this subroutine is that the pump has been simulated for
     129              :     // the necessary loop and the PumpRunning has been correctly set.
     130              : 
     131              :     int PumpNum; // Pump index within PumpEquip derived type
     132              : 
     133              :     // Get input from IDF one time
     134     56466326 :     if (state.dataPumps->GetInputFlag) {
     135          462 :         GetPumpInput(state);
     136          462 :         state.dataPumps->GetInputFlag = false;
     137              :     }
     138              : 
     139              :     // Exit early if no pumps found
     140     56466326 :     if (state.dataPumps->NumPumps == 0) {
     141            0 :         PumpHeat = 0.0;
     142     18821701 :         return;
     143              :     }
     144              : 
     145              :     // Setup pump component index if needed
     146     56466326 :     if (PumpIndex == 0) {
     147         1179 :         PumpNum = Util::FindItemInList(PumpName, state.dataPumps->PumpEquip); // Determine which pump to simulate
     148         1179 :         if (PumpNum == 0) {
     149            0 :             ShowFatalError(state, format("ManagePumps: Pump requested not found ={}", PumpName)); // Catch any bad names before crashing
     150              :         }
     151         1179 :         PumpIndex = PumpNum;
     152              :     } else {
     153     56465147 :         PumpNum = PumpIndex;
     154     56465147 :         if (state.dataPumps->PumpEquip(PumpNum).CheckEquipName) {
     155         1179 :             if (PumpNum > state.dataPumps->NumPumps || PumpNum < 1) {
     156            0 :                 ShowFatalError(
     157              :                     state,
     158            0 :                     format(
     159            0 :                         "ManagePumps: Invalid PumpIndex passed={}, Number of Pumps={}, Pump name={}", PumpNum, state.dataPumps->NumPumps, PumpName));
     160              :             }
     161         1179 :             if (PumpName != state.dataPumps->PumpEquip(PumpNum).Name) {
     162            0 :                 ShowFatalError(state,
     163            0 :                                format("ManagePumps: Invalid PumpIndex passed={}, Pump name={}, stored Pump Name for that index={}",
     164              :                                       PumpNum,
     165              :                                       PumpName,
     166            0 :                                       state.dataPumps->PumpEquip(PumpNum).Name));
     167              :             }
     168         1179 :             state.dataPumps->PumpEquip(PumpNum).CheckEquipName = false;
     169              :         }
     170              :     }
     171              : 
     172              :     // Perform one-time and begin-environment initialization
     173     56466326 :     InitializePumps(state, PumpNum);
     174              : 
     175              :     // If all we need is to set outlet min/max avail, then just do it and get out.  Also, we only do min/max avail on flow query
     176     56466326 :     if (state.dataPlnt->PlantLoop(LoopNum).LoopSide(state.dataPumps->PumpEquip(PumpNum).plantLoc.loopSideNum).FlowLock ==
     177              :         DataPlant::FlowLock::PumpQuery) {
     178     18821701 :         SetupPumpMinMaxFlows(state, LoopNum, PumpNum);
     179     18821701 :         return;
     180              :     }
     181              : 
     182              :     // Set pump flow rate and calculate power
     183     37644625 :     CalcPumps(state, PumpNum, FlowRequest, PumpRunning);
     184              : 
     185              :     // Update pump reporting data
     186     37644625 :     ReportPumps(state, PumpNum);
     187              : 
     188              :     // Send this up to the calling routine
     189     37644625 :     PumpHeat = state.dataPumps->PumpHeattoFluid;
     190              : }
     191              : 
     192          462 : void GetPumpInput(EnergyPlusData &state)
     193              : {
     194              : 
     195              :     // SUBROUTINE INFORMATION:
     196              :     //       AUTHOR:          Dan Fisher
     197              :     //       DATE WRITTEN:    April 1998
     198              :     //       MODIFIED:        July 2001, Rick Strand (addition of pump controls)
     199              :     //                        May 2009, Brent Griffith (added EMS calls)
     200              : 
     201              :     // PURPOSE OF THIS SUBROUTINE:
     202              :     // This routine will get the input
     203              :     // required by the pump simulation.
     204              : 
     205              :     // PUMP:VARIABLE SPEED,
     206              :     // This pump model is described in the ASHRAE secondary HVAC toolkit.
     207              : 
     208              :     // REFERENCES:
     209              :     // HVAC 2 Toolkit:  A Toolkit for Secondary HVAC System
     210              :     //  Energy Calculations, ASHRAE, 1993, pp2-10 to 2-15
     211              : 
     212              :     // Using/Aliasing
     213              :     using BranchNodeConnections::TestCompSet;
     214              :     using Curve::GetCurveIndex;
     215              :     using Curve::GetCurveMinMaxValues;
     216              :     using DataSizing::AutoSize;
     217              :     using NodeInputManager::GetOnlySingleNode;
     218              : 
     219              :     // SUBROUTINE PARAMETER DEFINITIONS:
     220          462 :     Real64 constexpr StartTemp(100.0); // Standard Temperature across code to calculated Steam density
     221              :     static constexpr std::string_view RoutineName("GetPumpInput: ");
     222              :     static constexpr std::string_view routineName = "GetPumpInput";
     223              : 
     224              :     static constexpr std::array<std::string_view, static_cast<int>(PumpControlType::Num)> pumpCtrlTypeNamesUC{"CONTINUOUS", "INTERMITTENT"};
     225              :     static constexpr std::array<std::string_view, static_cast<int>(ControlTypeVFD::Num)> controlTypeVFDNamesUC{"MANUALCONTROL",
     226              :                                                                                                                "PRESSURESETPOINTCONTROL"};
     227              :     static constexpr std::array<std::string_view, static_cast<int>(PowerSizingMethod::Num)> powerSizingMethodNamesUC{"POWERPERFLOW",
     228              :                                                                                                                      "POWERPERFLOWPERPRESSURE"};
     229              : 
     230              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     231              :     int PumpNum;
     232              :     int NumAlphas; // Number of elements in the alpha array
     233              :     int NumNums;   // Number of elements in the numeric array
     234              :     int IOStat;    // IO Status when calling get input subroutine
     235              :     bool ErrorsFound;
     236              :     int TempCurveIndex;
     237          462 :     int NumVarSpeedPumps = 0;
     238          462 :     int NumConstSpeedPumps = 0;
     239          462 :     int NumCondensatePumps = 0;
     240          462 :     int NumPumpBankSimpleVar = 0;
     241          462 :     int NumPumpBankSimpleConst = 0;
     242              :     Real64 SteamDensity;
     243              :     Real64 TempWaterDensity;
     244          462 :     int DummyWaterIndex(1);
     245          462 :     Real64 constexpr minToMaxRatioMax = 0.99;
     246              : 
     247          462 :     ErrorsFound = false;
     248              : 
     249              :     // GET NUMBER OF ALL EQUIPMENT TYPES
     250          462 :     NumVarSpeedPumps = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, pumpTypeIDFNames[static_cast<int>(PumpType::VarSpeed)]);
     251          462 :     NumConstSpeedPumps = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, pumpTypeIDFNames[static_cast<int>(PumpType::ConSpeed)]);
     252          462 :     NumCondensatePumps = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, pumpTypeIDFNames[static_cast<int>(PumpType::Cond)]);
     253              :     NumPumpBankSimpleVar =
     254          462 :         state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, pumpTypeIDFNames[static_cast<int>(PumpType::Bank_VarSpeed)]);
     255              :     NumPumpBankSimpleConst =
     256          462 :         state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, pumpTypeIDFNames[static_cast<int>(PumpType::Bank_ConSpeed)]);
     257          462 :     state.dataPumps->NumPumps = NumVarSpeedPumps + NumConstSpeedPumps + NumCondensatePumps + NumPumpBankSimpleVar + NumPumpBankSimpleConst;
     258              : 
     259          462 :     if (state.dataPumps->NumPumps <= 0) {
     260            0 :         ShowWarningError(state, "No Pumping Equipment Found");
     261            0 :         return;
     262              :     }
     263              : 
     264          462 :     state.dataPumps->PumpEquip.allocate(state.dataPumps->NumPumps);
     265          462 :     state.dataPumps->PumpUniqueNames.reserve(static_cast<unsigned>(state.dataPumps->NumPumps));
     266          462 :     state.dataPumps->PumpEquipReport.allocate(state.dataPumps->NumPumps);
     267          462 :     auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
     268          462 :     cCurrentModuleObject = pumpTypeIDFNames[static_cast<int>(PumpType::VarSpeed)];
     269          462 :     auto &thisInput = state.dataIPShortCut;
     270              : 
     271         1414 :     for (PumpNum = 1; PumpNum <= NumVarSpeedPumps; ++PumpNum) {
     272          952 :         auto &thisPump = state.dataPumps->PumpEquip(PumpNum);
     273         1904 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     274              :                                                                  cCurrentModuleObject,
     275              :                                                                  PumpNum,
     276          952 :                                                                  thisInput->cAlphaArgs,
     277              :                                                                  NumAlphas,
     278          952 :                                                                  thisInput->rNumericArgs,
     279              :                                                                  NumNums,
     280              :                                                                  IOStat,
     281          952 :                                                                  thisInput->lNumericFieldBlanks,
     282          952 :                                                                  thisInput->lAlphaFieldBlanks,
     283          952 :                                                                  thisInput->cAlphaFieldNames,
     284          952 :                                                                  thisInput->cNumericFieldNames);
     285              : 
     286          952 :         ErrorObjectHeader eoh{routineName, cCurrentModuleObject, thisInput->cAlphaArgs(1)};
     287              : 
     288          952 :         GlobalNames::VerifyUniqueInterObjectName(
     289         1904 :             state, state.dataPumps->PumpUniqueNames, thisInput->cAlphaArgs(1), cCurrentModuleObject, thisInput->cAlphaFieldNames(1), ErrorsFound);
     290          952 :         thisPump.Name = thisInput->cAlphaArgs(1);
     291          952 :         thisPump.pumpType = PumpType::VarSpeed; //'Pump:VariableSpeed'
     292          952 :         thisPump.TypeOf_Num = DataPlant::PlantEquipmentType::PumpVariableSpeed;
     293              : 
     294          952 :         thisPump.InletNodeNum = GetOnlySingleNode(state,
     295          952 :                                                   thisInput->cAlphaArgs(2),
     296              :                                                   ErrorsFound,
     297              :                                                   DataLoopNode::ConnectionObjectType::PumpVariableSpeed,
     298          952 :                                                   thisPump.Name,
     299              :                                                   DataLoopNode::NodeFluidType::Water,
     300              :                                                   DataLoopNode::ConnectionType::Inlet,
     301              :                                                   NodeInputManager::CompFluidStream::Primary,
     302              :                                                   ObjectIsNotParent);
     303              : 
     304         1904 :         thisPump.OutletNodeNum = GetOnlySingleNode(state,
     305          952 :                                                    thisInput->cAlphaArgs(3),
     306              :                                                    ErrorsFound,
     307              :                                                    DataLoopNode::ConnectionObjectType::PumpVariableSpeed,
     308          952 :                                                    thisPump.Name,
     309              :                                                    DataLoopNode::NodeFluidType::Water,
     310              :                                                    DataLoopNode::ConnectionType::Outlet,
     311              :                                                    NodeInputManager::CompFluidStream::Primary,
     312              :                                                    ObjectIsNotParent);
     313          952 :         TestCompSet(state, cCurrentModuleObject, thisPump.Name, thisInput->cAlphaArgs(2), thisInput->cAlphaArgs(3), "Water Nodes");
     314              : 
     315          952 :         thisPump.PumpControl = static_cast<PumpControlType>(getEnumValue(pumpCtrlTypeNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(4))));
     316          952 :         if (thisPump.PumpControl == PumpControlType::Invalid) {
     317            0 :             ShowWarningError(state,
     318            0 :                              format("{}{}=\"{}\", Invalid {}", RoutineName, cCurrentModuleObject, thisPump.Name, thisInput->cAlphaFieldNames(4)));
     319            0 :             ShowContinueError(
     320              :                 state,
     321            0 :                 format("Entered Value=[{}]. {} has been set to Continuous for this pump.", thisInput->cAlphaArgs(4), thisInput->cAlphaFieldNames(4)));
     322            0 :             thisPump.PumpControl = PumpControlType::Continuous;
     323              :         }
     324              : 
     325              :         // Input the optional schedule for the pump, this is a flow modifier schedule so blank/missing means Always On.
     326          952 :         if (thisInput->cAlphaArgs(5).empty()) {
     327          766 :             thisPump.flowRateSched = nullptr;
     328          186 :         } else if ((thisPump.flowRateSched = Sched::GetSchedule(state, thisInput->cAlphaArgs(5))) == nullptr) {
     329            0 :             ShowWarningItemNotFound(state, eoh, thisInput->cAlphaFieldNames(5), thisInput->cAlphaArgs(5), "");
     330              :         }
     331              : 
     332          952 :         thisPump.NomVolFlowRate = thisInput->rNumericArgs(1);
     333          952 :         if (thisPump.NomVolFlowRate == AutoSize) {
     334          555 :             thisPump.NomVolFlowRateWasAutoSized = true;
     335              :         }
     336          952 :         thisPump.NomPumpHead = thisInput->rNumericArgs(2);
     337          952 :         thisPump.NomPowerUse = thisInput->rNumericArgs(3);
     338          952 :         if (thisPump.NomPowerUse == AutoSize) {
     339          559 :             thisPump.NomPowerUseWasAutoSized = true;
     340              :         }
     341          952 :         thisPump.MotorEffic = thisInput->rNumericArgs(4);
     342          952 :         thisPump.FracMotorLossToFluid = thisInput->rNumericArgs(5);
     343          952 :         thisPump.PartLoadCoef[0] = thisInput->rNumericArgs(6);
     344          952 :         thisPump.PartLoadCoef[1] = thisInput->rNumericArgs(7);
     345          952 :         thisPump.PartLoadCoef[2] = thisInput->rNumericArgs(8);
     346          952 :         thisPump.PartLoadCoef[3] = thisInput->rNumericArgs(9);
     347          952 :         thisPump.MinVolFlowRate = thisInput->rNumericArgs(10);
     348          952 :         if (thisPump.MinVolFlowRate == AutoSize) {
     349           15 :             thisPump.minVolFlowRateWasAutosized = true;
     350          937 :         } else if (!thisPump.NomVolFlowRateWasAutoSized && (thisPump.MinVolFlowRate > (minToMaxRatioMax * thisPump.NomVolFlowRate))) {
     351              :             // Check that the minimum isn't greater than the maximum
     352            0 :             ShowWarningError(
     353            0 :                 state, format("{}{}=\"{}\", Invalid '{}'", RoutineName, cCurrentModuleObject, thisPump.Name, thisInput->cNumericFieldNames(10)));
     354            0 :             ShowContinueError(state,
     355            0 :                               format("Entered Value=[{:.5T}] is above or too close (equal) to the {}=[{:.5T}].",
     356            0 :                                      thisPump.MinVolFlowRate,
     357            0 :                                      thisInput->cNumericFieldNames(1),
     358            0 :                                      thisPump.NomVolFlowRate));
     359            0 :             ShowContinueError(
     360              :                 state,
     361            0 :                 format("Reseting value of '{}' to the value of 99% of '{}'.", thisInput->cNumericFieldNames(10), thisInput->cNumericFieldNames(1)));
     362              :             // Set min to roughly max, but not quite, otherwise it can't turn on, ever
     363            0 :             thisPump.MinVolFlowRate = minToMaxRatioMax * thisPump.NomVolFlowRate;
     364              :         }
     365              :         // Probably the following two lines will be used if the team agrees on changing the F10 value from min flow rate to
     366              :         // minimum flow as a fraction of nominal flow.
     367              : 
     368              :         // Input pressure related data such as pressure curve and impeller size/rotational speed
     369          952 :         if (thisInput->cAlphaArgs(6).empty()) {
     370          951 :             thisPump.PressureCurve_Index = -1;
     371              :         } else {
     372            1 :             TempCurveIndex = GetCurveIndex(state, thisInput->cAlphaArgs(6));
     373            1 :             if (TempCurveIndex == 0) {
     374            0 :                 thisPump.PressureCurve_Index = -1;
     375              :             } else {
     376            2 :                 ErrorsFound |= Curve::CheckCurveDims(state,
     377              :                                                      TempCurveIndex,                  // Curve index
     378              :                                                      {1},                             // Valid dimensions
     379              :                                                      RoutineName,                     // Routine name
     380              :                                                      cCurrentModuleObject,            // Object Type
     381              :                                                      thisPump.Name,                   // Object Name
     382            1 :                                                      thisInput->cAlphaFieldNames(6)); // Field Name
     383              : 
     384            1 :                 if (!ErrorsFound) {
     385            1 :                     thisPump.PressureCurve_Index = TempCurveIndex;
     386            1 :                     GetCurveMinMaxValues(state, TempCurveIndex, thisPump.MinPhiValue, thisPump.MaxPhiValue);
     387              :                 }
     388              :             }
     389              :         }
     390              : 
     391              :         // read in the rest of the pump pressure characteristics
     392          952 :         thisPump.ImpellerDiameter = thisInput->rNumericArgs(11);
     393              : 
     394              :         // Input VFD related data
     395          952 :         if (thisInput->lAlphaFieldBlanks(7)) {
     396          951 :             thisPump.HasVFD = false;
     397              :         } else {
     398            1 :             thisPump.HasVFD = true;
     399            1 :             thisPump.VFD.VFDControlType =
     400            1 :                 static_cast<ControlTypeVFD>(getEnumValue(controlTypeVFDNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(7))));
     401              : 
     402            1 :             switch (thisPump.VFD.VFDControlType) {
     403              : 
     404            1 :             case ControlTypeVFD::VFDManual: {
     405            1 :                 if ((thisPump.VFD.manualRPMSched = Sched::GetSchedule(state, thisInput->cAlphaArgs(8))) == nullptr) {
     406            0 :                     ShowSevereItemNotFound(state, eoh, thisInput->cAlphaFieldNames(8), thisInput->cAlphaArgs(8));
     407            0 :                     ErrorsFound = true;
     408            1 :                 } else if (!thisPump.VFD.manualRPMSched->checkMinVal(state, Clusive::Ex, 0.0)) {
     409            0 :                     Sched::ShowSevereBadMin(state, eoh, thisInput->cAlphaFieldNames(8), thisInput->cAlphaArgs(8), Clusive::Ex, 0.0);
     410            0 :                     ErrorsFound = true;
     411              :                 }
     412            1 :             } break;
     413              : 
     414            0 :             case ControlTypeVFD::VFDAutomatic: {
     415            0 :                 if (thisInput->lAlphaFieldBlanks(9)) {
     416            0 :                     ShowSevereEmptyField(state, eoh, thisInput->cAlphaFieldNames(9));
     417            0 :                     ErrorsFound = true;
     418            0 :                 } else if ((thisPump.VFD.lowerPsetSched = Sched::GetSchedule(state, thisInput->cAlphaArgs(9))) == nullptr) {
     419            0 :                     ShowSevereItemNotFound(state, eoh, thisInput->cAlphaFieldNames(9), thisInput->cAlphaArgs(9));
     420            0 :                     ErrorsFound = true;
     421              :                 }
     422              : 
     423            0 :                 if (thisInput->lAlphaFieldBlanks(10)) {
     424            0 :                     ShowSevereEmptyField(state, eoh, thisInput->cAlphaFieldNames(10));
     425            0 :                     ErrorsFound = true;
     426            0 :                 } else if ((thisPump.VFD.upperPsetSched = Sched::GetSchedule(state, thisInput->cAlphaArgs(10))) == nullptr) {
     427            0 :                     ShowSevereItemNotFound(state, eoh, thisInput->cAlphaFieldNames(10), thisInput->cAlphaArgs(10));
     428            0 :                     ErrorsFound = true;
     429              :                 }
     430              : 
     431            0 :                 if (thisInput->lAlphaFieldBlanks(11)) {
     432            0 :                     ShowSevereEmptyField(state, eoh, thisInput->cAlphaFieldNames(11));
     433            0 :                     ErrorsFound = true;
     434            0 :                 } else if ((thisPump.VFD.minRPMSched = Sched::GetSchedule(state, thisInput->cAlphaArgs(11))) == nullptr) {
     435            0 :                     ShowSevereItemNotFound(state, eoh, thisInput->cAlphaFieldNames(11), thisInput->cAlphaArgs(11));
     436            0 :                     ErrorsFound = true;
     437            0 :                 } else if (!thisPump.VFD.minRPMSched->checkMinVal(state, Clusive::Ex, 0.0)) {
     438            0 :                     Sched::ShowSevereBadMin(state, eoh, thisInput->cAlphaFieldNames(11), thisInput->cAlphaArgs(11), Clusive::Ex, 0.0);
     439            0 :                     ErrorsFound = true;
     440              :                 }
     441              : 
     442            0 :                 if (thisInput->lAlphaFieldBlanks(12)) {
     443            0 :                     ShowSevereEmptyField(state, eoh, thisInput->cAlphaFieldNames(12));
     444            0 :                     ErrorsFound = true;
     445            0 :                 } else if ((thisPump.VFD.maxRPMSched = Sched::GetSchedule(state, thisInput->cAlphaArgs(12))) == nullptr) {
     446            0 :                     ShowSevereItemNotFound(state, eoh, thisInput->cAlphaFieldNames(12), thisInput->cAlphaArgs(12));
     447            0 :                     ErrorsFound = true;
     448            0 :                 } else if (!thisPump.VFD.maxRPMSched->checkMinVal(state, Clusive::Ex, 0.0)) {
     449            0 :                     Sched::ShowSevereBadMin(state, eoh, thisInput->cAlphaFieldNames(12), thisInput->cAlphaArgs(12), Clusive::Ex, 0.0);
     450            0 :                     ErrorsFound = true;
     451              :                 }
     452            0 :             } break;
     453              : 
     454            0 :             default: {
     455            0 :                 ShowSevereError(state,
     456            0 :                                 format("{}{}=\"{}\", VFD Control type entered is invalid.  Use one of the key choice entries.",
     457              :                                        RoutineName,
     458              :                                        cCurrentModuleObject,
     459            0 :                                        thisPump.Name));
     460            0 :                 ErrorsFound = true;
     461            0 :             } break;
     462              :             }
     463              :         }
     464              : 
     465          952 :         if (!thisInput->lAlphaFieldBlanks(13)) { // zone named for pump skin losses
     466            0 :             thisPump.ZoneNum = Util::FindItemInList(thisInput->cAlphaArgs(13), state.dataHeatBal->Zone);
     467            0 :             if (thisPump.ZoneNum > 0) {
     468            0 :                 thisPump.HeatLossesToZone = true;
     469            0 :                 if (!thisInput->lNumericFieldBlanks(12)) {
     470            0 :                     thisPump.SkinLossRadFraction = thisInput->rNumericArgs(12);
     471              :                 }
     472              :             } else {
     473            0 :                 ShowSevereError(state,
     474            0 :                                 format("{}=\"{}\" invalid {}=\"{}\" not found.",
     475              :                                        cCurrentModuleObject,
     476            0 :                                        thisPump.Name,
     477            0 :                                        thisInput->cAlphaFieldNames(13),
     478            0 :                                        thisInput->cAlphaArgs(13)));
     479            0 :                 ErrorsFound = true;
     480              :             }
     481              :         }
     482              : 
     483          952 :         if (!thisInput->lAlphaFieldBlanks(14)) {
     484           23 :             thisPump.powerSizingMethod =
     485           23 :                 static_cast<PowerSizingMethod>(getEnumValue(powerSizingMethodNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(14))));
     486           23 :             if (thisPump.powerSizingMethod == PowerSizingMethod::Invalid) {
     487            0 :                 ShowSevereError(state,
     488            0 :                                 format("{}{}=\"{}\", sizing method type entered is invalid.  Use one of the key choice entries.",
     489              :                                        RoutineName,
     490              :                                        cCurrentModuleObject,
     491            0 :                                        thisPump.Name));
     492            0 :                 ErrorsFound = true;
     493              :             }
     494              :         }
     495              : 
     496          952 :         if (!thisInput->lNumericFieldBlanks(13)) {
     497           23 :             thisPump.powerPerFlowScalingFactor = thisInput->rNumericArgs(13);
     498              :         }
     499              : 
     500          952 :         if (!thisInput->lNumericFieldBlanks(14)) {
     501           23 :             thisPump.powerPerFlowPerPressureScalingFactor = thisInput->rNumericArgs(14);
     502              :         }
     503              : 
     504          952 :         if (!thisInput->lNumericFieldBlanks(15)) {
     505           23 :             thisPump.MinVolFlowRateFrac = thisInput->rNumericArgs(15);
     506              :         }
     507              : 
     508          952 :         if (NumAlphas > 14) {
     509           15 :             thisPump.EndUseSubcategoryName = thisInput->cAlphaArgs(15);
     510              :         } else {
     511          937 :             thisPump.EndUseSubcategoryName = "General";
     512              :         }
     513              : 
     514              :         // Is this really necessary for each pump GetInput loop?
     515          952 :         thisPump.Energy = 0.0;
     516          952 :         thisPump.Power = 0.0;
     517              :     }
     518              : 
     519          462 :     cCurrentModuleObject = pumpTypeIDFNames[static_cast<int>(PumpType::ConSpeed)];
     520              : 
     521          673 :     for (int NumConstPump = 1; NumConstPump <= NumConstSpeedPumps; ++NumConstPump) {
     522          211 :         PumpNum = NumVarSpeedPumps + NumConstPump;
     523          211 :         auto &thisPump = state.dataPumps->PumpEquip(PumpNum);
     524          422 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     525              :                                                                  cCurrentModuleObject,
     526              :                                                                  NumConstPump,
     527          211 :                                                                  thisInput->cAlphaArgs,
     528              :                                                                  NumAlphas,
     529          211 :                                                                  thisInput->rNumericArgs,
     530              :                                                                  NumNums,
     531              :                                                                  IOStat,
     532          211 :                                                                  thisInput->lNumericFieldBlanks,
     533          211 :                                                                  thisInput->lAlphaFieldBlanks,
     534          211 :                                                                  thisInput->cAlphaFieldNames,
     535          211 :                                                                  thisInput->cNumericFieldNames);
     536              : 
     537          211 :         ErrorObjectHeader eoh{routineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)};
     538              : 
     539          211 :         GlobalNames::VerifyUniqueInterObjectName(
     540          422 :             state, state.dataPumps->PumpUniqueNames, thisInput->cAlphaArgs(1), cCurrentModuleObject, thisInput->cAlphaFieldNames(1), ErrorsFound);
     541          211 :         thisPump.Name = thisInput->cAlphaArgs(1);
     542          211 :         thisPump.pumpType = PumpType::ConSpeed; //'Pump:ConstantSpeed'
     543          211 :         thisPump.TypeOf_Num = DataPlant::PlantEquipmentType::PumpConstantSpeed;
     544              : 
     545          211 :         thisPump.InletNodeNum = GetOnlySingleNode(state,
     546          211 :                                                   thisInput->cAlphaArgs(2),
     547              :                                                   ErrorsFound,
     548              :                                                   DataLoopNode::ConnectionObjectType::PumpConstantSpeed,
     549          211 :                                                   thisPump.Name,
     550              :                                                   DataLoopNode::NodeFluidType::Water,
     551              :                                                   DataLoopNode::ConnectionType::Inlet,
     552              :                                                   NodeInputManager::CompFluidStream::Primary,
     553              :                                                   ObjectIsNotParent);
     554              : 
     555          422 :         thisPump.OutletNodeNum = GetOnlySingleNode(state,
     556          211 :                                                    thisInput->cAlphaArgs(3),
     557              :                                                    ErrorsFound,
     558              :                                                    DataLoopNode::ConnectionObjectType::PumpConstantSpeed,
     559          211 :                                                    thisPump.Name,
     560              :                                                    DataLoopNode::NodeFluidType::Water,
     561              :                                                    DataLoopNode::ConnectionType::Outlet,
     562              :                                                    NodeInputManager::CompFluidStream::Primary,
     563              :                                                    ObjectIsNotParent);
     564          211 :         TestCompSet(state, cCurrentModuleObject, thisPump.Name, thisInput->cAlphaArgs(2), thisInput->cAlphaArgs(3), "Water Nodes");
     565              : 
     566          211 :         thisPump.NomVolFlowRate = thisInput->rNumericArgs(1);
     567          211 :         if (thisPump.NomVolFlowRate == AutoSize) {
     568          164 :             thisPump.NomVolFlowRateWasAutoSized = true;
     569              :         }
     570          211 :         thisPump.NomPumpHead = thisInput->rNumericArgs(2);
     571          211 :         thisPump.NomPowerUse = thisInput->rNumericArgs(3);
     572          211 :         if (thisPump.NomPowerUse == AutoSize) {
     573          167 :             thisPump.NomPowerUseWasAutoSized = true;
     574              :         }
     575          211 :         thisPump.MotorEffic = thisInput->rNumericArgs(4);
     576          211 :         thisPump.FracMotorLossToFluid = thisInput->rNumericArgs(5);
     577          211 :         thisPump.PartLoadCoef[0] = 1.0;
     578          211 :         thisPump.PartLoadCoef[1] = 0.0;
     579          211 :         thisPump.PartLoadCoef[2] = 0.0;
     580          211 :         thisPump.PartLoadCoef[3] = 0.0;
     581              :         // In a constant volume pump we previously set the minimum to the nominal capacity
     582              :         // Now we model the pump as constant speed and set flow by riding the pump curve.
     583          211 :         thisPump.MinVolFlowRate = 0.0;
     584          211 :         thisPump.Energy = 0.0;
     585          211 :         thisPump.Power = 0.0;
     586              : 
     587          211 :         thisPump.PumpControl = static_cast<PumpControlType>(getEnumValue(pumpCtrlTypeNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(4))));
     588              : 
     589          211 :         if (thisPump.PumpControl == PumpControlType::Invalid) {
     590            0 :             ShowWarningError(state,
     591            0 :                              format("{}{}=\"{}\", Invalid {}", RoutineName, cCurrentModuleObject, thisPump.Name, thisInput->cAlphaFieldNames(4)));
     592            0 :             ShowContinueError(
     593              :                 state,
     594            0 :                 format("Entered Value=[{}]. {} has been set to Continuous for this pump.", thisInput->cAlphaArgs(4), thisInput->cAlphaFieldNames(4)));
     595            0 :             thisPump.PumpControl = PumpControlType::Continuous;
     596              :         }
     597              : 
     598              :         // Input the optional schedule for the pump
     599          211 :         if (thisInput->lAlphaFieldBlanks(5)) {
     600          200 :             thisPump.flowRateSched = nullptr;
     601           11 :         } else if ((thisPump.flowRateSched = Sched::GetSchedule(state, thisInput->cAlphaArgs(5))) == nullptr) {
     602            1 :             ShowWarningItemNotFound(state, eoh, thisInput->cAlphaFieldNames(5), thisInput->cAlphaArgs(5), "");
     603              :         }
     604              : 
     605              :         // Input pressure related data such as pressure curve and impeller size/rotational speed
     606          211 :         if (thisInput->cAlphaArgs(6).empty()) {
     607          210 :             thisPump.PressureCurve_Index = -1;
     608              :         } else {
     609            1 :             TempCurveIndex = GetCurveIndex(state, thisInput->cAlphaArgs(6));
     610            1 :             if (TempCurveIndex == 0) {
     611            0 :                 thisPump.PressureCurve_Index = -1;
     612              :             } else {
     613            2 :                 ErrorsFound |= Curve::CheckCurveDims(state,
     614              :                                                      TempCurveIndex,                  // Curve index
     615              :                                                      {1},                             // Valid dimensions
     616              :                                                      RoutineName,                     // Routine name
     617              :                                                      cCurrentModuleObject,            // Object Type
     618              :                                                      thisPump.Name,                   // Object Name
     619            1 :                                                      thisInput->cAlphaFieldNames(6)); // Field Name
     620              : 
     621            1 :                 if (!ErrorsFound) {
     622            1 :                     thisPump.PressureCurve_Index = TempCurveIndex;
     623            1 :                     GetCurveMinMaxValues(state, TempCurveIndex, thisPump.MinPhiValue, thisPump.MaxPhiValue);
     624              :                 }
     625              :             }
     626              :         }
     627              : 
     628              :         // read in the rest of the pump pressure characteristics
     629          211 :         thisPump.ImpellerDiameter = thisInput->rNumericArgs(6);
     630          211 :         thisPump.RotSpeed_RPM = thisInput->rNumericArgs(7); // retrieve the input rotational speed, in revs/min
     631          211 :         thisPump.RotSpeed = thisPump.RotSpeed_RPM / 60.0;   // convert input[rpm] to calculation units[rps]
     632              : 
     633          211 :         if (!thisInput->lAlphaFieldBlanks(7)) { // zone named for pump skin losses
     634            0 :             thisPump.ZoneNum = Util::FindItemInList(thisInput->cAlphaArgs(7), state.dataHeatBal->Zone);
     635            0 :             if (thisPump.ZoneNum > 0) {
     636            0 :                 thisPump.HeatLossesToZone = true;
     637            0 :                 if (!thisInput->lNumericFieldBlanks(8)) {
     638            0 :                     thisPump.SkinLossRadFraction = thisInput->rNumericArgs(8);
     639              :                 }
     640              :             } else {
     641            0 :                 ShowSevereError(state,
     642            0 :                                 format("{}=\"{}\" invalid {}=\"{}\" not found.",
     643              :                                        cCurrentModuleObject,
     644            0 :                                        thisPump.Name,
     645            0 :                                        thisInput->cAlphaFieldNames(7),
     646            0 :                                        thisInput->cAlphaArgs(7)));
     647            0 :                 ErrorsFound = true;
     648              :             }
     649              :         }
     650              : 
     651          211 :         if (!thisInput->lAlphaFieldBlanks(8)) {
     652            8 :             thisPump.powerSizingMethod =
     653            8 :                 static_cast<PowerSizingMethod>(getEnumValue(powerSizingMethodNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(8))));
     654            8 :             if (thisPump.powerSizingMethod == PowerSizingMethod::Invalid) {
     655            0 :                 ShowSevereError(state,
     656            0 :                                 format("{}{}=\"{}\", sizing method type entered is invalid.  Use one of the key choice entries.",
     657              :                                        RoutineName,
     658              :                                        cCurrentModuleObject,
     659            0 :                                        thisPump.Name));
     660            0 :                 ErrorsFound = true;
     661              :             }
     662              :         }
     663              : 
     664          211 :         if (!thisInput->lNumericFieldBlanks(9)) {
     665            8 :             thisPump.powerPerFlowScalingFactor = thisInput->rNumericArgs(9);
     666              :         }
     667              : 
     668          211 :         if (!thisInput->lNumericFieldBlanks(10)) {
     669            0 :             thisPump.powerPerFlowPerPressureScalingFactor = thisInput->rNumericArgs(10);
     670              :         }
     671              : 
     672          211 :         if (NumAlphas > 8) {
     673            1 :             thisPump.EndUseSubcategoryName = thisInput->cAlphaArgs(9);
     674              :         } else {
     675          210 :             thisPump.EndUseSubcategoryName = "General";
     676              :         }
     677              :     }
     678              : 
     679              :     // pumps for steam system pumping condensate
     680          462 :     cCurrentModuleObject = pumpTypeIDFNames[static_cast<int>(PumpType::Cond)];
     681          471 :     for (int NumCondPump = 1; NumCondPump <= NumCondensatePumps; ++NumCondPump) {
     682            9 :         PumpNum = NumCondPump + NumVarSpeedPumps + NumConstSpeedPumps;
     683            9 :         auto &thisPump = state.dataPumps->PumpEquip(PumpNum);
     684           18 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     685              :                                                                  cCurrentModuleObject,
     686              :                                                                  NumCondPump,
     687            9 :                                                                  thisInput->cAlphaArgs,
     688              :                                                                  NumAlphas,
     689            9 :                                                                  thisInput->rNumericArgs,
     690              :                                                                  NumNums,
     691              :                                                                  IOStat,
     692            9 :                                                                  thisInput->lNumericFieldBlanks,
     693            9 :                                                                  thisInput->lAlphaFieldBlanks,
     694            9 :                                                                  thisInput->cAlphaFieldNames,
     695            9 :                                                                  thisInput->cNumericFieldNames);
     696              : 
     697            9 :         ErrorObjectHeader eoh{routineName, cCurrentModuleObject, thisInput->cAlphaArgs(1)};
     698              : 
     699            9 :         GlobalNames::VerifyUniqueInterObjectName(
     700           18 :             state, state.dataPumps->PumpUniqueNames, thisInput->cAlphaArgs(1), cCurrentModuleObject, thisInput->cAlphaFieldNames(1), ErrorsFound);
     701            9 :         thisPump.Name = thisInput->cAlphaArgs(1);
     702            9 :         thisPump.pumpType = PumpType::Cond; //'Pump:VariableSpeed:Condensate'
     703            9 :         thisPump.TypeOf_Num = DataPlant::PlantEquipmentType::PumpCondensate;
     704              : 
     705            9 :         thisPump.InletNodeNum = GetOnlySingleNode(state,
     706            9 :                                                   thisInput->cAlphaArgs(2),
     707              :                                                   ErrorsFound,
     708              :                                                   DataLoopNode::ConnectionObjectType::PumpVariableSpeedCondensate,
     709            9 :                                                   thisPump.Name,
     710              :                                                   DataLoopNode::NodeFluidType::Steam,
     711              :                                                   DataLoopNode::ConnectionType::Inlet,
     712              :                                                   NodeInputManager::CompFluidStream::Primary,
     713              :                                                   ObjectIsNotParent);
     714              : 
     715           18 :         thisPump.OutletNodeNum = GetOnlySingleNode(state,
     716            9 :                                                    thisInput->cAlphaArgs(3),
     717              :                                                    ErrorsFound,
     718              :                                                    DataLoopNode::ConnectionObjectType::PumpVariableSpeedCondensate,
     719            9 :                                                    thisPump.Name,
     720              :                                                    DataLoopNode::NodeFluidType::Steam,
     721              :                                                    DataLoopNode::ConnectionType::Outlet,
     722              :                                                    NodeInputManager::CompFluidStream::Primary,
     723              :                                                    ObjectIsNotParent);
     724            9 :         TestCompSet(state, cCurrentModuleObject, thisPump.Name, thisInput->cAlphaArgs(2), thisInput->cAlphaArgs(3), "Water Nodes");
     725              : 
     726            9 :         thisPump.PumpControl = PumpControlType::Intermittent;
     727              : 
     728              :         // Input the optional schedule for the pump
     729            9 :         if (thisInput->cAlphaArgs(4).empty()) {
     730            9 :             thisPump.flowRateSched = nullptr;
     731            0 :         } else if ((thisPump.flowRateSched = Sched::GetSchedule(state, thisInput->cAlphaArgs(4))) == nullptr) {
     732            0 :             ShowWarningItemNotFound(state, eoh, thisInput->cAlphaFieldNames(4), thisInput->cAlphaArgs(4));
     733              :         }
     734              : 
     735            9 :         thisPump.NomSteamVolFlowRate = thisInput->rNumericArgs(1);
     736            9 :         if (thisPump.NomSteamVolFlowRate == AutoSize) {
     737            6 :             thisPump.NomSteamVolFlowRateWasAutoSized = true;
     738              :         }
     739            9 :         thisPump.NomPumpHead = thisInput->rNumericArgs(2);
     740            9 :         thisPump.NomPowerUse = thisInput->rNumericArgs(3);
     741            9 :         if (thisPump.NomPowerUse == AutoSize) {
     742            8 :             thisPump.NomPowerUseWasAutoSized = true;
     743              :         }
     744            9 :         thisPump.MotorEffic = thisInput->rNumericArgs(4);
     745            9 :         thisPump.FracMotorLossToFluid = thisInput->rNumericArgs(5);
     746            9 :         thisPump.PartLoadCoef[0] = thisInput->rNumericArgs(6);
     747            9 :         thisPump.PartLoadCoef[1] = thisInput->rNumericArgs(7);
     748            9 :         thisPump.PartLoadCoef[2] = thisInput->rNumericArgs(8);
     749            9 :         thisPump.PartLoadCoef[3] = thisInput->rNumericArgs(9);
     750              : 
     751            9 :         if (!thisInput->lAlphaFieldBlanks(5)) { // zone named for pump skin losses
     752            0 :             thisPump.ZoneNum = Util::FindItemInList(thisInput->cAlphaArgs(5), state.dataHeatBal->Zone);
     753            0 :             if (thisPump.ZoneNum > 0) {
     754            0 :                 thisPump.HeatLossesToZone = true;
     755            0 :                 if (!thisInput->lNumericFieldBlanks(10)) {
     756            0 :                     thisPump.SkinLossRadFraction = thisInput->rNumericArgs(10);
     757              :                 }
     758              :             } else {
     759            0 :                 ShowSevereError(state,
     760            0 :                                 format("{}=\"{}\" invalid {}=\"{}\" not found.",
     761              :                                        cCurrentModuleObject,
     762            0 :                                        thisPump.Name,
     763            0 :                                        thisInput->cAlphaFieldNames(5),
     764            0 :                                        thisInput->cAlphaArgs(5)));
     765            0 :                 ErrorsFound = true;
     766              :             }
     767              :         }
     768              : 
     769            9 :         thisPump.MinVolFlowRate = 0.0;
     770            9 :         thisPump.Energy = 0.0;
     771            9 :         thisPump.Power = 0.0;
     772              : 
     773            9 :         if (thisPump.NomSteamVolFlowRateWasAutoSized) {
     774            6 :             thisPump.NomVolFlowRate = AutoSize;
     775            6 :             thisPump.NomVolFlowRateWasAutoSized = true;
     776              :         } else {
     777              :             // Calc Condensate Pump Water Volume Flow Rate
     778            3 :             SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, StartTemp, 1.0, routineName);
     779            3 :             TempWaterDensity = Fluid::GetWater(state)->getDensity(state, Constant::InitConvTemp, routineName);
     780            3 :             thisPump.NomVolFlowRate = (thisPump.NomSteamVolFlowRate * SteamDensity) / TempWaterDensity;
     781              :         }
     782              : 
     783            9 :         if (!thisInput->lAlphaFieldBlanks(6)) {
     784            1 :             thisPump.powerSizingMethod =
     785            1 :                 static_cast<PowerSizingMethod>(getEnumValue(powerSizingMethodNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(6))));
     786            1 :             if (thisPump.powerSizingMethod == PowerSizingMethod::Invalid) {
     787            0 :                 ShowSevereError(state,
     788            0 :                                 format("{}{}=\"{}\", sizing method type entered is invalid.  Use one of the key choice entries.",
     789              :                                        RoutineName,
     790              :                                        cCurrentModuleObject,
     791            0 :                                        thisPump.Name));
     792            0 :                 ErrorsFound = true;
     793              :             }
     794              :         }
     795              : 
     796            9 :         if (!thisInput->lNumericFieldBlanks(11)) {
     797            1 :             thisPump.powerPerFlowScalingFactor = thisInput->rNumericArgs(11);
     798              :         }
     799              : 
     800            9 :         if (!thisInput->lNumericFieldBlanks(12)) {
     801            1 :             thisPump.powerPerFlowPerPressureScalingFactor = thisInput->rNumericArgs(12);
     802              :         }
     803              : 
     804            9 :         if (NumAlphas > 6) {
     805            0 :             thisPump.EndUseSubcategoryName = thisInput->cAlphaArgs(7);
     806              :         } else {
     807            9 :             thisPump.EndUseSubcategoryName = "General";
     808              :         }
     809              :     }
     810              : 
     811              :     // LOAD Variable Speed Pump Bank ARRAYS WITH VARIABLE SPEED CURVE FIT PUMP DATA
     812          462 :     cCurrentModuleObject = pumpTypeIDFNames[static_cast<int>(PumpType::Bank_VarSpeed)];
     813          468 :     for (int NumVarPumpBankSimple = 1; NumVarPumpBankSimple <= NumPumpBankSimpleVar; ++NumVarPumpBankSimple) {
     814            6 :         PumpNum = NumVarPumpBankSimple + NumVarSpeedPumps + NumConstSpeedPumps + NumCondensatePumps;
     815            6 :         auto &thisPump = state.dataPumps->PumpEquip(PumpNum);
     816           12 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     817              :                                                                  cCurrentModuleObject,
     818              :                                                                  NumVarPumpBankSimple,
     819            6 :                                                                  thisInput->cAlphaArgs,
     820              :                                                                  NumAlphas,
     821            6 :                                                                  thisInput->rNumericArgs,
     822              :                                                                  NumNums,
     823              :                                                                  IOStat,
     824            6 :                                                                  thisInput->lNumericFieldBlanks,
     825            6 :                                                                  thisInput->lAlphaFieldBlanks,
     826            6 :                                                                  thisInput->cAlphaFieldNames,
     827            6 :                                                                  thisInput->cNumericFieldNames);
     828              : 
     829            6 :         ErrorObjectHeader eoh{routineName, cCurrentModuleObject, thisInput->cAlphaArgs(1)};
     830              : 
     831            6 :         GlobalNames::VerifyUniqueInterObjectName(
     832           12 :             state, state.dataPumps->PumpUniqueNames, thisInput->cAlphaArgs(1), cCurrentModuleObject, thisInput->cAlphaFieldNames(1), ErrorsFound);
     833            6 :         thisPump.Name = thisInput->cAlphaArgs(1);
     834            6 :         thisPump.pumpType = PumpType::Bank_VarSpeed; //'HeaderedPumps:VariableSpeed'
     835            6 :         thisPump.TypeOf_Num = DataPlant::PlantEquipmentType::PumpBankVariableSpeed;
     836              : 
     837            6 :         thisPump.InletNodeNum = GetOnlySingleNode(state,
     838            6 :                                                   thisInput->cAlphaArgs(2),
     839              :                                                   ErrorsFound,
     840              :                                                   DataLoopNode::ConnectionObjectType::HeaderedPumpsVariableSpeed,
     841            6 :                                                   thisPump.Name,
     842              :                                                   DataLoopNode::NodeFluidType::Water,
     843              :                                                   DataLoopNode::ConnectionType::Inlet,
     844              :                                                   NodeInputManager::CompFluidStream::Primary,
     845              :                                                   ObjectIsNotParent);
     846              : 
     847           12 :         thisPump.OutletNodeNum = GetOnlySingleNode(state,
     848            6 :                                                    thisInput->cAlphaArgs(3),
     849              :                                                    ErrorsFound,
     850              :                                                    DataLoopNode::ConnectionObjectType::HeaderedPumpsVariableSpeed,
     851            6 :                                                    thisPump.Name,
     852              :                                                    DataLoopNode::NodeFluidType::Water,
     853              :                                                    DataLoopNode::ConnectionType::Outlet,
     854              :                                                    NodeInputManager::CompFluidStream::Primary,
     855              :                                                    ObjectIsNotParent);
     856            6 :         TestCompSet(state, cCurrentModuleObject, thisPump.Name, thisInput->cAlphaArgs(2), thisInput->cAlphaArgs(3), "Water Nodes");
     857              : 
     858            6 :         if (Util::SameString(thisInput->cAlphaArgs(4), "Optimal")) {
     859            0 :             thisPump.SequencingScheme = PumpBankControlSeq::OptimalScheme;
     860            6 :         } else if (Util::SameString(thisInput->cAlphaArgs(4), "Sequential")) {
     861            6 :             thisPump.SequencingScheme = PumpBankControlSeq::SequentialScheme;
     862            0 :         } else if (Util::SameString(thisInput->cAlphaArgs(4), "SupplyEquipmentAssigned")) {
     863            0 :             thisPump.SequencingScheme = PumpBankControlSeq::UserDefined;
     864              :         } else {
     865            0 :             ShowWarningError(state,
     866            0 :                              format("{}{}=\"{}\", Invalid {}", RoutineName, cCurrentModuleObject, thisPump.Name, thisInput->cAlphaFieldNames(4)));
     867            0 :             ShowContinueError(
     868              :                 state,
     869            0 :                 format("Entered Value=[{}]. {} has been set to Sequential for this pump.", thisInput->cAlphaArgs(4), thisInput->cAlphaFieldNames(4)));
     870            0 :             thisPump.SequencingScheme = PumpBankControlSeq::SequentialScheme;
     871              :         }
     872              : 
     873            6 :         thisPump.PumpControl = static_cast<PumpControlType>(getEnumValue(pumpCtrlTypeNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(5))));
     874            6 :         if (thisPump.PumpControl == PumpControlType::Invalid) {
     875            0 :             ShowWarningError(state,
     876            0 :                              format("{}{}=\"{}\", Invalid {}", RoutineName, cCurrentModuleObject, thisPump.Name, thisInput->cAlphaFieldNames(5)));
     877            0 :             ShowContinueError(
     878              :                 state,
     879            0 :                 format("Entered Value=[{}]. {} has been set to Continuous for this pump.", thisInput->cAlphaArgs(5), thisInput->cAlphaFieldNames(5)));
     880            0 :             thisPump.PumpControl = PumpControlType::Continuous;
     881              :         }
     882              : 
     883              :         // Input the optional schedule for the pump
     884            6 :         if (thisInput->cAlphaArgs(6).empty()) { // Initialized to zero, don't get a schedule for an empty
     885            5 :             thisPump.flowRateSched = nullptr;
     886            1 :         } else if ((thisPump.flowRateSched = Sched::GetSchedule(state, thisInput->cAlphaArgs(6))) == nullptr) {
     887            0 :             ShowWarningItemNotFound(state, eoh, thisInput->cAlphaFieldNames(6), thisInput->cAlphaArgs(6));
     888              :         }
     889              : 
     890            6 :         thisPump.NomVolFlowRate = thisInput->rNumericArgs(1);
     891            6 :         if (thisPump.NomVolFlowRate == AutoSize) {
     892            6 :             thisPump.NomVolFlowRateWasAutoSized = true;
     893              :         }
     894            6 :         thisPump.NumPumpsInBank = thisInput->rNumericArgs(2);
     895            6 :         thisPump.NomPumpHead = thisInput->rNumericArgs(3);
     896            6 :         thisPump.NomPowerUse = thisInput->rNumericArgs(4);
     897            6 :         if (thisPump.NomPowerUse == AutoSize) {
     898            6 :             thisPump.NomPowerUseWasAutoSized = true;
     899              :         }
     900            6 :         thisPump.MotorEffic = thisInput->rNumericArgs(5);
     901            6 :         thisPump.FracMotorLossToFluid = thisInput->rNumericArgs(6);
     902            6 :         thisPump.PartLoadCoef[0] = thisInput->rNumericArgs(7);
     903            6 :         thisPump.PartLoadCoef[1] = thisInput->rNumericArgs(8);
     904            6 :         thisPump.PartLoadCoef[2] = thisInput->rNumericArgs(9);
     905            6 :         thisPump.PartLoadCoef[3] = thisInput->rNumericArgs(10);
     906            6 :         thisPump.MinVolFlowRateFrac = thisInput->rNumericArgs(11);
     907            6 :         thisPump.MinVolFlowRate = thisPump.NomVolFlowRate * thisPump.MinVolFlowRateFrac;
     908              : 
     909            6 :         if (!thisInput->lAlphaFieldBlanks(7)) { // zone named for pump skin losses
     910            0 :             thisPump.ZoneNum = Util::FindItemInList(thisInput->cAlphaArgs(7), state.dataHeatBal->Zone);
     911            0 :             if (thisPump.ZoneNum > 0) {
     912            0 :                 thisPump.HeatLossesToZone = true;
     913            0 :                 if (!thisInput->lNumericFieldBlanks(12)) {
     914            0 :                     thisPump.SkinLossRadFraction = thisInput->rNumericArgs(12);
     915              :                 }
     916              :             } else {
     917            0 :                 ShowSevereError(state,
     918            0 :                                 format("{}=\"{}\" invalid {}=\"{}\" not found.",
     919              :                                        cCurrentModuleObject,
     920            0 :                                        thisPump.Name,
     921            0 :                                        thisInput->cAlphaFieldNames(7),
     922            0 :                                        thisInput->cAlphaArgs(7)));
     923            0 :                 ErrorsFound = true;
     924              :             }
     925              :         }
     926              : 
     927            6 :         if (!thisInput->lAlphaFieldBlanks(8)) {
     928            1 :             thisPump.powerSizingMethod =
     929            1 :                 static_cast<PowerSizingMethod>(getEnumValue(powerSizingMethodNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(8))));
     930            1 :             if (thisPump.powerSizingMethod == PowerSizingMethod::Invalid) {
     931            0 :                 ShowSevereError(state,
     932            0 :                                 format("{}{}=\"{}\", sizing method type entered is invalid.  Use one of the key choice entries.",
     933              :                                        RoutineName,
     934              :                                        cCurrentModuleObject,
     935            0 :                                        thisPump.Name));
     936            0 :                 ErrorsFound = true;
     937              :             }
     938              :         }
     939              : 
     940            6 :         if (!thisInput->lNumericFieldBlanks(13)) {
     941            0 :             thisPump.powerPerFlowScalingFactor = thisInput->rNumericArgs(13);
     942              :         }
     943              : 
     944            6 :         if (!thisInput->lNumericFieldBlanks(14)) {
     945            0 :             thisPump.powerPerFlowPerPressureScalingFactor = thisInput->rNumericArgs(14);
     946              :         }
     947              : 
     948            6 :         if (NumAlphas > 8) {
     949            1 :             thisPump.EndUseSubcategoryName = thisInput->cAlphaArgs(9);
     950              :         } else {
     951            5 :             thisPump.EndUseSubcategoryName = "General";
     952              :         }
     953              : 
     954            6 :         thisPump.Energy = 0.0;
     955            6 :         thisPump.Power = 0.0;
     956              :     }
     957              : 
     958          462 :     cCurrentModuleObject = pumpTypeIDFNames[static_cast<int>(PumpType::Bank_ConSpeed)];
     959          463 :     for (int NumConstPumpBankSimple = 1; NumConstPumpBankSimple <= NumPumpBankSimpleConst; ++NumConstPumpBankSimple) {
     960            1 :         PumpNum = NumConstPumpBankSimple + NumVarSpeedPumps + NumConstSpeedPumps + NumCondensatePumps + NumPumpBankSimpleVar;
     961            1 :         auto &thisPump = state.dataPumps->PumpEquip(PumpNum);
     962            2 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     963              :                                                                  cCurrentModuleObject,
     964              :                                                                  NumConstPumpBankSimple,
     965            1 :                                                                  thisInput->cAlphaArgs,
     966              :                                                                  NumAlphas,
     967            1 :                                                                  thisInput->rNumericArgs,
     968              :                                                                  NumNums,
     969              :                                                                  IOStat,
     970            1 :                                                                  thisInput->lNumericFieldBlanks,
     971            1 :                                                                  thisInput->lAlphaFieldBlanks,
     972            1 :                                                                  thisInput->cAlphaFieldNames,
     973            1 :                                                                  thisInput->cNumericFieldNames);
     974              : 
     975            1 :         ErrorObjectHeader eoh{routineName, cCurrentModuleObject, thisInput->cAlphaArgs(1)};
     976              : 
     977            1 :         GlobalNames::VerifyUniqueInterObjectName(
     978            2 :             state, state.dataPumps->PumpUniqueNames, thisInput->cAlphaArgs(1), cCurrentModuleObject, thisInput->cAlphaFieldNames(1), ErrorsFound);
     979            1 :         thisPump.Name = thisInput->cAlphaArgs(1);
     980            1 :         thisPump.pumpType = PumpType::Bank_ConSpeed; //'HeaderedPumps:ConstantSpeed'
     981            1 :         thisPump.TypeOf_Num = DataPlant::PlantEquipmentType::PumpBankConstantSpeed;
     982              : 
     983            1 :         thisPump.InletNodeNum = GetOnlySingleNode(state,
     984            1 :                                                   thisInput->cAlphaArgs(2),
     985              :                                                   ErrorsFound,
     986              :                                                   DataLoopNode::ConnectionObjectType::HeaderedPumpsConstantSpeed,
     987            1 :                                                   thisPump.Name,
     988              :                                                   DataLoopNode::NodeFluidType::Water,
     989              :                                                   DataLoopNode::ConnectionType::Inlet,
     990              :                                                   NodeInputManager::CompFluidStream::Primary,
     991              :                                                   ObjectIsNotParent);
     992              : 
     993            2 :         thisPump.OutletNodeNum = GetOnlySingleNode(state,
     994            1 :                                                    thisInput->cAlphaArgs(3),
     995              :                                                    ErrorsFound,
     996              :                                                    DataLoopNode::ConnectionObjectType::HeaderedPumpsConstantSpeed,
     997            1 :                                                    thisPump.Name,
     998              :                                                    DataLoopNode::NodeFluidType::Water,
     999              :                                                    DataLoopNode::ConnectionType::Outlet,
    1000              :                                                    NodeInputManager::CompFluidStream::Primary,
    1001              :                                                    ObjectIsNotParent);
    1002            1 :         TestCompSet(state, cCurrentModuleObject, thisPump.Name, thisInput->cAlphaArgs(2), thisInput->cAlphaArgs(3), "Water Nodes");
    1003              : 
    1004            1 :         if (Util::SameString(thisInput->cAlphaArgs(4), "Optimal")) {
    1005            0 :             thisPump.SequencingScheme = PumpBankControlSeq::OptimalScheme;
    1006            1 :         } else if (Util::SameString(thisInput->cAlphaArgs(4), "Sequential")) {
    1007            1 :             thisPump.SequencingScheme = PumpBankControlSeq::SequentialScheme;
    1008              :         } else {
    1009            0 :             ShowWarningError(state,
    1010            0 :                              format("{}{}=\"{}\", Invalid {}", RoutineName, cCurrentModuleObject, thisPump.Name, thisInput->cAlphaFieldNames(4)));
    1011            0 :             ShowContinueError(
    1012              :                 state,
    1013            0 :                 format("Entered Value=[{}]. {} has been set to Sequential for this pump.", thisInput->cAlphaArgs(4), thisInput->cAlphaFieldNames(4)));
    1014            0 :             thisPump.SequencingScheme = PumpBankControlSeq::SequentialScheme;
    1015              :         }
    1016              : 
    1017            1 :         thisPump.PumpControl = static_cast<PumpControlType>(getEnumValue(pumpCtrlTypeNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(5))));
    1018              : 
    1019            1 :         if (thisPump.PumpControl == PumpControlType::Invalid) {
    1020            0 :             ShowWarningError(state,
    1021            0 :                              format("{}{}=\"{}\", Invalid {}", RoutineName, cCurrentModuleObject, thisPump.Name, thisInput->cAlphaFieldNames(5)));
    1022            0 :             ShowContinueError(
    1023              :                 state,
    1024            0 :                 format("Entered Value=[{}]. {} has been set to Continuous for this pump.", thisInput->cAlphaArgs(5), thisInput->cAlphaFieldNames(5)));
    1025            0 :             thisPump.PumpControl = PumpControlType::Continuous;
    1026              :         }
    1027              : 
    1028              :         // Input the optional schedule for the pump
    1029            1 :         if (thisInput->lAlphaFieldBlanks(6)) {
    1030            0 :             thisPump.flowRateSched = nullptr;
    1031            1 :         } else if ((thisPump.flowRateSched = Sched::GetSchedule(state, thisInput->cAlphaArgs(6))) == nullptr) {
    1032            0 :             ShowWarningItemNotFound(state, eoh, thisInput->cAlphaFieldNames(6), thisInput->cAlphaArgs(6), "");
    1033              :         }
    1034              : 
    1035            1 :         thisPump.NomVolFlowRate = thisInput->rNumericArgs(1);
    1036            1 :         if (thisPump.NomVolFlowRate == AutoSize) {
    1037            1 :             thisPump.NomVolFlowRateWasAutoSized = true;
    1038              :         }
    1039            1 :         thisPump.NumPumpsInBank = thisInput->rNumericArgs(2);
    1040            1 :         thisPump.NomPumpHead = thisInput->rNumericArgs(3);
    1041            1 :         thisPump.NomPowerUse = thisInput->rNumericArgs(4);
    1042            1 :         if (thisPump.NomPowerUse == AutoSize) {
    1043            1 :             thisPump.NomPowerUseWasAutoSized = true;
    1044              :         }
    1045            1 :         thisPump.MotorEffic = thisInput->rNumericArgs(5);
    1046            1 :         thisPump.FracMotorLossToFluid = thisInput->rNumericArgs(6);
    1047            1 :         thisPump.PartLoadCoef[0] = 1.0;
    1048            1 :         thisPump.PartLoadCoef[1] = 0.0;
    1049            1 :         thisPump.PartLoadCoef[2] = 0.0;
    1050            1 :         thisPump.PartLoadCoef[3] = 0.0;
    1051              : 
    1052            1 :         if (!thisInput->lAlphaFieldBlanks(7)) { // zone named for pump skin losses
    1053            0 :             thisPump.ZoneNum = Util::FindItemInList(thisInput->cAlphaArgs(7), state.dataHeatBal->Zone);
    1054            0 :             if (thisPump.ZoneNum > 0) {
    1055            0 :                 thisPump.HeatLossesToZone = true;
    1056            0 :                 if (!thisInput->lNumericFieldBlanks(7)) {
    1057            0 :                     thisPump.SkinLossRadFraction = thisInput->rNumericArgs(7);
    1058              :                 }
    1059              :             } else {
    1060            0 :                 ShowSevereError(state,
    1061            0 :                                 format("{}=\"{}\" invalid {}=\"{}\" not found.",
    1062              :                                        cCurrentModuleObject,
    1063            0 :                                        thisPump.Name,
    1064            0 :                                        thisInput->cAlphaFieldNames(7),
    1065            0 :                                        thisInput->cAlphaArgs(7)));
    1066            0 :                 ErrorsFound = true;
    1067              :             }
    1068              :         }
    1069            1 :         if (!thisInput->lAlphaFieldBlanks(8)) {
    1070            1 :             thisPump.powerSizingMethod =
    1071            1 :                 static_cast<PowerSizingMethod>(getEnumValue(powerSizingMethodNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(8))));
    1072            1 :             if (thisPump.powerSizingMethod == PowerSizingMethod::Invalid) {
    1073            0 :                 ShowSevereError(state,
    1074            0 :                                 format("{}{}=\"{}\", sizing method type entered is invalid.  Use one of the key choice entries.",
    1075              :                                        RoutineName,
    1076              :                                        cCurrentModuleObject,
    1077            0 :                                        thisPump.Name));
    1078            0 :                 ErrorsFound = true;
    1079              :             }
    1080              :         }
    1081              : 
    1082            1 :         if (!thisInput->lNumericFieldBlanks(8)) {
    1083            0 :             thisPump.powerPerFlowScalingFactor = thisInput->rNumericArgs(8);
    1084              :         }
    1085              : 
    1086            1 :         if (!thisInput->lNumericFieldBlanks(9)) {
    1087            1 :             thisPump.powerPerFlowPerPressureScalingFactor = thisInput->rNumericArgs(9);
    1088              :         }
    1089              : 
    1090            1 :         if (NumAlphas > 8) {
    1091            1 :             thisPump.EndUseSubcategoryName = thisInput->cAlphaArgs(9);
    1092              :         } else {
    1093            0 :             thisPump.EndUseSubcategoryName = "General";
    1094              :         }
    1095              : 
    1096            1 :         thisPump.MinVolFlowRate = 0.0;
    1097            1 :         thisPump.Energy = 0.0;
    1098            1 :         thisPump.Power = 0.0;
    1099              :     }
    1100              : 
    1101          462 :     if (ErrorsFound) {
    1102            0 :         ShowFatalError(state, "Errors found in getting Pump input");
    1103              :     }
    1104              : 
    1105         1641 :     for (PumpNum = 1; PumpNum <= state.dataPumps->NumPumps; ++PumpNum) { // CurrentModuleObject='Pumps'
    1106         1179 :         auto &thisPump = state.dataPumps->PumpEquip(PumpNum);
    1107         1179 :         auto &thisPumpRep = state.dataPumps->PumpEquipReport(PumpNum);
    1108         1179 :         switch (thisPump.pumpType) {
    1109         1172 :         case PumpType::VarSpeed:
    1110              :         case PumpType::ConSpeed:
    1111              :         case PumpType::Cond: {
    1112              : 
    1113         2344 :             SetupOutputVariable(state,
    1114              :                                 "Pump Electricity Energy",
    1115              :                                 Constant::Units::J,
    1116         1172 :                                 thisPump.Energy,
    1117              :                                 OutputProcessor::TimeStepType::System,
    1118              :                                 OutputProcessor::StoreType::Sum,
    1119         1172 :                                 thisPump.Name,
    1120              :                                 Constant::eResource::Electricity,
    1121              :                                 OutputProcessor::Group::Plant,
    1122              :                                 OutputProcessor::EndUseCat::Pumps,
    1123              :                                 thisPump.EndUseSubcategoryName);
    1124         2344 :             SetupOutputVariable(state,
    1125              :                                 "Pump Electricity Rate",
    1126              :                                 Constant::Units::W,
    1127         1172 :                                 thisPump.Power,
    1128              :                                 OutputProcessor::TimeStepType::System,
    1129              :                                 OutputProcessor::StoreType::Average,
    1130         1172 :                                 thisPump.Name);
    1131         2344 :             SetupOutputVariable(state,
    1132              :                                 "Pump Shaft Power",
    1133              :                                 Constant::Units::W,
    1134         1172 :                                 thisPumpRep.ShaftPower,
    1135              :                                 OutputProcessor::TimeStepType::System,
    1136              :                                 OutputProcessor::StoreType::Average,
    1137         1172 :                                 thisPump.Name);
    1138         2344 :             SetupOutputVariable(state,
    1139              :                                 "Pump Fluid Heat Gain Rate",
    1140              :                                 Constant::Units::W,
    1141         1172 :                                 thisPumpRep.PumpHeattoFluid,
    1142              :                                 OutputProcessor::TimeStepType::System,
    1143              :                                 OutputProcessor::StoreType::Average,
    1144         1172 :                                 thisPump.Name);
    1145         2344 :             SetupOutputVariable(state,
    1146              :                                 "Pump Fluid Heat Gain Energy",
    1147              :                                 Constant::Units::J,
    1148         1172 :                                 thisPumpRep.PumpHeattoFluidEnergy,
    1149              :                                 OutputProcessor::TimeStepType::System,
    1150              :                                 OutputProcessor::StoreType::Sum,
    1151         1172 :                                 thisPump.Name);
    1152         2344 :             SetupOutputVariable(state,
    1153              :                                 "Pump Outlet Temperature",
    1154              :                                 Constant::Units::C,
    1155         1172 :                                 thisPumpRep.OutletTemp,
    1156              :                                 OutputProcessor::TimeStepType::System,
    1157              :                                 OutputProcessor::StoreType::Average,
    1158         1172 :                                 thisPump.Name);
    1159         2344 :             SetupOutputVariable(state,
    1160              :                                 "Pump Mass Flow Rate",
    1161              :                                 Constant::Units::kg_s,
    1162         1172 :                                 thisPumpRep.PumpMassFlowRate,
    1163              :                                 OutputProcessor::TimeStepType::System,
    1164              :                                 OutputProcessor::StoreType::Average,
    1165         1172 :                                 thisPump.Name);
    1166         1172 :         } break;
    1167              : 
    1168            7 :         case PumpType::Bank_VarSpeed:
    1169              :         case PumpType::Bank_ConSpeed: { // CurrentModuleObject='HeaderedPumps'
    1170              : 
    1171           14 :             SetupOutputVariable(state,
    1172              :                                 "Pump Electricity Energy",
    1173              :                                 Constant::Units::J,
    1174            7 :                                 thisPump.Energy,
    1175              :                                 OutputProcessor::TimeStepType::System,
    1176              :                                 OutputProcessor::StoreType::Sum,
    1177            7 :                                 thisPump.Name,
    1178              :                                 Constant::eResource::Electricity,
    1179              :                                 OutputProcessor::Group::Plant,
    1180              :                                 OutputProcessor::EndUseCat::Pumps,
    1181              :                                 thisPump.EndUseSubcategoryName);
    1182           14 :             SetupOutputVariable(state,
    1183              :                                 "Pump Electricity Rate",
    1184              :                                 Constant::Units::W,
    1185            7 :                                 thisPump.Power,
    1186              :                                 OutputProcessor::TimeStepType::System,
    1187              :                                 OutputProcessor::StoreType::Average,
    1188            7 :                                 thisPump.Name);
    1189           14 :             SetupOutputVariable(state,
    1190              :                                 "Pump Shaft Power",
    1191              :                                 Constant::Units::W,
    1192            7 :                                 thisPumpRep.ShaftPower,
    1193              :                                 OutputProcessor::TimeStepType::System,
    1194              :                                 OutputProcessor::StoreType::Average,
    1195            7 :                                 thisPump.Name);
    1196           14 :             SetupOutputVariable(state,
    1197              :                                 "Pump Fluid Heat Gain Rate",
    1198              :                                 Constant::Units::W,
    1199            7 :                                 thisPumpRep.PumpHeattoFluid,
    1200              :                                 OutputProcessor::TimeStepType::System,
    1201              :                                 OutputProcessor::StoreType::Average,
    1202            7 :                                 thisPump.Name);
    1203           14 :             SetupOutputVariable(state,
    1204              :                                 "Pump Fluid Heat Gain Energy",
    1205              :                                 Constant::Units::J,
    1206            7 :                                 thisPumpRep.PumpHeattoFluidEnergy,
    1207              :                                 OutputProcessor::TimeStepType::System,
    1208              :                                 OutputProcessor::StoreType::Sum,
    1209            7 :                                 thisPump.Name);
    1210           14 :             SetupOutputVariable(state,
    1211              :                                 "Pump Outlet Temperature",
    1212              :                                 Constant::Units::C,
    1213            7 :                                 thisPumpRep.OutletTemp,
    1214              :                                 OutputProcessor::TimeStepType::System,
    1215              :                                 OutputProcessor::StoreType::Average,
    1216            7 :                                 thisPump.Name);
    1217           14 :             SetupOutputVariable(state,
    1218              :                                 "Pump Mass Flow Rate",
    1219              :                                 Constant::Units::kg_s,
    1220            7 :                                 thisPumpRep.PumpMassFlowRate,
    1221              :                                 OutputProcessor::TimeStepType::System,
    1222              :                                 OutputProcessor::StoreType::Average,
    1223            7 :                                 thisPump.Name);
    1224            7 :             SetupOutputVariable(state,
    1225              :                                 "Pump Operating Pumps Count",
    1226              :                                 Constant::Units::None,
    1227            7 :                                 thisPumpRep.NumPumpsOperating,
    1228              :                                 OutputProcessor::TimeStepType::System,
    1229              :                                 OutputProcessor::StoreType::Average,
    1230            7 :                                 thisPump.Name);
    1231            7 :         } break;
    1232            0 :         default: {
    1233            0 :             assert(false);
    1234              :         } break;
    1235              :         }
    1236              : 
    1237         1179 :         if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
    1238          134 :             SetupEMSInternalVariable(state, "Pump Maximum Mass Flow Rate", thisPump.Name, "[kg/s]", thisPump.MassFlowRateMax);
    1239          134 :             SetupEMSActuator(
    1240          134 :                 state, "Pump", thisPump.Name, "Pump Mass Flow Rate", "[kg/s]", thisPump.EMSMassFlowOverrideOn, thisPump.EMSMassFlowValue);
    1241          134 :             SetupEMSActuator(
    1242          134 :                 state, "Pump", thisPump.Name, "Pump Pressure Rise", "[Pa]", thisPump.EMSPressureOverrideOn, thisPump.EMSPressureOverrideValue);
    1243              :         }
    1244              : 
    1245         1179 :         if (thisPump.HeatLossesToZone) {
    1246              :             // setup skin loss output vars
    1247            0 :             SetupOutputVariable(state,
    1248              :                                 "Pump Zone Total Heating Rate",
    1249              :                                 Constant::Units::W,
    1250            0 :                                 thisPumpRep.ZoneTotalGainRate,
    1251              :                                 OutputProcessor::TimeStepType::System,
    1252              :                                 OutputProcessor::StoreType::Average,
    1253            0 :                                 thisPump.Name);
    1254            0 :             SetupOutputVariable(state,
    1255              :                                 "Pump Zone Total Heating Energy",
    1256              :                                 Constant::Units::J,
    1257            0 :                                 thisPumpRep.ZoneTotalGainEnergy,
    1258              :                                 OutputProcessor::TimeStepType::System,
    1259              :                                 OutputProcessor::StoreType::Sum,
    1260            0 :                                 thisPump.Name);
    1261            0 :             SetupOutputVariable(state,
    1262              :                                 "Pump Zone Convective Heating Rate",
    1263              :                                 Constant::Units::W,
    1264            0 :                                 thisPumpRep.ZoneConvGainRate,
    1265              :                                 OutputProcessor::TimeStepType::System,
    1266              :                                 OutputProcessor::StoreType::Average,
    1267            0 :                                 thisPump.Name);
    1268            0 :             SetupOutputVariable(state,
    1269              :                                 "Pump Zone Radiative Heating Rate",
    1270              :                                 Constant::Units::W,
    1271            0 :                                 thisPumpRep.ZoneRadGainRate,
    1272              :                                 OutputProcessor::TimeStepType::System,
    1273              :                                 OutputProcessor::StoreType::Average,
    1274            0 :                                 thisPump.Name);
    1275              : 
    1276              :             // setup internal gains
    1277            0 :             switch (thisPump.pumpType) {
    1278            0 :             case PumpType::VarSpeed: {
    1279            0 :                 SetupZoneInternalGain(state,
    1280              :                                       thisPump.ZoneNum,
    1281              :                                       thisPump.Name,
    1282              :                                       DataHeatBalance::IntGainType::Pump_VarSpeed,
    1283              :                                       &thisPumpRep.ZoneConvGainRate,
    1284              :                                       nullptr,
    1285              :                                       &thisPumpRep.ZoneRadGainRate);
    1286            0 :             } break;
    1287            0 :             case PumpType::ConSpeed: {
    1288            0 :                 SetupZoneInternalGain(state,
    1289              :                                       thisPump.ZoneNum,
    1290              :                                       thisPump.Name,
    1291              :                                       DataHeatBalance::IntGainType::Pump_ConSpeed,
    1292              :                                       &thisPumpRep.ZoneConvGainRate,
    1293              :                                       nullptr,
    1294              :                                       &thisPumpRep.ZoneRadGainRate);
    1295            0 :             } break;
    1296            0 :             case PumpType::Cond: {
    1297            0 :                 SetupZoneInternalGain(state,
    1298              :                                       thisPump.ZoneNum,
    1299              :                                       thisPump.Name,
    1300              :                                       DataHeatBalance::IntGainType::Pump_Cond,
    1301              :                                       &thisPumpRep.ZoneConvGainRate,
    1302              :                                       nullptr,
    1303              :                                       &thisPumpRep.ZoneRadGainRate);
    1304            0 :             } break;
    1305            0 :             case PumpType::Bank_VarSpeed: {
    1306            0 :                 SetupZoneInternalGain(state,
    1307              :                                       thisPump.ZoneNum,
    1308              :                                       thisPump.Name,
    1309              :                                       DataHeatBalance::IntGainType::PumpBank_VarSpeed,
    1310              :                                       &thisPumpRep.ZoneConvGainRate,
    1311              :                                       nullptr,
    1312              :                                       &thisPumpRep.ZoneRadGainRate);
    1313            0 :             } break;
    1314            0 :             case PumpType::Bank_ConSpeed: {
    1315            0 :                 SetupZoneInternalGain(state,
    1316              :                                       thisPump.ZoneNum,
    1317              :                                       thisPump.Name,
    1318              :                                       DataHeatBalance::IntGainType::PumpBank_ConSpeed,
    1319              :                                       &thisPumpRep.ZoneConvGainRate,
    1320              :                                       nullptr,
    1321              :                                       &thisPumpRep.ZoneRadGainRate);
    1322            0 :             } break;
    1323            0 :             default:
    1324            0 :                 break;
    1325              :             }
    1326              :         }
    1327              :     }
    1328              : }
    1329              : 
    1330     56466326 : void InitializePumps(EnergyPlusData &state, int const PumpNum)
    1331              : {
    1332              : 
    1333              :     // SUBROUTINE INFORMATION:
    1334              :     //       AUTHOR:        Edwin Lee
    1335              :     //       DATE WRITTEN:  August 2010
    1336              :     //       MODIFIED       Based on the INIT section of InitSimVars, credits here:
    1337              :     //                        Author:
    1338              :     //                          Oct 1998 Dan Fisher
    1339              :     //                        Modifications:
    1340              :     //                          Jul 2001 Richard Liesen
    1341              :     //                          July 2001, Rick Strand (implemented new pump controls)
    1342              :     //                          May 2009, Brent Griffith (added EMS override capability)
    1343              :     //                          Nov 2010, Brent Griffith (call InitComponentNodes, generalize fluid props)
    1344              :     //       RE-ENGINEERED  na
    1345              : 
    1346              :     // PURPOSE OF THIS SUBROUTINE:
    1347              :     // This subroutine does one-time and begin-envrn inits for the pump
    1348              : 
    1349              :     // Using/Aliasing
    1350              : 
    1351              :     using PlantUtilities::InitComponentNodes;
    1352              :     using PlantUtilities::ScanPlantLoopsForObject;
    1353              : 
    1354              :     // SUBROUTINE PARAMETER DEFINITIONS:
    1355     56466326 :     Real64 constexpr StartTemp(100.0); // Standard Temperature across code to calculated Steam density
    1356     56466326 :     Real64 constexpr ZeroPowerTol(0.0000001);
    1357              :     static constexpr std::string_view RoutineName("PlantPumps::InitializePumps ");
    1358              : 
    1359              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1360              :     Real64 TotalEffic;
    1361              :     Real64 SteamDensity; // Density of working fluid
    1362              :     Real64 TempWaterDensity;
    1363              :     Real64 mdotMax; // local fluid mass flow rate maximum
    1364              :     Real64 mdotMin; // local fluid mass flow rate minimum
    1365              :     DataPlant::LoopSideLocation lsnum;
    1366              : 
    1367              :     // Set some variables for convenience
    1368     56466326 :     auto &thisPump = state.dataPumps->PumpEquip(PumpNum);
    1369     56466326 :     int InletNode = thisPump.InletNodeNum;
    1370     56466326 :     int OutletNode = thisPump.OutletNodeNum;
    1371              : 
    1372              :     // One time inits
    1373     56466326 :     if (thisPump.PumpOneTimeFlag) {
    1374              : 
    1375         1179 :         bool errFlag = false;
    1376         1179 :         ScanPlantLoopsForObject(state, thisPump.Name, thisPump.TypeOf_Num, thisPump.plantLoc, errFlag, _, _, _, _, _);
    1377         1179 :         int plloopnum = thisPump.plantLoc.loopNum;
    1378         1179 :         lsnum = thisPump.plantLoc.loopSideNum;
    1379         1179 :         int brnum = thisPump.plantLoc.branchNum;
    1380         1179 :         int cpnum = thisPump.plantLoc.compNum;
    1381         1179 :         if (plloopnum > 0 && lsnum != DataPlant::LoopSideLocation::Invalid && brnum > 0 && cpnum > 0) {
    1382         1179 :             auto &thisPumpLoc = state.dataPlnt->PlantLoop(plloopnum).LoopSide(lsnum).Branch(brnum);
    1383         1179 :             if (thisPumpLoc.Comp(cpnum).NodeNumIn != InletNode || thisPumpLoc.Comp(cpnum).NodeNumOut != OutletNode) {
    1384            0 :                 ShowSevereError(
    1385              :                     state,
    1386            0 :                     format("InitializePumps: {}=\"{}\", non-matching nodes.", pumpTypeIDFNames[static_cast<int>(thisPump.pumpType)], thisPump.Name));
    1387            0 :                 ShowContinueError(state, format("...in Branch={}, Component referenced with:", thisPumpLoc.Name));
    1388            0 :                 ShowContinueError(state, format("...Inlet Node={}", state.dataLoopNodes->NodeID(thisPumpLoc.Comp(cpnum).NodeNumIn)));
    1389            0 :                 ShowContinueError(state, format("...Outlet Node={}", state.dataLoopNodes->NodeID(thisPumpLoc.Comp(cpnum).NodeNumOut)));
    1390            0 :                 ShowContinueError(state, format("...Pump Inlet Node={}", state.dataLoopNodes->NodeID(InletNode)));
    1391            0 :                 ShowContinueError(state, format("...Pump Outlet Node={}", state.dataLoopNodes->NodeID(OutletNode)));
    1392            0 :                 errFlag = true;
    1393              :             }
    1394         1179 :         } else { // CR9292
    1395            0 :             ShowSevereError(
    1396              :                 state,
    1397            0 :                 format("InitializePumps: {}=\"{}\", component missing.", pumpTypeIDFNames[static_cast<int>(thisPump.pumpType)], thisPump.Name));
    1398            0 :             errFlag = true; // should have received warning/severe earlier, will reiterate
    1399              :         }
    1400              : 
    1401         1179 :         if (errFlag) {
    1402            0 :             ShowFatalError(state, "InitializePumps: Program terminated due to previous condition(s).");
    1403              :         }
    1404         1179 :         DataPlant::CompData::getPlantComponent(state, thisPump.plantLoc).CompNum = PumpNum;
    1405              : 
    1406         1179 :         SizePump(state, PumpNum);
    1407              : 
    1408              :         // calculate the efficiency for each pump
    1409              :         // by calculating the efficiency for each pump being simulated.  The calculation
    1410              :         // is based on the PMPSIM code in the ASHRAE Secondary Toolkit
    1411         1179 :         if (thisPump.NomPowerUse > ZeroPowerTol && thisPump.MotorEffic > ZeroPowerTol) {
    1412         1144 :             TotalEffic = thisPump.NomVolFlowRate * thisPump.NomPumpHead / thisPump.NomPowerUse;
    1413         1144 :             thisPump.PumpEffic = TotalEffic / thisPump.MotorEffic;
    1414         1144 :             if (thisPump.PumpEffic < 0.50) {
    1415            2 :                 ShowWarningError(state,
    1416            2 :                                  format("Check input. Calculated Pump Efficiency={:.2R}% which is less than 50%, for pump={}",
    1417            0 :                                         thisPump.PumpEffic * 100.0,
    1418            1 :                                         thisPump.Name));
    1419            2 :                 ShowContinueError(state,
    1420            2 :                                   format("Calculated Pump_Efficiency % =Total_Efficiency % [{:.1R}] / Motor_Efficiency % [{:.1R}]",
    1421            0 :                                          TotalEffic * 100.0,
    1422            1 :                                          thisPump.MotorEffic * 100.0));
    1423            2 :                 ShowContinueError(
    1424              :                     state,
    1425            2 :                     format("Total_Efficiency % =(Rated_Volume_Flow_Rate [{:.3R}] * Rated_Pump_Head [{:.1R}] / Rated_Power_Use [{:.1R}]) * 100.",
    1426            1 :                            thisPump.NomVolFlowRate,
    1427            1 :                            thisPump.NomPumpHead,
    1428            1 :                            thisPump.NomPowerUse));
    1429         1143 :             } else if ((thisPump.PumpEffic > 0.95) && (thisPump.PumpEffic <= 1.0)) {
    1430            0 :                 ShowWarningError(state,
    1431            0 :                                  format("Check input.  Calculated Pump Efficiency={:.2R}% is approaching 100%, for pump={}",
    1432            0 :                                         thisPump.PumpEffic * 100.0,
    1433            0 :                                         thisPump.Name));
    1434            0 :                 ShowContinueError(state,
    1435            0 :                                   format("Calculated Pump_Efficiency % =Total_Efficiency % [{:.1R}] / Motor_Efficiency % [{:.1R}]",
    1436            0 :                                          TotalEffic * 100.0,
    1437            0 :                                          thisPump.MotorEffic * 100.0));
    1438            0 :                 ShowContinueError(
    1439              :                     state,
    1440            0 :                     format("Total_Efficiency % =(Rated_Volume_Flow_Rate [{:.3R}] * Rated_Pump_Head [{:.1R}] / Rated_Power_Use [{:.1R}]) * 100.",
    1441            0 :                            thisPump.NomVolFlowRate,
    1442            0 :                            thisPump.NomPumpHead,
    1443            0 :                            thisPump.NomPowerUse));
    1444         1143 :             } else if (thisPump.PumpEffic > 1.0) {
    1445            0 :                 ShowSevereError(state,
    1446            0 :                                 format("Check input.  Calculated Pump Efficiency={:.3R}% which is bigger than 100%, for pump={}",
    1447            0 :                                        thisPump.PumpEffic * 100.0,
    1448            0 :                                        thisPump.Name));
    1449            0 :                 ShowContinueError(state,
    1450            0 :                                   format("Calculated Pump_Efficiency % =Total_Efficiency % [{:.1R}] / Motor_Efficiency % [{:.1R}]",
    1451            0 :                                          TotalEffic * 100.0,
    1452            0 :                                          thisPump.MotorEffic * 100.0));
    1453            0 :                 ShowContinueError(
    1454              :                     state,
    1455            0 :                     format("Total_Efficiency % =(Rated_Volume_Flow_Rate [{:.3R}] * Rated_Pump_Head [{:.1R}] / Rated_Power_Use [{:.1R}]) * 100.",
    1456            0 :                            thisPump.NomVolFlowRate,
    1457            0 :                            thisPump.NomPumpHead,
    1458            0 :                            thisPump.NomPowerUse));
    1459            0 :                 ShowFatalError(state, "Errors found in Pump input");
    1460              :             }
    1461              :         } else {
    1462           35 :             ShowWarningError(state, format("Check input. Pump nominal power or motor efficiency is set to 0, for pump={}", thisPump.Name));
    1463              :         }
    1464              : 
    1465         1179 :         if (thisPump.NomVolFlowRate <= SmallWaterVolFlow) {
    1466            0 :             ShowWarningError(state, format("Check input. Pump nominal flow rate is set or calculated = 0, for pump={}", thisPump.Name));
    1467              :         }
    1468              : 
    1469         1179 :         if (thisPump.PumpControl == PumpControlType::Continuous) {
    1470              :             // reset flow priority appropriately (default was for Intermittent)
    1471           40 :             DataPlant::CompData::getPlantComponent(state, thisPump.plantLoc).FlowPriority = DataPlant::LoopFlowStatus::NeedyAndTurnsLoopOn;
    1472              :         }
    1473              : 
    1474         1179 :         thisPump.PumpOneTimeFlag = false;
    1475              :     }
    1476              : 
    1477              :     // HVAC Sizing Simulation resizing calls if needed
    1478     56466326 :     if (state.dataGlobal->RedoSizesHVACSimulation && !state.dataPlnt->PlantReSizingCompleted) {
    1479           44 :         SizePump(state, PumpNum);
    1480              :     }
    1481              : 
    1482              :     // Begin environment inits
    1483     56466326 :     if (thisPump.PumpInitFlag && state.dataGlobal->BeginEnvrnFlag) {
    1484         7237 :         if (thisPump.pumpType == PumpType::Cond) {
    1485           53 :             TempWaterDensity = Fluid::GetWater(state)->getDensity(state, Constant::InitConvTemp, RoutineName);
    1486           53 :             SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, StartTemp, 1.0, RoutineName);
    1487           53 :             thisPump.NomVolFlowRate = (thisPump.NomSteamVolFlowRate * SteamDensity) / TempWaterDensity;
    1488              : 
    1489              :             // set the maximum flow rate on the outlet node
    1490           53 :             mdotMax = thisPump.NomSteamVolFlowRate * SteamDensity;
    1491              :             // mdotMin = PumpEquip(PumpNum)%MinVolFlowRate      * SteamDensity
    1492              :             // On a pump the 'hardware min' (MassFlowRateMin) must be defined as zero and not
    1493              :             // confused with the desired pump operating scheme or the user specified
    1494              :             //'minimum flow rate'.  The user specified 'minimum flow rate' determines the minimum
    1495              :             // flow rate under normal operating conditions.  For cases when 'MaxAvail' on the pump
    1496              :             // inlet node actually less than the 'minimum flow rate' specified by the user, than a
    1497              :             // loop shutdown must  be triggered.
    1498           53 :             mdotMin = 0.0;
    1499           53 :             InitComponentNodes(state, mdotMin, mdotMax, InletNode, OutletNode);
    1500           53 :             thisPump.MassFlowRateMax = mdotMax;
    1501           53 :             thisPump.MassFlowRateMin = thisPump.MinVolFlowRate * SteamDensity;
    1502              : 
    1503              :         } else {
    1504         7184 :             auto &thisPumpPlant = state.dataPlnt->PlantLoop(thisPump.plantLoc.loopNum);
    1505         7184 :             TempWaterDensity = thisPumpPlant.glycol->getDensity(state, Constant::InitConvTemp, RoutineName);
    1506         7184 :             mdotMax = thisPump.NomVolFlowRate * TempWaterDensity;
    1507              :             // mdotMin = PumpEquip(PumpNum)%MinVolFlowRate * TempWaterDensity
    1508              :             // see note above
    1509         7184 :             mdotMin = 0.0;
    1510         7184 :             InitComponentNodes(state, mdotMin, mdotMax, InletNode, OutletNode);
    1511         7184 :             thisPump.MassFlowRateMax = mdotMax;
    1512         7184 :             thisPump.MassFlowRateMin = thisPump.MinVolFlowRate * TempWaterDensity;
    1513              :         }
    1514              :         // zero out report variables
    1515         7237 :         thisPump.Energy = 0.0;
    1516         7237 :         thisPump.Power = 0.0;
    1517         7237 :         new (&(state.dataPumps->PumpEquipReport(PumpNum))) ReportVars();
    1518         7237 :         thisPump.PumpInitFlag = false;
    1519              :     }
    1520              : 
    1521              :     // Reset the local environment flag for the next environment
    1522     56466326 :     if (!state.dataGlobal->BeginEnvrnFlag) {
    1523     56094693 :         thisPump.PumpInitFlag = true;
    1524              :     }
    1525              : 
    1526              :     // zero out module level working variables
    1527     56466326 :     auto const &daPumps = state.dataPumps;
    1528     56466326 :     daPumps->PumpMassFlowRate = 0.0;
    1529     56466326 :     daPumps->PumpHeattoFluid = 0.0;
    1530     56466326 :     daPumps->Power = 0.0;
    1531     56466326 :     daPumps->ShaftPower = 0.0;
    1532     56466326 : }
    1533              : 
    1534              : //*************************************************************************!
    1535              : 
    1536              : //*************************************************************************!
    1537              : 
    1538     18821701 : void SetupPumpMinMaxFlows(EnergyPlusData &state, int const LoopNum, int const PumpNum)
    1539              : {
    1540              : 
    1541              :     // SUBROUTINE INFORMATION:
    1542              :     //       AUTHOR:        Edwin Lee
    1543              :     //       DATE WRITTEN:  Aug 2010
    1544              :     //       MODIFIED       Based on the Flow control portion of what was previously Pumps::InitSimVars, by:
    1545              :     //                        Dan Fisher October 1998
    1546              :     //                        Richard Liesen July 2001
    1547              :     //                        July 2001, Rick Strand (implemented new pump controls)
    1548              :     //                        May 2009, Brent Griffith (added EMS override capability)
    1549              :     //                        B. Griffith, Nov 2011 Pump control: Intermittent vs Continuous
    1550              :     //       RE-ENGINEERED
    1551              : 
    1552              :     // PURPOSE OF THIS SUBROUTINE:
    1553              :     // This subroutine initializes the pump minAvail and maxAvail flow rates, and assigns them to the
    1554              :     //  outlet min/max avail according to inlet min/max constraints and zero flow request
    1555              :     // The loop solver then uses this information to set up the flow bounds for the loop side
    1556              :     //  for the current iteration.
    1557              : 
    1558              :     // METHODOLOGY EMPLOYED:
    1559              :     //  Design flow rate and user specified minimum flow rate is compared in the inlet node
    1560              :     //  min/maxavail.  The pump output is appropriately constrained.
    1561              :     //  Design flow is rated flow times schedule fraction
    1562              :     //  Inlet node max will represent the rated flow rate according to pump init routines.
    1563              :     //  These values are bounded by hardware min constraints on the inlet node, which is likely zero.
    1564              :     //  These values are also bounded by EMS overridable limit of max flow rate.
    1565              : 
    1566              :     // Using/Aliasing
    1567              :     using PlantPressureSystem::ResolveLoopFlowVsPressure;
    1568              :     using PlantUtilities::BoundValueToWithinTwoValues;
    1569              : 
    1570              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1571              :     int InletNode;  // pump inlet node number
    1572              :     int OutletNode; // pump outlet node number
    1573              :     Real64 InletNodeMax;
    1574              :     Real64 InletNodeMin;
    1575              :     Real64 PumpMassFlowRateMax; // max allowable flow rate at the pump
    1576              :     Real64 PumpMassFlowRateMin; // min allowable flow rate at the pump
    1577              :     Real64 PumpSchedFraction;
    1578              :     Real64 PumpOverridableMaxLimit;
    1579              :     Real64 PumpMassFlowRateMinLimit;
    1580              :     Real64 PumpSchedRPM; // Pump RPM Optional Input
    1581              : 
    1582     18821701 :     auto &thisPump = state.dataPumps->PumpEquip(PumpNum);
    1583              : 
    1584              :     // Inlet/Outlet Node Numbers
    1585     18821701 :     InletNode = thisPump.InletNodeNum;
    1586     18821701 :     OutletNode = thisPump.OutletNodeNum;
    1587     18821701 :     auto &thisInNode = state.dataLoopNodes->Node(InletNode);
    1588     18821701 :     auto &thisOutNode = state.dataLoopNodes->Node(OutletNode);
    1589              : 
    1590              :     // Inlet node Min/MaxAvail
    1591     18821701 :     InletNodeMax = thisInNode.MassFlowRateMaxAvail;
    1592     18821701 :     InletNodeMin = thisInNode.MassFlowRateMinAvail;
    1593              : 
    1594              :     // Retrieve the pump speed fraction from the pump schedule (if any)
    1595     18821701 :     PumpSchedFraction = (thisPump.flowRateSched != nullptr) ? std::clamp(thisPump.flowRateSched->getCurrentVal(), 0.0, 1.0) : 1.0;
    1596              : 
    1597              :     // User specified min/max mass flow rates for pump
    1598     18821701 :     PumpOverridableMaxLimit = thisPump.MassFlowRateMax;
    1599              : 
    1600              :     // override the user specified min to allow pump to turn off when no flow is required.
    1601     18821701 :     if (thisPump.LoopSolverOverwriteFlag) {
    1602      7214848 :         PumpMassFlowRateMinLimit = 0.0;
    1603              :     } else {
    1604     11606853 :         PumpMassFlowRateMinLimit = thisPump.MassFlowRateMin;
    1605              :     }
    1606              : 
    1607              :     // The pump outlet node Min/MaxAvail
    1608     18821701 :     PumpMassFlowRateMin = max(InletNodeMin, PumpMassFlowRateMinLimit);
    1609     18821701 :     PumpMassFlowRateMax = min(InletNodeMax, PumpOverridableMaxLimit * PumpSchedFraction);
    1610              : 
    1611              :     // Check for conflicts (MaxAvail < MinAvail)
    1612     18821701 :     if (PumpMassFlowRateMin > PumpMassFlowRateMax) { // the demand side wants to operate outside of the pump range
    1613              :         // shut the pump (and the loop) down
    1614          379 :         PumpMassFlowRateMin = 0.0;
    1615          379 :         PumpMassFlowRateMax = 0.0;
    1616              :         // Let the user know that his input file is overconstrained
    1617              :     }
    1618              : 
    1619     18821701 :     auto const &thisPumpPlant = state.dataPlnt->PlantLoop(thisPump.plantLoc.loopNum);
    1620              : 
    1621     18821701 :     switch (thisPump.pumpType) {
    1622     15033743 :     case PumpType::VarSpeed: {
    1623     15033743 :         if (thisPump.HasVFD) {
    1624         2340 :             switch (thisPump.VFD.VFDControlType) {
    1625         2340 :             case ControlTypeVFD::VFDManual: {
    1626              :                 // Evaluate the schedule if it exists and put the fraction into a local variable
    1627         2340 :                 PumpSchedRPM = thisPump.VFD.manualRPMSched->getCurrentVal();
    1628              :                 // Convert the RPM to rot/sec for calculation routine
    1629         2340 :                 thisPump.RotSpeed = PumpSchedRPM / 60.0;
    1630              :                 // Resolve the new mass flow rate based on current pressure characteristics
    1631         2340 :                 if (thisPumpPlant.UsePressureForPumpCalcs && thisPumpPlant.PressureSimType == DataPlant::PressSimType::FlowCorrection &&
    1632         1170 :                     thisPumpPlant.PressureDrop > 0.0) {
    1633              : 
    1634         1164 :                     state.dataPumps->PumpMassFlowRate = ResolveLoopFlowVsPressure(state,
    1635              :                                                                                   thisPump.plantLoc.loopNum,
    1636         1164 :                                                                                   state.dataLoopNodes->Node(thisPump.InletNodeNum).MassFlowRate,
    1637              :                                                                                   thisPump.PressureCurve_Index,
    1638              :                                                                                   thisPump.RotSpeed,
    1639              :                                                                                   thisPump.ImpellerDiameter,
    1640              :                                                                                   thisPump.MinPhiValue,
    1641              :                                                                                   thisPump.MaxPhiValue);
    1642              : 
    1643         1164 :                     PumpMassFlowRateMax = state.dataPumps->PumpMassFlowRate;
    1644         1164 :                     PumpMassFlowRateMin = state.dataPumps->PumpMassFlowRate;
    1645              :                 }
    1646         2340 :             } break;
    1647            0 :             case ControlTypeVFD::VFDAutomatic: {
    1648            0 :                 if (thisPumpPlant.UsePressureForPumpCalcs && thisPumpPlant.PressureSimType == DataPlant::PressSimType::FlowCorrection &&
    1649            0 :                     thisPumpPlant.PressureDrop > 0.0) {
    1650              : 
    1651            0 :                     GetRequiredMassFlowRate(state,
    1652              :                                             LoopNum,
    1653              :                                             PumpNum,
    1654            0 :                                             state.dataLoopNodes->Node(thisPump.InletNodeNum).MassFlowRate,
    1655            0 :                                             state.dataPumps->PumpMassFlowRate,
    1656              :                                             PumpMassFlowRateMin,
    1657              :                                             PumpMassFlowRateMax);
    1658              :                 }
    1659            0 :             } break;
    1660            0 :             default:
    1661            0 :                 break;
    1662              :             } // VFDControlType
    1663              :         }
    1664              : 
    1665     15033743 :         if (thisPump.PumpControl == PumpControlType::Continuous) {
    1666        60127 :             thisInNode.MassFlowRateRequest = PumpMassFlowRateMin;
    1667              :         }
    1668     15033743 :     } break;
    1669      3646277 :     case PumpType::ConSpeed: {
    1670      3646277 :         if (thisPump.PumpControl == PumpControlType::Continuous) {
    1671       549291 :             PumpMassFlowRateMin = PumpMassFlowRateMax;
    1672       549291 :             thisInNode.MassFlowRateRequest = PumpMassFlowRateMin;
    1673              :         }
    1674              : 
    1675              :         // Override (lock down flow) for pressure drop if applicable
    1676      3646277 :         if (thisPump.plantLoc.loopNum > 0) {
    1677      3646277 :             if (thisPumpPlant.UsePressureForPumpCalcs && thisPumpPlant.PressureSimType == DataPlant::PressSimType::FlowCorrection &&
    1678         2925 :                 thisPumpPlant.PressureDrop > 0.0) {
    1679         2910 :                 state.dataPumps->PumpMassFlowRate = ResolveLoopFlowVsPressure(state,
    1680              :                                                                               thisPump.plantLoc.loopNum,
    1681         2910 :                                                                               state.dataLoopNodes->Node(thisPump.InletNodeNum).MassFlowRate,
    1682              :                                                                               thisPump.PressureCurve_Index,
    1683              :                                                                               thisPump.RotSpeed,
    1684              :                                                                               thisPump.ImpellerDiameter,
    1685              :                                                                               thisPump.MinPhiValue,
    1686              :                                                                               thisPump.MaxPhiValue);
    1687         2910 :                 PumpMassFlowRateMax = state.dataPumps->PumpMassFlowRate;
    1688         2910 :                 PumpMassFlowRateMin = state.dataPumps->PumpMassFlowRate;
    1689              :             }
    1690              :         }
    1691      3646277 :     } break;
    1692       141681 :     default:
    1693       141681 :         break;
    1694              :     }
    1695              : 
    1696              :     // Override pump operation based on System Availability Managers, should be done elsewhere?  I suppose this should be OK though
    1697     18821701 :     if (allocated(state.dataAvail->PlantAvailMgr)) {
    1698     18821701 :         if (state.dataAvail->PlantAvailMgr(LoopNum).availStatus == Avail::Status::ForceOff) {
    1699       248526 :             PumpMassFlowRateMax = 0.0;
    1700       248526 :             PumpMassFlowRateMin = 0.0;
    1701              :         }
    1702              :     }
    1703              : 
    1704              :     // Check if EMS is overriding flow
    1705     18821701 :     if (thisPump.EMSMassFlowOverrideOn) {
    1706       148632 :         PumpMassFlowRateMax = thisPump.EMSMassFlowValue;
    1707       148632 :         PumpMassFlowRateMin = thisPump.EMSMassFlowValue;
    1708              :     }
    1709              : 
    1710              :     // Update outlet node to allow loop solver to get data
    1711              :     // could avoid this by passing data in/out to avoid putting things on nodes
    1712     18821701 :     thisOutNode.MassFlowRateMinAvail = PumpMassFlowRateMin;
    1713     18821701 :     thisOutNode.MassFlowRateMaxAvail = PumpMassFlowRateMax;
    1714     18821701 : }
    1715              : 
    1716     37644625 : void CalcPumps(EnergyPlusData &state, int const PumpNum, Real64 const FlowRequest, bool &PumpRunning)
    1717              : {
    1718              : 
    1719              :     // SUBROUTINE INFORMATION:
    1720              :     //       AUTHOR         Dan Fisher
    1721              :     //       DATE WRITTEN   Sept. 1998
    1722              :     //       MODIFIED       July 2001, Rick Strand
    1723              :     //       RE-ENGINEERED  Sept 2010, Edwin Lee
    1724              : 
    1725              :     // PURPOSE OF THIS SUBROUTINE:
    1726              :     // This subroutines simulates a pump following
    1727              :     // the methodology oulined in ASHRAE's secondary toolkit.
    1728              : 
    1729              :     // METHODOLOGY EMPLOYED:
    1730              :     // Calculates power and updates other pump things.
    1731              : 
    1732              :     // REFERENCES:
    1733              :     // HVAC 2 Toolkit:  A Toolkit for Secondary HVAC System
    1734              :     // Energy Calculations, ASHRAE, 1993, pp2-10 to 2-15
    1735              : 
    1736              :     // Using/Aliasing
    1737              :     using PlantUtilities::SetComponentFlowRate;
    1738              : 
    1739              :     // SUBROUTINE PARAMETER DEFINITIONS:
    1740              :     static constexpr std::string_view RoutineName("PlantPumps:CalcPumps: ");
    1741              : 
    1742              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1743              :     int InletNode;
    1744              :     int OutletNode;
    1745              :     Real64 LoopDensity;
    1746     37644625 :     Real64 VolFlowRate = 0.0;
    1747              :     Real64 PartLoadRatio;
    1748              :     Real64 FracFullLoadPower;
    1749              :     Real64 FullLoadVolFlowRate;
    1750              :     Real64 PartLoadVolFlowRate;
    1751              :     Real64 FullLoadPower;
    1752              :     Real64 FullLoadPowerRatio;
    1753              :     Real64 TotalEffic;
    1754              :     PumpType pumpType;
    1755              :     Real64 RotSpeed_Min;
    1756              :     Real64 RotSpeed_Max;
    1757              :     Real64 PumpActualRPMValueOne;
    1758              :     Real64 PumpActualRPMValueTwo;
    1759              : 
    1760     37644625 :     auto &daPumps = state.dataPumps;
    1761     37644625 :     auto &thisPump = state.dataPumps->PumpEquip(PumpNum);
    1762              : 
    1763     37644625 :     InletNode = thisPump.InletNodeNum;
    1764     37644625 :     OutletNode = thisPump.OutletNodeNum;
    1765     37644625 :     pumpType = thisPump.pumpType;
    1766              : 
    1767     37644625 :     auto &thisInNode = state.dataLoopNodes->Node(InletNode);
    1768     37644625 :     auto &thisOutNode = state.dataLoopNodes->Node(OutletNode);
    1769              : 
    1770              :     //****************************!
    1771              :     //** SETTING PUMP FLOW RATE **!
    1772              :     //****************************!
    1773              :     // So the loop solver always passes in the full loop side flow request to each pump called
    1774              :     // The pump will try to use this value according to its inlet conditions via the SetComponentFlowRate routine.
    1775              :     // If the loop solver is doing branch pumps, then individual parallel branch inlet nodes would have been previously
    1776              :     // constrained, so even though we pass in a full flow request, each pump will "pull down" to the min/max avail.
    1777              :     // Also, on flowlock == locked, we will just use the inlet node flow rate
    1778              :     // The flow resolver can take care of argument resolution beyond that.
    1779              :     // For a typical situation, the flow request should be within the values of min/max avail, so the pump will get this flow rate.
    1780     37644625 :     if (FlowRequest > DataBranchAirLoopPlant::MassFlowTolerance) {
    1781     20483989 :         daPumps->PumpMassFlowRate = FlowRequest;
    1782              :     } else {
    1783     17160636 :         daPumps->PumpMassFlowRate = 0.0;
    1784              :     }
    1785              : 
    1786              :     // For variable speed branch pumps, with other components
    1787              :     //  on the branch, we are not going to assign a request.
    1788              :     // Other components on this branch will request flow for this branch
    1789              : 
    1790              :     //  ! If this is a variable speed pump
    1791     37644625 :     if (thisPump.pumpType == PumpType::VarSpeed || thisPump.pumpType == PumpType::Bank_VarSpeed || thisPump.pumpType == PumpType::Cond) {
    1792     30337332 :         if (DataPlant::CompData::getPlantComponent(state, thisPump.plantLoc).FlowCtrl == DataBranchAirLoopPlant::ControlType::SeriesActive) {
    1793       631338 :             daPumps->PumpMassFlowRate = 0.0;
    1794              :         }
    1795              :     }
    1796              : 
    1797              :     // bound flow request by pump max limit, the Flow Request is total loop flow and if this is a branch pump that is not appropriate
    1798     37644625 :     daPumps->PumpMassFlowRate = min(thisPump.MassFlowRateMax, daPumps->PumpMassFlowRate);
    1799     37644625 :     daPumps->PumpMassFlowRate = max(thisPump.MassFlowRateMin, daPumps->PumpMassFlowRate);
    1800              : 
    1801     37644625 :     SetComponentFlowRate(state, daPumps->PumpMassFlowRate, InletNode, OutletNode, thisPump.plantLoc);
    1802              : 
    1803     37644625 :     auto &thisPumpPlant = state.dataPlnt->PlantLoop(thisPump.plantLoc.loopNum);
    1804              : 
    1805              :     // Get RPM value for reporting as output
    1806              :     // RPM is calculated using pump affinity laws for rotation speed
    1807     37644625 :     if (thisPumpPlant.UsePressureForPumpCalcs && thisPump.HasVFD) {
    1808         2340 :         RotSpeed_Min = thisPump.VFD.minRPMSched ? thisPump.VFD.minRPMSched->getCurrentVal() : 0.0;
    1809         2340 :         RotSpeed_Max = thisPump.VFD.maxRPMSched ? thisPump.VFD.maxRPMSched->getCurrentVal() : 0.0;
    1810         2340 :         if (thisPump.PumpMassFlowRateMaxRPM < DataBranchAirLoopPlant::MassFlowTolerance ||
    1811            0 :             thisPump.PumpMassFlowRateMinRPM < DataBranchAirLoopPlant::MassFlowTolerance) {
    1812         2340 :             thisPump.VFD.PumpActualRPM = 0.0;
    1813              :         } else {
    1814            0 :             PumpActualRPMValueOne = (daPumps->PumpMassFlowRate / thisPump.PumpMassFlowRateMaxRPM) * RotSpeed_Max;
    1815            0 :             PumpActualRPMValueTwo = (daPumps->PumpMassFlowRate / thisPump.PumpMassFlowRateMinRPM) * RotSpeed_Min;
    1816            0 :             thisPump.VFD.PumpActualRPM = (PumpActualRPMValueOne + PumpActualRPMValueTwo) / 2;
    1817              :         }
    1818              :     }
    1819              : 
    1820              :     //****************************!
    1821              :     //** DETERMINE IF PUMP IS ON *!
    1822              :     //****************************!
    1823              :     // Since we don't allow series pumping, if there is ANY flow rate for this pump, THIS PUMP is driving the flow!  Therefore...
    1824     37644625 :     PumpRunning = (daPumps->PumpMassFlowRate > DataBranchAirLoopPlant::MassFlowTolerance);
    1825              : 
    1826              :     //****************************!
    1827              :     //** UPDATE PUMP BANK USAGE **!
    1828              :     //****************************!
    1829     37644625 :     switch (thisPump.pumpType) {
    1830       161101 :     case PumpType::Bank_VarSpeed:
    1831              :     case PumpType::Bank_ConSpeed: {
    1832              :         // previously, pumps did whatever they wanted
    1833              :         // because of this a constant speed pump bank could adjust the flow rate as-desired
    1834              :         //  even if it was not allowed
    1835              :         // since pumps now must behave nicely like all other components, the calculation of number
    1836              :         //  of running pumps in a pump bank is the same for both bank types
    1837              :         // the pumps are loaded sequentially, and the last pump can have full or non-full part load
    1838              :         //  status...this is just how it works now.  The pump cannot *bump* up the flow on the loop
    1839              :         //  to make sure the last running pump is fully loaded anymore for constant speed pumps...sorry
    1840       161101 :         if (daPumps->PumpMassFlowRate >= thisPump.MassFlowRateMax) {
    1841              :             // running full on
    1842            0 :             daPumps->NumPumpsRunning = thisPump.NumPumpsInBank;
    1843              :         } else {
    1844              :             // running at some sort of part load
    1845       161101 :             daPumps->NumPumpsRunning = CEILING((daPumps->PumpMassFlowRate / (thisPump.MassFlowRateMax) * thisPump.NumPumpsInBank));
    1846       161101 :             daPumps->NumPumpsRunning = min(daPumps->NumPumpsRunning, thisPump.NumPumpsInBank);
    1847              :         }
    1848       161101 :     } break;
    1849     37483524 :     default:
    1850     37483524 :         break;
    1851              :     }
    1852              : 
    1853              :     //****************************!
    1854              :     //***** EXIT IF NO FLOW ******!
    1855              :     //****************************!
    1856     37644625 :     if (daPumps->PumpMassFlowRate <= DataBranchAirLoopPlant::MassFlowTolerance) {
    1857     17271724 :         thisOutNode.Temp = thisInNode.Temp;
    1858     17271724 :         thisOutNode.Press = thisInNode.Press;
    1859     17271724 :         thisOutNode.Quality = thisInNode.Quality;
    1860     17271724 :         return;
    1861              :     }
    1862              : 
    1863              :     // density used for volumetric flow calculations
    1864     20372901 :     LoopDensity = thisPumpPlant.glycol->getDensity(state, thisInNode.Temp, RoutineName);
    1865              : 
    1866              :     //****************************!
    1867              :     //***** CALCULATE POWER (1) **!
    1868              :     //****************************!
    1869     20372901 :     switch (pumpType) {
    1870     20282695 :     case PumpType::ConSpeed:
    1871              :     case PumpType::VarSpeed:
    1872              :     case PumpType::Cond: {
    1873     20282695 :         VolFlowRate = daPumps->PumpMassFlowRate / LoopDensity;
    1874     20282695 :         PartLoadRatio = min(1.0, (VolFlowRate / thisPump.NomVolFlowRate));
    1875     20282695 :         FracFullLoadPower = thisPump.PartLoadCoef[0] + thisPump.PartLoadCoef[1] * PartLoadRatio + thisPump.PartLoadCoef[2] * pow_2(PartLoadRatio) +
    1876     20282695 :                             thisPump.PartLoadCoef[3] * pow_3(PartLoadRatio);
    1877     20282695 :         daPumps->Power = FracFullLoadPower * thisPump.NomPowerUse;
    1878              : 
    1879     20282695 :     } break;
    1880        90206 :     case PumpType::Bank_ConSpeed:
    1881              :     case PumpType::Bank_VarSpeed: {
    1882              :         // now just assume the last one is (or is not) running at part load
    1883              :         // if it is actually at full load, the calculations work out to PLR = 1
    1884              :         // for the last pump, so all is OK
    1885        90206 :         daPumps->NumPumpsFullLoad = daPumps->NumPumpsRunning - 1;
    1886        90206 :         FullLoadVolFlowRate = thisPump.NomVolFlowRate / thisPump.NumPumpsInBank;
    1887        90206 :         PartLoadVolFlowRate = daPumps->PumpMassFlowRate / LoopDensity - FullLoadVolFlowRate * daPumps->NumPumpsFullLoad;
    1888        90206 :         FullLoadPower = thisPump.NomPowerUse / thisPump.NumPumpsInBank;
    1889        90206 :         FullLoadPowerRatio = thisPump.PartLoadCoef[0] + thisPump.PartLoadCoef[1] + thisPump.PartLoadCoef[2] + thisPump.PartLoadCoef[3];
    1890        90206 :         PartLoadRatio = min(1.0, (PartLoadVolFlowRate / FullLoadVolFlowRate));
    1891        90206 :         FracFullLoadPower = thisPump.PartLoadCoef[0] + thisPump.PartLoadCoef[1] * PartLoadRatio + thisPump.PartLoadCoef[2] * pow_2(PartLoadRatio) +
    1892        90206 :                             thisPump.PartLoadCoef[3] * pow_3(PartLoadRatio);
    1893        90206 :         daPumps->Power = (FullLoadPowerRatio * daPumps->NumPumpsFullLoad + FracFullLoadPower) * FullLoadPower;
    1894        90206 :         if (thisPump.EMSPressureOverrideOn) {
    1895            0 :             VolFlowRate = PartLoadVolFlowRate;
    1896              :         }
    1897        90206 :     } break;
    1898            0 :     default: {
    1899            0 :         assert(false);
    1900              :     } break;
    1901              :     }
    1902              : 
    1903              :     //****************************!
    1904              :     //***** CALCULATE POWER (2) **!
    1905              :     //****************************!
    1906     20372901 :     if (daPumps->Power < 0.0) {
    1907            0 :         if (thisPump.PowerErrIndex1 == 0) {
    1908            0 :             ShowWarningMessage(
    1909              :                 state,
    1910            0 :                 format("{} Calculated Pump Power < 0, Type={}, Name={}", RoutineName, pumpTypeIDFNames[static_cast<int>(pumpType)], thisPump.Name));
    1911            0 :             ShowContinueErrorTimeStamp(state, "");
    1912            0 :             ShowContinueError(state, format("...PartLoadRatio=[{:.4R}], Fraction Full Load Power={:.4R}]", PartLoadRatio, FracFullLoadPower));
    1913            0 :             ShowContinueError(state, "...Power is set to 0 for continuing the simulation.");
    1914            0 :             ShowContinueError(state, "...Pump coefficients should be checked for producing this negative value.");
    1915              :         }
    1916            0 :         daPumps->Power = 0.0;
    1917            0 :         ShowRecurringWarningErrorAtEnd(
    1918              :             state,
    1919            0 :             format("{} Calculated Pump Power < 0, {}, Name={}, PLR=", RoutineName, pumpTypeIDFNames[static_cast<int>(pumpType)], thisPump.Name),
    1920            0 :             thisPump.PowerErrIndex1,
    1921              :             PartLoadRatio,
    1922              :             PartLoadRatio);
    1923            0 :         ShowRecurringContinueErrorAtEnd(state, "...Fraction Full Load Power=", thisPump.PowerErrIndex2, FracFullLoadPower, FracFullLoadPower);
    1924              :     }
    1925              : 
    1926              :     //****************************!
    1927              :     //***** CALCULATE POWER (3) **!
    1928              :     //****************************!
    1929              :     // Now if we are doing pressure-based simulation, then we have a means to calculate power exactly based on current
    1930              :     // simulation conditions (flow rate and pressure drop) along with knowledge about pump impeller and motor efficiencies
    1931              :     // Thus we will override the power that was calculated based on nominal values with the corrected pressure-based power
    1932     20372901 :     if (thisPump.plantLoc.loopNum > 0) {
    1933     20372901 :         if (thisPumpPlant.UsePressureForPumpCalcs) {
    1934        10476 :             TotalEffic = thisPump.PumpEffic * thisPump.MotorEffic;
    1935              :             // Efficiency errors are caught previously, but it doesn't hurt to add another catch before dividing by zero!!!
    1936        10476 :             if (TotalEffic == 0.0) {
    1937            0 :                 ShowSevereError(state,
    1938            0 :                                 format("{} Plant pressure simulation encountered a pump with zero efficiency: {}", RoutineName, thisPump.Name));
    1939            0 :                 ShowContinueError(state, "Check efficiency inputs for this pump component.");
    1940            0 :                 ShowFatalError(state, "Errors in plant calculation would result in divide-by-zero cause program termination.");
    1941              :             }
    1942        10476 :             daPumps->Power = VolFlowRate * thisPumpPlant.PressureDrop / TotalEffic;
    1943              :         }
    1944              :     }
    1945              : 
    1946              :     // if user has specified a pressure value, then use it, same as for pressure-based simulation
    1947     20372901 :     if (thisPump.EMSPressureOverrideOn) {
    1948          744 :         TotalEffic = thisPump.PumpEffic * thisPump.MotorEffic;
    1949              :         // Efficiency errors are caught previously, but it doesn't hurt to add another catch before dividing by zero!!!
    1950          744 :         if (TotalEffic == 0.0) {
    1951            0 :             ShowSevereError(state, format("{} Plant pump simulation encountered a pump with zero efficiency: {}", RoutineName, thisPump.Name));
    1952            0 :             ShowContinueError(state, "Check efficiency inputs for this pump component.");
    1953            0 :             ShowFatalError(state, "Errors in plant calculation would result in divide-by-zero cause program termination.");
    1954              :         }
    1955          744 :         daPumps->Power = VolFlowRate * thisPump.EMSPressureOverrideValue / TotalEffic;
    1956              :     }
    1957              : 
    1958              :     //****************************!
    1959              :     //***** CALCULATE POWER (4) **!
    1960              :     //****************************!
    1961              :     // This adds the pump heat based on User input for the pump
    1962              :     // We assume that all of the heat ends up in the fluid eventually since this is a closed loop
    1963     20372901 :     daPumps->ShaftPower = daPumps->Power * thisPump.MotorEffic;
    1964     20372901 :     daPumps->PumpHeattoFluid = daPumps->ShaftPower + (daPumps->Power - daPumps->ShaftPower) * thisPump.FracMotorLossToFluid;
    1965              : 
    1966              :     //****************************!
    1967              :     //***** UPDATE INFORMATION ***!
    1968              :     //****************************!
    1969              :     // Update data structure variables
    1970     20372901 :     thisPump.Power = daPumps->Power;
    1971              : 
    1972              :     // Update outlet node conditions
    1973     20372901 :     thisOutNode.Temp = thisInNode.Temp;
    1974     20372901 :     thisOutNode.Press = thisInNode.Press;
    1975     20372901 :     thisOutNode.Quality = thisInNode.Quality;
    1976              : }
    1977              : 
    1978         1223 : void SizePump(EnergyPlusData &state, int const PumpNum)
    1979              : {
    1980              : 
    1981              :     // SUBROUTINE INFORMATION:
    1982              :     //       AUTHOR         Fred Buhl
    1983              :     //       DATE WRITTEN   December 2001
    1984              :     //       MODIFIED       na
    1985              :     //       RE-ENGINEERED  na
    1986              : 
    1987              :     // PURPOSE OF THIS SUBROUTINE:
    1988              :     // This subroutine is for sizing Pump Components for which flow rates have not been
    1989              :     // specified in the input.
    1990              : 
    1991              :     // METHODOLOGY EMPLOYED:
    1992              :     // Obtains flow rates from the plant sizing array.
    1993              : 
    1994              :     // SUBROUTINE PARAMETER DEFINITIONS:
    1995         1223 :     Real64 constexpr StartTemp(100.0); // Standard Temperature across code to calculated Steam density
    1996              :     static constexpr std::string_view RoutineName("PlantPumps::InitSimVars ");
    1997              :     static constexpr std::string_view RoutineNameSizePumps("SizePumps");
    1998              : 
    1999              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2000              :     int PlantSizNum; // index of Plant Sizing array
    2001              :     bool ErrorsFound;
    2002         1223 :     Real64 TotalEffic = 0.0; // pump total efficiency
    2003              :     Real64 PumpSizFac;       // pump sizing factor
    2004              :     Real64 SteamDensity;
    2005              :     Real64 TempWaterDensity;
    2006         1223 :     int DummyWaterIndex(1);
    2007              :     Real64 DesVolFlowRatePerBranch; // local temporary for split of branch pumps
    2008              : 
    2009         1223 :     auto &thisPump = state.dataPumps->PumpEquip(PumpNum);
    2010         1223 :     bool thisOkToReport = state.dataPlnt->PlantFinalSizesOkayToReport;
    2011              : 
    2012              :     // Calculate density at InitConvTemp once here, to remove RhoH2O calls littered throughout
    2013         1223 :     if (thisPump.plantLoc.loopNum > 0) {
    2014         1223 :         auto &thisPumpPlant = state.dataPlnt->PlantLoop(thisPump.plantLoc.loopNum);
    2015         1223 :         TempWaterDensity = thisPumpPlant.glycol->getDensity(state, Constant::InitConvTemp, RoutineName);
    2016              :     } else {
    2017            0 :         TempWaterDensity = Fluid::GetWater(state)->getDensity(state, Constant::InitConvTemp, RoutineName);
    2018              :     }
    2019              : 
    2020         1223 :     PlantSizNum = 0;
    2021         1223 :     PumpSizFac = 1.0;
    2022         1223 :     ErrorsFound = false;
    2023              : 
    2024         1223 :     if (thisPump.plantLoc.loopNum > 0) {
    2025         1223 :         PlantSizNum = state.dataPlnt->PlantLoop(thisPump.plantLoc.loopNum).PlantSizNum;
    2026              :     }
    2027              :     // use pump sizing factor stored in plant sizing data structure
    2028         1223 :     if (PlantSizNum > 0) {
    2029          859 :         PumpSizFac = state.dataSize->PlantSizData(PlantSizNum).PlantSizFac;
    2030              :     } else {
    2031              :         // might be able to remove this next block
    2032          364 :         if (thisPump.plantLoc.loopNum > 0) {
    2033          725 :             for (DataPlant::LoopSideLocation Side : DataPlant::LoopSideKeys) {
    2034          725 :                 auto &thisPumpLoop = state.dataPlnt->PlantLoop(thisPump.plantLoc.loopNum).LoopSide(Side);
    2035         2532 :                 for (int BranchNum = 1; BranchNum <= thisPumpLoop.TotalBranches; ++BranchNum) {
    2036         2171 :                     auto &thisPumpBranch = thisPumpLoop.Branch(BranchNum);
    2037         3985 :                     for (int CompNum = 1; CompNum <= thisPumpBranch.TotalComponents; ++CompNum) {
    2038         2178 :                         auto const &thisPumpComp = thisPumpBranch.Comp(CompNum);
    2039         2178 :                         if (thisPump.InletNodeNum == thisPumpComp.NodeNumIn && thisPump.OutletNodeNum == thisPumpComp.NodeNumOut) {
    2040          364 :                             if (thisPumpBranch.PumpSizFac > 0.0) {
    2041          364 :                                 PumpSizFac = thisPumpBranch.PumpSizFac;
    2042              :                             } else {
    2043            0 :                                 PumpSizFac = 1.0;
    2044              :                             }
    2045          364 :                             goto SideLoop_exit;
    2046              :                         }
    2047              :                     }
    2048              :                 }
    2049              :             }
    2050          364 :         SideLoop_exit:;
    2051              :         }
    2052              :     }
    2053              : 
    2054         1223 :     if (thisPump.NomVolFlowRateWasAutoSized) {
    2055              : 
    2056          775 :         if (PlantSizNum > 0) {
    2057          775 :             auto &thisPumpPlant = state.dataPlnt->PlantLoop(thisPump.plantLoc.loopNum);
    2058          775 :             auto &thisPlantSize = state.dataSize->PlantSizData(PlantSizNum);
    2059          775 :             if (thisPlantSize.DesVolFlowRate >= SmallWaterVolFlow) {
    2060          775 :                 if (!thisPumpPlant.LoopSide(thisPump.plantLoc.loopSideNum).BranchPumpsExist) {
    2061              :                     // size pump to full flow of plant loop
    2062          763 :                     if (thisPump.pumpType == PumpType::Cond) {
    2063            6 :                         TempWaterDensity = Fluid::GetWater(state)->getDensity(state, Constant::InitConvTemp, RoutineName);
    2064            6 :                         SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, StartTemp, 1.0, RoutineNameSizePumps);
    2065            6 :                         thisPump.NomSteamVolFlowRate = thisPlantSize.DesVolFlowRate * PumpSizFac;
    2066            6 :                         thisPump.NomVolFlowRate = thisPump.NomSteamVolFlowRate * SteamDensity / TempWaterDensity;
    2067              :                     } else {
    2068          757 :                         thisPump.NomVolFlowRate = thisPlantSize.DesVolFlowRate * PumpSizFac;
    2069              :                     }
    2070              :                 } else {
    2071              :                     // Distribute sizes evenly across all branch pumps
    2072           12 :                     DesVolFlowRatePerBranch = thisPlantSize.DesVolFlowRate / thisPumpPlant.LoopSide(thisPump.plantLoc.loopSideNum).TotalPumps;
    2073           12 :                     if (thisPump.pumpType == PumpType::Cond) {
    2074            0 :                         TempWaterDensity = Fluid::GetWater(state)->getDensity(state, Constant::InitConvTemp, RoutineName);
    2075            0 :                         SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, StartTemp, 1.0, RoutineNameSizePumps);
    2076            0 :                         thisPump.NomSteamVolFlowRate = DesVolFlowRatePerBranch * PumpSizFac;
    2077            0 :                         thisPump.NomVolFlowRate = thisPump.NomSteamVolFlowRate * SteamDensity / TempWaterDensity;
    2078              :                     } else {
    2079           12 :                         thisPump.NomVolFlowRate = DesVolFlowRatePerBranch * PumpSizFac;
    2080              :                     }
    2081              :                 }
    2082              : 
    2083              :             } else {
    2084            0 :                 if (thisOkToReport) {
    2085            0 :                     thisPump.NomVolFlowRate = 0.0;
    2086            0 :                     ShowWarningError(
    2087              :                         state,
    2088            0 :                         format("SizePump: Calculated Pump Nominal Volume Flow Rate=[{:.2R}] is too small. Set to 0.0", thisPlantSize.DesVolFlowRate));
    2089            0 :                     ShowContinueError(state, format("..occurs for Pump={}", thisPump.Name));
    2090              :                 }
    2091              :             }
    2092          775 :             if (thisOkToReport) {
    2093         1464 :                 BaseSizer::reportSizerOutput(
    2094          732 :                     state, pumpTypeIDFNames[static_cast<int>(thisPump.pumpType)], thisPump.Name, "Design Flow Rate [m3/s]", thisPump.NomVolFlowRate);
    2095              :             }
    2096          775 :             if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    2097           86 :                 BaseSizer::reportSizerOutput(state,
    2098           43 :                                              pumpTypeIDFNames[static_cast<int>(thisPump.pumpType)],
    2099              :                                              thisPump.Name,
    2100              :                                              "Initial Design Flow Rate [m3/s]",
    2101              :                                              thisPump.NomVolFlowRate);
    2102              :             }
    2103              :         } else {
    2104            0 :             if (thisOkToReport) {
    2105            0 :                 ShowSevereError(state, "Autosizing of plant loop pump flow rate requires a loop Sizing:Plant object");
    2106            0 :                 ShowContinueError(state, format("Occurs in plant pump object={}", thisPump.Name));
    2107            0 :                 ErrorsFound = true;
    2108              :             }
    2109              :         }
    2110              :     }
    2111              : 
    2112              :     // Note that autocalculation of power is based on nominal volume flow, regardless of whether the flow was
    2113              :     //  auto-sized or manually sized.  Thus, this must go after the flow sizing block above.
    2114         1223 :     if (thisPump.NomPowerUseWasAutoSized) {
    2115          784 :         if (thisPump.NomVolFlowRate >= SmallWaterVolFlow) {
    2116          784 :             switch (thisPump.powerSizingMethod) {
    2117              : 
    2118           25 :             case PowerSizingMethod::SizePowerPerFlow: {
    2119           25 :                 TotalEffic = thisPump.NomPumpHead / thisPump.powerPerFlowScalingFactor;
    2120           25 :                 break;
    2121              :             }
    2122              : 
    2123          759 :             case PowerSizingMethod::SizePowerPerFlowPerPressure: {
    2124          759 :                 TotalEffic = (1 / thisPump.powerPerFlowPerPressureScalingFactor) * thisPump.MotorEffic;
    2125          759 :                 break;
    2126              :             }
    2127            0 :             default:
    2128            0 :                 assert(false);
    2129              :             }
    2130              : 
    2131          784 :             thisPump.NomPowerUse = (thisPump.NomPumpHead * thisPump.NomVolFlowRate) / TotalEffic;
    2132              :         } else {
    2133            0 :             thisPump.NomPowerUse = 0.0;
    2134              :         }
    2135          784 :         if (thisOkToReport) {
    2136         1482 :             BaseSizer::reportSizerOutput(
    2137          741 :                 state, pumpTypeIDFNames[static_cast<int>(thisPump.pumpType)], thisPump.Name, "Design Power Consumption [W]", thisPump.NomPowerUse);
    2138              :         }
    2139          784 :         if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    2140           86 :             BaseSizer::reportSizerOutput(state,
    2141           43 :                                          pumpTypeIDFNames[static_cast<int>(thisPump.pumpType)],
    2142              :                                          thisPump.Name,
    2143              :                                          "Initial Design Power Consumption [W]",
    2144              :                                          thisPump.NomPowerUse);
    2145              :         }
    2146              :     }
    2147              : 
    2148         1223 :     if (thisPump.minVolFlowRateWasAutosized) {
    2149           19 :         thisPump.MinVolFlowRate = thisPump.NomVolFlowRate * thisPump.MinVolFlowRateFrac;
    2150           19 :         if (thisOkToReport) {
    2151           30 :             BaseSizer::reportSizerOutput(state,
    2152           15 :                                          pumpTypeIDFNames[static_cast<int>(thisPump.pumpType)],
    2153              :                                          thisPump.Name,
    2154              :                                          "Design Minimum Flow Rate [m3/s]",
    2155              :                                          thisPump.MinVolFlowRate);
    2156              :         }
    2157           19 :         if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    2158            8 :             BaseSizer::reportSizerOutput(state,
    2159            4 :                                          pumpTypeIDFNames[static_cast<int>(thisPump.pumpType)],
    2160              :                                          thisPump.Name,
    2161              :                                          "Initial Design Minimum Flow Rate [m3/s]",
    2162              :                                          thisPump.MinVolFlowRate);
    2163              :         }
    2164              :     }
    2165              : 
    2166         1223 :     if (thisOkToReport) {
    2167         1179 :         PumpDataForTable(state, PumpNum);
    2168              :     }
    2169              : 
    2170         1223 :     if (ErrorsFound) {
    2171            0 :         ShowFatalError(state, "Preceding sizing errors cause program termination");
    2172              :     }
    2173         1223 : }
    2174              : 
    2175     37644625 : void ReportPumps(EnergyPlusData &state, int const PumpNum)
    2176              : {
    2177              : 
    2178              :     // SUBROUTINE INFORMATION:
    2179              :     //       AUTHOR:          Dan Fisher
    2180              :     //       DATE WRITTEN:    October 1998
    2181              :     //       MODIFIED         July 2001, Rick Strand (revision of pump module)
    2182              :     //       RE-ENGINEERED    na
    2183              : 
    2184              :     // PURPOSE OF THIS SUBROUTINE:
    2185              :     // This subroutine sets the pump reporting variables.
    2186              : 
    2187              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2188              :     int OutletNode;    // pump outlet node number
    2189              :     PumpType PumpType; // Current pump type
    2190              : 
    2191     37644625 :     auto &thisPump = state.dataPumps->PumpEquip(PumpNum);
    2192     37644625 :     auto &thisPumpRep = state.dataPumps->PumpEquipReport(PumpNum);
    2193              : 
    2194     37644625 :     PumpType = thisPump.pumpType;
    2195     37644625 :     OutletNode = thisPump.OutletNodeNum;
    2196     37644625 :     auto const &thisOutNode = state.dataLoopNodes->Node(OutletNode);
    2197     37644625 :     auto const &daPumps = state.dataPumps;
    2198              : 
    2199     37644625 :     if (daPumps->PumpMassFlowRate <= DataBranchAirLoopPlant::MassFlowTolerance) {
    2200     17271724 :         new (&(state.dataPumps->PumpEquipReport(PumpNum))) ReportVars();
    2201     17271724 :         thisPumpRep.OutletTemp = thisOutNode.Temp;
    2202     17271724 :         thisPump.Power = 0.0;
    2203     17271724 :         thisPump.Energy = 0.0;
    2204              :     } else {
    2205     20372901 :         thisPumpRep.PumpMassFlowRate = daPumps->PumpMassFlowRate;
    2206     20372901 :         thisPumpRep.PumpHeattoFluid = daPumps->PumpHeattoFluid;
    2207     20372901 :         thisPumpRep.OutletTemp = thisOutNode.Temp;
    2208     20372901 :         thisPump.Power = daPumps->Power;
    2209     20372901 :         thisPump.Energy = thisPump.Power * state.dataHVACGlobal->TimeStepSysSec;
    2210     20372901 :         thisPumpRep.ShaftPower = daPumps->ShaftPower;
    2211     20372901 :         thisPumpRep.PumpHeattoFluidEnergy = daPumps->PumpHeattoFluid * state.dataHVACGlobal->TimeStepSysSec;
    2212     20372901 :         switch (PumpType) {
    2213     20282695 :         case PumpType::ConSpeed:
    2214              :         case PumpType::VarSpeed:
    2215              :         case PumpType::Cond:
    2216     20282695 :             thisPumpRep.NumPumpsOperating = 1;
    2217     20282695 :             break;
    2218              : 
    2219        90206 :         case PumpType::Bank_ConSpeed:
    2220              :         case PumpType::Bank_VarSpeed:
    2221        90206 :             thisPumpRep.NumPumpsOperating = daPumps->NumPumpsRunning;
    2222        90206 :             break;
    2223            0 :         default:
    2224            0 :             assert(false);
    2225              :             break;
    2226              :         }
    2227     20372901 :         thisPumpRep.ZoneTotalGainRate = daPumps->Power - daPumps->PumpHeattoFluid;
    2228     20372901 :         thisPumpRep.ZoneTotalGainEnergy = thisPumpRep.ZoneTotalGainRate * state.dataHVACGlobal->TimeStepSysSec;
    2229     20372901 :         thisPumpRep.ZoneConvGainRate = (1 - thisPump.SkinLossRadFraction) * thisPumpRep.ZoneTotalGainRate;
    2230     20372901 :         thisPumpRep.ZoneRadGainRate = thisPump.SkinLossRadFraction * thisPumpRep.ZoneTotalGainRate;
    2231              :     }
    2232     37644625 : }
    2233              : 
    2234         1179 : void PumpDataForTable(EnergyPlusData &state, int const NumPump)
    2235              : {
    2236              : 
    2237              :     // SUBROUTINE INFORMATION:
    2238              :     //       AUTHOR:          Jason Glazer
    2239              :     //       DATE WRITTEN:    September 2006
    2240              :     //       MODIFIED         na
    2241              :     //       RE-ENGINEERED    na
    2242              : 
    2243              :     // PURPOSE OF THIS SUBROUTINE:
    2244              :     // Pull data together for predefined tables.
    2245              : 
    2246              :     // Using/Aliasing
    2247              :     using namespace OutputReportPredefined;
    2248              : 
    2249              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2250         1179 :     std::string equipName;
    2251              : 
    2252         1179 :     auto &thisPump = state.dataPumps->PumpEquip(NumPump);
    2253         1179 :     auto &thisReport = state.dataOutRptPredefined;
    2254              : 
    2255         1179 :     equipName = thisPump.Name;
    2256         1179 :     PreDefTableEntry(state, thisReport->pdchPumpType, equipName, pumpTypeIDFNames[static_cast<int>(thisPump.pumpType)]);
    2257         1179 :     if (thisPump.PumpControl == PumpControlType::Continuous) {
    2258           40 :         PreDefTableEntry(state, thisReport->pdchPumpControl, equipName, "Continuous");
    2259         1139 :     } else if (thisPump.PumpControl == PumpControlType::Intermittent) {
    2260         1139 :         PreDefTableEntry(state, thisReport->pdchPumpControl, equipName, "Intermittent");
    2261              :     } else {
    2262            0 :         PreDefTableEntry(state, thisReport->pdchPumpControl, equipName, "Unknown");
    2263              :     }
    2264         1179 :     PreDefTableEntry(state, thisReport->pdchPumpHead, equipName, thisPump.NomPumpHead);
    2265         1179 :     PreDefTableEntry(state, thisReport->pdchPumpFlow, equipName, thisPump.NomVolFlowRate, 6);
    2266         1179 :     PreDefTableEntry(state, thisReport->pdchPumpPower, equipName, thisPump.NomPowerUse);
    2267         1179 :     if (thisPump.NomVolFlowRate != 0) {
    2268         1179 :         PreDefTableEntry(state, thisReport->pdchPumpPwrPerFlow, equipName, thisPump.NomPowerUse / thisPump.NomVolFlowRate);
    2269              :     } else {
    2270            0 :         PreDefTableEntry(state, thisReport->pdchPumpPwrPerFlow, equipName, "-");
    2271              :     }
    2272         1179 :     PreDefTableEntry(state, thisReport->pdchPumpEndUse, equipName, thisPump.EndUseSubcategoryName);
    2273         1179 :     PreDefTableEntry(state, thisReport->pdchMotEff, equipName, thisPump.MotorEffic);
    2274              :     // Std 229
    2275         1179 :     PreDefTableEntry(state, thisReport->pdchPumpAutosized, equipName, thisPump.NomVolFlowRateWasAutoSized ? "Yes" : "No");
    2276         2358 :     PreDefTableEntry(state,
    2277         1179 :                      thisReport->pdchPumpPlantloopName,
    2278              :                      equipName,
    2279         2358 :                      thisPump.plantLoc.loopNum > 0 ? state.dataPlnt->PlantLoop(thisPump.plantLoc.loopNum).Name : "N/A");
    2280         2358 :     PreDefTableEntry(
    2281              :         state,
    2282         1179 :         thisReport->pdchPumpPlantloopBranchName,
    2283              :         equipName,
    2284         1179 :         thisPump.plantLoc.loopNum > 0
    2285         2358 :             ? state.dataPlnt->PlantLoop(thisPump.plantLoc.loopNum).LoopSide(thisPump.plantLoc.loopSideNum).Branch(thisPump.plantLoc.branchNum).Name
    2286              :             : "N/A");
    2287         1179 : }
    2288              : 
    2289            0 : void GetRequiredMassFlowRate(EnergyPlusData &state,
    2290              :                              int const LoopNum,
    2291              :                              int const PumpNum,
    2292              :                              Real64 const InletNodeMassFlowRate,
    2293              :                              Real64 &ActualFlowRate,
    2294              :                              Real64 &PumpMinMassFlowRateVFDRange,
    2295              :                              Real64 &PumpMaxMassFlowRateVFDRange)
    2296              : {
    2297              :     // Using/Aliasing
    2298              :     using PlantPressureSystem::ResolveLoopFlowVsPressure;
    2299              :     using PlantUtilities::SetComponentFlowRate;
    2300              : 
    2301            0 :     Real64 PumpMassFlowRateMaxPress(0.0); // Maximum mass flow rate associated with maximum pressure limit
    2302            0 :     Real64 PumpMassFlowRateMinPress(0.0); // Minimum mass flow rate associated with minimum pressure limit
    2303            0 :     Real64 RotSpeed_Max(0.0);             // Maximum rotational speed in rps
    2304            0 :     Real64 RotSpeed_Min(0.0);             // Minimum rotational speed in rps
    2305            0 :     Real64 MinPress(0.0);                 // Minimum pressure
    2306            0 :     Real64 MaxPress(0.0);                 // Maximum pressure
    2307              : 
    2308            0 :     auto &thisPump = state.dataPumps->PumpEquip(PumpNum);
    2309              : 
    2310            0 :     RotSpeed_Min = thisPump.VFD.minRPMSched->getCurrentVal();
    2311            0 :     RotSpeed_Max = thisPump.VFD.maxRPMSched->getCurrentVal();
    2312            0 :     MinPress = thisPump.VFD.lowerPsetSched->getCurrentVal();
    2313            0 :     MaxPress = thisPump.VFD.upperPsetSched->getCurrentVal();
    2314              : 
    2315              :     // Calculate maximum and minimum mass flow rate associated with maximun and minimum RPM
    2316            0 :     if (thisPump.plantLoc.loopNum > 0) {
    2317            0 :         auto const &thisPlantLoop = state.dataPlnt->PlantLoop(thisPump.plantLoc.loopNum);
    2318            0 :         if (thisPlantLoop.UsePressureForPumpCalcs && thisPlantLoop.PressureSimType == DataPlant::PressSimType::FlowCorrection &&
    2319            0 :             thisPlantLoop.PressureDrop > 0.0) {
    2320            0 :             thisPump.PumpMassFlowRateMaxRPM = ResolveLoopFlowVsPressure(state,
    2321              :                                                                         thisPump.plantLoc.loopNum,
    2322              :                                                                         InletNodeMassFlowRate,
    2323              :                                                                         thisPump.PressureCurve_Index,
    2324              :                                                                         RotSpeed_Max,
    2325              :                                                                         thisPump.ImpellerDiameter,
    2326              :                                                                         thisPump.MinPhiValue,
    2327              :                                                                         thisPump.MaxPhiValue);
    2328            0 :             thisPump.PumpMassFlowRateMinRPM = ResolveLoopFlowVsPressure(state,
    2329              :                                                                         thisPump.plantLoc.loopNum,
    2330              :                                                                         InletNodeMassFlowRate,
    2331              :                                                                         thisPump.PressureCurve_Index,
    2332              :                                                                         RotSpeed_Min,
    2333              :                                                                         thisPump.ImpellerDiameter,
    2334              :                                                                         thisPump.MinPhiValue,
    2335              :                                                                         thisPump.MaxPhiValue);
    2336              :         }
    2337              :     }
    2338              : 
    2339              :     // Not correct necessarily, but values are coming out way wrong here, maxRPMmdot~3, minRPMmdot~62!
    2340            0 :     if (thisPump.PumpMassFlowRateMaxRPM < thisPump.PumpMassFlowRateMinRPM) {
    2341            0 :         thisPump.PumpMassFlowRateMaxRPM = thisPump.PumpMassFlowRateMinRPM;
    2342              :     }
    2343              : 
    2344              :     // Calculate maximum and minimum mass flow rate associated with operating pressure range
    2345            0 :     if (thisPump.plantLoc.loopNum > 0) {
    2346            0 :         auto const &thisPlantLoop = state.dataPlnt->PlantLoop(LoopNum);
    2347            0 :         if (thisPlantLoop.PressureEffectiveK > 0.0) {
    2348            0 :             PumpMassFlowRateMaxPress = std::sqrt(MaxPress / thisPlantLoop.PressureEffectiveK);
    2349            0 :             PumpMassFlowRateMinPress = std::sqrt(MinPress / thisPlantLoop.PressureEffectiveK);
    2350              :         }
    2351              :     }
    2352              : 
    2353              :     // Decide operating range for mass flow rate
    2354              :     // Maximum mass flow rate value of the range
    2355            0 :     if (thisPump.PumpMassFlowRateMaxRPM > PumpMassFlowRateMaxPress) {
    2356              :         // Maximum pressure value governs maximum VFD range value
    2357            0 :         PumpMaxMassFlowRateVFDRange = PumpMassFlowRateMaxPress;
    2358              :     } else {
    2359              :         // Maximum RPM value governs maximum VFD range value
    2360            0 :         PumpMaxMassFlowRateVFDRange = thisPump.PumpMassFlowRateMaxRPM;
    2361              :     }
    2362              : 
    2363              :     // Minimum mass flow rate value of the range
    2364            0 :     if (thisPump.PumpMassFlowRateMinRPM > PumpMassFlowRateMinPress) {
    2365              :         // Minimum pressure value governs minimum VFD range value
    2366            0 :         PumpMinMassFlowRateVFDRange = thisPump.PumpMassFlowRateMinRPM;
    2367              :     } else {
    2368              :         // Minimum pressure range value governs minimum VFD range value
    2369            0 :         PumpMinMassFlowRateVFDRange = PumpMassFlowRateMinPress;
    2370              :     }
    2371              : 
    2372              :     // Set the mass flow rate within VFD operating range
    2373            0 :     if (InletNodeMassFlowRate > PumpMinMassFlowRateVFDRange) {
    2374            0 :         if (InletNodeMassFlowRate < PumpMaxMassFlowRateVFDRange) {
    2375              :             // Flow request is within VFD operating range
    2376            0 :             ActualFlowRate = InletNodeMassFlowRate;
    2377              :         } else {
    2378              :             // Flow request is outside VFD operating range
    2379              :             // Flow is set to maximum VFD operating range
    2380            0 :             ActualFlowRate = PumpMaxMassFlowRateVFDRange;
    2381              :         }
    2382              :     } else {
    2383              :         // Flow request is outside VFD operating range
    2384              :         // Flow is set to minimum VFD operating Range
    2385            0 :         ActualFlowRate = PumpMinMassFlowRateVFDRange;
    2386              :     }
    2387            0 : }
    2388              : 
    2389              : } // namespace EnergyPlus::Pumps
        

Generated by: LCOV version 2.0-1