Skip to content
Snippets Groups Projects
snow_cover_1layer.F90 27.5 KiB
Newer Older
  • Learn to ignore specific revisions
  • !SFX_LIC Copyright 1994-2014 CNRS, Meteo-France and Universite Paul Sabatier
    !SFX_LIC This is part of the SURFEX software governed by the CeCILL-C licence
    !SFX_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt  
    !SFX_LIC for details. version 1.
    
    !     #########
    
        SUBROUTINE SNOW_COVER_1LAYER(CT, TOP, HPROGRAM, PTSTEP, PANSMIN, PANSMAX, PTODRY, PRHOSMIN, PRHOSMAX,   &
    
                                     PRHOFOLD, OALL_MELT, PDRAIN_TIME, PWCRN, PZ0SN, PZ0HSN, &
                                     TPSNOW, PTG, PTG_COEFA, PTG_COEFB, PABS_SW, PLW1, PLW2, &
                                     PTA, PQA, PVMOD, PPS, PRHOA, PSR, PZREF, PUREF, PRNSNOW,&
    
                                     PHSNOW, PLESNOW, PGSNOW, PMELT, PDQS_SNOW, PABS_LW, PEXP_ABS_LW, &
                                     PSEN_SNOW_DIF, PEMIT_LW_SNOW, PSNOW_HEAT, HTEST)
    
    !   ##########################################################################
    !
    !!****  *SNOW_COVER_1LAYER*  
    !!
    !!    PURPOSE
    !!    -------
    !
    !     One layer snow mantel scheme
    !         
    !     
    !!**  METHOD
    !     ------
    !
    !
    ! The temperature equation is written as:
    !
    !              b T+ = y
    !
    !
    !!    EXTERNAL
    !!    --------
    !!
    !!
    !!    IMPLICIT ARGUMENTS
    !!    ------------------
    !!
    !!    MODD_CST
    !!
    !!      
    !!    REFERENCE
    !!    ---------
    !!
    !!      
    !!    AUTHOR
    !!    ------
    !!
    
    !!      V. Masson           * Meteo-France *
    
    !!
    !!    MODIFICATIONS
    !!    -------------
    !!      Original    08/09/98 
    !!      J. Escobar 24/10/2012 : BUF PGI10.X , rewrite some 1 line WHERE statement
    
    !!      V. Masson  13/09/2013 : implicitation of coupling with roof below
    
    !!      M. Goret   04/09/2017 : add diagnostic of heat storage link to snow
    
    !-------------------------------------------------------------------------------
    !
    !*       0.     DECLARATIONS
    !               ------------
    !
    
    USE MODD_TEB_OPTION_n, ONLY : TEB_OPTIONS_t 
    
    USE MODD_TYPE_SNOW, ONLY : SURF_SNOW
    !
    
    USE MODD_CSTS,       ONLY : XTT, XCI, XRHOLI, XRHOLW, XCPD, XLSTT, XLMTT, XDAY, XCONDI, XSTEFAN, XSURF_EPSILON
    
    USE MODD_SNOW_PAR,   ONLY : XEMISSN
    USE MODD_SURF_PAR,   ONLY : XUNDEF
    
    USE MODD_CHECK_TEB,  ONLY : CHECK_TEB_t
    
    !
    USE MODE_THERMOS
    !
    USE MODI_SURFACE_RI
    USE MODI_SURFACE_AERO_COND
    !
    !
    USE YOMHOOK   ,ONLY : LHOOK,   DR_HOOK
    USE PARKIND1  ,ONLY : JPRB
    !
    IMPLICIT NONE
    !
    !*      0.1    declarations of arguments
    !
    !
    
    TYPE(TEB_OPTIONS_t), INTENT(INOUT) :: TOP
    TYPE(CHECK_TEB_t), INTENT(INOUT) :: CT
    !
    CHARACTER(LEN=2),     INTENT(IN)    :: HTEST             ! must be equal to 'OK'  
    CHARACTER(LEN=6), INTENT(IN)        :: HPROGRAM ! program calling surf. schemes
    
    REAL,                 INTENT(IN)    :: PTSTEP   ! time step
    REAL,                 INTENT(IN)    :: PANSMIN  ! minimum snow albedo
    REAL,                 INTENT(IN)    :: PANSMAX  ! maximum snow albedo
    REAL,                 INTENT(IN)    :: PTODRY   ! snow albedo decreasing constant
    REAL,                 INTENT(IN)    :: PRHOSMIN ! minimum snow density
    REAL,                 INTENT(IN)    :: PRHOSMAX ! maximum snow density
    REAL,                 INTENT(IN)    :: PRHOFOLD ! snow density increasing constant
    LOGICAL,              INTENT(IN)    :: OALL_MELT! T --> all snow runs off if
                                                    ! lower surf. temperature is
                                                    ! positive
    REAL,                 INTENT(IN)    :: PDRAIN_TIME ! drainage folding time (days)
    REAL,                 INTENT(IN)    :: PWCRN    ! critical snow amount necessary
                                                    ! to cover the considered surface
    REAL,                 INTENT(IN)    :: PZ0SN    ! snow roughness length for momentum
    REAL,                 INTENT(IN)    :: PZ0HSN   ! snow roughness length for heat
    
    TYPE(SURF_SNOW), INTENT(INOUT) :: TPSNOW
    
    REAL, DIMENSION(:), INTENT(IN)    :: PTG      ! underlying ground temperature
    
    REAL, DIMENSION(:), INTENT(IN)    :: PTG_COEFA! underlying ground temperature
    REAL, DIMENSION(:), INTENT(IN)    :: PTG_COEFB! implicit terms
    
    REAL, DIMENSION(:), INTENT(IN)    :: PABS_SW  ! absorbed SW energy (Wm-2)
    REAL, DIMENSION(:), INTENT(IN)    :: PLW1     ! LW coef independant of TSNOW
                                                  ! (Wm-2)     usually equal to:
                                                  !      emis_snow * LW_down
                                                  !
    
    REAL, DIMENSION(:), INTENT(IN)    :: PLW2     ! LW coef dependant of TSNOW (Wm-2 K-4) 
                                                  ! usually equal to -1 * emis_snow * stefan_constant
    
                                                  !
    REAL, DIMENSION(:), INTENT(IN)    :: PTA      ! temperature at the lowest level
    REAL, DIMENSION(:), INTENT(IN)    :: PQA      ! specific humidity
                                                    ! at the lowest level
    REAL, DIMENSION(:), INTENT(IN)    :: PVMOD    ! module of the horizontal wind
    REAL, DIMENSION(:), INTENT(IN)    :: PPS      ! pressure at the surface
    REAL, DIMENSION(:), INTENT(IN)    :: PRHOA    ! air density
                                                    ! at the lowest level
    REAL, DIMENSION(:), INTENT(IN)    :: PSR      ! snow rate
    REAL, DIMENSION(:), INTENT(IN)    :: PZREF    ! reference height of the first
                                                  ! atmospheric level (temperature)
    
    REAL, DIMENSION(:), INTENT(IN)    :: PUREF    ! reference height of the first atmospheric level (wind)
    REAL, DIMENSION(:), INTENT(IN)    :: PEXP_ABS_LW ! Longwave absorption when calculated explicitly
    
    REAL, DIMENSION(:), INTENT(OUT)   :: PRNSNOW  ! net radiation over snow
    REAL, DIMENSION(:), INTENT(OUT)   :: PHSNOW   ! sensible heat flux over snow
    REAL, DIMENSION(:), INTENT(OUT)   :: PLESNOW  ! latent heat flux over snow
    REAL, DIMENSION(:), INTENT(OUT)   :: PGSNOW   ! flux under the snow
    REAL, DIMENSION(:), INTENT(OUT)   :: PMELT    ! snow melting rate (kg/m2/s)
    REAL, DIMENSION(:), INTENT(OUT)   :: PDQS_SNOW! heat storage inside snow
    REAL, DIMENSION(:), INTENT(OUT)   :: PABS_LW ! absorbed LW rad by snow (W/m2)
    
    REAL, DIMENSION(:), INTENT(OUT)   :: PSEN_SNOW_DIF ! Sensible heat due to falling snow (W/m2)
    REAL, DIMENSION(:), INTENT(OUT)   :: PEMIT_LW_SNOW ! Longwave emission by snow (W/m²)
    REAL, DIMENSION(:), INTENT(OUT)   :: PSNOW_HEAT ! heat storage link to the presence of snow (W/m²)
    
    !
    !
    !*      0.2    declarations of local variables
    !
    REAL :: ZEXPL = 0.
    REAL :: ZIMPL = 1.
    !
    
    REAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: ZEXNS, ZEXNA, ZDIRCOSZW
    REAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: ZZ0      ! roughness length for momentum
    REAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: ZZ0H     ! roughness length forheat
    !
    REAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: ZRI      ! Richardson number
    REAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: ZAC      ! aerodynamical conductance
    REAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: ZRA      ! aerodynamical resistance
    REAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: ZCH      ! drag coefficient for heat
    REAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: ZB, ZY   ! coefficients in Ts eq.
    REAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: ZWSNOW   ! snow before evolution
    REAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: ZSNOW_HC ! snow heat capacity
    REAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: ZSNOW_TC ! snow thermal conductivity
    REAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: ZSNOW_D  ! snow depth
    REAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: ZMELT    ! snow melting rate (kg/m3/s)
    REAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: ZTS_SNOW ! snow surface temperature
    
                                              ! at previous time-step
    
    REAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: ZQSAT    ! specific humidity
    
    !                                         ! for ice
    
    REAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: ZDQSAT   ! d(specific humidity)/dT
    
    REAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: ZSR1, ZSR2   ! norm. snow precip.
    
    LOGICAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: GSNOWMASK ! where snow is
    
    !                                             ! at previuos time-step
    
    LOGICAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: GPROGSNOWMASK ! where prognostic equations are solved for the snow layer
    
    LOGICAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: GFLUXMASK ! where fluxes can
    
    !                                             ! be computed at
    !                                             ! new time-step
    !                                             ! i.e. snow occurence
    !                                             ! at previous time-step
    !                                             ! OR snow fall
    
    INTEGER, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: JSNOWMASK1, JSNOWMASK2, JSNOWMASK3 ! where snow is or not
    
    !                                                                      ! at previuos time-step
    
    INTEGER, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: JFLUXMASK ! where fluxes can
    
    !                                             ! be computed at
    !                                             ! new time-step
    !                                             ! i.e. snow occurence
    !                                             ! at previous time-step
    !                                             ! OR snow fall
    !
    
    REAL :: ZWSNOW_MIN = 0.001 ! minimum value of snow content (kg/m2) for prognostic
    !                          ! computations
    
    REAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: ZEI_SNOW  ! internal energy of snow
    REAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: ZPEI_SNOW ! internal energy of snow at t+
    REAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: ZWORK1
    REAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: ZDQSATI, ZQSATI
    
    REAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: ZQSAT_OLD
    !
    REAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: ZSEN_SNOW_BEF,ZSEN_SNOW_AFT
    REAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: ZTSNOW_OLD
    REAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: ZTSNOW_NEW
    REAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: ZIMB_SNOW
    LOGICAL, DIMENSION(SIZE(TPSNOW%WSNOW,1)) :: GCTL_LASTMM
    REAL :: ZIMP_LW
    
    !
    INTEGER                         :: JJ, JI, JCOMPT_SNOW1, JCOMPT_SNOW2, JCOMPT_SNOW3, JCOMPT_FLUX
    
    INTEGER :: ILUOUT         ! logical unit of output file
    
    REAL(KIND=JPRB) :: ZHOOK_HANDLE
    !-------------------------------------------------------------------------------
    !
    IF (LHOOK) CALL DR_HOOK('SNOW_COVER_1LAYER',0,ZHOOK_HANDLE)
    
    !
    IF (HTEST/='OK') THEN
       CALL ABOR1_SFX('SNOW_COVER_1layer: FATAL ERROR DURING ARGUMENT TRANSFER')
    ENDIF
    !
    ! Multiplier for implicit calculation of longwave radiation
    !
    IF (TOP%LEXPLW) THEN
       ZIMP_LW=0.0
    ELSE
       ZIMP_LW=1.0
    ENDIF
    !
    ZQSAT     (:) = XUNDEF
    ZDQSAT    (:) = XUNDEF
    ZDQSATI   (:) = XUNDEF
    ZQSATI    (:) = XUNDEF
    ZQSAT_OLD (:) = XUNDEF
    !
    
    ZB(:)=0.
    ZY(:)=0.
    ZMELT  (:) = 0.
    PMELT  (:) = 0.
    PRNSNOW(:) = 0.
    PHSNOW (:) = 0.
    PLESNOW(:) = 0.
    PGSNOW (:) = 0.
    
    PEMIT_LW_SNOW(:) = 0.0
    PSNOW_HEAT(:) = 0.
    PSEN_SNOW_DIF (:) = 0.
    !
    
    !RJ: workaround to prevent decomposition unstable xundef masks for Tx_LWA_SN_RD fields
    !RJ: in TEB_DIAGNOSTICS.nc during TEB_GARDEN_GREENROOF_BEM_3L_IRRIG_* tests
    !RJ: problem with decomposition handling somewhere else
    #ifdef RJ_PFIX
    PABS_LW(:) = 0.0
    #else
    
    !
    !* snow reservoir before evolution
    !
    
    ZWSNOW(:) = TPSNOW%WSNOW(:,1)
    
    ZTS_SNOW(:) = MIN(XTT,PTG(:))
    !
    ZSNOW_D (:) = 0.
    ZSNOW_TC(:) = 0.
    ZSNOW_HC(:) = 0.
    !
    
    !-------------------------------------------------------------------------------
    !
    !*      1.1    most useful masks
    !              -----------------
    !
    GSNOWMASK(:)=.FALSE.
    GFLUXMASK(:)=.FALSE.
    
    JSNOWMASK1(:)=0.
    JSNOWMASK2(:)=0.
    JSNOWMASK3(:)=0.
    JFLUXMASK(:)=0.
    
      !*      1.2    drag
    !              ----
    !
    !*      1.2.1  defaults
    !              --------
    !
    !* variation of temperature with altitude is neglected
    !
    ZEXNS(:) = 1.
    ZEXNA(:) = 1.
    !
    !* slope is neglected in drag computation
    !
    ZDIRCOSZW(:) = 1.
    !
    !* roughness length are imposed:
    !
    ZZ0   (:) = PZ0SN
    ZZ0H  (:) = PZ0HSN
    !
    !
    !*      1.1    most useful masks
    !              -----------------
    !* snow occurence at previous time-step
    !
    !* snow occurence during the time-step for fluxes computation
    !
    JCOMPT_SNOW1=0
    JCOMPT_SNOW2=0
    JCOMPT_SNOW3=0
    JCOMPT_FLUX=0
    DO JJ=1,SIZE(ZWSNOW)
      IF (ZWSNOW(JJ)>0.) THEN
        GSNOWMASK(JJ)=.TRUE.
        !* surface temperature
    
        ZTS_SNOW(JJ) = TPSNOW%TS(JJ)
    
        GFLUXMASK(JJ)=.TRUE.
        !gsnowmask=t
        JCOMPT_SNOW1=JCOMPT_SNOW1+1
        JSNOWMASK1(JCOMPT_SNOW1) = JJ
        !gfluxmask=t
        JCOMPT_FLUX=JCOMPT_FLUX+1
        JFLUXMASK(JCOMPT_FLUX) = JJ
        IF (ZWSNOW(JJ)>=ZWSNOW_MIN) THEN
          !second snow mask
          JCOMPT_SNOW3=JCOMPT_SNOW3+1
          JSNOWMASK3(JCOMPT_SNOW3)=JJ
    
        ELSE
          !lower limit of snow cover for prognostic computations
          !0.1 kg/m2 of snow water content
    
          TPSNOW%T(JJ,1) = MIN(PTG(JJ),XTT)
    
          ZTSNOW_NEW(JJ)=TPSNOW%TS(JJ)
          ZTSNOW_OLD(JJ)=TPSNOW%TS(JJ)
          !
    
        TPSNOW%T(JJ,1) = MIN(PTG(JJ),XTT)
    
        !gsnowmask=false
    
        ZTSNOW_NEW(JJ)=TPSNOW%T(JJ,1)
        ZTSNOW_OLD(JJ)=TPSNOW%T(JJ,1)
    
        JCOMPT_SNOW2=JCOMPT_SNOW2+1
        JSNOWMASK2(JCOMPT_SNOW2) = JJ
        IF (PSR(JJ)>0.) THEN
          GFLUXMASK(JJ)=.TRUE.
          JCOMPT_FLUX=JCOMPT_FLUX+1
          JFLUXMASK(JCOMPT_FLUX) = JJ
        ENDIF
      ENDIF
    ENDDO
    !-------------------------------------------------------------------------------
    !
    !*      1.2    drag
    !              ----
    !
    !*      1.2.2   qsat (Tsnow)
    !              ------------
    !
    ZQSAT(:) = QSATI(ZTS_SNOW(:), PPS(:) )
    !
    !*      1.2.3  Richardson number
    !              -----------------
    !
    !* snow is present on all the considered surface.
    !* computation occurs where snow is and/or falls.
    !
    
    CALL SURFACE_RI(ZTS_SNOW, ZQSAT, ZEXNS, ZEXNA, PTA, PQA, &
                    PZREF, PUREF, ZDIRCOSZW, PVMOD, ZRI      )  
    
    !
    !*      1.2.4  Aerodynamical conductance
    !              -------------------------
    !
    
    CALL SURFACE_AERO_COND(ZRI, PZREF, PUREF, PVMOD, ZZ0, ZZ0H, ZAC, ZRA, ZCH)
    
    !
    !-------------------------------------------------------------------------------
    !
    !*      2.     snow thermal characteristics
    !              ----------------------------
    !cdir nodep
    DO JJ=1,JCOMPT_SNOW1
      !
      JI = JSNOWMASK1(JJ)
      !
      !*      2.1    snow heat capacity
    
      ZSNOW_HC(JI) = TPSNOW%RHO(JI,1) * XCI * XRHOLI / XRHOLW
    
    !*      2.2    snow depth
    
      ZSNOW_D(JI) = ZWSNOW(JI) / TPSNOW%RHO(JI,1)
    
    !*      2.3    snow thermal conductivity
    
      ZSNOW_TC(JI) = XCONDI * (TPSNOW%RHO(JI,1)/XRHOLW)**1.885
    
    !*      2.4    internal energy of snow
    
      ZEI_SNOW(JI) = ZSNOW_HC(JI)*ZSNOW_D(JI)*TPSNOW%T(JI,1)
    
      !
    ENDDO
    !
    !cdir nodep
    DO JJ=1,JCOMPT_SNOW2
      !
      JI = JSNOWMASK2(JJ)
      !
      !*      2.1    snow heat capacity
      ZSNOW_HC(JI) = PRHOSMIN * XCI * XRHOLI / XRHOLW
    !*      2.2    snow depth
      ZSNOW_D(JI) = PTSTEP * PSR(JI) / PRHOSMIN
    !*      2.3    snow thermal conductivity
      ZSNOW_TC(JI) = XCONDI * (PRHOSMIN /XRHOLW)**1.885
    !*      2.4    internal energy of snow
      ZEI_SNOW(JI) = 0.
    !
    ENDDO
    !
    !-------------------------------------------------------------------------------
    !
    !*      3.     Snow temperature evolution
    !              --------------------------
    !
    !*      3.5    dqsat/ dT (Tsnow)
    !              -----------------
    !
    
    ZDQSATI (:) = DQSATI(ZTS_SNOW(:),PPS(:),ZQSAT(:))
    ZDQSAT  (:) = ZDQSATI(:)
    
    !
    !*      3.1    coefficients from Temperature tendency
    !              --------------------------------------
    !
    !cdir nodep
    DO JJ=1,JCOMPT_SNOW3
    !
      JI=JSNOWMASK3(JJ)
    
      ZWORK1(JI) = ZSNOW_D(JI) * ZSNOW_HC(JI) / PTSTEP
    !
      ZB(JI) = ZB(JI) + ZWORK1(JI)
    !
    !*      3.2    coefficients from solar radiation
    !          ---------------------------------
    !    
    
      ZY(JI) = ZY(JI) + ZWORK1(JI) * TPSNOW%T(JI,1) + PABS_SW(JI)
    
    !
    !
    !*      3.3    coefficients from infra-red radiation
    !              -------------------------------------
    !
    
      ZWORK1(JI) = PLW2(JI) * TPSNOW%T(JI,1)**3
    
      ZB(JI) = ZB(JI) - ZIMP_LW * 4 * ZIMPL * ZWORK1(JI)
    
      ZY(JI) = ZY(JI) + ZIMP_LW * ( PLW1(JI) + ZWORK1(JI) * (ZEXPL-3.*ZIMPL) * TPSNOW%T(JI,1) )
    
      ZY(JI) = ZY(JI) + (1.0 - ZIMP_LW) * PEXP_ABS_LW(JI)
    
    !
    !*      3.4    coefficients from sensible heat flux
    !              ------------------------------------
    !
     ZWORK1(JI) = XCPD * PRHOA(JI) * ZAC(JI)
    ! 
      ZB(JI) = ZB(JI) + ZWORK1(JI) *   ZIMPL
    !
    
      ZY(JI) = ZY(JI) - ZWORK1(JI) * ( ZEXPL * TPSNOW%T(JI,1) - PTA(JI) )
    
    !
    !
    !*      3.6    coefficients from latent heat flux
    !              ----------------------------------
    !
      ZWORK1(JI) =  XLSTT * PRHOA(JI) * ZAC(JI)
    !
      ZB(JI) = ZB(JI) + ZWORK1(JI) *  ZIMPL * ZDQSAT(JI)
    !
    
      ZY(JI) = ZY(JI) - ZWORK1(JI) * (  ZQSAT(JI) - PQA(JI) - ZIMPL * ZDQSAT(JI)*TPSNOW%T(JI,1) )
    
    !
    !*      3.7    coefficients from conduction flux at snow base
    !              ----------------------------------------------
    !
      ZWORK1(JI) = ZSNOW_TC(JI)/(0.5*ZSNOW_D(JI))
    !
    
      ZB(JI) = ZB(JI) + ZWORK1(JI) *  ZIMPL / ( 1. + ZWORK1(JI)*PTG_COEFA(JI) )
    
      ZY(JI) = ZY(JI) - ZWORK1(JI) * (ZEXPL * TPSNOW%T(JI,1) - PTG_COEFB(JI)) &
    
                       / ( 1. + ZWORK1(JI)*PTG_COEFA(JI) )
    
    !
    !*      3.8    guess of snow temperature before accumulation and melting
    !              ---------------------------------------------------------
    
      TPSNOW%T(JI,1) = ZY(JI) / ZB(JI)
    
    ! Robert: Save snow temperature after update (before accumulation and melting)
    
    ENDDO
    !
    !-------------------------------------------------------------------------------
    !
    !*      4.     Snow melt
    !              ---------
    !
    !*      4.1    melting
    !              -------
    !
    !cdir nodep
    DO JJ=1,JCOMPT_SNOW1
    !
      JI = JSNOWMASK1(JJ)
    !
    
      ZMELT(JI)  = MAX( TPSNOW%T(JI,1) - XTT , 0. ) * ZSNOW_HC(JI) /  XLMTT / PTSTEP
    
    !
      ZMELT(JI)  = MIN( ZMELT(JI) , ZWSNOW(JI) / ZSNOW_D(JI) / PTSTEP )
    !
    
      TPSNOW%T(JI,1) = MIN( TPSNOW%T(JI,1) , XTT )
    
    !
    ENDDO
    !
    !*      4.2    run-off of all snow if lower surface temperature is positive
    !              ------------------------------------------------------------
    !
    PMELT(:) = ZMELT(:) * ZSNOW_D(:)
    !
    !-------------------------------------------------------------------------------
    !
    !*      5.     fluxes
    !              ------
    !
    !*      5.3    qsat (Tsnow)
    !              ------------
    !
    
    ZQSATI = QSATI(TPSNOW%T(:,1),PPS(:))
    
    WHERE (GFLUXMASK(:)) 
       ZQSAT(:) = ZQSATI(:)
    END WHERE
    !
    !*      5.1    net radiation (with Ts lin. extrapolation)
    !              -------------
    !
    !cdir nodep
    DO JJ = 1, JCOMPT_FLUX
    
      JI = JFLUXMASK(JJ)
    
      !
      IF (.NOT.TOP%LEXPLW) THEN
         PABS_LW(JI) =  PLW1(JI) + ZEXPL*PLW2(JI)*ZTSNOW_OLD(JI)**4 + ZIMPL * (   &
                        PLW2(JI)*ZTSNOW_OLD(JI)**4                      +         &
                        4*PLW2(JI)*ZTSNOW_OLD(JI)**3*(ZTSNOW_NEW(JI)-ZTSNOW_OLD(JI)) )
      ELSE
         PABS_LW(JI) = PEXP_ABS_LW(JI)
      ENDIF
      !
    
      PRNSNOW(JI) = PABS_SW(JI) + PABS_LW(JI)
    
      !
      IF (TOP%LSPARTACUS) THEN
         PEMIT_LW_SNOW(JI)=XUNDEF
      ELSE
         PEMIT_LW_SNOW(JI)=XSTEFAN*ZTSNOW_NEW(JI)**4+(1.0-TPSNOW%EMIS(JI))/TPSNOW%EMIS(JI)*PABS_LW(JI)
      ENDIF
    
    !
    !*      5.2    sensible heat flux
    !              ------------------
    !
    
      PHSNOW(JI) = XCPD * PRHOA(JI) * ZAC(JI) * (ZIMPL*ZTSNOW_NEW(JI)+ZEXPL*ZTSNOW_OLD(JI)-PTA(JI))
    
    !
    !
    !*      5.4    latent heat flux
    !              ----------------
    !
    
      PLESNOW(JI) = XLSTT*PRHOA(JI)*ZAC(JI)*(ZQSAT_OLD(JI)+ZDQSAT(JI)*(ZTSNOW_NEW(JI)-ZTSNOW_OLD(JI))-PQA(JI))
    
    !
    !*      5.5    Conduction heat flux
    !              --------------------
    !
    
    DO JJ=1,JCOMPT_SNOW3
    !
       JI=JSNOWMASK3(JJ)
    !
      PGSNOW(JI) = ZSNOW_TC(JI)/(0.5*ZSNOW_D(JI)) * ( ZTSNOW_NEW(JI) - PTG_COEFB(JI) ) &
    
                 / ( 1. + ZSNOW_TC(JI)/(0.5*ZSNOW_D(JI))*PTG_COEFA(JI) )
    
    !
    !
    !*      5.6    If ground T>0 C, Melting is estimated from conduction heat flux
    !              ---------------------------------------------------------------
    !
    !
    ENDDO
    !
    !-------------------------------------------------------------------------------
    !
    !*      6.     reservoir evolution
    !              -------------------
    !
    !cdir nodep
    
    DO JJ = 1, SIZE(TPSNOW%WSNOW,1)
    
    !
    !*      6.1    snow fall
    !              ---------
    !
    
      TPSNOW%WSNOW(JJ,1) = TPSNOW%WSNOW(JJ,1) + PTSTEP * PSR(JJ)
    
    !
    !
    !*      6.2    sublimation
    !              -----------
    !
    
      PLESNOW(JJ) = MIN( PLESNOW(JJ), XLSTT*TPSNOW%WSNOW(JJ,1)/PTSTEP )
    
      TPSNOW%WSNOW(JJ,1)  = MAX( TPSNOW%WSNOW(JJ,1) - PTSTEP * PLESNOW(JJ)/XLSTT , 0.)
    
      PMELT(JJ) = MIN( PMELT(JJ), TPSNOW%WSNOW(JJ,1)/PTSTEP )
    !
      IF ( TPSNOW%WSNOW(JJ,1) .LT. (1.E-8*PTSTEP) ) THEN 
         PMELT(JJ) = PMELT(JJ) + TPSNOW%WSNOW(JJ,1)/PTSTEP
         TPSNOW%WSNOW(JJ,1) = 0.
      END IF
    
    !
    !*      6.3    melting
    !              -------
    !
    
      TPSNOW%WSNOW(JJ,1)= MAX( TPSNOW%WSNOW(JJ,1) - PTSTEP * PMELT(JJ) , 0.)
    
      IF ( TPSNOW%WSNOW(JJ,1) .LT. (1.E-8*PTSTEP) ) THEN
         PMELT(JJ) = PMELT(JJ) + TPSNOW%WSNOW(JJ,1)/PTSTEP
         TPSNOW%WSNOW(JJ,1) = 0.
      END IF
    
      IF (TPSNOW%WSNOW(JJ,1)==0.) THEN
         PGSNOW(JJ) = MAX ( PGSNOW(JJ), - PMELT(JJ)*XLMTT )
      END IF
    
    !
    ENDDO
    !
    !*      6.4    time dependent drainage
    !              -----------------------
    !
    IF (PDRAIN_TIME>0.) THEN
    
      CALL ABOR1_SFX("Time dependent drainage needs to be properly checked")
    
      WHERE ( TPSNOW%WSNOW(:,1)>0.)
        TPSNOW%WSNOW(:,1) = TPSNOW%WSNOW(:,1) * EXP(-PTSTEP/PDRAIN_TIME/XDAY)
    
    !*      6.5   Treatment of small snow values
    
    !              ---------------------------------
    !
    
    GCTL_LASTMM(:)=.FALSE.
    WHERE ((TPSNOW%WSNOW(:,1).LT.ZWSNOW_MIN).AND.(PSR(:).LT.XSURF_EPSILON))
      PMELT(:) = PMELT(:) + TPSNOW%WSNOW(:,1)/PTSTEP
    
      TPSNOW%WSNOW(:,1)=0.
    
    END WHERE
    !
    !-------------------------------------------------------------------------------
    !
    !*      7.     albedo evolution
    !              ----------------
    !
    !*      7.1    If melting occurs or not
    !              -----------------------
    !
    !
    !cdir nodep
    DO JJ=1,JCOMPT_SNOW1
    !
      JI = JSNOWMASK1(JJ)
    !
      IF (PMELT(JI) > 0. ) THEN
    !
    
        TPSNOW%ALB(JI) = (TPSNOW%ALB(JI)-PANSMIN)*EXP(-PRHOFOLD*PTSTEP/XDAY) + PANSMIN   &
                         + PSR(JI)*PTSTEP/PWCRN*PANSMAX  
    
    !
      ELSEIF (PMELT(JI)==0.) THEN 
    
        TPSNOW%ALB(JI) = TPSNOW%ALB(JI) - PTODRY*PTSTEP/XDAY  + PSR(JI)*PTSTEP/PWCRN*PANSMAX  
    
    !
      ENDIF
    !
    ENDDO
    !
    !-------------------------------------------------------------------------------
    !
    !*      8.     density evolution
    !              -----------------
    !
    !*      8.1    old snow
    !              --------
    !
    !cdir nodep
    DO JJ = 1, JCOMPT_SNOW1
    ! 
      JI = JSNOWMASK1(JJ)
    !
    
      IF (TPSNOW%WSNOW(JI,1)>0. ) THEN
    
        ZSR1(JI) = MAX( TPSNOW%WSNOW(JI,1) , PSR(JI) * PTSTEP )
    
        TPSNOW%RHO(JI,1) = (TPSNOW%RHO(JI,1)-PRHOSMAX)*EXP(-PRHOFOLD*PTSTEP/XDAY) + PRHOSMAX
        TPSNOW%RHO(JI,1) = ( (ZSR1(JI)-PSR(JI)*PTSTEP) * TPSNOW%RHO(JI,1)    &
    
                      + (PSR(JI)*PTSTEP) * PRHOSMIN ) / ZSR1(JI)  
      ENDIF
    !
    ENDDO
    !
    !*      8.2    fresh snow
    !              ----------
    !
    !cdir nodep
    
    DO JJ=1,SIZE(TPSNOW%WSNOW,1)
      IF (  TPSNOW%WSNOW(JJ,1)>0. ) THEN
        TPSNOW%ALB(JJ) = MAX(TPSNOW%ALB(JJ),PANSMIN)
        TPSNOW%ALB(JJ) = MIN(TPSNOW%ALB(JJ),PANSMAX)
    
        IF (ZWSNOW(JJ)==0.) THEN
    
          TPSNOW%ALB  (JJ) = PANSMAX
          TPSNOW%EMIS (JJ) = XEMISSN
          TPSNOW%RHO(JJ,1) = PRHOSMIN
    
    !
    !-------------------------------------------------------------------------------
    !
    !*      9.     fresh snow accumulation (if more than 1mm of snow depth)
    !              -----------------------
    !
    !cdir nodep
    DO JJ=1,JCOMPT_SNOW3
    !
      JI = JSNOWMASK3(JJ)
    !
    
      IF (PSR(JI)>0. .AND. TPSNOW%WSNOW(JI,1)>0.) THEN
    
        ZSR2(JI) = MIN( TPSNOW%WSNOW(JI,1) , PSR(JI) * PTSTEP )
    
    !
        ZSEN_SNOW_BEF(JI)=ZSNOW_HC(JI)*ZSNOW_D(JI)*TPSNOW%T(JI,1)
    
        TPSNOW%T(JI,1) =( ( TPSNOW%WSNOW(JI,1) - ZSR2(JI) ) *  TPSNOW%T(JI,1)        &
                  +   ZSR2(JI)  * MIN( PTA   (JI) ,XTT )) / ( TPSNOW%WSNOW(JI,1) )  
    
    !
        ZSEN_SNOW_AFT(JI)=ZSNOW_HC(JI)*ZSNOW_D(JI)*TPSNOW%T(JI,1)
    !
        PSEN_SNOW_DIF(JI)=(ZSEN_SNOW_AFT(JI)-ZSEN_SNOW_BEF(JI))/PTSTEP
    
      ENDIF
    !
    ENDDO
    !
    !-------------------------------------------------------------------------------
    !
    !*     10.     Surface temperature
    !              -------------------
    !
    !* note that if the relation between snow pack temperature and its
    !  surface temperature is modified, think to modify it also in
    !  subroutine init_snow_lw.f90
    !
    WHERE (GSNOWMASK(:) )
    
      TPSNOW%TS(:) = TPSNOW%T(:,1)
    
    END WHERE
    !
    !-------------------------------------------------------------------------------
    !
    !*     11.     bogus values
    !              ------------
    !
    !*     11.1    snow characteristics where snow IS present at current time-step
    !              ---------------------------------------------------------------
    !
    
    WHERE (TPSNOW%WSNOW(:,1)==0.)
    
      TPSNOW%T(:,1) = 273.16
      TPSNOW%RHO(:,1) = 600.0
      TPSNOW%ALB(:) = 0.60
      TPSNOW%TS(:) = 273.16
      TPSNOW%EMIS(:) = XEMISSN
    
    END WHERE
    !
    !
    !-------------------------------------------------------------------------------
    !
    !*     12.     Heat storage inside snow pack
    !
    WHERE (GSNOWMASK(:))
    
      ZPEI_SNOW(:) = ZSNOW_HC(:)*ZSNOW_D(:)*TPSNOW%T(:,1)
    
    ELSEWHERE
      ZPEI_SNOW(:) = 0.
    END WHERE
    PDQS_SNOW(:) = (ZPEI_SNOW(:)-ZEI_SNOW(:))/PTSTEP
    !
    
    ! Robert: Outside the mask with prognostic calculations,
    !         the heat storage inside the snow pack is set 
    !         to the flux imbalance.
    !
    DO JJ=1,SIZE(GPROGSNOWMASK)
       IF (.NOT.GPROGSNOWMASK(JJ)) THEN
          PDQS_SNOW(JJ)=PRNSNOW(JJ)-PHSNOW(JJ)-PLESNOW(JJ)-PGSNOW(JJ)-PMELT(JJ)*XLMTT
       ENDIF
    ENDDO
    !
    ! Robert: For the cases the snow depth has been set to 0.0
    !         during the current time step, the heat storage
    !         inside the snow pack is set to the flux imbalance
    !
    DO JJ=1,SIZE(GCTL_LASTMM)
       IF (GCTL_LASTMM(JJ) .OR. TPSNOW%WSNOW(JJ,1)==0.) THEN
          PDQS_SNOW(JJ)=PRNSNOW(JJ)-PHSNOW(JJ)-PLESNOW(JJ)-PGSNOW(JJ)-PMELT(JJ)*XLMTT
       ENDIF
    ENDDO
    !-------------------------------------------------------------------------------
    !
    ! 13.     Heat storage link to snow
    !
    PSNOW_HEAT=PDQS_SNOW+PMELT*XLMTT-PSEN_SNOW_DIF
    !
    ! Robert: Verification of snow layer energy budget 
    !
    DO JJ=1,SIZE(TPSNOW%WSNOW)
       !
       ZIMB_SNOW(JJ) = PRNSNOW(JJ)-PHSNOW(JJ)-PLESNOW(JJ)-PDQS_SNOW(JJ)- &
            PGSNOW(JJ)+PSEN_SNOW_DIF(JJ)-PMELT(JJ)*XLMTT
       !
       IF (ISNAN(ZIMB_SNOW(JJ))) CALL ABOR1_SFX("NAN detected in snow_cover_1layer")
       !
       IF (ABS(ZIMB_SNOW(JJ)).GT.1.0E-6) THEN
          !
          CALL GET_LUOUT(HPROGRAM,ILUOUT)
          !
          WRITE(ILUOUT,*) "PRNSNOW(JJ)       : ",+PRNSNOW(JJ)
          WRITE(ILUOUT,*) "PHSNOW(JJ)        : ",-PHSNOW(JJ)
          WRITE(ILUOUT,*) "PLESNOW(JJ)       : ",-PLESNOW(JJ)
          WRITE(ILUOUT,*) "PDQS_SNOW(JJ)     : ",-PDQS_SNOW(JJ)
          WRITE(ILUOUT,*) "PGSNOW(JJ)        : ",-PGSNOW(JJ)
          WRITE(ILUOUT,*) "PSEN_SNOW_DIF(JJ) : ",+PSEN_SNOW_DIF(JJ)
          WRITE(ILUOUT,*) "PMELT(JJ)*XLMTT   : ",-PMELT(JJ)*XLMTT
          WRITE(ILUOUT,*) "ZIMB_SNOW(JJ)     : ",+ZIMB_SNOW(JJ)
          CALL FLUSH(ILUOUT)
          !
          CALL ABOR1_SFX('Too large snow layer energy imbalance')
          !
       ENDIF
    ENDDO
    !
    ! Robert: Verification whether output of snow layer scheme physically plausible
    !
    IF (MAXVAL(ABS(PRNSNOW)).GT.2000.0) THEN
       CALL GET_LUOUT(HPROGRAM,ILUOUT)
       WRITE(ILUOUT,*) "MINVAL(PRNSNOW) : ",MINVAL(PRNSNOW)
       WRITE(ILUOUT,*) "MAXVAL(PRNSNOW) : ",MAXVAL(PRNSNOW)
       CALL FLUSH(ILUOUT)
       IF (CT%LCHECK_TEB) THEN
          CALL ABOR1_SFX('SNOW_COVER_1LAYER: Non plausible net radiation on snow, check report')     
       ENDIF
    ENDIF
    !
    IF (MAXVAL(ABS(PHSNOW)).GT.2000.0) THEN
       CALL GET_LUOUT(HPROGRAM,ILUOUT)
       WRITE(ILUOUT,*) "MINVAL(PHSNOW) : ",MINVAL(PHSNOW)
       WRITE(ILUOUT,*) "MAXVAL(PHSNOW) : ",MAXVAL(PHSNOW)
       CALL FLUSH(ILUOUT)
       IF (CT%LCHECK_TEB) THEN
          CALL ABOR1_SFX('SNOW_COVER_1LAYER: Non plausible sensible heat flux on snow, check report')
       ENDIF
    ENDIF
    !
    IF (MAXVAL(ABS(PLESNOW)).GT.2000.0) THEN
       CALL GET_LUOUT(HPROGRAM,ILUOUT)
       WRITE(ILUOUT,*) "MINVAL(PLESNOW) : ",MINVAL(PLESNOW)
       WRITE(ILUOUT,*) "MAXVAL(PLESNOW) : ",MAXVAL(PLESNOW)
       CALL FLUSH(ILUOUT)
       IF (CT%LCHECK_TEB) THEN
          CALL ABOR1_SFX('SNOW_COVER_1LAYER: Non plausible latent heat flux on snow, check report')
       ENDIF    
    ENDIF
    !
    IF (MAXVAL(ABS(PGSNOW)).GT.2000.0) THEN
       CALL GET_LUOUT(HPROGRAM,ILUOUT)
       WRITE(ILUOUT,*) "MINVAL(PGSNOW) : ",MINVAL(PGSNOW)
       WRITE(ILUOUT,*) "MAXVAL(PGSNOW) : ",MAXVAL(PGSNOW)
       CALL FLUSH(ILUOUT)
       IF (CT%LCHECK_TEB) THEN 
          CALL ABOR1_SFX('SNOW_COVER_1LAYER: Non plausible ground heat flux on snow, check report')
       ENDIF
    ENDIF
    !
    
    IF (LHOOK) CALL DR_HOOK('SNOW_COVER_1LAYER',1,ZHOOK_HANDLE)
    
    !------------------------------------------------------------------------------- !
    END SUBROUTINE SNOW_COVER_1LAYER