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), | optional | :: | ZoneToResimulate | 
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 CalcHeatBalanceOutsideSurf(ZoneToResimulate)
          ! SUBROUTINE INFORMATION:
          !       AUTHOR         George Walton
          !       DATE WRITTEN   December 1979
          !       MODIFIED       Jun 1990 (RDT for new CTF arrays);
          !                      Aug 2000 (RJL for MTF moisture calculations)
          !                      Sep 2000 (RKS for new radiant exchange algorithm)
          !                      Dec 2000 (RKS for radiant system model addition)
          !                      Apr 2002 (COP removed denominator from OSC calculation
          !                      Jul 2008 (P.Biddulph include calls to HAMT)
          !                      Jul 2011, M.J. Witte and C.O. Pedersen, add new fields to OSC for last T, max and min
          !                      Sep 2011 LKL/BG - resimulate only zones needing it for Radiant systems
          !       RE-ENGINEERED  Mar 1998 (RKS)
          ! PURPOSE OF THIS SUBROUTINE:
          ! This subroutine performs a heat balance on the outside face of each
          ! surface in the building.
          ! METHODOLOGY EMPLOYED:
          ! Various boundary conditions are set and additional parameters are set-
          ! up.  Then, the proper heat balance equation is selected based on the
          ! presence of movable insulation, thermal mass of the surface construction,
          ! and convection model being used.
          ! REFERENCES:
          ! (I)BLAST legacy routine HBOUT
          ! 1989 ASHRAE Handbook of Fundamentals (Figure 1 on p. 22.4, convection correlations)
          ! USE STATEMENTS:
  USE DataPrecisionGlobals
  USE DataGlobals
  USE DataEnvironment
  USE DataHeatBalFanSys
  USE DataHeatBalance
  USE DataHeatBalSurface
  USE DataSurfaces
  USE DataMoistureBalance,          ONLY : TempOutsideAirFD,RhoVaporAirOut,RhoVaporAirIn,HConvExtFD,HMassConvExtFD, &
                                           HConvInFD,HMassConvInFD,RhoVaporSurfIn, &
                                           HSkyFD,HGrndFD,HAirFD
  USE HeatBalanceMovableInsulation, ONLY : EvalOutsideMovableInsulation
  USE ConvectionCoefficients,       ONLY : InitExteriorConvectionCoeff, SetExtConvectionCoeff, SetIntConvectionCoeff
  USE HeatBalanceIntRadExchange,    ONLY : CalcInteriorRadExchange
  USE ScheduleManager,              ONLY : GetCurrentScheduleValue, GetScheduleIndex
  USE Psychrometrics
  USE EcoRoofManager, ONLY : CalcEcoRoof
  IMPLICIT NONE    ! Enforce explicit typing of all variables in this routine
          ! SUBROUTINE ARGUMENT DEFINITIONS:
  INTEGER, INTENT(IN), OPTIONAL :: ZoneToResimulate  ! if passed in, then only calculate surfaces that have this zone
          ! SUBROUTINE PARAMETER DEFINITIONS:
          ! na
          ! INTERFACE BLOCK SPECIFICATIONS:
          ! na
          ! DERIVED TYPE DEFINITIONS:
          ! na
          ! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
  REAL(r64)    :: AbsThermSurf        ! Thermal absoptance of the exterior surface
  INTEGER :: ConstrNum           ! Construction index for the current surface
  REAL(r64)    :: HGround             ! "Convection" coefficient from ground to surface
  REAL(r64)    :: HMovInsul           ! "Convection" coefficient of movable insulation
  REAL(r64)    :: HSky                ! "Convection" coefficient from sky to surface
  REAL(r64)    :: HAir                ! "Convection" coefficient from air to surface (radiation)
  REAL(r64)  :: ConstantTempCoef      ! Temperature Coefficient as input or modified using sine wave  COP mod
  INTEGER :: RoughSurf           ! Roughness index of the exterior surface
  INTEGER :: SurfNum             ! Surface number DO loop counter
  REAL(r64)    :: TempExt             ! Exterior temperature boundary condition
  INTEGER :: ZoneNum             ! Zone number the current surface is attached to
  INTEGER :: OPtr
  REAL(r64)    :: RhoVaporSat         ! Local temporary saturated vapor density for checking
          ! FUNCTION DEFINITIONS:
          ! na
          ! FLOW:
  DO SurfNum = 1, TotSurfaces
          ! Need to transfer any source/sink for a surface to the local array.  Note that
          ! the local array is flux (W/m2) while the QRadSysSource is heat transfer (W).
          ! This must be done at this location so that this is always updated correctly.
    IF (Surface(SurfNum)%Area > 0.0d0) &  ! Make sure we don't divide by zero...
      QsrcHist(SurfNum,1) = QRadSysSource(SurfNum)/Surface(SurfNum)%Area
          ! next we add source (actually a sink) from any integrated PV
    IF (Surface(SurfNum)%Area > 0.0d0) & ! Make sure we don't divide by zero...
      QsrcHist(SurfNum,1) = QsrcHist(SurfNum,1) + QPVSysSource(SurfNum)/Surface(SurfNum)%Area
  END DO
  IF (PRESENT(ZoneToResimulate)) THEN
    CALL CalcInteriorRadExchange(TH(:,1,2),0,NetLWRadToSurf, ZoneToResimulate,calledfrom='Outside')
  ELSE
    CALL CalcInteriorRadExchange(TH(:,1,2),0,NetLWRadToSurf,calledfrom='Outside')
  ENDIF
  DO SurfNum = 1, TotSurfaces   ! Loop through all surfaces...
    ZoneNum = Surface(SurfNum)%Zone
    IF (PRESENT(ZoneToResimulate)) THEN
      IF ((ZoneNum /= ZoneToResimulate) .AND. (AdjacentZoneToSurface(SurfNum) /= ZoneToResimulate)) THEN
        CYCLE ! skip surfaces that are not associated with this zone
      ENDIF
    ENDIF
    IF (.NOT. Surface(SurfNum)%HeatTransSurf .OR. ZoneNum == 0) CYCLE  ! Skip non-heat transfer surfaces
    IF(Surface(SurfNum)%Class == SurfaceClass_Window) CYCLE
    ! Interior windows in partitions use "normal" heat balance calculations
    ! For rest, Outside surface temp of windows not needed in Window5 calculation approach.
    ! Window layer temperatures are calculated in CalcHeatBalanceInsideSurf
          ! Initializations for this surface
    ConstrNum       = Surface(SurfNum)%Construction
    HMovInsul       = 0.0d0
    HSky            = 0.0d0
    HGround         = 0.0d0
    HAir            = 0.0d0
    HcExtSurf(SurfNum)   = 0.0d0
    HAirExtSurf(SurfNum) = 0.0d0
    HSkyExtSurf(SurfNum) = 0.0d0
    HGrdExtSurf(SurfNum) = 0.0d0
          ! Calculate the current outside surface temperature TH(SurfNum,1,1) for the
          ! various different boundary conditions
    SELECT CASE(Surface(SurfNum)%ExtBoundCond)
    CASE(Ground)     ! Surface in contact with ground
      TH(SurfNum,1,1) = GroundTemp
        ! Set the only radiant system heat balance coefficient that is non-zero for this case
      IF (Construct(ConstrNum)%SourceSinkPresent) RadSysToHBConstCoef(SurfNum) = TH(SurfNum,1,1)
! start HAMT
      IF (Surface(SurfNum)%HeatTransferAlgorithm  == HeatTransferModel_HAMT) THEN
      ! Set variables used in the HAMT moisture balance
        TempOutsideAirFD(SurfNum)= GroundTemp
        RhoVaporAirOut(SurfNum)=PsyRhovFnTdbRh(GroundTemp,1.0d0,'HBSurfMan:Ground:HAMT')
        HConvExtFD(Surfnum)=HighHConvLimit
        HMassConvExtFD(SurfNum)=HConvExtFD(SurfNum)/((PsyRhoAirFnPbTdbW(OutBaroPress,GroundTemp,  &
             PsyWFnTdbRhPb(GroundTemp,1.0d0,OutBaroPress,'CalcHeatBalanceOutsideSurf:GroundTemp'))+  &
             RhoVaporAirOut(SurfNum))*PsyCpAirFnWTdb(OutHumRat,GroundTemp))
        HSkyFD(SurfNum) = HSky
        HGrndFD(SurfNum) = HGround
        HAirFD(SurfNum) = HAir
      ENDIF
! end HAMT
      IF (Surface(SurfNum)%HeatTransferAlgorithm == HeatTransferModel_CondFD ) THEN
      ! Set variables used in the FD moisture balance
        TempOutsideAirFD(SurfNum)= GroundTemp
        RhoVaporAirOut(SurfNum)=PsyRhovFnTdbRhLBnd0C(GroundTemp,1.0d0,'HBSurfMan:Ground:CondFD')
        HConvExtFD(Surfnum)=HighHConvLimit
        HMassConvExtFD(SurfNum)=HConvExtFD(SurfNum)/((PsyRhoAirFnPbTdbW(OutBaroPress,GroundTemp,  &
             PsyWFnTdbRhPb(GroundTemp,1.0d0,OutBaroPress,'CalcHeatBalanceOutsideSurf:GroundTemp'))+  &
             RhoVaporAirOut(SurfNum))*PsyCpAirFnWTdb(OutHumRat,GroundTemp))
        HSkyFD(SurfNum) = HSky
        HGrndFD(SurfNum) = HGround
        HAirFD(SurfNum) = HAir
      ENDIF
    ! Added for FCfactor grounds
    CASE(GroundFCfactorMethod)     ! Surface in contact with ground
      TH(SurfNum,1,1) = GroundTempFC
      ! Set the only radiant system heat balance coefficient that is non-zero for this case
      IF (Construct(ConstrNum)%SourceSinkPresent) RadSysToHBConstCoef(SurfNum) = TH(SurfNum,1,1)
      IF (Surface(SurfNum)%HeatTransferAlgorithm == HeatTransferModel_HAMT) THEN
      ! Set variables used in the HAMT moisture balance
        TempOutsideAirFD(SurfNum)= GroundTempFC
        RhoVaporAirOut(SurfNum)=PsyRhovFnTdbRh(GroundTempFC,1.0d0,'HBSurfMan:GroundFC:HAMT')
        HConvExtFD(Surfnum)=HighHConvLimit
        HMassConvExtFD(SurfNum)=HConvExtFD(SurfNum)/((PsyRhoAirFnPbTdbW(OutBaroPress,GroundTempFC,  &
             PsyWFnTdbRhPb(GroundTempFC,1.0d0,OutBaroPress,'CalcHeatBalanceOutsideSurf:GroundTempFC'))+  &
             RhoVaporAirOut(SurfNum))*PsyCpAirFnWTdb(OutHumRat,GroundTempFC))
        HSkyFD(SurfNum) = HSky
        HGrndFD(SurfNum) = HGround
        HAirFD(SurfNum) = HAir
      ENDIF
      IF (Surface(SurfNum)%HeatTransferAlgorithm == HeatTransferModel_CondFD ) THEN
      ! Set variables used in the FD moisture balance
        TempOutsideAirFD(SurfNum)= GroundTempFC
        RhoVaporAirOut(SurfNum)=PsyRhovFnTdbRhLBnd0C(GroundTempFC,1.0d0,'HBSurfMan:GroundFC:CondFD')
        HConvExtFD(Surfnum)=HighHConvLimit
        HMassConvExtFD(SurfNum)=HConvExtFD(SurfNum)/((PsyRhoAirFnPbTdbW(OutBaroPress,GroundTempFC,  &
             PsyWFnTdbRhPb(GroundTempFC,1.0d0,OutBaroPress,'CalcHeatBalanceOutsideSurf:GroundTempFC'))+  &
             RhoVaporAirOut(SurfNum))*PsyCpAirFnWTdb(OutHumRat,GroundTempFC))
        HSkyFD(SurfNum) = HSky
        HGrndFD(SurfNum) = HGround
        HAirFD(SurfNum) = HAir
      ENDIF
    CASE(OtherSideCoefNoCalcExt)
          ! Use Other Side Coefficients to determine the surface film coefficient and
          ! the exterior boundary condition temperature
      OPtr=Surface(SurfNum)%OSCPtr
          ! Set surface temp from previous timestep
      IF(BeginTimeStepFlag) THEN
        OSC(OPtr)%TOutsideSurfPast = TH(SurfNum,1,1)
      ENDIF
      IF (OSC(OPtr)%ConstTempScheduleIndex /= 0) THEN ! Determine outside temperature from schedule
         OSC(OPtr)%ConstTemp = GetCurrentScheduleValue(OSC(OPtr)%ConstTempScheduleIndex)
      ENDIF
      !  Allow for modification of TemperatureCoefficient with unitary sine wave.
      IF (OSC(OPtr)%SinusoidalConstTempCoef )THEN   ! Sine wave C4
         ConstantTempCoef = sin( 2*PI * CurrentTime/OSC(OPtr)%SinusoidPeriod)
      ELSE
         ConstantTempCoef = OSC(OPtr)%ConstTempCoef
      END IF
      OSC(OPtr)%OSCTempCalc = ( OSC(OPtr)%ZoneAirTempCoef*MAT(ZoneNum)      &
                                 +OSC(OPtr)%ExtDryBulbCoef*Surface(SurfNum)%OutDryBulbTemp &
                                 + ConstantTempCoef                         &
                                  *OSC(OPtr)%ConstTemp                        &
                                 +OSC(OPtr)%GroundTempCoef*GroundTemp &
                                 +OSC(OPtr)%WindSpeedCoef*Surface(SurfNum)%WindSpeed*Surface(SurfNum)%OutDryBulbTemp &
                                 +OSC(OPtr)%TPreviousCoef*OSC(OPtr)%TOutsideSurfPast)
            ! Enforce max/min limits if applicable
      IF(OSC(OPtr)%MinLimitPresent) OSC(OPtr)%OSCTempCalc = MAX(OSC(OPtr)%MinTempLimit,OSC(OPtr)%OSCTempCalc)
      IF(OSC(OPtr)%MaxLimitPresent) OSC(OPtr)%OSCTempCalc = MIN(OSC(OPtr)%MaxTempLimit,OSC(OPtr)%OSCTempCalc)
      TH(SurfNum,1,1) = OSC(OPtr)%OSCTempCalc
          ! Set the only radiant system heat balance coefficient that is non-zero for this case
        IF (Construct(ConstrNum)%SourceSinkPresent) RadSysToHBConstCoef(SurfNum) = TH(SurfNum,1,1)
        IF (Surface(SurfNum)%HeatTransferAlgorithm == HeatTransferModel_CondFD .OR. &
            Surface(SurfNum)%HeatTransferAlgorithm == HeatTransferModel_HAMT ) THEN
        ! Set variables used in the FD moisture balance and HAMT
          TempOutsideAirFD(SurfNum)= TH(SurfNum,1,1)
          RhoVaporAirOut(SurfNum)=PsyRhovFnTdbWPb(TempOutsideAirFD(SurfNum),OutHumRat,OutBaroPress)
          HConvExtFD(SurfNum)=HighHConvLimit
          HMassConvExtFD(SurfNum)=HConvExtFD(SurfNum)/((PsyRhoAirFnPbTdbW(OutBaroPress,TempOutsideAirFD(SurfNum),  &
               PsyWFnTdbRhPb(TempOutsideAirFD(SurfNum),1.0D0,OutBaroPress,  &
                  'CalcHeatBalanceOutsideSurf:OtherSideCoefNoCalcExt'))+  &
               RhoVaporAirOut(SurfNum))*PsyCpAirFnWTdb(OutHumRat,TempOutsideAirFD(SurfNum)))
          HSkyFD(SurfNum) = HSky
          HGrndFD(SurfNum) = HGround
          HAirFD(SurfNum) = HAir
        ENDIF
          ! This ends the calculations for this surface and goes on to the next SurfNum
    CASE(OtherSideCoefCalcExt) ! A surface with other side coefficients that define the outside environment
          ! First, set up the outside convection coefficient and the exterior temperature
          ! boundary condition for the surface
      OPtr=Surface(SurfNum)%OSCPtr
          ! Set surface temp from previous timestep
      IF(BeginTimeStepFlag) THEN
        OSC(OPtr)%TOutsideSurfPast = TH(SurfNum,1,1)
      ENDIF
      IF (OSC(OPtr)%ConstTempScheduleIndex /= 0) THEN ! Determine outside temperature from schedule
         OSC(OPtr)%ConstTemp = GetCurrentScheduleValue(OSC(OPtr)%ConstTempScheduleIndex)
      ENDIF
      HcExtSurf(SurfNum) = OSC(OPtr)%SurfFilmCoef
      OSC(OPtr)%OSCTempCalc = ( OSC(OPtr)%ZoneAirTempCoef*MAT(ZoneNum)      &
                    +OSC(OPtr)%ExtDryBulbCoef*Surface(SurfNum)%OutDryBulbTemp &
                    +OSC(OPtr)%ConstTempCoef*OSC(OPtr)%ConstTemp &
                    +OSC(OPtr)%GroundTempCoef*GroundTemp         &
                    +OSC(OPtr)%WindSpeedCoef*Surface(SurfNum)%WindSpeed*Surface(SurfNum)%OutDryBulbTemp &
                    +OSC(OPtr)%TPreviousCoef*OSC(OPtr)%TOutsideSurfPast)
            ! Enforce max/min limits if applicable
      IF(OSC(OPtr)%MinLimitPresent) OSC(OPtr)%OSCTempCalc = MAX(OSC(OPtr)%MinTempLimit,OSC(OPtr)%OSCTempCalc)
      IF(OSC(OPtr)%MaxLimitPresent) OSC(OPtr)%OSCTempCalc = MIN(OSC(OPtr)%MaxTempLimit,OSC(OPtr)%OSCTempCalc)
      TempExt  = OSC(OPtr)%OSCTempCalc
          ! Set the only radiant system heat balance coefficient that is non-zero for this case
      IF (Construct(ConstrNum)%SourceSinkPresent) RadSysToHBConstCoef(SurfNum) = TH(SurfNum,1,1)
      IF ( Surface(SurfNum)%HeatTransferAlgorithm  == HeatTransferModel_CondFD .OR. &
            Surface(SurfNum)%HeatTransferAlgorithm == HeatTransferModel_HAMT ) THEN
      ! Set variables used in the FD moisture balance and HAMT
        TempOutsideAirFD(SurfNum)= TempExt
        RhoVaporAirOut(SurfNum)=PsyRhovFnTdbWPb(TempOutsideAirFD(SurfNum),OutHumRat,OutBaroPress)
        HConvExtFD(SurfNum)=HcExtSurf(SurfNum)
        HMassConvExtFD(SurfNum)=HConvExtFD(SurfNum)/((PsyRhoAirFnPbTdbW(OutBaroPress,TempOutsideAirFD(SurfNum),  &
             PsyWFnTdbRhPb(TempOutsideAirFD(SurfNum),1.0d0,OutBaroPress,'CalcHeatBalanceOutsideSurf:OtherSideCoefCalcExt'))+  &
             RhoVaporAirOut(SurfNum))*PsyCpAirFnWTdb(OutHumRat,TempOutsideAirFD(SurfNum)))
        HSkyFD(SurfNum) = HSkyExtSurf(SurfNum)
        HGrndFD(SurfNum)= HGrdExtSurf(SurfNum)
        HAirFD(SurfNum) = HAirExtSurf(SurfNum)
      ENDIF
      ! Call the outside surface temp calculation and pass the necessary terms
      IF (Surface(SurfNum)%HeatTransferAlgorithm == HeatTransferModel_CTF .OR. &
          Surface(SurfNum)%HeatTransferAlgorithm == HeatTransferModel_EMPD) &
        CALL CalcOutsideSurfTemp(SurfNum,ZoneNum,ConstrNum,HMovInsul,TempExt)
          ! This ends the calculations for this surface and goes on to the next SurfNum
    CASE(OtherSideCondModeledExt) ! A surface with other side conditions determined from seperate, dynamic component
    !                               modeling that defines the "outside environment"
          ! First, set up the outside convection coefficient and the exterior temperature
          ! boundary condition for the surface
      OPtr=Surface(SurfNum)%OSCMPtr
      ! EMS overrides
      IF (OSCM(OPtr)%EMSOverrideOnTConv) OSCM(OPtr)%TConv = OSCM(OPtr)%EMSOverrideTConvValue
      IF (OSCM(OPtr)%EMSOverrideOnHConv) OSCM(OPtr)%HConv = OSCM(OPtr)%EMSOverrideHConvValue
      IF (OSCM(OPtr)%EMSOverrideOnTRad)  OSCM(OPtr)%TRad  = OSCM(OPtr)%EMSOverrideTRadValue
      IF (OSCM(OPtr)%EMSOverrideOnHrad)  OSCM(OPtr)%Hrad  = OSCM(OPtr)%EMSOverrideHradValue
      HcExtSurf(SurfNum) = OSCM(OPtr)%Hconv
      TempExt  = OSCM(OPtr)%TConv
          ! Set the only radiant system heat balance coefficient that is non-zero for this case
      IF (Construct(ConstrNum)%SourceSinkPresent) RadSysToHBConstCoef(SurfNum) = TH(SurfNum,1,1)
      IF (Surface(SurfNum)%HeatTransferAlgorithm == HeatTransferModel_CondFD .OR. &
          Surface(SurfNum)%HeatTransferAlgorithm == HeatTransferModel_HAMT ) THEN
      ! Set variables used in the FD moisture balance and HAMT
        TempOutsideAirFD(SurfNum)= TempExt
        RhoVaporAirOut(SurfNum)=PsyRhovFnTdbWPb(TempOutsideAirFD(SurfNum),OutHumRat,OutBaroPress)
        HConvExtFD(SurfNum)=HcExtSurf(SurfNum)
        HMassConvExtFD(SurfNum)=HConvExtFD(SurfNum)/((PsyRhoAirFnPbTdbW(OutBaroPress,TempOutsideAirFD(SurfNum),  &
             PsyWFnTdbRhPb(TempOutsideAirFD(SurfNum),1.0d0,OutBaroPress,'CalcHeatBalanceOutsideSurf:OSCM'))+  &
             RhoVaporAirOut(SurfNum))*PsyCpAirFnWTdb(OutHumRat,TempOutsideAirFD(SurfNum)))
        HSkyFD(SurfNum) = OSCM(OPtr)%Hrad !CR 8046, use sky term for surface to baffle IR
        HGrndFD(SurfNum)= 0.0D0 !CR 8046, null out and use only sky term for surface to baffle IR
        HAirFD(SurfNum) = 0.0D0 !CR 8046, null out and use only sky term for surface to baffle IR
      ENDIF
      ! Call the outside surface temp calculation and pass the necessary terms
      IF (Surface(SurfNum)%HeatTransferAlgorithm == HeatTransferModel_CTF .OR. &
          Surface(SurfNum)%HeatTransferAlgorithm == HeatTransferModel_EMPD) THEN
        IF ( Surface(SurfNum)%ExtCavityPresent ) THEN
          CALL CalcExteriorVentedCavity(SurfNum)
        ENDIF
        CALL CalcOutsideSurfTemp(SurfNum,ZoneNum,ConstrNum,HMovInsul,TempExt)
      ELSEIF (Surface(SurfNum)%HeatTransferAlgorithm == HeatTransferModel_CondFD .OR. &
              Surface(SurfNum)%HeatTransferAlgorithm == HeatTransferModel_HAMT ) THEN
        IF ( Surface(SurfNum)%ExtCavityPresent ) THEN
          CALL CalcExteriorVentedCavity(SurfNum)
        ENDIF
      END IF
          ! This ends the calculations for this surface and goes on to the next SurfNum
    CASE(ExternalEnvironment)
      !checking the EcoRoof presented in the external environment
      ! recompute each load by calling ecoroof
      IF(Surface(SurfNum)%ExtEcoRoof ) THEN
        CALL CalcEcoRoof(SurfNum,ZoneNum,ConstrNum,TempExt)
        CYCLE
      END IF
      IF(SurfaceWindow(SurfNum)%StormWinFlag==1) ConstrNum = Surface(SurfNum)%StormWinConstruction
      RoughSurf    = Material(Construct(ConstrNum)%LayerPoint(1))%Roughness
      AbsThermSurf = Material(Construct(ConstrNum)%LayerPoint(1))%AbsorpThermal
      ! Check for outside movable insulation
      IF (Surface(SurfNum)%MaterialMovInsulExt > 0) &
        CALL EvalOutsideMovableInsulation(SurfNum,HMovInsul,RoughSurf,AbsThermSurf)
      ! Check for exposure to wind (exterior environment)
      IF (Surface(SurfNum)%ExtWind) THEN
        ! Calculate exterior heat transfer coefficients with windspeed (windspeed is calculated internally in subroutine)
        CALL InitExteriorConvectionCoeff(SurfNum,HMovInsul,RoughSurf,AbsThermSurf,TH(SurfNum,1,1), &
          HcExtSurf(SurfNum),HSkyExtSurf(SurfNum),HGrdExtSurf(SurfNum),HAirExtSurf(SurfNum))
        IF (IsRain) THEN ! Raining: since wind exposed, outside surface gets wet
          IF (Surface(SurfNum)%ExtConvCoeff <= 0) THEN ! Reset HcExtSurf because of wetness
            HcExtSurf(SurfNum) = 1000.d0
          ELSE  ! User set
            HcExtSurf(SurfNum) = SetExtConvectionCoeff(SurfNum)
          ENDIF
          TempExt = Surface(SurfNum)%OutWetBulbTemp
! start HAMT
          IF (Surface(SurfNum)%HeatTransferAlgorithm == HeatTransferModel_HAMT) THEN
            ! Set variables used in the HAMT moisture balance
            TempOutsideAirFD(SurfNum)= TempExt
            RhoVaporAirOut(SurfNum)=PsyRhovFnTdbRh(TempOutsideAirFD(SurfNum),1.0d0,'HBSurfMan:Rain:HAMT')
            HConvExtFD(SurfNum)=HcExtSurf(SurfNum)
            HMassConvExtFD(SurfNum)=HConvExtFD(SurfNum)/((PsyRhoAirFnPbTdbW(OutBaroPress,TempOutsideAirFD(SurfNum), &
                PsyWFnTdbRhPb(TempOutsideAirFD(SurfNum),1.0d0,OutBaroPress,'CalcHeatBalanceOutsideSurf:extEnvWetSurf'))+  &
                RhoVaporAirOut(SurfNum))*PsyCpAirFnWTdb(OutHumRat,TempOutsideAirFD(SurfNum)))
            HSkyFD(SurfNum) = HSkyExtSurf(SurfNum)
            HGrndFD(SurfNum)= HGrdExtSurf(SurfNum)
            HAirFD(SurfNum) = HAirExtSurf(SurfNum)
          ENDIF
! end HAMT
          IF (Surface(SurfNum)%HeatTransferAlgorithm == HeatTransferModel_CondFD ) THEN
            ! Set variables used in the FD moisture balance
            TempOutsideAirFD(SurfNum)= TempExt
            RhoVaporAirOut(SurfNum)=PsyRhovFnTdbRhLBnd0C(TempOutsideAirFD(SurfNum),1.0d0,'HBSurfMan:Rain:CondFD')
            HConvExtFD(SurfNum)=HcExtSurf(SurfNum)
            HMassConvExtFD(SurfNum)=HConvExtFD(SurfNum)/((PsyRhoAirFnPbTdbW(OutBaroPress,TempOutsideAirFD(SurfNum), &
                PsyWFnTdbRhPb(TempOutsideAirFD(SurfNum),1.0d0,OutBaroPress,'CalcHeatBalanceOutsideSurf:extEnvWetSurf'))+  &
                RhoVaporAirOut(SurfNum))*PsyCpAirFnWTdb(OutHumRat,TempOutsideAirFD(SurfNum)))
            HSkyFD(SurfNum) = HSkyExtSurf(SurfNum)
            HGrndFD(SurfNum)= HGrdExtSurf(SurfNum)
            HAirFD(SurfNum) = HAirExtSurf(SurfNum)
          ENDIF
        ELSE ! Surface is dry, use the normal correlation
          TempExt = Surface(SurfNum)%OutDryBulbTemp
          IF (Surface(SurfNum)%HeatTransferAlgorithm == HeatTransferModel_CondFD .OR. &
              Surface(SurfNum)%HeatTransferAlgorithm == HeatTransferModel_HAMT) THEN
            ! Set variables used in the FD moisture balance and HAMT
            TempOutsideAirFD(SurfNum)= TempExt
            RhoVaporAirOut(SurfNum)=PsyRhovFnTdbWPb(TempOutsideAirFD(SurfNum),OutHumRat,OutBaroPress)
            HConvExtFD(SurfNum)=HcExtSurf(SurfNum)
            HMassConvExtFD(SurfNum)=HConvExtFD(SurfNum)/((PsyRhoAirFnPbTdbW(OutBaroPress,TempOutsideAirFD(SurfNum), &
                PsyWFnTdbRhPb(TempOutsideAirFD(SurfNum),1.0d0,OutBaroPress,'CalcHeatBalanceOutsideSurf:extEnvDrySurf'))+  &
                RhoVaporAirOut(SurfNum))*PsyCpAirFnWTdb(OutHumRat,TempOutsideAirFD(SurfNum)))
             !  check for saturation conditions of air
            RhoVaporSat=PsyRhovFnTdbRh(TempOutsideAirFD(SurfNum),1.0d0,'HBSurfMan:DrySurf:CondFD')
            IF(RhoVaporAirOut(SurfNum) .gt. RhoVaporSat) RhoVaporAirOut(SurfNum)=RhoVaporSat
            HSkyFD(SurfNum) = HSkyExtSurf(SurfNum)
            HGrndFD(SurfNum)= HGrdExtSurf(SurfNum)
            HAirFD(SurfNum) = HAirExtSurf(SurfNum)
          ENDIF
        END IF
      ELSE ! No wind
        ! Calculate exterior heat transfer coefficients for windspeed = 0
        CALL InitExteriorConvectionCoeff(SurfNum,HMovInsul,RoughSurf,AbsThermSurf,TH(SurfNum,1,1), &
          HcExtSurf(SurfNum),HSkyExtSurf(SurfNum),HGrdExtSurf(SurfNum),HAirExtSurf(SurfNum))
        TempExt = Surface(SurfNum)%OutDryBulbTemp
        IF (Surface(SurfNum)%HeatTransferAlgorithm  == HeatTransferModel_CondFD .OR.      &
            Surface(SurfNum)%HeatTransferAlgorithm == HeatTransferModel_HAMT) THEN
          ! Set variables used in the FD moisture balance and HAMT
          TempOutsideAirFD(SurfNum)= TempExt
          RhoVaporAirOut(SurfNum)=PsyRhovFnTdbWPb(TempOutsideAirFD(SurfNum),OutHumRat,OutBaroPress)
          HConvExtFD(SurfNum)=HcExtSurf(SurfNum)
          HMassConvExtFD(SurfNum)=HConvExtFD(SurfNum)/((PsyRhoAirFnPbTdbW(OutBaroPress,TempOutsideAirFD(SurfNum), &
              PsyWFnTdbRhPb(TempOutsideAirFD(SurfNum),1.0d0,OutBaroPress,'CalcHeatBalanceOutsideSurf:nowind'))+  &
              RhoVaporAirOut(SurfNum))*PsyCpAirFnWTdb(OutHumRat,TempOutsideAirFD(SurfNum)))
          HSkyFD(SurfNum) = HSkyExtSurf(SurfNum)
          HGrndFD(SurfNum)= HGrdExtSurf(SurfNum)
          HAirFD(SurfNum) = HAirExtSurf(SurfNum)
        ENDIF
      END IF
      IF (Surface(SurfNum)%HeatTransferAlgorithm == HeatTransferModel_CTF .OR. &
          Surface(SurfNum)%HeatTransferAlgorithm == HeatTransferModel_EMPD)   &
          CALL CalcOutsideSurfTemp(SurfNum,ZoneNum,ConstrNum,HMovInsul,TempExt)
    CASE DEFAULT   ! for interior or other zone surfaces
      IF (Surface(SurfNum)%ExtBoundCond == SurfNum) THEN  ! Regular partition/internal mass
        TH(SurfNum,1,1) = TempSurfIn(SurfNum)
        ! No need to set any radiant system heat balance coefficients here--will be done during inside heat balance
        IF (Surface(SurfNum)%HeatTransferAlgorithm  == HeatTransferModel_CondFD .OR.      &
            Surface(SurfNum)%HeatTransferAlgorithm == HeatTransferModel_HAMT) THEN
          ! Set variables used in the FD moisture balance HAMT
          TempOutsideAirFD(SurfNum)= TempSurfIn(SurfNum)
          RhoVaporAirOut(SurfNum)=RhoVaporAirIn(SurfNum)
          HConvExtFD(SurfNum)=HConvIn(SurfNum)
          HMassConvExtFD(SurfNum)=HConvExtFD(SurfNum)/((PsyRhoAirFnPbTdbW(OutBaroPress,TempOutsideAirFD(SurfNum),  &
              PsyWFnTdbRhPb(TempOutsideAirFD(SurfNum),1.0d0,OutBaroPress,'CalcHeatBalanceOutsideSurf:interior/other'))+  &
              RhoVaporAirOut(SurfNum))*PsyCpAirFnWTdb(OutHumRat,TempOutsideAirFD(SurfNum)))
          HSkyFD(SurfNum) = 0.0d0
          HGrndFD(SurfNum) = 0.0d0
          HAirFD(SurfNum) = 0.0d0
        ENDIF
      ELSE  ! Interzone partition
        TH(SurfNum,1,1) = TH(Surface(SurfNum)%ExtBoundCond,1,2)
        ! No need to set any radiant system heat balance coefficients here--will be done during inside heat balance
        IF (Surface(SurfNum)%HeatTransferAlgorithm  == HeatTransferModel_CondFD .OR.      &
            Surface(SurfNum)%HeatTransferAlgorithm == HeatTransferModel_HAMT) THEN
          ! Set variables used in the FD moisture balance and HAMT
          TempOutsideAirFD(SurfNum)= TH(Surface(SurfNum)%ExtBoundCond,1,2)
          RhoVaporAirOut(SurfNum)=RhoVaporAirIn(Surface(SurfNum)%ExtBoundCond)
          HConvExtFD(SurfNum)=HConvIn(Surface(SurfNum)%ExtBoundCond)
          HMassConvExtFD(SurfNum)=HConvExtFD(SurfNum)/((PsyRhoAirFnPbTdbW(OutBaroPress,TempOutsideAirFD(SurfNum),  &
              PsyWFnTdbRhPb(TempOutsideAirFD(SurfNum),1.0d0,OutBaroPress,'CalcHeatBalanceOutsideSurf:IZPart'))+  &
              RhoVaporAirOut(SurfNum))*PsyCpAirFnWTdb(OutHumRat,TempOutsideAirFD(SurfNum)))
          HSkyFD(SurfNum) = 0.0d0
          HGrndFD(SurfNum) = 0.0d0
          HAirFD(SurfNum) = 0.0d0
        ENDIF
      END IF
          ! This ends the calculations for this surface and goes on to the next SurfNum
    END SELECT
    !fill in reporting values for outside face
    QdotConvOutRep(SurfNum)        = - Surface(SurfNum)%Area * HcExtSurf(SurfNum) *(TH(SurfNum,1,1) &
                                                               - Surface(SurfNum)%OutDryBulbTemp)
    IF (Surface(SurfNum)%OSCMPtr > 0) THEN !Optr is set above in this case, use OSCM boundary data
        QdotConvOutRepPerArea(SurfNum) = - OSCM(OPtr)%Hconv *(TH(SurfNum,1,1) - OSCM(OPtr)%Tconv)
    ELSE
        QdotConvOutRepPerArea(SurfNum) = - HcExtSurf(SurfNum) *(TH(SurfNum,1,1) - Surface(SurfNum)%OutDryBulbTemp)
    END IF
    QConvOutReport(SurfNum)        = QdotConvOutRep(SurfNum)* SecInHour * TimeStepZone
  END DO    ! ...end of DO loop over all surface (actually heat transfer surfaces)
  RETURN
END SUBROUTINE CalcHeatBalanceOutsideSurf