Guide for Module Developers — EnergyPlus 8.3

<< Prev | Table of Contents | Object Index | Next >>

Module Example[LINK]

This example can be used as a template for new HVAC component modules. In particular, the commenting structure in the module and within the subroutines should be followed closely. Of course, there is no perfect example module - this one is particularly simple. Some others that might be examined are in files Humidifiers.f90, HVACHeatingCoils.f90 and PlantChillers.f90. Templates are also available as separate files.

In particular, the module template with routines contains structure and information pertinent to module development.

Note that in the following module, the “Data IPShortcuts” is not used - rather those variables are allocated within this module - likely because another module calls this one during input.

    Module Fans
      ! Module containing the fan simulation routines

      ! MODULE INFORMATION:
      !       AUTHOR         Richard J. Liesen
      !       DATE WRITTEN   April 1998
      !       MODIFIED       Shirey, May 2001
      !       RE-ENGINEERED  na

      ! PURPOSE OF THIS MODULE:
      ! To encapsulate the data and algorithms required to
      ! manage the Fan System Component

      ! REFERENCES: none

      ! OTHER NOTES: none

      ! USE STATEMENTS:
      ! Use statements for data only modules
    USE DataPrecisionGlobals
    USE DataLoopNode
    USE DataHVACGlobals, ONLY: TurnFansOn, TurnFansOff, Main, Cooling, Heating, Other, &
              OnOffFanPartLoadFraction, SmallAirVolFlow, UnbalExhMassFlow, NightVentOn, cFanTypes, &
              FanType_SimpleConstVolume, FanType_SimpleVAV, FanType_SimpleOnOff, FanType_ZoneExhaust
    USE DataGlobals,     ONLY: SetupOutputVariable, BeginEnvrnFlag, BeginDayFlag, MaxNameLength, &
           ShowWarningError, ShowFatalError, ShowSevereError, HourofDay, SysSizingCalc, CurrentTime, &
           OutputFileDebug, ShowContinueError, ShowRecurringWarningErrorAtEnd, WarmupFlag, &
                               ShowContinueErrorTimeStamp
    Use DataEnvironment, ONLY: StdBaroPress, DayofMonth, Month, StdRhoAir
    USE Psychrometrics,  ONLY:PsyRhoAirFnPbTdbW, PsyTdbFnHW, PsyCpAirFnWTdb

      ! Use statements for access to subroutines in other modules
    USE ScheduleManager

    IMPLICIT NONE         ! Enforce explicit typing of all variables

    PRIVATE ! Everything private unless explicitly made public

      !MODULE PARAMETER DEFINITIONS
      !na

      ! DERIVED TYPE DEFINITIONS
    TYPE FanEquipConditions
      CHARACTER(len=MaxNameLength) :: FanName  =' '  ! Name of the fan
      CHARACTER(len=MaxNameLength) :: FanType  =' '  ! Type of Fan ie. Simple, Vane axial, Centrifugal, etc.
      CHARACTER(len=MaxNameLength) :: Schedule =' '  ! Fan Operation Schedule
      INTEGER      :: FanType_Num              =0    ! DataHVACGlobals fan type
      Integer      :: SchedPtr                 =0    ! Pointer to the correct schedule
      REAL(r64)    :: InletAirMassFlowRate     =0.0  !MassFlow through the Fan being Simulated [kg/Sec]
      REAL(r64)    :: OutletAirMassFlowRate    =0.0
      REAL(r64)    :: MaxAirFlowRate           =0.0  !Max Specified Volume Flow Rate of Fan [m3/sec]
      REAL(r64)    :: MinAirFlowRate           =0.0  !Min Specified Volume Flow Rate of Fan [m3/sec]
      REAL(r64)    :: MaxAirMassFlowRate       =0.0  ! Max flow rate of fan in kg/sec
      REAL(r64)    :: MinAirMassFlowRate       =0.0  ! Min flow rate of fan in kg/sec
      REAL(r64)    :: InletAirTemp             =0.0
      REAL(r64)    :: OutletAirTemp            =0.0
      REAL(r64)    :: InletAirHumRat           =0.0
      REAL(r64)    :: OutletAirHumRat          =0.0
      REAL(r64)    :: InletAirEnthalpy         =0.0
      REAL(r64)    :: OutletAirEnthalpy        =0.0
      REAL(r64)    :: FanPower                 =0.0  !Power of the Fan being Simulated [kW]
      REAL(r64)    :: FanEnergy                =0.0  !Fan energy in [kJ]
      REAL(r64)    :: FanRuntimeFraction       =0.0  !Fraction of the timestep that the fan operates
      REAL(r64)    :: DeltaTemp                =0.0  !Temp Rise across the Fan [C]
      REAL(r64)    :: DeltaPress               =0.0  !Delta Pressure Across the Fan [N/m2]
      REAL(r64)    :: FanEff                   =0.0  !Fan total efficiency; motor and mechanical
      REAL(r64)    :: MotEff                   =0.0  !Fan motor efficiency
      REAL(r64)    :: MotInAirFrac             =0.0  !Fraction of motor heat entering air stream
      REAL(r64), Dimension(5):: FanCoeff            =0.0  !Fan Part Load Coefficients to match fan type
      ! Mass Flow Rate Control Variables
      REAL(r64)    :: MassFlowRateMaxAvail     =0.0
      REAL(r64)    :: MassFlowRateMinAvail     =0.0
      REAL(r64)    :: RhoAirStdInit            =0.0
      INTEGER      :: InletNodeNum             =0
      INTEGER      :: OutletNodeNum            =0
      INTEGER      :: NVPerfNum                =0
      INTEGER      :: FanPowerRatAtSpeedRatCurveIndex  =0
      INTEGER      :: FanEffRatioCurveIndex    =0
      CHARACTER(len=MaxNameLength) :: EndUseSubcategoryName=' '
      LOGICAL      :: OneTimePowerRatioCheck = .TRUE. ! one time flag used for error message
      LOGICAL      :: OneTimeEffRatioCheck = .TRUE.   ! one time flag used for error message
    END TYPE FanEquipConditions

    TYPE NightVentPerfData
      CHARACTER(len=MaxNameLength) :: FanName  =' ' ! Name of the fan that will use this data
      REAL(r64)    :: FanEff                   =0.0 !Fan total efficiency; motor and mechanical
      REAL(r64)    :: DeltaPress               =0.0 !Delta Pressure Across the Fan [N/m2]
      REAL(r64)    :: MaxAirFlowRate           =0.0 !Max Specified Volume Flow Rate of Fan [m3/s]
      REAL(r64)    :: MaxAirMassFlowRate       =0.0 ! Max flow rate of fan in kg/sec
      REAL(r64)    :: MotEff                   =0.0 !Fan motor efficiency
      REAL(r64)    :: MotInAirFrac             =0.0 !Fraction of motor heat entering air stream
    END TYPE NightVentPerfData

      !MODULE VARIABLE DECLARATIONS:
      INTEGER :: NumFans     =0 ! The Number of Fans found in the Input
      INTEGER :: NumNightVentPerf =0 ! number of FAN:NIGHT VENT PERFORMANCE objects found in the input
      TYPE (FanEquipConditions), ALLOCATABLE, DIMENSION(:) :: Fan
      TYPE (NightVentPerfData), ALLOCATABLE, DIMENSION(:)  :: NightVentPerf
      LOGICAL :: GetFanInputFlag = .True.  ! Flag set to make sure you get input once

    ! Subroutine Specifications for the Module
              ! Driver/Manager Routines
    Public  SimulateFanComponents

              ! Get Input routines for module
    PRIVATE GetFanInput

              ! Initialization routines for module
    PRIVATE InitFan
    PRIVATE SizeFan

              ! Algorithms for the module
    Private SimSimpleFan
    PRIVATE SimVariableVolumeFan
    PRIVATE SimZoneExhaustFan

              ! Update routine to check convergence and update nodes
    Private UpdateFan

              ! Reporting routines for module
    Private ReportFan

    CONTAINS

    ! MODULE SUBROUTINES:
    !*************************************************************************
    SUBROUTINE SimulateFanComponents(CompName,FirstHVACIteration)

              ! SUBROUTINE INFORMATION:
              !       AUTHOR         Richard Liesen
              !       DATE WRITTEN   February 1998
              !       MODIFIED       na
              !       RE-ENGINEERED  na

              ! PURPOSE OF THIS SUBROUTINE:
              ! This subroutine manages Fan component simulation.

              ! METHODOLOGY EMPLOYED:
              ! na

              ! REFERENCES:
              ! na

              ! USE STATEMENTS:
      USE InputProcessor, ONLY: FindItemInList

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

              ! SUBROUTINE ARGUMENT DEFINITIONS:
      CHARACTER(len=*), INTENT(IN) :: CompName
      LOGICAL,      INTENT (IN):: FirstHVACIteration

              ! SUBROUTINE PARAMETER DEFINITIONS:
              ! na

              ! INTERFACE BLOCK SPECIFICATIONS

              ! DERIVED TYPE DEFINITIONS
              ! na

              ! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
      INTEGER             :: FanNum     ! current fan number
      LOGICAL,SAVE        :: GetInputFlag = .True.  ! Flag set to make sure you get input once

              ! FLOW:

      ! Obtains and Allocates fan related parameters from input file
      IF (GetInputFlag) THEN  !First time subroutine has been entered
        CALL GetFanInput
        GetInputFlag=.false.
      End If

      ! Find the correct FanNumber with the AirLoop & CompNum from AirLoop Derived Type
      !FanNum = AirLoopEquip(AirLoopNum)%ComponentOfTypeNum(CompNum)
      ! Determine which Fan given the Fan Name
      FanNum =   FindItemInList(CompName,Fan%FanName,NumFans)
      IF (FanNum == 0) THEN
        CALL ShowFatalError('Fan not found='//TRIM(CompName))
      ENDIF

      ! With the correct FanNum Initialize
      CALL InitFan(FanNum,FirstHVACIteration)  ! Initialize all fan related parameters

      ! Calculate the Correct Fan Model with the current FanNum
      IF (Fan(FanNum)%FanType_Num == FanType_SimpleConstVolume) THEN
        Call SimSimpleFan(FanNum)
      Else IF (Fan(FanNum)%FanType_Num == FanType_SimpleVAV) THEN
        Call SimVariableVolumeFan(FanNum)
      Else If (Fan(FanNum)%FanType_Num == FanType_SimpleOnOff) THEN
        Call SimOnOffFan(FanNum)
      Else If (Fan(FanNum)%FanType_Num == FanType_ZoneExhaust) THEN
        Call SimZoneExhaustFan(FanNum)
      End If
      ! Update the current fan to the outlet nodes
      Call UpdateFan(FanNum)

      ! Report the current fan
      Call ReportFan(FanNum)

      RETURN

    END SUBROUTINE SimulateFanComponents

    ! Get Input Section of the Module
    !******************************************************************************
    SUBROUTINE GetFanInput

              ! SUBROUTINE INFORMATION:
              !       AUTHOR         Richard Liesen
              !       DATE WRITTEN   April 1998
              !       MODIFIED       Shirey, May 2001
              !       RE-ENGINEERED  na

              ! PURPOSE OF THIS SUBROUTINE:
              ! Obtains input data for fans and stores it in fan data structures

              ! METHODOLOGY EMPLOYED:
              ! Uses "Get" routines to read in data.

              ! REFERENCES:
              ! na

              ! USE STATEMENTS:
        USE InputProcessor
        USE NodeInputManager,      ONLY: GetOnlySingleNode
        USE CurveManager,          ONLY: GetCurveIndex
        USE BranchNodeConnections, ONLY: TestCompSet
    !    USE DataIPShortCuts

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

              ! SUBROUTINE ARGUMENT DEFINITIONS:
              ! na

              ! SUBROUTINE PARAMETER DEFINITIONS:
              ! na

              ! INTERFACE BLOCK SPECIFICATIONS
              ! na

              ! DERIVED TYPE DEFINITIONS
              ! na

              ! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
        INTEGER :: FanNum      ! The fan that you are currently loading input into
        INTEGER :: NumSimpFan  ! The number of Simple Const Vol Fans
        INTEGER :: NumVarVolFan ! The number of Simple Variable Vol Fans
        INTEGER :: NumOnOff     ! The number of Simple on-off Fans
        INTEGER :: NumZoneExhFan
        INTEGER :: SimpFanNum
        INTEGER :: OnOffFanNum
        INTEGER :: VarVolFanNum
        INTEGER :: ExhFanNum
        INTEGER :: NVPerfNum
        LOGICAL :: NVPerfFanFound
        INTEGER :: NumAlphas
        INTEGER :: NumNums
        INTEGER :: IOSTAT
        LOGICAL :: ErrorsFound = .false.   ! If errors detected in input
        LOGICAL :: IsNotOK               ! Flag to verify name
        LOGICAL :: IsBlank               ! Flag for blank name
        CHARACTER(len=*), PARAMETER    :: RoutineName='GetFanInput: ' ! include trailing blank space
        CHARACTER(len=MaxNameLength+40),ALLOCATABLE, DIMENSION(:) :: cAlphaFieldNames
        CHARACTER(len=MaxNameLength+40),ALLOCATABLE, DIMENSION(:) :: cNumericFieldNames
        LOGICAL, ALLOCATABLE, DIMENSION(:) :: lNumericFieldBlanks
        LOGICAL, ALLOCATABLE, DIMENSION(:) :: lAlphaFieldBlanks
        CHARACTER(len=MaxNameLength),ALLOCATABLE, DIMENSION(:) :: cAlphaArgs
        REAL(r64),ALLOCATABLE, DIMENSION(:) :: rNumericArgs
        CHARACTER(len=MaxNameLength) :: cCurrentModuleObject
        INTEGER :: NumParams
        INTEGER :: MaxAlphas
        INTEGER :: MaxNumbers

              ! Flow
        MaxAlphas=0
        MaxNumbers=0
        NumSimpFan   = GetNumObjectsFound('Fan:ConstantVolume')
        IF (NumSimpFan > 0) THEN
          CALL GetObjectDefMaxArgs('Fan:ConstantVolume',NumParams,NumAlphas,NumNums)
          MaxAlphas=MAX(MaxAlphas,NumAlphas)
          MaxNumbers=MAX(MaxNumbers,NumNums)
        ENDIF
        NumVarVolFan = GetNumObjectsFound('Fan:VariableVolume')
        IF (NumVarVolFan > 0) THEN
          CALL GetObjectDefMaxArgs('Fan:VariableVolume',NumParams,NumAlphas,NumNums)
          MaxAlphas=MAX(MaxAlphas,NumAlphas)
          MaxNumbers=MAX(MaxNumbers,NumNums)
        ENDIF
        NumOnOff = GetNumObjectsFound('Fan:OnOff')
        IF (NumOnOff > 0) THEN
          CALL GetObjectDefMaxArgs('Fan:OnOff',NumParams,NumAlphas,NumNums)
          MaxAlphas=MAX(MaxAlphas,NumAlphas)
          MaxNumbers=MAX(MaxNumbers,NumNums)
        ENDIF
        NumZoneExhFan = GetNumObjectsFound('Fan:ZoneExhaust')
        IF (NumZoneExhFan > 0) THEN
          CALL GetObjectDefMaxArgs('Fan:ZoneExhaust',NumParams,NumAlphas,NumNums)
          MaxAlphas=MAX(MaxAlphas,NumAlphas)
          MaxNumbers=MAX(MaxNumbers,NumNums)
        ENDIF
        NumNightVentPerf = GetNumObjectsFound('FanPerformance:NightVentilation')
        IF (NumNightVentPerf > 0) THEN
          CALL GetObjectDefMaxArgs('FanPerformance:NightVentilation',NumParams,NumAlphas,NumNums)
          MaxAlphas=MAX(MaxAlphas,NumAlphas)
          MaxNumbers=MAX(MaxNumbers,NumNums)
        ENDIF
        ALLOCATE(cAlphaArgs(MaxAlphas))
        cAlphaArgs=' '
        ALLOCATE(cAlphaFieldNames(MaxAlphas))
        cAlphaFieldNames=' '
        ALLOCATE(lAlphaFieldBlanks(MaxAlphas))
        lAlphaFieldBlanks=.false.
        ALLOCATE(cNumericFieldNames(MaxNumbers))
        cNumericFieldNames=' '
        ALLOCATE(lNumericFieldBlanks(MaxNumbers))
        lNumericFieldBlanks=.false.
        ALLOCATE(rNumericArgs(MaxNumbers))
        rNumericArgs=0.0

        NumFans = NumSimpFan + NumVarVolFan + NumZoneExhFan+NumOnOff
        IF (NumFans > 0) THEN
          ALLOCATE(Fan(NumFans))
        ENDIF

          DO SimpFanNum = 1,  NumSimpFan
            FanNum = SimpFanNum
            cCurrentModuleObject= 'Fan:ConstantVolume'
            CALL GetObjectItem(TRIM(cCurrentModuleObject),SimpFanNum,cAlphaArgs,NumAlphas, &
                               rNumericArgs,NumNums,IOSTAT, &
                               NumBlank=lNumericFieldBlanks,AlphaBlank=lAlphaFieldBlanks, &
                               AlphaFieldNames=cAlphaFieldNames,NumericFieldNames=cNumericFieldNames)
            IsNotOK=.false.
            IsBlank=.false.
            CALL VerifyName(cAlphaArgs(1),Fan%FanName,FanNum-1,IsNotOK,IsBlank,TRIM(cCurrentModuleObject)//' Name')
            IF (IsNotOK) THEN
              ErrorsFound=.true.
              IF (IsBlank) cAlphaArgs(1)='xxxxx'
            ENDIF
            Fan(FanNum)%FanName  = cAlphaArgs(1)
            Fan(FanNum)%FanType =  cCurrentModuleObject
            Fan(FanNum)%Schedule = cAlphaArgs(2)
            Fan(FanNum)%SchedPtr = GetScheduleIndex(cAlphaArgs(2))
            IF (Fan(FanNum)%SchedPtr == 0) THEN
              IF (lAlphaFieldBlanks(2)) THEN
                CALL ShowSevereError(RoutineName//TRIM(cCurrentModuleObject)//': '//TRIM(cAlphaFieldNames(2))//  &
                     ' is required, missing for '//TRIM(cAlphaFieldNames(1))//'='//TRIM(cAlphaArgs(1)))
              ELSE
                CALL ShowSevereError(RoutineName//TRIM(cCurrentModuleObject)//': invalid '//TRIM(cAlphaFieldNames(2))//  &
                   ' entered ='//TRIM(cAlphaArgs(2))// &
                   ' for '//TRIM(cAlphaFieldNames(1))//'='//TRIM(cAlphaArgs(1)))
              END IF
              ErrorsFound=.true.
            END IF
    !        Fan(FanNum)%Control = 'CONSTVOLUME'
            Fan(FanNum)%FanType_Num=FanType_SimpleConstVolume

            Fan(FanNum)%FanEff        = rNumericArgs(1)
            Fan(FanNum)%DeltaPress    = rNumericArgs(2)
            Fan(FanNum)%MaxAirFlowRate= rNumericArgs(3)
            IF (Fan(FanNum)%MaxAirFlowRate == 0.0) THEN
              CALL ShowWarningError(TRIM(cCurrentModuleObject)//'="'//TRIM(Fan(FanNum)%FanName)//  &
                 '" has specified 0.0 max air flow rate. It will not be used in the simulation.')
            ENDIF
            Fan(FanNum)%MotEff        = rNumericArgs(4)
            Fan(FanNum)%MotInAirFrac  = rNumericArgs(5)
            Fan(FanNum)%MinAirFlowRate= 0.0

            Fan(FanNum)%InletNodeNum  = &
                   GetOnlySingleNode(cAlphaArgs(3),ErrorsFound,TRIM(cCurrentModuleObject),cAlphaArgs(1),  &
                                NodeType_Air,NodeConnectionType_Inlet,1,ObjectIsNotParent)
            Fan(FanNum)%OutletNodeNum = &
                   GetOnlySingleNode(cAlphaArgs(4),ErrorsFound,TRIM(cCurrentModuleObject),cAlphaArgs(1),  &
                                NodeType_Air,NodeConnectionType_Outlet,1,ObjectIsNotParent)

            IF (NumAlphas > 4) THEN
              Fan(FanNum)%EndUseSubcategoryName = cAlphaArgs(5)
            ELSE
              Fan(FanNum)%EndUseSubcategoryName = 'General'
            END IF

            CALL TestCompSet(TRIM(cCurrentModuleObject),cAlphaArgs(1),cAlphaArgs(3),cAlphaArgs(4),'Air Nodes')

          END DO   ! end Number of Simple FAN Loop

          DO VarVolFanNum = 1,  NumVarVolFan
            FanNum = NumSimpFan + VarVolFanNum
            cCurrentModuleObject= 'Fan:VariableVolume'
            CALL GetObjectItem(TRIM(cCurrentModuleObject),VarVolFanNum,cAlphaArgs,NumAlphas, &
                               rNumericArgs,NumNums,IOSTAT, &
                               NumBlank=lNumericFieldBlanks,AlphaBlank=lAlphaFieldBlanks, &
                               AlphaFieldNames=cAlphaFieldNames,NumericFieldNames=cNumericFieldNames)
            IsNotOK=.false.
            IsBlank=.false.
            CALL VerifyName(cAlphaArgs(1),Fan%FanName,FanNum-1,IsNotOK,IsBlank,TRIM(cCurrentModuleObject)//' Name')
            IF (IsNotOK) THEN
              ErrorsFound=.true.
              IF (IsBlank) cAlphaArgs(1)='xxxxx'
            ENDIF
            Fan(FanNum)%FanName = cAlphaArgs(1)
            Fan(FanNum)%FanType = cCurrentModuleObject
            Fan(FanNum)%Schedule = cAlphaArgs(2)
            Fan(FanNum)%SchedPtr =GetScheduleIndex(cAlphaArgs(2))
            IF (Fan(FanNum)%SchedPtr == 0) THEN
              IF (lAlphaFieldBlanks(2)) THEN
                CALL ShowSevereError(RoutineName//TRIM(cCurrentModuleObject)//': '//TRIM(cAlphaFieldNames(2))//  &
                     ' is required, missing for '//TRIM(cAlphaFieldNames(1))//'='//TRIM(cAlphaArgs(1)))
              ELSE
                CALL ShowSevereError(RoutineName//TRIM(cCurrentModuleObject)//': invalid '//TRIM(cAlphaFieldNames(2))//  &
                   ' entered ='//TRIM(cAlphaArgs(2))// &
                   ' for '//TRIM(cAlphaFieldNames(1))//'='//TRIM(cAlphaArgs(1)))
              END IF
              ErrorsFound=.true.
            ENDIF
    !        Fan(FanNum)%Control = 'VARIABLEVOLUME'
            Fan(FanNum)%FanType_Num=FanType_SimpleVAV

            Fan(FanNum)%FanEff        = rNumericArgs(1)
            Fan(FanNum)%DeltaPress    = rNumericArgs(2)
            Fan(FanNum)%MaxAirFlowRate= rNumericArgs(3)
            IF (Fan(FanNum)%MaxAirFlowRate == 0.0) THEN
              CALL ShowWarningError(TRIM(cCurrentModuleObject)//'="'//TRIM(Fan(FanNum)%FanName)//  &
                 '" has specified 0.0 max air flow rate. It will not be used in the simulation.')
            ENDIF
            Fan(FanNum)%MinAirFlowRate= rNumericArgs(4)
            Fan(FanNum)%MotEff        = rNumericArgs(5)
            Fan(FanNum)%MotInAirFrac  = rNumericArgs(6)
            Fan(FanNum)%FanCoeff(1)   = rNumericArgs(7)
            Fan(FanNum)%FanCoeff(2)   = rNumericArgs(8)
            Fan(FanNum)%FanCoeff(3)   = rNumericArgs(9)
            Fan(FanNum)%FanCoeff(4)   = rNumericArgs(10)
            Fan(FanNum)%FanCoeff(5)   = rNumericArgs(11)
            IF (Fan(FanNum)%FanCoeff(1) == 0.0 .and. Fan(FanNum)%FanCoeff(2) == 0.0 .and.  &
                Fan(FanNum)%FanCoeff(3) == 0.0 .and. Fan(FanNum)%FanCoeff(4) == 0.0 .and.  &
                Fan(FanNum)%FanCoeff(5) == 0.0)  THEN
                CALL ShowWarningError('Fan Coefficients are all zero.  No Fan power will be reported.')
                CALL ShowContinueError('For '//TRIM(cCurrentModuleObject)//', Fan='//TRIM(cAlphaArgs(1)))
            ENDIF
            Fan(FanNum)%InletNodeNum  = &
                   GetOnlySingleNode(cAlphaArgs(3),ErrorsFound,TRIM(cCurrentModuleObject),cAlphaArgs(1),  &
                                NodeType_Air,NodeConnectionType_Inlet,1,ObjectIsNotParent)
            Fan(FanNum)%OutletNodeNum = &
                   GetOnlySingleNode(cAlphaArgs(4),ErrorsFound,TRIM(cCurrentModuleObject),cAlphaArgs(1),  &
                                NodeType_Air,NodeConnectionType_Outlet,1,ObjectIsNotParent)

            IF (NumAlphas > 4) THEN
              Fan(FanNum)%EndUseSubcategoryName = cAlphaArgs(5)
            ELSE
              Fan(FanNum)%EndUseSubcategoryName = 'General'
            END IF

            CALL TestCompSet(TRIM(cCurrentModuleObject),cAlphaArgs(1),cAlphaArgs(3),cAlphaArgs(4),'Air Nodes')

          END DO   ! end Number of Variable Volume FAN Loop

          DO ExhFanNum = 1,  NumZoneExhFan
            FanNum = NumSimpFan + NumVarVolFan + ExhFanNum
            cCurrentModuleObject= 'Fan:ZoneExhaust'
            CALL GetObjectItem(TRIM(cCurrentModuleObject),ExhFanNum,cAlphaArgs,NumAlphas, &
                               rNumericArgs,NumNums,IOSTAT, &
                               NumBlank=lNumericFieldBlanks,AlphaBlank=lAlphaFieldBlanks, &
                               AlphaFieldNames=cAlphaFieldNames,NumericFieldNames=cNumericFieldNames)
            IsNotOK=.false.
            IsBlank=.false.
            CALL VerifyName(cAlphaArgs(1),Fan%FanName,FanNum-1,IsNotOK,IsBlank,TRIM(cCurrentModuleObject)//' Name')
            IF (IsNotOK) THEN
              ErrorsFound=.true.
              IF (IsBlank) cAlphaArgs(1)='xxxxx'
            ENDIF
            Fan(FanNum)%FanName = cAlphaArgs(1)
            Fan(FanNum)%FanType = cCurrentModuleObject
            Fan(FanNum)%Schedule = cAlphaArgs(2)
            Fan(FanNum)%SchedPtr =GetScheduleIndex(cAlphaArgs(2))
            IF (Fan(FanNum)%SchedPtr == 0) THEN
              IF (lAlphaFieldBlanks(2)) THEN
                CALL ShowSevereError(RoutineName//TRIM(cCurrentModuleObject)//': '//TRIM(cAlphaFieldNames(2))//  &
                     ' is required, missing for '//TRIM(cAlphaFieldNames(1))//'='//TRIM(cAlphaArgs(1)))
              ELSE
                CALL ShowSevereError(RoutineName//TRIM(cCurrentModuleObject)//': invalid '//TRIM(cAlphaFieldNames(2))//  &
                   ' entered ='//TRIM(cAlphaArgs(2))// &
                   ' for '//TRIM(cAlphaFieldNames(1))//'='//TRIM(cAlphaArgs(1)))
              END IF
              ErrorsFound=.true.
            ELSE
              IF (HasFractionalScheduleValue(Fan(FanNum)%SchedPtr)) THEN
                CALL ShowWarningError(TRIM(cCurrentModuleObject)//'="'//TRIM(Fan(FanNum)%FanName)//  &
                  '" has fractional values in Schedule='//TRIM(cAlphaArgs(2))//'. Only 0.0 in the schedule value turns the fan off.')
              ENDIF
            ENDIF
    !        Fan(FanNum)%Control = 'CONSTVOLUME'
            Fan(FanNum)%FanType_Num=FanType_ZoneExhaust

            Fan(FanNum)%FanEff        = rNumericArgs(1)
            Fan(FanNum)%DeltaPress    = rNumericArgs(2)
            Fan(FanNum)%MaxAirFlowRate= rNumericArgs(3)
            Fan(FanNum)%MotEff        = 1.0
            Fan(FanNum)%MotInAirFrac  = 1.0
            Fan(FanNum)%MinAirFlowRate= 0.0
            Fan(FanNum)%RhoAirStdInit = StdRhoAir
            Fan(FanNum)%MaxAirMassFlowRate = Fan(FanNum)%MaxAirFlowRate * Fan(FanNum)%RhoAirStdInit

            IF (Fan(FanNum)%MaxAirFlowRate == 0.0) THEN
              CALL ShowWarningError(TRIM(cCurrentModuleObject)//'="'//TRIM(Fan(FanNum)%FanName)//  &
                  '" has specified 0.0 max air flow rate. It will not be used in the simulation.')
            ENDIF

            Fan(FanNum)%InletNodeNum  = &
                   GetOnlySingleNode(cAlphaArgs(3),ErrorsFound,TRIM(cCurrentModuleObject),cAlphaArgs(1),  &
                                NodeType_Air,NodeConnectionType_Inlet,1,ObjectIsNotParent)
            Fan(FanNum)%OutletNodeNum = &
                   GetOnlySingleNode(cAlphaArgs(4),ErrorsFound,TRIM(cCurrentModuleObject),cAlphaArgs(1),  &
                                NodeType_Air,NodeConnectionType_Outlet,1,ObjectIsNotParent)

            IF (NumAlphas > 4) THEN
              Fan(FanNum)%EndUseSubcategoryName = cAlphaArgs(5)
            ELSE
              Fan(FanNum)%EndUseSubcategoryName = 'General'
            END IF

            ! Component sets not setup yet for zone equipment
            ! CALL TestCompSet(TRIM(cCurrentModuleObject),cAlphaArgs(1),cAlphaArgs(3),cAlphaArgs(4),'Air Nodes')

          END DO   ! end of Zone Exhaust Fan loop

          DO OnOffFanNum = 1,  NumOnOff
            FanNum = NumSimpFan + NumVarVolFan + NumZoneExhFan + OnOffFanNum
            cCurrentModuleObject= 'Fan:OnOff'
            CALL GetObjectItem(TRIM(cCurrentModuleObject),OnOffFanNum,cAlphaArgs,NumAlphas, &
                               rNumericArgs,NumNums,IOSTAT, &
                               NumBlank=lNumericFieldBlanks,AlphaBlank=lAlphaFieldBlanks, &
                               AlphaFieldNames=cAlphaFieldNames,NumericFieldNames=cNumericFieldNames)
            IsNotOK=.false.
            IsBlank=.false.
            CALL VerifyName(cAlphaArgs(1),Fan%FanName,FanNum-1,IsNotOK,IsBlank,TRIM(cCurrentModuleObject)//' Name')
            IF (IsNotOK) THEN
              ErrorsFound=.true.
              IF (IsBlank) cAlphaArgs(1)='xxxxx'
            ENDIF
            Fan(FanNum)%FanName  = cAlphaArgs(1)
            Fan(FanNum)%FanType  = cCurrentModuleObject
            Fan(FanNum)%Schedule = cAlphaArgs(2)
            Fan(FanNum)%SchedPtr = GetScheduleIndex(cAlphaArgs(2))
            IF (Fan(FanNum)%SchedPtr == 0) THEN
              IF (lAlphaFieldBlanks(2)) THEN
                CALL ShowSevereError(RoutineName//TRIM(cCurrentModuleObject)//': '//TRIM(cAlphaFieldNames(2))//  &
                     ' is required, missing for '//TRIM(cAlphaFieldNames(1))//'='//TRIM(cAlphaArgs(1)))
              ELSE
                CALL ShowSevereError(RoutineName//TRIM(cCurrentModuleObject)//': invalid '//TRIM(cAlphaFieldNames(2))//  &
                   ' entered ='//TRIM(cAlphaArgs(2))// &
                   ' for '//TRIM(cAlphaFieldNames(1))//'='//TRIM(cAlphaArgs(1)))
              END IF
              ErrorsFound=.true.
            ENDIF
    !        Fan(FanNum)%Control = 'ONOFF'
            Fan(FanNum)%FanType_Num=FanType_SimpleOnOff

            Fan(FanNum)%FanEff        = rNumericArgs(1)
            Fan(FanNum)%DeltaPress    = rNumericArgs(2)
            Fan(FanNum)%MaxAirFlowRate= rNumericArgs(3)
            IF (Fan(FanNum)%MaxAirFlowRate == 0.0) THEN
              CALL ShowWarningError(TRIM(cCurrentModuleObject)//'="'//TRIM(Fan(FanNum)%FanName)//  &
                  '" has specified 0.0 max air flow rate. It will not be used in the simulation.')
            ENDIF

    !       the following two structure variables are set here, as well as in InitFan, for the Heat Pump:Water Heater object
    !       (Standard Rating procedure may be called before BeginEnvirFlag is set to TRUE, if so MaxAirMassFlowRate = 0)
            Fan(FanNum)%RhoAirStdInit = StdRhoAir
            Fan(FanNum)%MaxAirMassFlowRate = Fan(FanNum)%MaxAirFlowRate * Fan(FanNum)%RhoAirStdInit

            Fan(FanNum)%MotEff        = rNumericArgs(4)
            Fan(FanNum)%MotInAirFrac  = rNumericArgs(5)
            Fan(FanNum)%MinAirFlowRate= 0.0

            Fan(FanNum)%InletNodeNum  = &
                   GetOnlySingleNode(cAlphaArgs(3),ErrorsFound,TRIM(cCurrentModuleObject),cAlphaArgs(1), &
                                NodeType_Air,NodeConnectionType_Inlet,1,ObjectIsNotParent)
            Fan(FanNum)%OutletNodeNum = &
                   GetOnlySingleNode(cAlphaArgs(4),ErrorsFound,TRIM(cCurrentModuleObject),cAlphaArgs(1), &
                                NodeType_Air,NodeConnectionType_Outlet,1,ObjectIsNotParent)

            IF (NumAlphas > 4 .AND. .NOT. lAlphaFieldBlanks(5)) THEN
              Fan(FanNum)%FanPowerRatAtSpeedRatCurveIndex  = GetCurveIndex(cAlphaArgs(5))
            END IF

            IF (NumAlphas > 5 .AND. .NOT. lAlphaFieldBlanks(6)) THEN
              Fan(FanNum)%FanEffRatioCurveIndex  = GetCurveIndex(cAlphaArgs(6))
            END IF

            IF (NumAlphas > 6 .AND. .NOT. lAlphaFieldBlanks(7)) THEN
              Fan(FanNum)%EndUseSubcategoryName = cAlphaArgs(7)
            ELSE
              Fan(FanNum)%EndUseSubcategoryName = 'General'
            END IF

            CALL TestCompSet(TRIM(cCurrentModuleObject),cAlphaArgs(1),cAlphaArgs(3),cAlphaArgs(4),'Air Nodes')

          END DO   ! end Number of Simple  ON-OFF FAN Loop

          cCurrentModuleObject= 'FanPerformance:NightVentilation'
          NumNightVentPerf = GetNumObjectsFound(TRIM(cCurrentModuleObject))

          IF (NumNightVentPerf > 0) THEN
            ALLOCATE(NightVentPerf(NumNightVentPerf))
            NightVentPerf%FanName = ' '
            NightVentPerf%FanEff = 0.0
            NightVentPerf%DeltaPress = 0.0
            NightVentPerf%MaxAirFlowRate = 0.0
            NightVentPerf%MotEff = 0.0
            NightVentPerf%MotInAirFrac = 0.0
            NightVentPerf%MaxAirMassFlowRate = 0.0
          END IF
          ! input the night ventilation performance objects
          DO NVPerfNum=1,NumNightVentPerf
             CALL GetObjectItem(TRIM(cCurrentModuleObject),NVPerfNum,cAlphaArgs,NumAlphas, &
                               rNumericArgs,NumNums,IOSTAT, &
                               NumBlank=lNumericFieldBlanks,AlphaBlank=lAlphaFieldBlanks, &
                               AlphaFieldNames=cAlphaFieldNames,NumericFieldNames=cNumericFieldNames)
            IsNotOK=.false.
            IsBlank=.false.
            CALL VerifyName(cAlphaArgs(1),NightVentPerf%FanName,NVPerfNum-1,IsNotOK,IsBlank,TRIM(cCurrentModuleObject)//' Name')
            IF (IsNotOK) THEN
              ErrorsFound=.true.
              IF (IsBlank) cAlphaArgs(1)='xxxxx'
            ENDIF
            NightVentPerf(NVPerfNum)%FanName        = cAlphaArgs(1)
            NightVentPerf(NVPerfNum)%FanEff         = rNumericArgs(1)
            NightVentPerf(NVPerfNum)%DeltaPress     = rNumericArgs(2)
            NightVentPerf(NVPerfNum)%MaxAirFlowRate = rNumericArgs(3)
            NightVentPerf(NVPerfNum)%MotEff         = rNumericArgs(4)
            NightVentPerf(NVPerfNum)%MotInAirFrac   = rNumericArgs(5)
            ! find the corresponding fan
            NVPerfFanFound = .FALSE.
            DO FanNum=1,NumFans
              IF (NightVentPerf(NVPerfNum)%FanName == Fan(FanNum)%FanName) THEN
                NVPerfFanFound = .TRUE.
                Fan(FanNum)%NVPerfNum = NVPerfNum
                EXIT
              END IF
            END DO
            IF ( .NOT. NVPerfFanFound) THEN
              CALL ShowSevereError(TRIM(cCurrentModuleObject)//', fan name not found='//TRIM(cAlphaArgs(1)))
              ErrorsFound=.true.
            END IF

          END DO

          DEALLOCATE(cAlphaArgs)
          DEALLOCATE(cAlphaFieldNames)
          DEALLOCATE(lAlphaFieldBlanks)
          DEALLOCATE(cNumericFieldNames)
          DEALLOCATE(lNumericFieldBlanks)
          DEALLOCATE(rNumericArgs)

          IF (ErrorsFound) THEN
                CALL ShowFatalError(RoutineName//'Errors found in input.  Program terminates.')
          ENDIF

          Do FanNum=1,NumFans
                 ! Setup Report variables for the Fans
           CALL SetupOutputVariable('Fan Electric Power[W]', Fan(FanNum)%FanPower, 'System','Average',Fan(FanNum)%FanName)
           CALL SetupOutputVariable('Fan Delta Temp[C]', Fan(FanNum)%DeltaTemp, 'System','Average',Fan(FanNum)%FanName)
           CALL SetupOutputVariable('Fan Electric Consumption[J]', Fan(FanNum)%FanEnergy, 'System','Sum',Fan(FanNum)%FanName, &
                                     ResourceTypeKey='Electric',GroupKey='System', &
                                     EndUseKey='Fans',EndUseSubKey=Fan(FanNum)%EndUseSubcategoryName)
          END DO

          DO OnOffFanNum = 1,  NumOnOff
           FanNum = NumSimpFan + NumVarVolFan + NumZoneExhFan + OnOffFanNum
           CALL SetupOutputVariable('On/Off Fan Runtime Fraction', Fan(FanNum)%FanRuntimeFraction, 'System','Average', &
                                     Fan(FanNum)%FanName)
          END DO
      RETURN

    END SUBROUTINE GetFanInput

    ! End of Get Input subroutines for the HB Module
    !******************************************************************************

    ! Beginning Initialization Section of the Module
    !******************************************************************************

    SUBROUTINE InitFan(FanNum,FirstHVACIteration)

              ! SUBROUTINE INFORMATION:
              !       AUTHOR         Richard J. Liesen
              !       DATE WRITTEN   February 1998
              !       MODIFIED       na
              !       RE-ENGINEERED  na

              ! PURPOSE OF THIS SUBROUTINE:
              ! This subroutine is for initializations of the Fan Components.

              ! METHODOLOGY EMPLOYED:
              ! Uses the status flags to trigger initializations.

              ! REFERENCES:
              ! na

              ! USE STATEMENTS:
      USE DataSizing, ONLY: CurSysNum
      USE DataAirLoop, ONLY: AirLoopControlInfo

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

              ! SUBROUTINE ARGUMENT DEFINITIONS:
      LOGICAL, INTENT (IN):: FirstHVACIteration
      Integer, Intent(IN) :: FanNum

              ! SUBROUTINE PARAMETER DEFINITIONS:
              ! na

              ! INTERFACE BLOCK SPECIFICATIONS
              ! na

              ! DERIVED TYPE DEFINITIONS
              ! na

              ! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
      Integer             :: InletNode
      Integer             :: OutletNode
      Integer             :: InNode
      Integer             :: OutNode
      LOGICAL,SAVE        :: MyOneTimeFlag = .true.
      LOGICAL, ALLOCATABLE,Save, DIMENSION(:) :: MyEnvrnFlag
      LOGICAL, ALLOCATABLE,Save, DIMENSION(:) :: MySizeFlag

              ! FLOW:

      IF (MyOneTimeFlag) THEN

        ALLOCATE(MyEnvrnFlag(NumFans))
        ALLOCATE(MySizeFlag(NumFans))
        MyEnvrnFlag = .TRUE.
        MySizeFlag = .TRUE.

        MyOneTimeFlag = .false.

      END IF

      IF ( .NOT. SysSizingCalc .AND. MySizeFlag(FanNum)) THEN

        CALL SizeFan(FanNum)
        ! Set the loop cycling flag
        IF (Fan(FanNum)%Control == 'ONOFF') THEN
          IF (CurSysNum > 0) THEN
            AirLoopControlInfo(CurSysNum)%CyclingFan = .TRUE.
          END IF
        END IF

        MySizeFlag(FanNum) = .FALSE.
      END IF

    ! Do the Begin Environment initializations
      IF (BeginEnvrnFlag .and. MyEnvrnFlag(FanNum)) THEN

        !For all Fan inlet nodes convert the Volume flow to a mass flow
        InNode = Fan(FanNum)%InletNodeNum
        OutNode = Fan(FanNum)%OutletNodeNum
        Fan(FanNum)%RhoAirStdInit = PsyRhoAirFnPbTdbW(StdBaroPress,20.0,0.0)

        !Change the Volume Flow Rates to Mass Flow Rates

        Fan(FanNum)%MaxAirMassFlowRate = Fan(FanNum)%MaxAirFlowRate *  Fan(FanNum)%RhoAirStdInit
        Fan(FanNum)%MinAirMassFlowRate = Fan(FanNum)%MinAirFlowRate *  Fan(FanNum)%RhoAirStdInit

        !Init the Node Control variables
        Node(OutNode)%MassFlowRateMax      = Fan(FanNum)%MaxAirMassFlowRate
        Node(OutNode)%MassFlowRateMin      = Fan(FanNum)%MinAirMassFlowRate

        !Initialize all report variables to a known state at beginning of simulation
        Fan(FanNum)%FanPower = 0.0
        Fan(FanNum)%DeltaTemp = 0.0
        Fan(FanNum)%FanEnergy = 0.0

        MyEnvrnFlag(FanNum) = .FALSE.
      END IF

      IF (.not. BeginEnvrnFlag) THEN
        MyEnvrnFlag(FanNum) = .true.
      ENDIF

      ! Do the Begin Day initializations
        ! none

      ! Do the begin HVAC time step initializations
        ! none

      ! Do the following initializations (every time step): This should be the info from
      ! the previous components outlets or the node data in this section.

      ! Do a check and make sure that the max and min available(control) flow is
      ! between the physical max and min for the Fan while operating.

      InletNode = Fan(FanNum)%InletNodeNum
      OutletNode = Fan(FanNum)%OutletNodeNum

      Fan(FanNum)%MassFlowRateMaxAvail = MIN(Node(OutletNode)%MassFlowRateMax, &
                                                  Node(InletNode)%MassFlowRateMaxAvail)
      Fan(FanNum)%MassFlowRateMinAvail = MIN(MAX(Node(OutletNode)%MassFlowRateMin, &
                                                 Node(InletNode)%MassFlowRateMinAvail), &
                                                 Node(InletNode)%MassFlowRateMaxAvail)

      ! Load the node data in this section for the component simulation
      !
      !First need to make sure that the massflowrate is between the max and min avail.
      IF (Fan(FanNum)%FanType .NE. 'ZONE EXHAUST FAN') THEN
        Fan(FanNum)%InletAirMassFlowRate = Min(Node(InletNode)%MassFlowRate, &
                                               Fan(FanNum)%MassFlowRateMaxAvail)
        Fan(FanNum)%InletAirMassFlowRate = Max(Fan(FanNum)%InletAirMassFlowRate, &
                                               Fan(FanNum)%MassFlowRateMinAvail)
      ELSE  ! zone exhaust fans - always run at the max
        Fan(FanNum)%MassFlowRateMaxAvail = Fan(FanNum)%MaxAirMassFlowRate
        Fan(FanNum)%MassFlowRateMinAvail = 0.0
        Fan(FanNum)%InletAirMassFlowRate = Fan(FanNum)%MassFlowRateMaxAvail
      END IF

      !Then set the other conditions
      Fan(FanNum)%InletAirTemp         = Node(InletNode)%Temp
      Fan(FanNum)%InletAirHumRat       = Node(InletNode)%HumRat
      Fan(FanNum)%InletAirEnthalpy     = Node(InletNode)%Enthalpy

      RETURN

    END SUBROUTINE InitFan

    SUBROUTINE SizeFan(FanNum)

              ! SUBROUTINE INFORMATION:
              !       AUTHOR         Fred Buhl
              !       DATE WRITTEN   September 2001
              !       MODIFIED       na
              !       RE-ENGINEERED  na

              ! PURPOSE OF THIS SUBROUTINE:
              ! This subroutine is for sizing Fan Components for which flow rates have not been
              ! specified in the input.

              ! METHODOLOGY EMPLOYED:
              ! Obtains flow rates from the zone or system sizing arrays.

              ! REFERENCES:
              ! na

              ! USE STATEMENTS:
      USE DataSizing

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

              ! SUBROUTINE ARGUMENT DEFINITIONS:
      Integer, Intent(IN) :: FanNum

              ! SUBROUTINE PARAMETER DEFINITIONS:
              ! na

              ! INTERFACE BLOCK SPECIFICATIONS
              ! na

              ! DERIVED TYPE DEFINITIONS
              ! na

              ! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
      REAL :: FanMinAirFlowRate
      EXTERNAL ReportSizingOutput

      FanMinAirFlowRate = 0.0
      IF (Fan(FanNum)%MaxAirFlowRate == AutoSize) THEN

        IF (CurSysNum > 0) THEN

          CALL CheckSysSizing('FAN:'//TRIM(Fan(FanNum)%FanType)// ':' // TRIM(Fan(FanNum)%Control), &
                               Fan(FanNum)%FanName)

          SELECT CASE(CurDuctType)
            CASE(Main)
              Fan(FanNum)%MaxAirFlowRate = FinalSysSizing(CurSysNum)%DesMainVolFlow
              FanMinAirFlowRate = CalcSysSizing(CurSysNum)%SysAirMinFlowRat * CalcSysSizing(CurSysNum)%DesMainVolFlow
            CASE(Cooling)
              Fan(FanNum)%MaxAirFlowRate = FinalSysSizing(CurSysNum)%DesCoolVolFlow
              FanMinAirFlowRate = CalcSysSizing(CurSysNum)%SysAirMinFlowRat * CalcSysSizing(CurSysNum)%DesCoolVolFlow
            CASE(Heating)
              Fan(FanNum)%MaxAirFlowRate = FinalSysSizing(CurSysNum)%DesHeatVolFlow
              FanMinAirFlowRate = CalcSysSizing(CurSysNum)%SysAirMinFlowRat * CalcSysSizing(CurSysNum)%DesHeatVolFlow
            CASE(Other)
              Fan(FanNum)%MaxAirFlowRate = FinalSysSizing(CurSysNum)%DesMainVolFlow
              FanMinAirFlowRate = CalcSysSizing(CurSysNum)%SysAirMinFlowRat * CalcSysSizing(CurSysNum)%DesMainVolFlow
            CASE DEFAULT
              Fan(FanNum)%MaxAirFlowRate = FinalSysSizing(CurSysNum)%DesMainVolFlow
              FanMinAirFlowRate = CalcSysSizing(CurSysNum)%SysAirMinFlowRat * CalcSysSizing(CurSysNum)%DesMainVolFlow
          END SELECT

        ELSE IF (CurZoneEqNum > 0) THEN

          CALL CheckZoneSizing('FAN:' // TRIM(Fan(FanNum)%FanType) // ':' // TRIM(Fan(FanNum)%Control), &
                               Fan(FanNum)%FanName)
          IF (.NOT. ZoneHeatingOnlyFan) THEN
            Fan(FanNum)%MaxAirFlowRate = MAX(FinalZoneSizing(CurZoneEqNum)%DesCoolVolFlow, &
                                             FinalZoneSizing(CurZoneEqNum)%DesHeatVolFlow)
          ELSE
            Fan(FanNum)%MaxAirFlowRate = FinalZoneSizing(CurZoneEqNum)%DesHeatVolFlow
          END IF

        END IF

        IF (Fan(FanNum)%MaxAirFlowRate < SmallAirVolFlow) THEN
          Fan(FanNum)%MaxAirFlowRate = 0.0
        END IF

        CALL ReportSizingOutput('FAN:' // TRIM(Fan(FanNum)%FanType) // ':' // TRIM(Fan(FanNum)%Control), &
                                Fan(FanNum)%FanName, 'Max Flow Rate [m3/s]', Fan(FanNum)%MaxAirFlowRate)

        IF (Fan(FanNum)%Control == 'VARIABLEVOLUME') THEN
          CALL CheckSysSizing('FAN:' // TRIM(Fan(FanNum)%FanType) // ':' // TRIM(Fan(FanNum)%Control), &
                               Fan(FanNum)%FanName)
          Fan(FanNum)%MinAirFlowRate = FanMinAirFlowRate
          CALL ReportSizingOutput('FAN:' // TRIM(Fan(FanNum)%FanType) // ':' // TRIM(Fan(FanNum)%Control), &
                                  Fan(FanNum)%FanName, 'Min Flow Rate [m3/s]', Fan(FanNum)%MinAirFlowRate)
        END IF

      END IF

      RETURN

    END SUBROUTINE SizeFan

    ! End Initialization Section of the Module
    !******************************************************************************

    ! Begin Algorithm Section of the Module
    !******************************************************************************
    SUBROUTINE SimSimpleFan(FanNum)

              ! SUBROUTINE INFORMATION:
              !       AUTHOR         Unknown
              !       DATE WRITTEN   Unknown
              !       MODIFIED       na
              !       RE-ENGINEERED  na

              ! PURPOSE OF THIS SUBROUTINE:
              ! This subroutine simulates the simple constant volume fan.

              ! METHODOLOGY EMPLOYED:
              ! Converts design pressure rise and efficiency into fan power and temperature rise
              ! Constant fan pressure rise is assumed.

              ! REFERENCES:
              ! ASHRAE HVAC 2 Toolkit, page 2-3 (FANSIM)

              ! USE STATEMENTS:
              ! na

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

              ! SUBROUTINE ARGUMENT DEFINITIONS:
       Integer, Intent(IN) :: FanNum

              ! SUBROUTINE PARAMETER DEFINITIONS:
              ! na

              ! INTERFACE BLOCK SPECIFICATIONS
              ! na

              ! DERIVED TYPE DEFINITIONS
              ! na

              ! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
          Real RhoAir
          Real DeltaPress  ! [N/M^2]
          Real FanEff
          Real MassFlow    ! [kg/sec]
          Real Tin         ! [C]
          Real Win
          Real FanShaftPower ! power delivered to fan shaft
          Real PowerLossToAir ! fan and motor loss to air stream (watts)

       DeltaPress = Fan(FanNum)%DeltaPress
       FanEff     = Fan(FanNum)%FanEff

       ! For a Constant Volume Simple Fan the Max Flow Rate is the Flow Rate for the fan
       Tin        = Fan(FanNum)%InletAirTemp
       Win        = Fan(FanNum)%InletAirHumRat
       RhoAir     = Fan(FanNum)%RhoAirStdInit
       MassFlow   = MIN(Fan(FanNum)%InletAirMassFlowRate,Fan(FanNum)%MaxAirMassFlowRate)
       MassFlow   = MAX(MassFlow,Fan(FanNum)%MinAirMassFlowRate)
       !
       !Determine the Fan Schedule for the Time step
      If( ( GetCurrentScheduleValue(Fan(FanNum)%SchedPtr)>0.0 .and. Massflow>0.0 .or. TurnFansOn .and. Massflow>0.0) &
            .and. .NOT.TurnFansOff ) Then
       !Fan is operating
       Fan(FanNum)%FanPower = MassFlow*DeltaPress/(FanEff*RhoAir) ! total fan power
       FanShaftPower = Fan(FanNum)%MotEff * Fan(FanNum)%FanPower  ! power delivered to shaft
       PowerLossToAir = FanShaftPower + (Fan(FanNum)%FanPower - FanShaftPower) * Fan(FanNum)%MotInAirFrac
       Fan(FanNum)%OutletAirEnthalpy = Fan(FanNum)%InletAirEnthalpy + PowerLossToAir/MassFlow
       ! This fan does not change the moisture or Mass Flow across the component
       Fan(FanNum)%OutletAirHumRat       = Fan(FanNum)%InletAirHumRat
       Fan(FanNum)%OutletAirMassFlowRate = MassFlow
       Fan(FanNum)%OutletAirTemp = PsyTdbFnHW(Fan(FanNum)%OutletAirEnthalpy,Fan(FanNum)%OutletAirHumRat)

     Else
       !Fan is off and not operating no power consumed and mass flow rate.
       Fan(FanNum)%FanPower = 0.0
       FanShaftPower = 0.0
       PowerLossToAir = 0.0
       Fan(FanNum)%OutletAirMassFlowRate = 0.0
       Fan(FanNum)%OutletAirHumRat       = Fan(FanNum)%InletAirHumRat
       Fan(FanNum)%OutletAirEnthalpy     = Fan(FanNum)%InletAirEnthalpy
       Fan(FanNum)%OutletAirTemp = Fan(FanNum)%InletAirTemp
       ! Set the Control Flow variables to 0.0 flow when OFF.
       Fan(FanNum)%MassFlowRateMaxAvail = 0.0
       Fan(FanNum)%MassFlowRateMinAvail = 0.0

     End If

     RETURN
    END SUBROUTINE SimSimpleFan

    SUBROUTINE SimVariableVolumeFan(FanNum)

              ! SUBROUTINE INFORMATION:
              !       AUTHOR         Unknown
              !       DATE WRITTEN   Unknown
              !       MODIFIED       Phil Haves
              !       RE-ENGINEERED  na

              ! PURPOSE OF THIS SUBROUTINE:
              ! This subroutine simulates the simple variable volume fan.

              ! METHODOLOGY EMPLOYED:
              ! Converts design pressure rise and efficiency into fan power and temperature rise
              ! Constant fan pressure rise is assumed.
              ! Uses curves of fan power fraction vs. fan part load to determine fan power at
              ! off design conditions.

              ! REFERENCES:
              ! ASHRAE HVAC 2 Toolkit, page 2-3 (FANSIM)

              ! USE STATEMENTS:
              ! na

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

              ! SUBROUTINE ARGUMENT DEFINITIONS:
       Integer, Intent(IN) :: FanNum

              ! SUBROUTINE PARAMETER DEFINITIONS:
              ! na

              ! INTERFACE BLOCK SPECIFICATIONS
              ! na

              ! DERIVED TYPE DEFINITIONS
              ! na

              ! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
          Real RhoAir
          Real DeltaPress  ! [N/M^2 = Pa]
          Real FanEff      ! Total fan efficiency - combined efficiency of fan, drive train,
                           ! motor and variable speed controller (if any)
          Real MassFlow    ! [kg/sec]
          Real Tin         ! [C]
          Real Win
          Real PartLoadFrac
          REAL MaxFlowFrac   !Variable Volume Fan Max Flow Fraction [-]
          REAL MinFlowFrac   !Variable Volume Fan Min Flow Fraction [-]
          REAL FlowFrac      !Variable Volume Fan Flow Fraction [-]
          Real FanShaftPower ! power delivered to fan shaft
          Real PowerLossToAir ! fan and motor loss to air stream (watts)

    ! Simple Variable Volume Fan - default values from DOE-2
    ! Type of Fan          Coeff1       Coeff2       Coeff3        Coeff4      Coeff5
    ! INLET VANE DAMPERS   0.35071223   0.30850535   -0.54137364   0.87198823  0.000
    ! DISCHARGE DAMPERS    0.37073425   0.97250253   -0.34240761   0.000       0.000
    ! VARIABLE SPEED MOTOR 0.0015302446 0.0052080574  1.1086242   -0.11635563  0.000

       DeltaPress  = Fan(FanNum)%DeltaPress
       FanEff      = Fan(FanNum)%FanEff

       Tin         = Fan(FanNum)%InletAirTemp
       Win         = Fan(FanNum)%InletAirHumRat
       RhoAir      = Fan(FanNum)%RhoAirStdInit
       MassFlow    = MIN(Fan(FanNum)%InletAirMassFlowRate,Fan(FanNum)%MaxAirMassFlowRate)
       ! MassFlow    = MAX(MassFlow,Fan(FanNum)%MinAirMassFlowRate)

      ! Calculate and check limits on fraction of system flow
      MaxFlowFrac = 1.0
      ! MinFlowFrac is calculated from the ration of the volume flows and is non-dimensional
      MinFlowFrac = Fan(FanNum)%MinAirFlowRate/Fan(FanNum)%MaxAirFlowRate
      ! The actual flow fraction is calculated from MassFlow and the MaxVolumeFlow * AirDensity
      FlowFrac = MassFlow/(Fan(FanNum)%MaxAirMassFlowRate)

    ! Calculate the part Load Fraction             (PH 7/13/03)

      FlowFrac = MAX(MinFlowFrac,MIN(FlowFrac,1.0))  ! limit flow fraction to allowed range

      PartLoadFrac=Fan(FanNum)%FanCoeff(1) + Fan(FanNum)%FanCoeff(2)*FlowFrac +  &
                      Fan(FanNum)%FanCoeff(3)*FlowFrac**2 + Fan(FanNum)%FanCoeff(4)*FlowFrac**3 + &
                      Fan(FanNum)%FanCoeff(5)*FlowFrac**4

       !Determine the Fan Schedule for the Time step
      If( ( GetCurrentScheduleValue(Fan(FanNum)%SchedPtr)>0.0 .and. Massflow>0.0 .or. TurnFansOn .and. Massflow>0.0) &
            .and. .NOT.TurnFansOff ) Then
       !Fan is operating - calculate power loss and enthalpy rise
    !   Fan(FanNum)%FanPower = PartLoadFrac*FullMassFlow*DeltaPress/(FanEff*RhoAir) ! total fan power
       Fan(FanNum)%FanPower = PartLoadFrac*Fan(FanNum)%MaxAirMassFlowRate*DeltaPress/(FanEff*RhoAir) ! total fan power (PH 7/13/03)
       FanShaftPower = Fan(FanNum)%MotEff * Fan(FanNum)%FanPower  ! power delivered to shaft
       PowerLossToAir = FanShaftPower + (Fan(FanNum)%FanPower - FanShaftPower) * Fan(FanNum)%MotInAirFrac
       Fan(FanNum)%OutletAirEnthalpy = Fan(FanNum)%InletAirEnthalpy + PowerLossToAir/MassFlow
       ! This fan does not change the moisture or Mass Flow across the component
       Fan(FanNum)%OutletAirHumRat       = Fan(FanNum)%InletAirHumRat
       Fan(FanNum)%OutletAirMassFlowRate = MassFlow
       Fan(FanNum)%OutletAirTemp = PsyTdbFnHW(Fan(FanNum)%OutletAirEnthalpy,Fan(FanNum)%OutletAirHumRat)
      Else
       !Fan is off and not operating no power consumed and mass flow rate.
       Fan(FanNum)%FanPower = 0.0
       FanShaftPower = 0.0
       PowerLossToAir = 0.0
       Fan(FanNum)%OutletAirMassFlowRate = 0.0
       Fan(FanNum)%OutletAirHumRat       = Fan(FanNum)%InletAirHumRat
       Fan(FanNum)%OutletAirEnthalpy     = Fan(FanNum)%InletAirEnthalpy
       Fan(FanNum)%OutletAirTemp = Fan(FanNum)%InletAirTemp
       ! Set the Control Flow variables to 0.0 flow when OFF.
       Fan(FanNum)%MassFlowRateMaxAvail = 0.0
       Fan(FanNum)%MassFlowRateMinAvail = 0.0
      End If

      RETURN
    END SUBROUTINE SimVariableVolumeFan

    SUBROUTINE SimOnOffFan(FanNum)

              ! SUBROUTINE INFORMATION:
              !       AUTHOR         Unknown
              !       DATE WRITTEN   Unknown
              !       MODIFIED       Shirey, May 2001
              !       RE-ENGINEERED  na

              ! PURPOSE OF THIS SUBROUTINE:
              ! This subroutine simulates the simple on/off fan.

              ! METHODOLOGY EMPLOYED:
              ! Converts design pressure rise and efficiency into fan power and temperature rise
              ! Constant fan pressure rise is assumed.
              ! Uses curves of fan power fraction vs. fan part load to determine fan power at
              ! off design conditions.
              ! Same as simple (constant volume) fan, except added part-load curve input

              ! REFERENCES:
              ! ASHRAE HVAC 2 Toolkit, page 2-3 (FANSIM)

              ! USE STATEMENTS:
      USE CurveManager, ONLY: CurveValue

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

              ! SUBROUTINE ARGUMENT DEFINITIONS:
       Integer, Intent(IN) :: FanNum

              ! SUBROUTINE PARAMETER DEFINITIONS:
              ! na

              ! INTERFACE BLOCK SPECIFICATIONS
              ! na

              ! DERIVED TYPE DEFINITIONS
              ! na

              ! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
          Real RhoAir
          Real DeltaPress  ! [N/M^2]
          Real FanEff
          Real MassFlow    ! [kg/sec]
          Real Tin         ! [C]
          Real Win
          Real PartLoadRatio !Ratio of actual mass flow rate to max mass flow rate
          REAL FlowFrac      !Actual Fan Flow Fraction = actual mass flow rate / max air mass flow rate
          Real FanShaftPower ! power delivered to fan shaft
          Real PowerLossToAir ! fan and motor loss to air stream (watts)

       DeltaPress = Fan(FanNum)%DeltaPress
       FanEff     = Fan(FanNum)%FanEff

       Tin        = Fan(FanNum)%InletAirTemp
       Win        = Fan(FanNum)%InletAirHumRat
       RhoAir     = Fan(FanNum)%RhoAirStdInit
       MassFlow   = MIN(Fan(FanNum)%InletAirMassFlowRate,Fan(FanNum)%MaxAirMassFlowRate)
       MassFlow   = MAX(MassFlow,Fan(FanNum)%MinAirMassFlowRate)
       Fan(FanNum)%FanRuntimeFraction = 0.0

      ! The actual flow fraction is calculated from MassFlow and the MaxVolumeFlow * AirDensity
      FlowFrac = MassFlow/(Fan(FanNum)%MaxAirMassFlowRate)

      ! Calculate the part load ratio, can't be greater than 1
      PartLoadRatio= MIN(1.0,FlowFrac)
      ! Determine the Fan Schedule for the Time step
      IF( ( GetCurrentScheduleValue(Fan(FanNum)%SchedPtr)>0.0 .and. Massflow>0.0 .or. TurnFansOn .and. Massflow>0.0) &
            .and. .NOT.TurnFansOff ) THEN
       ! Fan is operating
       IF (OnOffFanPartLoadFraction <= 0.0) THEN
         CALL ShowWarningError('FAN:SIMPLE:ONOFF, OnOffFanPartLoadFraction <= 0.0, Reset to 1.0')
         OnOffFanPartLoadFraction = 1.0 ! avoid divide by zero or negative PLF
       END IF

       IF (OnOffFanPartLoadFraction < 0.7) THEN
            OnOffFanPartLoadFraction = 0.7 ! a warning message is already issued from the DX coils or gas heating coil
       END IF
       ! Keep fan runtime fraction between 0.0 and 1.0
       Fan(FanNum)%FanRuntimeFraction = MAX(0.0,MIN(1.0,PartLoadRatio/OnOffFanPartLoadFraction))
       ! Fan(FanNum)%FanPower = MassFlow*DeltaPress/(FanEff*RhoAir*OnOffFanPartLoadFraction)! total fan power
       Fan(FanNum)%FanPower = Fan(FanNum)%MaxAirMassFlowRate*Fan(FanNum)%FanRuntimeFraction*DeltaPress/(FanEff*RhoAir)!total fan power
       ! OnOffFanPartLoadFraction is passed via DataHVACGlobals from the cooling or heating coil that is
       !   requesting the fan to operate in cycling fan/cycling coil mode
       OnOffFanPartLoadFraction = 1.0 ! reset to 1 in case other on/off fan is called without a part load curve
       FanShaftPower = Fan(FanNum)%MotEff * Fan(FanNum)%FanPower  ! power delivered to shaft
       PowerLossToAir = FanShaftPower + (Fan(FanNum)%FanPower - FanShaftPower) * Fan(FanNum)%MotInAirFrac
       Fan(FanNum)%OutletAirEnthalpy = Fan(FanNum)%InletAirEnthalpy + PowerLossToAir/MassFlow
       ! This fan does not change the moisture or Mass Flow across the component
       Fan(FanNum)%OutletAirHumRat       = Fan(FanNum)%InletAirHumRat
       Fan(FanNum)%OutletAirMassFlowRate = MassFlow
    !   Fan(FanNum)%OutletAirTemp = Tin + PowerLossToAir/(MassFlow*PsyCpAirFnWTdb(Win,Tin))
       Fan(FanNum)%OutletAirTemp = PsyTdbFnHW(Fan(FanNum)%OutletAirEnthalpy,Fan(FanNum)%OutletAirHumRat)
      ELSE
       ! Fan is off and not operating no power consumed and mass flow rate.
       Fan(FanNum)%FanPower = 0.0
       FanShaftPower = 0.0
       PowerLossToAir = 0.0
       Fan(FanNum)%OutletAirMassFlowRate = 0.0
       Fan(FanNum)%OutletAirHumRat       = Fan(FanNum)%InletAirHumRat
       Fan(FanNum)%OutletAirEnthalpy     = Fan(FanNum)%InletAirEnthalpy
       Fan(FanNum)%OutletAirTemp = Fan(FanNum)%InletAirTemp
       ! Set the Control Flow variables to 0.0 flow when OFF.
       Fan(FanNum)%MassFlowRateMaxAvail = 0.0
       Fan(FanNum)%MassFlowRateMinAvail = 0.0
      END IF

      RETURN
    END SUBROUTINE SimOnOffFan

    SUBROUTINE SimZoneExhaustFan(FanNum)

              ! SUBROUTINE INFORMATION:
              !       AUTHOR         Fred Buhl
              !       DATE WRITTEN   Jan 2000
              !       MODIFIED       na
              !       RE-ENGINEERED  na

              ! PURPOSE OF THIS SUBROUTINE:
              ! This subroutine simulates the Zone Exhaust Fan

              ! METHODOLOGY EMPLOYED:
              ! Converts design pressure rise and efficiency into fan power and temperature rise
              ! Constant fan pressure rise is assumed.

              ! REFERENCES:
              ! ASHRAE HVAC 2 Toolkit, page 2-3 (FANSIM)

              ! USE STATEMENTS:
              ! na

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

              ! SUBROUTINE ARGUMENT DEFINITIONS:
       Integer, Intent(IN) :: FanNum

              ! SUBROUTINE PARAMETER DEFINITIONS:
              ! na

              ! INTERFACE BLOCK SPECIFICATIONS
              ! na

              ! DERIVED TYPE DEFINITIONS
              ! na

              ! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
          Real RhoAir
          Real DeltaPress  ! [N/M^2]
          Real FanEff
          Real MassFlow    ! [kg/sec]
          Real Tin         ! [C]
          Real Win
          Real PowerLossToAir ! fan and motor loss to air stream (watts)

       DeltaPress = Fan(FanNum)%DeltaPress
       FanEff     = Fan(FanNum)%FanEff

       ! For a Constant Volume Simple Fan the Max Flow Rate is the Flow Rate for the fan
       Tin        = Fan(FanNum)%InletAirTemp
       Win        = Fan(FanNum)%InletAirHumRat
       RhoAir     = Fan(FanNum)%RhoAirStdInit
       MassFlow   = Fan(FanNum)%InletAirMassFlowRate
       !
       !Determine the Fan Schedule for the Time step
      If( ( GetCurrentScheduleValue(Fan(FanNum)%SchedPtr)>0.0 .or. TurnFansOn ) &
            .and. .NOT.TurnFansOff ) Then
       !Fan is operating
       Fan(FanNum)%FanPower = MassFlow*DeltaPress/(FanEff*RhoAir) ! total fan power
       PowerLossToAir = Fan(FanNum)%FanPower
       Fan(FanNum)%OutletAirEnthalpy = Fan(FanNum)%InletAirEnthalpy + PowerLossToAir/MassFlow
       ! This fan does not change the moisture or Mass Flow across the component
       Fan(FanNum)%OutletAirHumRat       = Fan(FanNum)%InletAirHumRat
       Fan(FanNum)%OutletAirMassFlowRate = MassFlow
       Fan(FanNum)%OutletAirTemp = PsyTdbFnHW(Fan(FanNum)%OutletAirEnthalpy,Fan(FanNum)%OutletAirHumRat)

     Else
       !Fan is off and not operating no power consumed and mass flow rate.
       Fan(FanNum)%FanPower = 0.0
       PowerLossToAir = 0.0
       Fan(FanNum)%OutletAirMassFlowRate = 0.0
       Fan(FanNum)%OutletAirHumRat       = Fan(FanNum)%InletAirHumRat
       Fan(FanNum)%OutletAirEnthalpy     = Fan(FanNum)%InletAirEnthalpy
       Fan(FanNum)%OutletAirTemp = Fan(FanNum)%InletAirTemp
       ! Set the Control Flow variables to 0.0 flow when OFF.
       Fan(FanNum)%MassFlowRateMaxAvail = 0.0
       Fan(FanNum)%MassFlowRateMinAvail = 0.0
       Fan(FanNum)%InletAirMassFlowRate = 0.0

     End If

     RETURN
    END SUBROUTINE SimZoneExhaustFan

    ! End Algorithm Section of the Module
    ! *****************************************************************************

    ! Beginning of Update subroutines for the Fan Module
    ! *****************************************************************************

    SUBROUTINE UpdateFan(FanNum)

              ! SUBROUTINE INFORMATION:
              !       AUTHOR         Richard Liesen
              !       DATE WRITTEN   April 1998
              !       MODIFIED       na
              !       RE-ENGINEERED  na

              ! PURPOSE OF THIS SUBROUTINE:
              ! This subroutine updates the fan outlet nodes.

              ! METHODOLOGY EMPLOYED:
              ! Data is moved from the fan data structure to the fan outlet nodes.

              ! REFERENCES:
              ! na

              ! USE STATEMENTS:
              ! na

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

              ! SUBROUTINE ARGUMENT DEFINITIONS:
       Integer, Intent(IN) :: FanNum

              ! SUBROUTINE PARAMETER DEFINITIONS:
              ! na

              ! INTERFACE BLOCK SPECIFICATIONS
              ! na

              ! DERIVED TYPE DEFINITIONS
              ! na

              ! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
      Integer             :: OutletNode
      Integer             :: InletNode

       OutletNode = Fan(FanNum)%OutletNodeNum
       InletNode = Fan(FanNum)%InletNodeNum

       ! Set the outlet air nodes of the fan
       Node(OutletNode)%MassFlowRate  = Fan(FanNum)%OutletAirMassFlowRate
       Node(OutletNode)%Temp          = Fan(FanNum)%OutletAirTemp
       Node(OutletNode)%HumRat        = Fan(FanNum)%OutletAirHumRat
       Node(OutletNode)%Enthalpy      = Fan(FanNum)%OutletAirEnthalpy
       ! Set the outlet nodes for properties that just pass through & not used
       Node(OutletNode)%Quality         = Node(InletNode)%Quality
       Node(OutletNode)%Press           = Node(InletNode)%Press

       ! Set the Node Flow Control Variables from the Fan Control Variables
       Node(OutletNode)%MassFlowRateMaxAvail = Fan(FanNum)%MassFlowRateMaxAvail
       Node(OutletNode)%MassFlowRateMinAvail = Fan(FanNum)%MassFlowRateMinAvail

       IF (Fan(FanNum)%FanType .EQ. 'ZONE EXHAUST FAN') THEN
         Node(InletNode)%MassFlowRate = Fan(FanNum)%InletAirMassFlowRate
       END IF

      RETURN
    END Subroutine UpdateFan

    !        End of Update subroutines for the Fan Module
    ! *****************************************************************************

    ! Beginning of Reporting subroutines for the Fan Module
    ! *****************************************************************************

    SUBROUTINE ReportFan(FanNum)

              ! SUBROUTINE INFORMATION:
              !       AUTHOR         Richard Liesen
              !       DATE WRITTEN   April 1998
              !       MODIFIED       na
              !       RE-ENGINEERED  na

              ! PURPOSE OF THIS SUBROUTINE:
              ! This subroutine updates the report variables for the fans.

              ! METHODOLOGY EMPLOYED:
              ! na

              ! REFERENCES:
              ! na

              ! USE STATEMENTS:
      Use DataHVACGlobals, ONLY: TimeStepSys, FanElecPower

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

              ! SUBROUTINE ARGUMENT DEFINITIONS:
       Integer, Intent(IN) :: FanNum

              ! SUBROUTINE PARAMETER DEFINITIONS:
              ! na

              ! INTERFACE BLOCK SPECIFICATIONS
              ! na

              ! DERIVED TYPE DEFINITIONS
              ! na

              ! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
              ! na

        Fan(FanNum)%FanEnergy=Fan(FanNum)%FanPower*TimeStepSys*3600
        Fan(FanNum)%DeltaTemp=Fan(FanNum)%OutletAirTemp - Fan(FanNum)%InletAirTemp
        FanElecPower = Fan(FanNum)%FanPower

      RETURN
    END Subroutine ReportFan

    !        End of Reporting subroutines for the Fan Module
    ! *****************************************************************************
    ! Beginning of Utility subroutines for the Fan Module
    ! *****************************************************************************
    FUNCTION GetFanDesignVolumeFlowRate(FanType,FanName,ErrorsFound) RESULT(DesignVolumeFlowRate)

              ! FUNCTION INFORMATION:
              !       AUTHOR         Linda Lawrie
              !       DATE WRITTEN   February 2006
              !       MODIFIED       na
              !       RE-ENGINEERED  na

              ! PURPOSE OF THIS FUNCTION:
              ! This function looks up the design volume flow rate for the given fan and returns it.  If
              ! incorrect fan type or name is given, errorsfound is returned as true and value is returned
              ! as negative.

              ! METHODOLOGY EMPLOYED:
              ! na

              ! REFERENCES:
              ! na

              ! USE STATEMENTS:
      USE InputProcessor,  ONLY: FindItemInList

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

              ! FUNCTION ARGUMENT DEFINITIONS:
      CHARACTER(len=*), INTENT(IN) :: FanType      ! must match fan types in this module
      CHARACTER(len=*), INTENT(IN) :: FanName      ! must match fan names for the fan type
      LOGICAL, INTENT(INOUT)       :: ErrorsFound  ! set to true if problem
      REAL                         :: DesignVolumeFlowRate ! returned flow rate of matched fan

              ! FUNCTION PARAMETER DEFINITIONS:
              ! na

              ! INTERFACE BLOCK SPECIFICATIONS:
              ! na

              ! DERIVED TYPE DEFINITIONS:
              ! na

              ! FUNCTION LOCAL VARIABLE DECLARATIONS:
      INTEGER :: WhichFan

      ! Obtains and Allocates fan related parameters from input file
      IF (GetFanInputFlag) THEN  !First time subroutine has been entered
        CALL GetFanInput
        GetFanInputFlag=.false.
      End If

      WhichFan=FindItemInList(FanName,Fan%FanName,NumFans)
      IF (WhichFan /= 0) THEN
        DesignVolumeFlowRate=Fan(WhichFan)%MaxAirFlowRate
      ENDIF

      IF (WhichFan == 0) THEN
        CALL ShowSevereError('Could not find FanType="'//TRIM(FanType)//'" with Name="'//TRIM(FanName)//'"')
        ErrorsFound=.true.
        DesignVolumeFlowRate=-1000.
      ENDIF

      RETURN

    END FUNCTION GetFanDesignVolumeFlowRate

    FUNCTION GetFanInletNode(FanType,FanName,ErrorsFound) RESULT(NodeNumber)

              ! FUNCTION INFORMATION:
              !       AUTHOR         Linda Lawrie
              !       DATE WRITTEN   February 2006
              !       MODIFIED       na
              !       RE-ENGINEERED  na

              ! PURPOSE OF THIS FUNCTION:
              ! This function looks up the given fan and returns the inlet node.  If
              ! incorrect fan type or name is given, errorsfound is returned as true and value is returned
              ! as zero.

              ! METHODOLOGY EMPLOYED:
              ! na

              ! REFERENCES:
              ! na

              ! USE STATEMENTS:
      USE InputProcessor,  ONLY: FindItemInList

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

              ! FUNCTION ARGUMENT DEFINITIONS:
      CHARACTER(len=*), INTENT(IN) :: FanType      ! must match fan types in this module
      CHARACTER(len=*), INTENT(IN) :: FanName      ! must match fan names for the fan type
      LOGICAL, INTENT(INOUT)       :: ErrorsFound  ! set to true if problem
      INTEGER                      :: NodeNumber   ! returned outlet node of matched fan

              ! FUNCTION PARAMETER DEFINITIONS:
              ! na

              ! INTERFACE BLOCK SPECIFICATIONS:
              ! na

              ! DERIVED TYPE DEFINITIONS:
              ! na

              ! FUNCTION LOCAL VARIABLE DECLARATIONS:
      INTEGER :: WhichFan

      ! Obtains and Allocates fan related parameters from input file
      IF (GetFanInputFlag) THEN  !First time subroutine has been entered
        CALL GetFanInput
        GetFanInputFlag=.false.
      End If

      WhichFan=FindItemInList(FanName,Fan%FanName,NumFans)
      IF (WhichFan /= 0) THEN
        NodeNumber=Fan(WhichFan)%InletNodeNum
      ENDIF

      IF (WhichFan == 0) THEN
        CALL ShowSevereError('Could not find FanType="'//TRIM(FanType)//'" with Name="'//TRIM(FanName)//'"')
        ErrorsFound=.true.
        NodeNumber=0
      ENDIF

      RETURN

    END FUNCTION GetFanInletNode

    FUNCTION GetFanOutletNode(FanType,FanName,ErrorsFound) RESULT(NodeNumber)

              ! FUNCTION INFORMATION:
              !       AUTHOR         Linda Lawrie
              !       DATE WRITTEN   February 2006
              !       MODIFIED       na
              !       RE-ENGINEERED  na

              ! PURPOSE OF THIS FUNCTION:
              ! This function looks up the given fan and returns the outlet node.  If
              ! incorrect fan type or name is given, errorsfound is returned as true and value is returned
              ! as zero.

              ! METHODOLOGY EMPLOYED:
              ! na

              ! REFERENCES:
              ! na

              ! USE STATEMENTS:
      USE InputProcessor,  ONLY: FindItemInList

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

              ! FUNCTION ARGUMENT DEFINITIONS:
      CHARACTER(len=*), INTENT(IN) :: FanType      ! must match fan types in this module
      CHARACTER(len=*), INTENT(IN) :: FanName      ! must match fan names for the fan type
      LOGICAL, INTENT(INOUT)       :: ErrorsFound  ! set to true if problem
      INTEGER                      :: NodeNumber   ! returned outlet node of matched fan

              ! FUNCTION PARAMETER DEFINITIONS:
              ! na

              ! INTERFACE BLOCK SPECIFICATIONS:
              ! na

              ! DERIVED TYPE DEFINITIONS:
              ! na

              ! FUNCTION LOCAL VARIABLE DECLARATIONS:
      INTEGER :: WhichFan

      ! Obtains and Allocates fan related parameters from input file
      IF (GetFanInputFlag) THEN  !First time subroutine has been entered
        CALL GetFanInput
        GetFanInputFlag=.false.
      End If

      WhichFan=FindItemInList(FanName,Fan%FanName,NumFans)
      IF (WhichFan /= 0) THEN
        NodeNumber=Fan(WhichFan)%OutletNodeNum
      ENDIF

      IF (WhichFan == 0) THEN
        CALL ShowSevereError('Could not find FanType="'//TRIM(FanType)//'" with Name="'//TRIM(FanName)//'"')
        ErrorsFound=.true.
        NodeNumber=0
      ENDIF

      RETURN

    END FUNCTION GetFanOutletNode

    ! End of Utility subroutines for the Fan Module
    ! *****************************************************************************

    !     NOTICE
    !
    !     Copyright © 1996-xxxx 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 Fans