SUBROUTINE InitOAController(OAControllerNum,FirstHVACIteration,AirLoopNum)
! SUBROUTINE INFORMATION:
! AUTHOR Fred Buhl
! DATE WRITTEN Oct 1998
! MODIFIED Shirey/Raustad FSEC, June/Aug 2003, Feb 2004
! Tianzhen Hong, Feb 2009 for DCV
! Tianzhen Hong, Aug 2013 for economizer faults
! RE-ENGINEERED na
! PURPOSE OF THIS SUBROUTINE
! Initialize the OAController data structure with input node data
! METHODOLOGY EMPLOYED:
! REFERENCES:
! USE STATEMENTS:
USE DataLoopNode
USE DataHeatBalance, ONLY: ZONEINTGAIN, Zone, ZoneList, TotPeople, People
USE Psychrometrics, ONLY:PsyRhoAirFnPbTdbW
USE InputProcessor, ONLY: FindItemInList, FindItem, SameString
USE General, ONLY: RoundSigDigits
USE OutputReportPredefined
USE EMSManager, ONLY: iTemperatureSetpoint, CheckIfNodeSetpointManagedByEMS
USE DataAirSystems, ONLY: PrimaryAirSystem
USE DataInterfaces, ONLY: SetupEMSInternalVariable
IMPLICIT NONE
! SUBROUTINE ARGUMENT DEFINITIONS
INTEGER, INTENT(IN) :: OAControllerNum
LOGICAL, INTENT(IN) :: FirstHVACIteration
INTEGER, INTENT(IN) :: AirLoopNum
! SUBROUTINE PARAMETER DEFINITIONS:
! INTERFACE BLOCK SPECIFICATIONS
! na
! DERIVED TYPE DEFINITIONS
! na
! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
LOGICAL,SAVE :: MyOneTimeFlag = .TRUE. ! One-time initialization flag
LOGICAL,SAVE :: MySetPointCheckFlag = .TRUE. ! One-time initialization flag
LOGICAL,SAVE :: SetUpAirLoopHVACVariables = .TRUE. ! One-time initialization flag
LOGICAL, ALLOCATABLE,SAVE, DIMENSION(:) :: MyEnvrnFlag ! One-time initialization flag
LOGICAL, ALLOCATABLE,SAVE, DIMENSION(:) :: MySizeFlag ! One-time initialization flag
LOGICAL, ALLOCATABLE,SAVE, DIMENSION(:) :: MechVentCheckFlag ! One-time initialization flag
LOGICAL :: FoundZone ! Logical determines if ZONE object is accounted for in VENTILATION:MECHANICAL object
LOGICAL :: FoundAreaZone ! Logical determines if ZONE object is accounted for in VENTILATION:MECHANICAL object
LOGICAL :: FoundPeopleZone ! Logical determines if ZONE object is accounted for in VENTILATION:MECHANICAL object
LOGICAL :: OASysFound ! Logical determines if OA system found
LOGICAL :: AirLoopFound ! Logical determines if primary air loop found
LOGICAL :: ErrorsFound ! Errors found getting input
REAL(r64) :: RhoAirStdInit ! Standard air density
REAL(r64) :: TotalPeopleOAFlow ! Total outside air required for PEOPLE objects served by this OA controller
INTEGER :: MixedAirNode ! Controller:OutdoorAir mixed air node
INTEGER :: OAControllerIndex ! Index to Controller:OutdoorAir
INTEGER :: ZoneNum ! DO loop index (zone number)
INTEGER :: ZoneIndex ! Index to zone in mechanical ventilation zone list
INTEGER :: AirLoopZoneInfoZoneNum ! Index to AirLoopZoneInfo structure
INTEGER :: NumZone ! Zone number in AirLoopZoneInfo structure
INTEGER :: PeopleNum ! Index to PEOPLE objects
INTEGER :: NumMechVentZone ! Index to number of zones in VentilationMechanical structure
INTEGER :: TempMechVentArrayCounter ! Temporary array counter
INTEGER :: thisOASys ! Temporary array counter
INTEGER :: thisNumForMixer ! Temporary array counter
INTEGER :: thisMixerIndex ! Temporary array counter
INTEGER :: OASysNum ! Temporary array counter
INTEGER :: thisOAController ! Temporary array counter
INTEGER :: found ! Temporary index to equipment
INTEGER :: OANode ! OA node index
INTEGER :: VentMechObjectNum ! Temporary variable
INTEGER :: OAControllerLoop ! Index to OA controller in an OA system
INTEGER :: OAControllerLoop2 ! Index to OA controller in an OA system
INTEGER :: thisAirLoop ! Temporary array counter
INTEGER :: BranchNum ! Temporary array counter
INTEGER :: CompNum ! Temporary array counter
CHARACTER(len=MaxNameLength) :: equipName ! Temporary equipment name
CHARACTER(len=MaxNameLength) :: airloopName ! Temporary equipment name
REAL(r64), DIMENSION(:),ALLOCATABLE:: TempZoneOAAreaRate ! Temporary array for mechanical ventilation rate (m3/s/m2) per zone
REAL(r64), DIMENSION(:),ALLOCATABLE:: TempZoneOAPeopleRate ! Temporary array for mechanical ventilation rate (m3/s/person) per zone
REAL(r64), DIMENSION(:),ALLOCATABLE:: TempZoneOAFlow ! Temporary array for mechanical ventilation rate (m3/s/flow) per zone
REAL(r64), DIMENSION(:),ALLOCATABLE:: TempZoneOAACH ! Temporary array for mechanical ventilation rate (m3/s/volume) per zone
INTEGER, DIMENSION(:),ALLOCATABLE:: TempZoneOADSOAIndex ! Temporary array for mechanical ventilation rate (m3/s/volume) per zone
CHARACTER(len=MaxNameLength), DIMENSION(:),ALLOCATABLE:: TempZoneOADSOAName ! Temporary array for mechanical ventilation rate (m3/s/volume) per zone
INTEGER, DIMENSION(:),ALLOCATABLE:: TempZone ! Temporary array for zones requiring mechanical ventilation
REAL(r64), DIMENSION(:),ALLOCATABLE:: TempZoneADEffCooling ! Temporary array for zone air distribution effectiveness
! in cooling mode for each zone
REAL(r64), DIMENSION(:),ALLOCATABLE:: TempZoneADEffHeating ! Temporary array for zone air distribution effectiveness
! in heating mode for each zone
INTEGER, DIMENSION(:),ALLOCATABLE:: TempZoneADEffSchPtr ! Temporary array for pointer to the zone air distribution
! effectiveness schedule for each zone
CHARACTER(len=MaxNameLength),DIMENSION(:),ALLOCATABLE:: TempZoneADEffSchName ! Temporary array for zone air distribution
! effectiveness schedule name for each zone
CHARACTER(len=MaxNameLength) :: zoneName
INTEGER :: jZone
REAL(r64) :: rSchVal
REAL(r64) :: rOffset
INTEGER :: i
INTEGER :: iEco
ErrorsFound = .FALSE.
OANode = 0
IF (MyOneTimeFlag) THEN
ALLOCATE(MyEnvrnFlag(NumOAControllers))
ALLOCATE(MySizeFlag(NumOAControllers))
ALLOCATE(MechVentCheckFlag(NumOAControllers))
MyEnvrnFlag = .TRUE.
MySizeFlag = .TRUE.
MechVentCheckFlag = .TRUE.
! Determine Inlet node index for OAController, not a user input for controller, but is obtained from OutsideAirSys and OAMixer
! This input setup needs to happen for all controllers, not just the one first passed into this init routine
Do thisOAController=1, NumOAControllers
SELECT CASE (OAController(thisOAController)%ControllerType_Num)
CASE (ControllerOutsideAir)
thisOASys = 0
DO OASysNum=1, NumOASystems
! find which OAsys has this controller
found = FindItemInList(OAController(thisOAController)%Name, OutsideAirSys(OASysNum)%ControllerName, &
size(OutsideAirSys(OASysNum)%ControllerName))
IF (found /= 0) then
thisOASys = OASysNum
EXIT ! we found it
ENDIF
ENDDO
IF (thisOASys == 0) then
CALL ShowSevereError('InitOAController: Did not find OAController="'//TRIM(OAController(thisOAController)%Name)//'".')
CALL ShowContinueError('in list of valid OA Controllers.')
Errorsfound = .true.
CYCLE
ENDIF
thisNumForMixer = FindItem(CurrentModuleObjects(CMO_OAMixer), OutsideAirSys(thisOASys)%ComponentType, &
size(OutsideAirSys(thisOASys)%ComponentType) )
If (thisNumForMixer /= 0) then
equipName = OutsideAirSys(thisOASys)%ComponentName(thisNumForMixer)
thisMixerIndex = FindItemInList(equipName,OAMixer%Name, NumOAMixers )
If (thisMixerIndex /= 0) then
OAController(thisOAController)%InletNode = OAMixer(thisMixerIndex)%InletNode
ELSE
CALL ShowSevereError('InitOAController: Did not find OAMixer="'//TRIM(equipName)//'".')
CALL ShowContinueError('in list of valid OA Mixers.')
Errorsfound = .true.
ENDIF
ELSE
CALL ShowSevereError('InitOAController: Did not find OutdoorAir:Mixer Component="OutdoorAir:Mixer".')
CALL ShowContinueError('in list of valid OA Components.')
Errorsfound = .true.
ENDIF
IF (OAController(thisOAController)%InletNode == 0) THEN !throw an error
CALL ShowSevereError('InitOAController: Failed to find proper inlet node for OutdoorAir:Mixer and Controller = ' &
//TRIM(OAController(thisOAController)%Name) )
ErrorsFound = .TRUE.
ENDIF
CASE (ControllerStandAloneERV)
! set the inlet node to also equal the OA node because this is a special controller for economizing stand alone ERV
! with the assumption that equipment is bypassed....
OAController(thisOAController)%InletNode = OAController(thisOAController)%OANode
CASE DEFAULT
CALL ShowSevereError('InitOAController: Failed to find ControllerType: '&
//TRIM(OAController(thisOAController)%ControllerType) )
ErrorsFound = .TRUE.
END SELECT
ENDDO
MyOneTimeFlag = .false.
END IF
IF ( .NOT. SysSizingCalc .AND. MySetPointCheckFlag .AND. DoSetPointTest .AND. .NOT. FirstHVACIteration) THEN
DO OAControllerIndex=1,NumOAControllers
MixedAirNode = OAController(OAControllerIndex)%MixNode
IF (MixedAirNode > 0) THEN
! IF (OAController(OAControllerIndex)%Econo == 1 .AND. .NOT. AirLoopControlInfo(AirLoopNum)%CyclingFan) THEN
IF (OAController(OAControllerIndex)%Econo .GT. NoEconomizer .AND. AirLoopControlInfo(AirLoopNum)%AnyContFan) THEN
IF (Node(MixedAirNode)%TempSetPoint == SensedNodeFlagValue) THEN
IF (.NOT. AnyEnergyManagementSystemInModel) THEN
CALL ShowSevereError('MixedAir: Missing temperature setpoint for economizer controller ' // &
TRIM(OAController(OAControllerIndex)%Name))
CALL ShowSevereError('Node Referenced (by Controller)='//TRIM(NodeID(MixedAirNode)))
CALL ShowContinueError(' use a Setpoint Manager with Control Variable = "Temperature" to establish '// &
'a setpoint at the mixed air node.')
SetPointErrorFlag = .TRUE.
ELSE
! add call to check node in EMS
CALL CheckIfNodeSetpointManagedByEMS(MixedAirNode,iTemperatureSetpoint, SetpointErrorFlag)
IF (SetPointErrorFlag) THEN
CALL ShowSevereError('MixedAir: Missing temperature setpoint for economizer controller ' // &
TRIM(OAController(OAControllerIndex)%Name))
CALL ShowSevereError('Node Referenced (by Controller)='//TRIM(NodeID(MixedAirNode)))
CALL ShowContinueError(' use a Setpoint Manager with Control Variable = "Temperature" to establish '// &
'a setpoint at the mixed air node.')
CALL ShowContinueError('Or add EMS Actuator to provide temperature setpoint at this node')
ENDIF
ENDIF
END IF
ENDIF
END IF
END DO
MySetPointCheckFlag = .FALSE.
END IF
IF ( .NOT. SysSizingCalc .AND. MySizeFlag(OAControllerNum)) THEN
CALL SizeOAController(OAControllerNum)
IF (AirLoopNum > 0) THEN
AirLoopControlInfo(AirLoopNum)%OACtrlNum = OAControllerNum
AirLoopControlInfo(AirLoopNum)%OACtrlname = OAController(OAControllerNum)%Name
IF (OAController(OAControllerNum)%Lockout == LockoutWithHeatingPossible) THEN
AirLoopControlInfo(AirLoopNum)%CanLockoutEconoWithHeating = .TRUE.
AirLoopControlInfo(AirLoopNum)%CanLockoutEconoWithCompressor = .FALSE.
AirLoopControlInfo(AirLoopNum)%CanNotLockoutEcono = .FALSE.
ELSE IF (OAController(OAControllerNum)%Lockout == LockoutWithCompressorPossible) THEN
AirLoopControlInfo(AirLoopNum)%CanLockoutEconoWithHeating = .FALSE.
AirLoopControlInfo(AirLoopNum)%CanLockoutEconoWithCompressor = .TRUE.
AirLoopControlInfo(AirLoopNum)%CanNotLockoutEcono = .FALSE.
ELSE
AirLoopControlInfo(AirLoopNum)%CanLockoutEconoWithHeating = .FALSE.
AirLoopControlInfo(AirLoopNum)%CanLockoutEconoWithCompressor = .FALSE.
AirLoopControlInfo(AirLoopNum)%CanNotLockoutEcono = .TRUE.
END IF
END IF
IF ((OAController(OAControllerNum)%MaxOA - OAController(OAControllerNum)%MinOA) .LT. -SmallAirVolFlow) THEN
CALL ShowSevereError('For Controller:OutdoorAir: ' // TRIM(OAController(OAControllerNum)%Name))
CALL ShowContinueError(' maximum outdoor air flow rate ('//TRIM(RoundSigDigits(OAController(OAControllerNum)%MaxOA,4))// &
') < minimum outdoor air flow rate ('//TRIM(RoundSigDigits(OAController(OAControllerNum)%MinOA,4))// &
')')
CALL ShowContinueError(' To set the minimum outside air flow rate use the '// &
'"Design (minimum) outdoor air flow rate" field in the Sizing:System object')
ErrorsFound=.true.
END IF
MySizeFlag(OAControllerNum) = .FALSE.
END IF
IF (BeginEnvrnFlag .and. MyEnvrnFlag(OAControllerNum)) THEN
OANode = OAController(OAControllerNum)%OANode
RhoAirStdInit = StdRhoAir
OAController(OAControllerNum)%MinOAMassFlowRate = OAController(OAControllerNum)%MinOA * RhoAirStdInit
OAController(OAControllerNum)%MaxOAMassFlowRate = OAController(OAControllerNum)%MaxOA * RhoAirStdInit
MyEnvrnFlag(OAControllerNum) = .FALSE.
Node(OANode)%MassFlowRateMax = OAController(OAControllerNum)%MaxOAMassFlowRate
!predefined reporting
IF (OAController(OAControllerNum)%econo .GT. NoEconomizer) THEN
equipName = OAController(OAControllerNum)%Name
! 90.1 descriptor for economizer controls
! Changed by Amit for New Feature implementation
IF (OAController(OAControllerNum)%Econo .EQ. DifferentialEnthalpy) THEN
CALL PreDefTableEntry(pdchEcoKind,equipName,'DifferentialEnthalpy')
ELSE IF (OAController(OAControllerNum)%Econo .EQ. DifferentialDryBulb) THEN
CALL PreDefTableEntry(pdchEcoKind,equipName,'DifferentialDryBulb')
ELSE IF (OAController(OAControllerNum)%Econo .EQ. FixedEnthalpy) THEN
CALL PreDefTableEntry(pdchEcoKind,equipName,'FixedEnthalpy')
ELSE IF (OAController(OAControllerNum)%Econo .EQ. FixedDryBulb) THEN
CALL PreDefTableEntry(pdchEcoKind,equipName,'FixedDryBulb')
ELSE
CALL PreDefTableEntry(pdchEcoKind,equipName,'Other')
ENDIF
CALL PreDefTableEntry(pdchEcoMinOA,equipName,OAController(OAControllerNum)%MinOA)
CALL PreDefTableEntry(pdchEcoMaxOA,equipName,OAController(OAControllerNum)%MaxOA)
!EnergyPlus input echos for economizer controls
! Chnged by Amit for new feature implementation
IF(OAController(OAControllerNum)%Econo .EQ. DifferentialDryBulb) THEN
CALL PreDefTableEntry(pdchEcoRetTemp,equipName,'Yes')
ELSE
CALL PreDefTableEntry(pdchEcoRetTemp,equipName,'No')
ENDIF
IF(OAController(OAControllerNum)%Econo .EQ. DifferentialEnthalpy) THEN
CALL PreDefTableEntry(pdchEcoRetTemp,equipName,'Yes')
ELSE
CALL PreDefTableEntry(pdchEcoRetTemp,equipName,'No')
ENDIF
IF(OAController(OAControllerNum)%Econo .EQ. FixedDryBulb) THEN
CALL PreDefTableEntry(pdchEcoRetTemp,equipName,OAController(OAControllerNum)%TempLim)
ELSE
CALL PreDefTableEntry(pdchEcoRetTemp,equipName,'-')
ENDIF
IF(OAController(OAControllerNum)%Econo .EQ. FixedEnthalpy) THEN
CALL PreDefTableEntry(pdchEcoRetTemp,equipName,OAController(OAControllerNum)%EnthLim)
ELSE
CALL PreDefTableEntry(pdchEcoRetTemp,equipName,'-')
ENDIF
END IF
END IF
IF (.not. BeginEnvrnFlag) THEN
MyEnvrnFlag(OAControllerNum) = .true.
ENDIF
VentMechObjectNum = OAController(OAControllerNum)%VentMechObjectNum
IF(MechVentCheckFlag(OAControllerNum))THEN
! Make these checks only once at the beginning of the simulation
! Make sure all air loop zones and air loop zones with people objects are covered by mechanical ventilation
! Issue a warning only if the zone is not accounted for in the associated mechanical ventilation object
IF(VentMechObjectNum .GT. 0)THEN
ALLOCATE(TempZoneOAAreaRate(VentilationMechanical(VentMechObjectNum)%NumofVentMechZones))
ALLOCATE(TempZoneOAPeopleRate(VentilationMechanical(VentMechObjectNum)%NumofVentMechZones))
ALLOCATE(TempZoneOAFlow(VentilationMechanical(VentMechObjectNum)%NumofVentMechZones))
ALLOCATE(TempZoneOAACH(VentilationMechanical(VentMechObjectNum)%NumofVentMechZones))
ALLOCATE(TempZoneOADSOAName(VentilationMechanical(VentMechObjectNum)%NumofVentMechZones))
ALLOCATE(TempZoneOADSOAIndex(VentilationMechanical(VentMechObjectNum)%NumofVentMechZones))
ALLOCATE(TempZone(VentilationMechanical(VentMechObjectNum)%NumofVentMechZones))
ALLOCATE(TempZoneADEffCooling(VentilationMechanical(VentMechObjectNum)%NumofVentMechZones))
ALLOCATE(TempZoneADEffHeating(VentilationMechanical(VentMechObjectNum)%NumofVentMechZones))
ALLOCATE(TempZoneADEffSchPtr(VentilationMechanical(VentMechObjectNum)%NumofVentMechZones))
ALLOCATE(TempZoneADEffSchName(VentilationMechanical(VentMechObjectNum)%NumofVentMechZones))
TempZoneOAAreaRate=0.0d0
TempZoneOAPeopleRate=0.0d0
TempZoneOAFlow=0.0d0
TempZoneOAACH=0.0d0
TempZoneOADSOAName=' '
TempZoneOADSOAIndex=0
TempZone=0
TempZoneADEffCooling=1.0d0
TempZoneADEffHeating=1.0d0
TempZoneADEffSchPtr=0
TempZoneADEffSchName=' '
! Make sure all zones with mechanical ventilation are on the correct air loop
TempMechVentArrayCounter = 0
DO NumMechVentZone = 1, VentilationMechanical(VentMechObjectNum)%NumofVentMechZones
ZoneNum = VentilationMechanical(VentMechObjectNum)%Zone(NumMechVentZone)
FoundZone = .FALSE.
DO AirLoopZoneInfoZoneNum = 1, AirLoopZoneInfo(AirLoopNum)%NumZones
NumZone = AirLoopZoneInfo(AirLoopNum)%ActualZoneNumber(AirLoopZoneInfoZoneNum)
IF(ZoneNum .EQ. NumZone)THEN
FoundZone = .TRUE.
TempMechVentArrayCounter = TempMechVentArrayCounter + 1
TempZone(TempMechVentArrayCounter) = &
VentilationMechanical(VentMechObjectNum)%Zone(NumMechVentZone)
TempZoneOAAreaRate(TempMechVentArrayCounter) = &
VentilationMechanical(VentMechObjectNum)%ZoneOAAreaRate(NumMechVentZone)
TempZoneOAPeopleRate(TempMechVentArrayCounter) = &
VentilationMechanical(VentMechObjectNum)%ZoneOAPeopleRate(NumMechVentZone)
TempZoneOAFlow(TempMechVentArrayCounter) = &
VentilationMechanical(VentMechObjectNum)%ZoneOAFlow(NumMechVentZone)
TempZoneOAACH(TempMechVentArrayCounter) = &
VentilationMechanical(VentMechObjectNum)%ZoneOAACH(NumMechVentZone)
TempZoneOADSOAIndex(TempMechVentArrayCounter) = &
VentilationMechanical(VentMechObjectNum)%ZoneDesignSpecOAObjIndex(NumMechVentZone)
TempZoneOADSOAName(TempMechVentArrayCounter) = &
VentilationMechanical(VentMechObjectNum)%ZoneDesignSpecOAObjName(NumMechVentZone)
! new DCV
TempZoneADEffCooling(TempMechVentArrayCounter) = &
VentilationMechanical(VentMechObjectNum)%ZoneADEffCooling(NumMechVentZone)
TempZoneADEffHeating(TempMechVentArrayCounter) = &
VentilationMechanical(VentMechObjectNum)%ZoneADEffHeating(NumMechVentZone)
TempZoneADEffSchPtr(TempMechVentArrayCounter) = &
VentilationMechanical(VentMechObjectNum)%ZoneADEffSchPtr(NumMechVentZone)
TempZoneADEffSchName(TempMechVentArrayCounter) = &
VentilationMechanical(VentMechObjectNum)%ZoneADEffSchName(NumMechVentZone)
! Sum outside air per unit floor area for each mechanical ventilation object only once per simulation
VentilationMechanical(VentMechObjectNum)%TotAreaOAFlow = &
VentilationMechanical(VentMechObjectNum)%TotAreaOAFlow + &
Zone(ZoneNum)%FloorArea * Zone(ZoneNum)%Multiplier * Zone(ZoneNum)%ListMultiplier * &
VentilationMechanical(VentMechObjectNum)%ZoneOAAreaRate(NumMechVentZone)
VentilationMechanical(VentMechObjectNum)%TotZoneOAFlow = &
VentilationMechanical(VentMechObjectNum)%TotZoneOAFlow + &
Zone(ZoneNum)%Multiplier * Zone(ZoneNum)%ListMultiplier * &
VentilationMechanical(VentMechObjectNum)%ZoneOAFlow(NumMechVentZone)
VentilationMechanical(VentMechObjectNum)%TotZoneOAACH = &
VentilationMechanical(VentMechObjectNum)%TotZoneOAACH + &
Zone(ZoneNum)%Multiplier * Zone(ZoneNum)%ListMultiplier * &
(VentilationMechanical(VentMechObjectNum)%ZoneOAACH(NumMechVentZone)*Zone(ZoneNum)%Volume/3600.d0)
EXIT
END IF
END DO
IF(.NOT. FoundZone)THEN
CALL ShowWarningError('Zone name = '//TRIM(Zone(ZoneNum)%Name)// &
' in '//trim(CurrentModuleObjects(CMO_MechVentilation))//' object name = ' &
//TRIM(OAController(OAControllerNum)%VentilationMechanicalName)// &
' is not on the same air loop as Controller:OutdoorAir = '//TRIM(OAController(OAControllerNum)%Name))
CALL ShowContinueError('This zone will not be used and the simulation will continue...')
END IF
END DO
! Re-size final array to conserve environment space
DEALLOCATE(VentilationMechanical(VentMechObjectNum)%Zone)
DEALLOCATE(VentilationMechanical(VentMechObjectNum)%ZoneOAAreaRate)
DEALLOCATE(VentilationMechanical(VentMechObjectNum)%ZoneOAPeopleRate)
DEALLOCATE(VentilationMechanical(VentMechObjectNum)%ZoneOAFlow)
DEALLOCATE(VentilationMechanical(VentMechObjectNum)%ZoneOAACH)
DEALLOCATE(VentilationMechanical(VentMechObjectNum)%ZoneDesignSpecOAObjIndex)
DEALLOCATE(VentilationMechanical(VentMechObjectNum)%ZoneDesignSpecOAObjName)
DEALLOCATE(VentilationMechanical(VentMechObjectNum)%ZoneADEffCooling)
DEALLOCATE(VentilationMechanical(VentMechObjectNum)%ZoneADEffHeating)
DEALLOCATE(VentilationMechanical(VentMechObjectNum)%ZoneADEffSchPtr)
DEALLOCATE(VentilationMechanical(VentMechObjectNum)%ZoneADEffSchName)
ALLOCATE(VentilationMechanical(VentMechObjectNum)%Zone(TempMechVentArrayCounter))
ALLOCATE(VentilationMechanical(VentMechObjectNum)%ZoneOAAreaRate(TempMechVentArrayCounter))
ALLOCATE(VentilationMechanical(VentMechObjectNum)%ZoneOAPeopleRate(TempMechVentArrayCounter))
ALLOCATE(VentilationMechanical(VentMechObjectNum)%ZoneOAFlow(TempMechVentArrayCounter))
ALLOCATE(VentilationMechanical(VentMechObjectNum)%ZoneOAACH(TempMechVentArrayCounter))
ALLOCATE(VentilationMechanical(VentMechObjectNum)%ZoneDesignSpecOAObjIndex(TempMechVentArrayCounter))
ALLOCATE(VentilationMechanical(VentMechObjectNum)%ZoneDesignSpecOAObjName(TempMechVentArrayCounter))
ALLOCATE(VentilationMechanical(VentMechObjectNum)%ZoneADEffCooling(TempMechVentArrayCounter))
ALLOCATE(VentilationMechanical(VentMechObjectNum)%ZoneADEffHeating(TempMechVentArrayCounter))
ALLOCATE(VentilationMechanical(VentMechObjectNum)%ZoneADEffSchPtr(TempMechVentArrayCounter))
ALLOCATE(VentilationMechanical(VentMechObjectNum)%ZoneADEffSchName(TempMechVentArrayCounter))
DO NumMechVentZone = 1, TempMechVentArrayCounter
VentilationMechanical(VentMechObjectNum)%Zone(NumMechVentZone) = &
TempZone(NumMechVentZone)
VentilationMechanical(VentMechObjectNum)%ZoneOAAreaRate(NumMechVentZone) = &
TempZoneOAAreaRate(NumMechVentZone)
VentilationMechanical(VentMechObjectNum)%ZoneOAPeopleRate(NumMechVentZone) = &
TempZoneOAPeopleRate(NumMechVentZone)
VentilationMechanical(VentMechObjectNum)%ZoneOAFlow(NumMechVentZone) = &
TempZoneOAFlow(NumMechVentZone)
VentilationMechanical(VentMechObjectNum)%ZoneOAACH(NumMechVentZone) = &
TempZoneOAACH(NumMechVentZone)
VentilationMechanical(VentMechObjectNum)%ZoneDesignSpecOAObjName(NumMechVentZone) = &
TempZoneOADSOAName(NumMechVentZone)
VentilationMechanical(VentMechObjectNum)%ZoneDesignSpecOAObjIndex(NumMechVentZone) = &
TempZoneOADSOAIndex(NumMechVentZone)
VentilationMechanical(VentMechObjectNum)%ZoneADEffCooling(NumMechVentZone) = &
TempZoneADEffCooling(NumMechVentZone)
VentilationMechanical(VentMechObjectNum)%ZoneADEffHeating(NumMechVentZone) = &
TempZoneADEffHeating(NumMechVentZone)
VentilationMechanical(VentMechObjectNum)%ZoneADEffSchPtr(NumMechVentZone) = &
TempZoneADEffSchPtr(NumMechVentZone)
VentilationMechanical(VentMechObjectNum)%ZoneADEffSchName(NumMechVentZone) = &
TempZoneADEffSchName(NumMechVentZone)
END DO
VentilationMechanical(VentMechObjectNum)%NumofVentMechZones = TempMechVentArrayCounter
!predefined report
DO jZone = 1, VentilationMechanical(VentMechObjectNum)%NumofVentMechZones
zoneName = zone(VentilationMechanical(VentMechObjectNum)%Zone(jZone))%name
CALL PreDefTableEntry(pdchDCVventMechName,zoneName,VentilationMechanical(VentMechObjectNum)%Name)
CALL PreDefTableEntry(pdchDCVperPerson,zoneName, VentilationMechanical(VentMechObjectNum)%ZoneOAPeopleRate(jZone),6)
CALL PreDefTableEntry(pdchDCVperArea,zoneName, VentilationMechanical(VentMechObjectNum)%ZoneOAAreaRate(jZone),6)
! added for new DCV inputs
CALL PreDefTableEntry(pdchDCVZoneADEffCooling,zoneName, VentilationMechanical(VentMechObjectNum)%ZoneADEffCooling(jZone),2)
CALL PreDefTableEntry(pdchDCVZoneADEffHeating,zoneName, VentilationMechanical(VentMechObjectNum)%ZoneADEffHeating(jZone),2)
CALL PreDefTableEntry(pdchDCVZoneADEffSchName,zoneName, &
GetScheduleName(VentilationMechanical(VentMechObjectNum)%ZoneADEffSchPtr(jZone)))
END DO
! Delete temporary array
DEALLOCATE(TempZone)
DEALLOCATE(TempZoneOAAreaRate)
DEALLOCATE(TempZoneOAPeopleRate)
DEALLOCATE(TempZoneOAFlow)
DEALLOCATE(TempZoneOAACH)
DEALLOCATE(TempZoneOADSOAIndex)
DEALLOCATE(TempZoneOADSOAName)
DEALLOCATE(TempZoneADEffCooling)
DEALLOCATE(TempZoneADEffHeating)
DEALLOCATE(TempZoneADEffSchPtr)
DEALLOCATE(TempZoneADEffSchName)
! Check to see if any zones on an air loop are not accounted for by a mechanical ventilation object
DO AirLoopZoneInfoZoneNum = 1, AirLoopZoneInfo(AirLoopNum)%NumZones
NumZone = AirLoopZoneInfo(AirLoopNum)%ActualZoneNumber(AirLoopZoneInfoZoneNum)
FoundAreaZone = .FALSE.
FoundPeopleZone = .FALSE.
DO NumMechVentZone = 1, VentilationMechanical(VentMechObjectNum)%NumofVentMechZones
ZoneNum = VentilationMechanical(VentMechObjectNum)%Zone(NumMechVentZone)
IF(ZoneNum .EQ. NumZone)THEN
FoundAreaZone = .TRUE.
IF(VentilationMechanical(VentMechObjectNum)%ZoneOAPeopleRate(NumMechVentZone) .GT. 0.0d0)THEN
FoundPeopleZone = .TRUE.
END IF
EXIT
END IF
END DO
IF(.NOT. FoundAreaZone)THEN
CALL ShowWarningError('Zone name = '//TRIM(Zone(NumZone)%Name)// &
' is not accounted for by '//trim(CurrentModuleObjects(CMO_MechVentilation))//' object name = ' &
//TRIM(OAController(OAControllerNum)%VentilationMechanicalName))
CALL ShowContinueError('Ventilation per unit floor area has not been specified for this zone, which is connected to')
CALL ShowContinueError('the air loop served by Controller:OutdoorAir = '//TRIM(OAController(OAControllerNum)%Name)//&
'. Simulation will continue...')
END IF
IF(.NOT. FoundPeopleZone)THEN
! Loop through people objects to see if this zone has a people object and only then show a warning
DO PeopleNum = 1, TotPeople
IF(People(PeopleNum)%ZonePtr .EQ. NumZone)THEN
IF (.not. FoundAreaZone)THEN
! ! If the zone was found, then the people ventilation rate is set to 0
! CALL ShowWarningError('PEOPLE object for zone = '//TRIM(Zone(NumZone)%Name)// &
! ' is not accounted for by '//trim(CurrentModuleObjects(CMO_MechVentilation))// &
! ' object name = '//TRIM(OAController(OAControllerNum)%VentilationMechanicalName))
! CALL ShowContinueError('A "PEOPLE" object has been specified in the idf for this zone, '// &
! 'but the ventilation rate is set to 0 in this Controller:MechanicalVentilation Object.')
! CALL ShowContinueError('Check ventilation rate in Controller:MechanicalVentilation object. '// &
! ' Simulation will continue.')
! ELSE
! If the zone was not found, then the PEOPLE objects are not accounted for
CALL ShowWarningError('PEOPLE object for zone = '//TRIM(Zone(NumZone)%Name)// &
' is not accounted for by '//trim(CurrentModuleObjects(CMO_MechVentilation))// &
' object name = '//TRIM(OAController(OAControllerNum)%VentilationMechanicalName))
CALL ShowContinueError('A "PEOPLE" object has been specified in the idf for this zone, but it is not included '// &
'in this '//trim(CurrentModuleObjects(CMO_MechVentilation))//' Object.')
CALL ShowContinueError('Check '//trim(CurrentModuleObjects(CMO_MechVentilation))// &
' object. Simulation will continue.')
END IF
END IF
END DO
ELSE ! People > 0, check to make sure there is a people statement in the zone
FoundAreaZone=.false.
DO PeopleNum = 1, TotPeople
IF (People(PeopleNum)%ZonePtr /= NumZone) CYCLE
FoundAreaZone=.true.
EXIT
ENDDO
IF (.not. FoundAreaZone) THEN
CALL ShowWarningError(trim(CurrentModuleObjects(CMO_MechVentilation))// &
' = "'//TRIM(OAController(OAControllerNum)%VentilationMechanicalName)// &
'", Zone="'//TRIM(Zone(NumZone)%Name)//'".')
CALL ShowContinueError('No "PEOPLE" object has been specified in the idf for this zone, '// &
'but the ventilation rate is > 0 in this Controller:MechanicalVentilation Object.')
CALL ShowContinueError('Check ventilation rate in Controller:MechanicalVentilation object. '// &
' Simulation will continue.')
ENDIF
END IF
END DO
END IF
MechVentCheckFlag(OAControllerNum) = .FALSE.
END IF
!****
! Perform a one time initialization of AirloopHVAC OA System report variables
!
! If AirloopHVAC objects are used, NumPrimaryAirSys > 0 and the initialization proceeds and then sets
! SetUpAirLoopHVACVariables to .FALSE. so this is never done again and only the first IF is checked
! each time through Init. If for some reason the primary air system have not yet been read in, this
! code waits for the air loop data to be available before performing the report variable initialization.
!
! If AirloopHVAC objects are not used, NumPrimaryAirSys is always equal to 0 and only these
! two IF statements are checked each time through Init (e.g., if StandAloneERV controllers are used
! without AirloopHVAC objects).
!
IF(SetUpAirLoopHVACVariables)THEN
IF(NumPrimaryAirSys .GT. 0)THEN
! Added code to report (TH, 10/20/2008):
! air economizer status (1 = on, 0 = off or does not exist), and
! actual and minimum outside air fraction (0 to 1)
DO OAControllerLoop=1,NumOAControllers
!Find the outside air system that has the OA controller
IF (OAController(OAControllerLoop)%ControllerType_Num == ControllerStandAloneERV) CYCLE ! ERV controller not on airloop
OASysFound = .FALSE.
thisOASys = 0
DO OASysNum = 1, NumOASystems
DO OAControllerLoop2 = 1, OutsideAirSys(OASysNum)%NumControllers
IF(SameString(OutsideAirSys(OASysNum)%ControllerName(OAControllerLoop2),&
OAController(OAControllerLoop)%Name))THEN
thisOASys = OASysNum
OASysFound = .TRUE.
EXIT
ENDIF
END DO
IF(OASysFound) EXIT
END DO
IF (ThisOASys <= 0) THEN
!Check outside air system name
CALL ShowWarningError('Cannot find the AirLoopHVAC:OutdoorAirSystem for the OA Controller: ' &
//TRIM(OAController(OAControllerNum)%Name))
AirLoopFound = .FALSE.
Else
!Find the primary air loop that has the outside air system
AirLoopFound = .FALSE.
DO thisAirLoop = 1, NumPrimaryAirSys
DO BranchNum = 1, PrimaryAirSystem(thisAirLoop)%NumBranches
DO CompNum = 1, PrimaryAirSystem(thisAirLoop)%Branch(BranchNum)%TotalComponents
IF(.NOT. SameString(PrimaryAirSystem(thisAirLoop)%Branch(BranchNum)%Comp(CompNum)%Name, &
OutsideAirSys(thisOASys)%Name) .OR. &
.NOT. SameString(PrimaryAirSystem(thisAirLoop)%Branch(BranchNum)%Comp(CompNum)%TypeOf, &
'AirLoopHVAC:OutdoorAirSystem'))CYCLE
AirLoopFound=.TRUE.
EXIT
END DO
IF(AirLoopFound)EXIT
END DO
IF(AirLoopFound)EXIT
ENDDO
ENDIF
! Check primary air loop name
IF (AirLoopFound .AND. thisAirLoop>0) THEN
airloopName = PrimaryAirSystem(thisAirLoop)%Name ! OutsideAirSys(OASysIndex)%Name
ELSE
CALL ShowWarningError('Cannot find the primary air loop for the OA Controller: ' &
//TRIM(OAController(OAControllerNum)%Name))
airloopName='AirLoop not found'
ENDIF
! Note use of OAControllerLoop here to keep DO Loop index separate from InitOAController local variable
! CurrentModuleObject='AirLoopHVAC'
CALL SetupOutputVariable('Air System Outdoor Air Economizer Status []', &
OAController(OAControllerLoop)%EconomizerStatus, 'System','Average',airloopName)
CALL SetupOutputVariable('Air System Outdoor Air Heat Recovery Bypass Status []', &
OAController(OAControllerLoop)%HeatRecoveryBypassStatus, 'System','Average',airloopName)
IF(OAController(OAControllerLoop)%HeatRecoveryBypassControlType == BypassWhenOAFlowGreaterThanMinimum)THEN
CALL SetupOutputVariable('Air System Outdoor Air Heat Recovery Bypass Heating Coil Activity Status []', &
OAController(OAControllerLoop)%HRHeatingCoilActive, 'System','Average',airloopName)
CALL SetupOutputVariable('Air System Outdoor Air Heat Recovery Bypass Minimum Outdoor Air Mixed Air Temperature [C]', &
OAController(OAControllerLoop)%MixedAirTempAtMinOAFlow, 'System','Average',airloopName)
END IF
CALL SetupOutputVariable('Air System Outdoor Air High Humidity Control Status []', &
OAController(OAControllerLoop)%HighHumCtrlStatus, 'System','Average',airloopName)
CALL SetupOutputVariable('Air System Outdoor Air Flow Fraction []', &
OAController(OAControllerLoop)%OAFractionRpt, 'System','Average',airloopName)
CALL SetupOutputVariable('Air System Outdoor Air Minimum Flow Fraction []', &
OAController(OAControllerLoop)%MinOAFracLimit, 'System','Average',airloopName)
CALL SetupOutputVariable('Air System Outdoor Air Mass Flow Rate [kg/s]', &
OAController(OAControllerLoop)%OAMassFlow, 'System','Average',airloopName)
CALL SetupOutputVariable('Air System Mixed Air Mass Flow Rate [kg/s]', &
OAController(OAControllerLoop)%MixMassFlow, 'System','Average',airloopName)
IF (AnyEnergyManagementSystemInModel) THEN
CALL SetupEMSInternalVariable('Outdoor Air Controller Maximum Mass Flow Rate', &
OAController(OAControllerLoop)%Name, '[kg/s]', OAController(OAControllerLoop)%MaxOAMassFlowRate )
CALL SetupEMSInternalVariable('Outdoor Air Controller Minimum Mass Flow Rate', &
OAController(OAControllerLoop)%Name, '[kg/s]', OAController(OAControllerLoop)%MinOAMassFlowRate )
CALL SetupEMSActuator('Outdoor Air Controller', OAController(OAControllerLoop)%Name, 'Air Mass Flow Rate' , '[kg/s]', &
OAController(OAControllerLoop)%EMSOverrideOARate, OAController(OAControllerLoop)%EMSOARateValue )
ENDIF
END DO
SetUpAirLoopHVACVariables = .FALSE.
END IF
END IF
! Each time step
IF (FirstHVACIteration) THEN
! Mixed air setpoint. Set by a setpoint manager.
IF(OAController(OAControllerNum)%ControllerType_Num == ControllerOutsideAir)THEN
IF (Node(OAController(OAControllerNum)%MixNode)%TempSetPoint > 0.0d0) THEN
OAController(OAControllerNum)%MixSetTemp = Node(OAController(OAControllerNum)%MixNode)%TempSetPoint
ELSE
OAController(OAControllerNum)%MixSetTemp = OAController(OAControllerNum)%TempLowLim
END IF
TotalPeopleOAFlow = 0.0d0
IF(VentMechObjectNum /= 0)THEN
DO ZoneIndex = 1, VentilationMechanical(VentMechObjectNum)%NumofVentMechZones
ZoneNum = VentilationMechanical(VentMechObjectNum)%Zone(ZoneIndex)
! ZoneIntGain(ZoneNum)%NOFOCC is the number of occupants of a zone at each time step, already counting the occupant schedule
TotalPeopleOAFlow = TotalPeopleOAFlow + &
ZoneIntGain(ZoneNum)%NOFOCC * Zone(ZoneNum)%Multiplier * Zone(ZoneNum)%ListMultiplier * &
VentilationMechanical(VentMechObjectNum)%ZoneOAPeopleRate(ZoneIndex)
END DO
VentilationMechanical(VentMechObjectNum)%TotPeopleOAFlow = TotalPeopleOAFlow
END IF
!
ELSE
! Stand Alone ERV does not require a termperature setpoint schedule, make setpoint equal to lower economizer limit
OAController(OAControllerNum)%MixSetTemp = OAController(OAControllerNum)%TempLowLim
END IF
END IF
! Each iteration
IF(OAController(OAControllerNum)%ControllerType_Num == ControllerOutsideAir)THEN
! zone exhaust mass flow is saved in AirLoopFlow%ZoneExhaust
! the zone exhaust mass flow that is said to be balanced by simple air flows is saved in AirLoopFlow%ZoneExhaustBalanced
IF (AirLoopNum > 0) THEN
!OAController(OAControllerNum)%ExhMassFlow = AirLoopFlow(AirLoopNum)%ZoneExhaust
OAController(OAControllerNum)%ExhMassFlow = AirLoopFlow(AirLoopNum)%ZoneExhaust - AirLoopFlow(AirLoopNum)%ZoneExhaustBalanced
IF (AirLoopControlInfo(AirLoopNum)%LoopFlowRateSet .AND. .NOT. FirstHVACIteration) THEN
! if flow rate has been specified by a manager, set it to the specified value
OAController(OAControllerNum)%MixMassFlow = AirLoopFlow(AirLoopNum)%ReqSupplyFrac * AirLoopFlow(AirLoopNum)%DesSupply
ELSE
OAController(OAControllerNum)%MixMassFlow = Node(OAController(OAControllerNum)%RetNode)%MassFlowRate + &
OAController(OAControllerNum)%ExhMassFlow
END IF
ELSE
OAController(OAControllerNum)%ExhMassFlow = 0.0d0
OAController(OAControllerNum)%MixMassFlow = Node(OAController(OAControllerNum)%RetNode)%MassFlowRate
END IF
IF (Node(OAController(OAControllerNum)%MixNode)%MassFlowRateMaxAvail <= 0.0d0) THEN
OAController(OAControllerNum)%MixMassFlow = 0.0d0
END IF
ELSE
! Mixed and exhaust flow rates are passed through to model CONTROLLER:STAND ALONE ERV in SimOAController
OAController(OAControllerNum)%OAMassFlow = OAController(OAControllerNum)%MaxOAMassFlowRate
OAController(OAControllerNum)%MixMassFlow = OAController(OAControllerNum)%MaxOAMassFlowRate
OAController(OAControllerNum)%ExhMassFlow = Node(OAController(OAControllerNum)%RetNode)%MassFlowRate
END IF
OAController(OAControllerNum)%ExhMassFlow = MAX(OAController(OAControllerNum)%ExhMassFlow,0.0d0)
! Outside air values
OAController(OAControllerNum)%OATemp = Node(OAController(OAControllerNum)%OANode)%Temp
OAController(OAControllerNum)%OAEnth = Node(OAController(OAControllerNum)%OANode)%Enthalpy
OAController(OAControllerNum)%OAPress = Node(OAController(OAControllerNum)%OANode)%Press
OAController(OAControllerNum)%OAHumRat = Node(OAController(OAControllerNum)%OANode)%HumRat
! Inlet air values (on OA input side)
OAController(OAControllerNum)%InletTemp = Node(OAController(OAControllerNum)%InletNode)%Temp
OAController(OAControllerNum)%InletEnth = Node(OAController(OAControllerNum)%InletNode)%Enthalpy
OAController(OAControllerNum)%InletPress = Node(OAController(OAControllerNum)%InletNode)%Press
OAController(OAControllerNum)%InletHumRat = Node(OAController(OAControllerNum)%InletNode)%HumRat
! Return air values
OAController(OAControllerNum)%RetTemp = Node(OAController(OAControllerNum)%RetNode)%Temp
OAController(OAControllerNum)%RetEnth = Node(OAController(OAControllerNum)%RetNode)%Enthalpy
!
! Check sensors faults for the air economizer
!
iEco = OAController(OAControllerNum)%Econo
IF (AnyFaultsInModel .AND. (iEco > NoEconomizer)) THEN
DO i = 1, NumFaults
IF ((Faults(i)%ControllerTypeEnum == iController_AirEconomizer) .AND. &
(Faults(i)%ControllerID == OAControllerNum)) THEN
IF (GetCurrentScheduleValue(Faults(i)%AvaiSchedPtr) > 0.0d0) THEN
rSchVal = 1.0d0
IF (Faults(i)%SeveritySchedPtr > 0) THEN
rSchVal = GetCurrentScheduleValue(Faults(i)%SeveritySchedPtr)
ENDIF
ELSE
! no fault
CYCLE
ENDIF
rOffset = rSchVal * Faults(i)%Offset
IF(ABS(rOffset) < 0.000000001d0) CYCLE
! ECONOMIZER - outdoor air dry-bulb temperature sensor offset
SELECT CASE(iEco)
CASE(FixedDryBulb, DifferentialDryBulb, FixedDewpointAndDryBulb, ElectronicEnthalpy, DifferentialDryBulbAndEnthalpy)
IF(Faults(i)%FaultTypeEnum == iFault_TemperatureSensorOffset_OutdoorAir) THEN
! FaultModel:TemperatureSensorOffset:OutdoorAir
OAController(OAControllerNum)%OATemp = OAController(OAControllerNum)%OATemp + rOffset
OAController(OAControllerNum)%InletTemp = OAController(OAControllerNum)%InletTemp + rOffset
ENDIF
CASE DEFAULT
END SELECT
! ECONOMIZER - outdoor air humidity ratio sensor offset. really needed ???
SELECT CASE(iEco)
CASE(FixedDewpointAndDryBulb, ElectronicEnthalpy)
IF(Faults(i)%FaultTypeEnum == iFault_HumiditySensorOffset_OutdoorAir) THEN
! FaultModel:HumiditySensorOffset:OutdoorAir
OAController(OAControllerNum)%OAHumRat = OAController(OAControllerNum)%OAHumRat + rOffset
OAController(OAControllerNum)%InletHumRat = OAController(OAControllerNum)%InletHumRat + rOffset
ENDIF
CASE DEFAULT
END SELECT
! ECONOMIZER - outdoor air enthalpy sensor offset
SELECT CASE(iEco)
CASE(FixedEnthalpy, ElectronicEnthalpy, DifferentialDryBulbAndEnthalpy)
IF(Faults(i)%FaultTypeEnum == iFault_EnthalpySensorOffset_OutdoorAir) THEN
! FaultModel:EnthalpySensorOffset:OutdoorAir
OAController(OAControllerNum)%OAEnth = OAController(OAControllerNum)%OAEnth + rOffset
OAController(OAControllerNum)%InletEnth = OAController(OAControllerNum)%InletEnth + rOffset
ENDIF
CASE DEFAULT
END SELECT
! ECONOMIZER - return air dry-bulb temperature sensor offset
SELECT CASE(iEco)
CASE(DifferentialDryBulb, DifferentialDryBulbAndEnthalpy)
IF(Faults(i)%FaultTypeEnum == iFault_TemperatureSensorOffset_ReturnAir) THEN
! FaultModel:TemperatureSensorOffset:ReturnAir
OAController(OAControllerNum)%RetTemp = OAController(OAControllerNum)%RetTemp + rOffset
ENDIF
CASE DEFAULT
END SELECT
! ECONOMIZER - return air enthalpy sensor offset
SELECT CASE(iEco)
CASE(ElectronicEnthalpy, DifferentialDryBulbAndEnthalpy)
IF(Faults(i)%FaultTypeEnum == iFault_EnthalpySensorOffset_ReturnAir) THEN
! FaultModel:EnthalpySensorOffset:ReturnAir
OAController(OAControllerNum)%RetEnth = OAController(OAControllerNum)%RetEnth + rOffset
ENDIF
CASE DEFAULT
END SELECT
ENDIF
ENDDO
ENDIF
IF (ErrorsFound) THEN
CALL ShowFatalError('Error in '//trim(CurrentModuleObjects(CMO_OAController))//'; program terminated')
END IF
RETURN
END SUBROUTINE InitOAController