Guide for Module Developers — EnergyPlus 8.7

<< 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