LCOV - code coverage report
Current view: top level - EnergyPlus - Pumps.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 761 1104 68.9 %
Date: 2023-01-17 19:17:23 Functions: 10 11 90.9 %

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

Generated by: LCOV version 1.13