LCOV - code coverage report
Current view: top level - EnergyPlus - Pumps.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 777 1136 68.4 %
Date: 2024-08-24 18:31:18 Functions: 8 9 88.9 %

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

Generated by: LCOV version 1.14