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, PsyCpAirFnW
! 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*PsyCpAirFnW(Win))
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
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, PsyCpAirFnW
! 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*PsyCpAirFnW(Win))
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
Documentation content copyright © 1996-2021 The Board of Trustees of the University of Illinois and the Regents of the University of California through the Ernest Orlando Lawrence Berkeley National Laboratory. All rights reserved. EnergyPlus is a trademark of the US Department of Energy.
This documentation is made available under the EnergyPlus Open Source License v1.0.