PlantPressureSystem.f90 Source File

This File Depends On

sourcefile~~plantpressuresystem.f90~~EfferentGraph sourcefile~plantpressuresystem.f90 PlantPressureSystem.f90 sourcefile~dataloopnode.f90 DataLoopNode.f90 sourcefile~dataloopnode.f90->sourcefile~plantpressuresystem.f90 sourcefile~dataplant.f90 DataPlant.f90 sourcefile~dataloopnode.f90->sourcefile~dataplant.f90 sourcefile~curvemanager.f90 CurveManager.f90 sourcefile~dataloopnode.f90->sourcefile~curvemanager.f90 sourcefile~branchinputmanager.f90 BranchInputManager.f90 sourcefile~dataloopnode.f90->sourcefile~branchinputmanager.f90 sourcefile~nodeinputmanager.f90 NodeInputManager.f90 sourcefile~dataloopnode.f90->sourcefile~nodeinputmanager.f90 sourcefile~branchnodeconnections.f90 BranchNodeConnections.f90 sourcefile~dataloopnode.f90->sourcefile~branchnodeconnections.f90 sourcefile~fluidproperties.f90 FluidProperties.f90 sourcefile~fluidproperties.f90->sourcefile~plantpressuresystem.f90 sourcefile~fluidproperties.f90->sourcefile~nodeinputmanager.f90 sourcefile~general.f90 General.f90 sourcefile~general.f90->sourcefile~plantpressuresystem.f90 sourcefile~general.f90->sourcefile~fluidproperties.f90 sourcefile~general.f90->sourcefile~dataplant.f90 sourcefile~general.f90->sourcefile~curvemanager.f90 sourcefile~dataenvironment.f90 DataEnvironment.f90 sourcefile~general.f90->sourcefile~dataenvironment.f90 sourcefile~general.f90->sourcefile~branchinputmanager.f90 sourcefile~general.f90->sourcefile~nodeinputmanager.f90 sourcefile~general.f90->sourcefile~branchnodeconnections.f90 sourcefile~schedulemanager.f90 ScheduleManager.f90 sourcefile~general.f90->sourcefile~schedulemanager.f90 sourcefile~outputprocessor.f90 OutputProcessor.f90 sourcefile~general.f90->sourcefile~outputprocessor.f90 sourcefile~psychroutines.f90 PsychRoutines.f90 sourcefile~general.f90->sourcefile~psychroutines.f90 sourcefile~sqlitefortranroutines.f90 SQLiteFortranRoutines.f90 sourcefile~general.f90->sourcefile~sqlitefortranroutines.f90 sourcefile~dataheatbalance.f90 DataHeatBalance.f90 sourcefile~general.f90->sourcefile~dataheatbalance.f90 sourcefile~dataplant.f90->sourcefile~plantpressuresystem.f90 sourcefile~curvemanager.f90->sourcefile~plantpressuresystem.f90 sourcefile~curvemanager.f90->sourcefile~branchinputmanager.f90 sourcefile~databranchairloopplant.f90 DataBranchAirLoopPlant.f90 sourcefile~databranchairloopplant.f90->sourcefile~plantpressuresystem.f90 sourcefile~databranchairloopplant.f90->sourcefile~curvemanager.f90 sourcefile~databranchairloopplant.f90->sourcefile~branchinputmanager.f90 sourcefile~dataprecisionglobals.f90 DataPrecisionGlobals.f90 sourcefile~dataprecisionglobals.f90->sourcefile~plantpressuresystem.f90 sourcefile~dataprecisionglobals.f90->sourcefile~dataloopnode.f90 sourcefile~dataprecisionglobals.f90->sourcefile~fluidproperties.f90 sourcefile~dataprecisionglobals.f90->sourcefile~general.f90 sourcefile~dataprecisionglobals.f90->sourcefile~dataplant.f90 sourcefile~dataprecisionglobals.f90->sourcefile~curvemanager.f90 sourcefile~dataprecisionglobals.f90->sourcefile~databranchairloopplant.f90 sourcefile~dataglobals.f90 DataGlobals.f90 sourcefile~dataprecisionglobals.f90->sourcefile~dataglobals.f90 sourcefile~datainterfaces.f90 DataInterfaces.f90 sourcefile~dataprecisionglobals.f90->sourcefile~datainterfaces.f90 sourcefile~dataprecisionglobals.f90->sourcefile~dataenvironment.f90 sourcefile~inputprocessor.f90 InputProcessor.f90 sourcefile~dataprecisionglobals.f90->sourcefile~inputprocessor.f90 sourcefile~dataipshortcuts.f90 DataIPShortCuts.f90 sourcefile~dataprecisionglobals.f90->sourcefile~dataipshortcuts.f90 sourcefile~datasizing.f90 DataSizing.f90 sourcefile~dataprecisionglobals.f90->sourcefile~datasizing.f90 sourcefile~datasystemvariables.f90 DataSystemVariables.f90 sourcefile~dataprecisionglobals.f90->sourcefile~datasystemvariables.f90 sourcefile~datahvacglobals.f90 DataHVACGlobals.f90 sourcefile~dataprecisionglobals.f90->sourcefile~datahvacglobals.f90 sourcefile~datasurfaces.f90 DataSurfaces.f90 sourcefile~dataprecisionglobals.f90->sourcefile~datasurfaces.f90 sourcefile~dataruntimelanguage.f90 DataRuntimeLanguage.f90 sourcefile~dataprecisionglobals.f90->sourcefile~dataruntimelanguage.f90 sourcefile~datavectortypes.f90 DataVectorTypes.f90 sourcefile~dataprecisionglobals.f90->sourcefile~datavectortypes.f90 sourcefile~databsdfwindow.f90 DataBSDFWindow.f90 sourcefile~dataprecisionglobals.f90->sourcefile~databsdfwindow.f90 sourcefile~dataprecisionglobals.f90->sourcefile~branchinputmanager.f90 sourcefile~dataerrortracking.f90 DataErrorTracking.f90 sourcefile~dataprecisionglobals.f90->sourcefile~dataerrortracking.f90 sourcefile~dataprecisionglobals.f90->sourcefile~nodeinputmanager.f90 sourcefile~dataprecisionglobals.f90->sourcefile~schedulemanager.f90 sourcefile~dataprecisionglobals.f90->sourcefile~outputprocessor.f90 sourcefile~datacontaminantbalance.f90 DataContaminantBalance.f90 sourcefile~dataprecisionglobals.f90->sourcefile~datacontaminantbalance.f90 sourcefile~dataprecisionglobals.f90->sourcefile~psychroutines.f90 sourcefile~dataprecisionglobals.f90->sourcefile~sqlitefortranroutines.f90 sourcefile~outputreportpredefined.f90 OutputReportPredefined.f90 sourcefile~dataprecisionglobals.f90->sourcefile~outputreportpredefined.f90 sourcefile~dataprecisionglobals.f90->sourcefile~dataheatbalance.f90 sourcefile~dataroomair.f90 DataRoomAir.f90 sourcefile~dataprecisionglobals.f90->sourcefile~dataroomair.f90 sourcefile~datacomplexfenestration.f90 DataComplexFenestration.f90 sourcefile~dataprecisionglobals.f90->sourcefile~datacomplexfenestration.f90 sourcefile~dataequivalentlayerwindow.f90 DataEquivalentLayerWindow.f90 sourcefile~dataprecisionglobals.f90->sourcefile~dataequivalentlayerwindow.f90 sourcefile~dataglobals.f90->sourcefile~plantpressuresystem.f90 sourcefile~dataglobals.f90->sourcefile~dataloopnode.f90 sourcefile~dataglobals.f90->sourcefile~fluidproperties.f90 sourcefile~dataglobals.f90->sourcefile~general.f90 sourcefile~dataglobals.f90->sourcefile~dataplant.f90 sourcefile~dataglobals.f90->sourcefile~curvemanager.f90 sourcefile~dataglobals.f90->sourcefile~databranchairloopplant.f90 sourcefile~dataglobals.f90->sourcefile~dataenvironment.f90 sourcefile~dataglobals.f90->sourcefile~inputprocessor.f90 sourcefile~sortandstringutilities.f90 SortAndStringUtilities.f90 sourcefile~dataglobals.f90->sourcefile~sortandstringutilities.f90 sourcefile~dataoutputs.f90 DataOutputs.f90 sourcefile~dataglobals.f90->sourcefile~dataoutputs.f90 sourcefile~dataglobals.f90->sourcefile~dataipshortcuts.f90 sourcefile~dataglobals.f90->sourcefile~datasizing.f90 sourcefile~dataglobals.f90->sourcefile~datahvacglobals.f90 sourcefile~dataglobals.f90->sourcefile~datasurfaces.f90 sourcefile~dataglobals.f90->sourcefile~dataruntimelanguage.f90 sourcefile~dataglobals.f90->sourcefile~databsdfwindow.f90 sourcefile~dataglobals.f90->sourcefile~branchinputmanager.f90 sourcefile~dataglobals.f90->sourcefile~nodeinputmanager.f90 sourcefile~dataglobals.f90->sourcefile~branchnodeconnections.f90 sourcefile~dataglobals.f90->sourcefile~schedulemanager.f90 sourcefile~dataglobals.f90->sourcefile~outputprocessor.f90 sourcefile~dataglobals.f90->sourcefile~datacontaminantbalance.f90 sourcefile~dataglobals.f90->sourcefile~psychroutines.f90 sourcefile~dataglobals.f90->sourcefile~sqlitefortranroutines.f90 sourcefile~dataglobalconstants.f90 DataGlobalConstants.f90 sourcefile~dataglobals.f90->sourcefile~dataglobalconstants.f90 sourcefile~dataglobals.f90->sourcefile~outputreportpredefined.f90 sourcefile~dataglobals.f90->sourcefile~dataheatbalance.f90 sourcefile~dataglobals.f90->sourcefile~dataroomair.f90 sourcefile~dataglobals.f90->sourcefile~datacomplexfenestration.f90 sourcefile~dataglobals.f90->sourcefile~dataequivalentlayerwindow.f90 sourcefile~databranchnodeconnections.f90 DataBranchNodeConnections.f90 sourcefile~dataglobals.f90->sourcefile~databranchnodeconnections.f90 sourcefile~datainterfaces.f90->sourcefile~plantpressuresystem.f90 sourcefile~datainterfaces.f90->sourcefile~fluidproperties.f90 sourcefile~datainterfaces.f90->sourcefile~general.f90 sourcefile~datainterfaces.f90->sourcefile~dataplant.f90 sourcefile~datainterfaces.f90->sourcefile~curvemanager.f90 sourcefile~datainterfaces.f90->sourcefile~dataenvironment.f90 sourcefile~datainterfaces.f90->sourcefile~inputprocessor.f90 sourcefile~datainterfaces.f90->sourcefile~dataruntimelanguage.f90 sourcefile~datainterfaces.f90->sourcefile~branchinputmanager.f90 sourcefile~datainterfaces.f90->sourcefile~nodeinputmanager.f90 sourcefile~datainterfaces.f90->sourcefile~branchnodeconnections.f90 sourcefile~datainterfaces.f90->sourcefile~schedulemanager.f90 sourcefile~datainterfaces.f90->sourcefile~outputprocessor.f90 sourcefile~datainterfaces.f90->sourcefile~psychroutines.f90 sourcefile~datainterfaces.f90->sourcefile~sqlitefortranroutines.f90 sourcefile~datainterfaces.f90->sourcefile~dataheatbalance.f90 sourcefile~dataenvironment.f90->sourcefile~plantpressuresystem.f90 sourcefile~dataenvironment.f90->sourcefile~nodeinputmanager.f90 sourcefile~dataenvironment.f90->sourcefile~schedulemanager.f90 sourcefile~dataenvironment.f90->sourcefile~outputprocessor.f90 sourcefile~dataenvironment.f90->sourcefile~psychroutines.f90 sourcefile~dataenvironment.f90->sourcefile~sqlitefortranroutines.f90 sourcefile~dataenvironment.f90->sourcefile~dataheatbalance.f90 sourcefile~inputprocessor.f90->sourcefile~fluidproperties.f90 sourcefile~inputprocessor.f90->sourcefile~general.f90 sourcefile~inputprocessor.f90->sourcefile~dataplant.f90 sourcefile~inputprocessor.f90->sourcefile~curvemanager.f90 sourcefile~inputprocessor.f90->sourcefile~branchinputmanager.f90 sourcefile~inputprocessor.f90->sourcefile~nodeinputmanager.f90 sourcefile~inputprocessor.f90->sourcefile~branchnodeconnections.f90 sourcefile~inputprocessor.f90->sourcefile~schedulemanager.f90 sourcefile~inputprocessor.f90->sourcefile~outputprocessor.f90 sourcefile~inputprocessor.f90->sourcefile~sqlitefortranroutines.f90 sourcefile~inputprocessor.f90->sourcefile~dataglobalconstants.f90 sourcefile~inputprocessor.f90->sourcefile~dataheatbalance.f90 sourcefile~sortandstringutilities.f90->sourcefile~inputprocessor.f90 sourcefile~sortandstringutilities.f90->sourcefile~outputprocessor.f90 sourcefile~dataoutputs.f90->sourcefile~inputprocessor.f90 sourcefile~dataoutputs.f90->sourcefile~outputprocessor.f90 sourcefile~dataipshortcuts.f90->sourcefile~general.f90 sourcefile~dataipshortcuts.f90->sourcefile~curvemanager.f90 sourcefile~dataipshortcuts.f90->sourcefile~inputprocessor.f90 sourcefile~dataipshortcuts.f90->sourcefile~schedulemanager.f90 sourcefile~dataipshortcuts.f90->sourcefile~outputprocessor.f90 sourcefile~datasizing.f90->sourcefile~dataplant.f90 sourcefile~datasizing.f90->sourcefile~inputprocessor.f90 sourcefile~datasizing.f90->sourcefile~branchinputmanager.f90 sourcefile~datastringglobals.f90 DataStringGlobals.f90 sourcefile~datastringglobals.f90->sourcefile~general.f90 sourcefile~datastringglobals.f90->sourcefile~inputprocessor.f90 sourcefile~datastringglobals.f90->sourcefile~datasystemvariables.f90 sourcefile~datastringglobals.f90->sourcefile~schedulemanager.f90 sourcefile~datastringglobals.f90->sourcefile~outputprocessor.f90 sourcefile~datastringglobals.f90->sourcefile~sqlitefortranroutines.f90 sourcefile~datasystemvariables.f90->sourcefile~curvemanager.f90 sourcefile~datasystemvariables.f90->sourcefile~inputprocessor.f90 sourcefile~datasystemvariables.f90->sourcefile~schedulemanager.f90 sourcefile~datasystemvariables.f90->sourcefile~outputprocessor.f90 sourcefile~datasystemvariables.f90->sourcefile~sqlitefortranroutines.f90 sourcefile~datahvacglobals.f90->sourcefile~general.f90 sourcefile~datahvacglobals.f90->sourcefile~branchinputmanager.f90 sourcefile~datasurfaces.f90->sourcefile~general.f90 sourcefile~datasurfaces.f90->sourcefile~datacontaminantbalance.f90 sourcefile~datasurfaces.f90->sourcefile~sqlitefortranroutines.f90 sourcefile~datasurfaces.f90->sourcefile~dataheatbalance.f90 sourcefile~dataruntimelanguage.f90->sourcefile~general.f90 sourcefile~datavectortypes.f90->sourcefile~datasurfaces.f90 sourcefile~datavectortypes.f90->sourcefile~databsdfwindow.f90 sourcefile~datavectortypes.f90->sourcefile~dataheatbalance.f90 sourcefile~databsdfwindow.f90->sourcefile~datasurfaces.f90 sourcefile~databsdfwindow.f90->sourcefile~dataheatbalance.f90 sourcefile~branchinputmanager.f90->sourcefile~dataplant.f90 sourcefile~dataerrortracking.f90->sourcefile~branchinputmanager.f90 sourcefile~dataerrortracking.f90->sourcefile~nodeinputmanager.f90 sourcefile~nodeinputmanager.f90->sourcefile~branchinputmanager.f90 sourcefile~branchnodeconnections.f90->sourcefile~branchinputmanager.f90 sourcefile~branchnodeconnections.f90->sourcefile~nodeinputmanager.f90 sourcefile~schedulemanager.f90->sourcefile~nodeinputmanager.f90 sourcefile~schedulemanager.f90->sourcefile~outputprocessor.f90 sourcefile~schedulemanager.f90->sourcefile~sqlitefortranroutines.f90 sourcefile~outputprocessor.f90->sourcefile~nodeinputmanager.f90 sourcefile~datacontaminantbalance.f90->sourcefile~nodeinputmanager.f90 sourcefile~psychroutines.f90->sourcefile~nodeinputmanager.f90 sourcefile~sqlitefortranroutines.f90->sourcefile~outputprocessor.f90 sourcefile~dataglobalconstants.f90->sourcefile~outputprocessor.f90 sourcefile~outputreportpredefined.f90->sourcefile~outputprocessor.f90 sourcefile~dataheatbalance.f90->sourcefile~outputprocessor.f90 sourcefile~dataheatbalance.f90->sourcefile~sqlitefortranroutines.f90 sourcefile~dataroomair.f90->sourcefile~sqlitefortranroutines.f90 sourcefile~datacomplexfenestration.f90->sourcefile~dataheatbalance.f90 sourcefile~dataequivalentlayerwindow.f90->sourcefile~dataheatbalance.f90 sourcefile~databranchnodeconnections.f90->sourcefile~branchnodeconnections.f90
Help

Files Dependent On This One

sourcefile~~plantpressuresystem.f90~~AfferentGraph sourcefile~plantpressuresystem.f90 PlantPressureSystem.f90 sourcefile~plantpumps.f90 PlantPumps.f90 sourcefile~plantpressuresystem.f90->sourcefile~plantpumps.f90 sourcefile~plantloopsolver.f90 PlantLoopSolver.f90 sourcefile~plantpressuresystem.f90->sourcefile~plantloopsolver.f90 sourcefile~plantpumps.f90->sourcefile~plantloopsolver.f90 sourcefile~plantloopequipment.f90 PlantLoopEquipment.f90 sourcefile~plantpumps.f90->sourcefile~plantloopequipment.f90 sourcefile~plantmanager.f90 PlantManager.f90 sourcefile~plantloopsolver.f90->sourcefile~plantmanager.f90 sourcefile~plantloopequipment.f90->sourcefile~plantloopsolver.f90 sourcefile~plantloopequipment.f90->sourcefile~plantmanager.f90 sourcefile~simulationmanager.f90 SimulationManager.f90 sourcefile~plantmanager.f90->sourcefile~simulationmanager.f90 sourcefile~utilityroutines.f90 UtilityRoutines.f90 sourcefile~plantmanager.f90->sourcefile~utilityroutines.f90 sourcefile~hvacmanager.f90 HVACManager.f90 sourcefile~plantmanager.f90->sourcefile~hvacmanager.f90 sourcefile~simulationmanager.f90->sourcefile~utilityroutines.f90 sourcefile~energyplus.f90 EnergyPlus.f90 sourcefile~simulationmanager.f90->sourcefile~energyplus.f90 sourcefile~hvacmanager.f90->sourcefile~simulationmanager.f90 sourcefile~heatbalanceairmanager.f90 HeatBalanceAirManager.f90 sourcefile~hvacmanager.f90->sourcefile~heatbalanceairmanager.f90 sourcefile~heatbalanceairmanager.f90->sourcefile~simulationmanager.f90 sourcefile~heatbalancesurfacemanager.f90 HeatBalanceSurfaceManager.f90 sourcefile~heatbalanceairmanager.f90->sourcefile~heatbalancesurfacemanager.f90 sourcefile~heatbalancesurfacemanager.f90->sourcefile~simulationmanager.f90 sourcefile~heatbalancemanager.f90 HeatBalanceManager.f90 sourcefile~heatbalancesurfacemanager.f90->sourcefile~heatbalancemanager.f90 sourcefile~heatbalancemanager.f90->sourcefile~simulationmanager.f90 sourcefile~sizingmanager.f90 SizingManager.f90 sourcefile~heatbalancemanager.f90->sourcefile~sizingmanager.f90 sourcefile~sizingmanager.f90->sourcefile~simulationmanager.f90
Help


Source Code

MODULE PlantPressureSystem

          ! Module containing the routines dealing with the PlantPressureSystem simulation

          ! MODULE INFORMATION:
          !       AUTHOR         Edwin Lee
          !       DATE WRITTEN   August 2009
          !       MODIFIED       February 2010: Add phase 2: loop flow correction
          !       RE-ENGINEERED  na

          ! PURPOSE OF THIS MODULE:
          ! This module manages plant pressure-based simulations

          ! METHODOLOGY EMPLOYED:
          ! General EnergyPlus Methodology:

          ! REFERENCES:
          ! na

          ! OTHER NOTES:
          !  Phase 1: Pump Power Correction: -Loop/Parallel flows are not resolved based on pressure drop
          !                                  -Every flow path must see at least one branch with pressure information
          !                                  -Pump power is updated based on the required pump head
          !  Phase 2: Pump Flow Correction: -Loop flow resolved based on pump curve and loop pressure drop
          !                                 -Parallel flows not resolved
          !                                 -Every flow path must see at least one branch with pressure information
          !                                 -Pump curve must be given also
          !  Phase 3: Pressure Simulation: -Loop and parallel flows are resolved
          !                                -All branches must have pressure information and pump must have pump curve
          !                                -Not currently implemented

          ! USE STATEMENTS:
USE DataPrecisionGlobals
USE DataGlobals, ONLY: MaxNameLength,Pi
USE DataInterfaces, ONLY: ShowWarningError,ShowSevereError,ShowFatalError,ShowContinueError,SetupOutputVariable
USE DataBranchAirLoopPlant

IMPLICIT NONE ! Enforce explicit typing of all variables

PRIVATE ! Everything private unless explicitly made public


          ! MODULE PARAMETER/ENUMERATIONS DEFINITIONS:
CHARACTER(*), PARAMETER        :: Blank                   = ' '


          ! DERIVED TYPE DEFINITIONS:
!TYPE, PUBLIC:: PlantPressureCurveData
!  CHARACTER(len=MaxNameLength) :: Name                    = Blank
!  REAL(r64)                    :: EquivDiameter           = 0.0d0   !- An effective diameter for calculation of Re & e/D [m]
!  REAL(r64)                    :: MinorLossCoeff          = 0.0d0   !- K factor                                          [-]
!  REAL(r64)                    :: EquivLength             = 0.0d0   !- An effective length to apply friction calculation [m]
!  REAL(r64)                    :: EquivRoughness          = 0.0d0   !- An effective roughness (e) to calculate e/D       [m]
!  LOGICAL                      :: ConstantFpresent        = .FALSE. !- Signal for if a constant value of f was entered
!  REAL(r64)                    :: ConstantF               = 0.0d0   !- Constant value of f (if applicable)               [-]
!END TYPE PlantPressureCurveData
!
!          ! MODULE VARIABLE DECLARATIONS:
!TYPE(PlantPressureCurveData), ALLOCATABLE, DIMENSION(:),PUBLIC :: PressureCurve
!LOGICAL  :: GetInputFlag = .TRUE. !Module level, since GetInput could be called by SIMPRESSUREDROP or by BRANCHINPUTMANAGER

          ! SUBROUTINE SPECIFICATIONS FOR MODULE:

     ! Driver/Manager Routines
PUBLIC  SimPressureDropSystem

     ! Initialization routines for module
!PRIVATE GetPressureSystemInput
PRIVATE InitPressureDrop

     ! Algorithms/Calculation routines for the module
PRIVATE BranchPressureDrop
!PRIVATE PressureCurveValue
!PRIVATE CalculateMoodyFrictionFactor

     ! Update routines to check convergence and update nodes
PRIVATE UpdatePressureDrop

     ! Utility routines for module
PRIVATE DistributePressureOnBranch
PRIVATE PassPressureAcrossMixer
PRIVATE PassPressureAcrossSplitter
PRIVATE PassPressureAcrossInterface

     ! Public Utility routines
!PUBLIC GetPressureCurveTypeAndIndex
PUBLIC ResolveLoopFlowVsPressure

CONTAINS

SUBROUTINE SimPressureDropSystem(LoopNum, FirstHVACIteration, CallType, LoopSideNum, BranchNum)

          ! SUBROUTINE INFORMATION:
          !       AUTHOR         Edwin Lee
          !       DATE WRITTEN   August 2009
          !       MODIFIED       na
          !       RE-ENGINEERED  na

          ! PURPOSE OF THIS SUBROUTINE:
          ! This routine is the public interface for pressure system simulation
          ! Calls are made to private components as needed

          ! METHODOLOGY EMPLOYED:
          ! Standard EnergyPlus methodology

          ! REFERENCES:
          ! na

          ! USE STATEMENTS:
  USE DataPlant, ONLY : PressureCall_Init, PressureCall_Calc, PressureCall_Update, PlantLoop, Press_NoPressure

  IMPLICIT NONE ! Enforce explicit typing of all variables in this routine

          ! SUBROUTINE ARGUMENT DEFINITIONS:
  INTEGER,           INTENT(IN)   :: LoopNum            ! Plant Loop to update pressure information
  LOGICAL,           INTENT(IN)   :: FirstHVACIteration ! System flag
  INTEGER,           INTENT(IN)   :: CallType           ! Enumerated call type
  INTEGER, OPTIONAL, INTENT(IN)   :: LoopSideNum        ! Loop side num for specific branch simulation
  INTEGER, OPTIONAL, INTENT(IN)   :: BranchNUm          ! Branch num for specific branch simulation

          ! SUBROUTINE PARAMETER DEFINITIONS:
          ! na

          ! INTERFACE BLOCK SPECIFICATIONS:
          ! na

          ! DERIVED TYPE DEFINITIONS:
          ! na

          ! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
          ! na

  !Check if we need to get pressure curve input data
!  IF (GetInputFlag) CALL GetPressureSystemInput

  !Exit out of any calculation routines if we don't do pressure simulation for this loop
  IF ((PlantLoop(LoopNum)%PressureSimType == Press_NoPressure) .AND.  &
      ((CallType == PressureCall_Calc) .OR. (CallType == PressureCall_Update))) RETURN

  !Pass to another routine based on calling flag
  SELECT CASE (CallType)
    CASE (PressureCall_Init)
      CALL InitPressureDrop(LoopNum, FirstHVACIteration)
    CASE (PressureCall_Calc)
      CALL BranchPressureDrop(LoopNum,LoopSideNum,BranchNum) !Objexx:OPTIONAL LoopSideNum, BranchNum used without PRESENT check
    CASE (PressureCall_Update)
      CALL UpdatePressureDrop(LoopNum)
    CASE DEFAULT
      !Calling routines should only use the three possible keywords here
  END SELECT

  RETURN

END SUBROUTINE SimPressureDropSystem

!=================================================================================================!

!SUBROUTINE GetPressureSystemInput()
! Getinput for PressureSystem moved to CurveManager module
!=================================================================================================!

SUBROUTINE InitPressureDrop(LoopNum, FirstHVACIteration)

          ! SUBROUTINE INFORMATION:
          !       AUTHOR         Edwin Lee
          !       DATE WRITTEN   August 2009
          !       MODIFIED       na
          !       RE-ENGINEERED  na

          ! PURPOSE OF THIS SUBROUTINE:
          ! Initializes output variables and data structure
          ! On FirstHVAC, updates the demand inlet node pressure

          ! METHODOLOGY EMPLOYED:
          ! General EnergyPlus Methodology

          ! REFERENCES:
          ! na

          ! USE STATEMENTS:
  USE DataPlant,       ONLY :  PlantLoop, DemandSide, SupplySide, Press_NoPressure, CommonPipe_No
  USE DataEnvironment, ONLY :  StdBaroPress
  USE DataLoopNode,    ONLY :  Node

  IMPLICIT NONE ! Enforce explicit typing of all variables in this routine

          ! SUBROUTINE ARGUMENT DEFINITIONS:
  INTEGER, INTENT(IN)      ::  LoopNum
  LOGICAL, INTENT(IN)      ::  FirstHVACIteration

          ! SUBROUTINE PARAMETER DEFINITIONS:
  INTEGER, PARAMETER       :: LoopType_Plant     = 1
  INTEGER, PARAMETER       :: LoopType_Condenser = 2

          ! INTERFACE BLOCK SPECIFICATIONS:
          ! na

          ! DERIVED TYPE DEFINITIONS:
          ! na

          ! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
  !Initialization Variables
  LOGICAL, SAVE            ::  OneTimeInit = .TRUE.
  LOGICAL, SAVE, ALLOCATABLE, DIMENSION(:) :: LoopInit

  !Simulation Variables
  LOGICAL                  ::  ErrorsFound
  INTEGER                  ::  LoopSideNum
  INTEGER                  ::  CompNum
  INTEGER                  ::  BranchNum
  INTEGER                  ::  NumBranches
  INTEGER                  ::  BranchPressureTally
  LOGICAL                  ::  SeriesPressureComponentFound
  LOGICAL, DIMENSION(2)    ::  FullParallelBranchSetFound
  LOGICAL, SAVE            ::  CommonPipeErrorEncountered = .FALSE.

  IF (OneTimeInit) THEN
    !First allocate the initialization array to each plant loop
    ALLOCATE(LoopInit(SIZE(PlantLoop)))
    LoopInit = .TRUE.
    OneTimeInit = .FALSE.
  END IF

  ! CurrentModuleObject='Curve:Functional:PressureDrop'
  IF (LoopInit(LoopNum)) THEN

    !Initialize
    ErrorsFound = .FALSE.
    FullParallelBranchSetFound = .FALSE.
    SeriesPressureComponentFound = .FALSE.

    !Need to go along plant loop and set up component pressure drop data structure!
    DO LoopSideNum = DemandSide, SupplySide

      !Loop through all branches on this loop side
      DO BranchNum = 1, SIZE(PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch)

        !If this branch has valid pressure drop data
        IF (PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%PressureCurveIndex .GT. 0) THEN

          !Update flags for higher level structure
          PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%HasPressureComponents = .TRUE.
          PlantLoop(LoopNum)%LoopSide(LoopSideNum)%HasPressureComponents = .TRUE.
          PlantLoop(LoopNum)%HasPressureComponents = .TRUE.

          !Setup output variable
          CALL SetupOutputVariable('Plant Branch Pressure Difference [Pa]',  &
                       PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%PressureDrop &
                       ,'Plant','Average', PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%Name)

        END IF

      END DO

      !Set up loopside level variables if applicable
      IF (PlantLoop(LoopNum)%LoopSide(LoopSideNum)%HasPressureComponents) THEN
        IF (LoopSideNum==DemandSide) THEN

          CALL SetupOutputVariable('Plant Demand Side Loop Pressure Difference [Pa]',  &
                      PlantLoop(LoopNum)%LoopSide(LoopSideNum)%PressureDrop &
                      ,'Plant','Average', PlantLoop(LoopNum)%Name)

        ELSE IF (LoopSideNum==SupplySide) THEN

          CALL SetupOutputVariable('Plant Supply Side Loop Pressure Difference [Pa]',  &
                       PlantLoop(LoopNum)%LoopSide(LoopSideNum)%PressureDrop &
                       ,'Plant','Average', PlantLoop(LoopNum)%Name)

        END IF
      END IF

    END DO

    IF (PlantLoop(LoopNum)%HasPressureComponents) THEN

      !Set up loop level variables if applicable

      CALL SetupOutputVariable('Plant Loop Pressure Difference [Pa]',  &
                     PlantLoop(LoopNum)%PressureDrop &
                     ,'Plant','Average', PlantLoop(LoopNum)%Name)


      !Check for illegal configurations on this plant loop
      DO LoopSideNum = DemandSide, SupplySide
        !Check for illegal parallel branch setups
        BranchPressureTally = 0
        NumBranches = SIZE(PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch)
        IF (NumBranches.GT.2) THEN
          DO BranchNum = 2, NumBranches-1
            IF (PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%HasPressureComponents) THEN
              PlantLoop(LoopNum)%LoopSide(LoopSideNum)%HasParallelPressComps = .TRUE.
              BranchPressureTally = BranchPressureTally + 1
            END IF
          END DO
        END IF
        IF (BranchPressureTally == 0) THEN
          !no parallel branches, ok for this check
        ELSE IF (BranchPressureTally == SIZE(PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch)-2) THEN
          !all parallel branches have pressure components
          FullParallelBranchSetFound(LoopSideNum) = .TRUE.
        ELSE
          !we aren't ok
          CALL ShowSevereError('Pressure drop component configuration error detected on loop: '//PlantLoop(LoopNum)%Name)
          CALL ShowContinueError('Pressure drop components must be on ALL or NONE of the parallel branches.')
          CALL ShowContinueError('Partial distribution is not allowed.')
          ErrorsFound = .TRUE.
        END IF
        IF (PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(1)%HasPressureComponents .OR. &
            PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(NumBranches)%HasPressureComponents) THEN
          !we have a series component pressure branch (whether a single branch half loop or mixer/splitter setup
          SeriesPressureComponentFound = .TRUE.
        END IF
      END DO

      !Check for full path pressure data
      IF(ANY(FullParallelBranchSetFound) .OR. (SeriesPressureComponentFound))THEN
        !we are fine, either way we will always have a path with at least one pressure component hit
      ELSE
        CALL ShowSevereError('Pressure drop component configuration error detected on loop: '//PlantLoop(LoopNum)%Name)
        CALL ShowContinueError('The loop has at least one fluid path which does not encounter a pressure component.')
        CALL ShowContinueError('Either use at least one serial component for pressure drop OR all possible parallel paths')
        CALL ShowContinueError('must be pressure drop components.')
        ErrorsFound = .TRUE.
      END IF !valid pressure path

    END IF !Has pressure components

    IF (ErrorsFound) Call ShowFatalError('Preceding errors cause program termination')

    !Also issue one time warning if there is a mismatch between plant loop simulation type and whether objects were entered
    IF (PlantLoop(LoopNum)%HasPressureComponents .AND. (PlantLoop(LoopNum)%PressureSimType == Press_NoPressure)) THEN
      !Then we found pressure components on the branches, but the plant loop said it didn't want to do pressure simulation
      CALL ShowWarningError('Error for pressure simulation on plant loop: '//PlantLoop(LoopNum)%Name)
      CALL ShowContinueError('Plant loop contains pressure simulation components on the branches,')
      CALL ShowContinueError(' yet in the PlantLoop object, there is no pressure simulation specified.')
      CALL ShowContinueError('Simulation continues, ignoring pressure simulation data.')
    ELSE IF ((.NOT. PlantLoop(LoopNum)%HasPressureComponents) .AND. (PlantLoop(LoopNum)%PressureSimType .NE. Press_NoPressure)) THEN
      !Then we don't have any pressure components on the branches, yet the plant loop wants to do some sort of pressure simulation
      CALL ShowWarningError('Error for pressure simulation on plant loop: '//PlantLoop(LoopNum)%Name)
      CALL ShowContinueError('Plant loop is requesting a pressure simulation,')
      CALL ShowContinueError(' yet there are no pressure simulation components detected on any of the branches in that loop.')
      CALL ShowContinueError('Simulation continues, ignoring pressure simulation data.')
    END IF

    LoopInit(LoopNum) = .FALSE.

  END IF !LoopInit = TRUE

  !Initialize the entire plant loop to the outdoor pressure if that loop has data
  !This value at the demand side outlet node will be used as a starting reference point
  ! for pressure calcs
  !The value is smeared across the loop, however, so that any nodes before a pump will
  ! have a proper value for pressure
  IF (PlantLoop(LoopNum)%HasPressureComponents .AND. FirstHVACIteration) THEN
    DO LoopSideNum = DemandSide, SupplySide
      DO BranchNum = 1, SIZE(PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch)
        DO CompNum = 1, SIZE(PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%Comp)
          Node(PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%Comp(CompNum)%NodeNumIn)%Press=StdBaroPress
          Node(PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%Comp(CompNum)%NodeNumOut)%Press=StdBaroPress
        END DO
      END DO
    END DO
  END IF

  !Now tell the pump routine whether or not to use the pressure data to calculate power
  IF (PlantLoop(LoopNum)%HasPressureComponents) THEN
    IF (FirstHVACIteration) THEN
      PlantLoop(LoopNum)%UsePressureForPumpCalcs = .FALSE.
    ELSE
      PlantLoop(LoopNum)%UsePressureForPumpCalcs = .TRUE.
    END IF
  ELSE !No Pressure Components
    PlantLoop(LoopNum)%UsePressureForPumpCalcs = .FALSE.
  END IF

  !Before we leave, override any settings in case we are doing common pipe simulation
  IF (PlantLoop(LoopNum)%HasPressureComponents) THEN
    !We need to make sure we aren't doing an invalid configuration here
    IF (PlantLoop(LoopNum)%CommonPipeType .NE. CommonPipe_No) THEN
      !There is a common pipe!
      IF (.NOT. CommonPipeErrorEncountered) THEN
        CALL ShowSevereError('Invalid pressure simulation configuration for Plant Loop='//TRIM(PlantLoop(LoopNum)%Name))
        CALL ShowContinueError('Currently pressure simulations cannot be performed for loops with common pipes.')
        CALL ShowContinueError('To repair, either remove the common pipe simulation, or remove the pressure simulation.')
        CALL ShowContinueError('The simulation will continue, but the pump power is not updated with pressure drop data.')
        CALL ShowContinueError('Check all results including node pressures to ensure proper simulation.')
        CALL ShowContinueError('This message is reported once, but may have been encountered in multiple loops.')
        CommonPipeErrorEncountered = .TRUE.
      END IF
      PlantLoop(LoopNum)%UsePressureForPumpCalcs = .FALSE.
    END IF
  END IF


END SUBROUTINE InitPressureDrop

!=================================================================================================!

SUBROUTINE BranchPressureDrop(LoopNum,LoopSideNum,BranchNum)

          ! SUBROUTINE INFORMATION:
          !       AUTHOR         Edwin Lee
          !       DATE WRITTEN   August 2009
          !       MODIFIED       na
          !       RE-ENGINEERED  na

          ! PURPOSE OF THIS SUBROUTINE:
          ! This will choose an appropriate pressure drop calculation routine based on structure flags

          ! METHODOLOGY EMPLOYED:
          ! Standard EnergyPlus Methodology

          ! REFERENCES:
          ! na

          ! USE STATEMENTS:
  USE DataLoopNode,    ONLY   :  Node
  USE FluidProperties, ONLY   :  GetDensityGlycol, GetViscosityGlycol
  USE DataPlant,       ONLY   :  PlantLoop
  USE CurveManager,    ONLY   :  CurveValue, PressureCurveValue

  IMPLICIT NONE ! Enforce explicit typing of all variables in this routine

          ! SUBROUTINE ARGUMENT DEFINITIONS:
  INTEGER,   INTENT(IN)       ::  LoopNum            !Plant Loop Index
  INTEGER,   INTENT(IN)       ::  LoopSideNum        !LoopSide Index (1=Demand, 2=Supply) on Plant Loop LoopNum
  INTEGER,   INTENT(IN)       ::  BranchNum          !Branch Index on LoopSide LoopSideNum

          ! SUBROUTINE PARAMETER DEFINITIONS:
  CHARACTER(len=*), PARAMETER :: RoutineName  = 'CalcPlantPressureSystem'
  CHARACTER(len=*), PARAMETER :: DummyFluid   = ' '

          ! INTERFACE BLOCK SPECIFICATIONS:
          ! na

          ! DERIVED TYPE DEFINITIONS:
          ! na

          ! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
  INTEGER                     :: FluidIndex          !Plant loop level Fluid Index
  INTEGER                     :: InletNodeNum        !Component inlet node number
  INTEGER                     :: OutletNodeNum       !Component outlet node number
  INTEGER                     :: PressureCurveType   !Type of curve used to evaluate pressure drop
  INTEGER                     :: PressureCurveIndex  !Curve index for PerfCurve structure
  REAL(r64)                   :: NodeMassFlow        !Nodal mass flow rate {kg/s}
  REAL(r64)                   :: NodeTemperature     !Nodal temperature {C}
  REAL(r64)                   :: NodeDensity         !Nodal density {kg/m3}
  REAL(r64)                   :: NodeViscosity       !Nodal viscosity, assuming mu here (dynamic viscosity)
  REAL(r64)                   :: BranchDeltaPress    !Pressure drop for component, {Pa}
  INTEGER, SAVE               :: ErrorCounter = 0    !For proper error handling

  !Exit early if need be
  IF (.NOT. PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%HasPressureComponents) THEN
    PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%PressureDrop = 0.0d0
    PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%PressureEffectiveK = 0.0d0
    RETURN
  END IF

  !Get data from data structure
  FluidIndex         = PlantLoop(LoopNum)%FluidIndex
  InletNodeNum       = PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%NodeNumIn
  OutletNodeNum      = PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%NodeNumOut
  PressureCurveType  = PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%PressureCurveType
  PressureCurveIndex = PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%PressureCurveIndex

  !Get nodal conditions
  NodeMassFlow       = Node(InletNodeNum)%MassFlowRate
  NodeTemperature    = Node(InletNodeNum)%Temp
  NodeDensity        = GetDensityGlycol(DummyFluid, NodeTemperature, FluidIndex, RoutineName)
  NodeViscosity      = GetViscosityGlycol(DummyFluid, NodeTemperature, FluidIndex, RoutineName)

  !Call the appropriate pressure calculation routine
  SELECT CASE (PressureCurveType)
    CASE (PressureCurve_Pressure)
      !DeltaP = [f*(L/D) + K] * (rho * V^2) / 2
      BranchDeltaPress = PressureCurveValue(PressureCurveIndex, NodeMassFlow, NodeDensity, NodeViscosity)

    CASE (PressureCurve_Generic)
      !DeltaP = func(mdot)
      !Generic curve, only pass V1=mass flow rate
      BranchDeltaPress = CurveValue(PressureCurveIndex, NodeMassFlow)

    CASE DEFAULT
      !Shouldn't end up here, but just in case
      ErrorCounter = ErrorCounter + 1
      IF (ErrorCounter == 1) THEN
        CALL ShowSevereError('Plant pressure simulation encountered a branch which contains invalid branch pressure curve type.')
        CALL ShowContinueError('Occurs for branch: '//PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%Name)
        CALL ShowContinueError('This error will be issued only once, although other branches may encounter the same problem')
        CALL ShowContinueError('For now, pressure drop on this branch will be set to zero.')
        CALL ShowContinueError('Verify all pressure inputs and pressure drop output variables to ensure proper simulation')
      END IF

  END SELECT

  !Log this pressure in the data structure to be handled by the update routine later
  PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%PressureDrop = BranchDeltaPress

  !Update the effective K-value for this branch
  IF (NodeMassFlow .GT. 0.0d0) THEN
    PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%PressureEffectiveK = BranchDeltaPress / (NodeMassFlow**2.0d0)
  ELSE
    PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%PressureEffectiveK = 0.0d0
  END IF

  RETURN

END SUBROUTINE BranchPressureDrop

!=================================================================================================!

!REAL(r64) FUNCTION PressureCurveValue(PressureCurveIndex, MassFlow, Density, Viscosity)
!
!          ! FUNCTION INFORMATION:
!          !       AUTHOR         Edwin Lee
!          !       DATE WRITTEN   August 2009
!          !       MODIFIED       na
!          !       RE-ENGINEERED  na
!
!          ! PURPOSE OF THIS FUNCTION:
!          ! This will evaluate the pressure drop for components which use pressure information
!
!          ! METHODOLOGY EMPLOYED:
!          ! Friction factor pressure drop equation:
!          ! DP = [f*(L/D) + K] * (rho * V^2) / 2
!
!          ! REFERENCES:
!          ! na
!
!          ! USE STATEMENTS:
!  USE DataPlant, ONLY : MassFlowTol
!  Use DataGlobals, ONLY : Pi
!
!  IMPLICIT NONE ! Enforce explicit typing of all variables in this routine
!
!          ! FUNCTION ARGUMENT DEFINITIONS:
!  INTEGER, INTENT(IN)      ::  PressureCurveIndex
!  REAL(r64), INTENT(IN)    ::  MassFlow
!  REAL(r64), INTENT(IN)    ::  Density
!  REAL(r64), INTENT(IN)    ::  Viscosity
!
!          ! FUNCTION PARAMETER DEFINITIONS:
!          ! na
!
!          ! INTERFACE BLOCK SPECIFICATIONS:
!          ! na
!
!          ! DERIVED TYPE DEFINITIONS:
!          ! na
!
!          ! FUNCTION LOCAL VARIABLE DECLARATIONS:
!  REAL(r64)                ::  Diameter
!  REAL(r64)                ::  MinorLossCoeff
!  REAL(r64)                ::  Length
!  REAL(r64)                ::  Roughness
!  LOGICAL                  ::  IsConstFPresent
!  REAL(r64)                ::  ConstantF
!  REAL(r64)                ::  FrictionFactor
!  REAL(r64)                ::  CrossSectArea
!  REAL(r64)                ::  Velocity
!  REAL(r64)                ::  ReynoldsNumber
!  REAL(r64)                ::  RoughnessRatio
!
!  !Retrieve data from structure
!  Diameter        = PressureCurve(PressureCurveIndex)%EquivDiameter
!  MinorLossCoeff  = PressureCurve(PressureCurveIndex)%MinorLossCoeff
!  Length          = PressureCurve(PressureCurveIndex)%EquivLength
!  Roughness       = PressureCurve(PressureCurveIndex)%EquivRoughness
!  IsConstFPresent = PressureCurve(PressureCurveIndex)%ConstantFPresent
!  ConstantF       = PressureCurve(PressureCurveIndex)%ConstantF
!
!  !Intermediate calculations
!  CrossSectArea         =  (Pi / 4.0d0) * Diameter**2
!  Velocity              =  MassFlow / (Density * CrossSectArea)
!  ReynoldsNumber        =  Density * Diameter * Velocity / Viscosity !assuming mu here
!  RoughnessRatio        =  Roughness / Diameter
!
!  !If we don't have any flow then exit out
!  IF (MassFlow .LT. MassFlowTol) THEN
!    PressureCurveValue = 0.0d0
!    RETURN
!  END IF
!
!  !Calculate the friction factor
!  IF (IsConstFPresent) THEN   !use the constant value
!    FrictionFactor    =  ConstantF
!  ELSE ! must calculate f
!    FrictionFactor    =  CalculateMoodyFrictionFactor(ReynoldsNumber,RoughnessRatio)
!  END IF
!
!  !Pressure drop calculation
!  PressureCurveValue  =  (FrictionFactor * (Length / Diameter) + MinorLossCoeff) * (Density * Velocity**2) / 2.0d0
!
!END FUNCTION PressureCurveValue
!
!=================================================================================================!

!REAL(r64) FUNCTION CalculateMoodyFrictionFactor(ReynoldsNumber, RoughnessRatio)
!
!          ! FUNCTION INFORMATION:
!          !       AUTHOR         Edwin Lee
!          !       DATE WRITTEN   August 2009
!          !       MODIFIED       na
!          !       RE-ENGINEERED  na
!
!          ! PURPOSE OF THIS FUNCTION:
!          ! This will evaluate the moody friction factor based on Reynolds number and roughness ratio
!
!          ! METHODOLOGY EMPLOYED:
!          ! General empirical correlations for friction factor based on Moody Chart data
!
!          ! REFERENCES:
!          ! Haaland, SE (1983). "Simple and Explicit Formulas for the Friction Factor in Turbulent Flow".
!          !   Trans. ASIVIE, J. of Fluids Engineering 103: 89-90.
!
!          ! USE STATEMENTS:
!  USE General, ONLY: RoundSigDigits
!
!  IMPLICIT NONE ! Enforce explicit typing of all variables in this routine
!
!          ! FUNCTION ARGUMENT DEFINITIONS:
!  REAL(r64), INTENT(IN)    ::  ReynoldsNumber
!  REAL(r64), INTENT(IN)    ::  RoughnessRatio
!
!          ! FUNCTION PARAMETER DEFINITIONS:
!          ! na
!
!          ! INTERFACE BLOCK SPECIFICATIONS:
!          ! na
!
!          ! DERIVED TYPE DEFINITIONS:
!          ! na
!
!          ! FUNCTION LOCAL VARIABLE DECLARATIONS:
!  REAL(r64)                    ::  Term1, Term2, Term3
!  CHARACTER(len=MaxNameLength) ::  RR, Re
!  LOGICAL, SAVE                ::  FrictionFactorErrorHasOccurred = .FALSE.
!
!  !Check for no flow before calculating values
!  IF (ReynoldsNumber .EQ. 0.0d0) THEN
!    CalculateMoodyFrictionFactor = 0.0d0
!    RETURN
!  END IF
!
!  !Check for no roughness also here
!  IF (RoughnessRatio .EQ. 0.0d0) THEN
!    CalculateMoodyFrictionFactor = 0.0d0
!    RETURN
!  END IF
!
!  !Calculate the friction factor
!  Term1 = (RoughnessRatio/3.7d0)**(1.11d0)
!  Term2 = 6.9d0/ReynoldsNumber
!  Term3 = -1.8d0 * LOG10(Term1 + Term2)
!  IF (Term3 .NE. 0.0d0) THEN
!    CalculateMoodyFrictionFactor = Term3 ** (-2.0d0)
!  ELSE
!    IF (.NOT. FrictionFactorErrorHasOccurred) THEN
!      RR=RoundSigDigits(RoughnessRatio,7)
!      Re=RoundSigDigits(ReynoldsNumber,1)
!      CALL ShowSevereError('Plant Pressure System: Error in moody friction factor calculation')
!      CALL ShowContinueError('Current Conditions: Roughness Ratio='//TRIM(RR)//'; Reynolds Number='//TRIM(Re))
!      CALL ShowContinueError('These conditions resulted in an unhandled numeric issue.')
!      CALL ShowContinueError('Please contact EnergyPlus support/development team to raise an alert about this issue')
!      CALL ShowContinueError('This issue will occur only one time.  The friction factor has been reset to 0.04 for calculations')
!      FrictionFactorErrorHasOccurred = .TRUE.
!    END IF
!    CalculateMoodyFrictionFactor = 0.04d0
!  END IF
!
!  RETURN
!
!END FUNCTION CalculateMoodyFrictionFactor
!
!!=================================================================================================!

SUBROUTINE UpdatePressureDrop(LoopNum)

          ! SUBROUTINE INFORMATION:
          !       AUTHOR         Edwin Lee
          !       DATE WRITTEN   August 2009
          !       MODIFIED       na
          !       RE-ENGINEERED  na

          ! PURPOSE OF THIS SUBROUTINE:
          ! Evaluate the pressure drop across an entire plant loop and places the value
          ! on the PlantLoop(:) data structure for the pump to use

          ! METHODOLOGY EMPLOYED:
          ! Assumes that the supply inlet is the starting node, which will be set to some standard pressure
          ! Then we move around the loop backward from this reference point and go until we hit a pump and stop.
          ! The pressure difference from reference to pump is the new required pump head.

          ! REFERENCES:
          ! na

          ! USE STATEMENTS:
  USE DataPlant,       ONLY :  PlantLoop, DemandSide, SupplySide
  USE DataLoopNode,    ONLY :  Node

  IMPLICIT NONE ! Enforce explicit typing of all variables in this routine

          ! SUBROUTINE ARGUMENT DEFINITIONS:
  INTEGER, INTENT(IN)      ::  LoopNum

          ! SUBROUTINE PARAMETER DEFINITIONS:
          ! na

          ! INTERFACE BLOCK SPECIFICATIONS:
          ! na

          ! DERIVED TYPE DEFINITIONS:
          ! na

          ! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
  INTEGER                  ::  LoopSideNum
  INTEGER                  ::  BranchNum
  INTEGER                  ::  NumBranches
  REAL(r64)                ::  BranchPressureDrop
  REAL(r64)                ::  LoopSidePressureDrop
  REAL(r64)                ::  LoopPressureDrop
  REAL(r64), ALLOCATABLE, DIMENSION(:) ::  ParallelBranchPressureDrops
  REAL(r64), ALLOCATABLE, DIMENSION(:) ::  ParallelBranchInletPressures
  INTEGER                  ::  ParallelBranchCounter
  REAL(r64)                ::  SplitterInletPressure
  REAL(r64)                ::  MixerPressure
  LOGICAL                  ::  FoundAPumpOnBranch
  REAL(r64)                ::  EffectiveLoopKValue
  REAL(r64)                ::  EffectiveLoopSideKValue
  REAL(r64)                ::  TempVal_SumOfOneByRootK

  !Exit if not needed
  IF (.NOT. PlantLoop(LoopNum)%HasPressureComponents) RETURN

  !Now go through and update the pressure drops as needed
  FoundAPumpOnBranch = .FALSE.
  LoopPressureDrop = 0.0d0
  DO LoopSideNum = DemandSide, SupplySide !Start at demand side outlet

    !Loop through all branches on this loop side
    LoopSidePressureDrop = 0.0d0
    NumBranches = SIZE(PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch)

    !Split here based on a single branch loop or a splitter/mixer configuration
    IF (NumBranches == 1) THEN  !Just do the single branch

      !***SINGLE BRANCH***!
      BranchNum = 1
      CALL DistributePressureOnBranch(LoopNum,LoopSideNum,BranchNum,BranchPressureDrop,FoundAPumpOnBranch)
      LoopSidePressureDrop = LoopSidePressureDrop + BranchPressureDrop
      LoopPressureDrop = LoopPressureDrop + BranchPressureDrop
      !*******************!

    ELSE IF (NumBranches > 1) THEN  !Loop through all branches on this loop side, mixer/splitter configuration

      !***OUTLET BRANCH***!
      BranchNum = NumBranches
      CALL DistributePressureOnBranch(LoopNum,LoopSideNum,BranchNum,BranchPressureDrop,FoundAPumpOnBranch)
      LoopSidePressureDrop = LoopSidePressureDrop + BranchPressureDrop
      LoopPressureDrop = LoopPressureDrop + BranchPressureDrop
      !*******************!

      !***MIXER SIMULATION***!
      MixerPressure = Node(PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%NodeNumIn)%Press
      CALL PassPressureAcrossMixer(LoopNum,LoopSideNum,MixerPressure,NumBranches)
      !**********************!

      !***PARALLEL BRANCHES***!
      IF (ALLOCATED(ParallelBranchPressureDrops)) DEALLOCATE(ParallelBranchPressureDrops)
      ALLOCATE(ParallelBranchPressureDrops(NumBranches-2))
      IF (ALLOCATED(ParallelBranchInletPressures)) DEALLOCATE(ParallelBranchInletPressures)
      ALLOCATE(ParallelBranchInletPressures(NumBranches-2))
      ParallelBranchCounter = 0
      DO BranchNum = NumBranches-1, 2, -1 !Working backward (not necessary, but consistent)
        ParallelBranchCounter = ParallelBranchCounter + 1
        CALL DistributePressureOnBranch(LoopNum,LoopSideNum,BranchNum, &
                                        ParallelBranchPressureDrops(ParallelBranchCounter),FoundAPumpOnBranch)
        !Store the branch inlet pressure so we can pass it properly across the splitter
        ParallelBranchInletPressures(ParallelBranchCounter) = &
          Node(PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%NodeNumIn)%Press
      END DO

      !Now take max inlet pressure to pass across splitter and max branch pressure for bookkeeping
      SplitterInletPressure = MAXVAL(ParallelBranchInletPressures)
      BranchPressureDrop = MAXVAL(ParallelBranchPressureDrops)
      LoopSidePressureDrop = LoopSidePressureDrop + BranchPressureDrop
      LoopPressureDrop = LoopPressureDrop + BranchPressureDrop
      !**********************!

      !If we found pumps on the parallel branches then we are done,
      ! If we are on the demand side, we have a common pipe situation and should issue a warning
      IF (FoundAPumpOnBranch) THEN
        IF (LoopSideNum == DemandSide) THEN
          CALL ShowSevereError('Pressure system information was found in a demand pump (common pipe) simulation')
          CALL ShowContinueError('Currently the pressure simulation is not set up to handle common pipe simulations')
          CALL ShowContinueError('Either modify simulation to avoid common pipe, or remove pressure curve information')
          CALL ShowFatalError('Pressure configuration mismatch causes program termination')
        END IF
        ! If we are on the supply side, we simply hit the branch pump, so we exit the IF statement as
        !  we don't need to simulate the splitter or inlet branch
        ! For now, not doing anything will leave the IF block
      END IF

      !If we haven't found a pump on the parallel branches then we need to go ahead
      ! and simulate the splitter and inlet branch

      !This may all be superfluous, if we just simulate the splitter and inlet branch we may be fine
      ! even if there were branch pumps found.
      IF (.NOT. FoundAPumpOnBranch) THEN

        !***SPLITTER SIMULATION***!
        CALL PassPressureAcrossSplitter(LoopNum,LoopSideNum,SplitterInletPressure)
        !*************************!

        !***INLET BRANCH***!
        BranchNum = 1
        CALL DistributePressureOnBranch(LoopNum,LoopSideNum,BranchNum,BranchPressureDrop,FoundAPumpOnBranch)
        LoopSidePressureDrop = LoopSidePressureDrop + BranchPressureDrop
        LoopPressureDrop = LoopPressureDrop + BranchPressureDrop
        !******************!

        !***PLANT INTERFACE***!
        IF (LoopSideNum == DemandSide) THEN
          CALL PassPressureAcrossInterface(LoopNum)
        END IF
        !*********************!

      END IF

    END IF

    PlantLoop(LoopNum)%LoopSide(LoopSideNum)%PressureDrop = LoopSidePressureDrop

  END DO !LoopSides on this loop

  PlantLoop(LoopNum)%PressureDrop = LoopPressureDrop

  !Now do effective K value calculations
  EffectiveLoopKValue = 0.0d0

  DO LoopSideNum = DemandSide, SupplySide

    EffectiveLoopSideKValue = 0.0d0

    !Always take the first branch K, it may be the only branch on this half loop
    EffectiveLoopSideKValue = EffectiveLoopSideKValue + PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(1)%PressureEffectiveK

    !If there is only one branch then move to the other loop side
    IF (SIZE(PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch).EQ.1) CYCLE

    !Add parallel branches if necessary by adding them as SUM(1/(sqrt(K_i)))
    TempVal_SumOfOneByRootK = 0.0d0
    DO BranchNum = 2, SIZE(PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch)-1

      !Only add this branch if the K value is non-zero
      IF (PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%PressureEffectiveK .GT. 0.0d0) THEN
        TempVal_SumOfOneByRootK = TempVal_SumOfOneByRootK  &
                                  + (1.0d0 / SQRT(PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%PressureEffectiveK))
      END IF

    END DO

    !Add parallel branches if they are greater than zero, by taking the sum and performing (1/(SUM^2))
    IF (TempVal_SumOfOneByRootK .GT. 0.0d0)   &
       EffectiveLoopSideKValue = EffectiveLoopSideKValue + (1.0d0/(TempVal_SumOfOneByRootK ** 2))

    !Always take the last branch K, it will be in series
    BranchNum = SIZE(PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch)
    EffectiveLoopSideKValue = EffectiveLoopSideKValue +   &
                                PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%PressureEffectiveK

    !Assign this loop side's K-value
    PlantLoop(LoopNum)%LoopSide(LoopSideNum)%PressureEffectiveK = EffectiveLoopSideKValue

    !Keep adding the overall loop K-value
    EffectiveLoopKValue = EffectiveLoopKValue + EffectiveLoopSideKValue

  END DO

  !Assign this loop's K-value
  PlantLoop(LoopNum)%PressureEffectiveK = EffectiveLoopKValue

  RETURN

END SUBROUTINE UpdatePressureDrop

!=================================================================================================!

SUBROUTINE DistributePressureOnBranch(LoopNum,LoopSideNum,BranchNum,BranchPressureDrop,PumpFound)

          ! SUBROUTINE INFORMATION:
          !       AUTHOR         Edwin Lee
          !       DATE WRITTEN   August 2009
          !       MODIFIED       na
          !       RE-ENGINEERED  na

          ! PURPOSE OF THIS SUBROUTINE:
          ! Apply proper pressure to nodes along branch

          ! METHODOLOGY EMPLOYED:
          ! Move backward through components, passing pressure upstream
          ! Account for branch pressure drop at branch inlet node
          ! Update PlantLoop(:)%LoopSide(:)%Branch(:)%PressureDrop Variable

          ! REFERENCES:
          ! na

          ! USE STATEMENTS:
  USE DataPlant,    ONLY :  PlantLoop, GenEquipTypes_Pump, DemandSide, SupplySide
  USE DataLoopNode, ONLY :  Node

  IMPLICIT NONE ! Enforce explicit typing of all variables in this routine

          ! SUBROUTINE ARGUMENT DEFINITIONS:
  INTEGER,   INTENT(IN)      ::  LoopNum
  INTEGER,   INTENT(IN)      ::  LoopSideNum
  INTEGER,   INTENT(IN)      ::  BranchNum
  REAL(r64), INTENT(INOUT)   ::  BranchPressureDrop
  LOGICAL                    ::  PumpFound

          ! SUBROUTINE PARAMETER DEFINITIONS:
          ! na

          ! INTERFACE BLOCK SPECIFICATIONS:
          ! na

          ! DERIVED TYPE DEFINITIONS:
          ! na

          ! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
  INTEGER                  ::  CompNum
  INTEGER                  ::  NumCompsOnBranch
  REAL(r64)                ::  TempBranchPressureDrop

  !Initialize
  TempBranchPressureDrop = 0.0d0
  BranchPressureDrop = 0.0d0
  PumpFound = .FALSE.
  NumCompsOnBranch = SIZE(PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%Comp)

  !Retrieve temporary branch pressure drop
  IF (PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%HasPressureComponents) THEN
    TempBranchPressureDrop = PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%PressureDrop
  END IF

  !If the last component on the branch is the pump, then check if a pressure drop is detected and set the flag and leave
  IF (PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%Comp(NumCompsOnBranch)%GeneralEquipType==GenEquipTypes_Pump)THEN
    PumpFound = .TRUE.
    IF (TempBranchPressureDrop .NE. 0.0d0) THEN
      CALL ShowSevereError('Error in plant pressure simulation for plant loop: '//PlantLoop(LoopNum)%Name)
      IF (LoopNum == DemandSide) THEN
        CALL ShowContinueError('Occurs for demand side, branch: '//PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%Name)
      ELSE IF (LoopNum == SupplySide) THEN
        CALL ShowContinueError('Occurs for supply side, branch: '//PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%Name)
      END IF
      CALL ShowContinueError('Branch contains only a single pump component, yet also a pressure drop component.')
      CALL ShowContinueError('Either add a second component to this branch after the pump, or move pressure drop data.')
      CALL ShowFatalError('Preceding pressure drop error causes program termination')
    END IF
    RETURN
  END IF

  !Assign official branch pressure drop
  IF (PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%HasPressureComponents) THEN
    BranchPressureDrop = TempBranchPressureDrop
  END IF

  !Otherwise update the inlet node of the last component on the branch with this corrected pressure
  !This essentially sets all the pressure drop on the branch to be accounted for on the last component
  Node(PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%Comp(NumCompsOnBranch)%NodeNumIn)%Press &
   = Node(PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%Comp(NumCompsOnBranch)%NodeNumOut)%Press + BranchPressureDrop

  !Then Smear any internal nodes with this new node pressure by working backward through
  ! all but the last component, and passing node pressure upstream
  IF (NumCompsOnBranch > 1) THEN
    DO CompNum = NumCompsOnBranch-1, 1, -1

      !If this component is a pump, stop passing pressure upstream, and set flag to true for calling routine
      IF (PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%Comp(CompNum)%GeneralEquipType==GenEquipTypes_Pump) THEN
        PumpFound = .TRUE.
        EXIT
      END IF

      !Otherwise just pass pressure upstream and move on
      Node(PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%Comp(CompNum)%NodeNumIn)%Press = &
      Node(PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%Comp(CompNum)%NodeNumOut)%Press

    END DO
  END IF


END SUBROUTINE DistributePressureOnBranch

!=================================================================================================!

SUBROUTINE PassPressureAcrossMixer(LoopNum,LoopSideNum,MixerPressure,NumBranchesOnLoopSide)

          ! SUBROUTINE INFORMATION:
          !       AUTHOR         Edwin Lee
          !       DATE WRITTEN   August 2009
          !       MODIFIED       na
          !       RE-ENGINEERED  na

          ! PURPOSE OF THIS SUBROUTINE:
          ! Set mixer inlet pressures, or in other words, set mixer inlet branch outlet pressures

          ! METHODOLOGY EMPLOYED:
          ! Set outlet node pressures for all parallel branches on this loopside
          ! Note that this is extremely simple, but is set to it's own routine to allow for clarity
          !  when possible expansion occurs during further development

          ! REFERENCES:
          ! na

          ! USE STATEMENTS:
  USE DataPlant,    ONLY :  PlantLoop
  USE DataLoopNode, ONLY :  Node

  IMPLICIT NONE ! Enforce explicit typing of all variables in this routine

          ! SUBROUTINE ARGUMENT DEFINITIONS:
  INTEGER,   INTENT(IN)      ::  LoopNum
  INTEGER,   INTENT(IN)      ::  LoopSideNum
  REAL(r64), INTENT(INOUT)   ::  MixerPressure
  INTEGER,   INTENT(IN)      ::  NumBranchesOnLoopSide

          ! SUBROUTINE PARAMETER DEFINITIONS:
          ! na

          ! INTERFACE BLOCK SPECIFICATIONS:
          ! na

          ! DERIVED TYPE DEFINITIONS:
          ! na

          ! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
  INTEGER                    ::  BranchNum

  DO BranchNum = 2, NumBranchesOnLoopSide-1
    Node(PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(BranchNum)%NodeNumOut)%Press = MixerPressure
  END DO

END SUBROUTINE PassPressureAcrossMixer

!=================================================================================================!

SUBROUTINE PassPressureAcrossSplitter(LoopNum,LoopSideNum,SplitterInletPressure)

          ! SUBROUTINE INFORMATION:
          !       AUTHOR         Edwin Lee
          !       DATE WRITTEN   August 2009
          !       MODIFIED       na
          !       RE-ENGINEERED  na

          ! PURPOSE OF THIS SUBROUTINE:
          ! Set the splitter inlet pressure in anticipation of the inlet branch pressure being simulated

          ! METHODOLOGY EMPLOYED:
          ! Set outlet node of loopside inlet branch to splitter pressure
          ! Note that this is extremely simple, but is set to it's own routine to allow for clarity
          !  when possible expansion occurs during further development

          ! REFERENCES:
          ! na

          ! USE STATEMENTS:
  USE DataPlant,    ONLY :  PlantLoop
  USE DataLoopNode, ONLY :  Node

  IMPLICIT NONE ! Enforce explicit typing of all variables in this routine

          ! SUBROUTINE ARGUMENT DEFINITIONS:
  INTEGER,   INTENT(IN)      ::  LoopNum
  INTEGER,   INTENT(IN)      ::  LoopSideNum
  REAL(r64), INTENT(INOUT)   ::  SplitterInletPressure

          ! SUBROUTINE PARAMETER DEFINITIONS:
  INTEGER, PARAMETER         ::  InletBranchNum = 1

          ! INTERFACE BLOCK SPECIFICATIONS:
          ! na

          ! DERIVED TYPE DEFINITIONS:
          ! na

          ! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
          ! na

  Node(PlantLoop(LoopNum)%LoopSide(LoopSideNum)%Branch(InletBranchNum)%NodeNumOut)%Press = SplitterInletPressure

END SUBROUTINE PassPressureAcrossSplitter

!=================================================================================================!

SUBROUTINE PassPressureAcrossInterface(LoopNum)

          ! SUBROUTINE INFORMATION:
          !       AUTHOR         Edwin Lee
          !       DATE WRITTEN   August 2009
          !       MODIFIED       na
          !       RE-ENGINEERED  na

          ! PURPOSE OF THIS SUBROUTINE:
          ! Pass pressure backward across plant demand inlet/supply outlet interface

          ! METHODOLOGY EMPLOYED:
          ! Set outlet node pressure of supply side equal to inlet node pressure of demand side
          ! Note that this is extremely simple, but is set to it's own routine to allow for clarity
          !  when possible expansion occurs during further development

          ! REFERENCES:
          ! na

          ! USE STATEMENTS:
  USE DataPlant,    ONLY :  PlantLoop, DemandSide, SupplySide
  USE DataLoopNode, ONLY :  Node

  IMPLICIT NONE ! Enforce explicit typing of all variables in this routine

          ! SUBROUTINE ARGUMENT DEFINITIONS:
  INTEGER,   INTENT(IN)      ::  LoopNum

          ! SUBROUTINE PARAMETER DEFINITIONS:
          ! na

          ! INTERFACE BLOCK SPECIFICATIONS:
          ! na

          ! DERIVED TYPE DEFINITIONS:
          ! na

          ! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
  INTEGER :: DemandInletNodeNum
  INTEGER :: SupplyOutletNodeNum

  DemandInletNodeNum = PlantLoop(LoopNum)%LoopSide(DemandSide)%NodeNumIn
  SupplyOutletNodeNum = PlantLoop(LoopNum)%LoopSide(SupplySide)%NodeNumOut

  Node(SupplyOutletNodeNum)%Press = Node(DemandInletNodeNum)%Press

END SUBROUTINE PassPressureAcrossInterface

!=================================================================================================!

!SUBROUTINE GetPressureCurveTypeAndIndex(PressureCurveName, PressureCurveType, PressureCurveIndex)
!
!          ! SUBROUTINE INFORMATION:
!          !       AUTHOR         Edwin Lee
!          !       DATE WRITTEN   August 2009
!          !       MODIFIED       na
!          !       RE-ENGINEERED  na
!
!          ! PURPOSE OF THIS SUBROUTINE:
!          ! Given a curve name, returns the curve type and index
!
!          ! METHODOLOGY EMPLOYED:
!          ! Curve types are:
!          !  PressureCurve_Error       = pressure name was given, but curve is not available
!          !  PressureCurve_None        = no pressure curve for this branch
!          !  PressureCurve_Pressure    = pressure curve based on friction/minor loss
!          !  PressureCurve_Generic     = curvemanager held curve which is function of flow rate
!
!          ! REFERENCES:
!          ! na
!
!          ! USE STATEMENTS:
!  USE InputProcessor, ONLY : FindItemInList
!  USE CurveManager,   ONLY : GetCurveIndex, GetCurveType
!  USE GlobalDataConstants,  ONLY : PressureCurve_None, PressureCurve_Pressure, PressureCurve_Generic, PressureCurve_Error
!
!  IMPLICIT NONE    ! Enforce explicit typing of all variables in this routine
!
!          ! SUBROUTINE ARGUMENT DEFINITIONS:
!  CHARACTER(len=*), INTENT (IN)  :: PressureCurveName            ! name of the curve
!  INTEGER, INTENT(INOUT)         :: PressureCurveType
!  INTEGER, INTENT(INOUT)         :: PressureCurveIndex
!
!          ! SUBROUTINE PARAMETER DEFINITIONS:
!          ! na
!
!          ! INTERFACE BLOCK SPECIFICATIONS
!          ! na
!
!          ! DERIVED TYPE DEFINITIONS
!          ! na
!
!          ! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
!  INTEGER           :: TempCurveIndex
!  LOGICAL           :: FoundCurve
!  CHARACTER(len=32) :: GenericCurveType
!
!  !If input is not gotten, go ahead and get it now
!  IF (GetInputFlag) CALL GetPressureSystemInput
!
!  !Initialize
!  FoundCurve = .FALSE.
!  PressureCurveType = PressureCurve_None
!  PressureCurveIndex = 0
!
!  !Try to retrieve a curve manager object
!  TempCurveIndex = GetCurveIndex(PressureCurveName)
!
!  !See if it is valid
!  IF (TempCurveIndex > 0) THEN
!    !We have to check the type of curve to make sure it is single independent variable type
!    GenericCurveType = GetCurveType(TempCurveIndex)
!    SELECT CASE (GenericCurveType)
!      CASE ('LINEAR', 'QUADRATIC', 'CUBIC', 'QUARTIC', 'EXPONENT')
!        PressureCurveType = PressureCurve_Generic
!        PressureCurveIndex = TempCurveIndex
!      CASE DEFAULT
!        CALL ShowSevereError('Plant Pressure Simulation: Found error for curve: '//PressureCurveName)
!        CALL ShowContinueError('Curve type detected: '//GenericCurveType)
!        CALL ShowContinueError('Generic curves should be single independent variable such that DeltaP = f(mdot)')
!        CALL ShowContinueError(' Therefore they should be of type: Linear, Quadratic, Cubic, Quartic, or Exponent')
!        CALL ShowFatalError('Errors in pressure simulation input cause program termination')
!    END SELECT
!    RETURN
!  END IF
!
!  !Then try to retrieve a pressure curve object
!  IF (ALLOCATED(PressureCurve)) THEN
!    IF (SIZE(PressureCurve) > 0) THEN
!      TempCurveIndex = FindItemInList(PressureCurveName,PressureCurve(1:SIZE(PressureCurve))%Name,SIZE(PressureCurve))
!    ELSE
!      TempCurveIndex = 0
!    END IF
!  END IF
!
!  !See if it is valid
!  IF (TempCurveIndex > 0) THEN
!    PressureCurveType = PressureCurve_Pressure
!    PressureCurveIndex = TempCurveIndex
!    RETURN
!  END IF
!
!  !If we made it here, we didn't find either type of match
!
!  !Last check, see if it is blank:
!  IF (TRIM(PressureCurveName)=='') THEN
!    PressureCurveType = PressureCurve_None
!    RETURN
!  END IF
!
!  !At this point, we had a non-blank user entry with no match
!  PressureCurveType = PressureCurve_Error
!  RETURN
!
!RETURN
!
!END SUBROUTINE
!
!
!=================================================================================================!


REAL(r64) FUNCTION ResolveLoopFlowVsPressure(LoopNum, SystemMassFlow, PumpCurveNum, &
                                             PumpSpeed, PumpImpellerDia, MinPhi, MaxPhi)  RESULT (ResolvedLoopMassFlowRate)


          ! FUNCTION INFORMATION:
          !       AUTHOR         Kaustubh Phalak
          !       DATE WRITTEN   Feb 2010
          !       MODIFIED       na
          !       RE-ENGINEERED  na

          ! PURPOSE OF THIS FUNCTION:
          ! To provide a means to simulate a constant speed pump curve and system curve to
          !  find a more realistic operating point for the plant.

          ! METHODOLOGY EMPLOYED:
          ! Pressure drop of complete loop is found for a perticular flow rate.
          !  i.e. pressuredrop = K * massflow ^ 2
          ! System curve is then solved with pump curve already entered
          !  and flow rate provided by the pump will be calculated.
          ! This routine does not trap for errors if a pressure simulation is not to be performed.
          ! Calling routine should only call this if needed.

          ! REFERENCES:
          !  -

          ! USE STATEMENTS:
  USE General,          ONLY: RoundSigDigits
  USE DataPlant,        ONLY: PlantLoop, SupplySide
  USE DataLoopNode,     ONLY: Node
  USE FluidProperties,  ONLY: GetDensityGlycol, GetViscosityGlycol
  USE CurveManager,     ONLY: CurveValue

  IMPLICIT NONE ! Enforce explicit typing of all variables in this routine

          ! FUNCTION ARGUMENT DEFINITIONS:
  INTEGER,    INTENT(IN)  ::  LoopNum         !- Index of which plant/condenser loop is being simulated
  REAL(r64),  INTENT(IN)  ::  SystemMassFlow  !- Initial "guess" at system mass flow rate [kg/s]
  INTEGER,    INTENT(IN)  ::  PumpCurveNum    !- Pump curve to use when calling the curve manager for psi = f(phi)
  REAL(r64),  INTENT(IN)  ::  PumpSpeed       !- Pump rotational speed, [rps] (revs per second)
  REAL(r64),  INTENT(IN)  ::  PumpImpellerDia !- Nominal pump impeller diameter [m]
  REAL(r64),  INTENT(IN)  ::  MinPhi          !- Minimum allowable value of phi, requested by the pump manager from curve mgr
  REAL(r64),  INTENT(IN)  ::  MaxPhi          !- Maximum allowable value of phi, requested by the pump manager from curve mgr

          ! FUNCTION PARAMETER DEFINITIONS:
  CHARACTER(len=*), PARAMETER   ::  RoutineName      = 'ResolvedLoopMassFlowRate: '
  INTEGER,          PARAMETER   ::  MaxIters         = 100
  CHARACTER(LEN=*), PARAMETER   ::  DummyFluidName   = ' '
  REAL(r64),        PARAMETER   ::  PressureConvergeCriteria = 0.1d0   !Pa
  REAL(r64),        PARAMETER   ::  ZeroTolerance    = 0.0001d0

          ! INTERFACE BLOCK SPECIFICATIONS:
          ! na

          ! DERIVED TYPE DEFINITIONS:
          ! na

          ! FUNCTION LOCAL VARIABLE DECLARATIONS:
  REAL(r64)                     ::  PumpPressureRise
  Real(r64)                     ::  NodeTemperature
  Real(r64)                     ::  NodeDensity
  REAL(r64)                     ::  SystemPressureDrop
  REAL(r64)                     ::  PhiPump
  REAL(r64)                     ::  PhiSystem
  REAL(r64)                     ::  PsiPump
  INTEGER                       ::  FluidIndex
  INTEGER                       ::  Iteration
  REAL(r64)                     ::  LocalSystemMassFlow
  REAL(r64)                     ::  LoopEffectiveK
  LOGICAL                       ::  Converged
  INTEGER, SAVE                 ::  ZeroKWarningCounter = 0
  INTEGER, SAVE                 ::  MaxIterWarningCounter = 0
  REAL(r64), DIMENSION(3)       ::  MassFlowIterativeHistory
  REAL(r64)                     ::  MdotDeltaLatest
  REAL(r64)                     ::  MdotDeltaPrevious
  REAL(r64)                     ::  DampingFactor

   !Get loop level data
  FluidIndex         = PlantLoop(LoopNum)%FluidIndex
  LoopEffectiveK     = PlantLoop(LoopNum)%PressureEffectiveK
  SystemPressureDrop = LoopEffectiveK * SystemMassFlow **2.0d0

  !Read data off the node data structure
  NodeTemperature = Node(PlantLoop(LoopNum)%LoopSide(SupplySide)%NodeNumIn)%Temp
  NodeDensity     = GetDensityGlycol(DummyFluidName, NodeTemperature, FluidIndex, RoutineName)

  !Store the passed in (requested, design) flow to the local value for performing iterations
  LocalSystemMassFlow = SystemMassFlow

  !Check and warn if invalid condition exists
  IF (LoopEffectiveK .LE. ZeroTolerance) THEN
    ZeroKWarningCounter = ZeroKWarningCounter + 1
    IF (ZeroKWarningCounter == 1) THEN
      CALL ShowWarningError('Pump pressure-flow resolution attempted, but invalid loop conditions encountered.')
      CALL ShowContinueError('Loop being calculated: '//PlantLoop(LoopNum)%Name)
      CALL ShowContinueError('An invalid pressure/flow condition existed which resulted in the approximation of')
      CALL ShowContinueError('the pressure coefficient K to be zero.  The pressure simulation will use the requested (design)')
      CALL ShowContinueError('pump flow in order to proceed with the simulation.  This warning is only issued once.')
    END IF
    ResolvedLoopMassFlowRate = SystemMassFlow
    RETURN
  END IF

  !Initialize flag
  Converged = .FALSE.

  !Initialize the mass flow history array and damping factor
  MassFlowIterativeHistory = LocalSystemMassFlow
  DampingFactor = 0.9d0

  !Start Convergence Loop
  DO Iteration = 1, MaxIters

    !Calculate System Mass Flow Rate
    LocalSystemMassFlow = SQRT(SystemPressureDrop / LoopEffectiveK)

    MassFlowIterativeHistory = EOSHIFT(MassFlowIterativeHistory, SHIFT=-1, BOUNDARY=LocalSystemMassFlow)

    PhiSystem = LocalSystemMassFlow / (NodeDensity * PumpSpeed * PumpImpellerDia)

    !4th order polynomial for non-dimensional pump curve
    PhiPump = PhiSystem

    !Constrain the value to the valid region
    PhiPump = MAX(PhiPump,MinPhi)
    PhiPump = MIN(PhiPump,MaxPhi)

    !Get the pump curve value from the curve manager
    PsiPump = CurveValue(PumpCurveNum, PhiPump)

    !Calcuate Pump Pressure rise
    PumpPressureRise = PsiPump * NodeDensity * (PumpSpeed**2) * (PumpImpellerDia**2)

    !Convergence Criteria Based on Pressure
    If (ABS(SystemPressureDrop - PumpPressureRise).LT.(PressureConvergeCriteria)) THEN
      ResolvedLoopMassFlowRate = LocalSystemMassFlow
      Converged = .TRUE.
      EXIT
    END IF

    IF (Iteration < 2) THEN
      !Don't do anything?
    ELSE
      MdotDeltaLatest = ABS(MassFlowIterativeHistory(1) - MassFlowIterativeHistory(2))
      MdotDeltaPrevious = ABS(MassFlowIterativeHistory(2) - MassFlowIterativeHistory(3))
      IF (MdotDeltaLatest < MdotDeltaPrevious) THEN
        !we are converging
        !DampingFactor = MIN(DampingFactor * 1.1, 0.9d0)
      ELSE
        !we are stuck or diverging
        DampingFactor = DampingFactor * 0.9d0
      END IF
    END IF

    !Update pressure value with damping factor
    SystemPressureDrop = DampingFactor * PumpPressureRise + (1.0d0 - DampingFactor) * SystemPressureDrop

  END DO

  !Check if we didn't converge
  IF (.NOT. Converged) THEN
    MaxIterWarningCounter = MaxIterWarningCounter + 1
    IF (MaxIterWarningCounter == 1) THEN
      CALL ShowWarningError('Pump pressure-flow resolution attempted, but iteration loop did not converge.')
      CALL ShowContinueError('Loop being calculated: '//PlantLoop(LoopNum)%Name)
      CALL ShowContinueError('A mismatch between the pump curve entered and the pressure drop components')
      CALL ShowContinueError('on the loop may be the cause.  The pressure simulation will use the requested (design)')
      CALL ShowContinueError('pump flow in order to proceed with the simulation.  This warning is only issued once.')
    END IF
    ResolvedLoopMassFlowRate = SystemMassFlow
    RETURN
  ENDIF

  RETURN

  End FUNCTION ResolveLoopFlowVsPressure

!=================================================================================================!

!     NOTICE
!
!     Copyright © 1996-2013 The Board of Trustees of the University of Illinois
!     and The Regents of the University of California through Ernest Orlando Lawrence
!     Berkeley National Laboratory.  All rights reserved.
!
!     Portions of the EnergyPlus software package have been developed and copyrighted
!     by other individuals, companies and institutions.  These portions have been
!     incorporated into the EnergyPlus software package under license.   For a complete
!     list of contributors, see "Notice" located in EnergyPlus.f90.
!
!     NOTICE: The U.S. Government is granted for itself and others acting on its
!     behalf a paid-up, nonexclusive, irrevocable, worldwide license in this data to
!     reproduce, prepare derivative works, and perform publicly and display publicly.
!     Beginning five (5) years after permission to assert copyright is granted,
!     subject to two possible five year renewals, the U.S. Government is granted for
!     itself and others acting on its behalf a paid-up, non-exclusive, irrevocable
!     worldwide license in this data to reproduce, prepare derivative works,
!     distribute copies to the public, perform publicly and display publicly, and to
!     permit others to do so.
!
!     TRADEMARKS: EnergyPlus is a trademark of the US Department of Energy.
!

END MODULE PlantPressureSystem

AirflowNetworkBalanceManager.f90 AirflowNetworkSolver.f90 BaseboardRadiator.f90 BaseboardRadiatorElectric.f90 BaseboardRadiatorSteam.f90 BaseboardRadiatorWater.f90 BranchInputManager.f90 BranchNodeConnections.f90 ConductionTransferFunctionCalc.f90 CoolTower.f90 CostEstimateManager.f90 CurveManager.f90 CVFOnlyRoutines.f90 DataAirflowNetwork.f90 DataAirLoop.f90 DataAirSystems.f90 DataBranchAirLoopPlant.f90 DataBranchNodeConnections.f90 DataBSDFWindow.f90 DataComplexFenestration.f90 DataContaminantBalance.f90 DataConvergParams.f90 DataConversions.f90 DataCostEstimate.f90 DataDaylighting.f90 DataDaylightingDevices.f90 Datadefineequip.f90 DataDElight.f90 DataEnvironment.f90 DataEquivalentLayerWindow.f90 DataErrorTracking.f90 DataGenerators.f90 DataGlobalConstants.f90 DataGlobals.f90 DataHeatBalance.f90 DataHeatBalFanSys.f90 DataHeatBalSurface.f90 DataHVACControllers.f90 DataHVACGlobals.f90 DataInterfaces.f90 DataIPShortCuts.f90 DataLoopNode.f90 DataMoistureBalance.f90 DataMoistureBalanceEMPD.f90 DataOutputs.f90 DataPhotovoltaics.f90 DataPlant.f90 DataPlantPipingSystems.f90 DataPrecisionGlobals.f90 DataReportingFlags.f90 DataRoomAir.f90 DataRootFinder.f90 DataRuntimeLanguage.f90 DataShadowingCombinations.f90 DataSizing.f90 DataStringGlobals.f90 DataSurfaceColors.f90 DataSurfaceLists.f90 DataSurfaces.f90 DataSystemVariables.f90 DataTimings.f90 DataUCSDSharedData.f90 DataVectorTypes.f90 DataViewFactorInformation.f90 DataWater.f90 DataZoneControls.f90 DataZoneEnergyDemands.f90 DataZoneEquipment.f90 DaylightingDevices.f90 DaylightingManager.f90 DElightManagerF.f90 DElightManagerF_NO.f90 DemandManager.f90 DesiccantDehumidifiers.f90 DirectAir.f90 DisplayRoutines.f90 DXCoil.f90 EarthTube.f90 EconomicLifeCycleCost.f90 EconomicTariff.f90 EcoRoof.f90 ElectricPowerGenerators.f90 ElectricPowerManager.f90 EMSManager.f90 EnergyPlus.f90 ExteriorEnergyUseManager.f90 ExternalInterface_NO.f90 FanCoilUnits.f90 FaultsManager.f90 FluidProperties.f90 General.f90 GeneralRoutines.f90 GlobalNames.f90 HeatBalanceAirManager.f90 HeatBalanceConvectionCoeffs.f90 HeatBalanceHAMTManager.f90 HeatBalanceInternalHeatGains.f90 HeatBalanceIntRadExchange.f90 HeatBalanceManager.f90 HeatBalanceMovableInsulation.f90 HeatBalanceSurfaceManager.f90 HeatBalFiniteDifferenceManager.f90 HeatRecovery.f90 Humidifiers.f90 HVACControllers.f90 HVACCooledBeam.f90 HVACDualDuctSystem.f90 HVACDuct.f90 HVACDXSystem.f90 HVACEvapComponent.f90 HVACFanComponent.f90 HVACFurnace.f90 HVACHeatingCoils.f90 HVACHXAssistedCoolingCoil.f90 HVACInterfaceManager.f90 HVACManager.f90 HVACMixerComponent.f90 HVACMultiSpeedHeatPump.f90 HVACSingleDuctInduc.f90 HVACSingleDuctSystem.f90 HVACSplitterComponent.f90 HVACStandAloneERV.f90 HVACSteamCoilComponent.f90 HVACTranspiredCollector.f90 HVACUnitaryBypassVAV.f90 HVACUnitarySystem.f90 HVACVariableRefrigerantFlow.f90 HVACWaterCoilComponent.f90 HVACWatertoAir.f90 HVACWatertoAirMultiSpeedHP.f90 InputProcessor.f90 MatrixDataManager.f90 MixedAir.f90 MoistureBalanceEMPDManager.f90 NodeInputManager.f90 NonZoneEquipmentManager.f90 OutAirNodeManager.f90 OutdoorAirUnit.f90 OutputProcessor.f90 OutputReportPredefined.f90 OutputReports.f90 OutputReportTabular.f90 PackagedTerminalHeatPump.f90 PackagedThermalStorageCoil.f90 Photovoltaics.f90 PhotovoltaicThermalCollectors.f90 PlantAbsorptionChillers.f90 PlantBoilers.f90 PlantBoilersSteam.f90 PlantCentralGSHP.f90 PlantChillers.f90 PlantCondLoopOperation.f90 PlantCondLoopTowers.f90 PlantEIRChillers.f90 PlantEvapFluidCoolers.f90 PlantExhaustAbsorptionChiller.f90 PlantFluidCoolers.f90 PlantGasAbsorptionChiller.f90 PlantGroundHeatExchangers.f90 PlantHeatExchanger.f90 PlantIceThermalStorage.f90 PlantLoadProfile.f90 PlantLoopEquipment.f90 PlantLoopSolver.f90 PlantManager.f90 PlantOutsideEnergySources.f90 PlantPipeHeatTransfer.f90 PlantPipes.f90 PlantPipingSystemManager.f90 PlantPondGroundHeatExchanger.f90 PlantPressureSystem.f90 PlantPumps.f90 PlantSolarCollectors.f90 PlantSurfaceGroundHeatExchanger.f90 PlantUtilities.f90 PlantValves.f90 PlantWaterSources.f90 PlantWaterThermalTank.f90 PlantWatertoWaterGSHP.f90 PlantWaterUse.f90 PollutionAnalysisModule.f90 PoweredInductionUnits.f90 PsychRoutines.f90 Purchasedairmanager.f90 RadiantSystemHighTemp.f90 RadiantSystemLowTemp.f90 RefrigeratedCase.f90 ReportSizingManager.f90 ReturnAirPath.f90 RoomAirManager.f90 RoomAirModelCrossVent.f90 RoomAirModelDisplacementVent.f90 RoomAirModelMundt.f90 RoomAirModelUFAD.f90 RoomAirModelUserTempPattern.f90 RootFinder.f90 RuntimeLanguageProcessor.f90 ScheduleManager.f90 SetPointManager.f90 SimAirServingZones.f90 SimulationManager.f90 SizingManager.f90 SolarReflectionManager.f90 SolarShading.f90 SortAndStringUtilities.f90 sqlite3.c SQLiteCRoutines.c SQLiteFortranRoutines.f90 SQLiteFortranRoutines_NO.f90 StandardRatings.f90 SurfaceGeometry.f90 SystemAvailabilityManager.f90 SystemReports.f90 TarcogComplexFenestration.f90 ThermalChimney.f90 ThermalComfort.f90 UnitHeater.f90 UnitVentilator.f90 UserDefinedComponents.f90 UtilityRoutines.f90 VectorUtilities.f90 VentilatedSlab.f90 WaterManager.f90 WeatherManager.f90 WindowAC.f90 WindowComplexManager.f90 WindowEquivalentLayer.f90 WindowManager.f90 WindTurbine.f90 Zoneairloopequipmentmanager.f90 ZoneContaminantPredictorCorrector.f90 ZoneDehumidifier.f90 Zoneequipmentmanager.f90 ZonePlenumComponent.f90 ZoneTempPredictorCorrector.f90