SUBROUTINE CalcCBVAV(CBVAVNum,FirstHVACIteration,PartLoadFrac,LoadMet,QZnReq,OnOffAirFlowRatio, HXUnitOn)
! SUBROUTINE INFORMATION:
! AUTHOR Richard Raustad
! DATE WRITTEN July 2006
! MODIFIED na
! RE-ENGINEERED na
! PURPOSE OF THIS SUBROUTINE:
! Simulate the components making up the changeover-bypass VAV system.
! METHODOLOGY EMPLOYED:
! Simulates the unit components sequentially in the air flow direction.
! REFERENCES:
! na
! USE STATEMENTS:
USE Fans, ONLY: SimulateFanComponents
USE DXCoils, ONLY: SimDXCoil, SimDXCoilMultiMode
USE General, ONLY: SolveRegulaFalsi, RoundSigDigits
USE MixedAir, ONLY: SimOAMixer
USE DataHVACGlobals, ONLY: SmallTempDiff
USE Psychrometrics, ONLY: PsyHFnTdbW, PsyCpAirFnWTdb, PsyTdpFnWPb
USE HVACHXAssistedCoolingCoil, ONLY: SimHXAssistedCoolingCoil
IMPLICIT NONE ! Enforce explicit typing of all variables in this routine
! SUBROUTINE ARGUMENT DEFINITIONS:
INTEGER, INTENT (IN) :: CBVAVNum ! Unit index in fan coil array
LOGICAL, INTENT (IN) :: FirstHVACIteration ! Flag for 1st HVAC iteration
REAL(r64) , INTENT (INOUT) :: PartLoadFrac ! Compressor part load fraction
REAL(r64) , INTENT (OUT) :: LoadMet ! Load met by unit (W)
REAL(r64) , INTENT (INOUT) :: QZnReq ! Zone load (W)
REAL(r64) , INTENT (INOUT) :: OnOffAirFlowRatio ! Ratio of compressor ON airflow to AVERAGE airflow over timestep
LOGICAL, INTENT (IN) :: HXUnitOn ! flag to enable heat exchanger
! SUBROUTINE PARAMETER DEFINITIONS:
INTEGER, PARAMETER :: MaxIte = 500 ! Maximum number of iterations
! INTERFACE BLOCK SPECIFICATIONS
! na
! DERIVED TYPE DEFINITIONS
! na
! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
INTEGER :: OutletNode ! CBVAV air outlet node
INTEGER :: InletNode ! CBVAV air inlet node
REAL(r64) :: MinHumRat ! Minimum humidity ratio for sensible capacity calculation (kg/kg)
REAL(r64) :: Par(6) ! RegulaFalsi parameters
INTEGER :: SolFla ! Flag of RegulaFalsi solver
REAL(r64) :: QHeater ! Load to be met by heater [W]
REAL(r64) :: QHeaterActual ! actual heating load met [W]
REAL(r64) :: CpAir ! Specific heat of air [J/kg-K]
INTEGER :: MixerOutsideAirNode ! Outside air node number in OA mixer
INTEGER :: MixerReliefAirNode ! Relief air node number in OA mixer
INTEGER :: DehumidMode ! Dehumidification mode (0=normal, 1=enhanced)
REAL(r64) :: ApproachTemp
REAL(r64) :: DesiredDewPoint
REAL(r64) :: OutdoorDryBulbTemp ! Dry-bulb temperature at outdoor condenser
REAL(r64) :: OutdoorBaroPress ! Barometric pressure at outdoor condenser
! FLOW
OutletNode = CBVAV(CBVAVNum)%AirOutNode
InletNode = CBVAV(CBVAVNum)%AirInNode
MixerOutsideAirNode = CBVAV(CBVAVNum)%MixerOutsideAirNode
MixerReliefAirNode = CBVAV(CBVAVNum)%MixerReliefAirNode
IF (CBVAV(CBVAVNum)%CondenserNodeNum > 0) THEN
OutdoorDryBulbTemp = Node(CBVAV(CBVAVNum)%CondenserNodeNum)%Temp
OutdoorBaroPress = Node(CBVAV(CBVAVNum)%CondenserNodeNum)%Press
ELSE
OutdoorDryBulbTemp = OutDryBulbTemp
OutdoorBaroPress = OutBaroPress
ENDIF
SaveCompressorPLR = 0.0d0
! Bypass excess system air through bypass duct and calculate new mixed air conditions at OA mixer inlet node
Node(CBVAV(CBVAVNum)%MixerInletAirNode)%Temp = (1.0d0 - ByPassDuctFlowFraction) * Node(InletNode)%Temp + &
ByPassDuctFlowFraction * Node(OutletNode)%Temp
Node(CBVAV(CBVAVNum)%MixerInletAirNode)%HumRat = (1.0d0 - ByPassDuctFlowFraction) * Node(InletNode)%HumRat + &
ByPassDuctFlowFraction * Node(OutletNode)%HumRat
Node(CBVAV(CBVAVNum)%MixerInletAirNode)%Enthalpy = PsyHFnTdbW(Node(CBVAV(CBVAVNum)%MixerInletAirNode)%Temp, &
Node(CBVAV(CBVAVNum)%MixerInletAirNode)%HumRat)
CALL SimOAMixer(CBVAV(CBVAVNum)%OAMixName,FirstHVACIteration,CBVAV(CBVAVNum)%OAMixIndex)
IF (CBVAV(CBVAVNum)%FanPlace .EQ. BlowThru)&
CALL SimulateFanComponents(CBVAV(CBVAVNum)%FanName,FirstHVACIteration,CBVAV(CBVAVNum)%FanIndex,FanSpeedRatio)
! Simulate cooling coil if zone load is negative (cooling load)
IF (CBVAV(CBVAVNum)%HeatCoolMode == CoolingMode) THEN
IF(OutdoorDryBulbTemp .GE. CBVAV(CBVAVNum)%MinOATCompressor)THEN
SELECT CASE(CBVAV(CBVAVNum)%DXCoolCoilType_Num)
CASE(CoilDX_CoolingHXAssisted)
CALL SimHXAssistedCoolingCoil(CBVAV(CBVAVNum)%DXCoolCoilName,FirstHVACIteration,On,PartLoadFrac, &
CBVAV(CBVAVNum)%CoolCoilCompIndex, ContFanCycCoil, HXUnitEnable=HXUnitOn)
IF(Node(CBVAV(CBVAVNum)%DXCoilInletNode)%Temp .LE. CBVAV(CBVAVNum)%CoilTempSetpoint)THEN
! If coil inlet temp is already below the setpoint, simulated with coil off
PartLoadFrac = 0.0d0
CALL SimHXAssistedCoolingCoil(CBVAV(CBVAVNum)%DXCoolCoilName,FirstHVACIteration,Off,PartLoadFrac, &
CBVAV(CBVAVNum)%CoolCoilCompIndex, ContFanCycCoil, HXUnitEnable=HXUnitOn)
ELSE IF(Node(CBVAV(CBVAVNum)%DXCoilOutletNode)%Temp .LT. CBVAV(CBVAVNum)%CoilTempSetpoint .AND. &
Node(CBVAV(CBVAVNum)%DXCoilInletNode)%Temp .GT. CBVAV(CBVAVNum)%CoilTempSetpoint)THEN
Par(1) = REAL(CBVAV(CBVAVNum)%CoolCoilCompIndex,r64)
Par(2) = CBVAV(CBVAVNum)%CoilTempSetpoint
Par(3) = OnOffAirFlowRatio
Par(4) = REAL(CBVAVNum,r64)
IF(FirstHVACIteration)THEN
Par(5) = 1.0d0
ELSE
Par(5) = 0.0d0
END IF
IF(HXUnitOn)THEN
Par(6) = 1.0d0
ELSE
Par(6) = 0.0d0
END IF
CALL SolveRegulaFalsi(SmallTempDiff, MaxIte, SolFla, PartLoadFrac, HXAssistDXCoilResidual, 0.0d0, 1.0d0, Par)
CALL SimHXAssistedCoolingCoil(CBVAV(CBVAVNum)%DXCoolCoilName,FirstHVACIteration,On,PartLoadFrac, &
CBVAV(CBVAVNum)%CoolCoilCompIndex, ContFanCycCoil, HXUnitEnable=HXUnitOn)
IF (SolFla == -1 .AND. .NOT. WarmupFlag) THEN
IF(CBVAV(CBVAVNum)%HXDXIterationExceeded .LT. 1)THEN
CBVAV(CBVAVNum)%HXDXIterationExceeded = CBVAV(CBVAVNum)%HXDXIterationExceeded + 1
CALL ShowWarningError('Iteration limit exceeded calculating HX assisted DX unit part-load ratio, for unit = '// &
TRIM(CBVAV(CBVAVNum)%DXCoolCoilName))
CALL ShowContinueError('Calculated part-load ratio = '//TRIM(RoundSigDigits(PartLoadFrac,3)))
CALL ShowContinueErrorTimeStamp('The calculated part-load ratio will be used and the simulation continues.'// &
' Occurrence info: ')
ELSE
CALL ShowRecurringWarningErrorAtEnd(TRIM(CBVAV(CBVAVNum)%Name)// &
', Iteration limit exceeded for HX assisted DX unit part-load ratio error continues.', &
CBVAV(CBVAVNum)%HXDXIterationExceededIndex,PartLoadFrac,PartLoadFrac)
END IF
ELSE IF (SolFla == -2 .AND. .NOT. WarmupFlag) THEN
PartLoadFrac = MAX(0.0d0,MIN(1.0d0,(Node(CBVAV(CBVAVNum)%DXCoilInletNode)%Temp - CBVAV(CBVAVNum)%CoilTempSetpoint) / &
(Node(CBVAV(CBVAVNum)%DXCoilInletNode)%Temp - Node(CBVAV(CBVAVNum)%DXCoilOutletNode)%Temp)))
IF(CBVAV(CBVAVNum)%HXDXIterationFailed .LT. 1)THEN
CBVAV(CBVAVNum)%HXDXIterationFailed = CBVAV(CBVAVNum)%HXDXIterationFailed + 1
CALL ShowSevereError('HX assisted DX unit part-load ratio calculation failed: part-load ratio limits exceeded, ' &
//'for unit = '//TRIM(CBVAV(CBVAVNum)%DXCoolCoilName))
CALL ShowContinueErrorTimeStamp('An estimated part-load ratio of '//TRIM(RoundSigDigits(PartLoadFrac,3))// &
'will be used and the simulation continues. Occurrence info: ')
ELSE
CALL ShowRecurringWarningErrorAtEnd(TRIM(CBVAV(CBVAVNum)%Name)// &
', Part-load ratio calculation failed for HX assisted DX unit error continues.', &
CBVAV(CBVAVNum)%HXDXIterationFailedIndex,PartLoadFrac,PartLoadFrac)
END IF
END IF
END IF
CASE(CoilDX_CoolingSingleSpeed)
CALL SimDXCoil(CBVAV(CBVAVNum)%DXCoolCoilName,On,FirstHVACIteration,PartLoadFrac,CBVAV(CBVAVNum)%CoolCoilCompIndex, &
ContFanCycCoil, OnOffAirFlowRatio)
IF(Node(CBVAV(CBVAVNum)%DXCoilInletNode)%Temp .LT. CBVAV(CBVAVNum)%CoilTempSetpoint)THEN
! If coil inlet temp is already below the setpoint, simulated with coil off
PartLoadFrac = 0.0d0
CALL SimDXCoil(CBVAV(CBVAVNum)%DXCoolCoilName,On,FirstHVACIteration,PartLoadFrac,CBVAV(CBVAVNum)%CoolCoilCompIndex, &
ContFanCycCoil, OnOffAirFlowRatio)
ELSE IF(Node(CBVAV(CBVAVNum)%DXCoilOutletNode)%Temp .LT. CBVAV(CBVAVNum)%CoilTempSetpoint .AND. &
Node(CBVAV(CBVAVNum)%DXCoilInletNode)%Temp .GT. CBVAV(CBVAVNum)%CoilTempSetpoint)THEN
Par(1) = REAL(CBVAV(CBVAVNum)%CoolCoilCompIndex,r64)
Par(2) = CBVAV(CBVAVNum)%CoilTempSetpoint
Par(3) = OnOffAirFlowRatio
CALL SolveRegulaFalsi(SmallTempDiff, MaxIte, SolFla, PartLoadFrac, DOE2DXCoilResidual, 0.0d0, 1.0d0, Par)
CALL SimDXCoil(CBVAV(CBVAVNum)%DXCoolCoilName,On,FirstHVACIteration,PartLoadFrac, &
CBVAV(CBVAVNum)%CoolCoilCompIndex,ContFanCycCoil, OnOffAirFlowRatio)
IF (SolFla == -1 .AND. .NOT. WarmupFlag) THEN
IF(CBVAV(CBVAVNum)%DXIterationExceeded .LT. 1)THEN
CBVAV(CBVAVNum)%DXIterationExceeded = CBVAV(CBVAVNum)%DXIterationExceeded + 1
CALL ShowWarningError('Iteration limit exceeded calculating DX unit part-load ratio, for unit = '// &
TRIM(CBVAV(CBVAVNum)%DXCoolCoilName))
CALL ShowContinueError('Calculated part-load ratio = '//TRIM(RoundSigDigits(PartLoadFrac,3)))
CALL ShowContinueErrorTimeStamp('The calculated part-load ratio will be used and the simulation continues.'// &
' Occurrence info: ')
ELSE
CALL ShowRecurringWarningErrorAtEnd(TRIM(CBVAV(CBVAVNum)%Name)// &
', Iteration limit exceeded for DX unit part-load ratio calculation error continues.', &
CBVAV(CBVAVNum)%DXIterationExceededIndex,PartLoadFrac,PartLoadFrac)
END IF
ELSE IF (SolFla == -2 .AND. .NOT. WarmupFlag) THEN
PartLoadFrac = MAX(0.0d0,MIN(1.0d0,(Node(CBVAV(CBVAVNum)%DXCoilInletNode)%Temp - CBVAV(CBVAVNum)%CoilTempSetpoint) / &
(Node(CBVAV(CBVAVNum)%DXCoilInletNode)%Temp - Node(CBVAV(CBVAVNum)%DXCoilOutletNode)%Temp)))
IF(CBVAV(CBVAVNum)%DXIterationFailed .LT. 1)THEN
CBVAV(CBVAVNum)%DXIterationFailed = CBVAV(CBVAVNum)%DXIterationFailed + 1
CALL ShowSevereError('DX unit part-load ratio calculation failed: part-load ratio limits exceeded, for unit = '// &
TRIM(CBVAV(CBVAVNum)%DXCoolCoilName))
CALL ShowContinueErrorTimeStamp('An estimated part-load ratio of '//TRIM(RoundSigDigits(PartLoadFrac,3))// &
'will be used and the simulation continues. Occurrence info: ')
ELSE
CALL ShowRecurringWarningErrorAtEnd(TRIM(CBVAV(CBVAVNum)%Name)// &
', Part-load ratio calculation failed for DX unit error continues.', &
CBVAV(CBVAVNum)%DXIterationFailedIndex,PartLoadFrac,PartLoadFrac)
END IF
END IF
END IF
CASE (CoilDX_CoolingTwoStageWHumControl) ! Coil:Cooling:DX:TwoStageWithHumidityControlMode
! formerly (v3 and beyond) Coil:DX:MultiMode:CoolingEmpirical
! If DXCoolingSystem runs with a cooling load then set PartLoadFrac on Cooling System and the Mass Flow
! Multimode coil will switch to enhanced dehumidification if available and needed, but it
! still runs to meet the sensible load
! Determine required part load for normal mode
! Get full load result
DehumidMode = 0
CBVAV(CBVAVNum)%DehumidificationMode = DehumidMode
CALL SimDXCoilMultiMode(CBVAV(CBVAVNum)%DXCoolCoilName,On,FirstHVACIteration,PartLoadFrac,DehumidMode, &
CBVAV(CBVAVNum)%CoolCoilCompIndex,ContFanCycCoil)
IF (Node(CBVAV(CBVAVNum)%DXCoilInletNode)%Temp < CBVAV(CBVAVNum)%CoilTempSetpoint) THEN
PartLoadFrac = 0.0d0
CALL SimDXCoilMultiMode(CBVAV(CBVAVNum)%DXCoolCoilName,On,FirstHVACIteration,PartLoadFrac,DehumidMode, &
CBVAV(CBVAVNum)%CoolCoilCompIndex,ContFanCycCoil)
ELSE IF (Node(CBVAV(CBVAVNum)%DXCoilOutletNode)%Temp > CBVAV(CBVAVNum)%CoilTempSetpoint) THEN
PartLoadFrac = 1.0d0
ELSE
Par(1) = REAL(CBVAV(CBVAVNum)%CoolCoilCompIndex,r64)
Par(2) = CBVAV(CBVAVNum)%CoilTempSetpoint
! Dehumidification mode = 0 for normal mode, 1+ for enhanced mode
Par(3) = REAL(DehumidMode,r64)
CALL SolveRegulaFalsi(SmallTempDiff, MaxIte, SolFla, PartLoadFrac, MultiModeDXCoilResidual, 0.0d0, 1.0d0, Par)
IF (SolFla == -1) THEN
IF(CBVAV(CBVAVNum)%MMDXIterationExceeded .LT. 1)THEN
CBVAV(CBVAVNum)%MMDXIterationExceeded = CBVAV(CBVAVNum)%MMDXIterationExceeded + 1
CALL ShowWarningError('Iteration limit exceeded calculating DX unit part-load ratio, for unit='// &
TRIM(CBVAV(CBVAVNum)%Name))
CALL ShowContinueErrorTimeStamp('Part-load ratio returned = '//TRIM(RoundSigDigits(PartLoadFrac,2)))
CALL ShowContinueErrorTimeStamp('The calculated part-load ratio will be used and the simulation continues.'// &
' Occurrence info: ')
ELSE
CALL ShowRecurringWarningErrorAtEnd(TRIM(CBVAV(CBVAVNum)%Name)// &
', Iteration limit exceeded calculating DX unit part-load ratio error continues.', &
CBVAV(CBVAVNum)%MMDXIterationExceededIndex,PartLoadFrac,PartLoadFrac)
END IF
ELSE IF (SolFla == -2) THEN
PartLoadFrac = MAX(0.0d0,MIN(1.0d0,(Node(CBVAV(CBVAVNum)%DXCoilInletNode)%Temp - CBVAV(CBVAVNum)%CoilTempSetpoint) / &
(Node(CBVAV(CBVAVNum)%DXCoilInletNode)%Temp - Node(CBVAV(CBVAVNum)%DXCoilOutletNode)%Temp)))
IF(CBVAV(CBVAVNum)%MMDXIterationFailed .LT. 1)THEN
CBVAV(CBVAVNum)%MMDXIterationFailed = CBVAV(CBVAVNum)%MMDXIterationFailed + 1
CALL ShowSevereError('DX unit part-load ratio calculation failed: part-load ratio limits exceeded, for unit='// &
TRIM(CBVAV(CBVAVNum)%Name))
CALL ShowContinueError('Estimated part-load ratio = '//TRIM(RoundSigDigits(PartLoadFrac,3)))
CALL ShowContinueErrorTimeStamp('The estimated part-load ratio will be used and the simulation continues.'// &
' Occurrence info: ')
ELSE
CALL ShowRecurringWarningErrorAtEnd(TRIM(CBVAV(CBVAVNum)%Name)// &
', Part-load ratio calculation failed for DX unit error continues.', &
CBVAV(CBVAVNum)%MMDXIterationFailedIndex,PartLoadFrac,PartLoadFrac)
END IF
END IF
END IF
! If humidity setpoint is not satisfied and humidity control type is Multimode,
! then turn on enhanced dehumidification mode 1
IF (( Node(CBVAV(CBVAVNum)%DXCoilOutletNode)%HumRat > Node(OutletNode)%HumRatMax ) .AND. &
( Node(CBVAV(CBVAVNum)%DXCoilInletNode)%HumRat > Node(OutletNode)%HumRatMax ) .AND. &
( CBVAV(CBVAVNum)%DehumidControlType .EQ. DehumidControl_Multimode ) .AND. &
Node(OutletNode)%HumRatMax .GT. 0.0d0) THEN
! Determine required part load for enhanced dehumidification mode 1
! Get full load result
PartLoadFrac = 1.0d0
DehumidMode = 1
CBVAV(CBVAVNum)%DehumidificationMode = DehumidMode
CALL SimDXCoilMultiMode(CBVAV(CBVAVNum)%DXCoolCoilName,On,FirstHVACIteration,PartLoadFrac,DehumidMode, &
CBVAV(CBVAVNum)%CoolCoilCompIndex, ContFanCycCoil)
IF (Node(CBVAV(CBVAVNum)%DXCoilInletNode)%Temp < CBVAV(CBVAVNum)%CoilTempSetpoint) THEN
PartLoadFrac = 0.0d0
ELSE IF (Node(CBVAV(CBVAVNum)%DXCoilOutletNode)%Temp > CBVAV(CBVAVNum)%CoilTempSetpoint) THEN
PartLoadFrac = 1.0d0
ELSE
Par(1) = REAL(CBVAV(CBVAVNum)%CoolCoilCompIndex,r64)
Par(2) = CBVAV(CBVAVNum)%CoilTempSetpoint
! Dehumidification mode = 0 for normal mode, 1+ for enhanced mode
Par(3) = REAL(DehumidMode,r64)
CALL SolveRegulaFalsi(SmallTempDiff, MaxIte, SolFla, PartLoadFrac, MultiModeDXCoilResidual, 0.0d0, 1.0d0, Par)
IF (SolFla == -1) THEN
IF(CBVAV(CBVAVNum)%DMDXIterationExceeded .LT. 1)THEN
CBVAV(CBVAVNum)%DMDXIterationExceeded = CBVAV(CBVAVNum)%DMDXIterationExceeded + 1
CALL ShowWarningError('Iteration limit exceeded calculating DX unit dehumidifying part-load ratio, '// &
'for unit = '//TRIM(CBVAV(CBVAVNum)%Name))
CALL ShowContinueErrorTimeStamp('Part-load ratio returned='//TRIM(RoundSigDigits(PartLoadFrac,2)))
CALL ShowContinueErrorTimeStamp('The calculated part-load ratio will be used and the simulation continues.'// &
' Occurrence info: ')
ELSE
CALL ShowRecurringWarningErrorAtEnd(TRIM(CBVAV(CBVAVNum)%Name)// &
', Iteration limit exceeded calculating DX unit dehumidifying part-load ratio error ' &
//'continues.',CBVAV(CBVAVNum)%DMDXIterationExceededIndex,PartLoadFrac,PartLoadFrac)
END IF
ELSE IF (SolFla == -2) THEN
PartLoadFrac = MAX(0.0d0,MIN(1.0d0,(Node(CBVAV(CBVAVNum)%DXCoilInletNode)%Temp-CBVAV(CBVAVNum)%CoilTempSetpoint) / &
(Node(CBVAV(CBVAVNum)%DXCoilInletNode)%Temp - Node(CBVAV(CBVAVNum)%DXCoilOutletNode)%Temp)))
IF(CBVAV(CBVAVNum)%DMDXIterationFailed .LT. 1)THEN
CBVAV(CBVAVNum)%DMDXIterationFailed = CBVAV(CBVAVNum)%DMDXIterationFailed + 1
CALL ShowSevereError('DX unit dehumidifying part-load ratio calculation failed: part-load ratio '// &
'limits exceeded, for unit = '//TRIM(CBVAV(CBVAVNum)%Name))
CALL ShowContinueError('Estimated part-load ratio = '//TRIM(RoundSigDigits(PartLoadFrac,3)))
CALL ShowContinueErrorTimeStamp('The estimated part-load ratio will be used and the simulation continues.'// &
' Occurrence info: ')
ELSE
CALL ShowRecurringWarningErrorAtEnd(TRIM(CBVAV(CBVAVNum)%Name)// &
', Dehumidifying part-load ratio calculation failed for DX unit error continues.', &
CBVAV(CBVAVNum)%DMDXIterationFailedIndex,PartLoadFrac,PartLoadFrac)
END IF
END IF
END IF
END IF ! End if humidity ratio setpoint not met - multimode humidity control
! If humidity setpoint is not satisfied and humidity control type is CoolReheat,
! then run to meet latent load
IF (( Node(CBVAV(CBVAVNum)%DXCoilOutletNode)%HumRat > Node(OutletNode)%HumRatMax) .AND. &
( Node(CBVAV(CBVAVNum)%DXCoilInletNode)%HumRat > Node(OutletNode)%HumRatMax) .AND. &
(CBVAV(CBVAVNum)%DehumidControlType .EQ. DehumidControl_CoolReheat) .AND. &
Node(OutletNode)%HumRatMax .GT. 0.0d0) THEN
! Determine revised desired outlet temperature - use approach temperature control strategy
! based on CONTROLLER:SIMPLE TEMPANDHUMRAT control type.
! Calculate the approach temperature (difference between SA dry-bulb temp and SA dew point temp)
ApproachTemp = Node(CBVAV(CBVAVNum)%DXCoilOutletNode)%Temp - &
PsyTdpFnWPb(Node(OutletNode)%HumRat,OutdoorBaroPress)
! Calculate the dew point temperature at the SA humidity ratio setpoint
DesiredDewPoint = PsyTdpFnWPb(Node(OutletNode)%HumRatMax, OutdoorBaroPress)
! Adjust the calculated dew point temperature by the approach temp
CBVAV(CBVAVNum)%CoilTempSetpoint = &
MIN(CBVAV(CBVAVNum)%CoilTempSetpoint, (DesiredDewPoint + ApproachTemp))
! Determine required part load for cool reheat at adjusted DesiredOutletTemp
! Get full load result
PartLoadFrac = 1.0d0
DehumidMode = 0
CBVAV(CBVAVNum)%DehumidificationMode = DehumidMode
CALL SimDXCoilMultiMode(CBVAV(CBVAVNum)%DXCoolCoilName,On,FirstHVACIteration,PartLoadFrac,DehumidMode, &
CBVAV(CBVAVNum)%CoolCoilCompIndex, ContFanCycCoil)
IF (Node(CBVAV(CBVAVNum)%DXCoilInletNode)%Temp < CBVAV(CBVAVNum)%CoilTempSetpoint) THEN
PartLoadFrac = 0.0d0
ELSE IF (Node(CBVAV(CBVAVNum)%DXCoilOutletNode)%Temp > CBVAV(CBVAVNum)%CoilTempSetpoint) THEN
PartLoadFrac = 1.0d0
ELSE
Par(1) = REAL(CBVAV(CBVAVNum)%CoolCoilCompIndex,r64)
Par(2) = CBVAV(CBVAVNum)%CoilTempSetpoint
! Dehumidification mode = 0 for normal mode, 1+ for enhanced mode
Par(3) = REAL(DehumidMode,r64)
CALL SolveRegulaFalsi(SmallTempDiff, MaxIte, SolFla, PartLoadFrac, MultiModeDXCoilResidual, 0.0d0, 1.0d0, Par)
IF (SolFla == -1) THEN
IF(CBVAV(CBVAVNum)%CRDXIterationExceeded .LT. 1)THEN
CBVAV(CBVAVNum)%CRDXIterationExceeded = CBVAV(CBVAVNum)%CRDXIterationExceeded + 1
CALL ShowWarningError('Iteration limit exceeded calculating DX unit cool reheat part-load ratio, '// &
'for unit = '//TRIM(CBVAV(CBVAVNum)%Name))
CALL ShowContinueErrorTimeStamp('Part-load ratio returned = '//TRIM(RoundSigDigits(PartLoadFrac,2)))
CALL ShowContinueErrorTimeStamp('The calculated part-load ratio will be used and the simulation '// &
'continues. Occurrence info: ')
ELSE
CALL ShowRecurringWarningErrorAtEnd(TRIM(CBVAV(CBVAVNum)%Name)// &
', Iteration limit exceeded calculating cool reheat part-load ratio DX unit error continues.', &
CBVAV(CBVAVNum)%CRDXIterationExceededIndex,PartLoadFrac,PartLoadFrac)
END IF
ELSE IF (SolFla == -2) THEN
PartLoadFrac = MAX(0.0d0,MIN(1.0d0, &
(Node(CBVAV(CBVAVNum)%DXCoilInletNode)%Temp-CBVAV(CBVAVNum)%CoilTempSetpoint) / &
(Node(CBVAV(CBVAVNum)%DXCoilInletNode)%Temp - Node(CBVAV(CBVAVNum)%DXCoilOutletNode)%Temp)))
IF(CBVAV(CBVAVNum)%CRDXIterationFailed .LT. 1)THEN
CBVAV(CBVAVNum)%CRDXIterationFailed = CBVAV(CBVAVNum)%CRDXIterationFailed + 1
CALL ShowSevereError('DX unit cool reheat part-load ratio calculation failed: part-load ratio limits '// &
'exceeded, for unit = '//TRIM(CBVAV(CBVAVNum)%Name))
CALL ShowContinueError('Estimated part-load ratio = '//TRIM(RoundSigDigits(PartLoadFrac,3)))
CALL ShowContinueErrorTimeStamp('The estimated part-load ratio will be used and the simulation '// &
'continues. Occurrence info: ')
ELSE
CALL ShowRecurringWarningErrorAtEnd(TRIM(CBVAV(CBVAVNum)%Name)// &
', Dehumidifying part-load ratio calculation failed for DX unit error continues.', &
CBVAV(CBVAVNum)%DMDXIterationFailedIndex,PartLoadFrac,PartLoadFrac)
END IF
END IF
END IF
END IF ! End if humidity ratio setpoint not met - CoolReheat humidity control
IF(PartLoadFrac.GT.1.0d0) THEN
PartLoadFrac = 1.0d0
ELSEIF(PartLoadFrac < 0.0d0) THEN
PartLoadFrac = 0.0d0
END IF
CASE DEFAULT
CALL ShowFatalError('SimCBVAV System: Invalid DX Cooling Coil='// &
TRIM(CBVAV(CBVAVNum)%DXCoolCoilType))
END SELECT
ELSE ! IF(OutdoorDryBulbTemp .GE. CBVAV(CBVAVNum)%MinOATCompressor)THEN
! Simulate DX cooling coil with compressor off
IF (CBVAV(CBVAVNum)%DXCoolCoilType_Num == CoilDX_CoolingHXAssisted) THEN
CALL SimHXAssistedCoolingCoil(CBVAV(CBVAVNum)%DXCoolCoilName,FirstHVACIteration,Off,0.0d0,&
CBVAV(CBVAVNum)%CoolCoilCompIndex, ContFanCycCoil, HXUnitEnable=HXUnitOn)
ELSE IF(CBVAV(CBVAVNum)%DXCoolCoilType_Num == CoilDX_CoolingSingleSpeed)THEN
CALL SimDXCoil(CBVAV(CBVAVNum)%DXCoolCoilName,Off,FirstHVACIteration, 0.0d0,CBVAV(CBVAVNum)%CoolCoilCompIndex, &
ContFanCycCoil, OnOffAirFlowRatio)
ELSE IF(CBVAV(CBVAVNum)%DXCoolCoilType_Num == CoilDX_CoolingTwoStageWHumControl)THEN
CALL SimDXCoilMultiMode(CBVAV(CBVAVNum)%DXCoolCoilName,Off,FirstHVACIteration, 0.0d0,0,CBVAV(CBVAVNum)%CoolCoilCompIndex, &
ContFanCycCoil)
END IF
END IF
SaveCompressorPLR = DXCoilPartLoadRatio(CBVAV(CBVAVNum)%DXCoolCoilIndexNum)
! Simulate cooling coil with compressor off if zone requires heating
ELSE ! HeatCoolMode == HeatingMode and no cooling is required, set PLR to 0
IF (CBVAV(CBVAVNum)%DXCoolCoilType_Num == CoilDX_CoolingHXAssisted) THEN
CALL SimHXAssistedCoolingCoil(CBVAV(CBVAVNum)%DXCoolCoilName,FirstHVACIteration,Off,0.0d0,CBVAV(CBVAVNum)%CoolCoilCompIndex, &
ContFanCycCoil, HXUnitEnable=HXUnitOn)
ELSE IF(CBVAV(CBVAVNum)%DXCoolCoilType_Num == CoilDX_CoolingSingleSpeed)THEN
CALL SimDXCoil(CBVAV(CBVAVNum)%DXCoolCoilName,Off,FirstHVACIteration, 0.0d0,CBVAV(CBVAVNum)%CoolCoilCompIndex, &
ContFanCycCoil, OnOffAirFlowRatio)
ELSE IF(CBVAV(CBVAVNum)%DXCoolCoilType_Num == CoilDX_CoolingTwoStageWHumControl)THEN
CALL SimDXCoilMultiMode(CBVAV(CBVAVNum)%DXCoolCoilName,Off,FirstHVACIteration,0.0d0,0,CBVAV(CBVAVNum)%CoolCoilCompIndex, &
ContFanCycCoil)
END IF
END IF
! Simulate the heating coil based on coil type
SELECT CASE(CBVAV(CBVAVNum)%HeatCoilType_Num)
CASE(CoilDX_HeatingEmpirical)
! Simulate DX heating coil if zone load is positive (heating load)
IF (CBVAV(CBVAVNum)%HeatCoolMode == HeatingMode)THEN
IF(OutdoorDryBulbTemp .GT. CBVAV(CBVAVNum)%MinOATCompressor)THEN
! simulate the DX heating coil
CALL SimDXCoil(CBVAV(CBVAVNum)%HeatCoilName,On,FirstHVACIteration, PartLoadFrac,CBVAV(CBVAVNum)%HeatCoilIndex, &
ContFanCycCoil, OnOffAirFlowRatio)
IF(Node(CBVAV(CBVAVNum)%HeatingCoilOutletNode)%Temp .GT. CBVAV(CBVAVNum)%CoilTempSetpoint .AND. &
Node(CBVAV(CBVAVNum)%HeatingCoilInletNode)%Temp .LT. CBVAV(CBVAVNum)%CoilTempSetpoint)THEN
! iterate to find PLR at CoilTempSetpoint
Par(1) = REAL(CBVAV(CBVAVNum)%HeatCoilIndex,r64)
Par(2) = MIN(CBVAV(CBVAVNum)%CoilTempSetpoint,CBVAV(CBVAVNum)%MaxLATHeating)
Par(3) = OnOffAirFlowRatio
CALL SolveRegulaFalsi(SmallTempDiff, MaxIte, SolFla, PartLoadFrac, DXHeatingCoilResidual, 0.0d0, 1.0d0, Par)
CALL SimDXCoil(CBVAV(CBVAVNum)%HeatCoilName,On,FirstHVACIteration, PartLoadFrac,CBVAV(CBVAVNum)%HeatCoilIndex, &
ContFanCycCoil, OnOffAirFlowRatio)
IF (SolFla == -1 .AND. .NOT. WarmupFlag) THEN
CALL ShowWarningError('Iteration limit exceeded calculating DX unit part-load ratio, for unit = '// &
TRIM(CBVAV(CBVAVNum)%HeatCoilName))
CALL ShowContinueError('Calculated part-load ratio = '//TRIM(RoundSigDigits(PartLoadFrac,3)))
CALL ShowContinueErrorTimeStamp('The calculated part-load ratio will be used and the simulation continues.'// &
' Occurrence info: ')
ELSE IF (SolFla == -2 .AND. .NOT. WarmupFlag) THEN
CALL ShowSevereError('DX unit part-load ratio calculation failed: part-load ratio limits exceeded, for unit = '// &
TRIM(CBVAV(CBVAVNum)%HeatCoilName))
CALL ShowContinueErrorTimeStamp('A part-load ratio of '//TRIM(RoundSigDigits(PartLoadFrac,3))// &
'will be used and the simulation continues. Occurrence info: ')
CALL ShowContinueError('Please send this information to the EnergyPlus support group.')
END IF
END IF
ELSE ! OAT .LT. MinOATCompressor
! simulate DX heating coil with compressor off
CALL SimDXCoil(CBVAV(CBVAVNum)%HeatCoilName,Off,FirstHVACIteration,0.0d0, CBVAV(CBVAVNum)%HeatCoilIndex, &
ContFanCycCoil, OnOffAirFlowRatio)
END IF
SaveCompressorPLR = DXCoilPartLoadRatio(CBVAV(CBVAVNum)%DXHeatCoilIndexNum)
ELSE ! HeatCoolMode = CoolingMode
! simulate DX heating coil with compressor off when cooling load is required
CALL SimDXCoil(CBVAV(CBVAVNum)%HeatCoilName,Off,FirstHVACIteration, 0.0d0,CBVAV(CBVAVNum)%HeatCoilIndex, &
ContFanCycCoil, OnOffAirFlowRatio)
END IF
CASE(Coil_HeatingGas, Coil_HeatingElectric, Coil_HeatingWater, Coil_HeatingSteam) ! not a DX heating coil
IF(CBVAV(CBVAVNum)%HeatCoolMode == HeatingMode)THEN
CpAir = PsyCpAirFnWTdb(Node(CBVAV(CBVAVNum)%HeatingCoilInletNode)%HumRat,Node(CBVAV(CBVAVNum)%HeatingCoilInletNode)%Temp)
QHeater = Node(CBVAV(CBVAVNum)%HeatingCoilInletNode)%MassFlowRate * CpAir * &
(CBVAV(CBVAVNum)%CoilTempSetpoint - Node(CBVAV(CBVAVNum)%HeatingCoilInletNode)%Temp)
ELSE
QHeater = 0.0d0
END IF
! Added None DX heating coils calling point
CALL CalcNonDXHeatingCoils(CBVAVNum,FirstHVACIteration,QHeater,CBVAV(CBVAVNum)%OpMode,QHeaterActual)
CASE DEFAULT
CALL ShowFatalError('SimCBVAV System: Invalid Heating Coil='// &
TRIM(CBVAV(CBVAVNum)%HeatCoilType))
END SELECT
IF (CBVAV(CBVAVNum)%FanPlace .EQ. DrawThru)&
CALL SimulateFanComponents(CBVAV(CBVAVNum)%FanName,FirstHVACIteration,CBVAV(CBVAVNum)%FanIndex,FanSpeedRatio)
Node(OutletNode)%MassFlowRate = (1.0d0 - ByPassDuctFlowFraction) * Node(CBVAV(CBVAVNum)%MixerInletAirNode)%MassFlowRate
Node(OutletNode)%Temp = Node(CBVAV(CBVAVNum)%SplitterOutletAirNode)%Temp
Node(OutletNode)%HumRat = Node(CBVAV(CBVAVNum)%SplitterOutletAirNode)%HumRat
Node(OutletNode)%Quality = Node(CBVAV(CBVAVNum)%SplitterOutletAirNode)%Quality
Node(OutletNode)%Press = Node(CBVAV(CBVAVNum)%SplitterOutletAirNode)%Press
Node(OutletNode)%Enthalpy = Node(CBVAV(CBVAVNum)%SplitterOutletAirNode)%Enthalpy
Node(OutletNode)%Height = Node(CBVAV(CBVAVNum)%SplitterOutletAirNode)%Height
CBVAV(CBVAVNum)%BypassMassFlowRate = ByPassDuctFlowFraction * Node(CBVAV(CBVAVNum)%MixerInletAirNode)%MassFlowRate
! calculate sensible load met using delta enthalpy at a constant (minimum) humidity ratio)
MinHumRat = MIN(Node(InletNode)%HumRat,Node(OutletNode)%HumRat)
LoadMet = Node(OutletNode)%MassFlowRate * &
(PsyHFnTdbW(Node(OutletNode)%Temp,MinHumRat) - PsyHFnTdbW(Node(InletNode)%Temp,MinHumRat))
RETURN
END SUBROUTINE CalcCBVAV