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