SUBROUTINE InitLoadBasedControl(UnitarySysNum,AirLoopNum,FirstHVACIteration,OnOffAirFlowRatio,ZoneLoad)
! SUBROUTINE INFORMATION:
! AUTHOR Richard Raustad, FSEC
! DATE WRITTEN February 2013
! RE-ENGINEERED na
! PURPOSE OF THIS SUBROUTINE:
! This subroutine is for initializations of the load controlled Unitary Systems.
! METHODOLOGY EMPLOYED:
! Initialize mass flow rates and speed ratios. Calculate loads and adjust if necessary when using constant fan.
! REFERENCES:
! na
! USE STATEMENTS:
USE DataAirLoop, ONLY: AirLoopControlInfo, AirToZoneNodeInfo
USE Fans, ONLY: GetFanDesignVolumeFlowRate, GetFanSpeedRatioCurveIndex
USE General, ONLY: RoundSigDigits, TrimSigDigits
USE DataHeatBalance, ONLY: Zone
USE DataHeatBalFanSys, ONLY: TempControlType
USE DataAirflowNetwork, ONLY: SimulateAirflowNetwork, AirflowNetworkControlMultizone, AirflowNetworkFanActivated
USE Psychrometrics, ONLY: PsyHFnTdbW
USE ReportSizingManager, ONLY: ReportSizingOutput
USE WaterCoils, ONLY: GetCoilMaxWaterFlowRate, SimulateWaterCoilComponents
USE SteamCoils, ONLY: GetCoilMaxSteamFlowRate, SimulateSteamCoilComponents
USE DataPlant, ONLY: PlantLoop
USE FluidProperties, ONLY: GetDensityGlycol, GetSatDensityRefrig
USE PlantUtilities, ONLY: SetComponentFlowRate, InitComponentNodes
USE DataZoneEnergyDemands, ONLY: ZoneSysEnergyDemand, CurDeadbandOrSetback, SetBack
USE DataZoneControls, ONLY: StageZoneLogic
USE BranchInputManager, ONLY: CheckSystemBranchFlow
IMPLICIT NONE ! Enforce explicit typing of all variables in this routine
! SUBROUTINE ARGUMENT DEFINITIONS:
INTEGER, INTENT (IN) :: UnitarySysNum ! number of the current DX Sys being simulated
INTEGER, INTENT (IN) :: AirLoopNum ! number of the current air loop being simulated
LOGICAL, INTENT (IN) :: FirstHVACIteration
REAL(R64), INTENT (INOUT) :: OnOffAirFlowRatio
REAL(r64), INTENT (INOUT) :: ZoneLoad
! SUBROUTINE PARAMETER DEFINITIONS:
REAL(r64), PARAMETER :: Small5WLoad = 5.0d0
! INTERFACE BLOCK SPECIFICATIONS
! na
! DERIVED TYPE DEFINITIONS
! na
! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
LOGICAL, ALLOCATABLE,SAVE, DIMENSION(:) :: MyEnvrnFlag ! environment flag
LOGICAL, ALLOCATABLE,SAVE, DIMENSION(:) :: MyFanFlag ! used for sizing fan inputs one time
LOGICAL, ALLOCATABLE,SAVE, DIMENSION(:) :: MyCheckFlag ! Used to obtain the zone inlet node number
! in the controlled zone
LOGICAL, ALLOCATABLE,SAVE, DIMENSION(:) :: MyFlowFracFlag ! Used for calculatig flow fraction once
LOGICAL, ALLOCATABLE,SAVE, DIMENSION(:) :: MyStagedFlag ! used for finding on staged thermostat
LOGICAL, SAVE :: MyOneTimeFlag = .TRUE. ! one time allocation flag
LOGICAL, SAVE :: MyAirLoopPass = .TRUE. ! one time allocation flag
INTEGER :: AirLoopPass = 0 ! Number of air loop pass
CHARACTER(len=MaxNameLength) :: FanType ! used in warning messages
CHARACTER(len=MaxNameLength) :: FanName ! used in warning messages
LOGICAL :: ErrFlag ! error flag for mining functions
LOGICAL :: ErrorsFound ! error flag for mining functions
INTEGER :: ZoneInNode ! Zone inlet node number in the controlled zone
REAL(r64) :: MinHumRat ! Minimum humidity ratio for sensible capacity calculation (kg/kg)
REAL(r64) :: DeltaMassRate ! DIFference of mass flow rate between
! inlet node and system outlet node
INTEGER :: i,j,k ! index to get the zone inlet node
REAL(r64) :: MassFlowRate ! mass flow rate to calculate loss
REAL(r64) :: MaxTemp ! Maximum temperature used in latent loss calculation
INTEGER :: EquipNum = 0 ! local DO loop index for zone equipment
INTEGER :: ZoneInSysIndex = 0 ! number of zone inlet nodes counter in an airloop
INTEGER :: NumAirLoopZones = 0 ! number of zone inlet nodes in an air loop
INTEGER :: ZoneInletNodeNum = 0 ! zone inlet nodes node number
LOGICAL :: FlowFracFlagReady = .TRUE. ! one time flag for calculating flow fraction
REAL(r64) :: SumOfMassFlowRateMax = 0.0d0 ! the sum of zone inlet mass flow rates
REAL(r64) :: CntrlZoneTerminalUnitMassFlowRateMax = 0.0d0 ! Maximum mass flow rate through controlled zone
REAL(R64) :: rho
REAL(R64) :: QZnReq
REAL(R64) :: QActual
REAL(R64) :: CoilMaxVolFlowRate
INTEGER :: SteamIndex
REAL(R64) :: SteamDensity
REAL(R64) :: SensOutputOff
REAL(R64) :: LatOutputOff
LOGICAL :: HXUnitOn
IF (MyOneTimeFlag) THEN
! initialize the environment and sizing flags
ALLOCATE(MyEnvrnFlag(NumUnitarySystem))
ALLOCATE(MyFanFlag(NumUnitarySystem))
ALLOCATE(MyCheckFlag(NumUnitarySystem))
ALLOCATE(MyFlowFracFlag(NumUnitarySystem))
ALLOCATE(MyStagedFlag(NumUnitarySystem))
MyEnvrnFlag = .TRUE.
MyFanFlag = .TRUE.
MyCheckFlag = .TRUE.
MyFlowFracFlag = .TRUE.
MyOneTimeFlag = .FALSE.
MyStagedFlag = .TRUE.
END IF
! do the Begin Environment initializations
IF (BeginEnvrnFlag .and. MyEnvrnFlag(UnitarySysNum)) THEN
! set fluid-side hardware limits
IF(UnitarySystem(UnitarySysNum)%HeatCoilFluidInletNode .GT. 0)THEN
IF(UnitarySystem(UnitarySysNum)%MaxHeatCoilFluidFlow .EQ. Autosize)THEN
! IF water coil max water flow rate is autosized, simulate once in order to mine max flow rate
IF(UnitarySystem(UnitarySysNum)%HeatingCoilType_Num == Coil_HeatingWater) THEN
CALL SimulateWaterCoilComponents(UnitarySystem(UnitarySysNum)%HeatingCoilName,FirstHVACIteration, &
UnitarySystem(UnitarySysNum)%HeatingCoilIndex)
CoilMaxVolFlowRate = GetCoilMaxWaterFlowRate('Coil:Heating:Water', &
UnitarySystem(UnitarySysNum)%HeatingCoilName,ErrorsFound)
IF(CoilMaxVolFlowRate .NE. Autosize) THEN
rho = GetDensityGlycol(PlantLoop(UnitarySystem(UnitarySysNum)%HeatCoilLoopNum)%fluidName, &
InitConvTemp, &
PlantLoop(UnitarySystem(UnitarySysNum)%HeatCoilLoopNum)%fluidIndex, &
'InitUnitarySystems')
UnitarySystem(UnitarySysNum)%MaxHeatCoilFluidFlow = CoilMaxVolFlowRate * rho
END IF
END IF
! IF steam coil max steam flow rate is autosized, simulate once in order to mine max flow rate
IF(UnitarySystem(UnitarySysNum)%HeatingCoilType_Num == Coil_HeatingSteam) THEN
CALL SimulateSteamCoilComponents(UnitarySystem(UnitarySysNum)%HeatingCoilName, &
FirstHVACIteration, &
1.0d0, & !QCoilReq, simulate any load > 0 to get max capacity
UnitarySystem(UnitarySysNum)%HeatingCoilIndex, QActual)
CoilMaxVolFlowRate = GetCoilMaxSteamFlowRate(UnitarySystem(UnitarySysNum)%HeatingCoilIndex,ErrorsFound)
IF(CoilMaxVolFlowRate .NE. Autosize) THEN
SteamIndex = 0 ! Function GetSatDensityRefrig will look up steam index if 0 is passed
SteamDensity=GetSatDensityRefrig('STEAM',TempSteamIn,1.0d0,SteamIndex,'InitUnitarySystems')
UnitarySystem(UnitarySysNum)%MaxHeatCoilFluidFlow = CoilMaxVolFlowRate * SteamDensity
END IF
END IF
END IF
CALL InitComponentNodes(0.0d0, UnitarySystem(UnitarySysNum)%MaxHeatCoilFluidFlow, &
UnitarySystem(UnitarySysNum)%HeatCoilFluidInletNode, &
UnitarySystem(UnitarySysNum)%HeatCoilFluidOutletNodeNum, &
UnitarySystem(UnitarySysNum)%HeatCoilLoopNum, &
UnitarySystem(UnitarySysNum)%HeatCoilLoopSide, &
UnitarySystem(UnitarySysNum)%HeatCoilBranchNum, &
UnitarySystem(UnitarySysNum)%HeatCoilCompNum )
END IF
IF(UnitarySystem(UnitarySysNum)%SuppCoilFluidInletNode .GT. 0)THEN
IF(UnitarySystem(UnitarySysNum)%MaxSuppCoilFluidFlow .EQ. Autosize)THEN
IF(UnitarySystem(UnitarySysNum)%SuppHeatCoilType_Num == Coil_HeatingWater) THEN
! IF water coil max water flow rate is autosized, simulate once in order to mine max flow rate
CALL SimulateWaterCoilComponents(UnitarySystem(UnitarySysNum)%SuppHeatCoilName,FirstHVACIteration, &
UnitarySystem(UnitarySysNum)%SuppHeatCoilIndex)
CoilMaxVolFlowRate = GetCoilMaxWaterFlowRate('Coil:Heating:Water', &
UnitarySystem(UnitarySysNum)%SuppHeatCoilName,ErrorsFound)
IF(CoilMaxVolFlowRate .NE. Autosize) THEN
rho = GetDensityGlycol(PlantLoop(UnitarySystem(UnitarySysNum)%SuppCoilLoopNum)%fluidName, &
InitConvTemp, &
PlantLoop(UnitarySystem(UnitarySysNum)%SuppCoilLoopNum)%fluidIndex, &
'InitUnitarySystems')
UnitarySystem(UnitarySysNum)%MaxSuppCoilFluidFlow = CoilMaxVolFlowRate * rho
END IF
END IF
IF(UnitarySystem(UnitarySysNum)%SuppHeatCoilType_Num == Coil_HeatingSteam) THEN
CALL SimulateSteamCoilComponents(UnitarySystem(UnitarySysNum)%SuppHeatCoilName, &
FirstHVACIteration, &
1.0d0, & !QCoilReq, simulate any load > 0 to get max capacity
UnitarySystem(UnitarySysNum)%SuppHeatCoilIndex, QActual)
CoilMaxVolFlowRate = GetCoilMaxSteamFlowRate(UnitarySystem(UnitarySysNum)%SuppHeatCoilIndex,ErrorsFound)
IF(CoilMaxVolFlowRate .NE. Autosize) THEN
SteamIndex = 0 ! Function GetSatDensityRefrig will look up steam index if 0 is passed
SteamDensity=GetSatDensityRefrig('STEAM',TempSteamIn,1.0d0,SteamIndex,'InitUnitarySystems')
UnitarySystem(UnitarySysNum)%MaxSuppCoilFluidFlow = CoilMaxVolFlowRate * SteamDensity
END IF
END IF
CALL InitComponentNodes(0.0d0, UnitarySystem(UnitarySysNum)%MaxSuppCoilFluidFlow, &
UnitarySystem(UnitarySysNum)%SuppCoilFluidInletNode, &
UnitarySystem(UnitarySysNum)%SuppCoilFluidOutletNodeNum, &
UnitarySystem(UnitarySysNum)%SuppCoilLoopNum, &
UnitarySystem(UnitarySysNum)%SuppCoilLoopSide, &
UnitarySystem(UnitarySysNum)%SuppCoilBranchNum, &
UnitarySystem(UnitarySysNum)%SuppCoilCompNum )
END IF
END IF
MyEnvrnFlag(UnitarySysNum) = .FALSE.
END IF
IF (.not. BeginEnvrnFlag) THEN
MyEnvrnFlag(UnitarySysNum) = .TRUE.
END IF
IF(MyFanFlag(UnitarySysNum))THEN
IF(UnitarySystem(UnitarySysNum)%ActualFanVolFlowRate /= Autosize)THEN
IF(UnitarySystem(UnitarySysNum)%ActualFanVolFlowRate .GT. 0.0d0)THEN
UnitarySystem(UnitarySysNum)%HeatingFanSpeedRatio = &
UnitarySystem(UnitarySysNum)%MaxHeatAirVolFlow/UnitarySystem(UnitarySysNum)%ActualFanVolFlowRate
UnitarySystem(UnitarySysNum)%CoolingFanSpeedRatio = &
UnitarySystem(UnitarySysNum)%MaxCoolAirVolFlow/UnitarySystem(UnitarySysNum)%ActualFanVolFlowRate
UnitarySystem(UnitarySysNum)%NoHeatCoolSpeedRatio = &
UnitarySystem(UnitarySysNum)%MaxNoCoolHeatAirVolFlow/UnitarySystem(UnitarySysNum)%ActualFanVolFlowRate
IF(UnitarySystem(UnitarySysNum)%FanExists)THEN
IF(GetFanSpeedRatioCurveIndex(FanType,FanName,UnitarySystem(UnitarySysNum)%FanIndex) .GT. 0)THEN
IF(UnitarySystem(UnitarySysNum)%ActualFanVolFlowRate .EQ. UnitarySystem(UnitarySysNum)%MaxHeatAirVolFlow .AND. &
UnitarySystem(UnitarySysNum)%ActualFanVolFlowRate .EQ. UnitarySystem(UnitarySysNum)%MaxCoolAirVolFlow .AND. &
UnitarySystem(UnitarySysNum)%ActualFanVolFlowRate .EQ. UnitarySystem(UnitarySysNum)%MaxNoCoolHeatAirVolFlow)THEN
CALL ShowWarningError(TRIM(UnitarySystem(UnitarySysNum)%UnitarySystemType)// &
' "'//TRIM(UnitarySystem(UnitarySysNum)%Name)//'"')
CALL ShowContinueError('...For fan type and name = '//TRIM(FanType)//' "'//TRIM(FanName)//'"')
CALL ShowContinueError('...Fan power ratio function of speed ratio curve has no impact IF fan volumetric '// &
'flow rate is the same as the unitary system volumetric flow rate.')
CALL ShowContinueError('...Fan volumetric flow rate = '// &
TRIM(RoundSigDigits(UnitarySystem(UnitarySysNum)%ActualFanVolFlowRate,5))//' m3/s.')
CALL ShowContinueError('...Unitary system volumetric flow rate = '// &
TRIM(RoundSigDigits(UnitarySystem(UnitarySysNum)%MaxHeatAirVolFlow,5))//' m3/s.')
END IF
END IF
ELSE
CALL CheckSystemBranchFlow(TRIM(UnitarySystem(UnitarySysNum)%UnitarySystemType),UnitarySystem(UnitarySysNum)%Name, &
UnitarySystem(UnitarySysNum)%ActualFanVolFlowRate,0.0d0,ErrFlag)
END IF
END IF
MyFanFlag(UnitarySysNum) = .FALSE.
ELSE
IF(UnitarySystem(UnitarySysNum)%FanExists)THEN
UnitarySystem(UnitarySysNum)%ActualFanVolFlowRate = &
GetFanDesignVolumeFlowRate(Blank,Blank,ErrFlag,UnitarySystem(UnitarySysNum)%FanIndex)
ELSE
CALL CheckSystemBranchFlow(TRIM(UnitarySystem(UnitarySysNum)%UnitarySystemType),UnitarySystem(UnitarySysNum)%Name, &
UnitarySystem(UnitarySysNum)%ActualFanVolFlowRate,0.0d0,ErrFlag)
END IF
END IF
END IF
! Get the zone inlet node
IF (ALLOCATED(ZoneEquipConfig) .AND. MyCheckFlag(UnitarySysNum)) THEN
DO i=1,NumOfZones
IF(UnitarySystem(UnitarySysNum)%AirLoopEquipment)THEN
IF (AirLoopNum .NE. ZoneEquipConfig(i)%AirLoopNum) CYCLE
IF (UnitarySystem(UnitarySysNum)%ControlZoneNum .EQ. ZoneEquipConfig(i)%ActualZoneNum) THEN
DO j=1, ZoneEquipConfig(i)%NumInletNodes
IF (UnitarySystem(UnitarySysNum)%ZoneInletNode .EQ. 0) THEN
DO k=1,ZoneEquipConfig(i)%NumInletNodes
IF (ZoneEquipConfig(i)%InletNode(j) .EQ. ZoneEquipConfig(i)%AirDistUnitCool(k)%OutNode) THEN
UnitarySystem(UnitarySysNum)%ZoneInletNode = ZoneEquipConfig(i)%InletNode(j)
EXIT
ELSEIF (ZoneEquipConfig(i)%InletNode(j) .EQ. ZoneEquipConfig(i)%AirDistUnitHeat(k)%OutNode) THEN
UnitarySystem(UnitarySysNum)%ZoneInletNode = ZoneEquipConfig(i)%InletNode(j)
EXIT
END IF
END DO
END IF
END DO
!setup unitary system zone equipment sequence information based on finding an air terminal
IF (ZoneEquipConfig(i)%EquipListIndex > 0) THEN
DO EquipNum = 1, ZoneEquipList(ZoneEquipConfig(i)%EquipListIndex)%NumOfEquipTypes
IF ((ZoneEquipList(ZoneEquipConfig(i)%EquipListIndex)%EquipType_Num(EquipNum) == AirDistUnit_Num) &
.OR. (ZoneEquipList(ZoneEquipConfig(i)%EquipListIndex)%EquipType_Num(EquipNum) == DirectAir_Num) ) THEN
UnitarySystem(UnitarySysNum)%ZoneSequenceCoolingNum = &
ZoneEquipList(ZoneEquipConfig(i)%EquipListIndex)%CoolingPriority(EquipNum)
UnitarySystem(UnitarySysNum)%ZoneSequenceHeatingNum = &
ZoneEquipList(ZoneEquipConfig(i)%EquipListIndex)%HeatingPriority(EquipNum)
END IF
END DO
END IF
END IF
END IF
END DO
MyCheckFlag(UnitarySysNum) = .FALSE.
IF (UnitarySystem(UnitarySysNum)%ZoneInletNode .EQ. 0) THEN
CALL ShowSevereError(TRIM(UnitarySystem(UnitarySysNum)%UnitarySystemType)//' "'//TRIM(UnitarySystem(UnitarySysNum)%Name)// &
'": The zone inlet node in the controlled zone (' &
//Trim(Zone(UnitarySystem(UnitarySysNum)%ControlZoneNum)%Name) //') is not found.')
CALL ShowFatalError('Subroutine InitLoadBasedControl: '//'Errors found in getting '// &
TRIM(UnitarySystem(UnitarySysNum)%UnitarySystemType)//' input. '//'Preceding condition(s) causes termination.')
END IF
END IF
! Find the number of zones (zone Inlet Nodes) attached to an air loop from the air loop number
IF(MyFlowFracFlag(UnitarySysNum))THEN
IF(UnitarySystem(UnitarySysNum)%AirLoopEquipment)THEN
IF(ALLOCATED(AirToZoneNodeInfo))NumAirLoopZones = &
AirToZoneNodeInfo(AirLoopNum)%NumZonesCooled + AirToZoneNodeInfo(AirLoopNum)%NumZonesHeated
IF (ALLOCATED(AirToZoneNodeInfo) .AND. MyFlowFracFlag(UnitarySysNum)) THEN
FlowFracFlagReady = .TRUE.
ZonesLoop: DO ZoneInSysIndex = 1, NumAirLoopZones
! zone inlet nodes for cooling
IF (AirToZoneNodeInfo(AirLoopNum)%NumZonesCooled > 0) THEN
IF( AirToZoneNodeInfo(AirLoopNum)%TermUnitCoolInletNodes(ZoneInSysIndex) == -999 )THEN
! the data structure for the zones inlet nodes has not been filled
FlowFracFlagReady = .FALSE.
END IF
END IF
! zone inlet nodes for heating
IF (AirToZoneNodeInfo(AirLoopNum)%NumZonesHeated > 0) THEN
IF( AirToZoneNodeInfo(AirLoopNum)%TermUnitHeatInletNodes(ZoneInSysIndex) == -999 ) THEN
! the data structure for the zones inlet nodes has not been filled
FlowFracFlagReady = .FALSE.
END IF
END IF
END DO ZonesLoop
END IF
IF (ALLOCATED(AirToZoneNodeInfo) .AND. FlowFracFlagReady ) THEN
SumOfMassFlowRateMax = 0.0d0 ! initialize the sum of the maximum flows
DO ZoneInSysIndex = 1, NumAirLoopZones
ZoneInletNodeNum = AirToZoneNodeInfo(AirLoopNum)%TermUnitCoolInletNodes(ZoneInSysIndex)
SumOfMassFlowRateMax = SumOfMassFlowRateMax + Node(ZoneInletNodeNum)%MassFlowRateMax
IF(AirToZoneNodeInfo(AirLoopNum)%CoolCtrlZoneNums(ZoneInSysIndex) == UnitarySystem(UnitarySysNum)%ControlZoneNum )THEN
CntrlZoneTerminalUnitMassFlowRateMax = Node(ZoneInletNodeNum)%MassFlowRateMax
END IF
END DO
IF (SumOfMassFlowRateMax /= 0.0d0 .AND. MyFlowFracFlag(UnitarySysNum)) THEN
IF (CntrlZoneTerminalUnitMassFlowRateMax >= SmallAirVolFlow ) THEN
UnitarySystem(UnitarySysNum)%ControlZoneMassFlowFrac = CntrlZoneTerminalUnitMassFlowRateMax/SumOfMassFlowRateMax
ELSE
CALL ShowSevereError(TRIM(UnitarySystem(UnitarySysNum)%UnitarySystemType)//' = '// &
TRIM(UnitarySystem(UnitarySysNum)%Name))
CALL ShowContinueError(' The Fraction of Supply Air Flow That Goes Through the Controlling Zone is set to 1.')
END IF
CALL ReportSizingOutput(UnitarySystem(UnitarySysNum)%UnitarySystemType,UnitarySystem(UnitarySysNum)%Name, &
'Fraction of Supply Air Flow That Goes Through the Controlling Zone', &
UnitarySystem(UnitarySysNum)%ControlZoneMassFlowFrac)
MyFlowFracFlag(UnitarySysNum) = .FALSE.
END IF
END IF
ELSE
UnitarySystem(UnitarySysNum)%ControlZoneMassFlowFrac = 1.0d0
END IF
END IF ! IF(MyFlowFracFlag(UnitarySysNum))THEN
! What type of logic is this? Is the point to go through the main IF once? or every other time?
IF (BeginEnvrnFlag .and. MyAirLoopPass) THEN
AirLoopPass = 0
MyAirLoopPass = .FALSE.
END IF
IF (.not. BeginEnvrnFlag) THEN
MyAirLoopPass = .TRUE.
END IF
AirLoopPass = AirLoopPass + 1
IF (AirLoopPass > 2) AirLoopPass = 1
! reset duct losses from previous iteration
IF (FirstHVACIteration) THEN
UnitarySystem(UnitarySysNum)%SenLoadLoss = 0.0d0
UnitarySystem(UnitarySysNum)%LatLoadLoss = 0.0d0
END IF
! Calcuate air distribution losses
! IF (.NOT. FirstHVACIteration .AND. AirLoopPass .EQ. 1 .AND. AirflowNetworkFanActivated) THEN
IF (.NOT. FirstHVACIteration .AND. AirflowNetworkFanActivated) THEN
ZoneInNode = UnitarySystem(UnitarySysNum)%ZoneInletNode
MinHumRat = Node(ZoneInNode)%HumRat
MassFlowRate = Node(ZoneInNode)%MassFlowrate/UnitarySystem(UnitarySysNum)%ControlZoneMassFlowFrac
IF(Node(UnitarySystem(UnitarySysNum)%UnitarySystemOutletNodeNum)%Temp .LT. &
Node(UnitarySystem(UnitarySysNum)%NodeNumofControlledZone)%Temp ) &
MinHumRat = Node(UnitarySystem(UnitarySysNum)%UnitarySystemOutletNodeNum)%HumRat
IF (SimulateAirflowNetwork > AirflowNetworkControlMultizone) THEN
DeltaMassRate = Node(UnitarySystem(UnitarySysNum)%UnitarySystemOutletNodeNum)%MassFlowrate - &
Node(ZoneInNode)%MassFlowrate/UnitarySystem(UnitarySysNum)%ControlZoneMassFlowFrac
IF (DeltaMassRate .LT. 0.0d0) DeltaMassRate = 0.0d0
ELSE
MassFlowRate = Node(UnitarySystem(UnitarySysNum)%UnitarySystemOutletNodeNum)%MassFlowrate
DeltaMassRate = 0.0d0
END IF
UnitarySystem(UnitarySysNum)%SenLoadLoss = &
MassFlowRate * (PsyHFnTdbW(Node(UnitarySystem(UnitarySysNum)%UnitarySystemOutletNodeNum)%Temp,MinHumRat)- &
PsyHFnTdbW(Node(ZoneInNode)%Temp,MinHumRat)) + DeltaMassRate * &
(PsyHFnTdbW(Node(UnitarySystem(UnitarySysNum)%UnitarySystemOutletNodeNum)%Temp,MinHumRat) - &
PsyHFnTdbW(Node(UnitarySystem(UnitarySysNum)%NodeNumofControlledZone)%Temp,MinHumRat))
IF (ABS(UnitarySystem(UnitarySysNum)%SensibleLoadMet) > 0.0d0) THEN
IF (ABS(UnitarySystem(UnitarySysNum)%SenLoadLoss/UnitarySystem(UnitarySysNum)%SensibleLoadMet) < 0.001d0) &
UnitarySystem(UnitarySysNum)%SenLoadLoss = 0.0d0
END IF
IF(UnitarySystem(UnitarySysNum)%Humidistat)THEN
MaxTemp = Node(UnitarySystem(UnitarySysNum)%NodeNumofControlledZone)%Temp
UnitarySystem(UnitarySysNum)%LatLoadLoss = &
MassFlowRate*(PsyHFnTdbW(MaxTemp,Node(UnitarySystem(UnitarySysNum)%UnitarySystemOutletNodeNum)%HumRat)- &
PsyHFnTdbW(MaxTemp,Node(ZoneInNode)%HumRat)) + DeltaMassRate * &
(PsyHFnTdbW(MaxTemp,Node(UnitarySystem(UnitarySysNum)%UnitarySystemOutletNodeNum)%HumRat) - &
PsyHFnTdbW(MaxTemp,Node(UnitarySystem(UnitarySysNum)%NodeNumofControlledZone)%HumRat))
IF (ABS(UnitarySystem(UnitarySysNum)%LatentLoadMet) > 0.0d0) THEN
IF (ABS(UnitarySystem(UnitarySysNum)%LatLoadLoss/UnitarySystem(UnitarySysNum)%LatentLoadMet) < 0.001d0) &
UnitarySystem(UnitarySysNum)%LatLoadLoss = 0.0d0
END IF
END IF
END IF
IF (UnitarySystem(UnitarySysNum)%FanOpModeSchedPtr .GT. 0) THEN
IF (GetCurrentScheduleValue(UnitarySystem(UnitarySysNum)%FanOpModeSchedPtr) .EQ. 0.0d0) THEN
UnitarySystem(UnitarySysNum)%FanOpMode = CycFanCycCoil
ELSE
UnitarySystem(UnitarySysNum)%FanOpMode = ContFanCycCoil
OnOffFanPartLoadFraction = 1.0d0
END IF
END IF
! OpMode = UnitarySystem(UnitarySysNum)%FanOpMode
IF(ALLOCATED(AirLoopControlInfo) .AND. UnitarySystem(UnitarySysNum)%AirLoopEquipment)THEN
EconomizerFlag = AirLoopControlInfo(AirLoopNum)%EconoActive
ELSE
EconomizerFlag = .FALSE.
END IF
! System load calculation for cycling fan systems
IF(UnitarySystem(UnitarySysNum)%ControlZoneMassFlowFrac .GT. 0.0d0)THEN
QZnReq = ZoneLoad/UnitarySystem(UnitarySysNum)%ControlZoneMassFlowFrac
MoistureLoad = MoistureLoad/UnitarySystem(UnitarySysNum)%ControlZoneMassFlowFrac
QToCoolSetPt=QToCoolSetPt/UnitarySystem(UnitarySysNum)%ControlZoneMassFlowFrac
QToHeatSetPt=QToHeatSetPt/UnitarySystem(UnitarySysNum)%ControlZoneMassFlowFrac
ZoneLoad = QZnReq
ELSE
QZnReq = ZoneLoad
UnitarySystem(UnitarySysNum)%ControlZoneMassFlowFrac = 1.0d0
END IF
CoolingLoad = .FALSE.
HeatingLoad = .FALSE.
IF(QZnReq .GT. Small5WLoad/UnitarySystem(UnitarySysNum)%ControlZoneMassFlowFrac .AND. &
.NOT. CurDeadbandOrSetback(UnitarySystem(UnitarySysNum)%ControlZoneNum))THEN
IF(TempControlType(UnitarySystem(UnitarySysNum)%ControlZoneNum) .NE. SingleCoolingSetPoint)THEN
HeatingLoad = .TRUE.
END IF
ELSEIF(QZnReq .LT. -Small5WLoad/UnitarySystem(UnitarySysNum)%ControlZoneMassFlowFrac .AND. &
.NOT. CurDeadbandOrSetback(UnitarySystem(UnitarySysNum)%ControlZoneNum))THEN
IF(TempControlType(UnitarySystem(UnitarySysNum)%ControlZoneNum) .NE. SingleHeatingSetPoint)THEN
CoolingLoad = .TRUE.
END IF
END IF
! System load calculation for constant fan systems
IF(UnitarySystem(UnitarySysNum)%FanOpMode == ContFanCycCoil)THEN
HXUnitOn = .FALSE.
CALL CalcUnitarySystemToLoad(UnitarySysNum,FirstHVACIteration,0.0d0,0.0d0, &
OnOffAirFlowRatio,SensOutputOff,LatOutputOff,HXUnitOn)
SELECT CASE(TempControlType(UnitarySystem(UnitarySysNum)%ControlZoneNum))
CASE(SingleHeatingSetPoint)
CoolingLoad = .FALSE.
! No heating load and constant fan pushes zone below heating set point
IF(SensOutputOff .LT. 0.0d0 .AND. QToHeatSetPt .LT. 0.0d0 .AND. &
SensOutputOff-QToHeatSetPt .LT. -SmallLoad)THEN
HeatingLoad = .TRUE.
CoolingLoad = .FALSE.
ZoneLoad = QToHeatSetPt
END IF
CASE(SingleCoolingSetPoint)
HeatingLoad = .FALSE.
! No heating load and constant fan pushes zone above cooling set point
IF(SensOutputOff .GT. 0.0d0 .AND. QToCoolSetPt .GT. 0.0d0 .AND. &
SensOutputOff-QToCoolSetPt .GT. SmallLoad)THEN
HeatingLoad = .FALSE.
CoolingLoad = .TRUE.
ZoneLoad = QToCoolSetPt
END IF
CASE(SingleHeatCoolSetPoint)
! zone temp above cooling and heating set point temps
IF(QToHeatSetPt .LT. 0.0d0 .AND. QToCoolSetPt .LT. 0.0d0)THEN
! zone pushed below heating set point
IF(SensOutputOff .LT. 0.0d0 .AND. &
QToHeatSetPt-SensOutputOff .GT. SmallLoad)THEN
HeatingLoad = .TRUE.
CoolingLoad = .FALSE.
ZoneLoad = QToHeatSetPt
END IF
! zone temp below heating set point temp
ELSEIF(QToHeatSetPt .GT. 0.0d0 .AND. QToCoolSetPt .GT. 0.0d0)THEN
! zone pushed above cooling set point
IF(SensOutputOff .GT. 0.0d0 .AND. &
QToCoolSetPt-SensOutputOff .GT. SmallLoad)THEN
HeatingLoad = .FALSE.
CoolingLoad = .TRUE.
ZoneLoad = QToCoolSetPt
END IF
END IF
CASE(DualSetPointWithDeadBand)
! zone temp above cooling and heating set point temps
IF(QToHeatSetPt .LT. 0.0d0 .AND. QToCoolSetPt .LT. 0.0d0)THEN
! zone pushed into deadband
IF(SensOutputOff .LT. 0.0d0 .AND. &
QToCoolSetPt-SensOutputOff .GT. SmallLoad)THEN
HeatingLoad = .FALSE.
CoolingLoad = .FALSE.
ZoneLoad = 0.0d0
END IF
! zone pushed below heating set point
IF(SensOutputOff .LT. 0.0d0 .AND. &
QToHeatSetPt-SensOutputOff .GT. SmallLoad)THEN
HeatingLoad = .TRUE.
CoolingLoad = .FALSE.
ZoneLoad = QToHeatSetPt
END IF
! zone temp below heating set point temp
ELSEIF(QToHeatSetPt .GT. 0.0d0 .AND. QToCoolSetPt .GT. 0.0d0)THEN
! zone pushed into deadband
IF(SensOutputOff .GT. 0.0d0 .AND. &
SensOutputOff-QToHeatSetPt .GT. SmallLoad)THEN
HeatingLoad = .FALSE.
CoolingLoad = .FALSE.
ZoneLoad = 0.0d0
END IF
! zone pushed above cooling set point
IF(SensOutputOff .GT. 0.0d0 .AND. &
SensOutputOff-QToCoolSetPt .GT. SmallLoad)THEN
HeatingLoad = .FALSE.
CoolingLoad = .TRUE.
ZoneLoad = QToCoolSetPt
END IF
! zone temp between set point temps
ELSEIF(QToHeatSetPt .LT. 0.0d0 .AND. QToCoolSetPt .GT. 0.0d0)THEN
! zone pushed below heating set point
IF(SensOutputOff .LT. 0.0d0 .AND. &
SensOutputOff-QToHeatSetPt .LT. -SmallLoad)THEN
HeatingLoad = .TRUE.
CoolingLoad = .FALSE.
ZoneLoad = QToHeatSetPt
! zone pushed above cooling set point
ELSEIF(SensOutputOff .GT. 0.0d0 .AND. &
SensOutputOff-QToCoolSetPt .GT. SmallLoad)THEN
HeatingLoad = .FALSE.
CoolingLoad = .TRUE.
ZoneLoad = QToCoolSetPt
END IF
END IF
CASE DEFAULT
END SELECT
! IF small loads to meet, just shut down unit
IF(ABS(ZoneLoad) < Small5WLoad)THEN
ZoneLoad = 0.0d0
CoolingLoad = .FALSE.
HeatingLoad = .FALSE.
END IF
END IF
! Determine the staged status
IF (ALLOCATED(StageZoneLogic) .AND. UnitarySystem(UnitarySysNum)%DesignSpecMSHPIndex > 0) THEN
IF (StageZoneLogic(UnitarySystem(UnitarySysNum)%ControlZoneNum)) THEN
UnitarySystem(UnitarySysNum)%Staged = .TRUE.
UnitarySystem(UnitarySysNum)%StageNum = ZoneSysEnergyDemand(UnitarySystem(UnitarySysNum)%ControlZoneNum)%StageNum
ELSE
IF (MyStagedFlag(UnitarySysNum)) THEN
CALL ShowWarningError('ZoneControl:Thermostat:StagedDualSetpoint is found, but is not applied to '// &
'this AirLoopHVAC:UnitarySystem object with UnitarySystemPerformance:HeatPump:Multispeed type = ')
CALL ShowContinueError(Trim(UnitarySystem(UnitarySysNum)%Name) //'. Please make correction. Simulation continues...')
MyStagedFlag(UnitarySysNum) = .FALSE.
END IF
END IF
END IF
! Staged control
IF (UnitarySystem(UnitarySysNum)%Staged) THEN
IF (UnitarySystem(UnitarySysNum)%StageNum == 0) THEN
HeatingLoad = .FALSE.
CoolingLoad = .FALSE.
QZnReq = 0.0d0
ELSE
QZnReq = ZoneSysEnergyDemand(UnitarySystem(UnitarySysNum)%ControlZoneNum)%RemainingOutputRequired/ &
UnitarySystem(UnitarySysNum)%ControlZoneMassFlowFrac
IF (UnitarySystem(UnitarySysNum)%StageNum > 0) THEN
HeatingLoad = .TRUE.
CoolingLoad = .FALSE.
ELSE
HeatingLoad = .FALSE.
CoolingLoad = .TRUE.
END IF
END IF
END IF
IF(UnitarySystem(UnitarySysNum)%DehumidControlType_Num == DehumidControl_MultiMode) THEN
IF(HeatingLoad)MoistureLoad = 0.0d0
END IF
! Check load control
IF(UnitarySystem(UnitarySysNum)%RunOnLatentOnlyWithSensible .AND. ZoneLoad == 0.0d0)MoistureLoad = 0.0d0
IF(.NOT. UnitarySystem(UnitarySysNum)%RunOnSensibleLoad)THEN
ZoneLoad = 0.0d0
CoolingLoad = .FALSE.
HeatingLoad = .FALSE.
END IF
IF(.NOT. UnitarySystem(UnitarySysNum)%RunOnLatentLoad)MoistureLoad = 0.0d0
! Testing heat pump air to air with RH control with CoolReheat dehumidifaction control showed that when there was heating
! and moisture load, the cooling coil was turning on to meet the moisture load and reheat was then turning on to meet both
! heating load and excess cooling load caused by cooling coil. Adding the logic below caused the zone temperature,
! relative humidity, cooling/heating rate to line up for both the orignal and new file with unitary system object.
IF(UnitarySystem(UnitarySysNum)%SuppCoilExists)THEN
IF(UnitarySystem(UnitarySysNum)%DehumidControlType_Num == DehumidControl_CoolReheat) THEN
IF (MoistureLoad < 0.0d0 .AND. UnitarySystem(UnitarySysNum)%HeatPump) THEN
HeatingLoad = .FALSE.
CoolingLoad = .TRUE.
END IF
END IF
END IF
RETURN
END SUBROUTINE InitLoadBasedControl