LCOV - code coverage report
Current view: top level - EnergyPlus - Pumps.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 61.8 % 1130 698
Test Date: 2025-05-22 16:09:37 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       264659 : 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       264659 :     if (state.dataPumps->GetInputFlag) {
     135           21 :         GetPumpInput(state);
     136           21 :         state.dataPumps->GetInputFlag = false;
     137              :     }
     138              : 
     139              :     // Exit early if no pumps found
     140       264659 :     if (state.dataPumps->NumPumps == 0) {
     141            0 :         PumpHeat = 0.0;
     142        88208 :         return;
     143              :     }
     144              : 
     145              :     // Setup pump component index if needed
     146       264659 :     if (PumpIndex == 0) {
     147           35 :         PumpNum = Util::FindItemInList(PumpName, state.dataPumps->PumpEquip); // Determine which pump to simulate
     148           35 :         if (PumpNum == 0) {
     149            0 :             ShowFatalError(state, format("ManagePumps: Pump requested not found ={}", PumpName)); // Catch any bad names before crashing
     150              :         }
     151           35 :         PumpIndex = PumpNum;
     152              :     } else {
     153       264624 :         PumpNum = PumpIndex;
     154       264624 :         if (state.dataPumps->PumpEquip(PumpNum).CheckEquipName) {
     155           35 :             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           35 :             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           35 :             state.dataPumps->PumpEquip(PumpNum).CheckEquipName = false;
     169              :         }
     170              :     }
     171              : 
     172              :     // Perform one-time and begin-environment initialization
     173       264659 :     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       264659 :     if (state.dataPlnt->PlantLoop(LoopNum).LoopSide(state.dataPumps->PumpEquip(PumpNum).plantLoc.loopSideNum).FlowLock ==
     177              :         DataPlant::FlowLock::PumpQuery) {
     178        88208 :         SetupPumpMinMaxFlows(state, LoopNum, PumpNum);
     179        88208 :         return;
     180              :     }
     181              : 
     182              :     // Set pump flow rate and calculate power
     183       176451 :     CalcPumps(state, PumpNum, FlowRequest, PumpRunning);
     184              : 
     185              :     // Update pump reporting data
     186       176451 :     ReportPumps(state, PumpNum);
     187              : 
     188              :     // Send this up to the calling routine
     189       176451 :     PumpHeat = state.dataPumps->PumpHeattoFluid;
     190              : }
     191              : 
     192           40 : 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           40 :     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           40 :     int NumVarSpeedPumps = 0;
     238           40 :     int NumConstSpeedPumps = 0;
     239           40 :     int NumCondensatePumps = 0;
     240           40 :     int NumPumpBankSimpleVar = 0;
     241           40 :     int NumPumpBankSimpleConst = 0;
     242              :     Real64 SteamDensity;
     243              :     Real64 TempWaterDensity;
     244           40 :     int DummyWaterIndex(1);
     245           40 :     Real64 constexpr minToMaxRatioMax = 0.99;
     246              : 
     247           40 :     ErrorsFound = false;
     248              : 
     249              :     // GET NUMBER OF ALL EQUIPMENT TYPES
     250           40 :     NumVarSpeedPumps = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, pumpTypeIDFNames[static_cast<int>(PumpType::VarSpeed)]);
     251           40 :     NumConstSpeedPumps = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, pumpTypeIDFNames[static_cast<int>(PumpType::ConSpeed)]);
     252           40 :     NumCondensatePumps = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, pumpTypeIDFNames[static_cast<int>(PumpType::Cond)]);
     253              :     NumPumpBankSimpleVar =
     254           40 :         state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, pumpTypeIDFNames[static_cast<int>(PumpType::Bank_VarSpeed)]);
     255              :     NumPumpBankSimpleConst =
     256           40 :         state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, pumpTypeIDFNames[static_cast<int>(PumpType::Bank_ConSpeed)]);
     257           40 :     state.dataPumps->NumPumps = NumVarSpeedPumps + NumConstSpeedPumps + NumCondensatePumps + NumPumpBankSimpleVar + NumPumpBankSimpleConst;
     258              : 
     259           40 :     if (state.dataPumps->NumPumps <= 0) {
     260            0 :         ShowWarningError(state, "No Pumping Equipment Found");
     261            0 :         return;
     262              :     }
     263              : 
     264           40 :     state.dataPumps->PumpEquip.allocate(state.dataPumps->NumPumps);
     265           40 :     state.dataPumps->PumpUniqueNames.reserve(static_cast<unsigned>(state.dataPumps->NumPumps));
     266           40 :     state.dataPumps->PumpEquipReport.allocate(state.dataPumps->NumPumps);
     267           40 :     auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
     268           40 :     cCurrentModuleObject = pumpTypeIDFNames[static_cast<int>(PumpType::VarSpeed)];
     269           40 :     auto &thisInput = state.dataIPShortCut;
     270              : 
     271           71 :     for (PumpNum = 1; PumpNum <= NumVarSpeedPumps; ++PumpNum) {
     272           31 :         auto &thisPump = state.dataPumps->PumpEquip(PumpNum);
     273           62 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     274              :                                                                  cCurrentModuleObject,
     275              :                                                                  PumpNum,
     276           31 :                                                                  thisInput->cAlphaArgs,
     277              :                                                                  NumAlphas,
     278           31 :                                                                  thisInput->rNumericArgs,
     279              :                                                                  NumNums,
     280              :                                                                  IOStat,
     281           31 :                                                                  thisInput->lNumericFieldBlanks,
     282           31 :                                                                  thisInput->lAlphaFieldBlanks,
     283           31 :                                                                  thisInput->cAlphaFieldNames,
     284           31 :                                                                  thisInput->cNumericFieldNames);
     285              : 
     286           31 :         ErrorObjectHeader eoh{routineName, cCurrentModuleObject, thisInput->cAlphaArgs(1)};
     287              : 
     288           31 :         GlobalNames::VerifyUniqueInterObjectName(
     289           62 :             state, state.dataPumps->PumpUniqueNames, thisInput->cAlphaArgs(1), cCurrentModuleObject, thisInput->cAlphaFieldNames(1), ErrorsFound);
     290           31 :         thisPump.Name = thisInput->cAlphaArgs(1);
     291           31 :         thisPump.pumpType = PumpType::VarSpeed; //'Pump:VariableSpeed'
     292           31 :         thisPump.TypeOf_Num = DataPlant::PlantEquipmentType::PumpVariableSpeed;
     293              : 
     294           31 :         thisPump.InletNodeNum = GetOnlySingleNode(state,
     295           31 :                                                   thisInput->cAlphaArgs(2),
     296              :                                                   ErrorsFound,
     297              :                                                   DataLoopNode::ConnectionObjectType::PumpVariableSpeed,
     298           31 :                                                   thisPump.Name,
     299              :                                                   DataLoopNode::NodeFluidType::Water,
     300              :                                                   DataLoopNode::ConnectionType::Inlet,
     301              :                                                   NodeInputManager::CompFluidStream::Primary,
     302              :                                                   ObjectIsNotParent);
     303              : 
     304           62 :         thisPump.OutletNodeNum = GetOnlySingleNode(state,
     305           31 :                                                    thisInput->cAlphaArgs(3),
     306              :                                                    ErrorsFound,
     307              :                                                    DataLoopNode::ConnectionObjectType::PumpVariableSpeed,
     308           31 :                                                    thisPump.Name,
     309              :                                                    DataLoopNode::NodeFluidType::Water,
     310              :                                                    DataLoopNode::ConnectionType::Outlet,
     311              :                                                    NodeInputManager::CompFluidStream::Primary,
     312              :                                                    ObjectIsNotParent);
     313           31 :         TestCompSet(state, cCurrentModuleObject, thisPump.Name, thisInput->cAlphaArgs(2), thisInput->cAlphaArgs(3), "Water Nodes");
     314              : 
     315           31 :         thisPump.PumpControl = static_cast<PumpControlType>(getEnumValue(pumpCtrlTypeNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(4))));
     316           31 :         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           31 :         if (thisInput->cAlphaArgs(5).empty()) {
     327           31 :             thisPump.flowRateSched = nullptr;
     328            0 :         } 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           31 :         thisPump.NomVolFlowRate = thisInput->rNumericArgs(1);
     333           31 :         if (thisPump.NomVolFlowRate == AutoSize) {
     334            4 :             thisPump.NomVolFlowRateWasAutoSized = true;
     335              :         }
     336           31 :         thisPump.NomPumpHead = thisInput->rNumericArgs(2);
     337           31 :         thisPump.NomPowerUse = thisInput->rNumericArgs(3);
     338           31 :         if (thisPump.NomPowerUse == AutoSize) {
     339            9 :             thisPump.NomPowerUseWasAutoSized = true;
     340              :         }
     341           31 :         thisPump.MotorEffic = thisInput->rNumericArgs(4);
     342           31 :         thisPump.FracMotorLossToFluid = thisInput->rNumericArgs(5);
     343           31 :         thisPump.PartLoadCoef[0] = thisInput->rNumericArgs(6);
     344           31 :         thisPump.PartLoadCoef[1] = thisInput->rNumericArgs(7);
     345           31 :         thisPump.PartLoadCoef[2] = thisInput->rNumericArgs(8);
     346           31 :         thisPump.PartLoadCoef[3] = thisInput->rNumericArgs(9);
     347           31 :         thisPump.MinVolFlowRate = thisInput->rNumericArgs(10);
     348           31 :         if (thisPump.MinVolFlowRate == AutoSize) {
     349            4 :             thisPump.minVolFlowRateWasAutosized = true;
     350           27 :         } else if (!thisPump.NomVolFlowRateWasAutoSized && (thisPump.MinVolFlowRate > (minToMaxRatioMax * thisPump.NomVolFlowRate))) {
     351              :             // Check that the minimum isn't greater than the maximum
     352            4 :             ShowWarningError(
     353            4 :                 state, format("{}{}=\"{}\", Invalid '{}'", RoutineName, cCurrentModuleObject, thisPump.Name, thisInput->cNumericFieldNames(10)));
     354            4 :             ShowContinueError(state,
     355            6 :                               format("Entered Value=[{:.5T}] is above or too close (equal) to the {}=[{:.5T}].",
     356            2 :                                      thisPump.MinVolFlowRate,
     357            2 :                                      thisInput->cNumericFieldNames(1),
     358            2 :                                      thisPump.NomVolFlowRate));
     359            4 :             ShowContinueError(
     360              :                 state,
     361            4 :                 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            2 :             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           31 :         if (thisInput->cAlphaArgs(6).empty()) {
     370           31 :             thisPump.PressureCurve_Index = -1;
     371              :         } else {
     372            0 :             TempCurveIndex = GetCurveIndex(state, thisInput->cAlphaArgs(6));
     373            0 :             if (TempCurveIndex == 0) {
     374            0 :                 thisPump.PressureCurve_Index = -1;
     375              :             } else {
     376            0 :                 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            0 :                                                      thisInput->cAlphaFieldNames(6)); // Field Name
     383              : 
     384            0 :                 if (!ErrorsFound) {
     385            0 :                     thisPump.PressureCurve_Index = TempCurveIndex;
     386            0 :                     GetCurveMinMaxValues(state, TempCurveIndex, thisPump.MinPhiValue, thisPump.MaxPhiValue);
     387              :                 }
     388              :             }
     389              :         }
     390              : 
     391              :         // read in the rest of the pump pressure characteristics
     392           31 :         thisPump.ImpellerDiameter = thisInput->rNumericArgs(11);
     393              : 
     394              :         // Input VFD related data
     395           31 :         if (thisInput->lAlphaFieldBlanks(7)) {
     396           31 :             thisPump.HasVFD = false;
     397              :         } else {
     398            0 :             thisPump.HasVFD = true;
     399            0 :             thisPump.VFD.VFDControlType =
     400            0 :                 static_cast<ControlTypeVFD>(getEnumValue(controlTypeVFDNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(7))));
     401              : 
     402            0 :             switch (thisPump.VFD.VFDControlType) {
     403              : 
     404            0 :             case ControlTypeVFD::VFDManual: {
     405            0 :                 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            0 :                 } 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            0 :             } 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           31 :         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           31 :         if (!thisInput->lAlphaFieldBlanks(14)) {
     484            5 :             thisPump.powerSizingMethod =
     485            5 :                 static_cast<PowerSizingMethod>(getEnumValue(powerSizingMethodNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(14))));
     486            5 :             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           31 :         if (!thisInput->lNumericFieldBlanks(13)) {
     497            2 :             thisPump.powerPerFlowScalingFactor = thisInput->rNumericArgs(13);
     498              :         }
     499              : 
     500           31 :         if (!thisInput->lNumericFieldBlanks(14)) {
     501            4 :             thisPump.powerPerFlowPerPressureScalingFactor = thisInput->rNumericArgs(14);
     502              :         }
     503              : 
     504           31 :         if (!thisInput->lNumericFieldBlanks(15)) {
     505            2 :             thisPump.MinVolFlowRateFrac = thisInput->rNumericArgs(15);
     506              :         }
     507              : 
     508           31 :         if (NumAlphas > 14) {
     509            1 :             thisPump.EndUseSubcategoryName = thisInput->cAlphaArgs(15);
     510              :         } else {
     511           30 :             thisPump.EndUseSubcategoryName = "General";
     512              :         }
     513              : 
     514              :         // Is this really necessary for each pump GetInput loop?
     515           31 :         thisPump.Energy = 0.0;
     516           31 :         thisPump.Power = 0.0;
     517              :     }
     518              : 
     519           40 :     cCurrentModuleObject = pumpTypeIDFNames[static_cast<int>(PumpType::ConSpeed)];
     520              : 
     521           53 :     for (int NumConstPump = 1; NumConstPump <= NumConstSpeedPumps; ++NumConstPump) {
     522           13 :         PumpNum = NumVarSpeedPumps + NumConstPump;
     523           13 :         auto &thisPump = state.dataPumps->PumpEquip(PumpNum);
     524           26 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     525              :                                                                  cCurrentModuleObject,
     526              :                                                                  NumConstPump,
     527           13 :                                                                  thisInput->cAlphaArgs,
     528              :                                                                  NumAlphas,
     529           13 :                                                                  thisInput->rNumericArgs,
     530              :                                                                  NumNums,
     531              :                                                                  IOStat,
     532           13 :                                                                  thisInput->lNumericFieldBlanks,
     533           13 :                                                                  thisInput->lAlphaFieldBlanks,
     534           13 :                                                                  thisInput->cAlphaFieldNames,
     535           13 :                                                                  thisInput->cNumericFieldNames);
     536              : 
     537           13 :         ErrorObjectHeader eoh{routineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)};
     538              : 
     539           13 :         GlobalNames::VerifyUniqueInterObjectName(
     540           26 :             state, state.dataPumps->PumpUniqueNames, thisInput->cAlphaArgs(1), cCurrentModuleObject, thisInput->cAlphaFieldNames(1), ErrorsFound);
     541           13 :         thisPump.Name = thisInput->cAlphaArgs(1);
     542           13 :         thisPump.pumpType = PumpType::ConSpeed; //'Pump:ConstantSpeed'
     543           13 :         thisPump.TypeOf_Num = DataPlant::PlantEquipmentType::PumpConstantSpeed;
     544              : 
     545           13 :         thisPump.InletNodeNum = GetOnlySingleNode(state,
     546           13 :                                                   thisInput->cAlphaArgs(2),
     547              :                                                   ErrorsFound,
     548              :                                                   DataLoopNode::ConnectionObjectType::PumpConstantSpeed,
     549           13 :                                                   thisPump.Name,
     550              :                                                   DataLoopNode::NodeFluidType::Water,
     551              :                                                   DataLoopNode::ConnectionType::Inlet,
     552              :                                                   NodeInputManager::CompFluidStream::Primary,
     553              :                                                   ObjectIsNotParent);
     554              : 
     555           26 :         thisPump.OutletNodeNum = GetOnlySingleNode(state,
     556           13 :                                                    thisInput->cAlphaArgs(3),
     557              :                                                    ErrorsFound,
     558              :                                                    DataLoopNode::ConnectionObjectType::PumpConstantSpeed,
     559           13 :                                                    thisPump.Name,
     560              :                                                    DataLoopNode::NodeFluidType::Water,
     561              :                                                    DataLoopNode::ConnectionType::Outlet,
     562              :                                                    NodeInputManager::CompFluidStream::Primary,
     563              :                                                    ObjectIsNotParent);
     564           13 :         TestCompSet(state, cCurrentModuleObject, thisPump.Name, thisInput->cAlphaArgs(2), thisInput->cAlphaArgs(3), "Water Nodes");
     565              : 
     566           13 :         thisPump.NomVolFlowRate = thisInput->rNumericArgs(1);
     567           13 :         if (thisPump.NomVolFlowRate == AutoSize) {
     568            4 :             thisPump.NomVolFlowRateWasAutoSized = true;
     569              :         }
     570           13 :         thisPump.NomPumpHead = thisInput->rNumericArgs(2);
     571           13 :         thisPump.NomPowerUse = thisInput->rNumericArgs(3);
     572           13 :         if (thisPump.NomPowerUse == AutoSize) {
     573            7 :             thisPump.NomPowerUseWasAutoSized = true;
     574              :         }
     575           13 :         thisPump.MotorEffic = thisInput->rNumericArgs(4);
     576           13 :         thisPump.FracMotorLossToFluid = thisInput->rNumericArgs(5);
     577           13 :         thisPump.PartLoadCoef[0] = 1.0;
     578           13 :         thisPump.PartLoadCoef[1] = 0.0;
     579           13 :         thisPump.PartLoadCoef[2] = 0.0;
     580           13 :         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           13 :         thisPump.MinVolFlowRate = 0.0;
     584           13 :         thisPump.Energy = 0.0;
     585           13 :         thisPump.Power = 0.0;
     586              : 
     587           13 :         thisPump.PumpControl = static_cast<PumpControlType>(getEnumValue(pumpCtrlTypeNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(4))));
     588              : 
     589           13 :         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           13 :         if (thisInput->lAlphaFieldBlanks(5)) {
     600           13 :             thisPump.flowRateSched = nullptr;
     601            0 :         } else if ((thisPump.flowRateSched = Sched::GetSchedule(state, thisInput->cAlphaArgs(5))) == nullptr) {
     602            0 :             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           13 :         if (thisInput->cAlphaArgs(6).empty()) {
     607           13 :             thisPump.PressureCurve_Index = -1;
     608              :         } else {
     609            0 :             TempCurveIndex = GetCurveIndex(state, thisInput->cAlphaArgs(6));
     610            0 :             if (TempCurveIndex == 0) {
     611            0 :                 thisPump.PressureCurve_Index = -1;
     612              :             } else {
     613            0 :                 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            0 :                                                      thisInput->cAlphaFieldNames(6)); // Field Name
     620              : 
     621            0 :                 if (!ErrorsFound) {
     622            0 :                     thisPump.PressureCurve_Index = TempCurveIndex;
     623            0 :                     GetCurveMinMaxValues(state, TempCurveIndex, thisPump.MinPhiValue, thisPump.MaxPhiValue);
     624              :                 }
     625              :             }
     626              :         }
     627              : 
     628              :         // read in the rest of the pump pressure characteristics
     629           13 :         thisPump.ImpellerDiameter = thisInput->rNumericArgs(6);
     630           13 :         thisPump.RotSpeed_RPM = thisInput->rNumericArgs(7); // retrieve the input rotational speed, in revs/min
     631           13 :         thisPump.RotSpeed = thisPump.RotSpeed_RPM / 60.0;   // convert input[rpm] to calculation units[rps]
     632              : 
     633           13 :         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           13 :         if (!thisInput->lAlphaFieldBlanks(8)) {
     652            3 :             thisPump.powerSizingMethod =
     653            3 :                 static_cast<PowerSizingMethod>(getEnumValue(powerSizingMethodNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(8))));
     654            3 :             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           13 :         if (!thisInput->lNumericFieldBlanks(9)) {
     665            2 :             thisPump.powerPerFlowScalingFactor = thisInput->rNumericArgs(9);
     666              :         }
     667              : 
     668           13 :         if (!thisInput->lNumericFieldBlanks(10)) {
     669            2 :             thisPump.powerPerFlowPerPressureScalingFactor = thisInput->rNumericArgs(10);
     670              :         }
     671              : 
     672           13 :         if (NumAlphas > 8) {
     673            2 :             thisPump.EndUseSubcategoryName = thisInput->cAlphaArgs(9);
     674              :         } else {
     675           11 :             thisPump.EndUseSubcategoryName = "General";
     676              :         }
     677              :     }
     678              : 
     679              :     // pumps for steam system pumping condensate
     680           40 :     cCurrentModuleObject = pumpTypeIDFNames[static_cast<int>(PumpType::Cond)];
     681           43 :     for (int NumCondPump = 1; NumCondPump <= NumCondensatePumps; ++NumCondPump) {
     682            3 :         PumpNum = NumCondPump + NumVarSpeedPumps + NumConstSpeedPumps;
     683            3 :         auto &thisPump = state.dataPumps->PumpEquip(PumpNum);
     684            6 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     685              :                                                                  cCurrentModuleObject,
     686              :                                                                  NumCondPump,
     687            3 :                                                                  thisInput->cAlphaArgs,
     688              :                                                                  NumAlphas,
     689            3 :                                                                  thisInput->rNumericArgs,
     690              :                                                                  NumNums,
     691              :                                                                  IOStat,
     692            3 :                                                                  thisInput->lNumericFieldBlanks,
     693            3 :                                                                  thisInput->lAlphaFieldBlanks,
     694            3 :                                                                  thisInput->cAlphaFieldNames,
     695            3 :                                                                  thisInput->cNumericFieldNames);
     696              : 
     697            3 :         ErrorObjectHeader eoh{routineName, cCurrentModuleObject, thisInput->cAlphaArgs(1)};
     698              : 
     699            3 :         GlobalNames::VerifyUniqueInterObjectName(
     700            6 :             state, state.dataPumps->PumpUniqueNames, thisInput->cAlphaArgs(1), cCurrentModuleObject, thisInput->cAlphaFieldNames(1), ErrorsFound);
     701            3 :         thisPump.Name = thisInput->cAlphaArgs(1);
     702            3 :         thisPump.pumpType = PumpType::Cond; //'Pump:VariableSpeed:Condensate'
     703            3 :         thisPump.TypeOf_Num = DataPlant::PlantEquipmentType::PumpCondensate;
     704              : 
     705            3 :         thisPump.InletNodeNum = GetOnlySingleNode(state,
     706            3 :                                                   thisInput->cAlphaArgs(2),
     707              :                                                   ErrorsFound,
     708              :                                                   DataLoopNode::ConnectionObjectType::PumpVariableSpeedCondensate,
     709            3 :                                                   thisPump.Name,
     710              :                                                   DataLoopNode::NodeFluidType::Steam,
     711              :                                                   DataLoopNode::ConnectionType::Inlet,
     712              :                                                   NodeInputManager::CompFluidStream::Primary,
     713              :                                                   ObjectIsNotParent);
     714              : 
     715            6 :         thisPump.OutletNodeNum = GetOnlySingleNode(state,
     716            3 :                                                    thisInput->cAlphaArgs(3),
     717              :                                                    ErrorsFound,
     718              :                                                    DataLoopNode::ConnectionObjectType::PumpVariableSpeedCondensate,
     719            3 :                                                    thisPump.Name,
     720              :                                                    DataLoopNode::NodeFluidType::Steam,
     721              :                                                    DataLoopNode::ConnectionType::Outlet,
     722              :                                                    NodeInputManager::CompFluidStream::Primary,
     723              :                                                    ObjectIsNotParent);
     724            3 :         TestCompSet(state, cCurrentModuleObject, thisPump.Name, thisInput->cAlphaArgs(2), thisInput->cAlphaArgs(3), "Water Nodes");
     725              : 
     726            3 :         thisPump.PumpControl = PumpControlType::Intermittent;
     727              : 
     728              :         // Input the optional schedule for the pump
     729            3 :         if (thisInput->cAlphaArgs(4).empty()) {
     730            3 :             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            3 :         thisPump.NomSteamVolFlowRate = thisInput->rNumericArgs(1);
     736            3 :         if (thisPump.NomSteamVolFlowRate == AutoSize) {
     737            0 :             thisPump.NomSteamVolFlowRateWasAutoSized = true;
     738              :         }
     739            3 :         thisPump.NomPumpHead = thisInput->rNumericArgs(2);
     740            3 :         thisPump.NomPowerUse = thisInput->rNumericArgs(3);
     741            3 :         if (thisPump.NomPowerUse == AutoSize) {
     742            3 :             thisPump.NomPowerUseWasAutoSized = true;
     743              :         }
     744            3 :         thisPump.MotorEffic = thisInput->rNumericArgs(4);
     745            3 :         thisPump.FracMotorLossToFluid = thisInput->rNumericArgs(5);
     746            3 :         thisPump.PartLoadCoef[0] = thisInput->rNumericArgs(6);
     747            3 :         thisPump.PartLoadCoef[1] = thisInput->rNumericArgs(7);
     748            3 :         thisPump.PartLoadCoef[2] = thisInput->rNumericArgs(8);
     749            3 :         thisPump.PartLoadCoef[3] = thisInput->rNumericArgs(9);
     750              : 
     751            3 :         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            3 :         thisPump.MinVolFlowRate = 0.0;
     770            3 :         thisPump.Energy = 0.0;
     771            3 :         thisPump.Power = 0.0;
     772              : 
     773            3 :         if (thisPump.NomSteamVolFlowRateWasAutoSized) {
     774            0 :             thisPump.NomVolFlowRate = AutoSize;
     775            0 :             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            3 :         if (!thisInput->lAlphaFieldBlanks(6)) {
     784            2 :             thisPump.powerSizingMethod =
     785            2 :                 static_cast<PowerSizingMethod>(getEnumValue(powerSizingMethodNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(6))));
     786            2 :             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            3 :         if (!thisInput->lNumericFieldBlanks(11)) {
     797            1 :             thisPump.powerPerFlowScalingFactor = thisInput->rNumericArgs(11);
     798              :         }
     799              : 
     800            3 :         if (!thisInput->lNumericFieldBlanks(12)) {
     801            1 :             thisPump.powerPerFlowPerPressureScalingFactor = thisInput->rNumericArgs(12);
     802              :         }
     803              : 
     804            3 :         if (NumAlphas > 6) {
     805            1 :             thisPump.EndUseSubcategoryName = thisInput->cAlphaArgs(7);
     806              :         } else {
     807            2 :             thisPump.EndUseSubcategoryName = "General";
     808              :         }
     809              :     }
     810              : 
     811              :     // LOAD Variable Speed Pump Bank ARRAYS WITH VARIABLE SPEED CURVE FIT PUMP DATA
     812           40 :     cCurrentModuleObject = pumpTypeIDFNames[static_cast<int>(PumpType::Bank_VarSpeed)];
     813           44 :     for (int NumVarPumpBankSimple = 1; NumVarPumpBankSimple <= NumPumpBankSimpleVar; ++NumVarPumpBankSimple) {
     814            4 :         PumpNum = NumVarPumpBankSimple + NumVarSpeedPumps + NumConstSpeedPumps + NumCondensatePumps;
     815            4 :         auto &thisPump = state.dataPumps->PumpEquip(PumpNum);
     816            8 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     817              :                                                                  cCurrentModuleObject,
     818              :                                                                  NumVarPumpBankSimple,
     819            4 :                                                                  thisInput->cAlphaArgs,
     820              :                                                                  NumAlphas,
     821            4 :                                                                  thisInput->rNumericArgs,
     822              :                                                                  NumNums,
     823              :                                                                  IOStat,
     824            4 :                                                                  thisInput->lNumericFieldBlanks,
     825            4 :                                                                  thisInput->lAlphaFieldBlanks,
     826            4 :                                                                  thisInput->cAlphaFieldNames,
     827            4 :                                                                  thisInput->cNumericFieldNames);
     828              : 
     829            4 :         ErrorObjectHeader eoh{routineName, cCurrentModuleObject, thisInput->cAlphaArgs(1)};
     830              : 
     831            4 :         GlobalNames::VerifyUniqueInterObjectName(
     832            8 :             state, state.dataPumps->PumpUniqueNames, thisInput->cAlphaArgs(1), cCurrentModuleObject, thisInput->cAlphaFieldNames(1), ErrorsFound);
     833            4 :         thisPump.Name = thisInput->cAlphaArgs(1);
     834            4 :         thisPump.pumpType = PumpType::Bank_VarSpeed; //'HeaderedPumps:VariableSpeed'
     835            4 :         thisPump.TypeOf_Num = DataPlant::PlantEquipmentType::PumpBankVariableSpeed;
     836              : 
     837            4 :         thisPump.InletNodeNum = GetOnlySingleNode(state,
     838            4 :                                                   thisInput->cAlphaArgs(2),
     839              :                                                   ErrorsFound,
     840              :                                                   DataLoopNode::ConnectionObjectType::HeaderedPumpsVariableSpeed,
     841            4 :                                                   thisPump.Name,
     842              :                                                   DataLoopNode::NodeFluidType::Water,
     843              :                                                   DataLoopNode::ConnectionType::Inlet,
     844              :                                                   NodeInputManager::CompFluidStream::Primary,
     845              :                                                   ObjectIsNotParent);
     846              : 
     847            8 :         thisPump.OutletNodeNum = GetOnlySingleNode(state,
     848            4 :                                                    thisInput->cAlphaArgs(3),
     849              :                                                    ErrorsFound,
     850              :                                                    DataLoopNode::ConnectionObjectType::HeaderedPumpsVariableSpeed,
     851            4 :                                                    thisPump.Name,
     852              :                                                    DataLoopNode::NodeFluidType::Water,
     853              :                                                    DataLoopNode::ConnectionType::Outlet,
     854              :                                                    NodeInputManager::CompFluidStream::Primary,
     855              :                                                    ObjectIsNotParent);
     856            4 :         TestCompSet(state, cCurrentModuleObject, thisPump.Name, thisInput->cAlphaArgs(2), thisInput->cAlphaArgs(3), "Water Nodes");
     857              : 
     858            4 :         if (Util::SameString(thisInput->cAlphaArgs(4), "Optimal")) {
     859            0 :             thisPump.SequencingScheme = PumpBankControlSeq::OptimalScheme;
     860            4 :         } else if (Util::SameString(thisInput->cAlphaArgs(4), "Sequential")) {
     861            4 :             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            4 :         thisPump.PumpControl = static_cast<PumpControlType>(getEnumValue(pumpCtrlTypeNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(5))));
     874            4 :         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            4 :         if (thisInput->cAlphaArgs(6).empty()) { // Initialized to zero, don't get a schedule for an empty
     885            0 :             thisPump.flowRateSched = nullptr;
     886            4 :         } else if ((thisPump.flowRateSched = Sched::GetSchedule(state, thisInput->cAlphaArgs(6))) == nullptr) {
     887            4 :             ShowWarningItemNotFound(state, eoh, thisInput->cAlphaFieldNames(6), thisInput->cAlphaArgs(6));
     888              :         }
     889              : 
     890            4 :         thisPump.NomVolFlowRate = thisInput->rNumericArgs(1);
     891            4 :         if (thisPump.NomVolFlowRate == AutoSize) {
     892            0 :             thisPump.NomVolFlowRateWasAutoSized = true;
     893              :         }
     894            4 :         thisPump.NumPumpsInBank = thisInput->rNumericArgs(2);
     895            4 :         thisPump.NomPumpHead = thisInput->rNumericArgs(3);
     896            4 :         thisPump.NomPowerUse = thisInput->rNumericArgs(4);
     897            4 :         if (thisPump.NomPowerUse == AutoSize) {
     898            4 :             thisPump.NomPowerUseWasAutoSized = true;
     899              :         }
     900            4 :         thisPump.MotorEffic = thisInput->rNumericArgs(5);
     901            4 :         thisPump.FracMotorLossToFluid = thisInput->rNumericArgs(6);
     902            4 :         thisPump.PartLoadCoef[0] = thisInput->rNumericArgs(7);
     903            4 :         thisPump.PartLoadCoef[1] = thisInput->rNumericArgs(8);
     904            4 :         thisPump.PartLoadCoef[2] = thisInput->rNumericArgs(9);
     905            4 :         thisPump.PartLoadCoef[3] = thisInput->rNumericArgs(10);
     906            4 :         thisPump.MinVolFlowRateFrac = thisInput->rNumericArgs(11);
     907            4 :         thisPump.MinVolFlowRate = thisPump.NomVolFlowRate * thisPump.MinVolFlowRateFrac;
     908              : 
     909            4 :         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            4 :         if (!thisInput->lAlphaFieldBlanks(8)) {
     928            3 :             thisPump.powerSizingMethod =
     929            3 :                 static_cast<PowerSizingMethod>(getEnumValue(powerSizingMethodNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(8))));
     930            3 :             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            4 :         if (!thisInput->lNumericFieldBlanks(13)) {
     941            0 :             thisPump.powerPerFlowScalingFactor = thisInput->rNumericArgs(13);
     942              :         }
     943              : 
     944            4 :         if (!thisInput->lNumericFieldBlanks(14)) {
     945            2 :             thisPump.powerPerFlowPerPressureScalingFactor = thisInput->rNumericArgs(14);
     946              :         }
     947              : 
     948            4 :         if (NumAlphas > 8) {
     949            2 :             thisPump.EndUseSubcategoryName = thisInput->cAlphaArgs(9);
     950              :         } else {
     951            2 :             thisPump.EndUseSubcategoryName = "General";
     952              :         }
     953              : 
     954            4 :         thisPump.Energy = 0.0;
     955            4 :         thisPump.Power = 0.0;
     956              :     }
     957              : 
     958           40 :     cCurrentModuleObject = pumpTypeIDFNames[static_cast<int>(PumpType::Bank_ConSpeed)];
     959           43 :     for (int NumConstPumpBankSimple = 1; NumConstPumpBankSimple <= NumPumpBankSimpleConst; ++NumConstPumpBankSimple) {
     960            3 :         PumpNum = NumConstPumpBankSimple + NumVarSpeedPumps + NumConstSpeedPumps + NumCondensatePumps + NumPumpBankSimpleVar;
     961            3 :         auto &thisPump = state.dataPumps->PumpEquip(PumpNum);
     962            6 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     963              :                                                                  cCurrentModuleObject,
     964              :                                                                  NumConstPumpBankSimple,
     965            3 :                                                                  thisInput->cAlphaArgs,
     966              :                                                                  NumAlphas,
     967            3 :                                                                  thisInput->rNumericArgs,
     968              :                                                                  NumNums,
     969              :                                                                  IOStat,
     970            3 :                                                                  thisInput->lNumericFieldBlanks,
     971            3 :                                                                  thisInput->lAlphaFieldBlanks,
     972            3 :                                                                  thisInput->cAlphaFieldNames,
     973            3 :                                                                  thisInput->cNumericFieldNames);
     974              : 
     975            3 :         ErrorObjectHeader eoh{routineName, cCurrentModuleObject, thisInput->cAlphaArgs(1)};
     976              : 
     977            3 :         GlobalNames::VerifyUniqueInterObjectName(
     978            6 :             state, state.dataPumps->PumpUniqueNames, thisInput->cAlphaArgs(1), cCurrentModuleObject, thisInput->cAlphaFieldNames(1), ErrorsFound);
     979            3 :         thisPump.Name = thisInput->cAlphaArgs(1);
     980            3 :         thisPump.pumpType = PumpType::Bank_ConSpeed; //'HeaderedPumps:ConstantSpeed'
     981            3 :         thisPump.TypeOf_Num = DataPlant::PlantEquipmentType::PumpBankConstantSpeed;
     982              : 
     983            3 :         thisPump.InletNodeNum = GetOnlySingleNode(state,
     984            3 :                                                   thisInput->cAlphaArgs(2),
     985              :                                                   ErrorsFound,
     986              :                                                   DataLoopNode::ConnectionObjectType::HeaderedPumpsConstantSpeed,
     987            3 :                                                   thisPump.Name,
     988              :                                                   DataLoopNode::NodeFluidType::Water,
     989              :                                                   DataLoopNode::ConnectionType::Inlet,
     990              :                                                   NodeInputManager::CompFluidStream::Primary,
     991              :                                                   ObjectIsNotParent);
     992              : 
     993            6 :         thisPump.OutletNodeNum = GetOnlySingleNode(state,
     994            3 :                                                    thisInput->cAlphaArgs(3),
     995              :                                                    ErrorsFound,
     996              :                                                    DataLoopNode::ConnectionObjectType::HeaderedPumpsConstantSpeed,
     997            3 :                                                    thisPump.Name,
     998              :                                                    DataLoopNode::NodeFluidType::Water,
     999              :                                                    DataLoopNode::ConnectionType::Outlet,
    1000              :                                                    NodeInputManager::CompFluidStream::Primary,
    1001              :                                                    ObjectIsNotParent);
    1002            3 :         TestCompSet(state, cCurrentModuleObject, thisPump.Name, thisInput->cAlphaArgs(2), thisInput->cAlphaArgs(3), "Water Nodes");
    1003              : 
    1004            3 :         if (Util::SameString(thisInput->cAlphaArgs(4), "Optimal")) {
    1005            0 :             thisPump.SequencingScheme = PumpBankControlSeq::OptimalScheme;
    1006            3 :         } else if (Util::SameString(thisInput->cAlphaArgs(4), "Sequential")) {
    1007            3 :             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            3 :         thisPump.PumpControl = static_cast<PumpControlType>(getEnumValue(pumpCtrlTypeNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(5))));
    1018              : 
    1019            3 :         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            3 :         if (thisInput->lAlphaFieldBlanks(6)) {
    1030            0 :             thisPump.flowRateSched = nullptr;
    1031            3 :         } else if ((thisPump.flowRateSched = Sched::GetSchedule(state, thisInput->cAlphaArgs(6))) == nullptr) {
    1032            3 :             ShowWarningItemNotFound(state, eoh, thisInput->cAlphaFieldNames(6), thisInput->cAlphaArgs(6), "");
    1033              :         }
    1034              : 
    1035            3 :         thisPump.NomVolFlowRate = thisInput->rNumericArgs(1);
    1036            3 :         if (thisPump.NomVolFlowRate == AutoSize) {
    1037            0 :             thisPump.NomVolFlowRateWasAutoSized = true;
    1038              :         }
    1039            3 :         thisPump.NumPumpsInBank = thisInput->rNumericArgs(2);
    1040            3 :         thisPump.NomPumpHead = thisInput->rNumericArgs(3);
    1041            3 :         thisPump.NomPowerUse = thisInput->rNumericArgs(4);
    1042            3 :         if (thisPump.NomPowerUse == AutoSize) {
    1043            3 :             thisPump.NomPowerUseWasAutoSized = true;
    1044              :         }
    1045            3 :         thisPump.MotorEffic = thisInput->rNumericArgs(5);
    1046            3 :         thisPump.FracMotorLossToFluid = thisInput->rNumericArgs(6);
    1047            3 :         thisPump.PartLoadCoef[0] = 1.0;
    1048            3 :         thisPump.PartLoadCoef[1] = 0.0;
    1049            3 :         thisPump.PartLoadCoef[2] = 0.0;
    1050            3 :         thisPump.PartLoadCoef[3] = 0.0;
    1051              : 
    1052            3 :         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            3 :         if (!thisInput->lAlphaFieldBlanks(8)) {
    1070            2 :             thisPump.powerSizingMethod =
    1071            2 :                 static_cast<PowerSizingMethod>(getEnumValue(powerSizingMethodNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(8))));
    1072            2 :             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            3 :         if (!thisInput->lNumericFieldBlanks(8)) {
    1083            1 :             thisPump.powerPerFlowScalingFactor = thisInput->rNumericArgs(8);
    1084              :         }
    1085              : 
    1086            3 :         if (!thisInput->lNumericFieldBlanks(9)) {
    1087            1 :             thisPump.powerPerFlowPerPressureScalingFactor = thisInput->rNumericArgs(9);
    1088              :         }
    1089              : 
    1090            3 :         if (NumAlphas > 8) {
    1091            1 :             thisPump.EndUseSubcategoryName = thisInput->cAlphaArgs(9);
    1092              :         } else {
    1093            2 :             thisPump.EndUseSubcategoryName = "General";
    1094              :         }
    1095              : 
    1096            3 :         thisPump.MinVolFlowRate = 0.0;
    1097            3 :         thisPump.Energy = 0.0;
    1098            3 :         thisPump.Power = 0.0;
    1099              :     }
    1100              : 
    1101           40 :     if (ErrorsFound) {
    1102            0 :         ShowFatalError(state, "Errors found in getting Pump input");
    1103              :     }
    1104              : 
    1105           94 :     for (PumpNum = 1; PumpNum <= state.dataPumps->NumPumps; ++PumpNum) { // CurrentModuleObject='Pumps'
    1106           54 :         auto &thisPump = state.dataPumps->PumpEquip(PumpNum);
    1107           54 :         auto &thisPumpRep = state.dataPumps->PumpEquipReport(PumpNum);
    1108           54 :         switch (thisPump.pumpType) {
    1109           47 :         case PumpType::VarSpeed:
    1110              :         case PumpType::ConSpeed:
    1111              :         case PumpType::Cond: {
    1112              : 
    1113           94 :             SetupOutputVariable(state,
    1114              :                                 "Pump Electricity Energy",
    1115              :                                 Constant::Units::J,
    1116           47 :                                 thisPump.Energy,
    1117              :                                 OutputProcessor::TimeStepType::System,
    1118              :                                 OutputProcessor::StoreType::Sum,
    1119           47 :                                 thisPump.Name,
    1120              :                                 Constant::eResource::Electricity,
    1121              :                                 OutputProcessor::Group::Plant,
    1122              :                                 OutputProcessor::EndUseCat::Pumps,
    1123              :                                 thisPump.EndUseSubcategoryName);
    1124           94 :             SetupOutputVariable(state,
    1125              :                                 "Pump Electricity Rate",
    1126              :                                 Constant::Units::W,
    1127           47 :                                 thisPump.Power,
    1128              :                                 OutputProcessor::TimeStepType::System,
    1129              :                                 OutputProcessor::StoreType::Average,
    1130           47 :                                 thisPump.Name);
    1131           94 :             SetupOutputVariable(state,
    1132              :                                 "Pump Shaft Power",
    1133              :                                 Constant::Units::W,
    1134           47 :                                 thisPumpRep.ShaftPower,
    1135              :                                 OutputProcessor::TimeStepType::System,
    1136              :                                 OutputProcessor::StoreType::Average,
    1137           47 :                                 thisPump.Name);
    1138           94 :             SetupOutputVariable(state,
    1139              :                                 "Pump Fluid Heat Gain Rate",
    1140              :                                 Constant::Units::W,
    1141           47 :                                 thisPumpRep.PumpHeattoFluid,
    1142              :                                 OutputProcessor::TimeStepType::System,
    1143              :                                 OutputProcessor::StoreType::Average,
    1144           47 :                                 thisPump.Name);
    1145           94 :             SetupOutputVariable(state,
    1146              :                                 "Pump Fluid Heat Gain Energy",
    1147              :                                 Constant::Units::J,
    1148           47 :                                 thisPumpRep.PumpHeattoFluidEnergy,
    1149              :                                 OutputProcessor::TimeStepType::System,
    1150              :                                 OutputProcessor::StoreType::Sum,
    1151           47 :                                 thisPump.Name);
    1152           94 :             SetupOutputVariable(state,
    1153              :                                 "Pump Outlet Temperature",
    1154              :                                 Constant::Units::C,
    1155           47 :                                 thisPumpRep.OutletTemp,
    1156              :                                 OutputProcessor::TimeStepType::System,
    1157              :                                 OutputProcessor::StoreType::Average,
    1158           47 :                                 thisPump.Name);
    1159           94 :             SetupOutputVariable(state,
    1160              :                                 "Pump Mass Flow Rate",
    1161              :                                 Constant::Units::kg_s,
    1162           47 :                                 thisPumpRep.PumpMassFlowRate,
    1163              :                                 OutputProcessor::TimeStepType::System,
    1164              :                                 OutputProcessor::StoreType::Average,
    1165           47 :                                 thisPump.Name);
    1166           47 :         } 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           54 :         if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
    1238            1 :             SetupEMSInternalVariable(state, "Pump Maximum Mass Flow Rate", thisPump.Name, "[kg/s]", thisPump.MassFlowRateMax);
    1239            1 :             SetupEMSActuator(
    1240            1 :                 state, "Pump", thisPump.Name, "Pump Mass Flow Rate", "[kg/s]", thisPump.EMSMassFlowOverrideOn, thisPump.EMSMassFlowValue);
    1241            1 :             SetupEMSActuator(
    1242            1 :                 state, "Pump", thisPump.Name, "Pump Pressure Rise", "[Pa]", thisPump.EMSPressureOverrideOn, thisPump.EMSPressureOverrideValue);
    1243              :         }
    1244              : 
    1245           54 :         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       264659 : 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       264659 :     Real64 constexpr StartTemp(100.0); // Standard Temperature across code to calculated Steam density
    1356       264659 :     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       264659 :     auto &thisPump = state.dataPumps->PumpEquip(PumpNum);
    1369       264659 :     int InletNode = thisPump.InletNodeNum;
    1370       264659 :     int OutletNode = thisPump.OutletNodeNum;
    1371              : 
    1372              :     // One time inits
    1373       264659 :     if (thisPump.PumpOneTimeFlag) {
    1374              : 
    1375           35 :         bool errFlag = false;
    1376           35 :         ScanPlantLoopsForObject(state, thisPump.Name, thisPump.TypeOf_Num, thisPump.plantLoc, errFlag, _, _, _, _, _);
    1377           35 :         int plloopnum = thisPump.plantLoc.loopNum;
    1378           35 :         lsnum = thisPump.plantLoc.loopSideNum;
    1379           35 :         int brnum = thisPump.plantLoc.branchNum;
    1380           35 :         int cpnum = thisPump.plantLoc.compNum;
    1381           35 :         if (plloopnum > 0 && lsnum != DataPlant::LoopSideLocation::Invalid && brnum > 0 && cpnum > 0) {
    1382           35 :             auto &thisPumpLoc = state.dataPlnt->PlantLoop(plloopnum).LoopSide(lsnum).Branch(brnum);
    1383           35 :             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           35 :         } 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           35 :         if (errFlag) {
    1402            0 :             ShowFatalError(state, "InitializePumps: Program terminated due to previous condition(s).");
    1403              :         }
    1404           35 :         DataPlant::CompData::getPlantComponent(state, thisPump.plantLoc).CompNum = PumpNum;
    1405              : 
    1406           35 :         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           35 :         if (thisPump.NomPowerUse > ZeroPowerTol && thisPump.MotorEffic > ZeroPowerTol) {
    1412           35 :             TotalEffic = thisPump.NomVolFlowRate * thisPump.NomPumpHead / thisPump.NomPowerUse;
    1413           35 :             thisPump.PumpEffic = TotalEffic / thisPump.MotorEffic;
    1414           35 :             if (thisPump.PumpEffic < 0.50) {
    1415           12 :                 ShowWarningError(state,
    1416           12 :                                  format("Check input. Calculated Pump Efficiency={:.2R}% which is less than 50%, for pump={}",
    1417            0 :                                         thisPump.PumpEffic * 100.0,
    1418            6 :                                         thisPump.Name));
    1419           12 :                 ShowContinueError(state,
    1420           12 :                                   format("Calculated Pump_Efficiency % =Total_Efficiency % [{:.1R}] / Motor_Efficiency % [{:.1R}]",
    1421            0 :                                          TotalEffic * 100.0,
    1422            6 :                                          thisPump.MotorEffic * 100.0));
    1423           12 :                 ShowContinueError(
    1424              :                     state,
    1425           12 :                     format("Total_Efficiency % =(Rated_Volume_Flow_Rate [{:.3R}] * Rated_Pump_Head [{:.1R}] / Rated_Power_Use [{:.1R}]) * 100.",
    1426            6 :                            thisPump.NomVolFlowRate,
    1427            6 :                            thisPump.NomPumpHead,
    1428            6 :                            thisPump.NomPowerUse));
    1429           29 :             } 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           29 :             } 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            0 :             ShowWarningError(state, format("Check input. Pump nominal power or motor efficiency is set to 0, for pump={}", thisPump.Name));
    1463              :         }
    1464              : 
    1465           35 :         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           35 :         if (thisPump.PumpControl == PumpControlType::Continuous) {
    1470              :             // reset flow priority appropriately (default was for Intermittent)
    1471            0 :             DataPlant::CompData::getPlantComponent(state, thisPump.plantLoc).FlowPriority = DataPlant::LoopFlowStatus::NeedyAndTurnsLoopOn;
    1472              :         }
    1473              : 
    1474           35 :         thisPump.PumpOneTimeFlag = false;
    1475              :     }
    1476              : 
    1477              :     // HVAC Sizing Simulation resizing calls if needed
    1478       264659 :     if (state.dataGlobal->RedoSizesHVACSimulation && !state.dataPlnt->PlantReSizingCompleted) {
    1479            0 :         SizePump(state, PumpNum);
    1480              :     }
    1481              : 
    1482              :     // Begin environment inits
    1483       264659 :     if (thisPump.PumpInitFlag && state.dataGlobal->BeginEnvrnFlag) {
    1484           86 :         if (thisPump.pumpType == PumpType::Cond) {
    1485            0 :             TempWaterDensity = Fluid::GetWater(state)->getDensity(state, Constant::InitConvTemp, RoutineName);
    1486            0 :             SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, StartTemp, 1.0, RoutineName);
    1487            0 :             thisPump.NomVolFlowRate = (thisPump.NomSteamVolFlowRate * SteamDensity) / TempWaterDensity;
    1488              : 
    1489              :             // set the maximum flow rate on the outlet node
    1490            0 :             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            0 :             mdotMin = 0.0;
    1499            0 :             InitComponentNodes(state, mdotMin, mdotMax, InletNode, OutletNode);
    1500            0 :             thisPump.MassFlowRateMax = mdotMax;
    1501            0 :             thisPump.MassFlowRateMin = thisPump.MinVolFlowRate * SteamDensity;
    1502              : 
    1503              :         } else {
    1504           86 :             auto &thisPumpPlant = state.dataPlnt->PlantLoop(thisPump.plantLoc.loopNum);
    1505           86 :             TempWaterDensity = thisPumpPlant.glycol->getDensity(state, Constant::InitConvTemp, RoutineName);
    1506           86 :             mdotMax = thisPump.NomVolFlowRate * TempWaterDensity;
    1507              :             // mdotMin = PumpEquip(PumpNum)%MinVolFlowRate * TempWaterDensity
    1508              :             // see note above
    1509           86 :             mdotMin = 0.0;
    1510           86 :             InitComponentNodes(state, mdotMin, mdotMax, InletNode, OutletNode);
    1511           86 :             thisPump.MassFlowRateMax = mdotMax;
    1512           86 :             thisPump.MassFlowRateMin = thisPump.MinVolFlowRate * TempWaterDensity;
    1513              :         }
    1514              :         // zero out report variables
    1515           86 :         thisPump.Energy = 0.0;
    1516           86 :         thisPump.Power = 0.0;
    1517           86 :         new (&(state.dataPumps->PumpEquipReport(PumpNum))) ReportVars();
    1518           86 :         thisPump.PumpInitFlag = false;
    1519              :     }
    1520              : 
    1521              :     // Reset the local environment flag for the next environment
    1522       264659 :     if (!state.dataGlobal->BeginEnvrnFlag) thisPump.PumpInitFlag = true;
    1523              : 
    1524              :     // zero out module level working variables
    1525       264659 :     auto const &daPumps = state.dataPumps;
    1526       264659 :     daPumps->PumpMassFlowRate = 0.0;
    1527       264659 :     daPumps->PumpHeattoFluid = 0.0;
    1528       264659 :     daPumps->Power = 0.0;
    1529       264659 :     daPumps->ShaftPower = 0.0;
    1530       264659 : }
    1531              : 
    1532              : //*************************************************************************!
    1533              : 
    1534              : //*************************************************************************!
    1535              : 
    1536        88208 : void SetupPumpMinMaxFlows(EnergyPlusData &state, int const LoopNum, int const PumpNum)
    1537              : {
    1538              : 
    1539              :     // SUBROUTINE INFORMATION:
    1540              :     //       AUTHOR:        Edwin Lee
    1541              :     //       DATE WRITTEN:  Aug 2010
    1542              :     //       MODIFIED       Based on the Flow control portion of what was previously Pumps::InitSimVars, by:
    1543              :     //                        Dan Fisher October 1998
    1544              :     //                        Richard Liesen July 2001
    1545              :     //                        July 2001, Rick Strand (implemented new pump controls)
    1546              :     //                        May 2009, Brent Griffith (added EMS override capability)
    1547              :     //                        B. Griffith, Nov 2011 Pump control: Intermittent vs Continuous
    1548              :     //       RE-ENGINEERED
    1549              : 
    1550              :     // PURPOSE OF THIS SUBROUTINE:
    1551              :     // This subroutine initializes the pump minAvail and maxAvail flow rates, and assigns them to the
    1552              :     //  outlet min/max avail according to inlet min/max constraints and zero flow request
    1553              :     // The loop solver then uses this information to set up the flow bounds for the loop side
    1554              :     //  for the current iteration.
    1555              : 
    1556              :     // METHODOLOGY EMPLOYED:
    1557              :     //  Design flow rate and user specified minimum flow rate is compared in the inlet node
    1558              :     //  min/maxavail.  The pump output is appropriately constrained.
    1559              :     //  Design flow is rated flow times schedule fraction
    1560              :     //  Inlet node max will represent the rated flow rate according to pump init routines.
    1561              :     //  These values are bounded by hardware min constraints on the inlet node, which is likely zero.
    1562              :     //  These values are also bounded by EMS overridable limit of max flow rate.
    1563              : 
    1564              :     // Using/Aliasing
    1565              :     using PlantPressureSystem::ResolveLoopFlowVsPressure;
    1566              :     using PlantUtilities::BoundValueToWithinTwoValues;
    1567              : 
    1568              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1569              :     int InletNode;  // pump inlet node number
    1570              :     int OutletNode; // pump outlet node number
    1571              :     Real64 InletNodeMax;
    1572              :     Real64 InletNodeMin;
    1573              :     Real64 PumpMassFlowRateMax; // max allowable flow rate at the pump
    1574              :     Real64 PumpMassFlowRateMin; // min allowable flow rate at the pump
    1575              :     Real64 PumpSchedFraction;
    1576              :     Real64 PumpOverridableMaxLimit;
    1577              :     Real64 PumpMassFlowRateMinLimit;
    1578              :     Real64 PumpSchedRPM; // Pump RPM Optional Input
    1579              : 
    1580        88208 :     auto &thisPump = state.dataPumps->PumpEquip(PumpNum);
    1581              : 
    1582              :     // Inlet/Outlet Node Numbers
    1583        88208 :     InletNode = thisPump.InletNodeNum;
    1584        88208 :     OutletNode = thisPump.OutletNodeNum;
    1585        88208 :     auto &thisInNode = state.dataLoopNodes->Node(InletNode);
    1586        88208 :     auto &thisOutNode = state.dataLoopNodes->Node(OutletNode);
    1587              : 
    1588              :     // Inlet node Min/MaxAvail
    1589        88208 :     InletNodeMax = thisInNode.MassFlowRateMaxAvail;
    1590        88208 :     InletNodeMin = thisInNode.MassFlowRateMinAvail;
    1591              : 
    1592              :     // Retrieve the pump speed fraction from the pump schedule (if any)
    1593        88208 :     PumpSchedFraction = (thisPump.flowRateSched != nullptr) ? std::clamp(thisPump.flowRateSched->getCurrentVal(), 0.0, 1.0) : 1.0;
    1594              : 
    1595              :     // User specified min/max mass flow rates for pump
    1596        88208 :     PumpOverridableMaxLimit = thisPump.MassFlowRateMax;
    1597              : 
    1598              :     // override the user specified min to allow pump to turn off when no flow is required.
    1599        88208 :     if (thisPump.LoopSolverOverwriteFlag) {
    1600        32004 :         PumpMassFlowRateMinLimit = 0.0;
    1601              :     } else {
    1602        56204 :         PumpMassFlowRateMinLimit = thisPump.MassFlowRateMin;
    1603              :     }
    1604              : 
    1605              :     // The pump outlet node Min/MaxAvail
    1606        88208 :     PumpMassFlowRateMin = max(InletNodeMin, PumpMassFlowRateMinLimit);
    1607        88208 :     PumpMassFlowRateMax = min(InletNodeMax, PumpOverridableMaxLimit * PumpSchedFraction);
    1608              : 
    1609              :     // Check for conflicts (MaxAvail < MinAvail)
    1610        88208 :     if (PumpMassFlowRateMin > PumpMassFlowRateMax) { // the demand side wants to operate outside of the pump range
    1611              :         // shut the pump (and the loop) down
    1612            0 :         PumpMassFlowRateMin = 0.0;
    1613            0 :         PumpMassFlowRateMax = 0.0;
    1614              :         // Let the user know that his input file is overconstrained
    1615              :     }
    1616              : 
    1617        88208 :     auto const &thisPumpPlant = state.dataPlnt->PlantLoop(thisPump.plantLoc.loopNum);
    1618              : 
    1619        88208 :     switch (thisPump.pumpType) {
    1620        68156 :     case PumpType::VarSpeed: {
    1621        68156 :         if (thisPump.HasVFD) {
    1622            0 :             switch (thisPump.VFD.VFDControlType) {
    1623            0 :             case ControlTypeVFD::VFDManual: {
    1624              :                 // Evaluate the schedule if it exists and put the fraction into a local variable
    1625            0 :                 PumpSchedRPM = thisPump.VFD.manualRPMSched->getCurrentVal();
    1626              :                 // Convert the RPM to rot/sec for calculation routine
    1627            0 :                 thisPump.RotSpeed = PumpSchedRPM / 60.0;
    1628              :                 // Resolve the new mass flow rate based on current pressure characteristics
    1629            0 :                 if (thisPumpPlant.UsePressureForPumpCalcs && thisPumpPlant.PressureSimType == DataPlant::PressSimType::FlowCorrection &&
    1630            0 :                     thisPumpPlant.PressureDrop > 0.0) {
    1631              : 
    1632            0 :                     state.dataPumps->PumpMassFlowRate = ResolveLoopFlowVsPressure(state,
    1633              :                                                                                   thisPump.plantLoc.loopNum,
    1634            0 :                                                                                   state.dataLoopNodes->Node(thisPump.InletNodeNum).MassFlowRate,
    1635              :                                                                                   thisPump.PressureCurve_Index,
    1636              :                                                                                   thisPump.RotSpeed,
    1637              :                                                                                   thisPump.ImpellerDiameter,
    1638              :                                                                                   thisPump.MinPhiValue,
    1639              :                                                                                   thisPump.MaxPhiValue);
    1640              : 
    1641            0 :                     PumpMassFlowRateMax = state.dataPumps->PumpMassFlowRate;
    1642            0 :                     PumpMassFlowRateMin = state.dataPumps->PumpMassFlowRate;
    1643              :                 }
    1644            0 :             } break;
    1645            0 :             case ControlTypeVFD::VFDAutomatic: {
    1646            0 :                 if (thisPumpPlant.UsePressureForPumpCalcs && thisPumpPlant.PressureSimType == DataPlant::PressSimType::FlowCorrection &&
    1647            0 :                     thisPumpPlant.PressureDrop > 0.0) {
    1648              : 
    1649            0 :                     GetRequiredMassFlowRate(state,
    1650              :                                             LoopNum,
    1651              :                                             PumpNum,
    1652            0 :                                             state.dataLoopNodes->Node(thisPump.InletNodeNum).MassFlowRate,
    1653            0 :                                             state.dataPumps->PumpMassFlowRate,
    1654              :                                             PumpMassFlowRateMin,
    1655              :                                             PumpMassFlowRateMax);
    1656              :                 }
    1657            0 :             } break;
    1658            0 :             default:
    1659            0 :                 break;
    1660              :             } // VFDControlType
    1661              :         }
    1662              : 
    1663        68156 :         if (thisPump.PumpControl == PumpControlType::Continuous) {
    1664            0 :             thisInNode.MassFlowRateRequest = PumpMassFlowRateMin;
    1665              :         }
    1666        68156 :     } break;
    1667        20052 :     case PumpType::ConSpeed: {
    1668        20052 :         if (thisPump.PumpControl == PumpControlType::Continuous) {
    1669            0 :             PumpMassFlowRateMin = PumpMassFlowRateMax;
    1670            0 :             thisInNode.MassFlowRateRequest = PumpMassFlowRateMin;
    1671              :         }
    1672              : 
    1673              :         // Override (lock down flow) for pressure drop if applicable
    1674        20052 :         if (thisPump.plantLoc.loopNum > 0) {
    1675        20052 :             if (thisPumpPlant.UsePressureForPumpCalcs && thisPumpPlant.PressureSimType == DataPlant::PressSimType::FlowCorrection &&
    1676            0 :                 thisPumpPlant.PressureDrop > 0.0) {
    1677            0 :                 state.dataPumps->PumpMassFlowRate = ResolveLoopFlowVsPressure(state,
    1678              :                                                                               thisPump.plantLoc.loopNum,
    1679            0 :                                                                               state.dataLoopNodes->Node(thisPump.InletNodeNum).MassFlowRate,
    1680              :                                                                               thisPump.PressureCurve_Index,
    1681              :                                                                               thisPump.RotSpeed,
    1682              :                                                                               thisPump.ImpellerDiameter,
    1683              :                                                                               thisPump.MinPhiValue,
    1684              :                                                                               thisPump.MaxPhiValue);
    1685            0 :                 PumpMassFlowRateMax = state.dataPumps->PumpMassFlowRate;
    1686            0 :                 PumpMassFlowRateMin = state.dataPumps->PumpMassFlowRate;
    1687              :             }
    1688              :         }
    1689        20052 :     } break;
    1690            0 :     default:
    1691            0 :         break;
    1692              :     }
    1693              : 
    1694              :     // Override pump operation based on System Availability Managers, should be done elsewhere?  I suppose this should be OK though
    1695        88208 :     if (allocated(state.dataAvail->PlantAvailMgr)) {
    1696        88208 :         if (state.dataAvail->PlantAvailMgr(LoopNum).availStatus == Avail::Status::ForceOff) {
    1697          712 :             PumpMassFlowRateMax = 0.0;
    1698          712 :             PumpMassFlowRateMin = 0.0;
    1699              :         }
    1700              :     }
    1701              : 
    1702              :     // Check if EMS is overriding flow
    1703        88208 :     if (thisPump.EMSMassFlowOverrideOn) {
    1704            0 :         PumpMassFlowRateMax = thisPump.EMSMassFlowValue;
    1705            0 :         PumpMassFlowRateMin = thisPump.EMSMassFlowValue;
    1706              :     }
    1707              : 
    1708              :     // Update outlet node to allow loop solver to get data
    1709              :     // could avoid this by passing data in/out to avoid putting things on nodes
    1710        88208 :     thisOutNode.MassFlowRateMinAvail = PumpMassFlowRateMin;
    1711        88208 :     thisOutNode.MassFlowRateMaxAvail = PumpMassFlowRateMax;
    1712        88208 : }
    1713              : 
    1714       176452 : void CalcPumps(EnergyPlusData &state, int const PumpNum, Real64 const FlowRequest, bool &PumpRunning)
    1715              : {
    1716              : 
    1717              :     // SUBROUTINE INFORMATION:
    1718              :     //       AUTHOR         Dan Fisher
    1719              :     //       DATE WRITTEN   Sept. 1998
    1720              :     //       MODIFIED       July 2001, Rick Strand
    1721              :     //       RE-ENGINEERED  Sept 2010, Edwin Lee
    1722              : 
    1723              :     // PURPOSE OF THIS SUBROUTINE:
    1724              :     // This subroutines simulates a pump following
    1725              :     // the methodology oulined in ASHRAE's secondary toolkit.
    1726              : 
    1727              :     // METHODOLOGY EMPLOYED:
    1728              :     // Calculates power and updates other pump things.
    1729              : 
    1730              :     // REFERENCES:
    1731              :     // HVAC 2 Toolkit:  A Toolkit for Secondary HVAC System
    1732              :     // Energy Calculations, ASHRAE, 1993, pp2-10 to 2-15
    1733              : 
    1734              :     // Using/Aliasing
    1735              :     using PlantUtilities::SetComponentFlowRate;
    1736              : 
    1737              :     // SUBROUTINE PARAMETER DEFINITIONS:
    1738              :     static constexpr std::string_view RoutineName("PlantPumps:CalcPumps: ");
    1739              : 
    1740              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1741              :     int InletNode;
    1742              :     int OutletNode;
    1743              :     Real64 LoopDensity;
    1744       176452 :     Real64 VolFlowRate = 0.0;
    1745              :     Real64 PartLoadRatio;
    1746              :     Real64 FracFullLoadPower;
    1747              :     Real64 FullLoadVolFlowRate;
    1748              :     Real64 PartLoadVolFlowRate;
    1749              :     Real64 FullLoadPower;
    1750              :     Real64 FullLoadPowerRatio;
    1751              :     Real64 TotalEffic;
    1752              :     PumpType pumpType;
    1753              :     Real64 RotSpeed_Min;
    1754              :     Real64 RotSpeed_Max;
    1755              :     Real64 PumpActualRPMValueOne;
    1756              :     Real64 PumpActualRPMValueTwo;
    1757              : 
    1758       176452 :     auto &daPumps = state.dataPumps;
    1759       176452 :     auto &thisPump = state.dataPumps->PumpEquip(PumpNum);
    1760              : 
    1761       176452 :     InletNode = thisPump.InletNodeNum;
    1762       176452 :     OutletNode = thisPump.OutletNodeNum;
    1763       176452 :     pumpType = thisPump.pumpType;
    1764              : 
    1765       176452 :     auto &thisInNode = state.dataLoopNodes->Node(InletNode);
    1766       176452 :     auto &thisOutNode = state.dataLoopNodes->Node(OutletNode);
    1767              : 
    1768              :     //****************************!
    1769              :     //** SETTING PUMP FLOW RATE **!
    1770              :     //****************************!
    1771              :     // So the loop solver always passes in the full loop side flow request to each pump called
    1772              :     // The pump will try to use this value according to its inlet conditions via the SetComponentFlowRate routine.
    1773              :     // If the loop solver is doing branch pumps, then individual parallel branch inlet nodes would have been previously
    1774              :     // constrained, so even though we pass in a full flow request, each pump will "pull down" to the min/max avail.
    1775              :     // Also, on flowlock == locked, we will just use the inlet node flow rate
    1776              :     // The flow resolver can take care of argument resolution beyond that.
    1777              :     // For a typical situation, the flow request should be within the values of min/max avail, so the pump will get this flow rate.
    1778       176452 :     if (FlowRequest > DataBranchAirLoopPlant::MassFlowTolerance) {
    1779        94317 :         daPumps->PumpMassFlowRate = FlowRequest;
    1780              :     } else {
    1781        82135 :         daPumps->PumpMassFlowRate = 0.0;
    1782              :     }
    1783              : 
    1784              :     // For variable speed branch pumps, with other components
    1785              :     //  on the branch, we are not going to assign a request.
    1786              :     // Other components on this branch will request flow for this branch
    1787              : 
    1788              :     //  ! If this is a variable speed pump
    1789       176452 :     if (thisPump.pumpType == PumpType::VarSpeed || thisPump.pumpType == PumpType::Bank_VarSpeed || thisPump.pumpType == PumpType::Cond) {
    1790       136338 :         if (DataPlant::CompData::getPlantComponent(state, thisPump.plantLoc).FlowCtrl == DataBranchAirLoopPlant::ControlType::SeriesActive) {
    1791            0 :             daPumps->PumpMassFlowRate = 0.0;
    1792              :         }
    1793              :     }
    1794              : 
    1795              :     // 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
    1796       176452 :     daPumps->PumpMassFlowRate = min(thisPump.MassFlowRateMax, daPumps->PumpMassFlowRate);
    1797       176452 :     daPumps->PumpMassFlowRate = max(thisPump.MassFlowRateMin, daPumps->PumpMassFlowRate);
    1798              : 
    1799       176452 :     SetComponentFlowRate(state, daPumps->PumpMassFlowRate, InletNode, OutletNode, thisPump.plantLoc);
    1800              : 
    1801       176452 :     auto &thisPumpPlant = state.dataPlnt->PlantLoop(thisPump.plantLoc.loopNum);
    1802              : 
    1803              :     // Get RPM value for reporting as output
    1804              :     // RPM is calculated using pump affinity laws for rotation speed
    1805       176452 :     if (thisPumpPlant.UsePressureForPumpCalcs && thisPump.HasVFD) {
    1806            0 :         RotSpeed_Min = thisPump.VFD.minRPMSched ? thisPump.VFD.minRPMSched->getCurrentVal() : 0.0;
    1807            0 :         RotSpeed_Max = thisPump.VFD.maxRPMSched ? thisPump.VFD.maxRPMSched->getCurrentVal() : 0.0;
    1808            0 :         if (thisPump.PumpMassFlowRateMaxRPM < DataBranchAirLoopPlant::MassFlowTolerance ||
    1809            0 :             thisPump.PumpMassFlowRateMinRPM < DataBranchAirLoopPlant::MassFlowTolerance) {
    1810            0 :             thisPump.VFD.PumpActualRPM = 0.0;
    1811              :         } else {
    1812            0 :             PumpActualRPMValueOne = (daPumps->PumpMassFlowRate / thisPump.PumpMassFlowRateMaxRPM) * RotSpeed_Max;
    1813            0 :             PumpActualRPMValueTwo = (daPumps->PumpMassFlowRate / thisPump.PumpMassFlowRateMinRPM) * RotSpeed_Min;
    1814            0 :             thisPump.VFD.PumpActualRPM = (PumpActualRPMValueOne + PumpActualRPMValueTwo) / 2;
    1815              :         }
    1816              :     }
    1817              : 
    1818              :     //****************************!
    1819              :     //** DETERMINE IF PUMP IS ON *!
    1820              :     //****************************!
    1821              :     // Since we don't allow series pumping, if there is ANY flow rate for this pump, THIS PUMP is driving the flow!  Therefore...
    1822       176452 :     PumpRunning = (daPumps->PumpMassFlowRate > DataBranchAirLoopPlant::MassFlowTolerance);
    1823              : 
    1824              :     //****************************!
    1825              :     //** UPDATE PUMP BANK USAGE **!
    1826              :     //****************************!
    1827       176452 :     switch (thisPump.pumpType) {
    1828            1 :     case PumpType::Bank_VarSpeed:
    1829              :     case PumpType::Bank_ConSpeed: {
    1830              :         // previously, pumps did whatever they wanted
    1831              :         // because of this a constant speed pump bank could adjust the flow rate as-desired
    1832              :         //  even if it was not allowed
    1833              :         // since pumps now must behave nicely like all other components, the calculation of number
    1834              :         //  of running pumps in a pump bank is the same for both bank types
    1835              :         // the pumps are loaded sequentially, and the last pump can have full or non-full part load
    1836              :         //  status...this is just how it works now.  The pump cannot *bump* up the flow on the loop
    1837              :         //  to make sure the last running pump is fully loaded anymore for constant speed pumps...sorry
    1838            1 :         if (daPumps->PumpMassFlowRate >= thisPump.MassFlowRateMax) {
    1839              :             // running full on
    1840            1 :             daPumps->NumPumpsRunning = thisPump.NumPumpsInBank;
    1841              :         } else {
    1842              :             // running at some sort of part load
    1843            0 :             daPumps->NumPumpsRunning = CEILING((daPumps->PumpMassFlowRate / (thisPump.MassFlowRateMax) * thisPump.NumPumpsInBank));
    1844            0 :             daPumps->NumPumpsRunning = min(daPumps->NumPumpsRunning, thisPump.NumPumpsInBank);
    1845              :         }
    1846            1 :     } break;
    1847       176451 :     default:
    1848       176451 :         break;
    1849              :     }
    1850              : 
    1851              :     //****************************!
    1852              :     //***** EXIT IF NO FLOW ******!
    1853              :     //****************************!
    1854       176452 :     if (daPumps->PumpMassFlowRate <= DataBranchAirLoopPlant::MassFlowTolerance) {
    1855        82135 :         thisOutNode.Temp = thisInNode.Temp;
    1856        82135 :         thisOutNode.Press = thisInNode.Press;
    1857        82135 :         thisOutNode.Quality = thisInNode.Quality;
    1858        82135 :         return;
    1859              :     }
    1860              : 
    1861              :     // density used for volumetric flow calculations
    1862        94317 :     LoopDensity = thisPumpPlant.glycol->getDensity(state, thisInNode.Temp, RoutineName);
    1863              : 
    1864              :     //****************************!
    1865              :     //***** CALCULATE POWER (1) **!
    1866              :     //****************************!
    1867        94317 :     switch (pumpType) {
    1868        94316 :     case PumpType::ConSpeed:
    1869              :     case PumpType::VarSpeed:
    1870              :     case PumpType::Cond: {
    1871        94316 :         VolFlowRate = daPumps->PumpMassFlowRate / LoopDensity;
    1872        94316 :         PartLoadRatio = min(1.0, (VolFlowRate / thisPump.NomVolFlowRate));
    1873        94316 :         FracFullLoadPower = thisPump.PartLoadCoef[0] + thisPump.PartLoadCoef[1] * PartLoadRatio + thisPump.PartLoadCoef[2] * pow_2(PartLoadRatio) +
    1874        94316 :                             thisPump.PartLoadCoef[3] * pow_3(PartLoadRatio);
    1875        94316 :         daPumps->Power = FracFullLoadPower * thisPump.NomPowerUse;
    1876              : 
    1877        94316 :     } break;
    1878            1 :     case PumpType::Bank_ConSpeed:
    1879              :     case PumpType::Bank_VarSpeed: {
    1880              :         // now just assume the last one is (or is not) running at part load
    1881              :         // if it is actually at full load, the calculations work out to PLR = 1
    1882              :         // for the last pump, so all is OK
    1883            1 :         daPumps->NumPumpsFullLoad = daPumps->NumPumpsRunning - 1;
    1884            1 :         FullLoadVolFlowRate = thisPump.NomVolFlowRate / thisPump.NumPumpsInBank;
    1885            1 :         PartLoadVolFlowRate = daPumps->PumpMassFlowRate / LoopDensity - FullLoadVolFlowRate * daPumps->NumPumpsFullLoad;
    1886            1 :         FullLoadPower = thisPump.NomPowerUse / thisPump.NumPumpsInBank;
    1887            1 :         FullLoadPowerRatio = thisPump.PartLoadCoef[0] + thisPump.PartLoadCoef[1] + thisPump.PartLoadCoef[2] + thisPump.PartLoadCoef[3];
    1888            1 :         PartLoadRatio = min(1.0, (PartLoadVolFlowRate / FullLoadVolFlowRate));
    1889            1 :         FracFullLoadPower = thisPump.PartLoadCoef[0] + thisPump.PartLoadCoef[1] * PartLoadRatio + thisPump.PartLoadCoef[2] * pow_2(PartLoadRatio) +
    1890            1 :                             thisPump.PartLoadCoef[3] * pow_3(PartLoadRatio);
    1891            1 :         daPumps->Power = (FullLoadPowerRatio * daPumps->NumPumpsFullLoad + FracFullLoadPower) * FullLoadPower;
    1892            1 :         if (thisPump.EMSPressureOverrideOn) {
    1893            1 :             VolFlowRate = PartLoadVolFlowRate;
    1894              :         }
    1895            1 :     } break;
    1896            0 :     default: {
    1897            0 :         assert(false);
    1898              :     } break;
    1899              :     }
    1900              : 
    1901              :     //****************************!
    1902              :     //***** CALCULATE POWER (2) **!
    1903              :     //****************************!
    1904        94317 :     if (daPumps->Power < 0.0) {
    1905            0 :         if (thisPump.PowerErrIndex1 == 0) {
    1906            0 :             ShowWarningMessage(
    1907              :                 state,
    1908            0 :                 format("{} Calculated Pump Power < 0, Type={}, Name={}", RoutineName, pumpTypeIDFNames[static_cast<int>(pumpType)], thisPump.Name));
    1909            0 :             ShowContinueErrorTimeStamp(state, "");
    1910            0 :             ShowContinueError(state, format("...PartLoadRatio=[{:.4R}], Fraction Full Load Power={:.4R}]", PartLoadRatio, FracFullLoadPower));
    1911            0 :             ShowContinueError(state, "...Power is set to 0 for continuing the simulation.");
    1912            0 :             ShowContinueError(state, "...Pump coefficients should be checked for producing this negative value.");
    1913              :         }
    1914            0 :         daPumps->Power = 0.0;
    1915            0 :         ShowRecurringWarningErrorAtEnd(
    1916              :             state,
    1917            0 :             format("{} Calculated Pump Power < 0, {}, Name={}, PLR=", RoutineName, pumpTypeIDFNames[static_cast<int>(pumpType)], thisPump.Name),
    1918            0 :             thisPump.PowerErrIndex1,
    1919              :             PartLoadRatio,
    1920              :             PartLoadRatio);
    1921            0 :         ShowRecurringContinueErrorAtEnd(state, "...Fraction Full Load Power=", thisPump.PowerErrIndex2, FracFullLoadPower, FracFullLoadPower);
    1922              :     }
    1923              : 
    1924              :     //****************************!
    1925              :     //***** CALCULATE POWER (3) **!
    1926              :     //****************************!
    1927              :     // Now if we are doing pressure-based simulation, then we have a means to calculate power exactly based on current
    1928              :     // simulation conditions (flow rate and pressure drop) along with knowledge about pump impeller and motor efficiencies
    1929              :     // Thus we will override the power that was calculated based on nominal values with the corrected pressure-based power
    1930        94317 :     if (thisPump.plantLoc.loopNum > 0) {
    1931        94317 :         if (thisPumpPlant.UsePressureForPumpCalcs) {
    1932            0 :             TotalEffic = thisPump.PumpEffic * thisPump.MotorEffic;
    1933              :             // Efficiency errors are caught previously, but it doesn't hurt to add another catch before dividing by zero!!!
    1934            0 :             if (TotalEffic == 0.0) {
    1935            0 :                 ShowSevereError(state,
    1936            0 :                                 format("{} Plant pressure simulation encountered a pump with zero efficiency: {}", RoutineName, thisPump.Name));
    1937            0 :                 ShowContinueError(state, "Check efficiency inputs for this pump component.");
    1938            0 :                 ShowFatalError(state, "Errors in plant calculation would result in divide-by-zero cause program termination.");
    1939              :             }
    1940            0 :             daPumps->Power = VolFlowRate * thisPumpPlant.PressureDrop / TotalEffic;
    1941              :         }
    1942              :     }
    1943              : 
    1944              :     // if user has specified a pressure value, then use it, same as for pressure-based simulation
    1945        94317 :     if (thisPump.EMSPressureOverrideOn) {
    1946            1 :         TotalEffic = thisPump.PumpEffic * thisPump.MotorEffic;
    1947              :         // Efficiency errors are caught previously, but it doesn't hurt to add another catch before dividing by zero!!!
    1948            1 :         if (TotalEffic == 0.0) {
    1949            0 :             ShowSevereError(state, format("{} Plant pump simulation encountered a pump with zero efficiency: {}", RoutineName, thisPump.Name));
    1950            0 :             ShowContinueError(state, "Check efficiency inputs for this pump component.");
    1951            0 :             ShowFatalError(state, "Errors in plant calculation would result in divide-by-zero cause program termination.");
    1952              :         }
    1953            1 :         daPumps->Power = VolFlowRate * thisPump.EMSPressureOverrideValue / TotalEffic;
    1954              :     }
    1955              : 
    1956              :     //****************************!
    1957              :     //***** CALCULATE POWER (4) **!
    1958              :     //****************************!
    1959              :     // This adds the pump heat based on User input for the pump
    1960              :     // We assume that all of the heat ends up in the fluid eventually since this is a closed loop
    1961        94317 :     daPumps->ShaftPower = daPumps->Power * thisPump.MotorEffic;
    1962        94317 :     daPumps->PumpHeattoFluid = daPumps->ShaftPower + (daPumps->Power - daPumps->ShaftPower) * thisPump.FracMotorLossToFluid;
    1963              : 
    1964              :     //****************************!
    1965              :     //***** UPDATE INFORMATION ***!
    1966              :     //****************************!
    1967              :     // Update data structure variables
    1968        94317 :     thisPump.Power = daPumps->Power;
    1969              : 
    1970              :     // Update outlet node conditions
    1971        94317 :     thisOutNode.Temp = thisInNode.Temp;
    1972        94317 :     thisOutNode.Press = thisInNode.Press;
    1973        94317 :     thisOutNode.Quality = thisInNode.Quality;
    1974              : }
    1975              : 
    1976           52 : void SizePump(EnergyPlusData &state, int const PumpNum)
    1977              : {
    1978              : 
    1979              :     // SUBROUTINE INFORMATION:
    1980              :     //       AUTHOR         Fred Buhl
    1981              :     //       DATE WRITTEN   December 2001
    1982              :     //       MODIFIED       na
    1983              :     //       RE-ENGINEERED  na
    1984              : 
    1985              :     // PURPOSE OF THIS SUBROUTINE:
    1986              :     // This subroutine is for sizing Pump Components for which flow rates have not been
    1987              :     // specified in the input.
    1988              : 
    1989              :     // METHODOLOGY EMPLOYED:
    1990              :     // Obtains flow rates from the plant sizing array.
    1991              : 
    1992              :     // SUBROUTINE PARAMETER DEFINITIONS:
    1993           52 :     Real64 constexpr StartTemp(100.0); // Standard Temperature across code to calculated Steam density
    1994              :     static constexpr std::string_view RoutineName("PlantPumps::InitSimVars ");
    1995              :     static constexpr std::string_view RoutineNameSizePumps("SizePumps");
    1996              : 
    1997              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1998              :     int PlantSizNum; // index of Plant Sizing array
    1999              :     bool ErrorsFound;
    2000           52 :     Real64 TotalEffic = 0.0; // pump total efficiency
    2001              :     Real64 PumpSizFac;       // pump sizing factor
    2002              :     Real64 SteamDensity;
    2003              :     Real64 TempWaterDensity;
    2004           52 :     int DummyWaterIndex(1);
    2005              :     Real64 DesVolFlowRatePerBranch; // local temporary for split of branch pumps
    2006              : 
    2007           52 :     auto &thisPump = state.dataPumps->PumpEquip(PumpNum);
    2008           52 :     bool thisOkToReport = state.dataPlnt->PlantFinalSizesOkayToReport;
    2009              : 
    2010              :     // Calculate density at InitConvTemp once here, to remove RhoH2O calls littered throughout
    2011           52 :     if (thisPump.plantLoc.loopNum > 0) {
    2012           35 :         auto &thisPumpPlant = state.dataPlnt->PlantLoop(thisPump.plantLoc.loopNum);
    2013           35 :         TempWaterDensity = thisPumpPlant.glycol->getDensity(state, Constant::InitConvTemp, RoutineName);
    2014              :     } else {
    2015           17 :         TempWaterDensity = Fluid::GetWater(state)->getDensity(state, Constant::InitConvTemp, RoutineName);
    2016              :     }
    2017              : 
    2018           52 :     PlantSizNum = 0;
    2019           52 :     PumpSizFac = 1.0;
    2020           52 :     ErrorsFound = false;
    2021              : 
    2022           52 :     if (thisPump.plantLoc.loopNum > 0) {
    2023           35 :         PlantSizNum = state.dataPlnt->PlantLoop(thisPump.plantLoc.loopNum).PlantSizNum;
    2024              :     }
    2025              :     // use pump sizing factor stored in plant sizing data structure
    2026           52 :     if (PlantSizNum > 0) {
    2027           15 :         PumpSizFac = state.dataSize->PlantSizData(PlantSizNum).PlantSizFac;
    2028              :     } else {
    2029              :         // might be able to remove this next block
    2030           37 :         if (thisPump.plantLoc.loopNum > 0) {
    2031           40 :             for (DataPlant::LoopSideLocation Side : DataPlant::LoopSideKeys) {
    2032           40 :                 auto &thisPumpLoop = state.dataPlnt->PlantLoop(thisPump.plantLoc.loopNum).LoopSide(Side);
    2033          114 :                 for (int BranchNum = 1; BranchNum <= thisPumpLoop.TotalBranches; ++BranchNum) {
    2034           94 :                     auto &thisPumpBranch = thisPumpLoop.Branch(BranchNum);
    2035          168 :                     for (int CompNum = 1; CompNum <= thisPumpBranch.TotalComponents; ++CompNum) {
    2036           94 :                         auto const &thisPumpComp = thisPumpBranch.Comp(CompNum);
    2037           94 :                         if (thisPump.InletNodeNum == thisPumpComp.NodeNumIn && thisPump.OutletNodeNum == thisPumpComp.NodeNumOut) {
    2038           20 :                             if (thisPumpBranch.PumpSizFac > 0.0) {
    2039           20 :                                 PumpSizFac = thisPumpBranch.PumpSizFac;
    2040              :                             } else {
    2041            0 :                                 PumpSizFac = 1.0;
    2042              :                             }
    2043           20 :                             goto SideLoop_exit;
    2044              :                         }
    2045              :                     }
    2046              :                 }
    2047              :             }
    2048           20 :         SideLoop_exit:;
    2049              :         }
    2050              :     }
    2051              : 
    2052           52 :     if (thisPump.NomVolFlowRateWasAutoSized) {
    2053              : 
    2054            8 :         if (PlantSizNum > 0) {
    2055            8 :             auto &thisPumpPlant = state.dataPlnt->PlantLoop(thisPump.plantLoc.loopNum);
    2056            8 :             auto &thisPlantSize = state.dataSize->PlantSizData(PlantSizNum);
    2057            8 :             if (thisPlantSize.DesVolFlowRate >= SmallWaterVolFlow) {
    2058            8 :                 if (!thisPumpPlant.LoopSide(thisPump.plantLoc.loopSideNum).BranchPumpsExist) {
    2059              :                     // size pump to full flow of plant loop
    2060            8 :                     if (thisPump.pumpType == PumpType::Cond) {
    2061            0 :                         TempWaterDensity = Fluid::GetWater(state)->getDensity(state, Constant::InitConvTemp, RoutineName);
    2062            0 :                         SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, StartTemp, 1.0, RoutineNameSizePumps);
    2063            0 :                         thisPump.NomSteamVolFlowRate = thisPlantSize.DesVolFlowRate * PumpSizFac;
    2064            0 :                         thisPump.NomVolFlowRate = thisPump.NomSteamVolFlowRate * SteamDensity / TempWaterDensity;
    2065              :                     } else {
    2066            8 :                         thisPump.NomVolFlowRate = thisPlantSize.DesVolFlowRate * PumpSizFac;
    2067              :                     }
    2068              :                 } else {
    2069              :                     // Distribute sizes evenly across all branch pumps
    2070            0 :                     DesVolFlowRatePerBranch = thisPlantSize.DesVolFlowRate / thisPumpPlant.LoopSide(thisPump.plantLoc.loopSideNum).TotalPumps;
    2071            0 :                     if (thisPump.pumpType == PumpType::Cond) {
    2072            0 :                         TempWaterDensity = Fluid::GetWater(state)->getDensity(state, Constant::InitConvTemp, RoutineName);
    2073            0 :                         SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, StartTemp, 1.0, RoutineNameSizePumps);
    2074            0 :                         thisPump.NomSteamVolFlowRate = DesVolFlowRatePerBranch * PumpSizFac;
    2075            0 :                         thisPump.NomVolFlowRate = thisPump.NomSteamVolFlowRate * SteamDensity / TempWaterDensity;
    2076              :                     } else {
    2077            0 :                         thisPump.NomVolFlowRate = DesVolFlowRatePerBranch * PumpSizFac;
    2078              :                     }
    2079              :                 }
    2080              : 
    2081              :             } else {
    2082            0 :                 if (thisOkToReport) {
    2083            0 :                     thisPump.NomVolFlowRate = 0.0;
    2084            0 :                     ShowWarningError(
    2085              :                         state,
    2086            0 :                         format("SizePump: Calculated Pump Nominal Volume Flow Rate=[{:.2R}] is too small. Set to 0.0", thisPlantSize.DesVolFlowRate));
    2087            0 :                     ShowContinueError(state, format("..occurs for Pump={}", thisPump.Name));
    2088              :                 }
    2089              :             }
    2090            8 :             if (thisOkToReport) {
    2091           16 :                 BaseSizer::reportSizerOutput(
    2092            8 :                     state, pumpTypeIDFNames[static_cast<int>(thisPump.pumpType)], thisPump.Name, "Design Flow Rate [m3/s]", thisPump.NomVolFlowRate);
    2093              :             }
    2094            8 :             if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    2095            0 :                 BaseSizer::reportSizerOutput(state,
    2096            0 :                                              pumpTypeIDFNames[static_cast<int>(thisPump.pumpType)],
    2097              :                                              thisPump.Name,
    2098              :                                              "Initial Design Flow Rate [m3/s]",
    2099              :                                              thisPump.NomVolFlowRate);
    2100              :             }
    2101              :         } else {
    2102            0 :             if (thisOkToReport) {
    2103            0 :                 ShowSevereError(state, "Autosizing of plant loop pump flow rate requires a loop Sizing:Plant object");
    2104            0 :                 ShowContinueError(state, format("Occurs in plant pump object={}", thisPump.Name));
    2105            0 :                 ErrorsFound = true;
    2106              :             }
    2107              :         }
    2108              :     }
    2109              : 
    2110              :     // Note that autocalculation of power is based on nominal volume flow, regardless of whether the flow was
    2111              :     //  auto-sized or manually sized.  Thus, this must go after the flow sizing block above.
    2112           52 :     if (thisPump.NomPowerUseWasAutoSized) {
    2113           26 :         if (thisPump.NomVolFlowRate >= SmallWaterVolFlow) {
    2114           26 :             switch (thisPump.powerSizingMethod) {
    2115              : 
    2116            5 :             case PowerSizingMethod::SizePowerPerFlow: {
    2117            5 :                 TotalEffic = thisPump.NomPumpHead / thisPump.powerPerFlowScalingFactor;
    2118            5 :                 break;
    2119              :             }
    2120              : 
    2121           21 :             case PowerSizingMethod::SizePowerPerFlowPerPressure: {
    2122           21 :                 TotalEffic = (1 / thisPump.powerPerFlowPerPressureScalingFactor) * thisPump.MotorEffic;
    2123           21 :                 break;
    2124              :             }
    2125            0 :             default:
    2126            0 :                 assert(false);
    2127              :             }
    2128              : 
    2129           26 :             thisPump.NomPowerUse = (thisPump.NomPumpHead * thisPump.NomVolFlowRate) / TotalEffic;
    2130              :         } else {
    2131            0 :             thisPump.NomPowerUse = 0.0;
    2132              :         }
    2133           26 :         if (thisOkToReport) {
    2134           18 :             BaseSizer::reportSizerOutput(
    2135            9 :                 state, pumpTypeIDFNames[static_cast<int>(thisPump.pumpType)], thisPump.Name, "Design Power Consumption [W]", thisPump.NomPowerUse);
    2136              :         }
    2137           26 :         if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    2138            0 :             BaseSizer::reportSizerOutput(state,
    2139            0 :                                          pumpTypeIDFNames[static_cast<int>(thisPump.pumpType)],
    2140              :                                          thisPump.Name,
    2141              :                                          "Initial Design Power Consumption [W]",
    2142              :                                          thisPump.NomPowerUse);
    2143              :         }
    2144              :     }
    2145              : 
    2146           52 :     if (thisPump.minVolFlowRateWasAutosized) {
    2147            4 :         thisPump.MinVolFlowRate = thisPump.NomVolFlowRate * thisPump.MinVolFlowRateFrac;
    2148            4 :         if (thisOkToReport) {
    2149            0 :             BaseSizer::reportSizerOutput(state,
    2150            0 :                                          pumpTypeIDFNames[static_cast<int>(thisPump.pumpType)],
    2151              :                                          thisPump.Name,
    2152              :                                          "Design Minimum Flow Rate [m3/s]",
    2153              :                                          thisPump.MinVolFlowRate);
    2154              :         }
    2155            4 :         if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    2156            0 :             BaseSizer::reportSizerOutput(state,
    2157            0 :                                          pumpTypeIDFNames[static_cast<int>(thisPump.pumpType)],
    2158              :                                          thisPump.Name,
    2159              :                                          "Initial Design Minimum Flow Rate [m3/s]",
    2160              :                                          thisPump.MinVolFlowRate);
    2161              :         }
    2162              :     }
    2163              : 
    2164           52 :     if (thisOkToReport) {
    2165           35 :         PumpDataForTable(state, PumpNum);
    2166              :     }
    2167              : 
    2168           52 :     if (ErrorsFound) {
    2169            0 :         ShowFatalError(state, "Preceding sizing errors cause program termination");
    2170              :     }
    2171           52 : }
    2172              : 
    2173       176451 : void ReportPumps(EnergyPlusData &state, int const PumpNum)
    2174              : {
    2175              : 
    2176              :     // SUBROUTINE INFORMATION:
    2177              :     //       AUTHOR:          Dan Fisher
    2178              :     //       DATE WRITTEN:    October 1998
    2179              :     //       MODIFIED         July 2001, Rick Strand (revision of pump module)
    2180              :     //       RE-ENGINEERED    na
    2181              : 
    2182              :     // PURPOSE OF THIS SUBROUTINE:
    2183              :     // This subroutine sets the pump reporting variables.
    2184              : 
    2185              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2186              :     int OutletNode;    // pump outlet node number
    2187              :     PumpType PumpType; // Current pump type
    2188              : 
    2189       176451 :     auto &thisPump = state.dataPumps->PumpEquip(PumpNum);
    2190       176451 :     auto &thisPumpRep = state.dataPumps->PumpEquipReport(PumpNum);
    2191              : 
    2192       176451 :     PumpType = thisPump.pumpType;
    2193       176451 :     OutletNode = thisPump.OutletNodeNum;
    2194       176451 :     auto const &thisOutNode = state.dataLoopNodes->Node(OutletNode);
    2195       176451 :     auto const &daPumps = state.dataPumps;
    2196              : 
    2197       176451 :     if (daPumps->PumpMassFlowRate <= DataBranchAirLoopPlant::MassFlowTolerance) {
    2198        82135 :         new (&(state.dataPumps->PumpEquipReport(PumpNum))) ReportVars();
    2199        82135 :         thisPumpRep.OutletTemp = thisOutNode.Temp;
    2200        82135 :         thisPump.Power = 0.0;
    2201        82135 :         thisPump.Energy = 0.0;
    2202              :     } else {
    2203        94316 :         thisPumpRep.PumpMassFlowRate = daPumps->PumpMassFlowRate;
    2204        94316 :         thisPumpRep.PumpHeattoFluid = daPumps->PumpHeattoFluid;
    2205        94316 :         thisPumpRep.OutletTemp = thisOutNode.Temp;
    2206        94316 :         thisPump.Power = daPumps->Power;
    2207        94316 :         thisPump.Energy = thisPump.Power * state.dataHVACGlobal->TimeStepSysSec;
    2208        94316 :         thisPumpRep.ShaftPower = daPumps->ShaftPower;
    2209        94316 :         thisPumpRep.PumpHeattoFluidEnergy = daPumps->PumpHeattoFluid * state.dataHVACGlobal->TimeStepSysSec;
    2210        94316 :         switch (PumpType) {
    2211        94316 :         case PumpType::ConSpeed:
    2212              :         case PumpType::VarSpeed:
    2213              :         case PumpType::Cond:
    2214        94316 :             thisPumpRep.NumPumpsOperating = 1;
    2215        94316 :             break;
    2216              : 
    2217            0 :         case PumpType::Bank_ConSpeed:
    2218              :         case PumpType::Bank_VarSpeed:
    2219            0 :             thisPumpRep.NumPumpsOperating = daPumps->NumPumpsRunning;
    2220            0 :             break;
    2221            0 :         default:
    2222            0 :             assert(false);
    2223              :             break;
    2224              :         }
    2225        94316 :         thisPumpRep.ZoneTotalGainRate = daPumps->Power - daPumps->PumpHeattoFluid;
    2226        94316 :         thisPumpRep.ZoneTotalGainEnergy = thisPumpRep.ZoneTotalGainRate * state.dataHVACGlobal->TimeStepSysSec;
    2227        94316 :         thisPumpRep.ZoneConvGainRate = (1 - thisPump.SkinLossRadFraction) * thisPumpRep.ZoneTotalGainRate;
    2228        94316 :         thisPumpRep.ZoneRadGainRate = thisPump.SkinLossRadFraction * thisPumpRep.ZoneTotalGainRate;
    2229              :     }
    2230       176451 : }
    2231              : 
    2232           35 : void PumpDataForTable(EnergyPlusData &state, int const NumPump)
    2233              : {
    2234              : 
    2235              :     // SUBROUTINE INFORMATION:
    2236              :     //       AUTHOR:          Jason Glazer
    2237              :     //       DATE WRITTEN:    September 2006
    2238              :     //       MODIFIED         na
    2239              :     //       RE-ENGINEERED    na
    2240              : 
    2241              :     // PURPOSE OF THIS SUBROUTINE:
    2242              :     // Pull data together for predefined tables.
    2243              : 
    2244              :     // Using/Aliasing
    2245              :     using namespace OutputReportPredefined;
    2246              : 
    2247              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2248           35 :     std::string equipName;
    2249              : 
    2250           35 :     auto &thisPump = state.dataPumps->PumpEquip(NumPump);
    2251           35 :     auto &thisReport = state.dataOutRptPredefined;
    2252              : 
    2253           35 :     equipName = thisPump.Name;
    2254           35 :     PreDefTableEntry(state, thisReport->pdchPumpType, equipName, pumpTypeIDFNames[static_cast<int>(thisPump.pumpType)]);
    2255           35 :     if (thisPump.PumpControl == PumpControlType::Continuous) {
    2256            0 :         PreDefTableEntry(state, thisReport->pdchPumpControl, equipName, "Continuous");
    2257           35 :     } else if (thisPump.PumpControl == PumpControlType::Intermittent) {
    2258           35 :         PreDefTableEntry(state, thisReport->pdchPumpControl, equipName, "Intermittent");
    2259              :     } else {
    2260            0 :         PreDefTableEntry(state, thisReport->pdchPumpControl, equipName, "Unknown");
    2261              :     }
    2262           35 :     PreDefTableEntry(state, thisReport->pdchPumpHead, equipName, thisPump.NomPumpHead);
    2263           35 :     PreDefTableEntry(state, thisReport->pdchPumpFlow, equipName, thisPump.NomVolFlowRate, 6);
    2264           35 :     PreDefTableEntry(state, thisReport->pdchPumpPower, equipName, thisPump.NomPowerUse);
    2265           35 :     if (thisPump.NomVolFlowRate != 0) {
    2266           35 :         PreDefTableEntry(state, thisReport->pdchPumpPwrPerFlow, equipName, thisPump.NomPowerUse / thisPump.NomVolFlowRate);
    2267              :     } else {
    2268            0 :         PreDefTableEntry(state, thisReport->pdchPumpPwrPerFlow, equipName, "-");
    2269              :     }
    2270           35 :     PreDefTableEntry(state, thisReport->pdchPumpEndUse, equipName, thisPump.EndUseSubcategoryName);
    2271           35 :     PreDefTableEntry(state, thisReport->pdchMotEff, equipName, thisPump.MotorEffic);
    2272              :     // Std 229
    2273           35 :     PreDefTableEntry(state, thisReport->pdchPumpAutosized, equipName, thisPump.NomVolFlowRateWasAutoSized ? "Yes" : "No");
    2274           70 :     PreDefTableEntry(state,
    2275           35 :                      thisReport->pdchPumpPlantloopName,
    2276              :                      equipName,
    2277           70 :                      thisPump.plantLoc.loopNum > 0 ? state.dataPlnt->PlantLoop(thisPump.plantLoc.loopNum).Name : "N/A");
    2278           70 :     PreDefTableEntry(
    2279              :         state,
    2280           35 :         thisReport->pdchPumpPlantloopBranchName,
    2281              :         equipName,
    2282           35 :         thisPump.plantLoc.loopNum > 0
    2283           70 :             ? state.dataPlnt->PlantLoop(thisPump.plantLoc.loopNum).LoopSide(thisPump.plantLoc.loopSideNum).Branch(thisPump.plantLoc.branchNum).Name
    2284              :             : "N/A");
    2285           35 : }
    2286              : 
    2287            0 : void GetRequiredMassFlowRate(EnergyPlusData &state,
    2288              :                              int const LoopNum,
    2289              :                              int const PumpNum,
    2290              :                              Real64 const InletNodeMassFlowRate,
    2291              :                              Real64 &ActualFlowRate,
    2292              :                              Real64 &PumpMinMassFlowRateVFDRange,
    2293              :                              Real64 &PumpMaxMassFlowRateVFDRange)
    2294              : {
    2295              :     // Using/Aliasing
    2296              :     using PlantPressureSystem::ResolveLoopFlowVsPressure;
    2297              :     using PlantUtilities::SetComponentFlowRate;
    2298              : 
    2299            0 :     Real64 PumpMassFlowRateMaxPress(0.0); // Maximum mass flow rate associated with maximum pressure limit
    2300            0 :     Real64 PumpMassFlowRateMinPress(0.0); // Minimum mass flow rate associated with minimum pressure limit
    2301            0 :     Real64 RotSpeed_Max(0.0);             // Maximum rotational speed in rps
    2302            0 :     Real64 RotSpeed_Min(0.0);             // Minimum rotational speed in rps
    2303            0 :     Real64 MinPress(0.0);                 // Minimum pressure
    2304            0 :     Real64 MaxPress(0.0);                 // Maximum pressure
    2305              : 
    2306            0 :     auto &thisPump = state.dataPumps->PumpEquip(PumpNum);
    2307              : 
    2308            0 :     RotSpeed_Min = thisPump.VFD.minRPMSched->getCurrentVal();
    2309            0 :     RotSpeed_Max = thisPump.VFD.maxRPMSched->getCurrentVal();
    2310            0 :     MinPress = thisPump.VFD.lowerPsetSched->getCurrentVal();
    2311            0 :     MaxPress = thisPump.VFD.upperPsetSched->getCurrentVal();
    2312              : 
    2313              :     // Calculate maximum and minimum mass flow rate associated with maximun and minimum RPM
    2314            0 :     if (thisPump.plantLoc.loopNum > 0) {
    2315            0 :         auto const &thisPlantLoop = state.dataPlnt->PlantLoop(thisPump.plantLoc.loopNum);
    2316            0 :         if (thisPlantLoop.UsePressureForPumpCalcs && thisPlantLoop.PressureSimType == DataPlant::PressSimType::FlowCorrection &&
    2317            0 :             thisPlantLoop.PressureDrop > 0.0) {
    2318            0 :             thisPump.PumpMassFlowRateMaxRPM = ResolveLoopFlowVsPressure(state,
    2319              :                                                                         thisPump.plantLoc.loopNum,
    2320              :                                                                         InletNodeMassFlowRate,
    2321              :                                                                         thisPump.PressureCurve_Index,
    2322              :                                                                         RotSpeed_Max,
    2323              :                                                                         thisPump.ImpellerDiameter,
    2324              :                                                                         thisPump.MinPhiValue,
    2325              :                                                                         thisPump.MaxPhiValue);
    2326            0 :             thisPump.PumpMassFlowRateMinRPM = ResolveLoopFlowVsPressure(state,
    2327              :                                                                         thisPump.plantLoc.loopNum,
    2328              :                                                                         InletNodeMassFlowRate,
    2329              :                                                                         thisPump.PressureCurve_Index,
    2330              :                                                                         RotSpeed_Min,
    2331              :                                                                         thisPump.ImpellerDiameter,
    2332              :                                                                         thisPump.MinPhiValue,
    2333              :                                                                         thisPump.MaxPhiValue);
    2334              :         }
    2335              :     }
    2336              : 
    2337              :     // Not correct necessarily, but values are coming out way wrong here, maxRPMmdot~3, minRPMmdot~62!
    2338            0 :     if (thisPump.PumpMassFlowRateMaxRPM < thisPump.PumpMassFlowRateMinRPM) {
    2339            0 :         thisPump.PumpMassFlowRateMaxRPM = thisPump.PumpMassFlowRateMinRPM;
    2340              :     }
    2341              : 
    2342              :     // Calculate maximum and minimum mass flow rate associated with operating pressure range
    2343            0 :     if (thisPump.plantLoc.loopNum > 0) {
    2344            0 :         auto const &thisPlantLoop = state.dataPlnt->PlantLoop(LoopNum);
    2345            0 :         if (thisPlantLoop.PressureEffectiveK > 0.0) {
    2346            0 :             PumpMassFlowRateMaxPress = std::sqrt(MaxPress / thisPlantLoop.PressureEffectiveK);
    2347            0 :             PumpMassFlowRateMinPress = std::sqrt(MinPress / thisPlantLoop.PressureEffectiveK);
    2348              :         }
    2349              :     }
    2350              : 
    2351              :     // Decide operating range for mass flow rate
    2352              :     // Maximum mass flow rate value of the range
    2353            0 :     if (thisPump.PumpMassFlowRateMaxRPM > PumpMassFlowRateMaxPress) {
    2354              :         // Maximum pressure value governs maximum VFD range value
    2355            0 :         PumpMaxMassFlowRateVFDRange = PumpMassFlowRateMaxPress;
    2356              :     } else {
    2357              :         // Maximum RPM value governs maximum VFD range value
    2358            0 :         PumpMaxMassFlowRateVFDRange = thisPump.PumpMassFlowRateMaxRPM;
    2359              :     }
    2360              : 
    2361              :     // Minimum mass flow rate value of the range
    2362            0 :     if (thisPump.PumpMassFlowRateMinRPM > PumpMassFlowRateMinPress) {
    2363              :         // Minimum pressure value governs minimum VFD range value
    2364            0 :         PumpMinMassFlowRateVFDRange = thisPump.PumpMassFlowRateMinRPM;
    2365              :     } else {
    2366              :         // Minimum pressure range value governs minimum VFD range value
    2367            0 :         PumpMinMassFlowRateVFDRange = PumpMassFlowRateMinPress;
    2368              :     }
    2369              : 
    2370              :     // Set the mass flow rate within VFD operating range
    2371            0 :     if (InletNodeMassFlowRate > PumpMinMassFlowRateVFDRange) {
    2372            0 :         if (InletNodeMassFlowRate < PumpMaxMassFlowRateVFDRange) {
    2373              :             // Flow request is within VFD operating range
    2374            0 :             ActualFlowRate = InletNodeMassFlowRate;
    2375              :         } else {
    2376              :             // Flow request is outside VFD operating range
    2377              :             // Flow is set to maximum VFD operating range
    2378            0 :             ActualFlowRate = PumpMaxMassFlowRateVFDRange;
    2379              :         }
    2380              :     } else {
    2381              :         // Flow request is outside VFD operating range
    2382              :         // Flow is set to minimum VFD operating Range
    2383            0 :         ActualFlowRate = PumpMinMassFlowRateVFDRange;
    2384              :     }
    2385            0 : }
    2386              : 
    2387              : } // namespace EnergyPlus::Pumps
        

Generated by: LCOV version 2.0-1