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) | :: | FurnaceNum | |||
logical, | intent(in) | :: | FirstHVACIteration | |||
real(kind=r64), | intent(in) | :: | ZoneLoad | |||
real(kind=r64), | intent(inout) | :: | HeatCoilLoad | |||
real(kind=r64), | intent(inout) | :: | OnOffAirFlowRatio |
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 CalcNewZoneHeatOnlyFlowRates(FurnaceNum,FirstHVACIteration,ZoneLoad,HeatCoilLoad, OnOffAirFlowRatio)
! SUBROUTINE INFORMATION:
! AUTHOR Richard Liesen
! DATE WRITTEN Feb 2001
! MODIFIED Don Shirey and R. Raustad, Mar 2001 & Mar 2003
! RE-ENGINEERED na
! PURPOSE OF THIS SUBROUTINE:
! This subroutine updates the coil outlet nodes by simulating a heat-only
! furnace or unitary system.
! METHODOLOGY EMPLOYED:
! Determine the operating PLR to meet the zone sensible load.
! REFERENCES:
! na
! USE STATEMENTS:
USE HeatingCoils, ONLY: SimulateHeatingCoilComponents
USE ScheduleManager
USE DataHeatBalFanSys, ONLY: MAT
USE General, ONLY: TrimSigDigits
IMPLICIT NONE ! Enforce explicit typing of all variables in this routine
! SUBROUTINE ARGUMENT DEFINITIONS:
INTEGER, INTENT(IN) :: FurnaceNum ! Index to furnace
LOGICAL, INTENT(IN) :: FirstHVACIteration ! Iteration flag
REAL(r64), INTENT(IN) :: ZoneLoad ! load to be met by furnace (W)
REAL(r64), INTENT(INOUT) :: HeatCoilLoad ! actual load passed to heating coil (W)
REAL(r64), INTENT(INOUT) :: OnOffAirFlowRatio ! ratio of coil on to coil off air flow rate
! SUBROUTINE PARAMETER DEFINITIONS:
INTEGER, PARAMETER :: MaxIter = 15 ! maximum number of iterations
REAL(r64), PARAMETER :: MinPLR = 0.0d0 ! minimum part load ratio allowed
! INTERFACE BLOCK SPECIFICATIONS
! na
! DERIVED TYPE DEFINITIONS
! na
! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
REAL(r64) :: cpair
REAL(r64) :: Error = 1.0d0
REAL(r64) :: SystemSensibleLoad ! Sensible load to be met by furnace (W)
REAL(r64) :: FullSensibleOutput ! Full sensible output of furnace (W)
REAL(r64) :: FullLatentOutput ! Full latent output of furnace = 0 (W)
REAL(r64) :: NoSensibleOutput ! Sensible output of furnace with no heating allowed (W)
REAL(r64) :: NoLatentOutput ! Latent output of furnace = 0 (W)
REAL(r64) :: PartLoadRatio ! Part load ratio of furnace
REAL(r64) :: HeatErrorToler ! Error tolerance in heating mode
REAL(r64) :: IterRelax ! Relaxation factor for iterations
REAL(r64) :: ActualSensibleOutput ! Actual furnace sensible capacity
REAL(r64) :: ActualLatentOutput ! Actual furnace latent capacity = 0
REAL(r64) :: DeltaT ! Heater outlet temp minus design heater outlet temp
! CHARACTER(len=20) :: ErrNum = ' ' ! For displaying error message in cooling
! INTEGER,SAVE :: ErrCount = 0
INTEGER :: Iter = 0 ! Iteration counter
INTEGER :: FurnaceInletNode ! Node number of furnace inlet
INTEGER :: FurnaceOutletNode ! Node number of furnace outlet
INTEGER :: OpMode ! Mode of Operation (fan cycling or fan continuous)
! Set local variables
! Retrieve the load on the controlled zone
FurnaceOutletNode = Furnace(FurnaceNum)%FurnaceOutletNodeNum
FurnaceInletNode = Furnace(FurnaceNum)%FurnaceInletNodeNum
OpMode = Furnace(FurnaceNum)%OpMode
Furnace(FurnaceNum)%MdotFurnace = Furnace(FurnaceNum)%DesignMassFlowRate
Furnace(FurnaceNum)%CoolPartLoadRatio = 0.0d0
! OnOffAirFlowRatio = 1.0
!Calculate the Cp Air
cpair = PsyCpAirFnWTdb(Node(FurnaceInletNode)%HumRat,Node(FurnaceInletNode)%Temp)
IF(FirstHVACIteration) THEN
HeatCoilLoad = ZoneLoad
OnOffFanPartLoadFraction = 1.0d0
Node(FurnaceInletNode)%MassFlowRate = Furnace(FurnaceNum)%MdotFurnace
ELSE
! If Furnace runs then set HeatCoilLoad on Heating Coil and the Mass Flow
IF((GetCurrentScheduleValue(Furnace(FurnaceNum)%SchedPtr) .gt. 0.0d0) .and. &
(Node(FurnaceInletNode)%MassFlowRate .gt. 0.0d0) .and. &
(HeatingLoad)) THEN
Node(FurnaceInletNode)%MassFlowRate=Furnace(FurnaceNum)%MdotFurnace
HeatCoilLoad = Furnace(FurnaceNum)%DesignHeatingCapacity
SystemSensibleLoad = ZoneLoad
! Get no load result
IF (OpMode .EQ. CycFanCycCoil) THEN
Node(FurnaceInletNode)%MassFlowRate = 0.0d0
END IF
IF (OpMode .EQ. ContFanCycCoil) THEN
OnOffFanPartLoadFraction = 1.0d0 ! The on/off fan will not cycle, so set part-load fraction = 1
END IF
! Set the inlet mass flow rate based on user specified coil OFF flow rate
PartLoadRatio = 0.0d0
CALL SetAverageAirFlow(FurnaceNum, PartLoadRatio, OnOffAirFlowRatio)
CALL CalcFurnaceOutput(FurnaceNum,FirstHVACIteration,OpMode,On,0.0d0,0.0d0,0.0d0,0.0d0,NoSensibleOutput,NoLatentOutput, &
OnOffAirFlowRatio, .FALSE.)
Node(FurnaceInletNode)%MassFlowRate=Furnace(FurnaceNum)%MdotFurnace
! Set fan part-load fraction equal to 1 while getting full load result
OnOffFanPartLoadFraction = 1.0d0
OnOffAirFlowRatio = 1.0d0
! Get full load result
CALL CalcFurnaceOutput(FurnaceNum,FirstHVACIteration,OpMode,On,0.0d0,1.0d0,HeatCoilLoad,0.0d0,FullSensibleOutput, &
FullLatentOutput, OnOffAirFlowRatio, .FALSE.)
! Since we are heating, we expect FullSensibleOutput to be > 0 and FullSensibleOutput > NoSensibleOutput
! Check that this is the case; if not set PartLoadRatio = 0.0d0 (off) and return
IF(FullSensibleOutput.GT.NoSensibleOutput)THEN
PartLoadRatio = MAX(MinPLR, MIN(1.0d0, ABS(SystemSensibleLoad-NoSensibleOutput) &
/ ABS(FullSensibleOutput-NoSensibleOutput)))
IF (OpMode .EQ. CycFanCycCoil) THEN
Node(FurnaceInletNode)%MassFlowRate = Furnace(FurnaceNum)%MdotFurnace * PartLoadRatio
HeatCoilLoad = Furnace(FurnaceNum)%DesignHeatingCapacity * PartLoadRatio
ELSE ! ContFanCycCoil
IF(Node(FurnaceOutletNode)%Temp .GT. Furnace(FurnaceNum)%DesignMaxOutletTemp) THEN
deltaT = Node(FurnaceOutletNode)%Temp-Furnace(FurnaceNum)%DesignMaxOutletTemp
IF(HeatCoilLoad .GT. Furnace(FurnaceNum)%DesignHeatingCapacity) &
HeatCoilLoad = Furnace(FurnaceNum)%DesignHeatingCapacity
HeatCoilLoad = HeatCoilLoad - Node(FurnaceInletNode)%MassFlowRate * cpair * deltaT
ELSE
HeatCoilLoad = SystemSensibleLoad - NoSensibleOutput
END IF
END IF
! Calculate the part load ratio through iteration
HeatErrorToler = Furnace(FurnaceNum)%HeatingConvergenceTolerance !Error tolerance for convergence from input deck
Error = 1.0d0 ! initialize error value for comparison against tolerance
Iter = 0 ! initialize iteration counter
IterRelax = 0.9d0 ! relaxation factor for iterations
DO WHILE (Iter .LE. MaxIter)
IF (OpMode .EQ. CycFanCycCoil) Node(FurnaceInletNode)%MassFlowRate = Furnace(FurnaceNum)%MdotFurnace * PartLoadRatio
CALL CalcFurnaceOutput(FurnaceNum,FirstHVACIteration,OpMode,On,0.0d0,PartLoadRatio, &
HeatCoilLoad,0.0d0,ActualSensibleOutput,ActualLatentOutput, OnOffAirFlowRatio, .FALSE.)
IF(SystemSensibleLoad .NE. 0.0d0) Error=(SystemSensibleLoad-ActualSensibleOutput)/(SystemSensibleLoad)
IF(ABS(Error) .LE. HeatErrorToler) EXIT
PartLoadRatio = MAX(MinPLR,MIN(1.0d0,PartLoadRatio + IterRelax*&
(SystemSensibleLoad-ActualSensibleOutput)/(FullSensibleOutput-NoSensibleOutput)))
! limit the heating coil outlet air temperature to DesignMaxOutletTemp
IF(Node(FurnaceOutletNode)%Temp .GT. Furnace(FurnaceNum)%DesignMaxOutletTemp) THEN
deltaT = Node(FurnaceOutletNode)%Temp-Furnace(FurnaceNum)%DesignMaxOutletTemp
IF(HeatCoilLoad .GT. Furnace(FurnaceNum)%DesignHeatingCapacity) &
HeatCoilLoad = Furnace(FurnaceNum)%DesignHeatingCapacity
HeatCoilLoad = HeatCoilLoad - Node(FurnaceInletNode)%MassFlowRate * cpair * deltaT
CALL CalcFurnaceOutput(FurnaceNum,FirstHVACIteration,OpMode,On,0.0d0,PartLoadRatio, &
HeatCoilLoad,0.0d0,ActualSensibleOutput,ActualLatentOutput, OnOffAirFlowRatio, .FALSE.)
IF(SystemSensibleLoad .NE. 0.0d0) Error=(SystemSensibleLoad-ActualSensibleOutput)/(SystemSensibleLoad)
PartLoadRatio = MAX(MinPLR,MIN(1.0d0,PartLoadRatio + IterRelax* &
(SystemSensibleLoad-ActualSensibleOutput)/(FullSensibleOutput-NoSensibleOutput)))
ELSE
HeatCoilLoad = Furnace(FurnaceNum)%DesignHeatingCapacity * PartLoadRatio
END IF
IF(PartLoadRatio.eq.MinPLR)EXIT
IF(PartLoadRatio.eq.1.0d0)EXIT
Iter = Iter + 1
IF(Iter.eq.7)IterRelax=0.7d0
IF(Iter.eq.15)IterRelax=0.4d0
END DO
IF (Iter .GT. MaxIter) THEN
IF (Furnace(FurnaceNum)%HeatingMaxIterIndex2 == 0) THEN
CALL ShowWarningMessage(TRIM(cFurnaceTypes(Furnace(FurnaceNum)%FurnaceType_Num))//' "'&
//TRIM(Furnace(FurnaceNum)%Name)//'" -- Exceeded max heating iterations ('// &
TRIM(TrimSigDigits(MaxIter))// &
') while adjusting furnace runtime.')
CALL ShowContinueErrorTimeStamp(' ')
ENDIF
CALL ShowRecurringWarningErrorAtEnd(TRIM(cFurnaceTypes(Furnace(FurnaceNum)%FurnaceType_Num))//' "'// &
TRIM(Furnace(FurnaceNum)%Name)//'" -- Exceeded max heating iterations error continues...', &
Furnace(FurnaceNum)%HeatingMaxIterIndex2)
END IF
ELSE !ELSE from IF(FullSensibleOutput.GT.NoSensibleOutput)THEN above
! Set part load ratio to 1 and run heater at design heating capacity
PartLoadRatio = 1.0d0
HeatCoilLoad = Furnace(FurnaceNum)%DesignHeatingCapacity
END IF
! Set the final results
! IF (OpMode .EQ. CycFanCycCoil) THEN
! Furnace(FurnaceNum)%MdotFurnace = Furnace(FurnaceNum)%MdotFurnace * PartLoadRatio
! END IF
Furnace(FurnaceNum)%MdotFurnace = Node(FurnaceInletNode)%MassFlowRate
ELSEIF((GetCurrentScheduleValue(Furnace(FurnaceNum)%SchedPtr) .gt. 0.0d0) .and. &
(Node(FurnaceInletNode)%MassFlowRate .gt. 0.0d0) .and. (OpMode .EQ. ContFanCycCoil)) THEN
HeatCoilLoad = 0.0d0
ELSE ! no heating and no flow
Furnace(FurnaceNum)%MdotFurnace = 0.0d0
HeatCoilLoad = 0.0d0
END IF ! End of the Scheduled Furnace If block
END IF ! End of the FirstHVACIteration control of the mass flow If block
! Set the fan inlet node flow rates
Node(FurnaceInletNode)%MassFlowRateMaxAvail = Furnace(FurnaceNum)%MdotFurnace
Node(FurnaceInletNode)%MassFlowRate = Furnace(FurnaceNum)%MdotFurnace
RETURN
END Subroutine CalcNewZoneHeatOnlyFlowRates