Nodes of different colours represent the following:
Solid arrows point from a parent (sub)module to the submodule which is descended from it. Dashed arrows point from a module being used to the module or program unit using it. Where possible, edges connecting nodes are given different colours to make them easier to distinguish in large graphs.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
integer, | intent(in) | :: | PTUnitNum | |||
logical, | intent(in) | :: | FirstHVACIteration | |||
integer, | intent(in) | :: | OpMode | |||
real(kind=r64), | intent(in) | :: | QZnReq | |||
integer, | intent(in) | :: | ZoneNum | |||
real(kind=r64), | intent(out) | :: | PartLoadFrac | |||
real(kind=r64), | intent(inout) | :: | OnOffAirFlowRatio | |||
real(kind=r64), | intent(inout) | :: | SupHeaterLoad | |||
logical, | intent(inout) | :: | HXUnitOn |
Nodes of different colours represent the following:
Solid arrows point from a procedure to one which it calls. Dashed arrows point from an interface to procedures which implement that interface. This could include the module procedures in a generic interface or the implementation in a submodule of an interface in a parent module. Where possible, edges connecting nodes are given different colours to make them easier to distinguish in large graphs.
Nodes of different colours represent the following:
Solid arrows point from a procedure to one which it calls. Dashed arrows point from an interface to procedures which implement that interface. This could include the module procedures in a generic interface or the implementation in a submodule of an interface in a parent module. Where possible, edges connecting nodes are given different colours to make them easier to distinguish in large graphs.
SUBROUTINE ControlPTUnitOutput(PTUnitNum,FirstHVACIteration,OpMode,QZnReq,ZoneNum,PartLoadFrac,OnOffAirFlowRatio,SupHeaterLoad, &
HXUnitOn)
! SUBROUTINE INFORMATION:
! AUTHOR Richard Raustad
! DATE WRITTEN July 2005
! MODIFIED na
! RE-ENGINEERED na
! PURPOSE OF THIS SUBROUTINE:
! Determine the part load fraction of the heat pump for this time step.
! METHODOLOGY EMPLOYED:
! Use RegulaFalsi technique to iterate on part-load ratio until convergence is achieved.
! REFERENCES:
! na
! USE STATEMENTS:
USE General, ONLY: SolveRegulaFalsi, RoundSigDigits, TrimSigDigits
USE DataGlobals, ONLY: WarmUpFlag
USE HeatingCoils, ONLY: SimulateHeatingCoilComponents
USE Psychrometrics, ONLY: PsyCpAirFnWTdb
USE DataEnvironment, ONLY: OutDryBulbTemp
USE SteamCoils, ONLY: SimulateSteamCoilComponents
USE WaterCoils, ONLY: SimulateWaterCoilComponents
USE PlantUtilities, ONLY: SetComponentFlowRate
IMPLICIT NONE ! Enforce explicit typing of all variables in this routine
! SUBROUTINE ARGUMENT DEFINITIONS:
INTEGER, INTENT (IN) :: PTUnitNum ! Unit index in fan coil array
LOGICAL, INTENT (IN) :: FirstHVACIteration ! flag for 1st HVAC iteration in the time step
INTEGER, INTENT (IN) :: OpMode ! operating mode: CycFanCycCoil | ContFanCycCoil
REAL(r64), INTENT (IN) :: QZnReq ! cooling or heating output needed by zone [W]
INTEGER, INTENT (IN) :: ZoneNum ! Index to zone number
REAL(r64), INTENT (OUT) :: PartLoadFrac ! unit part load fraction
REAL(r64), INTENT (INOUT) :: OnOffAirFlowRatio ! ratio of compressor ON airflow to AVERAGE airflow over timestep
REAL(r64), INTENT (INOUT) :: SupHeaterLoad ! Supplemental heater load [W]
LOGICAL, INTENT (INOUT) :: HXUnitOn ! flag to enable heat exchanger
REAL(r64) :: mdot ! coil fluid mass flow rate (kg/s)
! SUBROUTINE PARAMETER DEFINITIONS:
!
INTEGER, PARAMETER :: MaxIte = 500 ! maximum number of iterations
REAL(r64), PARAMETER :: MinPLF = 0.0d0 ! minimum part load factor allowed
! INTERFACE BLOCK SPECIFICATIONS
! na
! DERIVED TYPE DEFINITIONS
! na
! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
REAL(r64) :: FullOutput ! unit full output when compressor is operating [W]
REAL(r64) :: TempOutput ! unit output when iteration limit exceeded [W]
REAL(r64) :: NoCompOutput ! output when no active compressor [W]
REAL(r64) :: ErrorToler ! error tolerance
INTEGER :: SolFla ! Flag of RegulaFalsi solver
REAL(r64), DIMENSION(8) :: Par ! Parameters passed to RegulaFalsi
CHARACTER(len=20) :: IterNum ! Max number of iterations for warning message
REAL(r64) :: CpAir ! air specific heat
REAL(r64) :: OutsideDryBulbTemp ! Outside air temperature at external node height
!unused1208 REAL(r64) :: UpperLimitPLR ! used when RegulaFalsi exceeds iteration limit
REAL(r64) :: TempMinPLR
REAL(r64) :: TempMaxPLR
LOGICAL :: ContinueIter
SupHeaterLoad = 0.0d0
PartLoadFrac = 0.0d0
IF(PTUnit(PTUnitNum)%CondenserNodeNum .EQ. 0)THEN
OutsideDryBulbTemp = OutDryBulbTemp
ELSE
OutsideDryBulbTemp = Node(PTUnit(PTUnitNum)%CondenserNodeNum)%Temp
END IF
IF (GetCurrentScheduleValue(PTUnit(PTUnitNum)%SchedPtr) .EQ. 0.0d0) RETURN
! If no heating or cooling required the coils needs to be off
IF (.NOT. HeatingLoad .AND. .NOT. CoolingLoad) THEN
RETURN
END IF
! Get result when DX coil is off
CALL CalcPTUnit(PTUnitNum, FirstHVACIteration, PartLoadFrac, NoCompOutput, QZnReq, OnOffAirFlowRatio, SupHeaterLoad, HXUnitOn)
! Get full load result
PartLoadFrac = 1.0d0
CALL CalcPTUnit(PTUnitNum, FirstHVACIteration, PartLoadFrac, FullOutput, QZnReq, OnOffAirFlowRatio, SupHeaterLoad, HXUnitOn)
IF (CoolingLoad) THEN
! Since we are cooling, we expect FullOutput < NoCompOutput
! Check that this is the case; if not set PartLoadFrac = 0.0 (off) and return
IF (FullOutput >= NoCompOutput) THEN
PartLoadFrac = 0.0d0
RETURN
END IF
! If the QZnReq <= FullOutput the unit needs to run full out
IF (QZnReq <= FullOutput) THEN
PartLoadFrac = 1.0d0
RETURN
END IF
IF(PTUnit(PTUnitNum)%UnitType_Num .EQ. PTACUnit)THEN
ErrorToler = 0.001d0
ELSE
ErrorToler = PTUnit(PTUnitNum)%CoolConvergenceTol !Error tolerance for convergence from input deck
END IF
ELSE
! Since we are heating, we expect FullOutput > NoCompOutput
! Check that this is the case; if not set PartLoadFrac = 0.0 (off)
IF (FullOutput <= NoCompOutput) THEN
PartLoadFrac = 0.0d0
! may need supplemental heating so don't return in heating mode
! RETURN
END IF
! If the QZnReq >= FullOutput the unit needs to run full out
IF (QZnReq >= FullOutput .AND. PTUnit(PTUnitNum)%SuppHeatCoilIndex .GT. 0) THEN
PartLoadFrac = 1.0d0
! may need supplemental heating so don't return in heating mode
! RETURN
END IF
ErrorToler = PTUnit(PTUnitNum)%HeatConvergenceTol !Error tolerance for convergence from input deck
END IF
! Calculate the part load fraction
IF ((HeatingLoad .AND. QZnReq < FullOutput) .OR. (CoolingLoad .AND. QZnReq > FullOutput)) THEN
Par(1) = PTUnitNum
Par(2) = ZoneNum
IF (FirstHVACIteration) THEN
Par(3) = 1.0d0
ELSE
Par(3) = 0.0d0
END IF
Par(4) = OpMode
Par(5) = QZnReq
Par(6) = OnOffAirFlowRatio
Par(7) = SupHeaterLoad
IF(HXUnitOn)THEN
Par(8) = 1.0d0
ELSE
Par(8) = 0.0d0
END IF
CALL SolveRegulaFalsi(ErrorToler, MaxIte, SolFla, PartLoadFrac, PLRResidual, &
0.0d0, 1.0d0, Par)
IF (SolFla == -1) THEN
! Very low loads may not converge quickly. Tighten PLR boundary and try again.
TempMaxPLR = -0.1d0
ContinueIter = .TRUE.
DO WHILE(ContinueIter .AND. TempMaxPLR .LT. 1.0d0)
TempMaxPLR = TempMaxPLR + 0.1d0
CALL CalcPTUnit(PTUnitNum,FirstHVACIteration,TempMaxPLR,TempOutput,QZnReq,OnOffAirFlowRatio,SupHeaterLoad, HXUnitOn)
IF(HeatingLoad .AND. TempOutput .GT. QZnReq)ContinueIter = .FALSE.
IF(CoolingLoad .AND. TempOutput .LT. QZnReq)ContinueIter = .FALSE.
END DO
TempMinPLR = TempMaxPLR
ContinueIter = .TRUE.
DO WHILE(ContinueIter .AND. TempMinPLR .GT. 0.0d0)
TempMinPLR = TempMinPLR - 0.01d0
CALL CalcPTUnit(PTUnitNum,FirstHVACIteration,TempMinPLR,TempOutput,QZnReq,OnOffAirFlowRatio,SupHeaterLoad, HXUnitOn)
IF(HeatingLoad .AND. TempOutput .LT. QZnReq)ContinueIter = .FALSE.
IF(CoolingLoad .AND. TempOutput .GT. QZnReq)ContinueIter = .FALSE.
END DO
CALL SolveRegulaFalsi(ErrorToler, MaxIte, SolFla, PartLoadFrac, PLRResidual, &
TempMinPLR, TempMaxPLR, Par)
IF (SolFla == -1) THEN
IF (.NOT. FirstHVACIteration .AND. .NOT. WarmupFlag) THEN
CALL CalcPTUnit(PTUnitNum,FirstHVACIteration,PartLoadFrac,TempOutput,QZnReq,OnOffAirFlowRatio,SupHeaterLoad, HXUnitOn)
IF(PTUnit(PTUnitNum)%IterErrIndex .EQ. 0)THEN
WRITE(IterNum,*) MaxIte
IterNum=ADJUSTL(IterNum)
Call ShowWarningError(TRIM(PTUnit(PTUnitNum)%UnitType)//' "'//TRIM(PTUnit(PTUnitNum)%Name)//'"')
CALL ShowContinueError(' Iteration limit exceeded calculating packaged terminal unit part-load ratio, '// &
'maximum iterations = '//TRIM(IterNum))
CALL ShowContinueErrorTimeStamp(' Part-load ratio returned = '//TRIM(RoundSigDigits(PartLoadFrac,3)))
CALL ShowContinueError(' Load requested = '//TRIM(TrimSigDigits(QZnReq,5))//', Load delivered = ' &
//TRIM(TrimSigDigits(TempOutput,5)))
END IF
CALL ShowRecurringWarningErrorAtEnd(TRIM(PTUnit(PTUnitNum)%UnitType)//' "'//TRIM(PTUnit(PTUnitNum)%Name)//&
'" - Iteration limit exceeded error continues...', &
PTUnit(PTUnitNum)%IterErrIndex,ReportMinOf=TempOutput,ReportMaxOf=TempOutput, &
ReportMaxUnits='{W}',ReportMinUnits='{W}')
END IF
ELSE IF (SolFla == -2) THEN
IF (.NOT. FirstHVACIteration) THEN
Call ShowWarningError(TRIM(PTUnit(PTUnitNum)%UnitType)//' "'//TRIM(PTUnit(PTUnitNum)%Name)//'"')
CALL ShowContinueError('Packaged terminal unit part-load ratio calculation failed: ' &
//'PLR limits of 0 to 1 exceeded')
CALL ShowContinueError('Please fill out a bug report and forward to the EnergyPlus support group.')
CALL ShowContinueErrorTimeStamp(' ')
IF (WarmupFlag) CALL ShowContinueError ('Error occurred during warmup days.')
END IF
PartLoadFrac = MAX(MinPLF, ABS(QZnReq - NoCompOutput) / ABS(FullOutput - NoCompOutput))
END IF
ELSE IF (SolFla == -2) THEN
IF (.NOT. FirstHVACIteration) THEN
Call ShowWarningError(TRIM(PTUnit(PTUnitNum)%UnitType)//' "'//TRIM(PTUnit(PTUnitNum)%Name)//'"')
CALL ShowContinueError('Packaged terminal unit part-load ratio calculation failed: ' &
//'PLR limits of 0 to 1 exceeded')
CALL ShowContinueError('Please fill out a bug report and forward to the EnergyPlus support group.')
CALL ShowContinueErrorTimeStamp(' ')
IF (WarmupFlag) CALL ShowContinueError ('Error occurred during warmup days.')
END IF
PartLoadFrac = MAX(MinPLF, ABS(QZnReq - NoCompOutput) / ABS(FullOutput - NoCompOutput))
END IF
END IF
! if the DX heating coil cannot meet the load, trim with supplemental heater
! occurs with constant fan mode when compressor is on or off
! occurs with cycling fan mode when compressor PLR is equal to 1
IF (HeatingLoad .AND. QZnReq .GT. FullOutput .AND. PTUnit(PTUnitNum)%SuppHeatCoilIndex .GT. 0)THEN
PartLoadFrac = 1.0d0
IF (OutsideDryBulbTemp .LE. PTUnit(PTUnitNum)%MaxOATSupHeat) THEN
SupHeaterLoad = QZnReq - FullOutput
ELSE
SupHeaterLoad = 0.0d0
END IF
CALL CalcPTUnit(PTUnitNum, FirstHVACIteration, PartLoadFrac, TempOutput, QZnReq, OnOffAirFlowRatio, SupHeaterLoad, HXUnitOn)
END IF
! check the outlet of the supplemental heater to be lower than the maximum supplemental heater supply air temperature
IF(PTUnit(PTUnitNum)%SuppHeatCoilIndex .GT. 0)THEN
IF (Node(PTUnit(PTUnitNum)%AirOutNode)%Temp .GT. PTUnit(PTUnitNum)%MaxSATSupHeat .AND. SupHeaterLoad .GT. 0.0d0) THEN
! If supply air temperature is to high, turn off the supplemental heater to recalculate the outlet temperature
SupHeaterLoad = 0.0d0
Select Case (PTUnit(PTUnitNum)%SuppHeatCoilType_Num)
Case (Coil_HeatingGas,Coil_HeatingElectric )
CALL SimulateHeatingCoilComponents(PTUnit(PTUnitNum)%SuppHeatCoilName,FirstHVACIteration, &
SupHeaterLoad, PTUnit(PTUnitNum)%SuppHeatCoilIndex)
Case (Coil_HeatingWater)
mdot = 0.d0
Call SetComponentFlowRate( mdot , &
PTUnit(PTUnitNum)%HotWaterControlNode, &
PTUnit(PTUnitNum)%PlantCoilOutletNode, &
PTUnit(PTUnitNum)%LoopNum, &
PTUnit(PTUnitNum)%LoopSide, &
PTUnit(PTUnitNum)%BranchNum, &
PTUnit(PTUnitNum)%CompNum)
CALL SimulateWaterCoilComponents(PTUnit(PTUnitNum)%SuppHeatCoilName,FirstHVACIteration, &
PTUnit(PTUnitNum)%SuppHeatCoilIndex, SupHeaterLoad, &
PTUnit(PTUnitNum)%OpMode, PartLoadFrac)
Case (Coil_HeatingSteam)
mdot = 0.d0
CALL SetComponentFlowRate( mdot , &
PTUnit(PTUnitNum)%HWCoilSteamInletNode, &
PTUnit(PTUnitNum)%PlantCoilOutletNode, &
PTUnit(PTUnitNum)%LoopNum, &
PTUnit(PTUnitNum)%LoopSide, &
PTUnit(PTUnitNum)%BranchNum, &
PTUnit(PTUnitNum)%CompNum)
CALL SimulateSteamCoilComponents(PTUnit(PTUnitNum)%SuppHeatCoilName, &
FirstHVACIteration, SupHeaterLoad, &
PTUnit(PTUnitNum)%SuppHeatCoilIndex)
END Select
! If the outlet temperature is below the maximum supplemental heater supply air temperature, reduce the load passed to
! the supplemental heater, otherwise leave the supplemental heater off. If the supplemental heater is to be turned on,
! use the outlet conditions when the supplemental heater was off (CALL above) as the inlet conditions for the calculation
! of supplemental heater load to just meet the maximum supply air temperature from the supplemental heater.
IF (Node(PTUnit(PTUnitNum)%AirOutNode)%Temp .LT. PTUnit(PTUnitNum)%MaxSATSupHeat) THEN
CpAir = PsyCpAirFnWTdb(Node(PTUnit(PTUnitNum)%AirOutNode)%HumRat,Node(PTUnit(PTUnitNum)%AirOutNode)%Temp)
SupHeaterLoad = Node(PTUnit(PTUnitNum)%AirInNode)%MassFlowRate * CpAir * &
(PTUnit(PTUnitNum)%MaxSATSupHeat - Node(PTUnit(PTUnitNum)%AirOutNode)%Temp)
ELSE
SupHeaterLoad = 0.0d0
END IF
END IF
END IF
RETURN
END SUBROUTINE ControlPTUnitOutput