Index: NEMO/branches/2020/dev_12905_xios_restart/src/ICE/ice.F90
===================================================================
--- NEMO/branches/2020/dev_12905_xios_restart/src/ICE/ice.F90	(revision 13033)
+++ NEMO/branches/2020/dev_12905_xios_restart/src/ICE/ice.F90	(revision 13727)
@@ -70,4 +70,5 @@
    !! a_ip        |      -      |    Ice pond concentration       |       |
    !! v_ip        |      -      |    Ice pond volume per unit area| m     |
+   !! v_il        |    v_il_1d  |    Ice pond lid volume per area | m     |
    !!                                                                     |
    !!-------------|-------------|---------------------------------|-------|
@@ -85,4 +86,5 @@
    !! t_su        ! t_su_1d     |    Sea ice surface temperature  ! K     |
    !! h_ip        | h_ip_1d     |    Ice pond thickness           | m     |
+   !! h_il        | h_il_1d     |    Ice pond lid thickness       | m     |
    !!                                                                     |
    !! notes: the ice model only sees a bulk (i.e., vertically averaged)   |
@@ -112,4 +114,6 @@
    !! hm_ip       |      -      |    Mean ice pond depth          | m     |
    !! vt_ip       |      -      |    Total ice pond vol. per unit area| m |
+   !! hm_il       |      -      |    Mean ice pond lid depth      | m     |
+   !! vt_il       |      -      |    Total ice pond lid vol. per area | m |
    !!=====================================================================
 
@@ -137,8 +141,8 @@
    REAL(wp), PUBLIC ::   rn_ishlat        !: lateral boundary condition for sea-ice
    LOGICAL , PUBLIC ::   ln_landfast_L16  !: landfast ice parameterizationfrom lemieux2016 
-   REAL(wp), PUBLIC ::   rn_depfra        !:    fraction of ocean depth that ice must reach to initiate landfast ice
-   REAL(wp), PUBLIC ::   rn_icebfr        !:    maximum bottom stress per unit area of contact (lemieux2016) or per unit volume (home) 
-   REAL(wp), PUBLIC ::   rn_lfrelax       !:    relaxation time scale (s-1) to reach static friction
-   REAL(wp), PUBLIC ::   rn_tensile       !:    isotropic tensile strength
+   REAL(wp), PUBLIC ::   rn_lf_depfra     !:    fraction of ocean depth that ice must reach to initiate landfast ice
+   REAL(wp), PUBLIC ::   rn_lf_bfr        !:    maximum bottom stress per unit area of contact (lemieux2016) or per unit volume (home) 
+   REAL(wp), PUBLIC ::   rn_lf_relax      !:    relaxation time scale (s-1) to reach static friction
+   REAL(wp), PUBLIC ::   rn_lf_tensile    !:    isotropic tensile strength
    !
    !                                     !!** ice-ridging/rafting namelist (namdyn_rdgrft) **
@@ -151,4 +155,5 @@
    INTEGER , PUBLIC ::   nn_nevp          !: number of iterations for subcycling
    REAL(wp), PUBLIC ::   rn_relast        !: ratio => telast/rDt_ice (1/3 or 1/9 depending on nb of subcycling nevp) 
+   INTEGER , PUBLIC ::   nn_rhg_chkcvg    !: check ice rheology convergence 
    !
    !                                     !!** ice-advection namelist (namdyn_adv) **
@@ -158,5 +163,10 @@
    !                                     !!** ice-surface boundary conditions namelist (namsbc) **
                                           ! -- icethd_dh -- !
-   REAL(wp), PUBLIC ::   rn_blow_s        !: coef. for partitioning of snowfall between leads and sea ice
+   REAL(wp), PUBLIC ::   rn_snwblow       !: coef. for partitioning of snowfall between leads and sea ice
+                                          ! -- icethd_zdf and icealb -- !
+   INTEGER , PUBLIC ::   nn_snwfra        !: calculate the fraction of ice covered by snow
+   !                                      !   = 0  fraction = 1 (if snow) or 0 (if no snow)
+   !                                      !   = 1  fraction = 1-exp(-0.2*rhos*hsnw) [MetO formulation]
+   !                                      !   = 2  fraction = hsnw / (hsnw+0.02)    [CICE formulation]
                                           ! -- icethd -- !
    REAL(wp), PUBLIC ::   rn_cio           !: drag coefficient for oceanic stress
@@ -166,4 +176,5 @@
    !                                      !   = 1  Average N(cat) fluxes then redistribute over the N(cat) ice using T-ice and albedo sensitivity
    !                                      !   = 2  Redistribute a single flux over categories
+                                          ! -- icethd_zdf -- !
    LOGICAL , PUBLIC ::   ln_cndflx        !: use conduction flux as surface boundary condition (instead of qsr and qns) 
    LOGICAL , PUBLIC ::   ln_cndemulate    !: emulate conduction flux (if not provided) 
@@ -173,10 +184,17 @@
    INTEGER, PUBLIC, PARAMETER ::   np_cnd_ON  = 1  !: forcing from conduction flux (SM0L) (compute qcn and qsr_tr via sbcblk.F90 or sbccpl.F90)
    INTEGER, PUBLIC, PARAMETER ::   np_cnd_EMU = 2  !: emulate conduction flux via icethd_zdf.F90 (BL99) (1st round compute qcn and qsr_tr, 2nd round use it)
-
+   INTEGER, PUBLIC ::   nn_qtrice         !: Solar flux transmitted thru the surface scattering layer:
+   !                                      !   = 0  Grenfell and Maykut 1977 (depends on cloudiness and is 0 when there is snow) 
+   !                                      !   = 1  Lebrun 2019 (equals 0.3 anytime with different melting/dry snw conductivities)
+   !
    !                                     !!** ice-vertical diffusion namelist (namthd_zdf) **
    LOGICAL , PUBLIC ::   ln_cndi_U64      !: thermal conductivity: Untersteiner (1964)
    LOGICAL , PUBLIC ::   ln_cndi_P07      !: thermal conductivity: Pringle et al (2007)
-   REAL(wp), PUBLIC ::   rn_kappa_i       !: coef. for the extinction of radiation Grenfell et al. (2006) [1/m]
    REAL(wp), PUBLIC ::   rn_cnd_s         !: thermal conductivity of the snow [W/m/K]   
+   REAL(wp), PUBLIC ::   rn_kappa_i       !: coef. for the extinction of radiation in sea ice, Grenfell et al. (2006) [1/m]
+   REAL(wp), PUBLIC ::   rn_kappa_s       !: coef. for the extinction of radiation in snw (nn_qtrice=0) [1/m]
+   REAL(wp), PUBLIC ::   rn_kappa_smlt    !: coef. for the extinction of radiation in melt snw (nn_qtrice=1) [1/m]
+   REAL(wp), PUBLIC ::   rn_kappa_sdry    !: coef. for the extinction of radiation in dry  snw (nn_qtrice=1) [1/m]
+   LOGICAL , PUBLIC ::   ln_zdf_chkcvg    !: check convergence of heat diffusion scheme
 
    !                                     !!** ice-salinity namelist (namthd_sal) **
@@ -191,8 +209,11 @@
    !                                     !!** ice-ponds namelist (namthd_pnd)
    LOGICAL , PUBLIC ::   ln_pnd           !: Melt ponds (T) or not (F)
-   LOGICAL , PUBLIC ::   ln_pnd_H12       !: Melt ponds scheme from Holland et al 2012
+   LOGICAL , PUBLIC ::   ln_pnd_LEV       !: Melt ponds scheme from Holland et al (2012), Flocco et al (2007, 2010)
+   REAL(wp), PUBLIC ::   rn_apnd_min      !: Minimum ice fraction that contributes to melt ponds
+   REAL(wp), PUBLIC ::   rn_apnd_max      !: Maximum ice fraction that contributes to melt ponds
    LOGICAL , PUBLIC ::   ln_pnd_CST       !: Melt ponds scheme with constant fraction and depth
    REAL(wp), PUBLIC ::   rn_apnd          !: prescribed pond fraction (0<rn_apnd<1)
    REAL(wp), PUBLIC ::   rn_hpnd          !: prescribed pond depth    (0<rn_hpnd<1)
+   LOGICAL,  PUBLIC ::   ln_pnd_lids      !: Allow ponds to have frozen lids
    LOGICAL , PUBLIC ::   ln_pnd_alb       !: melt ponds affect albedo
 
@@ -219,74 +240,73 @@
 
    !                                     !!** define arrays
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   u_oce,v_oce !: surface ocean velocity used in ice dynamics
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   ht_i_new    !: ice collection thickness accreted in leads
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   strength    !: ice strength
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   stress1_i, stress2_i, stress12_i   !: 1st, 2nd & diagonal stress tensor element
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   delta_i     !: ice rheology elta factor (Flato & Hibler 95) [s-1]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   divu_i      !: Divergence of the velocity field             [s-1]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   shear_i     !: Shear of the velocity field                  [s-1]
-   !
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   t_bo        !: Sea-Ice bottom temperature [Kelvin]     
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   qlead       !: heat balance of the lead (or of the open ocean)
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   qsb_ice_bot !: net downward heat flux from the ice to the ocean
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   fhld        !: heat flux from the lead used for bottom melting
-
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   wfx_snw     !: mass flux from snow-ocean mass exchange             [kg.m-2.s-1]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   wfx_snw_sni !: mass flux from snow ice growth component of wfx_snw [kg.m-2.s-1]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   wfx_snw_sum !: mass flux from surface melt component of wfx_snw    [kg.m-2.s-1]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   wfx_pnd     !: mass flux from melt pond-ocean mass exchange        [kg.m-2.s-1]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   wfx_spr     !: mass flux from snow precipitation on ice            [kg.m-2.s-1]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   wfx_sub     !: mass flux from sublimation of snow/ice              [kg.m-2.s-1]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   wfx_snw_sub !: mass flux from snow sublimation                     [kg.m-2.s-1]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   wfx_ice_sub !: mass flux from ice sublimation                      [kg.m-2.s-1]
-
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   wfx_snw_dyn !: mass flux from dynamical component of wfx_snw       [kg.m-2.s-1]
-
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   wfx_ice     !: mass flux from ice-ocean mass exchange                   [kg.m-2.s-1]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   wfx_sni     !: mass flux from snow ice growth component of wfx_ice      [kg.m-2.s-1]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   wfx_opw     !: mass flux from lateral ice growth component of wfx_ice   [kg.m-2.s-1]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   wfx_bog     !: mass flux from bottom ice growth component of wfx_ice    [kg.m-2.s-1]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   wfx_dyn     !: mass flux from dynamical ice growth component of wfx_ice [kg.m-2.s-1]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   wfx_bom     !: mass flux from bottom melt component of wfx_ice          [kg.m-2.s-1]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   wfx_sum     !: mass flux from surface melt component of wfx_ice         [kg.m-2.s-1]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   wfx_lam     !: mass flux from lateral melt component of wfx_ice         [kg.m-2.s-1]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   wfx_res     !: mass flux from residual component of wfx_ice             [kg.m-2.s-1]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   wfx_err_sub !: mass flux error after sublimation                        [kg.m-2.s-1]
-
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   sfx_bog     !: salt flux due to ice bottom growth                   [pss.kg.m-2.s-1 => g.m-2.s-1]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   sfx_bom     !: salt flux due to ice bottom melt                     [pss.kg.m-2.s-1 => g.m-2.s-1]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   sfx_lam     !: salt flux due to ice lateral melt                    [pss.kg.m-2.s-1 => g.m-2.s-1]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   sfx_sum     !: salt flux due to ice surface melt                    [pss.kg.m-2.s-1 => g.m-2.s-1]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   sfx_sni     !: salt flux due to snow-ice growth                     [pss.kg.m-2.s-1 => g.m-2.s-1]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   sfx_opw     !: salt flux due to growth in open water                [pss.kg.m-2.s-1 => g.m-2.s-1]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   sfx_bri     !: salt flux due to brine rejection                     [pss.kg.m-2.s-1 => g.m-2.s-1]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   sfx_dyn     !: salt flux due to porous ridged ice formation         [pss.kg.m-2.s-1 => g.m-2.s-1]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   sfx_res     !: salt flux due to correction on ice thick. (residual) [pss.kg.m-2.s-1 => g.m-2.s-1]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   sfx_sub     !: salt flux due to ice sublimation                     [pss.kg.m-2.s-1 => g.m-2.s-1]
-
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   hfx_bog     !: total heat flux causing bottom ice growth           [W.m-2]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   hfx_bom     !: total heat flux causing bottom ice melt             [W.m-2]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   hfx_sum     !: total heat flux causing surface ice melt            [W.m-2]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   hfx_opw     !: total heat flux causing open water ice formation    [W.m-2]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   hfx_dif     !: total heat flux causing Temp change in the ice      [W.m-2]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   hfx_snw     !: heat flux for snow melt                             [W.m-2]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   hfx_err_dif !: heat flux remaining due to change in non-solar flux [W.m-2]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   hfx_err_rem !: heat flux error after heat remapping => must be 0   [W.m-2]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   qt_atm_oi   !: heat flux at the interface atm-[oce+ice]            [W.m-2]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   qt_oce_ai   !: heat flux at the interface oce-[atm+ice]            [W.m-2]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   u_oce,v_oce     !: surface ocean velocity used in ice dynamics
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   ht_i_new        !: ice collection thickness accreted in leads
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   strength        !: ice strength
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   stress1_i, stress2_i, stress12_i   !: 1st, 2nd & diagonal stress tensor element
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   delta_i         !: ice rheology elta factor (Flato & Hibler 95) [s-1]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   divu_i          !: Divergence of the velocity field             [s-1]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   shear_i         !: Shear of the velocity field                  [s-1]
+   !
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   t_bo            !: Sea-Ice bottom temperature [Kelvin]     
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   qlead           !: heat balance of the lead (or of the open ocean)
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   qsb_ice_bot     !: net downward heat flux from the ice to the ocean
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   fhld            !: heat flux from the lead used for bottom melting
+
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   wfx_snw         !: mass flux from snow-ocean mass exchange             [kg.m-2.s-1]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   wfx_snw_sni     !: mass flux from snow ice growth component of wfx_snw [kg.m-2.s-1]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   wfx_snw_sum     !: mass flux from surface melt component of wfx_snw    [kg.m-2.s-1]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   wfx_pnd         !: mass flux from melt pond-ocean mass exchange        [kg.m-2.s-1]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   wfx_spr         !: mass flux from snow precipitation on ice            [kg.m-2.s-1]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   wfx_sub         !: mass flux from sublimation of snow/ice              [kg.m-2.s-1]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   wfx_snw_sub     !: mass flux from snow sublimation                     [kg.m-2.s-1]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   wfx_ice_sub     !: mass flux from ice sublimation                      [kg.m-2.s-1]
+
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   wfx_snw_dyn     !: mass flux from dynamical component of wfx_snw       [kg.m-2.s-1]
+
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   wfx_ice         !: mass flux from ice-ocean mass exchange                   [kg.m-2.s-1]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   wfx_sni         !: mass flux from snow ice growth component of wfx_ice      [kg.m-2.s-1]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   wfx_opw         !: mass flux from lateral ice growth component of wfx_ice   [kg.m-2.s-1]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   wfx_bog         !: mass flux from bottom ice growth component of wfx_ice    [kg.m-2.s-1]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   wfx_dyn         !: mass flux from dynamical ice growth component of wfx_ice [kg.m-2.s-1]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   wfx_bom         !: mass flux from bottom melt component of wfx_ice          [kg.m-2.s-1]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   wfx_sum         !: mass flux from surface melt component of wfx_ice         [kg.m-2.s-1]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   wfx_lam         !: mass flux from lateral melt component of wfx_ice         [kg.m-2.s-1]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   wfx_res         !: mass flux from residual component of wfx_ice             [kg.m-2.s-1]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   wfx_err_sub     !: mass flux error after sublimation                        [kg.m-2.s-1]
+
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   sfx_bog         !: salt flux due to ice bottom growth                   [pss.kg.m-2.s-1 => g.m-2.s-1]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   sfx_bom         !: salt flux due to ice bottom melt                     [pss.kg.m-2.s-1 => g.m-2.s-1]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   sfx_lam         !: salt flux due to ice lateral melt                    [pss.kg.m-2.s-1 => g.m-2.s-1]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   sfx_sum         !: salt flux due to ice surface melt                    [pss.kg.m-2.s-1 => g.m-2.s-1]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   sfx_sni         !: salt flux due to snow-ice growth                     [pss.kg.m-2.s-1 => g.m-2.s-1]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   sfx_opw         !: salt flux due to growth in open water                [pss.kg.m-2.s-1 => g.m-2.s-1]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   sfx_bri         !: salt flux due to brine rejection                     [pss.kg.m-2.s-1 => g.m-2.s-1]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   sfx_dyn         !: salt flux due to porous ridged ice formation         [pss.kg.m-2.s-1 => g.m-2.s-1]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   sfx_res         !: salt flux due to correction on ice thick. (residual) [pss.kg.m-2.s-1 => g.m-2.s-1]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   sfx_sub         !: salt flux due to ice sublimation                     [pss.kg.m-2.s-1 => g.m-2.s-1]
+
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   hfx_bog         !: total heat flux causing bottom ice growth           [W.m-2]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   hfx_bom         !: total heat flux causing bottom ice melt             [W.m-2]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   hfx_sum         !: total heat flux causing surface ice melt            [W.m-2]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   hfx_opw         !: total heat flux causing open water ice formation    [W.m-2]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   hfx_dif         !: total heat flux causing Temp change in the ice      [W.m-2]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   hfx_snw         !: heat flux for snow melt                             [W.m-2]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   hfx_err_dif     !: heat flux remaining due to change in non-solar flux [W.m-2]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   qt_atm_oi       !: heat flux at the interface atm-[oce+ice]            [W.m-2]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   qt_oce_ai       !: heat flux at the interface oce-[atm+ice]            [W.m-2]
    
    ! heat flux associated with ice-atmosphere mass exchange
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   hfx_sub     !: heat flux for sublimation            [W.m-2]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   hfx_spr     !: heat flux of the snow precipitation  [W.m-2]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   hfx_sub         !: heat flux for sublimation            [W.m-2]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   hfx_spr         !: heat flux of the snow precipitation  [W.m-2]
 
    ! heat flux associated with ice-ocean mass exchange
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   hfx_thd     !: ice-ocean heat flux from thermo processes (icethd_dh) [W.m-2]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   hfx_dyn     !: ice-ocean heat flux from ridging                      [W.m-2]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   hfx_res     !: heat flux due to correction on ice thick. (residual)  [W.m-2]
-
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   rn_amax_2d     !: maximum ice concentration 2d array
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   qtr_ice_bot    !: transmitted solar radiation under ice
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   t1_ice         !: temperature of the first layer                (ln_cndflx=T) [K]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   cnd_ice        !: effective conductivity at the top of ice/snow (ln_cndflx=T) [W.m-2.K-1]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   hfx_thd         !: ice-ocean heat flux from thermo processes (icethd_dh) [W.m-2]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   hfx_dyn         !: ice-ocean heat flux from ridging                      [W.m-2]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   hfx_res         !: heat flux due to correction on ice thick. (residual)  [W.m-2]
+
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   rn_amax_2d      !: maximum ice concentration 2d array
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   qtr_ice_bot     !: transmitted solar radiation under ice
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   t1_ice          !: temperature of the first layer          (ln_cndflx=T) [K]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   cnd_ice         !: effective conductivity of the 1st layer (ln_cndflx=T) [W.m-2.K-1]
 
    !!----------------------------------------------------------------------
@@ -294,87 +314,97 @@
    !!----------------------------------------------------------------------
    !! Variables defined for each ice category
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   h_i       !: Ice thickness                           (m)
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   a_i       !: Ice fractional areas (concentration)
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   v_i       !: Ice volume per unit area                (m)
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   v_s       !: Snow volume per unit area               (m)
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   h_s       !: Snow thickness                          (m)
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   t_su      !: Sea-Ice Surface Temperature             (K)
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   s_i       !: Sea-Ice Bulk salinity                   (pss)
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   sv_i      !: Sea-Ice Bulk salinity * volume per area (pss.m)
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   o_i       !: Sea-Ice Age                             (s)
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   oa_i      !: Sea-Ice Age times ice area              (s)
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   bv_i      !: brine volume
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:)   ::   h_i           !: Ice thickness                           (m)
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:)   ::   a_i           !: Ice fractional areas (concentration)
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:)   ::   v_i           !: Ice volume per unit area                (m)
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:)   ::   v_s           !: Snow volume per unit area               (m)
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:)   ::   h_s           !: Snow thickness                          (m)
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:)   ::   t_su          !: Sea-Ice Surface Temperature             (K)
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:)   ::   s_i           !: Sea-Ice Bulk salinity                   (pss)
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:)   ::   sv_i          !: Sea-Ice Bulk salinity * volume per area (pss.m)
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:)   ::   o_i           !: Sea-Ice Age                             (s)
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:)   ::   oa_i          !: Sea-Ice Age times ice area              (s)
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:)   ::   bv_i          !: brine volume
 
    !! Variables summed over all categories, or associated to all the ice in a single grid cell
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   u_ice, v_ice !: components of the ice velocity                          (m/s)
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   vt_i , vt_s  !: ice and snow total volume per unit area                 (m)
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   st_i         !: Total ice salinity content                              (pss.m)
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   at_i         !: ice total fractional area (ice concentration)
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   ato_i        !: =1-at_i ; total open water fractional area
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   et_i , et_s  !: ice and snow total heat content                         (J/m2)
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   tm_i         !: mean ice temperature over all categories                (K)
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   tm_s         !: mean snw temperature over all categories                (K)
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   bvm_i        !: brine volume averaged over all categories
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   sm_i         !: mean sea ice salinity averaged over all categories      (pss)
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   tm_su        !: mean surface temperature over all categories            (K)
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   hm_i         !: mean ice  thickness over all categories                 (m)
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   hm_s         !: mean snow thickness over all categories                 (m)
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   om_i         !: mean ice age over all categories                        (s)
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   tau_icebfr   !: ice friction on ocean bottom (landfast param activated)
-
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:,:) ::   t_s      !: Snow temperatures     [K]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:,:) ::   e_s      !: Snow enthalpy         [J/m2]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:,:) ::   t_i      !: ice temperatures      [K]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:,:) ::   e_i      !: ice enthalpy          [J/m2]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:,:) ::   sz_i     !: ice salinity          [PSS]
-
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   a_ip       !: melt pond concentration
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   v_ip       !: melt pond volume per grid cell area      [m]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   a_ip_frac  !: melt pond fraction (a_ip/a_i)
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   h_ip       !: melt pond depth                          [m]
-
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   at_ip      !: total melt pond concentration
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   hm_ip      !: mean melt pond depth                     [m]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   vt_ip      !: total melt pond volume per gridcell area [m]
-
-   !!----------------------------------------------------------------------
-   !! * Old values of global variables
-   !!----------------------------------------------------------------------
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:)   ::   v_s_b, v_i_b, h_s_b, h_i_b, h_ip_b    !: snow and ice volumes/thickness
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:)   ::   a_i_b, sv_i_b, oa_i_b                 !:
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:,:) ::   e_s_b                                 !: snow heat content
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:,:) ::   e_i_b                                 !: ice temperatures
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)     ::   u_ice_b, v_ice_b                      !: ice velocity
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)     ::   at_i_b                                !: ice concentration (total)
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)     ::   u_ice, v_ice  !: components of the ice velocity                          (m/s)
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)     ::   vt_i , vt_s   !: ice and snow total volume per unit area                 (m)
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)     ::   st_i          !: Total ice salinity content                              (pss.m)
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)     ::   at_i          !: ice total fractional area (ice concentration)
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)     ::   ato_i         !: =1-at_i ; total open water fractional area
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)     ::   et_i , et_s   !: ice and snow total heat content                         (J/m2)
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)     ::   tm_i          !: mean ice temperature over all categories                (K)
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)     ::   tm_s          !: mean snw temperature over all categories                (K)
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)     ::   bvm_i         !: brine volume averaged over all categories
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)     ::   sm_i          !: mean sea ice salinity averaged over all categories      (pss)
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)     ::   tm_su         !: mean surface temperature over all categories            (K)
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)     ::   hm_i          !: mean ice  thickness over all categories                 (m)
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)     ::   hm_s          !: mean snow thickness over all categories                 (m)
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)     ::   om_i          !: mean ice age over all categories                        (s)
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)     ::   tau_icebfr    !: ice friction on ocean bottom (landfast param activated)
+
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:,:) ::   t_s           !: Snow temperatures     [K]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:,:) ::   e_s           !: Snow enthalpy         [J/m2]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:,:) ::   t_i           !: ice temperatures      [K]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:,:) ::   e_i           !: ice enthalpy          [J/m2]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:,:) ::   sz_i          !: ice salinity          [PSS]
+
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:)   ::   a_ip          !: melt pond concentration
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:)   ::   v_ip          !: melt pond volume per grid cell area      [m]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:)   ::   a_ip_frac     !: melt pond fraction (a_ip/a_i)
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:)   ::   a_ip_eff      !: melt pond effective fraction (not covered up by lid) (a_ip/a_i)
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:)   ::   h_ip          !: melt pond depth                          [m]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:)   ::   v_il          !: melt pond lid volume                     [m]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:)   ::   h_il          !: melt pond lid thickness                  [m]
+
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)     ::   at_ip         !: total melt pond concentration
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)     ::   hm_ip         !: mean melt pond depth                     [m]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)     ::   vt_ip         !: total melt pond volume per gridcell area [m]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)     ::   hm_il         !: mean melt pond lid depth                     [m]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)     ::   vt_il         !: total melt pond lid volume per gridcell area [m]
+
+   !!----------------------------------------------------------------------
+   !! * Global variables at before time step
+   !!----------------------------------------------------------------------
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:)   ::   v_s_b, v_i_b, h_s_b, h_i_b !: snow and ice volumes/thickness
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:)   ::   a_i_b, sv_i_b              !:
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:,:) ::   e_s_b                      !: snow heat content
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:,:) ::   e_i_b                      !: ice temperatures
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)     ::   u_ice_b, v_ice_b           !: ice velocity
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)     ::   at_i_b                     !: ice concentration (total)
             
    !!----------------------------------------------------------------------
    !! * Ice thickness distribution variables
    !!----------------------------------------------------------------------
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   hi_max         !: Boundary of ice thickness categories in thickness space
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   hi_mean        !: Mean ice thickness in catgories 
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:)   ::   hi_max            !: Boundary of ice thickness categories in thickness space
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:)   ::   hi_mean           !: Mean ice thickness in catgories 
    !
    !!----------------------------------------------------------------------
    !! * Ice diagnostics
    !!----------------------------------------------------------------------
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_trp_vi   !: transport of ice volume
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_trp_vs   !: transport of snw volume
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_trp_ei   !: transport of ice enthalpy [W/m2]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_trp_es   !: transport of snw enthalpy [W/m2]
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_trp_sv   !: transport of salt content
-   !
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_heat     !: snw/ice heat content variation   [W/m2] 
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_sice     !: ice salt content variation   [] 
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_vice     !: ice volume variation   [m/s] 
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_vsnw     !: snw volume variation   [m/s] 
-
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_trp_vi       !: transport of ice volume
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_trp_vs       !: transport of snw volume
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_trp_ei       !: transport of ice enthalpy [W/m2]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_trp_es       !: transport of snw enthalpy [W/m2]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_trp_sv       !: transport of salt content
+   !
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_heat         !: snw/ice heat content variation   [W/m2] 
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_sice         !: ice salt content variation   [] 
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_vice         !: ice volume variation   [m/s] 
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_vsnw         !: snw volume variation   [m/s] 
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_aice         !: ice conc.  variation   [s-1] 
+   !
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_adv_mass     !: advection of mass (kg/m2/s)
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_adv_salt     !: advection of salt (g/m2/s)
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_adv_heat     !: advection of heat (W/m2)
+   !
    !!----------------------------------------------------------------------
    !! * Ice conservation
    !!----------------------------------------------------------------------
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_v        !: conservation of ice volume
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_s        !: conservation of ice salt
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_t        !: conservation of ice heat
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_fv       !: conservation of ice volume
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_fs       !: conservation of ice salt
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_ft       !: conservation of ice heat
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_v            !: conservation of ice volume
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_s            !: conservation of ice salt
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_t            !: conservation of ice heat
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_fv           !: conservation of ice volume
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_fs           !: conservation of ice salt
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   diag_ft           !: conservation of ice heat
    !
    !!----------------------------------------------------------------------
@@ -382,9 +412,8 @@
    !!----------------------------------------------------------------------
    ! Extra sea ice diagnostics to address the data request
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   t_si          !: Temperature at Snow-ice interface (K) 
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   tm_si         !: mean temperature at the snow-ice interface (K) 
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   qcn_ice_bot   !: Bottom  conduction flux (W/m2)
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   qcn_ice_top   !: Surface conduction flux (W/m2)
-
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   t_si            !: Temperature at Snow-ice interface (K) 
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   tm_si           !: mean temperature at the snow-ice interface (K) 
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   qcn_ice_bot     !: Bottom  conduction flux (W/m2)
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   qcn_ice_top     !: Surface conduction flux (W/m2)
    !
    !!----------------------------------------------------------------------
@@ -425,5 +454,5 @@
          &      hfx_sum    (jpi,jpj) , hfx_bom   (jpi,jpj) , hfx_bog(jpi,jpj) , hfx_dif(jpi,jpj) ,     &
          &      hfx_opw    (jpi,jpj) , hfx_thd   (jpi,jpj) , hfx_dyn(jpi,jpj) , hfx_spr(jpi,jpj) ,     &
-         &      hfx_err_dif(jpi,jpj) , hfx_err_rem(jpi,jpj) , wfx_err_sub(jpi,jpj)             ,  STAT=ierr(ii) )
+         &      hfx_err_dif(jpi,jpj) , wfx_err_sub(jpi,jpj)                   , STAT=ierr(ii) )
 
       ! * Ice global state variables
@@ -449,14 +478,15 @@
 
       ii = ii + 1
-      ALLOCATE( a_ip(jpi,jpj,jpl) , v_ip(jpi,jpj,jpl) , a_ip_frac(jpi,jpj,jpl) , h_ip(jpi,jpj,jpl) , STAT = ierr(ii) )
-
-      ii = ii + 1
-      ALLOCATE( at_ip(jpi,jpj) , hm_ip(jpi,jpj) , vt_ip(jpi,jpj) , STAT = ierr(ii) )
+      ALLOCATE( a_ip(jpi,jpj,jpl) , v_ip(jpi,jpj,jpl) , a_ip_frac(jpi,jpj,jpl) , h_ip(jpi,jpj,jpl),  &
+         &      v_il(jpi,jpj,jpl) , h_il(jpi,jpj,jpl) , a_ip_eff (jpi,jpj,jpl) , STAT = ierr(ii) )
+
+      ii = ii + 1
+      ALLOCATE( at_ip(jpi,jpj) , hm_ip(jpi,jpj) , vt_ip(jpi,jpj) , hm_il(jpi,jpj) , vt_il(jpi,jpj) , STAT = ierr(ii) )
 
       ! * Old values of global variables
       ii = ii + 1
-      ALLOCATE( v_s_b (jpi,jpj,jpl) , v_i_b (jpi,jpj,jpl) , h_s_b(jpi,jpj,jpl)        , h_i_b(jpi,jpj,jpl), h_ip_b(jpi,jpj,jpl),  &
-         &      a_i_b (jpi,jpj,jpl) , sv_i_b(jpi,jpj,jpl) , e_i_b(jpi,jpj,nlay_i,jpl) , e_s_b(jpi,jpj,nlay_s,jpl) ,               &
-         &      oa_i_b(jpi,jpj,jpl)                                                   , STAT=ierr(ii) )
+      ALLOCATE( v_s_b (jpi,jpj,jpl) , v_i_b (jpi,jpj,jpl) , h_s_b(jpi,jpj,jpl)        , h_i_b(jpi,jpj,jpl),         &
+         &      a_i_b (jpi,jpj,jpl) , sv_i_b(jpi,jpj,jpl) , e_i_b(jpi,jpj,nlay_i,jpl) , e_s_b(jpi,jpj,nlay_s,jpl) , &
+         &      STAT=ierr(ii) )
 
       ii = ii + 1
@@ -469,7 +499,8 @@
       ! * Ice diagnostics
       ii = ii + 1
-      ALLOCATE( diag_trp_vi(jpi,jpj) , diag_trp_vs (jpi,jpj) , diag_trp_ei(jpi,jpj),   & 
-         &      diag_trp_es(jpi,jpj) , diag_trp_sv (jpi,jpj) , diag_heat  (jpi,jpj),   &
-         &      diag_sice  (jpi,jpj) , diag_vice   (jpi,jpj) , diag_vsnw  (jpi,jpj), STAT=ierr(ii) )
+      ALLOCATE( diag_trp_vi(jpi,jpj) , diag_trp_vs (jpi,jpj) , diag_trp_ei(jpi,jpj),                      & 
+         &      diag_trp_es(jpi,jpj) , diag_trp_sv (jpi,jpj) , diag_heat  (jpi,jpj),                      &
+         &      diag_sice  (jpi,jpj) , diag_vice   (jpi,jpj) , diag_vsnw  (jpi,jpj), diag_aice(jpi,jpj),  &
+         &      diag_adv_mass(jpi,jpj), diag_adv_salt(jpi,jpj), diag_adv_heat(jpi,jpj), STAT=ierr(ii) )
 
       ! * Ice conservation
@@ -485,4 +516,5 @@
       IF( ice_alloc /= 0 )   CALL ctl_stop( 'STOP', 'ice_alloc: failed to allocate arrays.' )
       !
+
    END FUNCTION ice_alloc
 
Index: NEMO/branches/2020/dev_12905_xios_restart/src/ICE/ice1d.F90
===================================================================
--- NEMO/branches/2020/dev_12905_xios_restart/src/ICE/ice1d.F90	(revision 13033)
+++ NEMO/branches/2020/dev_12905_xios_restart/src/ICE/ice1d.F90	(revision 13727)
@@ -51,5 +51,4 @@
    REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   hfx_snw_1d
    REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   hfx_dyn_1d
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   hfx_err_rem_1d
    REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   hfx_err_dif_1d
    REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   qt_oce_ai_1d
@@ -124,8 +123,9 @@
    REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   oa_i_1d       !:
    REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   o_i_1d        !:
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   a_ip_1d       !:
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   a_ip_1d       !: ice ponds
    REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   v_ip_1d       !:
    REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   h_ip_1d       !:
-   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   a_ip_frac_1d  !:
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   v_il_1d       !: Ice pond lid
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   h_il_1d       !:
 
    REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   t_s_1d      !: corresponding to the 2D var  t_s
@@ -145,5 +145,9 @@
    REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   sst_1d
    REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   sss_1d
-
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   frq_m_1d
+
+   ! convergence check
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   tice_cvgerr_1d   !: convergence of ice/snow temp (dT)          [K]
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   tice_cvgstp_1d   !: convergence of ice/snow temp (subtimestep) [-]
    ! 
    !!----------------------
@@ -157,4 +161,5 @@
    REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   a_ip_2d
    REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   v_ip_2d 
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   v_il_2d 
    REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   t_su_2d 
    REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   h_i_2d
@@ -175,5 +180,5 @@
       !!---------------------------------------------------------------------!
       INTEGER ::   ice1D_alloc   ! return value
-      INTEGER ::   ierr(7), ii
+      INTEGER ::   ierr(8), ii
       !!---------------------------------------------------------------------!
       ierr(:) = 0
@@ -189,5 +194,5 @@
          &      hfx_thd_1d(jpij) , hfx_spr_1d    (jpij) ,                      &
          &      hfx_snw_1d(jpij) , hfx_sub_1d    (jpij) ,                      &
-         &      hfx_res_1d(jpij) , hfx_err_rem_1d(jpij) , hfx_err_dif_1d(jpij) , qt_oce_ai_1d(jpij), STAT=ierr(ii) )
+         &      hfx_res_1d(jpij) , hfx_err_dif_1d(jpij) , qt_oce_ai_1d(jpij), STAT=ierr(ii) )
       !
       ii = ii + 1
@@ -208,6 +213,6 @@
          &      dh_s_tot(jpij) , dh_i_sum(jpij) , dh_i_itm  (jpij) , dh_i_bom(jpij) , dh_i_bog(jpij) ,  &    
          &      dh_i_sub(jpij) , dh_s_mlt(jpij) , dh_snowice(jpij) , s_i_1d  (jpij) , s_i_new (jpij) ,  &
-         &      a_ip_1d (jpij) , v_ip_1d (jpij) , v_i_1d    (jpij) , v_s_1d  (jpij) ,                   &
-         &      h_ip_1d (jpij) , a_ip_frac_1d(jpij) ,                                                   &
+         &      a_ip_1d (jpij) , v_ip_1d (jpij) , v_i_1d    (jpij) , v_s_1d  (jpij) , v_il_1d (jpij) ,  &
+         &      h_il_1d (jpij) , h_ip_1d (jpij) ,                                                       &
          &      sv_i_1d (jpij) , oa_i_1d (jpij) , o_i_1d    (jpij) , STAT=ierr(ii) )
       !
@@ -221,10 +226,13 @@
       !
       ii = ii + 1
-      ALLOCATE( sst_1d(jpij) , sss_1d(jpij) , STAT=ierr(ii) )
+      ALLOCATE( sst_1d(jpij) , sss_1d(jpij) , frq_m_1d(jpij) , STAT=ierr(ii) )
+      !
+      ii = ii + 1
+      ALLOCATE( tice_cvgerr_1d(jpij) , tice_cvgstp_1d(jpij) , STAT=ierr(ii) )
       !
       ii = ii + 1
       ALLOCATE( a_i_2d (jpij,jpl) , a_ib_2d(jpij,jpl) , h_i_2d (jpij,jpl) , h_ib_2d(jpij,jpl) ,  &
          &      v_i_2d (jpij,jpl) , v_s_2d (jpij,jpl) , oa_i_2d(jpij,jpl) , sv_i_2d(jpij,jpl) ,  &
-         &      a_ip_2d(jpij,jpl) , v_ip_2d(jpij,jpl) , t_su_2d(jpij,jpl) ,                      &
+         &      a_ip_2d(jpij,jpl) , v_ip_2d(jpij,jpl) , t_su_2d(jpij,jpl) , v_il_2d(jpij,jpl) ,  &
          &      STAT=ierr(ii) )
 
Index: NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icealb.F90
===================================================================
--- NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icealb.F90	(revision 13033)
+++ NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icealb.F90	(revision 13727)
@@ -14,7 +14,8 @@
    !!   ice_alb_init   : initialisation of albedo computation
    !!----------------------------------------------------------------------
-   USE ice, ONLY: jpl ! sea-ice: number of categories
    USE phycst         ! physical constants
    USE dom_oce        ! domain: ocean
+   USE ice, ONLY: jpl ! sea-ice: number of categories
+   USE icevar         ! sea-ice: operations
    !
    USE in_out_manager ! I/O manager
@@ -47,5 +48,5 @@
 CONTAINS
 
-   SUBROUTINE ice_alb( pt_su, ph_ice, ph_snw, ld_pnd_alb, pafrac_pnd, ph_pnd, palb_cs, palb_os )
+   SUBROUTINE ice_alb( pt_su, ph_ice, ph_snw, ld_pnd_alb, pafrac_pnd, ph_pnd, pcloud_fra, palb_ice )
       !!----------------------------------------------------------------------
       !!               ***  ROUTINE ice_alb  ***
@@ -99,7 +100,8 @@
       REAL(wp), INTENT(in   ), DIMENSION(:,:,:) ::   pafrac_pnd   !  melt pond relative fraction (per unit ice area)
       REAL(wp), INTENT(in   ), DIMENSION(:,:,:) ::   ph_pnd       !  melt pond depth
-      REAL(wp), INTENT(  out), DIMENSION(:,:,:) ::   palb_cs      !  albedo of ice under clear    sky
-      REAL(wp), INTENT(  out), DIMENSION(:,:,:) ::   palb_os      !  albedo of ice under overcast sky
-      !
+      REAL(wp), INTENT(in   ), DIMENSION(:,:)   ::   pcloud_fra   !  cloud fraction
+      REAL(wp), INTENT(  out), DIMENSION(:,:,:) ::   palb_ice     !  albedo of ice
+      !
+      REAL(wp), DIMENSION(jpi,jpj,jpl) :: za_s_fra   ! ice fraction covered by snow
       INTEGER  ::   ji, jj, jl                ! dummy loop indices
       REAL(wp) ::   z1_c1, z1_c2,z1_c3, z1_c4 ! local scalar
@@ -108,4 +110,5 @@
       REAL(wp) ::   zalb_ice, zafrac_ice      ! bare sea ice albedo & relative ice fraction
       REAL(wp) ::   zalb_snw, zafrac_snw      ! snow-covered sea ice albedo & relative snow fraction
+      REAL(wp) ::   zalb_cs, zalb_os          ! albedo of ice under clear/overcast sky
       !!---------------------------------------------------------------------
       !
@@ -118,27 +121,29 @@
       z1_c4 = 1. / 0.03
       !
+      CALL ice_var_snwfra( ph_snw, za_s_fra )   ! calculate ice fraction covered by snow
+      !
       DO jl = 1, jpl
-         DO_2D_11_11
-            !                       !--- Specific snow, ice and pond fractions (for now, we prevent melt ponds and snow at the same time)
-            IF( ph_snw(ji,jj,jl) == 0._wp ) THEN
-               zafrac_snw = 0._wp
-               IF( ld_pnd_alb ) THEN
-                  zafrac_pnd = pafrac_pnd(ji,jj,jl)
-               ELSE
-                  zafrac_pnd = 0._wp
-               ENDIF
-               zafrac_ice = 1._wp - zafrac_pnd
+         DO_2D( 1, 1, 1, 1 )
+            !
+            !---------------------------------------------!
+            !--- Specific snow, ice and pond fractions ---!
+            !---------------------------------------------!               
+            zafrac_snw = za_s_fra(ji,jj,jl)
+            IF( ld_pnd_alb ) THEN
+               zafrac_pnd = MIN( pafrac_pnd(ji,jj,jl), 1._wp - zafrac_snw ) ! make sure (a_ip_eff + a_s_fra) <= 1
             ELSE
-               zafrac_snw = 1._wp      ! Snow fully "shades" melt ponds and ice
                zafrac_pnd = 0._wp
-               zafrac_ice = 0._wp
-            ENDIF
-            !
+            ENDIF
+            zafrac_ice = MAX( 0._wp, 1._wp - zafrac_pnd - zafrac_snw ) ! max for roundoff errors
+            !
+            !---------------!
+            !--- Albedos ---!
+            !---------------!               
             !                       !--- Bare ice albedo (for hi > 150cm)
             IF( ld_pnd_alb ) THEN
                zalb_ice = rn_alb_idry
             ELSE
-               IF( ph_snw(ji,jj,jl) == 0._wp .AND. pt_su(ji,jj,jl) >= rt0 ) THEN  ;   zalb_ice = rn_alb_imlt
-               ELSE                                                               ;   zalb_ice = rn_alb_idry   ;   ENDIF
+               IF( ph_snw(ji,jj,jl) == 0._wp .AND. pt_su(ji,jj,jl) >= rt0 ) THEN   ;   zalb_ice = rn_alb_imlt
+               ELSE                                                                ;   zalb_ice = rn_alb_idry   ;   ENDIF
             ENDIF
             !                       !--- Bare ice albedo (for hi < 150cm)
@@ -156,16 +161,15 @@
             ENDIF
             !                       !--- Ponded ice albedo
-            IF( ld_pnd_alb ) THEN
-               zalb_pnd = rn_alb_dpnd - ( rn_alb_dpnd - zalb_ice ) * EXP( - ph_pnd(ji,jj,jl) * z1_href_pnd ) 
-            ELSE
-               zalb_pnd = rn_alb_dpnd
-            ENDIF
+            zalb_pnd = rn_alb_dpnd - ( rn_alb_dpnd - zalb_ice ) * EXP( - ph_pnd(ji,jj,jl) * z1_href_pnd ) 
+            !
             !                       !--- Surface albedo is weighted mean of snow, ponds and bare ice contributions
-            palb_os(ji,jj,jl) = ( zafrac_snw * zalb_snw + zafrac_pnd * zalb_pnd + zafrac_ice * zalb_ice ) * tmask(ji,jj,1)
-            !
-            palb_cs(ji,jj,jl) = palb_os(ji,jj,jl)  &
-               &                - ( - 0.1010 * palb_os(ji,jj,jl) * palb_os(ji,jj,jl)  &
-               &                    + 0.1933 * palb_os(ji,jj,jl) - 0.0148 ) * tmask(ji,jj,1)
-            !
+            zalb_os = ( zafrac_snw * zalb_snw + zafrac_pnd * zalb_pnd + zafrac_ice * zalb_ice ) * tmask(ji,jj,1)
+            !
+            zalb_cs = zalb_os - ( - 0.1010 * zalb_os * zalb_os  &
+               &                  + 0.1933 * zalb_os - 0.0148 ) * tmask(ji,jj,1)
+            !
+            ! albedo depends on cloud fraction because of non-linear spectral effects
+            palb_ice(ji,jj,jl) = ( 1._wp - pcloud_fra(ji,jj) ) * zalb_cs + pcloud_fra(ji,jj) * zalb_os
+
          END_2D
       END DO
Index: NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icecor.F90
===================================================================
--- NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icecor.F90	(revision 13033)
+++ NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icecor.F90	(revision 13727)
@@ -55,5 +55,4 @@
       INTEGER  ::   ji, jj, jk, jl   ! dummy loop indices
       REAL(wp) ::   zsal, zzc
-      REAL(wp), DIMENSION(jpi,jpj) ::   zafx   ! concentration trends diag
       !!----------------------------------------------------------------------
       ! controls
@@ -81,6 +80,10 @@
       DO jl = 1, jpl
          WHERE( at_i(:,:) > rn_amax_2d(:,:) )   a_i(:,:,jl) = a_i(:,:,jl) * rn_amax_2d(:,:) / at_i(:,:)
-      END DO
-    
+      END DO    
+      !                             !-----------------------------------------------------
+      !                             !  Rebin categories with thickness out of bounds     !
+      !                             !-----------------------------------------------------
+      IF ( jpl > 1 )   CALL ice_itd_reb( kt )
+      !
       !                             !-----------------------------------------------------
       IF ( nn_icesal == 2 ) THEN    !  salinity must stay in bounds [Simin,Simax]        !
@@ -88,23 +91,22 @@
          zzc = rhoi * r1_Dt_ice
          DO jl = 1, jpl
-            DO_2D_11_11
+            DO_2D( 1, 1, 1, 1 )
                zsal = sv_i(ji,jj,jl)
                sv_i(ji,jj,jl) = MIN(  MAX( rn_simin*v_i(ji,jj,jl) , sv_i(ji,jj,jl) ) , rn_simax*v_i(ji,jj,jl)  )
-               sfx_res(ji,jj) = sfx_res(ji,jj) - ( sv_i(ji,jj,jl) - zsal ) * zzc   ! associated salt flux
+               IF( kn /= 0 ) & ! no ice-ocean exchanges if kn=0 (for bdy for instance) otherwise conservation diags will fail
+                  &   sfx_res(ji,jj) = sfx_res(ji,jj) - ( sv_i(ji,jj,jl) - zsal ) * zzc   ! associated salt flux
             END_2D
          END DO
       ENDIF
-      !                             !-----------------------------------------------------
-      !                             !  Rebin categories with thickness out of bounds     !
-      !                             !-----------------------------------------------------
-      IF ( jpl > 1 )   CALL ice_itd_reb( kt )
 
-      !                             !-----------------------------------------------------
-      CALL ice_var_zapsmall         !  Zap small values                                  !
-      !                             !-----------------------------------------------------
-
+      IF( kn /= 0 ) THEN   ! no zapsmall if kn=0 (for bdy for instance) because we do not want ice-ocean exchanges (wfx,sfx,hfx)
+         !                                                              otherwise conservation diags will fail
+         !                          !-----------------------------------------------------
+         CALL ice_var_zapsmall      !  Zap small values                                  !
+         !                          !-----------------------------------------------------
+      ENDIF
       !                             !-----------------------------------------------------
       IF( kn == 2 ) THEN            !  Ice drift case: Corrections to avoid wrong values !
-         DO_2D_00_00
+         DO_2D( 0, 0, 0, 0 )        !-----------------------------------------------------
             IF ( at_i(ji,jj) == 0._wp ) THEN    ! what to do if there is no ice
                IF ( at_i(ji+1,jj) == 0._wp )   u_ice(ji  ,jj) = 0._wp   ! right side
@@ -114,49 +116,6 @@
             ENDIF
          END_2D
-         CALL lbc_lnk_multi( 'icecor', u_ice, 'U', -1., v_ice, 'V', -1. )
+         CALL lbc_lnk_multi( 'icecor', u_ice, 'U', -1.0_wp, v_ice, 'V', -1.0_wp )
       ENDIF
-
-      !                             !-----------------------------------------------------
-      SELECT CASE( kn )             !  Diagnostics                                       !
-      !                             !-----------------------------------------------------
-      CASE( 1 )                        !--- dyn trend diagnostics
-         !
-         IF( ln_icediachk .OR. iom_use('hfxdhc') ) THEN
-            diag_heat(:,:) = - SUM(SUM( e_i (:,:,1:nlay_i,:) - e_i_b (:,:,1:nlay_i,:), dim=4 ), dim=3 ) * r1_Dt_ice &      ! W.m-2
-               &             - SUM(SUM( e_s (:,:,1:nlay_s,:) - e_s_b (:,:,1:nlay_s,:), dim=4 ), dim=3 ) * r1_Dt_ice
-            diag_sice(:,:) =   SUM(     sv_i(:,:,:)          - sv_i_b(:,:,:)                  , dim=3 ) * r1_Dt_ice * rhoi
-            diag_vice(:,:) =   SUM(     v_i (:,:,:)          - v_i_b (:,:,:)                  , dim=3 ) * r1_Dt_ice * rhoi
-            diag_vsnw(:,:) =   SUM(     v_s (:,:,:)          - v_s_b (:,:,:)                  , dim=3 ) * r1_Dt_ice * rhos
-         ENDIF
-         !                       ! concentration tendency (dynamics)
-         IF( iom_use('afxdyn') .OR. iom_use('afxthd') .OR. iom_use('afxtot') ) THEN 
-            zafx(:,:) = SUM( a_i(:,:,:) - a_i_b(:,:,:), dim=3 ) * r1_Dt_ice 
-            CALL iom_put( 'afxdyn' , zafx )
-         ENDIF
-         !
-      CASE( 2 )                        !--- thermo trend diagnostics & ice aging
-         !
-         oa_i(:,:,:) = oa_i(:,:,:) + a_i(:,:,:) * rDt_ice   ! ice natural aging incrementation
-         !
-         IF( ln_icediachk .OR. iom_use('hfxdhc') ) THEN
-            diag_heat(:,:) = diag_heat(:,:) &
-               &             - SUM(SUM( e_i (:,:,1:nlay_i,:) - e_i_b (:,:,1:nlay_i,:), dim=4 ), dim=3 ) * r1_Dt_ice &
-               &             - SUM(SUM( e_s (:,:,1:nlay_s,:) - e_s_b (:,:,1:nlay_s,:), dim=4 ), dim=3 ) * r1_Dt_ice
-            diag_sice(:,:) = diag_sice(:,:) &
-               &             + SUM(     sv_i(:,:,:)          - sv_i_b(:,:,:)                  , dim=3 ) * r1_Dt_ice * rhoi
-            diag_vice(:,:) = diag_vice(:,:) &
-               &             + SUM(     v_i (:,:,:)          - v_i_b (:,:,:)                  , dim=3 ) * r1_Dt_ice * rhoi
-            diag_vsnw(:,:) = diag_vsnw(:,:) &
-               &             + SUM(     v_s (:,:,:)          - v_s_b (:,:,:)                  , dim=3 ) * r1_Dt_ice * rhos
-            CALL iom_put ( 'hfxdhc' , diag_heat ) 
-         ENDIF
-         !                       ! concentration tendency (total + thermo)
-         IF( iom_use('afxdyn') .OR. iom_use('afxthd') .OR. iom_use('afxtot') ) THEN 
-            zafx(:,:) = zafx(:,:) + SUM( a_i(:,:,:) - a_i_b(:,:,:), dim=3 ) * r1_Dt_ice
-            CALL iom_put( 'afxthd' , SUM( a_i(:,:,:) - a_i_b(:,:,:), dim=3 ) * r1_Dt_ice )
-            CALL iom_put( 'afxtot' , zafx )
-         ENDIF
-         !
-      END SELECT
       !
       ! controls
Index: NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icectl.F90
===================================================================
--- NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icectl.F90	(revision 13033)
+++ NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icectl.F90	(revision 13727)
@@ -43,4 +43,6 @@
    PUBLIC   ice_prt
    PUBLIC   ice_prt3D
+   PUBLIC   ice_drift_wri
+   PUBLIC   ice_drift_init
 
    ! thresold rates for conservation
@@ -49,4 +51,10 @@
    REAL(wp), PARAMETER ::   zchk_s   = 2.5e-6   ! g/m2/s  <=> 1e-6 m of ice per hour spuriously gained/lost (considering s=10g/kg)
    REAL(wp), PARAMETER ::   zchk_t   = 7.5e-2   ! W/m2    <=> 1e-6 m of ice per hour spuriously gained/lost (considering Lf=3e5J/kg)
+
+   ! for drift outputs
+   CHARACTER(LEN=50)   ::   clname="icedrift_diagnostics.ascii"   ! ascii filename
+   INTEGER             ::   numicedrift                           ! outfile unit
+   REAL(wp)            ::   rdiag_icemass, rdiag_icesalt, rdiag_iceheat 
+   REAL(wp)            ::   rdiag_adv_icemass, rdiag_adv_icesalt, rdiag_adv_iceheat 
    
    !! * Substitutions
@@ -132,6 +140,6 @@
 
          ! -- advection scheme is conservative? -- !
-         zvtrp = glob_sum( 'icectl', ( diag_trp_vi * rhoi + diag_trp_vs * rhos ) * e1e2t ) ! must be close to 0 (only for Prather)
-         zetrp = glob_sum( 'icectl', ( diag_trp_ei        + diag_trp_es        ) * e1e2t ) ! must be close to 0 (only for Prather)
+         zvtrp = glob_sum( 'icectl', diag_adv_mass * e1e2t )
+         zetrp = glob_sum( 'icectl', diag_adv_heat * e1e2t )
 
          ! ice area (+epsi10 to set a threshold > 0 when there is no ice) 
@@ -156,9 +164,8 @@
                &                   WRITE(numout,*)   cd_routine,' : violation a_i > amax      = ',zdiag_amax
             ! check if advection scheme is conservative
-            !    only check for Prather because Ultimate-Macho uses corrective fluxes (wfx etc)
-            !    so the formulation for conservation is different (and not coded) 
-            !    it does not mean UM is not conservative (it is checked with above prints) => update (09/2019): same for Prather now
-            !IF( ln_adv_Pra .AND. ABS(zvtrp) > zchk_m * rn_icechk_glo * zarea .AND. cd_routine == 'icedyn_adv' ) &
-            !   &                   WRITE(numout,*)   cd_routine,' : violation adv scheme [kg] = ',zvtrp * rDt_ice
+            IF( ABS(zvtrp) > zchk_m * rn_icechk_glo * zarea .AND. cd_routine == 'icedyn_adv' ) &
+               &                   WRITE(numout,*)   cd_routine,' : violation adv scheme [kg] = ',zvtrp * rdt_ice
+            IF( ABS(zetrp) > zchk_t * rn_icechk_glo * zarea .AND. cd_routine == 'icedyn_adv' ) &
+               &                   WRITE(numout,*)   cd_routine,' : violation adv scheme [J]  = ',zetrp * rdt_ice
          ENDIF
          !
@@ -186,13 +193,16 @@
       ! water flux
       ! -- mass diag -- !
-      zdiag_mass = glob_sum( 'icectl', ( wfx_ice + wfx_snw + wfx_spr + wfx_sub + diag_vice + diag_vsnw ) * e1e2t )
+      zdiag_mass = glob_sum( 'icectl', (  wfx_ice   + wfx_snw   + wfx_spr + wfx_sub &
+         &                              + diag_vice + diag_vsnw - diag_adv_mass ) * e1e2t )
 
       ! -- salt diag -- !
-      zdiag_salt = glob_sum( 'icectl', ( sfx + diag_sice ) * e1e2t )
+      zdiag_salt = glob_sum( 'icectl', ( sfx + diag_sice - diag_adv_salt ) * e1e2t )
 
       ! -- heat diag -- !
-      ! clem: not the good formulation
-      !!zdiag_heat  = glob_sum( 'icectl', ( qt_oce_ai - qt_atm_oi + diag_heat + hfx_thd + hfx_dyn + hfx_res + hfx_sub + hfx_spr  &
-      !!   &                              ) * e1e2t )
+      zdiag_heat  = glob_sum( 'icectl', ( qt_oce_ai - qt_atm_oi + diag_heat - diag_adv_heat ) * e1e2t )
+      ! equivalent to this:
+      !!zdiag_heat = glob_sum( 'icectl', ( -diag_heat + hfx_sum + hfx_bom + hfx_bog + hfx_dif + hfx_opw + hfx_snw &
+      !!   &                                          - hfx_thd - hfx_dyn - hfx_res - hfx_sub - hfx_spr &
+      !!   &                                          ) * e1e2t )
 
       ! ice area (+epsi10 to set a threshold > 0 when there is no ice) 
@@ -204,5 +214,6 @@
          IF( ABS(zdiag_salt) > zchk_s * rn_icechk_glo * zarea ) &
             &                   WRITE(numout,*) cd_routine,' : violation salt cons. [g]  = ',zdiag_salt * rDt_ice
-         !!IF( ABS(zdiag_heat) > zchk_t * rn_icechk_glo * zarea ) WRITE(numout,*) cd_routine,' : violation heat cons. [J]  = ',zdiag_heat * rDt_ice
+         IF( ABS(zdiag_heat) > zchk_t * rn_icechk_glo * zarea ) &
+            &                   WRITE(numout,*) cd_routine,' : violation heat cons. [J]  = ',zdiag_heat * rDt_ice
       ENDIF
       !
@@ -350,138 +361,136 @@
       !!                   ***  ROUTINE ice_ctl *** 
       !!                 
-      !! ** Purpose :   Alerts in case of model crash
+      !! ** Purpose :   control checks
       !!-------------------------------------------------------------------
       INTEGER, INTENT(in) ::   kt      ! ocean time step
-      INTEGER  ::   ji, jj, jk,  jl   ! dummy loop indices
-      INTEGER  ::   inb_altests       ! number of alert tests (max 20)
-      INTEGER  ::   ialert_id         ! number of the current alert
-      REAL(wp) ::   ztmelts           ! ice layer melting point
+      INTEGER  ::   ja, ji, jj, jk, jl ! dummy loop indices
+      INTEGER  ::   ialert_id          ! number of the current alert
+      REAL(wp) ::   ztmelts            ! ice layer melting point
       CHARACTER (len=30), DIMENSION(20) ::   cl_alname   ! name of alert
       INTEGER           , DIMENSION(20) ::   inb_alp     ! number of alerts positive
       !!-------------------------------------------------------------------
-
-      inb_altests = 10
-      inb_alp(:)  =  0
-
-      ! Alert if incompatible volume and concentration
-      ialert_id = 2 ! reference number of this alert
-      cl_alname(ialert_id) = ' Incompat vol and con         '    ! name of the alert
+      inb_alp(:) = 0
+      ialert_id = 0
+      
+      ! Alert if very high salinity
+      ialert_id = ialert_id + 1 ! reference number of this alert
+      cl_alname(ialert_id) = ' Very high salinity ' ! name of the alert
       DO jl = 1, jpl
-         DO_2D_11_11
-            IF(  v_i(ji,jj,jl) /= 0._wp   .AND.   a_i(ji,jj,jl) == 0._wp   ) THEN
-               WRITE(numout,*) ' ALERTE 2 :   Incompatible volume and concentration '
-               inb_alp(ialert_id) = inb_alp(ialert_id) + 1
+         DO_2D( 1, 1, 1, 1 )
+            IF( v_i(ji,jj,jl) > epsi10  ) THEN
+               IF( sv_i(ji,jj,jl) / v_i(ji,jj,jl) > rn_simax ) THEN
+                  WRITE(numout,*) ' ALERTE :   Very high salinity ',sv_i(ji,jj,jl)/v_i(ji,jj,jl)
+                  WRITE(numout,*) ' at i,j,l = ',ji,jj,jl
+                  inb_alp(ialert_id) = inb_alp(ialert_id) + 1
+               ENDIF
             ENDIF
          END_2D
       END DO
 
-      ! Alerte if very thick ice
-      ialert_id = 3 ! reference number of this alert
-      cl_alname(ialert_id) = ' Very thick ice               ' ! name of the alert
-      jl = jpl 
-      DO_2D_11_11
-         IF(   h_i(ji,jj,jl)  >  50._wp   ) THEN
-            WRITE(numout,*) ' ALERTE 3 :   Very thick ice'
-            !CALL ice_prt( kt, ji, jj, 2, ' ALERTE 3 :   Very thick ice ' )
-            inb_alp(ialert_id) = inb_alp(ialert_id) + 1
-         ENDIF
-      END_2D
-
-      ! Alert if very fast ice
-      ialert_id = 4 ! reference number of this alert
-      cl_alname(ialert_id) = ' Very fast ice               ' ! name of the alert
-      DO_2D_11_11
-         IF(   MAX( ABS( u_ice(ji,jj) ), ABS( v_ice(ji,jj) ) ) > 2.  .AND.  &
-            &  at_i(ji,jj) > 0._wp   ) THEN
-            WRITE(numout,*) ' ALERTE 4 :   Very fast ice'
-            !CALL ice_prt( kt, ji, jj, 1, ' ALERTE 4 :   Very fast ice ' )
-            inb_alp(ialert_id) = inb_alp(ialert_id) + 1
-         ENDIF
-      END_2D
-
-      ! Alert on salt flux
-      ialert_id = 5 ! reference number of this alert
-      cl_alname(ialert_id) = ' High salt flux               ' ! name of the alert
-      DO_2D_11_11
-         IF( ABS( sfx (ji,jj) ) > 1.0e-2 ) THEN  ! = 1 psu/day for 1m ocean depth
-            WRITE(numout,*) ' ALERTE 5 :   High salt flux'
-            !CALL ice_prt( kt, ji, jj, 3, ' ALERTE 5 :   High salt flux ' )
-            inb_alp(ialert_id) = inb_alp(ialert_id) + 1
-         ENDIF
-      END_2D
-
-      ! Alert if there is ice on continents
-      ialert_id = 6 ! reference number of this alert
-      cl_alname(ialert_id) = ' Ice on continents           ' ! name of the alert
-      DO_2D_11_11
-         IF(   tmask(ji,jj,1) <= 0._wp   .AND.   at_i(ji,jj) > 0._wp   ) THEN 
-            WRITE(numout,*) ' ALERTE 6 :   Ice on continents'
-            !CALL ice_prt( kt, ji, jj, 1, ' ALERTE 6 :   Ice on continents ' )
-            inb_alp(ialert_id) = inb_alp(ialert_id) + 1
-         ENDIF
-      END_2D
-
-!
-!     ! Alert if very fresh ice
-      ialert_id = 7 ! reference number of this alert
-      cl_alname(ialert_id) = ' Very fresh ice               ' ! name of the alert
+      ! Alert if very low salinity
+      ialert_id = ialert_id + 1 ! reference number of this alert
+      cl_alname(ialert_id) = ' Very low salinity ' ! name of the alert
       DO jl = 1, jpl
-         DO_2D_11_11
-            IF( s_i(ji,jj,jl) < 0.1 .AND. a_i(ji,jj,jl) > 0._wp ) THEN
-               WRITE(numout,*) ' ALERTE 7 :   Very fresh ice'
-!                 CALL ice_prt(kt,ji,jj,1, ' ALERTE 7 :   Very fresh ice ' )
-               inb_alp(ialert_id) = inb_alp(ialert_id) + 1
+         DO_2D( 1, 1, 1, 1 )
+            IF( v_i(ji,jj,jl) > epsi10  ) THEN
+               IF( sv_i(ji,jj,jl) / v_i(ji,jj,jl) < rn_simin ) THEN
+                  WRITE(numout,*) ' ALERTE :   Very low salinity ',sv_i(ji,jj,jl),v_i(ji,jj,jl)
+                  WRITE(numout,*) ' at i,j,l = ',ji,jj,jl
+                  inb_alp(ialert_id) = inb_alp(ialert_id) + 1
+               ENDIF
             ENDIF
          END_2D
       END DO
-!
-      ! Alert if qns very big
-      ialert_id = 8 ! reference number of this alert
-      cl_alname(ialert_id) = ' fnsolar very big             ' ! name of the alert
-      DO_2D_11_11
-         IF( ABS( qns(ji,jj) ) > 1500._wp .AND. at_i(ji,jj) > 0._wp ) THEN
-            !
-            WRITE(numout,*) ' ALERTE 8 :   Very high non-solar heat flux'
-            !CALL ice_prt( kt, ji, jj, 2, '   ')
-            inb_alp(ialert_id) = inb_alp(ialert_id) + 1
-            !
-         ENDIF
-      END_2D
-      !+++++
-
-!     ! Alert if too old ice
-      ialert_id = 9 ! reference number of this alert
-      cl_alname(ialert_id) = ' Very old   ice               ' ! name of the alert
+
+      ! Alert if very cold ice
+      ialert_id = ialert_id + 1 ! reference number of this alert
+      cl_alname(ialert_id) = ' Very cold ice ' ! name of the alert
       DO jl = 1, jpl
-         DO_2D_11_11
-            IF ( ( ( ABS( o_i(ji,jj,jl) ) > rDt_ice ) .OR. &
-                   ( ABS( o_i(ji,jj,jl) ) < 0._wp) ) .AND. &
-                          ( a_i(ji,jj,jl) > 0._wp ) ) THEN
-               WRITE(numout,*) ' ALERTE 9 :   Wrong ice age'
-               !CALL ice_prt( kt, ji, jj, 1, ' ALERTE 9 :   Wrong ice age ')
-               inb_alp(ialert_id) = inb_alp(ialert_id) + 1
-            ENDIF
-         END_2D
-      END DO
-  
-      ! Alert if very warm ice
-      ialert_id = 10 ! reference number of this alert
-      cl_alname(ialert_id) = ' Very warm ice                ' ! name of the alert
-      inb_alp(ialert_id) = 0
-      DO jl = 1, jpl
-         DO_3D_11_11( 1, nlay_i )
+         DO_3D( 1, 1, 1, 1, 1, nlay_i )
             ztmelts    =  -rTmlt * sz_i(ji,jj,jk,jl) + rt0
-            IF( t_i(ji,jj,jk,jl) > ztmelts  .AND.  v_i(ji,jj,jl) > 1.e-10   &
-               &                            .AND.  a_i(ji,jj,jl) > 0._wp   ) THEN
-               WRITE(numout,*) ' ALERTE 10 :   Very warm ice'
+            IF( t_i(ji,jj,jk,jl) < -50.+rt0  .AND.  v_i(ji,jj,jl) > epsi10 ) THEN
+               WRITE(numout,*) ' ALERTE :   Very cold ice ',(t_i(ji,jj,jk,jl)-rt0)
+               WRITE(numout,*) ' at i,j,k,l = ',ji,jj,jk,jl
               inb_alp(ialert_id) = inb_alp(ialert_id) + 1
             ENDIF
          END_3D
       END DO
+  
+      ! Alert if very warm ice
+      ialert_id = ialert_id + 1 ! reference number of this alert
+      cl_alname(ialert_id) = ' Very warm ice ' ! name of the alert
+      DO jl = 1, jpl
+         DO_3D( 1, 1, 1, 1, 1, nlay_i )
+            ztmelts    =  -rTmlt * sz_i(ji,jj,jk,jl) + rt0
+            IF( t_i(ji,jj,jk,jl) > ztmelts  .AND.  v_i(ji,jj,jl) > epsi10 ) THEN
+               WRITE(numout,*) ' ALERTE :   Very warm ice',(t_i(ji,jj,jk,jl)-rt0)
+               WRITE(numout,*) ' at i,j,k,l = ',ji,jj,jk,jl
+              inb_alp(ialert_id) = inb_alp(ialert_id) + 1
+            ENDIF
+         END_3D
+      END DO
+      
+      ! Alerte if very thick ice
+      ialert_id = ialert_id + 1 ! reference number of this alert
+      cl_alname(ialert_id) = ' Very thick ice ' ! name of the alert
+      jl = jpl 
+      DO_2D( 1, 1, 1, 1 )
+         IF( h_i(ji,jj,jl) > 50._wp ) THEN
+            WRITE(numout,*) ' ALERTE :   Very thick ice ',h_i(ji,jj,jl)
+            WRITE(numout,*) ' at i,j,l = ',ji,jj,jl
+            inb_alp(ialert_id) = inb_alp(ialert_id) + 1
+         ENDIF
+      END_2D
+
+      ! Alerte if very thin ice
+      ialert_id = ialert_id + 1 ! reference number of this alert
+      cl_alname(ialert_id) = ' Very thin ice ' ! name of the alert
+      jl = 1 
+      DO_2D( 1, 1, 1, 1 )
+         IF( h_i(ji,jj,jl) < rn_himin ) THEN
+            WRITE(numout,*) ' ALERTE :   Very thin ice ',h_i(ji,jj,jl)
+            WRITE(numout,*) ' at i,j,l = ',ji,jj,jl
+            inb_alp(ialert_id) = inb_alp(ialert_id) + 1
+         ENDIF
+      END_2D
+
+      ! Alert if very fast ice
+      ialert_id = ialert_id + 1 ! reference number of this alert
+      cl_alname(ialert_id) = ' Very fast ice ' ! name of the alert
+      DO_2D( 1, 1, 1, 1 )
+         IF( MAX( ABS( u_ice(ji,jj) ), ABS( v_ice(ji,jj) ) ) > 2. ) THEN
+            WRITE(numout,*) ' ALERTE :   Very fast ice ',MAX( ABS( u_ice(ji,jj) ), ABS( v_ice(ji,jj) ) )
+            WRITE(numout,*) ' at i,j = ',ji,jj
+            inb_alp(ialert_id) = inb_alp(ialert_id) + 1
+         ENDIF
+      END_2D
+
+      ! Alert if there is ice on continents
+      ialert_id = ialert_id + 1 ! reference number of this alert
+      cl_alname(ialert_id) = ' Ice on continents ' ! name of the alert
+      DO_2D( 1, 1, 1, 1 )
+         IF( tmask(ji,jj,1) == 0._wp .AND. ( at_i(ji,jj) > 0._wp .OR. vt_i(ji,jj) > 0._wp ) ) THEN 
+            WRITE(numout,*) ' ALERTE :   Ice on continents ',at_i(ji,jj),vt_i(ji,jj)
+            WRITE(numout,*) ' at i,j = ',ji,jj
+            inb_alp(ialert_id) = inb_alp(ialert_id) + 1
+         ENDIF
+      END_2D
+
+      ! Alert if incompatible ice concentration and volume
+      ialert_id = ialert_id + 1 ! reference number of this alert
+      cl_alname(ialert_id) = ' Incompatible ice conc and vol ' ! name of the alert
+      DO_2D( 1, 1, 1, 1 )
+         IF(  ( vt_i(ji,jj) == 0._wp .AND. at_i(ji,jj) >  0._wp ) .OR. &
+            & ( vt_i(ji,jj) >  0._wp .AND. at_i(ji,jj) == 0._wp ) ) THEN 
+            WRITE(numout,*) ' ALERTE :   Incompatible ice conc and vol ',at_i(ji,jj),vt_i(ji,jj)
+            WRITE(numout,*) ' at i,j = ',ji,jj
+            inb_alp(ialert_id) = inb_alp(ialert_id) + 1
+         ENDIF
+      END_2D
 
       ! sum of the alerts on all processors
       IF( lk_mpp ) THEN
-         DO ialert_id = 1, inb_altests
-            CALL mpp_sum('icectl', inb_alp(ialert_id))
+         DO ja = 1, ialert_id
+            CALL mpp_sum('icectl', inb_alp(ja))
          END DO
       ENDIF
@@ -489,10 +498,8 @@
       ! print alerts
       IF( lwp ) THEN
-         ialert_id = 1                                 ! reference number of this alert
-         cl_alname(ialert_id) = ' NO alerte 1      '   ! name of the alert
          WRITE(numout,*) ' time step ',kt
          WRITE(numout,*) ' All alerts at the end of ice model '
-         DO ialert_id = 1, inb_altests
-            WRITE(numout,*) ialert_id, cl_alname(ialert_id)//' : ', inb_alp(ialert_id), ' times ! '
+         DO ja = 1, ialert_id
+            WRITE(numout,*) ja, cl_alname(ja)//' : ', inb_alp(ja), ' times ! '
          END DO
       ENDIF
@@ -543,5 +550,4 @@
                WRITE(numout,*) ' v_ice(i  ,j)  : ', v_ice(ji,jj)
                WRITE(numout,*) ' strength      : ', strength(ji,jj)
-               WRITE(numout,*)
                WRITE(numout,*) ' - Cell values '
                WRITE(numout,*) '   ~~~~~~~~~~~ '
@@ -552,4 +558,5 @@
                DO jl = 1, jpl
                   WRITE(numout,*) ' - Category (', jl,')'
+                  WRITE(numout,*) '   ~~~~~~~~~~~ '
                   WRITE(numout,*) ' a_i           : ', a_i(ji,jj,jl)
                   WRITE(numout,*) ' h_i           : ', h_i(ji,jj,jl)
@@ -588,5 +595,4 @@
                WRITE(numout,*) ' v_ice(i  ,j)  : ', v_ice(ji,jj)
                WRITE(numout,*) ' strength      : ', strength(ji,jj)
-               WRITE(numout,*) ' u_ice_b       : ', u_ice_b(ji,jj)    , ' v_ice_b       : ', v_ice_b(ji,jj)  
                WRITE(numout,*)
                
@@ -605,5 +611,4 @@
                   WRITE(numout,*) ' e_snow     : ', e_s(ji,jj,1,jl)            , ' e_snow_b   : ', e_s_b(ji,jj,1,jl) 
                   WRITE(numout,*) ' sv_i       : ', sv_i(ji,jj,jl)             , ' sv_i_b     : ', sv_i_b(ji,jj,jl)   
-                  WRITE(numout,*) ' oa_i       : ', oa_i(ji,jj,jl)             , ' oa_i_b     : ', oa_i_b(ji,jj,jl)
                END DO !jl
                
@@ -702,5 +707,5 @@
       DO jl = 1, jpl
          CALL prt_ctl_info(' ')
-         CALL prt_ctl_info(' - Category : ', ivar1=jl)
+         CALL prt_ctl_info(' - Category : ', ivar=jl)
          CALL prt_ctl_info('   ~~~~~~~~~~')
          CALL prt_ctl(tab2d_1=h_i        (:,:,jl)        , clinfo1= ' h_i         : ')
@@ -713,5 +718,4 @@
          CALL prt_ctl(tab2d_1=v_i        (:,:,jl)        , clinfo1= ' v_i         : ')
          CALL prt_ctl(tab2d_1=v_s        (:,:,jl)        , clinfo1= ' v_s         : ')
-         CALL prt_ctl(tab2d_1=e_i        (:,:,1,jl)      , clinfo1= ' e_i1        : ')
          CALL prt_ctl(tab2d_1=e_s        (:,:,1,jl)      , clinfo1= ' e_snow      : ')
          CALL prt_ctl(tab2d_1=sv_i       (:,:,jl)        , clinfo1= ' sv_i        : ')
@@ -719,6 +723,7 @@
          
          DO jk = 1, nlay_i
-            CALL prt_ctl_info(' - Layer : ', ivar1=jk)
+            CALL prt_ctl_info(' - Layer : ', ivar=jk)
             CALL prt_ctl(tab2d_1=t_i(:,:,jk,jl) , clinfo1= ' t_i       : ')
+            CALL prt_ctl(tab2d_1=e_i(:,:,jk,jl) , clinfo1= ' e_i       : ')
          END DO
       END DO
@@ -731,4 +736,133 @@
       
    END SUBROUTINE ice_prt3D
+
+
+   SUBROUTINE ice_drift_wri( kt )
+      !!-------------------------------------------------------------------
+      !!                     ***  ROUTINE ice_drift_wri ***
+      !!
+      !! ** Purpose : conservation of mass, salt and heat
+      !!              write the drift in a ascii file at each time step
+      !!              and the total run drifts
+      !!-------------------------------------------------------------------
+      INTEGER, INTENT(in) ::   kt   ! ice time-step index
+      !
+      INTEGER  ::   ji, jj
+      REAL(wp) ::   zdiag_mass, zdiag_salt, zdiag_heat, zdiag_adv_mass, zdiag_adv_salt, zdiag_adv_heat
+      REAL(wp), DIMENSION(jpi,jpj) ::   zdiag_mass2D, zdiag_salt2D, zdiag_heat2D
+      !!-------------------------------------------------------------------
+      !
+      IF( kt == nit000 .AND. lwp ) THEN
+         WRITE(numout,*)
+         WRITE(numout,*) 'ice_drift_wri: sea-ice drifts'
+         WRITE(numout,*) '~~~~~~~~~~~~~'
+      ENDIF
+      !
+      ! 2D budgets (must be close to 0)
+      IF( iom_use('icedrift_mass') .OR. iom_use('icedrift_salt') .OR. iom_use('icedrift_heat') ) THEN
+         DO_2D( 1, 1, 1, 1 )
+            zdiag_mass2D(ji,jj) =   wfx_ice(ji,jj)   + wfx_snw(ji,jj)   + wfx_spr(ji,jj) + wfx_sub(ji,jj) &
+               &                  + diag_vice(ji,jj) + diag_vsnw(ji,jj) - diag_adv_mass(ji,jj)
+            zdiag_salt2D(ji,jj) = sfx(ji,jj) + diag_sice(ji,jj) - diag_adv_salt(ji,jj)
+            zdiag_heat2D(ji,jj) = qt_oce_ai(ji,jj) - qt_atm_oi(ji,jj) + diag_heat(ji,jj) - diag_adv_heat(ji,jj)
+         END_2D
+         !
+         ! write outputs
+         CALL iom_put( 'icedrift_mass', zdiag_mass2D )
+         CALL iom_put( 'icedrift_salt', zdiag_salt2D )
+         CALL iom_put( 'icedrift_heat', zdiag_heat2D )
+      ENDIF
+
+      ! -- mass diag -- !
+      zdiag_mass     = glob_sum( 'icectl', (  wfx_ice   + wfx_snw   + wfx_spr + wfx_sub &
+         &                                  + diag_vice + diag_vsnw - diag_adv_mass ) * e1e2t ) * rdt_ice
+      zdiag_adv_mass = glob_sum( 'icectl', diag_adv_mass * e1e2t ) * rDt_ice
+
+      ! -- salt diag -- !
+      zdiag_salt     = glob_sum( 'icectl', ( sfx + diag_sice - diag_adv_salt ) * e1e2t ) * rdt_ice * 1.e-3
+      zdiag_adv_salt = glob_sum( 'icectl', diag_adv_salt * e1e2t ) * rDt_ice * 1.e-3
+
+      ! -- heat diag -- !
+      zdiag_heat     = glob_sum( 'icectl', ( qt_oce_ai - qt_atm_oi + diag_heat - diag_adv_heat ) * e1e2t )
+      zdiag_adv_heat = glob_sum( 'icectl', diag_adv_heat * e1e2t )
+
+      !                    ! write out to file
+      IF( lwp ) THEN
+         ! check global drift (must be close to 0)
+         WRITE(numicedrift,FMT='(2x,i6,3x,a19,4x,f25.5)') kt, 'mass drift     [kg]', zdiag_mass
+         WRITE(numicedrift,FMT='(11x,     a19,4x,f25.5)')     'salt drift     [kg]', zdiag_salt
+         WRITE(numicedrift,FMT='(11x,     a19,4x,f25.5)')     'heat drift     [W] ', zdiag_heat
+         ! check drift from advection scheme (can be /=0 with bdy but not sure why)
+         WRITE(numicedrift,FMT='(11x,     a19,4x,f25.5)')     'mass drift adv [kg]', zdiag_adv_mass
+         WRITE(numicedrift,FMT='(11x,     a19,4x,f25.5)')     'salt drift adv [kg]', zdiag_adv_salt
+         WRITE(numicedrift,FMT='(11x,     a19,4x,f25.5)')     'heat drift adv [W] ', zdiag_adv_heat
+      ENDIF
+      !                    ! drifts
+      rdiag_icemass = rdiag_icemass + zdiag_mass
+      rdiag_icesalt = rdiag_icesalt + zdiag_salt
+      rdiag_iceheat = rdiag_iceheat + zdiag_heat
+      rdiag_adv_icemass = rdiag_adv_icemass + zdiag_adv_mass
+      rdiag_adv_icesalt = rdiag_adv_icesalt + zdiag_adv_salt
+      rdiag_adv_iceheat = rdiag_adv_iceheat + zdiag_adv_heat
+      !
+      !                    ! output drifts and close ascii file
+      IF( kt == nitend - nn_fsbc + 1 .AND. lwp ) THEN
+         ! to ascii file
+         WRITE(numicedrift,*) '******************************************'
+         WRITE(numicedrift,FMT='(3x,a23,6x,E10.2)') 'Run mass drift     [kg]', rdiag_icemass
+         WRITE(numicedrift,FMT='(3x,a23,6x,E10.2)') 'Run mass drift adv [kg]', rdiag_adv_icemass
+         WRITE(numicedrift,*) '******************************************'
+         WRITE(numicedrift,FMT='(3x,a23,6x,E10.2)') 'Run salt drift     [kg]', rdiag_icesalt
+         WRITE(numicedrift,FMT='(3x,a23,6x,E10.2)') 'Run salt drift adv [kg]', rdiag_adv_icesalt
+         WRITE(numicedrift,*) '******************************************'
+         WRITE(numicedrift,FMT='(3x,a23,6x,E10.2)') 'Run heat drift     [W] ', rdiag_iceheat
+         WRITE(numicedrift,FMT='(3x,a23,6x,E10.2)') 'Run heat drift adv [W] ', rdiag_adv_iceheat
+         CLOSE( numicedrift )
+         !
+         ! to ocean output
+         WRITE(numout,*)
+         WRITE(numout,*) 'ice_drift_wri: ice drifts information for the run '
+         WRITE(numout,*) '~~~~~~~~~~~~~'
+         ! check global drift (must be close to 0)
+         WRITE(numout,*) '   sea-ice mass drift     [kg] = ', rdiag_icemass
+         WRITE(numout,*) '   sea-ice salt drift     [kg] = ', rdiag_icesalt
+         WRITE(numout,*) '   sea-ice heat drift     [W]  = ', rdiag_iceheat
+         ! check drift from advection scheme (can be /=0 with bdy but not sure why)
+         WRITE(numout,*) '   sea-ice mass drift adv [kg] = ', rdiag_adv_icemass
+         WRITE(numout,*) '   sea-ice salt drift adv [kg] = ', rdiag_adv_icesalt
+         WRITE(numout,*) '   sea-ice heat drift adv [W]  = ', rdiag_adv_iceheat
+      ENDIF
+      !
+   END SUBROUTINE ice_drift_wri
+
+   SUBROUTINE ice_drift_init
+      !!----------------------------------------------------------------------
+      !!                  ***  ROUTINE ice_drift_init  ***
+      !!                   
+      !! ** Purpose :   create output file, initialise arrays
+      !!----------------------------------------------------------------------
+      !
+      IF( .NOT.ln_icediachk ) RETURN ! exit
+      !
+      IF(lwp) THEN
+         WRITE(numout,*)
+         WRITE(numout,*) 'ice_drift_init: Output ice drifts to ',TRIM(clname), ' file'
+         WRITE(numout,*) '~~~~~~~~~~~~~'
+         WRITE(numout,*)
+         !
+         ! create output ascii file
+         CALL ctl_opn( numicedrift, clname, 'UNKNOWN', 'FORMATTED', 'SEQUENTIAL', 1, numout, lwp, narea )
+         WRITE(numicedrift,*) 'Timestep  Drifts'
+         WRITE(numicedrift,*) '******************************************'
+      ENDIF
+      !
+      rdiag_icemass = 0._wp
+      rdiag_icesalt = 0._wp
+      rdiag_iceheat = 0._wp
+      rdiag_adv_icemass = 0._wp
+      rdiag_adv_icesalt = 0._wp
+      rdiag_adv_iceheat = 0._wp
+      !
+   END SUBROUTINE ice_drift_init
       
 #else
Index: NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icedia.F90
===================================================================
--- NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icedia.F90	(revision 13033)
+++ NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icedia.F90	(revision 13727)
@@ -230,8 +230,8 @@
             CALL iom_get( numrir, 'frc_temtop' , frc_temtop, ldxios = lrixios  )
             CALL iom_get( numrir, 'frc_tembot' , frc_tembot, ldxios = lrixios  )
-            CALL iom_get( numrir, 'frc_sal'    , frc_sal, ldxios = lrixios     )
-            CALL iom_get( numrir, jpdom_autoglo, 'vol_loc_ini', vol_loc_ini, ldxios = lrixios )
-            CALL iom_get( numrir, jpdom_autoglo, 'tem_loc_ini', tem_loc_ini, ldxios = lrixios )
-            CALL iom_get( numrir, jpdom_autoglo, 'sal_loc_ini', sal_loc_ini, ldxios = lrixios )
+            CALL iom_get( numrir, 'frc_sal'    , frc_sal,    ldxios = lrixios  )
+            CALL iom_get( numrir, jpdom_auto, 'vol_loc_ini', vol_loc_ini, ldxios = lrixios )
+            CALL iom_get( numrir, jpdom_auto, 'tem_loc_ini', tem_loc_ini, ldxios = lrixios )
+            CALL iom_get( numrir, jpdom_auto, 'sal_loc_ini', sal_loc_ini, ldxios = lrixios )
             IF(lrixios) CALL iom_swap(cxios_context)
          ELSE
Index: NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icedyn.F90
===================================================================
--- NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icedyn.F90	(revision 13033)
+++ NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icedyn.F90	(revision 13727)
@@ -100,6 +100,8 @@
       WHERE( a_ip(:,:,:) >= epsi20 )
          h_ip(:,:,:) = v_ip(:,:,:) / a_ip(:,:,:)
+         h_il(:,:,:) = v_il(:,:,:) / a_ip(:,:,:)
       ELSEWHERE
          h_ip(:,:,:) = 0._wp
+         h_il(:,:,:) = 0._wp
       END WHERE
       !
@@ -126,9 +128,9 @@
          ! CFL = 0.5 at a distance from the bound of 1/6 of the basin length
          ! Then for dx = 2m and dt = 1s => rn_uice = u (1/6th) = 1m/s 
-         DO_2D_11_11
-            zcoefu = ( REAL(jpiglo+1)*0.5 - REAL(ji+nimpp-1) ) / ( REAL(jpiglo+1)*0.5 - 1. )
-            zcoefv = ( REAL(jpjglo+1)*0.5 - REAL(jj+njmpp-1) ) / ( REAL(jpjglo+1)*0.5 - 1. )
-            u_ice(ji,jj) = rn_uice * 1.5 * SIGN( 1., zcoefu ) * ABS( zcoefu ) * umask(ji,jj,1)
-            v_ice(ji,jj) = rn_vice * 1.5 * SIGN( 1., zcoefv ) * ABS( zcoefv ) * vmask(ji,jj,1)
+         DO_2D( 1, 1, 1, 1 )
+            zcoefu = ( REAL(jpiglo+1)*0.5_wp - REAL(ji+nimpp-1) ) / ( REAL(jpiglo+1)*0.5_wp - 1._wp )
+            zcoefv = ( REAL(jpjglo+1)*0.5_wp - REAL(jj+njmpp-1) ) / ( REAL(jpjglo+1)*0.5_wp - 1._wp )
+            u_ice(ji,jj) = rn_uice * 1.5_wp * SIGN( 1.0_wp, zcoefu ) * ABS( zcoefu ) * umask(ji,jj,1)
+            v_ice(ji,jj) = rn_vice * 1.5_wp * SIGN( 1.0_wp, zcoefv ) * ABS( zcoefv ) * vmask(ji,jj,1)
          END_2D
          ! ---
@@ -155,9 +157,9 @@
 
             ALLOCATE( zdivu_i(jpi,jpj) )
-            DO_2D_00_00
+            DO_2D( 0, 0, 0, 0 )
                zdivu_i(ji,jj) = ( e2u(ji,jj) * u_ice(ji,jj) - e2u(ji-1,jj) * u_ice(ji-1,jj)   &
                   &             + e1v(ji,jj) * v_ice(ji,jj) - e1v(ji,jj-1) * v_ice(ji,jj-1) ) * r1_e1e2t(ji,jj)
             END_2D
-            CALL lbc_lnk( 'icedyn', zdivu_i, 'T', 1. )
+            CALL lbc_lnk( 'icedyn', zdivu_i, 'T', 1.0_wp )
             ! output
             CALL iom_put( 'icediv' , zdivu_i )
@@ -218,5 +220,5 @@
       NAMELIST/namdyn/ ln_dynALL, ln_dynRHGADV, ln_dynADV1D, ln_dynADV2D, rn_uice, rn_vice,  &
          &             rn_ishlat ,                                                           &
-         &             ln_landfast_L16, rn_depfra, rn_icebfr, rn_lfrelax, rn_tensile
+         &             ln_landfast_L16, rn_lf_depfra, rn_lf_bfr, rn_lf_relax, rn_lf_tensile
       !!-------------------------------------------------------------------
       !
@@ -239,8 +241,8 @@
          WRITE(numout,*) '      lateral boundary condition for sea ice dynamics        rn_ishlat       = ', rn_ishlat
          WRITE(numout,*) '      Landfast: param from Lemieux 2016                      ln_landfast_L16 = ', ln_landfast_L16
-         WRITE(numout,*) '         fraction of ocean depth that ice must reach         rn_depfra       = ', rn_depfra
-         WRITE(numout,*) '         maximum bottom stress per unit area of contact      rn_icebfr       = ', rn_icebfr
-         WRITE(numout,*) '         relax time scale (s-1) to reach static friction     rn_lfrelax      = ', rn_lfrelax
-         WRITE(numout,*) '         isotropic tensile strength                          rn_tensile      = ', rn_tensile
+         WRITE(numout,*) '         fraction of ocean depth that ice must reach         rn_lf_depfra    = ', rn_lf_depfra
+         WRITE(numout,*) '         maximum bottom stress per unit area of contact      rn_lf_bfr       = ', rn_lf_bfr
+         WRITE(numout,*) '         relax time scale (s-1) to reach static friction     rn_lf_relax     = ', rn_lf_relax
+         WRITE(numout,*) '         isotropic tensile strength                          rn_lf_tensile   = ', rn_lf_tensile
          WRITE(numout,*)
       ENDIF
Index: NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icedyn_adv.F90
===================================================================
--- NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icedyn_adv.F90	(revision 13033)
+++ NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icedyn_adv.F90	(revision 13727)
@@ -82,10 +82,10 @@
          !                             !-----------------------!
          CALL ice_dyn_adv_umx( nn_UMx, kt, u_ice, v_ice, h_i, h_s, h_ip, &
-            &                          ato_i, v_i, v_s, sv_i, oa_i, a_i, a_ip, v_ip, e_s, e_i )
+            &                          ato_i, v_i, v_s, sv_i, oa_i, a_i, a_ip, v_ip, v_il, e_s, e_i )
          !                             !-----------------------!
       CASE( np_advPRA )                ! PRATHER scheme        !
          !                             !-----------------------!
          CALL ice_dyn_adv_pra(         kt, u_ice, v_ice, h_i, h_s, h_ip, &
-            &                          ato_i, v_i, v_s, sv_i, oa_i, a_i, a_ip, v_ip, e_s, e_i )
+            &                          ato_i, v_i, v_s, sv_i, oa_i, a_i, a_ip, v_ip, v_il, e_s, e_i )
       END SELECT
 
Index: NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icedyn_adv_pra.F90
===================================================================
--- NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icedyn_adv_pra.F90	(revision 13033)
+++ NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icedyn_adv_pra.F90	(revision 13727)
@@ -44,4 +44,5 @@
    REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:)   ::   sxap , syap , sxxap , syyap , sxyap    ! melt pond fraction
    REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:)   ::   sxvp , syvp , sxxvp , syyvp , sxyvp    ! melt pond volume
+   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:)   ::   sxvl , syvl , sxxvl , syyvl , sxyvl    ! melt pond lid volume
 
    !! * Substitutions
@@ -55,5 +56,5 @@
 
    SUBROUTINE ice_dyn_adv_pra(         kt, pu_ice, pv_ice, ph_i, ph_s, ph_ip,  &
-      &                        pato_i, pv_i, pv_s, psv_i, poa_i, pa_i, pa_ip, pv_ip, pe_s, pe_i )
+      &                        pato_i, pv_i, pv_s, psv_i, poa_i, pa_i, pa_ip, pv_ip, pv_il, pe_s, pe_i )
       !!----------------------------------------------------------------------
       !!                **  routine ice_dyn_adv_pra  **
@@ -81,41 +82,55 @@
       REAL(wp), DIMENSION(:,:,:)  , INTENT(inout) ::   pa_ip      ! melt pond fraction
       REAL(wp), DIMENSION(:,:,:)  , INTENT(inout) ::   pv_ip      ! melt pond volume
+      REAL(wp), DIMENSION(:,:,:)  , INTENT(inout) ::   pv_il      ! melt pond lid thickness
       REAL(wp), DIMENSION(:,:,:,:), INTENT(inout) ::   pe_s       ! snw heat content
       REAL(wp), DIMENSION(:,:,:,:), INTENT(inout) ::   pe_i       ! ice heat content
       !
-      INTEGER  ::   ji,jj, jk, jl, jt       ! dummy loop indices
+      INTEGER  ::   ji, jj, jk, jl, jt      ! dummy loop indices
       INTEGER  ::   icycle                  ! number of sub-timestep for the advection
-      REAL(wp) ::   zdt                     !   -      -
+      REAL(wp) ::   zdt, z1_dt              !   -      -
       REAL(wp), DIMENSION(1)                  ::   zcflprv, zcflnow   ! for global communication
       REAL(wp), DIMENSION(jpi,jpj)            ::   zati1, zati2
       REAL(wp), DIMENSION(jpi,jpj)            ::   zudy, zvdx
-      REAL(wp), DIMENSION(jpi,jpj,jpl)        ::   zhi_max, zhs_max, zhip_max
+      REAL(wp), DIMENSION(jpi,jpj,jpl)        ::   zhi_max, zhs_max, zhip_max, zs_i, zsi_max
+      REAL(wp), DIMENSION(jpi,jpj,nlay_i,jpl) ::   ze_i, zei_max
+      REAL(wp), DIMENSION(jpi,jpj,nlay_s,jpl) ::   ze_s, zes_max
       REAL(wp), DIMENSION(jpi,jpj,jpl)        ::   zarea
       REAL(wp), DIMENSION(jpi,jpj,jpl)        ::   z0ice, z0snw, z0ai, z0smi, z0oi
-      REAL(wp), DIMENSION(jpi,jpj,jpl)        ::   z0ap , z0vp
+      REAL(wp), DIMENSION(jpi,jpj,jpl)        ::   z0ap , z0vp, z0vl
       REAL(wp), DIMENSION(jpi,jpj,nlay_s,jpl) ::   z0es
       REAL(wp), DIMENSION(jpi,jpj,nlay_i,jpl) ::   z0ei
+      !! diagnostics
+      REAL(wp), DIMENSION(jpi,jpj)            ::   zdiag_adv_mass, zdiag_adv_salt, zdiag_adv_heat      
       !!----------------------------------------------------------------------
       !
       IF( kt == nit000 .AND. lwp )   WRITE(numout,*) '-- ice_dyn_adv_pra: Prather advection scheme'
       !
-      ! --- Record max of the surrounding 9-pts ice thick. (for call Hbig) --- !
-      DO jl = 1, jpl
-         DO_2D_00_00
-            zhip_max(ji,jj,jl) = MAX( epsi20, ph_ip(ji,jj,jl), ph_ip(ji+1,jj  ,jl), ph_ip(ji  ,jj+1,jl), &
-               &                                               ph_ip(ji-1,jj  ,jl), ph_ip(ji  ,jj-1,jl), &
-               &                                               ph_ip(ji+1,jj+1,jl), ph_ip(ji-1,jj-1,jl), &
-               &                                               ph_ip(ji+1,jj-1,jl), ph_ip(ji-1,jj+1,jl) )
-            zhi_max (ji,jj,jl) = MAX( epsi20, ph_i (ji,jj,jl), ph_i (ji+1,jj  ,jl), ph_i (ji  ,jj+1,jl), &
-               &                                               ph_i (ji-1,jj  ,jl), ph_i (ji  ,jj-1,jl), &
-               &                                               ph_i (ji+1,jj+1,jl), ph_i (ji-1,jj-1,jl), &
-               &                                               ph_i (ji+1,jj-1,jl), ph_i (ji-1,jj+1,jl) )
-            zhs_max (ji,jj,jl) = MAX( epsi20, ph_s (ji,jj,jl), ph_s (ji+1,jj  ,jl), ph_s (ji  ,jj+1,jl), &
-               &                                               ph_s (ji-1,jj  ,jl), ph_s (ji  ,jj-1,jl), &
-               &                                               ph_s (ji+1,jj+1,jl), ph_s (ji-1,jj-1,jl), &
-               &                                               ph_s (ji+1,jj-1,jl), ph_s (ji-1,jj+1,jl) )
-         END_2D
+      ! --- Record max of the surrounding 9-pts (for call Hbig) --- !
+      ! thickness and salinity
+      WHERE( pv_i(:,:,:) >= epsi10 ) ; zs_i(:,:,:) = psv_i(:,:,:) / pv_i(:,:,:)
+      ELSEWHERE                      ; zs_i(:,:,:) = 0._wp
+      END WHERE
+      CALL icemax3D( ph_i , zhi_max )
+      CALL icemax3D( ph_s , zhs_max )
+      CALL icemax3D( ph_ip, zhip_max)
+      CALL icemax3D( zs_i , zsi_max )
+      CALL lbc_lnk_multi( 'icedyn_adv_pra', zhi_max, 'T', 1._wp, zhs_max, 'T', 1._wp, zhip_max, 'T', 1._wp, zsi_max, 'T', 1._wp )
+      !
+      ! enthalpies
+      DO jk = 1, nlay_i
+         WHERE( pv_i(:,:,:) >= epsi10 ) ; ze_i(:,:,jk,:) = pe_i(:,:,jk,:) / pv_i(:,:,:)
+         ELSEWHERE                      ; ze_i(:,:,jk,:) = 0._wp
+         END WHERE
       END DO
-      CALL lbc_lnk_multi( 'icedyn_adv_pra', zhi_max, 'T', 1., zhs_max, 'T', 1., zhip_max, 'T', 1. )
+      DO jk = 1, nlay_s
+         WHERE( pv_s(:,:,:) >= epsi10 ) ; ze_s(:,:,jk,:) = pe_s(:,:,jk,:) / pv_s(:,:,:)
+         ELSEWHERE                      ; ze_s(:,:,jk,:) = 0._wp
+         END WHERE
+      END DO   
+      CALL icemax4D( ze_i , zei_max )
+      CALL icemax4D( ze_s , zes_max )
+      CALL lbc_lnk( 'icedyn_adv_pra', zei_max, 'T', 1._wp )
+      CALL lbc_lnk( 'icedyn_adv_pra', zes_max, 'T', 1._wp )
+      !
       !
       ! --- If ice drift is too fast, use  subtime steps for advection (CFL test for stability) --- !
@@ -132,4 +147,5 @@
       ENDIF
       zdt = rDt_ice / REAL(icycle)
+      z1_dt = 1._wp / zdt
       
       ! --- transport --- !
@@ -138,4 +154,10 @@
 
       DO jt = 1, icycle
+
+         ! diagnostics
+         zdiag_adv_mass(:,:) =   SUM(  pv_i(:,:,:) , dim=3 ) * rhoi + SUM(  pv_s(:,:,:) , dim=3 ) * rhos
+         zdiag_adv_salt(:,:) =   SUM( psv_i(:,:,:) , dim=3 ) * rhoi
+         zdiag_adv_heat(:,:) = - SUM(SUM( pe_i(:,:,1:nlay_i,:) , dim=4 ), dim=3 ) &
+            &                  - SUM(SUM( pe_s(:,:,1:nlay_s,:) , dim=4 ), dim=3 )
 
          ! record at_i before advection (for open water)
@@ -156,7 +178,10 @@
                z0ei(:,:,jk,jl) = pe_i(:,:,jk,jl) * e1e2t(:,:) ! Ice  heat content
             END DO
-            IF ( ln_pnd_H12 ) THEN
-               z0ap(:,:,jl)  = pa_ip(:,:,jl) * e1e2t(:,:)     ! Melt pond fraction
-               z0vp(:,:,jl)  = pv_ip(:,:,jl) * e1e2t(:,:)     ! Melt pond volume
+            IF ( ln_pnd_LEV ) THEN
+               z0ap(:,:,jl) = pa_ip(:,:,jl) * e1e2t(:,:)      ! Melt pond fraction
+               z0vp(:,:,jl) = pv_ip(:,:,jl) * e1e2t(:,:)      ! Melt pond volume
+               IF ( ln_pnd_lids ) THEN
+                  z0vl(:,:,jl) = pv_il(:,:,jl) * e1e2t(:,:)   ! Melt pond lid volume
+               ENDIF
             ENDIF
          END DO
@@ -189,9 +214,13 @@
             END DO
             !
-            IF ( ln_pnd_H12 ) THEN
+            IF ( ln_pnd_LEV ) THEN
                CALL adv_x( zdt , zudy , 1._wp , zarea , z0ap , sxap , sxxap , syap , syyap , sxyap )    !--- melt pond fraction
                CALL adv_y( zdt , zvdx , 0._wp , zarea , z0ap , sxap , sxxap , syap , syyap , sxyap ) 
                CALL adv_x( zdt , zudy , 1._wp , zarea , z0vp , sxvp , sxxvp , syvp , syyvp , sxyvp )    !--- melt pond volume
                CALL adv_y( zdt , zvdx , 0._wp , zarea , z0vp , sxvp , sxxvp , syvp , syyvp , sxyvp ) 
+               IF ( ln_pnd_lids ) THEN
+                  CALL adv_x( zdt , zudy , 1._wp , zarea , z0vl , sxvl , sxxvl , syvl , syyvl , sxyvl ) !--- melt pond lid volume
+                  CALL adv_y( zdt , zvdx , 0._wp , zarea , z0vl , sxvl , sxxvl , syvl , syyvl , sxyvl ) 
+               ENDIF
             ENDIF
             !                                                               !--------------------------------------------!
@@ -220,11 +249,42 @@
                   &                                 sxxe(:,:,jk,:), sye(:,:,jk,:), syye(:,:,jk,:), sxye(:,:,jk,:) )
             END DO
-            IF ( ln_pnd_H12 ) THEN
+            IF ( ln_pnd_LEV ) THEN
                CALL adv_y( zdt , zvdx , 1._wp , zarea , z0ap , sxap , sxxap , syap , syyap , sxyap )    !--- melt pond fraction
                CALL adv_x( zdt , zudy , 0._wp , zarea , z0ap , sxap , sxxap , syap , syyap , sxyap )
                CALL adv_y( zdt , zvdx , 1._wp , zarea , z0vp , sxvp , sxxvp , syvp , syyvp , sxyvp )    !--- melt pond volume
                CALL adv_x( zdt , zudy , 0._wp , zarea , z0vp , sxvp , sxxvp , syvp , syyvp , sxyvp )
+               IF ( ln_pnd_lids ) THEN
+                  CALL adv_y( zdt , zvdx , 1._wp , zarea , z0vl , sxvl , sxxvl , syvl , syyvl , sxyvl ) !--- melt pond lid volume
+                  CALL adv_x( zdt , zudy , 0._wp , zarea , z0vl , sxvl , sxxvl , syvl , syyvl , sxyvl ) 
+               ENDIF
             ENDIF
             !
+         ENDIF
+         
+         ! --- Lateral boundary conditions --- !
+         !     caution: for gradients (sx and sy) the sign changes
+         CALL lbc_lnk_multi( 'icedyn_adv_pra', z0ice , 'T', 1._wp, sxice , 'T', -1._wp, syice , 'T', -1._wp  & ! ice volume
+            &                                , sxxice, 'T', 1._wp, syyice, 'T',  1._wp, sxyice, 'T',  1._wp  &
+            &                                , z0snw , 'T', 1._wp, sxsn  , 'T', -1._wp, sysn  , 'T', -1._wp  & ! snw volume
+            &                                , sxxsn , 'T', 1._wp, syysn , 'T',  1._wp, sxysn , 'T',  1._wp  )
+         CALL lbc_lnk_multi( 'icedyn_adv_pra', z0smi , 'T', 1._wp, sxsal , 'T', -1._wp, sysal , 'T', -1._wp  & ! ice salinity
+            &                                , sxxsal, 'T', 1._wp, syysal, 'T',  1._wp, sxysal, 'T',  1._wp  &
+            &                                , z0ai  , 'T', 1._wp, sxa   , 'T', -1._wp, sya   , 'T', -1._wp  & ! ice concentration
+            &                                , sxxa  , 'T', 1._wp, syya  , 'T',  1._wp, sxya  , 'T',  1._wp  )
+         CALL lbc_lnk_multi( 'icedyn_adv_pra', z0oi  , 'T', 1._wp, sxage , 'T', -1._wp, syage , 'T', -1._wp  & ! ice age
+            &                                , sxxage, 'T', 1._wp, syyage, 'T',  1._wp, sxyage, 'T',  1._wp  )
+         CALL lbc_lnk_multi( 'icedyn_adv_pra', z0es  , 'T', 1._wp, sxc0  , 'T', -1._wp, syc0  , 'T', -1._wp  & ! snw enthalpy
+            &                                , sxxc0 , 'T', 1._wp, syyc0 , 'T',  1._wp, sxyc0 , 'T',  1._wp  ) 
+         CALL lbc_lnk_multi( 'icedyn_adv_pra', z0ei  , 'T', 1._wp, sxe   , 'T', -1._wp, sye   , 'T', -1._wp  & ! ice enthalpy
+            &                                , sxxe  , 'T', 1._wp, syye  , 'T',  1._wp, sxye  , 'T',  1._wp  )
+         IF ( ln_pnd_LEV ) THEN
+            CALL lbc_lnk_multi( 'icedyn_adv_pra', z0ap , 'T', 1._wp, sxap , 'T', -1._wp, syap , 'T', -1._wp  & ! melt pond fraction
+               &                                , sxxap, 'T', 1._wp, syyap, 'T',  1._wp, sxyap, 'T',  1._wp  &
+               &                                , z0vp , 'T', 1._wp, sxvp , 'T', -1._wp, syvp , 'T', -1._wp  & ! melt pond volume
+               &                                , sxxvp, 'T', 1._wp, syyvp, 'T',  1._wp, sxyvp, 'T',  1._wp  ) 
+            IF ( ln_pnd_lids ) THEN
+               CALL lbc_lnk_multi( 'icedyn_adv_pra', z0vl ,'T', 1._wp, sxvl ,'T', -1._wp, syvl ,'T', -1._wp  & ! melt pond lid volume
+                  &                                , sxxvl,'T', 1._wp, syyvl,'T',  1._wp, sxyvl,'T',  1._wp  ) 
+            ENDIF
          ENDIF
 
@@ -242,7 +302,10 @@
                pe_i(:,:,jk,jl) = z0ei(:,:,jk,jl) * r1_e1e2t(:,:) * tmask(:,:,1)
             END DO
-            IF ( ln_pnd_H12 ) THEN
+            IF ( ln_pnd_LEV ) THEN
                pa_ip(:,:,jl) = z0ap(:,:,jl) * r1_e1e2t(:,:) * tmask(:,:,1)
                pv_ip(:,:,jl) = z0vp(:,:,jl) * r1_e1e2t(:,:) * tmask(:,:,1)
+               IF ( ln_pnd_lids ) THEN
+                  pv_il(:,:,jl) = z0vl(:,:,jl) * r1_e1e2t(:,:) * tmask(:,:,1)
+               ENDIF
             ENDIF
          END DO
@@ -250,18 +313,28 @@
          ! derive open water from ice concentration
          zati2(:,:) = SUM( pa_i(:,:,:), dim=3 )
-         DO_2D_00_00
+         DO_2D( 0, 0, 0, 0 )
             pato_i(ji,jj) = pato_i(ji,jj) - ( zati2(ji,jj) - zati1(ji,jj) ) &                        !--- open water
                &                          - ( zudy(ji,jj) - zudy(ji-1,jj) + zvdx(ji,jj) - zvdx(ji,jj-1) ) * r1_e1e2t(ji,jj) * zdt
          END_2D
-         CALL lbc_lnk( 'icedyn_adv_pra', pato_i, 'T',  1. )
+         CALL lbc_lnk( 'icedyn_adv_pra', pato_i, 'T',  1.0_wp )
+         !
+         ! --- diagnostics --- !
+         diag_adv_mass(:,:) = diag_adv_mass(:,:) + (   SUM( pv_i(:,:,:) , dim=3 ) * rhoi + SUM( pv_s(:,:,:) , dim=3 ) * rhos &
+            &                                        - zdiag_adv_mass(:,:) ) * z1_dt
+         diag_adv_salt(:,:) = diag_adv_salt(:,:) + (   SUM( psv_i(:,:,:) , dim=3 ) * rhoi &
+            &                                        - zdiag_adv_salt(:,:) ) * z1_dt
+         diag_adv_heat(:,:) = diag_adv_heat(:,:) + ( - SUM(SUM( pe_i(:,:,1:nlay_i,:) , dim=4 ), dim=3 ) &
+            &                                        - SUM(SUM( pe_s(:,:,1:nlay_s,:) , dim=4 ), dim=3 ) &
+            &                                        - zdiag_adv_heat(:,:) ) * z1_dt
          !
          ! --- Ensure non-negative fields --- !
          !     Remove negative values (conservation is ensured)
          !     (because advected fields are not perfectly bounded and tiny negative values can occur, e.g. -1.e-20)
-         CALL ice_var_zapneg( zdt, pato_i, pv_i, pv_s, psv_i, poa_i, pa_i, pa_ip, pv_ip, pe_s, pe_i )
+         CALL ice_var_zapneg( zdt, pato_i, pv_i, pv_s, psv_i, poa_i, pa_i, pa_ip, pv_ip, pv_il, pe_s, pe_i )
          !
          ! --- Make sure ice thickness is not too big --- !
          !     (because ice thickness can be too large where ice concentration is very small)
-         CALL Hbig( zdt, zhi_max, zhs_max, zhip_max, pv_i, pv_s, pa_i, pa_ip, pv_ip, pe_s )
+         CALL Hbig( zdt, zhi_max, zhs_max, zhip_max, zsi_max, zes_max, zei_max, &
+            &            pv_i, pv_s, pa_i, pa_ip, pv_ip, psv_i, pe_s, pe_i )
          !
          ! --- Ensure snow load is not too big --- !
@@ -292,11 +365,18 @@
       !! 
       INTEGER  ::   ji, jj, jl, jcat                     ! dummy loop indices
+      INTEGER  ::   jj0                                  ! dummy loop indices
       REAL(wp) ::   zs1max, zslpmax, ztemp               ! local scalars
       REAL(wp) ::   zs1new, zalf , zalfq , zbt           !   -      -
       REAL(wp) ::   zs2new, zalf1, zalf1q, zbt1          !   -      -
+      REAL(wp) ::   zpsm, zps0
+      REAL(wp) ::   zpsx, zpsy, zpsxx, zpsyy, zpsxy
       REAL(wp), DIMENSION(jpi,jpj) ::   zf0 , zfx  , zfy   , zbet   ! 2D workspace
       REAL(wp), DIMENSION(jpi,jpj) ::   zfm , zfxx , zfyy  , zfxy   !  -      -
       REAL(wp), DIMENSION(jpi,jpj) ::   zalg, zalg1, zalg1q         !  -      -
       !-----------------------------------------------------------------------
+      ! in order to avoid lbc_lnk (communications):
+      !    jj loop must be 1:jpj   if adv_x is called first
+      !                and 2:jpj-1 if adv_x is called second
+      jj0 = NINT(pcrh)
       !
       jcat = SIZE( ps0 , 3 )   ! size of input arrays
@@ -305,128 +385,159 @@
          !
          ! Limitation of moments.                                           
-         DO_2D_00_11
-            !  Initialize volumes of boxes  (=area if adv_x first called, =psm otherwise)                                     
-            psm (ji,jj,jl) = MAX( pcrh * e1e2t(ji,jj) + ( 1.0 - pcrh ) * psm(ji,jj,jl) , epsi20 )
-            !
-            zslpmax = MAX( 0._wp, ps0(ji,jj,jl) )
-            zs1max  = 1.5 * zslpmax
-            zs1new  = MIN( zs1max, MAX( -zs1max, psx(ji,jj,jl) ) )
-            zs2new  = MIN(  2.0 * zslpmax - 0.3334 * ABS( zs1new ),      &
-               &            MAX( ABS( zs1new ) - zslpmax, psxx(ji,jj,jl) )  )
-            rswitch = ( 1.0 - MAX( 0._wp, SIGN( 1._wp, -zslpmax) ) ) * tmask(ji,jj,1)   ! Case of empty boxes & Apply mask
-
-            ps0 (ji,jj,jl) = zslpmax  
-            psx (ji,jj,jl) = zs1new         * rswitch
-            psxx(ji,jj,jl) = zs2new         * rswitch
-            psy (ji,jj,jl) = psy (ji,jj,jl) * rswitch
-            psyy(ji,jj,jl) = psyy(ji,jj,jl) * rswitch
-            psxy(ji,jj,jl) = MIN( zslpmax, MAX( -zslpmax, psxy(ji,jj,jl) ) ) * rswitch
-         END_2D
-
-         !  Calculate fluxes and moments between boxes i<-->i+1              
-         DO_2D_00_11
-            zbet(ji,jj)  =  MAX( 0._wp, SIGN( 1._wp, put(ji,jj) ) )
-            zalf         =  MAX( 0._wp, put(ji,jj) ) * pdt / psm(ji,jj,jl)
-            zalfq        =  zalf * zalf
-            zalf1        =  1.0 - zalf
-            zalf1q       =  zalf1 * zalf1
-            !
-            zfm (ji,jj)  =  zalf  *   psm (ji,jj,jl)
-            zf0 (ji,jj)  =  zalf  * ( ps0 (ji,jj,jl) + zalf1 * ( psx(ji,jj,jl) + (zalf1 - zalf) * psxx(ji,jj,jl) ) )
-            zfx (ji,jj)  =  zalfq * ( psx (ji,jj,jl) + 3.0 * zalf1 * psxx(ji,jj,jl) )
-            zfxx(ji,jj)  =  zalf  *   psxx(ji,jj,jl) * zalfq
-            zfy (ji,jj)  =  zalf  * ( psy (ji,jj,jl) + zalf1 * psxy(ji,jj,jl) )
-            zfxy(ji,jj)  =  zalfq *   psxy(ji,jj,jl)
-            zfyy(ji,jj)  =  zalf  *   psyy(ji,jj,jl)
-
-            !  Readjust moments remaining in the box.
-            psm (ji,jj,jl)  =  psm (ji,jj,jl) - zfm(ji,jj)
-            ps0 (ji,jj,jl)  =  ps0 (ji,jj,jl) - zf0(ji,jj)
-            psx (ji,jj,jl)  =  zalf1q * ( psx(ji,jj,jl) - 3.0 * zalf * psxx(ji,jj,jl) )
-            psxx(ji,jj,jl)  =  zalf1  * zalf1q * psxx(ji,jj,jl)
-            psy (ji,jj,jl)  =  psy (ji,jj,jl) - zfy(ji,jj)
-            psyy(ji,jj,jl)  =  psyy(ji,jj,jl) - zfyy(ji,jj)
-            psxy(ji,jj,jl)  =  zalf1q * psxy(ji,jj,jl)
-         END_2D
-
-         DO_2D_00_10
-            zalf          = MAX( 0._wp, -put(ji,jj) ) * pdt / psm(ji+1,jj,jl) 
-            zalg  (ji,jj) = zalf
-            zalfq         = zalf * zalf
-            zalf1         = 1.0 - zalf
-            zalg1 (ji,jj) = zalf1
-            zalf1q        = zalf1 * zalf1
-            zalg1q(ji,jj) = zalf1q
-            !
-            zfm   (ji,jj) = zfm (ji,jj) + zalf  *    psm (ji+1,jj,jl)
-            zf0   (ji,jj) = zf0 (ji,jj) + zalf  * (  ps0 (ji+1,jj,jl) &
-               &                                   - zalf1 * ( psx(ji+1,jj,jl) - (zalf1 - zalf ) * psxx(ji+1,jj,jl) ) )
-            zfx   (ji,jj) = zfx (ji,jj) + zalfq * (  psx (ji+1,jj,jl) - 3.0 * zalf1 * psxx(ji+1,jj,jl) )
-            zfxx  (ji,jj) = zfxx(ji,jj) + zalf  *    psxx(ji+1,jj,jl) * zalfq
-            zfy   (ji,jj) = zfy (ji,jj) + zalf  * (  psy (ji+1,jj,jl) - zalf1 * psxy(ji+1,jj,jl) )
-            zfxy  (ji,jj) = zfxy(ji,jj) + zalfq *    psxy(ji+1,jj,jl)
-            zfyy  (ji,jj) = zfyy(ji,jj) + zalf  *    psyy(ji+1,jj,jl)
-         END_2D
-
-         DO_2D_00_00
-            zbt  =       zbet(ji-1,jj)
-            zbt1 = 1.0 - zbet(ji-1,jj)
-            !
-            psm (ji,jj,jl) = zbt * psm(ji,jj,jl) + zbt1 * ( psm(ji,jj,jl) - zfm(ji-1,jj) )
-            ps0 (ji,jj,jl) = zbt * ps0(ji,jj,jl) + zbt1 * ( ps0(ji,jj,jl) - zf0(ji-1,jj) )
-            psx (ji,jj,jl) = zalg1q(ji-1,jj) * ( psx(ji,jj,jl) + 3.0 * zalg(ji-1,jj) * psxx(ji,jj,jl) )
-            psxx(ji,jj,jl) = zalg1 (ji-1,jj) * zalg1q(ji-1,jj) * psxx(ji,jj,jl)
-            psy (ji,jj,jl) = zbt * psy (ji,jj,jl) + zbt1 * ( psy (ji,jj,jl) - zfy (ji-1,jj) )
-            psyy(ji,jj,jl) = zbt * psyy(ji,jj,jl) + zbt1 * ( psyy(ji,jj,jl) - zfyy(ji-1,jj) )
-            psxy(ji,jj,jl) = zalg1q(ji-1,jj) * psxy(ji,jj,jl)
-         END_2D
-
-         !   Put the temporary moments into appropriate neighboring boxes.    
-         DO_2D_00_00
-            zbt  =       zbet(ji-1,jj)
-            zbt1 = 1.0 - zbet(ji-1,jj)
-            psm(ji,jj,jl) = zbt * ( psm(ji,jj,jl) + zfm(ji-1,jj) ) + zbt1 * psm(ji,jj,jl)
-            zalf          = zbt * zfm(ji-1,jj) / psm(ji,jj,jl)
-            zalf1         = 1.0 - zalf
-            ztemp         = zalf * ps0(ji,jj,jl) - zalf1 * zf0(ji-1,jj)
-            !
-            ps0 (ji,jj,jl) =  zbt  * ( ps0(ji,jj,jl) + zf0(ji-1,jj) ) + zbt1 * ps0(ji,jj,jl)
-            psx (ji,jj,jl) =  zbt  * ( zalf * zfx(ji-1,jj) + zalf1 * psx(ji,jj,jl) + 3.0 * ztemp ) + zbt1 * psx(ji,jj,jl)
-            psxx(ji,jj,jl) =  zbt  * ( zalf * zalf * zfxx(ji-1,jj) + zalf1 * zalf1 * psxx(ji,jj,jl)                             &
-               &                     + 5.0 * ( zalf * zalf1 * ( psx (ji,jj,jl) - zfx(ji-1,jj) ) - ( zalf1 - zalf ) * ztemp )  ) &
-               &            + zbt1 * psxx(ji,jj,jl)
-            psxy(ji,jj,jl) =  zbt  * ( zalf * zfxy(ji-1,jj) + zalf1 * psxy(ji,jj,jl)             &
-               &                     + 3.0 * (- zalf1*zfy(ji-1,jj)  + zalf * psy(ji,jj,jl) ) )   &
-               &            + zbt1 * psxy(ji,jj,jl)
-            psy (ji,jj,jl) =  zbt  * ( psy (ji,jj,jl) + zfy (ji-1,jj) ) + zbt1 * psy (ji,jj,jl)
-            psyy(ji,jj,jl) =  zbt  * ( psyy(ji,jj,jl) + zfyy(ji-1,jj) ) + zbt1 * psyy(ji,jj,jl)
-         END_2D
-
-         DO_2D_00_00
-            zbt  =       zbet(ji,jj)
-            zbt1 = 1.0 - zbet(ji,jj)
-            psm(ji,jj,jl) = zbt * psm(ji,jj,jl) + zbt1 * ( psm(ji,jj,jl) + zfm(ji,jj) )
-            zalf          = zbt1 * zfm(ji,jj) / psm(ji,jj,jl)
-            zalf1         = 1.0 - zalf
-            ztemp         = - zalf * ps0(ji,jj,jl) + zalf1 * zf0(ji,jj)
-            !
-            ps0 (ji,jj,jl) = zbt * ps0 (ji,jj,jl) + zbt1 * ( ps0(ji,jj,jl) + zf0(ji,jj) )
-            psx (ji,jj,jl) = zbt * psx (ji,jj,jl) + zbt1 * ( zalf * zfx(ji,jj) + zalf1 * psx(ji,jj,jl) + 3.0 * ztemp )
-            psxx(ji,jj,jl) = zbt * psxx(ji,jj,jl) + zbt1 * ( zalf * zalf * zfxx(ji,jj) + zalf1 * zalf1 * psxx(ji,jj,jl) &
-               &                                           + 5.0 * ( zalf * zalf1 * ( - psx(ji,jj,jl) + zfx(ji,jj) )    &
-               &                                           + ( zalf1 - zalf ) * ztemp ) )
-            psxy(ji,jj,jl) = zbt * psxy(ji,jj,jl) + zbt1 * ( zalf * zfxy(ji,jj) + zalf1 * psxy(ji,jj,jl)  &
-               &                                           + 3.0 * ( zalf1 * zfy(ji,jj) - zalf * psy(ji,jj,jl) ) )
-            psy (ji,jj,jl) = zbt * psy (ji,jj,jl) + zbt1 * ( psy (ji,jj,jl) + zfy (ji,jj) )
-            psyy(ji,jj,jl) = zbt * psyy(ji,jj,jl) + zbt1 * ( psyy(ji,jj,jl) + zfyy(ji,jj) )
-         END_2D
-
+         DO jj = Njs0 - jj0, Nje0 + jj0
+            
+            DO ji = Nis0 - 1, Nie0 + 1
+
+               zpsm  = psm (ji,jj,jl) ! optimization
+               zps0  = ps0 (ji,jj,jl)
+               zpsx  = psx (ji,jj,jl)
+               zpsxx = psxx(ji,jj,jl)
+               zpsy  = psy (ji,jj,jl)
+               zpsyy = psyy(ji,jj,jl)
+               zpsxy = psxy(ji,jj,jl)
+
+               !  Initialize volumes of boxes  (=area if adv_x first called, =psm otherwise)                                     
+               zpsm = MAX( pcrh * e1e2t(ji,jj) + ( 1.0 - pcrh ) * zpsm , epsi20 )
+               !
+               zslpmax = MAX( 0._wp, zps0 )
+               zs1max  = 1.5 * zslpmax
+               zs1new  = MIN( zs1max, MAX( -zs1max, zpsx ) )
+               zs2new  = MIN( 2.0 * zslpmax - 0.3334 * ABS( zs1new ), MAX( ABS( zs1new ) - zslpmax, zpsxx ) )
+               rswitch = ( 1.0 - MAX( 0._wp, SIGN( 1._wp, -zslpmax) ) ) * tmask(ji,jj,1)   ! Case of empty boxes & Apply mask
+
+               zps0  = zslpmax  
+               zpsx  = zs1new  * rswitch
+               zpsxx = zs2new  * rswitch
+               zpsy  = zpsy    * rswitch
+               zpsyy = zpsyy   * rswitch
+               zpsxy = MIN( zslpmax, MAX( -zslpmax, zpsxy ) ) * rswitch
+
+               !  Calculate fluxes and moments between boxes i<-->i+1              
+               !                                !  Flux from i to i+1 WHEN u GT 0 
+               zbet(ji,jj)  =  MAX( 0._wp, SIGN( 1._wp, put(ji,jj) ) )
+               zalf         =  MAX( 0._wp, put(ji,jj) ) * pdt / zpsm
+               zalfq        =  zalf * zalf
+               zalf1        =  1.0 - zalf
+               zalf1q       =  zalf1 * zalf1
+               !
+               zfm (ji,jj)  =  zalf  *   zpsm 
+               zf0 (ji,jj)  =  zalf  * ( zps0  + zalf1 * ( zpsx + (zalf1 - zalf) * zpsxx ) )
+               zfx (ji,jj)  =  zalfq * ( zpsx  + 3.0 * zalf1 * zpsxx )
+               zfxx(ji,jj)  =  zalf  *   zpsxx * zalfq
+               zfy (ji,jj)  =  zalf  * ( zpsy  + zalf1 * zpsxy )
+               zfxy(ji,jj)  =  zalfq *   zpsxy
+               zfyy(ji,jj)  =  zalf  *   zpsyy
+
+               !                                !  Readjust moments remaining in the box.
+               zpsm  =  zpsm  - zfm(ji,jj)
+               zps0  =  zps0  - zf0(ji,jj)
+               zpsx  =  zalf1q * ( zpsx - 3.0 * zalf * zpsxx )
+               zpsxx =  zalf1  * zalf1q * zpsxx
+               zpsy  =  zpsy  - zfy (ji,jj)
+               zpsyy =  zpsyy - zfyy(ji,jj)
+               zpsxy =  zalf1q * zpsxy
+               !
+               psm (ji,jj,jl) = zpsm ! optimization
+               ps0 (ji,jj,jl) = zps0 
+               psx (ji,jj,jl) = zpsx 
+               psxx(ji,jj,jl) = zpsxx
+               psy (ji,jj,jl) = zpsy 
+               psyy(ji,jj,jl) = zpsyy
+               psxy(ji,jj,jl) = zpsxy
+               !
+            END DO
+            
+            DO ji = Nis0 - 1, Nie0
+               !                                !  Flux from i+1 to i when u LT 0.
+               zalf          = MAX( 0._wp, -put(ji,jj) ) * pdt / psm(ji+1,jj,jl) 
+               zalg  (ji,jj) = zalf
+               zalfq         = zalf * zalf
+               zalf1         = 1.0 - zalf
+               zalg1 (ji,jj) = zalf1
+               zalf1q        = zalf1 * zalf1
+               zalg1q(ji,jj) = zalf1q
+               !
+               zfm   (ji,jj) = zfm (ji,jj) + zalf  *    psm (ji+1,jj,jl)
+               zf0   (ji,jj) = zf0 (ji,jj) + zalf  * (  ps0 (ji+1,jj,jl) &
+                  &                                   - zalf1 * ( psx(ji+1,jj,jl) - (zalf1 - zalf ) * psxx(ji+1,jj,jl) ) )
+               zfx   (ji,jj) = zfx (ji,jj) + zalfq * (  psx (ji+1,jj,jl) - 3.0 * zalf1 * psxx(ji+1,jj,jl) )
+               zfxx  (ji,jj) = zfxx(ji,jj) + zalf  *    psxx(ji+1,jj,jl) * zalfq
+               zfy   (ji,jj) = zfy (ji,jj) + zalf  * (  psy (ji+1,jj,jl) - zalf1 * psxy(ji+1,jj,jl) )
+               zfxy  (ji,jj) = zfxy(ji,jj) + zalfq *    psxy(ji+1,jj,jl)
+               zfyy  (ji,jj) = zfyy(ji,jj) + zalf  *    psyy(ji+1,jj,jl)
+            END DO
+
+            DO ji = Nis0, Nie0
+               !
+               zpsm  = psm (ji,jj,jl) ! optimization
+               zps0  = ps0 (ji,jj,jl)
+               zpsx  = psx (ji,jj,jl)
+               zpsxx = psxx(ji,jj,jl)
+               zpsy  = psy (ji,jj,jl)
+               zpsyy = psyy(ji,jj,jl)
+               zpsxy = psxy(ji,jj,jl)
+               !                                !  Readjust moments remaining in the box.
+               zbt  =       zbet(ji-1,jj)
+               zbt1 = 1.0 - zbet(ji-1,jj)
+               !
+               zpsm  = zbt * zpsm + zbt1 * ( zpsm - zfm(ji-1,jj) )
+               zps0  = zbt * zps0 + zbt1 * ( zps0 - zf0(ji-1,jj) )
+               zpsx  = zalg1q(ji-1,jj) * ( zpsx + 3.0 * zalg(ji-1,jj) * zpsxx )
+               zpsxx = zalg1 (ji-1,jj) * zalg1q(ji-1,jj) * zpsxx
+               zpsy  = zbt * zpsy  + zbt1 * ( zpsy  - zfy (ji-1,jj) )
+               zpsyy = zbt * zpsyy + zbt1 * ( zpsyy - zfyy(ji-1,jj) )
+               zpsxy = zalg1q(ji-1,jj) * zpsxy
+
+               !   Put the temporary moments into appropriate neighboring boxes.    
+               !                                !   Flux from i to i+1 IF u GT 0.
+               zbt   =       zbet(ji-1,jj)
+               zbt1  = 1.0 - zbet(ji-1,jj)
+               zpsm  = zbt * ( zpsm + zfm(ji-1,jj) ) + zbt1 * zpsm
+               zalf  = zbt * zfm(ji-1,jj) / zpsm
+               zalf1 = 1.0 - zalf
+               ztemp = zalf * zps0 - zalf1 * zf0(ji-1,jj)
+               !
+               zps0  =  zbt  * ( zps0 + zf0(ji-1,jj) ) + zbt1 * zps0
+               zpsx  =  zbt  * ( zalf * zfx(ji-1,jj) + zalf1 * zpsx + 3.0 * ztemp ) + zbt1 * zpsx
+               zpsxx =  zbt  * ( zalf * zalf * zfxx(ji-1,jj) + zalf1 * zalf1 * zpsxx                            &
+                  &            + 5.0 * ( zalf * zalf1 * ( zpsx  - zfx(ji-1,jj) ) - ( zalf1 - zalf ) * ztemp ) ) &
+                  &            + zbt1 * zpsxx
+               zpsxy =  zbt  * ( zalf * zfxy(ji-1,jj) + zalf1 * zpsxy            &
+                  &            + 3.0 * (- zalf1*zfy(ji-1,jj)  + zalf * zpsy ) )  &
+                  &            + zbt1 * zpsxy
+               zpsy  =  zbt  * ( zpsy  + zfy (ji-1,jj) ) + zbt1 * zpsy 
+               zpsyy =  zbt  * ( zpsyy + zfyy(ji-1,jj) ) + zbt1 * zpsyy
+
+               !                                !  Flux from i+1 to i IF u LT 0.
+               zbt   =       zbet(ji,jj)
+               zbt1  = 1.0 - zbet(ji,jj)
+               zpsm  = zbt * zpsm + zbt1 * ( zpsm + zfm(ji,jj) )
+               zalf  = zbt1 * zfm(ji,jj) / zpsm
+               zalf1 = 1.0 - zalf
+               ztemp = - zalf * zps0 + zalf1 * zf0(ji,jj)
+               !
+               zps0  = zbt * zps0  + zbt1 * ( zps0 + zf0(ji,jj) )
+               zpsx  = zbt * zpsx  + zbt1 * ( zalf * zfx(ji,jj) + zalf1 * zpsx + 3.0 * ztemp )
+               zpsxx = zbt * zpsxx + zbt1 * ( zalf * zalf * zfxx(ji,jj) + zalf1 * zalf1 * zpsxx &
+                  &                         + 5.0 * ( zalf * zalf1 * ( - zpsx + zfx(ji,jj) )    &
+                  &                         + ( zalf1 - zalf ) * ztemp ) )
+               zpsxy = zbt * zpsxy + zbt1 * ( zalf * zfxy(ji,jj) + zalf1 * zpsxy  &
+                  &                         + 3.0 * ( zalf1 * zfy(ji,jj) - zalf * zpsy ) )
+               zpsy  = zbt * zpsy  + zbt1 * ( zpsy  + zfy (ji,jj) )
+               zpsyy = zbt * zpsyy + zbt1 * ( zpsyy + zfyy(ji,jj) )
+               !
+               psm (ji,jj,jl) = zpsm  ! optimization
+               ps0 (ji,jj,jl) = zps0 
+               psx (ji,jj,jl) = zpsx 
+               psxx(ji,jj,jl) = zpsxx
+               psy (ji,jj,jl) = zpsy 
+               psyy(ji,jj,jl) = zpsyy
+               psxy(ji,jj,jl) = zpsxy
+            END DO
+            !
+         END DO
+         !
       END DO
-
-      !-- Lateral boundary conditions
-      CALL lbc_lnk_multi( 'icedyn_adv_pra', psm(:,:,1:jcat) , 'T',  1., ps0 , 'T',  1.   &
-         &                                , psx             , 'T', -1., psy , 'T', -1.   &   ! caution gradient ==> the sign changes
-         &                                , psxx            , 'T',  1., psyy, 'T',  1. , psxy, 'T',  1. )
-      !
+      !      
    END SUBROUTINE adv_x
 
@@ -449,11 +560,18 @@
       !!
       INTEGER  ::   ji, jj, jl, jcat                     ! dummy loop indices
+      INTEGER  ::   ji0                                  ! dummy loop indices
       REAL(wp) ::   zs1max, zslpmax, ztemp               ! temporary scalars
       REAL(wp) ::   zs1new, zalf , zalfq , zbt           !    -         -
       REAL(wp) ::   zs2new, zalf1, zalf1q, zbt1          !    -         -
+      REAL(wp) ::   zpsm, zps0
+      REAL(wp) ::   zpsx, zpsy, zpsxx, zpsyy, zpsxy
       REAL(wp), DIMENSION(jpi,jpj) ::   zf0, zfx , zfy , zbet   ! 2D workspace
       REAL(wp), DIMENSION(jpi,jpj) ::   zfm, zfxx, zfyy, zfxy   !  -      -
       REAL(wp), DIMENSION(jpi,jpj) ::   zalg, zalg1, zalg1q     !  -      -
       !---------------------------------------------------------------------
+      ! in order to avoid lbc_lnk (communications):
+      !    ji loop must be 1:jpi   if adv_y is called first
+      !                and 2:jpi-1 if adv_y is called second
+      ji0 = NINT(pcrh)
       !
       jcat = SIZE( ps0 , 3 )   ! size of input arrays
@@ -462,50 +580,66 @@
          !
          ! Limitation of moments.
-         DO_2D_11_00
-            !  Initialize volumes of boxes (=area if adv_x first called, =psm otherwise)
-            psm(ji,jj,jl) = MAX(  pcrh * e1e2t(ji,jj) + ( 1.0 - pcrh ) * psm(ji,jj,jl) , epsi20  )
-            !
-            zslpmax = MAX( 0._wp, ps0(ji,jj,jl) )
+         DO_2D( 1, 1, ji0, ji0 )
+            !
+            zpsm  = psm (ji,jj,jl) ! optimization
+            zps0  = ps0 (ji,jj,jl)
+            zpsx  = psx (ji,jj,jl)
+            zpsxx = psxx(ji,jj,jl)
+            zpsy  = psy (ji,jj,jl)
+            zpsyy = psyy(ji,jj,jl)
+            zpsxy = psxy(ji,jj,jl)
+            !
+            !  Initialize volumes of boxes (=area if adv_y first called, =psm otherwise)
+            zpsm = MAX(  pcrh * e1e2t(ji,jj) + ( 1.0 - pcrh ) * zpsm , epsi20  )
+            !
+            zslpmax = MAX( 0._wp, zps0 )
             zs1max  = 1.5 * zslpmax
-            zs1new  = MIN( zs1max, MAX( -zs1max, psy(ji,jj,jl) ) )
-            zs2new  = MIN(  ( 2.0 * zslpmax - 0.3334 * ABS( zs1new ) ),   &
-               &             MAX( ABS( zs1new )-zslpmax, psyy(ji,jj,jl) )  )
+            zs1new  = MIN( zs1max, MAX( -zs1max, zpsy ) )
+            zs2new  = MIN( ( 2.0 * zslpmax - 0.3334 * ABS( zs1new ) ), MAX( ABS( zs1new )-zslpmax, zpsyy ) )
             rswitch = ( 1.0 - MAX( 0._wp, SIGN( 1._wp, -zslpmax) ) ) * tmask(ji,jj,1)   ! Case of empty boxes & Apply mask
             !
-            ps0 (ji,jj,jl) = zslpmax  
-            psx (ji,jj,jl) = psx (ji,jj,jl) * rswitch
-            psxx(ji,jj,jl) = psxx(ji,jj,jl) * rswitch
-            psy (ji,jj,jl) = zs1new         * rswitch
-            psyy(ji,jj,jl) = zs2new         * rswitch
-            psxy(ji,jj,jl) = MIN( zslpmax, MAX( -zslpmax, psxy(ji,jj,jl) ) ) * rswitch
-         END_2D
- 
-         !  Calculate fluxes and moments between boxes j<-->j+1              
-         DO_2D_11_00
+            zps0  = zslpmax  
+            zpsx  = zpsx  * rswitch
+            zpsxx = zpsxx * rswitch
+            zpsy  = zs1new         * rswitch
+            zpsyy = zs2new         * rswitch
+            zpsxy = MIN( zslpmax, MAX( -zslpmax, zpsxy ) ) * rswitch
+
+            !  Calculate fluxes and moments between boxes j<-->j+1              
+            !                                !  Flux from j to j+1 WHEN v GT 0   
             zbet(ji,jj)  =  MAX( 0._wp, SIGN( 1._wp, pvt(ji,jj) ) )
-            zalf         =  MAX( 0._wp, pvt(ji,jj) ) * pdt / psm(ji,jj,jl)
+            zalf         =  MAX( 0._wp, pvt(ji,jj) ) * pdt / zpsm
             zalfq        =  zalf * zalf
             zalf1        =  1.0 - zalf
             zalf1q       =  zalf1 * zalf1
             !
-            zfm (ji,jj)  =  zalf  * psm(ji,jj,jl)
-            zf0 (ji,jj)  =  zalf  * ( ps0(ji,jj,jl) + zalf1 * ( psy(ji,jj,jl)  + (zalf1-zalf) * psyy(ji,jj,jl) ) ) 
-            zfy (ji,jj)  =  zalfq *( psy(ji,jj,jl) + 3.0*zalf1*psyy(ji,jj,jl) )
-            zfyy(ji,jj)  =  zalf  * zalfq * psyy(ji,jj,jl)
-            zfx (ji,jj)  =  zalf  * ( psx(ji,jj,jl) + zalf1 * psxy(ji,jj,jl) )
-            zfxy(ji,jj)  =  zalfq * psxy(ji,jj,jl)
-            zfxx(ji,jj)  =  zalf  * psxx(ji,jj,jl)
-            !
-            !  Readjust moments remaining in the box.
-            psm (ji,jj,jl)  =  psm (ji,jj,jl) - zfm(ji,jj)
-            ps0 (ji,jj,jl)  =  ps0 (ji,jj,jl) - zf0(ji,jj)
-            psy (ji,jj,jl)  =  zalf1q * ( psy(ji,jj,jl) -3.0 * zalf * psyy(ji,jj,jl) )
-            psyy(ji,jj,jl)  =  zalf1 * zalf1q * psyy(ji,jj,jl)
-            psx (ji,jj,jl)  =  psx (ji,jj,jl) - zfx(ji,jj)
-            psxx(ji,jj,jl)  =  psxx(ji,jj,jl) - zfxx(ji,jj)
-            psxy(ji,jj,jl)  =  zalf1q * psxy(ji,jj,jl)
+            zfm (ji,jj)  =  zalf  * zpsm
+            zf0 (ji,jj)  =  zalf  * ( zps0 + zalf1 * ( zpsy  + (zalf1-zalf) * zpsyy ) ) 
+            zfy (ji,jj)  =  zalfq *( zpsy + 3.0*zalf1*zpsyy )
+            zfyy(ji,jj)  =  zalf  * zalfq * zpsyy
+            zfx (ji,jj)  =  zalf  * ( zpsx + zalf1 * zpsxy )
+            zfxy(ji,jj)  =  zalfq * zpsxy
+            zfxx(ji,jj)  =  zalf  * zpsxx
+            !
+            !                                !  Readjust moments remaining in the box.
+            zpsm   =  zpsm  - zfm(ji,jj)
+            zps0   =  zps0  - zf0(ji,jj)
+            zpsy   =  zalf1q * ( zpsy -3.0 * zalf * zpsyy )
+            zpsyy  =  zalf1 * zalf1q * zpsyy
+            zpsx   =  zpsx  - zfx(ji,jj)
+            zpsxx  =  zpsxx - zfxx(ji,jj)
+            zpsxy  =  zalf1q * zpsxy
+            !
+            psm (ji,jj,jl) = zpsm ! optimization
+            ps0 (ji,jj,jl) = zps0 
+            psx (ji,jj,jl) = zpsx 
+            psxx(ji,jj,jl) = zpsxx
+            psy (ji,jj,jl) = zpsy 
+            psyy(ji,jj,jl) = zpsyy
+            psxy(ji,jj,jl) = zpsxy
          END_2D
          !
-         DO_2D_10_00
+         DO_2D( 1, 0, ji0, ji0 )
+            !                                !  Flux from j+1 to j when v LT 0.
             zalf          = MAX( 0._wp, -pvt(ji,jj) ) * pdt / psm(ji,jj+1,jl) 
             zalg  (ji,jj) = zalf
@@ -526,70 +660,80 @@
          END_2D
 
-         !  Readjust moments remaining in the box. 
-         DO_2D_00_00
+         DO_2D( 0, 0, ji0, ji0 )
+            !                                !  Readjust moments remaining in the box.
             zbt  =         zbet(ji,jj-1)
             zbt1 = ( 1.0 - zbet(ji,jj-1) )
             !
-            psm (ji,jj,jl) = zbt * psm(ji,jj,jl) + zbt1 * ( psm(ji,jj,jl) - zfm(ji,jj-1) )
-            ps0 (ji,jj,jl) = zbt * ps0(ji,jj,jl) + zbt1 * ( ps0(ji,jj,jl) - zf0(ji,jj-1) )
-            psy (ji,jj,jl) = zalg1q(ji,jj-1) * ( psy(ji,jj,jl) + 3.0 * zalg(ji,jj-1) * psyy(ji,jj,jl) )
-            psyy(ji,jj,jl) = zalg1 (ji,jj-1) * zalg1q(ji,jj-1) * psyy(ji,jj,jl)
-            psx (ji,jj,jl) = zbt * psx (ji,jj,jl) + zbt1 * ( psx (ji,jj,jl) - zfx (ji,jj-1) )
-            psxx(ji,jj,jl) = zbt * psxx(ji,jj,jl) + zbt1 * ( psxx(ji,jj,jl) - zfxx(ji,jj-1) )
-            psxy(ji,jj,jl) = zalg1q(ji,jj-1) * psxy(ji,jj,jl)
+            zpsm  = psm (ji,jj,jl) ! optimization
+            zps0  = ps0 (ji,jj,jl)
+            zpsx  = psx (ji,jj,jl)
+            zpsxx = psxx(ji,jj,jl)
+            zpsy  = psy (ji,jj,jl)
+            zpsyy = psyy(ji,jj,jl)
+            zpsxy = psxy(ji,jj,jl)
+            !
+            zpsm  = zbt * zpsm + zbt1 * ( zpsm - zfm(ji,jj-1) )
+            zps0  = zbt * zps0 + zbt1 * ( zps0 - zf0(ji,jj-1) )
+            zpsy  = zalg1q(ji,jj-1) * ( zpsy + 3.0 * zalg(ji,jj-1) * zpsyy )
+            zpsyy = zalg1 (ji,jj-1) * zalg1q(ji,jj-1) * zpsyy
+            zpsx  = zbt * zpsx  + zbt1 * ( zpsx  - zfx (ji,jj-1) )
+            zpsxx = zbt * zpsxx + zbt1 * ( zpsxx - zfxx(ji,jj-1) )
+            zpsxy = zalg1q(ji,jj-1) * zpsxy
+
+            !   Put the temporary moments into appropriate neighboring boxes.    
+            !                                !   Flux from j to j+1 IF v GT 0.
+            zbt   =       zbet(ji,jj-1)
+            zbt1  = 1.0 - zbet(ji,jj-1)
+            zpsm  = zbt * ( zpsm + zfm(ji,jj-1) ) + zbt1 * zpsm 
+            zalf  = zbt * zfm(ji,jj-1) / zpsm 
+            zalf1 = 1.0 - zalf
+            ztemp = zalf * zps0 - zalf1 * zf0(ji,jj-1)
+            !
+            zps0  =   zbt  * ( zps0 + zf0(ji,jj-1) ) + zbt1 * zps0
+            zpsy  =   zbt  * ( zalf * zfy(ji,jj-1) + zalf1 * zpsy + 3.0 * ztemp )  &
+               &             + zbt1 * zpsy  
+            zpsyy =   zbt  * ( zalf * zalf * zfyy(ji,jj-1) + zalf1 * zalf1 * zpsyy                           &
+               &             + 5.0 * ( zalf * zalf1 * ( zpsy - zfy(ji,jj-1) ) - ( zalf1 - zalf ) * ztemp ) ) & 
+               &             + zbt1 * zpsyy
+            zpsxy =   zbt  * ( zalf * zfxy(ji,jj-1) + zalf1 * zpsxy             &
+               &             + 3.0 * (- zalf1 * zfx(ji,jj-1) + zalf * zpsx ) )  &
+               &             + zbt1 * zpsxy
+            zpsx  =   zbt * ( zpsx  + zfx (ji,jj-1) ) + zbt1 * zpsx 
+            zpsxx =   zbt * ( zpsxx + zfxx(ji,jj-1) ) + zbt1 * zpsxx
+
+            !                                !  Flux from j+1 to j IF v LT 0.
+            zbt   =       zbet(ji,jj)
+            zbt1  = 1.0 - zbet(ji,jj)
+            zpsm  = zbt * zpsm + zbt1 * ( zpsm + zfm(ji,jj) )
+            zalf  = zbt1 * zfm(ji,jj) / zpsm
+            zalf1 = 1.0 - zalf
+            ztemp = - zalf * zps0 + zalf1 * zf0(ji,jj)
+            !
+            zps0  = zbt * zps0  + zbt1 * (  zps0 + zf0(ji,jj) )
+            zpsy  = zbt * zpsy  + zbt1 * (  zalf * zfy(ji,jj) + zalf1 * zpsy + 3.0 * ztemp )
+            zpsyy = zbt * zpsyy + zbt1 * (  zalf * zalf * zfyy(ji,jj) + zalf1 * zalf1 * zpsyy &
+               &                         + 5.0 * ( zalf * zalf1 * ( - zpsy + zfy(ji,jj) )     &
+               &                         + ( zalf1 - zalf ) * ztemp ) )
+            zpsxy = zbt * zpsxy + zbt1 * (  zalf * zfxy(ji,jj) + zalf1 * zpsxy  &
+               &                         + 3.0 * ( zalf1 * zfx(ji,jj) - zalf * zpsx ) )
+            zpsx  = zbt * zpsx  + zbt1 * ( zpsx  + zfx (ji,jj) )
+            zpsxx = zbt * zpsxx + zbt1 * ( zpsxx + zfxx(ji,jj) )
+            !
+            psm (ji,jj,jl) = zpsm ! optimization
+            ps0 (ji,jj,jl) = zps0 
+            psx (ji,jj,jl) = zpsx 
+            psxx(ji,jj,jl) = zpsxx
+            psy (ji,jj,jl) = zpsy 
+            psyy(ji,jj,jl) = zpsyy
+            psxy(ji,jj,jl) = zpsxy
          END_2D
-
-         !   Put the temporary moments into appropriate neighboring boxes.    
-         DO_2D_00_00
-            zbt  =       zbet(ji,jj-1)
-            zbt1 = 1.0 - zbet(ji,jj-1)
-            psm(ji,jj,jl) = zbt * ( psm(ji,jj,jl) + zfm(ji,jj-1) ) + zbt1 * psm(ji,jj,jl) 
-            zalf          = zbt * zfm(ji,jj-1) / psm(ji,jj,jl) 
-            zalf1         = 1.0 - zalf
-            ztemp         = zalf * ps0(ji,jj,jl) - zalf1 * zf0(ji,jj-1)
-            !
-            ps0(ji,jj,jl)  =   zbt  * ( ps0(ji,jj,jl) + zf0(ji,jj-1) ) + zbt1 * ps0(ji,jj,jl)
-            psy(ji,jj,jl)  =   zbt  * ( zalf * zfy(ji,jj-1) + zalf1 * psy(ji,jj,jl) + 3.0 * ztemp )  &
-               &             + zbt1 * psy(ji,jj,jl)  
-            psyy(ji,jj,jl) =   zbt  * ( zalf * zalf * zfyy(ji,jj-1) + zalf1 * zalf1 * psyy(ji,jj,jl)                           &
-               &                      + 5.0 * ( zalf * zalf1 * ( psy(ji,jj,jl) - zfy(ji,jj-1) ) - ( zalf1 - zalf ) * ztemp ) ) & 
-               &             + zbt1 * psyy(ji,jj,jl)
-            psxy(ji,jj,jl) =   zbt  * (  zalf * zfxy(ji,jj-1) + zalf1 * psxy(ji,jj,jl)            &
-               &                      + 3.0 * (- zalf1 * zfx(ji,jj-1) + zalf * psx(ji,jj,jl) ) )  &
-               &             + zbt1 * psxy(ji,jj,jl)
-            psx (ji,jj,jl) =   zbt * ( psx (ji,jj,jl) + zfx (ji,jj-1) ) + zbt1 * psx (ji,jj,jl)
-            psxx(ji,jj,jl) =   zbt * ( psxx(ji,jj,jl) + zfxx(ji,jj-1) ) + zbt1 * psxx(ji,jj,jl)
-         END_2D
-
-         DO_2D_00_00
-            zbt  =       zbet(ji,jj)
-            zbt1 = 1.0 - zbet(ji,jj)
-            psm(ji,jj,jl) = zbt * psm(ji,jj,jl) + zbt1 * ( psm(ji,jj,jl) + zfm(ji,jj) )
-            zalf          = zbt1 * zfm(ji,jj) / psm(ji,jj,jl)
-            zalf1         = 1.0 - zalf
-            ztemp         = - zalf * ps0(ji,jj,jl) + zalf1 * zf0(ji,jj)
-            !
-            ps0 (ji,jj,jl) = zbt * ps0 (ji,jj,jl) + zbt1 * (  ps0(ji,jj,jl) + zf0(ji,jj) )
-            psy (ji,jj,jl) = zbt * psy (ji,jj,jl) + zbt1 * (  zalf * zfy(ji,jj) + zalf1 * psy(ji,jj,jl) + 3.0 * ztemp )
-            psyy(ji,jj,jl) = zbt * psyy(ji,jj,jl) + zbt1 * (  zalf * zalf * zfyy(ji,jj) + zalf1 * zalf1 * psyy(ji,jj,jl) &
-               &                                            + 5.0 * ( zalf * zalf1 * ( - psy(ji,jj,jl) + zfy(ji,jj) )    &
-               &                                            + ( zalf1 - zalf ) * ztemp ) )
-            psxy(ji,jj,jl) = zbt * psxy(ji,jj,jl) + zbt1 * (  zalf * zfxy(ji,jj) + zalf1 * psxy(ji,jj,jl)  &
-               &                                            + 3.0 * ( zalf1 * zfx(ji,jj) - zalf * psx(ji,jj,jl) ) )
-            psx (ji,jj,jl) = zbt * psx (ji,jj,jl) + zbt1 * ( psx (ji,jj,jl) + zfx (ji,jj) )
-            psxx(ji,jj,jl) = zbt * psxx(ji,jj,jl) + zbt1 * ( psxx(ji,jj,jl) + zfxx(ji,jj) )
-         END_2D
-
+         !
       END DO
-
-      !-- Lateral boundary conditions
-      CALL lbc_lnk_multi( 'icedyn_adv_pra', psm(:,:,1:jcat) , 'T',  1., ps0 , 'T',  1.   &
-         &                                , psx             , 'T', -1., psy , 'T', -1.   &   ! caution gradient ==> the sign changes
-         &                                , psxx            , 'T',  1., psyy, 'T',  1. , psxy, 'T',  1. )
       !
    END SUBROUTINE adv_y
 
 
-   SUBROUTINE Hbig( pdt, phi_max, phs_max, phip_max, pv_i, pv_s, pa_i, pa_ip, pv_ip, pe_s )
+   SUBROUTINE Hbig( pdt, phi_max, phs_max, phip_max, psi_max, pes_max, pei_max, &
+      &                  pv_i, pv_s, pa_i, pa_ip, pv_ip, psv_i, pe_s, pe_i )
       !!-------------------------------------------------------------------
       !!                  ***  ROUTINE Hbig  ***
@@ -605,11 +749,14 @@
       !! ** input   : Max thickness of the surrounding 9-points
       !!-------------------------------------------------------------------
-      REAL(wp)                    , INTENT(in   ) ::   pdt                          ! tracer time-step
-      REAL(wp), DIMENSION(:,:,:)  , INTENT(in   ) ::   phi_max, phs_max, phip_max   ! max ice thick from surrounding 9-pts
-      REAL(wp), DIMENSION(:,:,:)  , INTENT(inout) ::   pv_i, pv_s, pa_i, pa_ip, pv_ip
+      REAL(wp)                    , INTENT(in   ) ::   pdt                                   ! tracer time-step
+      REAL(wp), DIMENSION(:,:,:)  , INTENT(in   ) ::   phi_max, phs_max, phip_max, psi_max   ! max ice thick from surrounding 9-pts
+      REAL(wp), DIMENSION(:,:,:,:), INTENT(in   ) ::   pes_max
+      REAL(wp), DIMENSION(:,:,:,:), INTENT(in   ) ::   pei_max
+      REAL(wp), DIMENSION(:,:,:)  , INTENT(inout) ::   pv_i, pv_s, pa_i, pa_ip, pv_ip, psv_i
       REAL(wp), DIMENSION(:,:,:,:), INTENT(inout) ::   pe_s
-      !
-      INTEGER  ::   ji, jj, jl         ! dummy loop indices
-      REAL(wp) ::   z1_dt, zhip, zhi, zhs, zfra
+      REAL(wp), DIMENSION(:,:,:,:), INTENT(inout) ::   pe_i
+      !
+      INTEGER  ::   ji, jj, jk, jl         ! dummy loop indices
+      REAL(wp) ::   z1_dt, zhip, zhi, zhs, zsi, zes, zei, zfra
       !!-------------------------------------------------------------------
       !
@@ -617,11 +764,10 @@
       !
       DO jl = 1, jpl
-
-         DO_2D_11_11
+         DO_2D( 1, 1, 1, 1 )
             IF ( pv_i(ji,jj,jl) > 0._wp ) THEN
                !
                !                               ! -- check h_ip -- !
                ! if h_ip is larger than the surrounding 9 pts => reduce h_ip and increase a_ip
-               IF( ln_pnd_H12 .AND. pv_ip(ji,jj,jl) > 0._wp ) THEN
+               IF( ln_pnd_LEV .AND. pv_ip(ji,jj,jl) > 0._wp ) THEN
                   zhip = pv_ip(ji,jj,jl) / MAX( epsi20, pa_ip(ji,jj,jl) )
                   IF( zhip > phip_max(ji,jj,jl) .AND. pa_ip(ji,jj,jl) < 0.15 ) THEN
@@ -650,7 +796,45 @@
                ENDIF           
                !                  
+               !                               ! -- check s_i -- !
+               ! if s_i is larger than the surrounding 9 pts => put salt excess in the ocean
+               zsi = psv_i(ji,jj,jl) / pv_i(ji,jj,jl)
+               IF( zsi > psi_max(ji,jj,jl) .AND. pa_i(ji,jj,jl) < 0.15 ) THEN
+                  zfra = psi_max(ji,jj,jl) / zsi
+                  sfx_res(ji,jj) = sfx_res(ji,jj) + psv_i(ji,jj,jl) * ( 1._wp - zfra ) * rhoi * z1_dt
+                  psv_i(ji,jj,jl) = psv_i(ji,jj,jl) * zfra
+               ENDIF
+               !
             ENDIF
          END_2D
       END DO 
+      !
+      !                                           ! -- check e_i/v_i -- !
+      DO jl = 1, jpl
+         DO_3D( 1, 1, 1, 1, 1, nlay_i )
+            IF ( pv_i(ji,jj,jl) > 0._wp ) THEN
+               ! if e_i/v_i is larger than the surrounding 9 pts => put the heat excess in the ocean
+               zei = pe_i(ji,jj,jk,jl) / pv_i(ji,jj,jl)
+               IF( zei > pei_max(ji,jj,jk,jl) .AND. pa_i(ji,jj,jl) < 0.15 ) THEN
+                  zfra = pei_max(ji,jj,jk,jl) / zei
+                  hfx_res(ji,jj) = hfx_res(ji,jj) - pe_i(ji,jj,jk,jl) * ( 1._wp - zfra ) * z1_dt ! W.m-2 <0
+                  pe_i(ji,jj,jk,jl) = pe_i(ji,jj,jk,jl) * zfra
+               ENDIF
+            ENDIF
+         END_3D
+      END DO
+      !                                           ! -- check e_s/v_s -- !
+      DO jl = 1, jpl
+         DO_3D( 1, 1, 1, 1, 1, nlay_s )
+            IF ( pv_s(ji,jj,jl) > 0._wp ) THEN
+               ! if e_s/v_s is larger than the surrounding 9 pts => put the heat excess in the ocean
+               zes = pe_s(ji,jj,jk,jl) / pv_s(ji,jj,jl)
+               IF( zes > pes_max(ji,jj,jk,jl) .AND. pa_i(ji,jj,jl) < 0.15 ) THEN
+                  zfra = pes_max(ji,jj,jk,jl) / zes
+                  hfx_res(ji,jj) = hfx_res(ji,jj) - pe_s(ji,jj,jk,jl) * ( 1._wp - zfra ) * z1_dt ! W.m-2 <0
+                  pe_s(ji,jj,jk,jl) = pe_s(ji,jj,jk,jl) * zfra
+               ENDIF
+            ENDIF
+         END_3D
+      END DO
       !
    END SUBROUTINE Hbig
@@ -684,5 +868,5 @@
       ! -- check snow load -- !
       DO jl = 1, jpl
-         DO_2D_11_11
+         DO_2D( 1, 1, 1, 1 )
             IF ( pv_i(ji,jj,jl) > 0._wp ) THEN
                !
@@ -724,6 +908,7 @@
          &      sxsal(jpi,jpj,jpl) , sysal(jpi,jpj,jpl) , sxxsal(jpi,jpj,jpl) , syysal(jpi,jpj,jpl) , sxysal(jpi,jpj,jpl) ,   &
          &      sxage(jpi,jpj,jpl) , syage(jpi,jpj,jpl) , sxxage(jpi,jpj,jpl) , syyage(jpi,jpj,jpl) , sxyage(jpi,jpj,jpl) ,   &
-         &      sxap(jpi,jpj,jpl)  , syap (jpi,jpj,jpl) , sxxap (jpi,jpj,jpl) , syyap (jpi,jpj,jpl) , sxyap (jpi,jpj,jpl) ,   &
-         &      sxvp(jpi,jpj,jpl)  , syvp (jpi,jpj,jpl) , sxxvp (jpi,jpj,jpl) , syyvp (jpi,jpj,jpl) , sxyvp (jpi,jpj,jpl) ,   &
+         &      sxap (jpi,jpj,jpl) , syap (jpi,jpj,jpl) , sxxap (jpi,jpj,jpl) , syyap (jpi,jpj,jpl) , sxyap (jpi,jpj,jpl) ,   &
+         &      sxvp (jpi,jpj,jpl) , syvp (jpi,jpj,jpl) , sxxvp (jpi,jpj,jpl) , syyvp (jpi,jpj,jpl) , sxyvp (jpi,jpj,jpl) ,   &
+         &      sxvl (jpi,jpj,jpl) , syvl (jpi,jpj,jpl) , sxxvl (jpi,jpj,jpl) , syyvl (jpi,jpj,jpl) , sxyvl (jpi,jpj,jpl) ,   &
          !
          &      sxc0 (jpi,jpj,nlay_s,jpl) , syc0 (jpi,jpj,nlay_s,jpl) , sxxc0(jpi,jpj,nlay_s,jpl) , &
@@ -773,46 +958,46 @@
             !
             !                                                        ! ice thickness
-            CALL iom_get( numrir, jpdom_autoglo, 'sxice' , sxice, ldxios = lrixios  )
-            CALL iom_get( numrir, jpdom_autoglo, 'syice' , syice, ldxios = lrixios  )
-            CALL iom_get( numrir, jpdom_autoglo, 'sxxice', sxxice, ldxios = lrixios )
-            CALL iom_get( numrir, jpdom_autoglo, 'syyice', syyice, ldxios = lrixios )
-            CALL iom_get( numrir, jpdom_autoglo, 'sxyice', sxyice, ldxios = lrixios )
+            CALL iom_get( numrir, jpdom_auto, 'sxice' , sxice , psgn = -1._wp, ldxios = lrixios )
+            CALL iom_get( numrir, jpdom_auto, 'syice' , syice , psgn = -1._wp, ldxios = lrixios )
+            CALL iom_get( numrir, jpdom_auto, 'sxxice', sxxice, ldxios = lrixios )
+            CALL iom_get( numrir, jpdom_auto, 'syyice', syyice, ldxios = lrixios )
+            CALL iom_get( numrir, jpdom_auto, 'sxyice', sxyice, ldxios = lrixios )
             !                                                        ! snow thickness
-            CALL iom_get( numrir, jpdom_autoglo, 'sxsn'  , sxsn, ldxios = lrixios   )
-            CALL iom_get( numrir, jpdom_autoglo, 'sysn'  , sysn, ldxios = lrixios   )
-            CALL iom_get( numrir, jpdom_autoglo, 'sxxsn' , sxxsn, ldxios = lrixios  )
-            CALL iom_get( numrir, jpdom_autoglo, 'syysn' , syysn, ldxios = lrixios  )
-            CALL iom_get( numrir, jpdom_autoglo, 'sxysn' , sxysn, ldxios = lrixios  )
+            CALL iom_get( numrir, jpdom_auto, 'sxsn'  , sxsn  , psgn = -1._wp, ldxios = lrixios )
+            CALL iom_get( numrir, jpdom_auto, 'sysn'  , sysn  , psgn = -1._wp, ldxios = lrixios )
+            CALL iom_get( numrir, jpdom_auto, 'sxxsn' , sxxsn, ldxios = lrixios  )
+            CALL iom_get( numrir, jpdom_auto, 'syysn' , syysn, ldxios = lrixios  )
+            CALL iom_get( numrir, jpdom_auto, 'sxysn' , sxysn, ldxios = lrixios  )
             !                                                        ! ice concentration
-            CALL iom_get( numrir, jpdom_autoglo, 'sxa'   , sxa, ldxios = lrixios    )
-            CALL iom_get( numrir, jpdom_autoglo, 'sya'   , sya, ldxios = lrixios    )
-            CALL iom_get( numrir, jpdom_autoglo, 'sxxa'  , sxxa, ldxios = lrixios   )
-            CALL iom_get( numrir, jpdom_autoglo, 'syya'  , syya, ldxios = lrixios   )
-            CALL iom_get( numrir, jpdom_autoglo, 'sxya'  , sxya, ldxios = lrixios   )
+            CALL iom_get( numrir, jpdom_auto, 'sxa'   , sxa   , psgn = -1._wp, ldxios = lrixios )
+            CALL iom_get( numrir, jpdom_auto, 'sya'   , sya   , psgn = -1._wp, ldxios = lrixios )
+            CALL iom_get( numrir, jpdom_auto, 'sxxa'  , sxxa, ldxios = lrixios   )
+            CALL iom_get( numrir, jpdom_auto, 'syya'  , syya, ldxios = lrixios   )
+            CALL iom_get( numrir, jpdom_auto, 'sxya'  , sxya, ldxios = lrixios   )
             !                                                        ! ice salinity
-            CALL iom_get( numrir, jpdom_autoglo, 'sxsal' , sxsal, ldxios = lrixios  )
-            CALL iom_get( numrir, jpdom_autoglo, 'sysal' , sysal, ldxios = lrixios  )
-            CALL iom_get( numrir, jpdom_autoglo, 'sxxsal', sxxsal, ldxios = lrixios )
-            CALL iom_get( numrir, jpdom_autoglo, 'syysal', syysal, ldxios = lrixios )
-            CALL iom_get( numrir, jpdom_autoglo, 'sxysal', sxysal, ldxios = lrixios )
+            CALL iom_get( numrir, jpdom_auto, 'sxsal' , sxsal , psgn = -1._wp, ldxios = lrixios )
+            CALL iom_get( numrir, jpdom_auto, 'sysal' , sysal , psgn = -1._wp, ldxios = lrixios )
+            CALL iom_get( numrir, jpdom_auto, 'sxxsal', sxxsal, ldxios = lrixios )
+            CALL iom_get( numrir, jpdom_auto, 'syysal', syysal, ldxios = lrixios )
+            CALL iom_get( numrir, jpdom_auto, 'sxysal', sxysal, ldxios = lrixios )
             !                                                        ! ice age
-            CALL iom_get( numrir, jpdom_autoglo, 'sxage' , sxage, ldxios = lrixios  )
-            CALL iom_get( numrir, jpdom_autoglo, 'syage' , syage, ldxios = lrixios  )
-            CALL iom_get( numrir, jpdom_autoglo, 'sxxage', sxxage, ldxios = lrixios )
-            CALL iom_get( numrir, jpdom_autoglo, 'syyage', syyage, ldxios = lrixios )
-            CALL iom_get( numrir, jpdom_autoglo, 'sxyage', sxyage, ldxios = lrixios )
+            CALL iom_get( numrir, jpdom_auto, 'sxage' , sxage , psgn = -1._wp, ldxios = lrixios )
+            CALL iom_get( numrir, jpdom_auto, 'syage' , syage , psgn = -1._wp, ldxios = lrixios )
+            CALL iom_get( numrir, jpdom_auto, 'sxxage', sxxage, ldxios = lrixios )
+            CALL iom_get( numrir, jpdom_auto, 'syyage', syyage, ldxios = lrixios )
+            CALL iom_get( numrir, jpdom_auto, 'sxyage', sxyage, ldxios = lrixios )
             !                                                        ! snow layers heat content
             DO jk = 1, nlay_s
                WRITE(zchar1,'(I2.2)') jk
                znam = 'sxc0'//'_l'//zchar1  
-               CALL iom_get( numrir, jpdom_autoglo, znam , z3d, ldxios = lrixios )   ;   sxc0 (:,:,jk,:) = z3d(:,:,:)
+               CALL iom_get( numrir, jpdom_auto, znam , z3d, psgn = -1._wp, ldxios = lrixios )   ;   sxc0 (:,:,jk,:) = z3d(:,:,:)
                znam = 'syc0'//'_l'//zchar1  
-               CALL iom_get( numrir, jpdom_autoglo, znam , z3d, ldxios = lrixios )   ;   syc0 (:,:,jk,:) = z3d(:,:,:)
+               CALL iom_get( numrir, jpdom_auto, znam , z3d, psgn = -1._wp, ldxios = lrixios )   ;   syc0 (:,:,jk,:) = z3d(:,:,:)
                znam = 'sxxc0'//'_l'//zchar1 
-               CALL iom_get( numrir, jpdom_autoglo, znam , z3d, ldxios = lrixios )   ;   sxxc0(:,:,jk,:) = z3d(:,:,:)
+               CALL iom_get( numrir, jpdom_auto, znam , z3d, ldxios = lrixios )   ;   sxxc0(:,:,jk,:) = z3d(:,:,:)
                znam = 'syyc0'//'_l'//zchar1 
-               CALL iom_get( numrir, jpdom_autoglo, znam , z3d, ldxios = lrixios )   ;   syyc0(:,:,jk,:) = z3d(:,:,:)
+               CALL iom_get( numrir, jpdom_auto, znam , z3d, ldxios = lrixios )   ;   syyc0(:,:,jk,:) = z3d(:,:,:)
                znam = 'sxyc0'//'_l'//zchar1 
-               CALL iom_get( numrir, jpdom_autoglo, znam , z3d, ldxios = lrixios )   ;   sxyc0(:,:,jk,:) = z3d(:,:,:)
+               CALL iom_get( numrir, jpdom_auto, znam , z3d, ldxios = lrixios )   ;   sxyc0(:,:,jk,:) = z3d(:,:,:)
             END DO
             !                                                        ! ice layers heat content
@@ -820,27 +1005,44 @@
                WRITE(zchar1,'(I2.2)') jk
                znam = 'sxe'//'_l'//zchar1   
-               CALL iom_get( numrir, jpdom_autoglo, znam , z3d, ldxios = lrixios )   ;   sxe (:,:,jk,:) = z3d(:,:,:)
+               CALL iom_get( numrir, jpdom_auto, znam , z3d, psgn = -1._wp, ldxios = lrixios )   ;   sxe (:,:,jk,:) = z3d(:,:,:)
                znam = 'sye'//'_l'//zchar1   
-               CALL iom_get( numrir, jpdom_autoglo, znam , z3d, ldxios = lrixios )   ;   sye (:,:,jk,:) = z3d(:,:,:)
+               CALL iom_get( numrir, jpdom_auto, znam , z3d, psgn = -1._wp, ldxios = lrixios )   ;   sye (:,:,jk,:) = z3d(:,:,:)
                znam = 'sxxe'//'_l'//zchar1  
-               CALL iom_get( numrir, jpdom_autoglo, znam , z3d, ldxios = lrixios )   ;   sxxe(:,:,jk,:) = z3d(:,:,:)
+               CALL iom_get( numrir, jpdom_auto, znam , z3d, ldxios = lrixios )   ;   sxxe(:,:,jk,:) = z3d(:,:,:)
                znam = 'syye'//'_l'//zchar1  
-               CALL iom_get( numrir, jpdom_autoglo, znam , z3d, ldxios = lrixios )   ;   syye(:,:,jk,:) = z3d(:,:,:)
+               CALL iom_get( numrir, jpdom_auto, znam , z3d, ldxios = lrixios )   ;   syye(:,:,jk,:) = z3d(:,:,:)
                znam = 'sxye'//'_l'//zchar1  
-               CALL iom_get( numrir, jpdom_autoglo, znam , z3d, ldxios = lrixios )   ;   sxye(:,:,jk,:) = z3d(:,:,:)
-            END DO
-            !
-            IF( ln_pnd_H12 ) THEN                                    ! melt pond fraction
-               CALL iom_get( numrir, jpdom_autoglo, 'sxap' , sxap,  ldxios = lrixios )
-               CALL iom_get( numrir, jpdom_autoglo, 'syap' , syap,  ldxios = lrixios )
-               CALL iom_get( numrir, jpdom_autoglo, 'sxxap', sxxap, ldxios = lrixios )
-               CALL iom_get( numrir, jpdom_autoglo, 'syyap', syyap, ldxios = lrixios )
-               CALL iom_get( numrir, jpdom_autoglo, 'sxyap', sxyap, ldxios = lrixios )
-               !                                                     ! melt pond volume
-               CALL iom_get( numrir, jpdom_autoglo, 'sxvp' , sxvp,  ldxios = lrixios )
-               CALL iom_get( numrir, jpdom_autoglo, 'syvp' , syvp,  ldxios = lrixios )
-               CALL iom_get( numrir, jpdom_autoglo, 'sxxvp', sxxvp, ldxios = lrixios )
-               CALL iom_get( numrir, jpdom_autoglo, 'syyvp', syyvp, ldxios = lrixios )
-               CALL iom_get( numrir, jpdom_autoglo, 'sxyvp', sxyvp, ldxios = lrixios )
+               CALL iom_get( numrir, jpdom_auto, znam , z3d, ldxios = lrixios )   ;   sxye(:,:,jk,:) = z3d(:,:,:)
+            END DO
+            !
+            IF( ln_pnd_LEV ) THEN                                    ! melt pond fraction
+               IF( iom_varid( numrir, 'sxap', ldstop = .FALSE. ) > 0 ) THEN
+                  CALL iom_get( numrir, jpdom_auto, 'sxap' , sxap , psgn = -1._wp, ldxios = lrixios )
+                  CALL iom_get( numrir, jpdom_auto, 'syap' , syap , psgn = -1._wp, ldxios = lrixios )
+                  CALL iom_get( numrir, jpdom_auto, 'sxxap', sxxap, ldxios = lrixios )
+                  CALL iom_get( numrir, jpdom_auto, 'syyap', syyap, ldxios = lrixios )
+                  CALL iom_get( numrir, jpdom_auto, 'sxyap', sxyap, ldxios = lrixios )
+                  !                                                     ! melt pond volume
+                  CALL iom_get( numrir, jpdom_auto, 'sxvp' , sxvp , psgn = -1._wp, ldxios = lrixios )
+                  CALL iom_get( numrir, jpdom_auto, 'syvp' , syvp , psgn = -1._wp, ldxios = lrixios )
+                  CALL iom_get( numrir, jpdom_auto, 'sxxvp', sxxvp, ldxios = lrixios )
+                  CALL iom_get( numrir, jpdom_auto, 'syyvp', syyvp, ldxios = lrixios )
+                  CALL iom_get( numrir, jpdom_auto, 'sxyvp', sxyvp, ldxios = lrixios )
+               ELSE
+                  sxap = 0._wp ;   syap = 0._wp    ;   sxxap = 0._wp    ;   syyap = 0._wp    ;   sxyap = 0._wp   ! melt pond fraction
+                  sxvp = 0._wp ;   syvp = 0._wp    ;   sxxvp = 0._wp    ;   syyvp = 0._wp    ;   sxyvp = 0._wp   ! melt pond volume
+               ENDIF
+                  !
+               IF ( ln_pnd_lids ) THEN                               ! melt pond lid volume
+                  IF( iom_varid( numrir, 'sxvl', ldstop = .FALSE. ) > 0 ) THEN
+                     CALL iom_get( numrir, jpdom_auto, 'sxvl' , sxvl , psgn = -1._wp, ldxios = lrixios )
+                     CALL iom_get( numrir, jpdom_auto, 'syvl' , syvl , psgn = -1._wp, ldxios = lrixios )
+                     CALL iom_get( numrir, jpdom_auto, 'sxxvl', sxxvl, ldxios = lrixios )
+                     CALL iom_get( numrir, jpdom_auto, 'syyvl', syyvl, ldxios = lrixios )
+                     CALL iom_get( numrir, jpdom_auto, 'sxyvl', sxyvl, ldxios = lrixios )
+                  ELSE
+                     sxvl = 0._wp; syvl = 0._wp    ;   sxxvl = 0._wp    ;   syyvl = 0._wp    ;   sxyvl = 0._wp   ! melt pond lid volume
+                  ENDIF
+               ENDIF
             ENDIF
             IF(lrixios) CALL iom_swap(cxios_context)
@@ -857,7 +1059,10 @@
             sxc0  = 0._wp   ;   syc0  = 0._wp   ;   sxxc0  = 0._wp   ;   syyc0  = 0._wp   ;   sxyc0  = 0._wp      ! snow layers heat content
             sxe   = 0._wp   ;   sye   = 0._wp   ;   sxxe   = 0._wp   ;   syye   = 0._wp   ;   sxye   = 0._wp      ! ice layers heat content
-            IF( ln_pnd_H12 ) THEN
-               sxap  = 0._wp   ;   syap  = 0._wp   ;   sxxap  = 0._wp   ;   syyap  = 0._wp   ;   sxyap  = 0._wp   ! melt pond fraction
-               sxvp  = 0._wp   ;   syvp  = 0._wp   ;   sxxvp  = 0._wp   ;   syyvp  = 0._wp   ;   sxyvp  = 0._wp   ! melt pond volume
+            IF( ln_pnd_LEV ) THEN
+               sxap = 0._wp ;   syap = 0._wp    ;   sxxap = 0._wp    ;   syyap = 0._wp    ;   sxyap = 0._wp       ! melt pond fraction
+               sxvp = 0._wp ;   syvp = 0._wp    ;   sxxvp = 0._wp    ;   syyvp = 0._wp    ;   sxyvp = 0._wp       ! melt pond volume
+               IF ( ln_pnd_lids ) THEN
+                  sxvl = 0._wp; syvl = 0._wp    ;   sxxvl = 0._wp    ;   syyvl = 0._wp    ;   sxyvl = 0._wp       ! melt pond lid volume
+               ENDIF
             ENDIF
          ENDIF
@@ -933,16 +1138,24 @@
          END DO
          !
-         IF( ln_pnd_H12 ) THEN                                       ! melt pond fraction
-            CALL iom_rstput( iter, nitrst, numriw, 'sxap' , sxap,  ldxios = lwxios)
-            CALL iom_rstput( iter, nitrst, numriw, 'syap' , syap,  ldxios = lwxios)
-            CALL iom_rstput( iter, nitrst, numriw, 'sxxap', sxxap, ldxios = lwxios)
-            CALL iom_rstput( iter, nitrst, numriw, 'syyap', syyap, ldxios = lwxios)
-            CALL iom_rstput( iter, nitrst, numriw, 'sxyap', sxyap, ldxios = lwxios)
+         IF( ln_pnd_LEV ) THEN                                       ! melt pond fraction
+            CALL iom_rstput( iter, nitrst, numriw, 'sxap' , sxap , ldxios = lwxios )
+            CALL iom_rstput( iter, nitrst, numriw, 'syap' , syap , ldxios = lwxios )
+            CALL iom_rstput( iter, nitrst, numriw, 'sxxap', sxxap, ldxios = lwxios )
+            CALL iom_rstput( iter, nitrst, numriw, 'syyap', syyap, ldxios = lwxios )
+            CALL iom_rstput( iter, nitrst, numriw, 'sxyap', sxyap, ldxios = lwxios )
             !                                                        ! melt pond volume
-            CALL iom_rstput( iter, nitrst, numriw, 'sxvp' , sxvp,  ldxios = lwxios)
-            CALL iom_rstput( iter, nitrst, numriw, 'syvp' , syvp,  ldxios = lwxios)
-            CALL iom_rstput( iter, nitrst, numriw, 'sxxvp', sxxvp, ldxios = lwxios)
-            CALL iom_rstput( iter, nitrst, numriw, 'syyvp', syyvp, ldxios = lwxios)
-            CALL iom_rstput( iter, nitrst, numriw, 'sxyvp', sxyvp, ldxios = lwxios)
+            CALL iom_rstput( iter, nitrst, numriw, 'sxvp' , sxvp , ldxios = lwxios )
+            CALL iom_rstput( iter, nitrst, numriw, 'syvp' , syvp , ldxios = lwxios )
+            CALL iom_rstput( iter, nitrst, numriw, 'sxxvp', sxxvp, ldxios = lwxios )
+            CALL iom_rstput( iter, nitrst, numriw, 'syyvp', syyvp, ldxios = lwxios )
+            CALL iom_rstput( iter, nitrst, numriw, 'sxyvp', sxyvp, ldxios = lwxios )
+            !
+            IF ( ln_pnd_lids ) THEN                                  ! melt pond lid volume
+               CALL iom_rstput( iter, nitrst, numriw, 'sxvl' , sxvl , ldxios = lwxios )
+               CALL iom_rstput( iter, nitrst, numriw, 'syvl' , syvl , ldxios = lwxios )
+               CALL iom_rstput( iter, nitrst, numriw, 'sxxvl', sxxvl, ldxios = lwxios )
+               CALL iom_rstput( iter, nitrst, numriw, 'syyvl', syyvl, ldxios = lwxios )
+               CALL iom_rstput( iter, nitrst, numriw, 'sxyvl', sxyvl, ldxios = lwxios )
+            ENDIF
          ENDIF
          IF( lwxios ) CALL iom_swap(      cxios_context         )
@@ -951,4 +1164,55 @@
       !
    END SUBROUTINE adv_pra_rst
+
+   SUBROUTINE icemax3D( pice , pmax )
+      !!---------------------------------------------------------------------
+      !!                   ***  ROUTINE icemax3D ***                     
+      !! ** Purpose :  compute the max of the 9 points around
+      !!----------------------------------------------------------------------
+      REAL(wp), DIMENSION(:,:,:)      , INTENT(in ) ::   pice   ! input
+      REAL(wp), DIMENSION(:,:,:)      , INTENT(out) ::   pmax   ! output
+      REAL(wp), DIMENSION(2:jpim1,jpj)              ::   zmax   ! temporary array
+      INTEGER  ::   ji, jj, jl   ! dummy loop indices
+      !!----------------------------------------------------------------------
+      DO jl = 1, jpl
+         DO jj = Njs0-1, Nje0+1    
+            DO ji = Nis0, Nie0
+               zmax(ji,jj) = MAX( epsi20, pice(ji,jj,jl), pice(ji-1,jj,jl), pice(ji+1,jj,jl) )
+            END DO
+         END DO
+         DO jj = Njs0, Nje0    
+            DO ji = Nis0, Nie0
+               pmax(ji,jj,jl) = MAX( epsi20, zmax(ji,jj), zmax(ji,jj-1), zmax(ji,jj+1) )
+            END DO
+         END DO
+      END DO
+   END SUBROUTINE icemax3D
+
+   SUBROUTINE icemax4D( pice , pmax )
+      !!---------------------------------------------------------------------
+      !!                   ***  ROUTINE icemax4D ***                     
+      !! ** Purpose :  compute the max of the 9 points around
+      !!----------------------------------------------------------------------
+      REAL(wp), DIMENSION(:,:,:,:)    , INTENT(in ) ::   pice   ! input
+      REAL(wp), DIMENSION(:,:,:,:)    , INTENT(out) ::   pmax   ! output
+      REAL(wp), DIMENSION(2:jpim1,jpj)              ::   zmax   ! temporary array
+      INTEGER  ::   jlay, ji, jj, jk, jl   ! dummy loop indices
+      !!----------------------------------------------------------------------
+      jlay = SIZE( pice , 3 )   ! size of input arrays
+      DO jl = 1, jpl
+         DO jk = 1, jlay
+            DO jj = Njs0-1, Nje0+1    
+               DO ji = Nis0, Nie0
+                  zmax(ji,jj) = MAX( epsi20, pice(ji,jj,jk,jl), pice(ji-1,jj,jk,jl), pice(ji+1,jj,jk,jl) )
+               END DO
+            END DO
+            DO jj = Njs0, Nje0    
+               DO ji = Nis0, Nie0
+                  pmax(ji,jj,jk,jl) = MAX( epsi20, zmax(ji,jj), zmax(ji,jj-1), zmax(ji,jj+1) )
+               END DO
+            END DO
+         END DO
+      END DO
+   END SUBROUTINE icemax4D
 
 #else
Index: NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icedyn_adv_umx.F90
===================================================================
--- NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icedyn_adv_umx.F90	(revision 13033)
+++ NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icedyn_adv_umx.F90	(revision 13727)
@@ -60,5 +60,5 @@
 
    SUBROUTINE ice_dyn_adv_umx( kn_umx, kt, pu_ice, pv_ice, ph_i, ph_s, ph_ip,  &
-      &                        pato_i, pv_i, pv_s, psv_i, poa_i, pa_i, pa_ip, pv_ip, pe_s, pe_i )
+      &                        pato_i, pv_i, pv_s, psv_i, poa_i, pa_i, pa_ip, pv_ip, pv_il, pe_s, pe_i )
       !!----------------------------------------------------------------------
       !!                  ***  ROUTINE ice_dyn_adv_umx  ***
@@ -85,4 +85,5 @@
       REAL(wp), DIMENSION(:,:,:)  , INTENT(inout) ::   pa_ip      ! melt pond concentration
       REAL(wp), DIMENSION(:,:,:)  , INTENT(inout) ::   pv_ip      ! melt pond volume
+      REAL(wp), DIMENSION(:,:,:)  , INTENT(inout) ::   pv_il      ! melt pond lid volume
       REAL(wp), DIMENSION(:,:,:,:), INTENT(inout) ::   pe_s       ! snw heat content
       REAL(wp), DIMENSION(:,:,:,:), INTENT(inout) ::   pe_i       ! ice heat content
@@ -91,36 +92,48 @@
       INTEGER  ::   icycle                  ! number of sub-timestep for the advection
       REAL(wp) ::   zamsk                   ! 1 if advection of concentration, 0 if advection of other tracers
-      REAL(wp) ::   zdt, zvi_cen
-      REAL(wp), DIMENSION(1)           ::   zcflprv, zcflnow   ! for global communication
-      REAL(wp), DIMENSION(jpi,jpj)     ::   zudy, zvdx, zcu_box, zcv_box
-      REAL(wp), DIMENSION(jpi,jpj)     ::   zati1, zati2
-      REAL(wp), DIMENSION(jpi,jpj,jpl) ::   zu_cat, zv_cat
-      REAL(wp), DIMENSION(jpi,jpj,jpl) ::   zua_ho, zva_ho, zua_ups, zva_ups
-      REAL(wp), DIMENSION(jpi,jpj,jpl) ::   z1_ai , z1_aip, zhvar
-      REAL(wp), DIMENSION(jpi,jpj,jpl) ::   zhi_max, zhs_max, zhip_max
+      REAL(wp) ::   zdt, z1_dt, zvi_cen
+      REAL(wp), DIMENSION(1)                  ::   zcflprv, zcflnow   ! for global communication
+      REAL(wp), DIMENSION(jpi,jpj)            ::   zudy, zvdx, zcu_box, zcv_box
+      REAL(wp), DIMENSION(jpi,jpj)            ::   zati1, zati2
+      REAL(wp), DIMENSION(jpi,jpj,jpl)        ::   zu_cat, zv_cat
+      REAL(wp), DIMENSION(jpi,jpj,jpl)        ::   zua_ho, zva_ho, zua_ups, zva_ups
+      REAL(wp), DIMENSION(jpi,jpj,jpl)        ::   z1_ai , z1_aip, zhvar
+      REAL(wp), DIMENSION(jpi,jpj,jpl)        ::   zhi_max, zhs_max, zhip_max, zs_i, zsi_max
+      REAL(wp), DIMENSION(jpi,jpj,nlay_i,jpl) ::   ze_i, zei_max
+      REAL(wp), DIMENSION(jpi,jpj,nlay_s,jpl) ::   ze_s, zes_max
       !
       REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) ::   zuv_ho, zvv_ho, zuv_ups, zvv_ups, z1_vi, z1_vs 
+      !! diagnostics
+      REAL(wp), DIMENSION(jpi,jpj)            ::   zdiag_adv_mass, zdiag_adv_salt, zdiag_adv_heat      
       !!----------------------------------------------------------------------
       !
       IF( kt == nit000 .AND. lwp )   WRITE(numout,*) '-- ice_dyn_adv_umx: Ultimate-Macho advection scheme'
       !
-      ! --- Record max of the surrounding 9-pts ice thick. (for call Hbig) --- !
-      DO jl = 1, jpl
-         DO_2D_00_00
-            zhip_max(ji,jj,jl) = MAX( epsi20, ph_ip(ji,jj,jl), ph_ip(ji+1,jj  ,jl), ph_ip(ji  ,jj+1,jl), &
-               &                                               ph_ip(ji-1,jj  ,jl), ph_ip(ji  ,jj-1,jl), &
-               &                                               ph_ip(ji+1,jj+1,jl), ph_ip(ji-1,jj-1,jl), &
-               &                                               ph_ip(ji+1,jj-1,jl), ph_ip(ji-1,jj+1,jl) )
-            zhi_max (ji,jj,jl) = MAX( epsi20, ph_i (ji,jj,jl), ph_i (ji+1,jj  ,jl), ph_i (ji  ,jj+1,jl), &
-               &                                               ph_i (ji-1,jj  ,jl), ph_i (ji  ,jj-1,jl), &
-               &                                               ph_i (ji+1,jj+1,jl), ph_i (ji-1,jj-1,jl), &
-               &                                               ph_i (ji+1,jj-1,jl), ph_i (ji-1,jj+1,jl) )
-            zhs_max (ji,jj,jl) = MAX( epsi20, ph_s (ji,jj,jl), ph_s (ji+1,jj  ,jl), ph_s (ji  ,jj+1,jl), &
-               &                                               ph_s (ji-1,jj  ,jl), ph_s (ji  ,jj-1,jl), &
-               &                                               ph_s (ji+1,jj+1,jl), ph_s (ji-1,jj-1,jl), &
-               &                                               ph_s (ji+1,jj-1,jl), ph_s (ji-1,jj+1,jl) )
-         END_2D
-      END DO
-      CALL lbc_lnk_multi( 'icedyn_adv_umx', zhi_max, 'T', 1., zhs_max, 'T', 1., zhip_max, 'T', 1. )
+      ! --- Record max of the surrounding 9-pts (for call Hbig) --- !
+      ! thickness and salinity
+      WHERE( pv_i(:,:,:) >= epsi10 ) ; zs_i(:,:,:) = psv_i(:,:,:) / pv_i(:,:,:)
+      ELSEWHERE                      ; zs_i(:,:,:) = 0._wp
+      END WHERE
+      CALL icemax3D( ph_i , zhi_max )
+      CALL icemax3D( ph_s , zhs_max )
+      CALL icemax3D( ph_ip, zhip_max)
+      CALL icemax3D( zs_i , zsi_max )
+      CALL lbc_lnk_multi( 'icedyn_adv_umx', zhi_max, 'T', 1._wp, zhs_max, 'T', 1._wp, zhip_max, 'T', 1._wp, zsi_max, 'T', 1._wp )
+      !
+      ! enthalpies
+      DO jk = 1, nlay_i
+         WHERE( pv_i(:,:,:) >= epsi10 ) ; ze_i(:,:,jk,:) = pe_i(:,:,jk,:) / pv_i(:,:,:)
+         ELSEWHERE                      ; ze_i(:,:,jk,:) = 0._wp
+         END WHERE
+      END DO
+      DO jk = 1, nlay_s
+         WHERE( pv_s(:,:,:) >= epsi10 ) ; ze_s(:,:,jk,:) = pe_s(:,:,jk,:) / pv_s(:,:,:)
+         ELSEWHERE                      ; ze_s(:,:,jk,:) = 0._wp
+         END WHERE
+      END DO   
+      CALL icemax4D( ze_i , zei_max )
+      CALL icemax4D( ze_s , zes_max )
+      CALL lbc_lnk( 'icedyn_adv_umx', zei_max, 'T', 1._wp )
+      CALL lbc_lnk( 'icedyn_adv_umx', zes_max, 'T', 1._wp )
       !
       !
@@ -138,4 +151,5 @@
       ENDIF
       zdt = rDt_ice / REAL(icycle)
+      z1_dt = 1._wp / zdt
 
       ! --- transport --- !
@@ -150,5 +164,5 @@
       !
       ! --- define velocity for advection: u*grad(H) --- !
-      DO_2D_00_00
+      DO_2D( 0, 0, 0, 0 )
          IF    ( pu_ice(ji,jj) * pu_ice(ji-1,jj) <= 0._wp ) THEN   ;   zcu_box(ji,jj) = 0._wp
          ELSEIF( pu_ice(ji,jj)                   >  0._wp ) THEN   ;   zcu_box(ji,jj) = pu_ice(ji-1,jj)
@@ -166,4 +180,10 @@
       !---------------!
       DO jt = 1, icycle
+
+         ! diagnostics
+         zdiag_adv_mass(:,:) =   SUM(  pv_i(:,:,:) , dim=3 ) * rhoi + SUM(  pv_s(:,:,:) , dim=3 ) * rhos
+         zdiag_adv_salt(:,:) =   SUM( psv_i(:,:,:) , dim=3 ) * rhoi
+         zdiag_adv_heat(:,:) = - SUM(SUM( pe_i(:,:,1:nlay_i,:) , dim=4 ), dim=3 ) &
+            &                  - SUM(SUM( pe_s(:,:,1:nlay_s,:) , dim=4 ), dim=3 )
 
          ! record at_i before advection (for open water)
@@ -183,5 +203,5 @@
             IF( .NOT. ALLOCATED(jmsk_small) )   ALLOCATE( jmsk_small(jpi,jpj,jpl) ) 
             DO jl = 1, jpl
-               DO_2D_10_10
+               DO_2D( 1, 0, 1, 0 )
                   zvi_cen = 0.5_wp * ( pv_i(ji+1,jj,jl) + pv_i(ji,jj,jl) )
                   IF( zvi_cen < epsi06) THEN   ;   imsk_small(ji,jj,jl) = 0
@@ -318,5 +338,5 @@
          !
          !== melt ponds ==!
-         IF ( ln_pnd_H12 ) THEN
+         IF ( ln_pnd_LEV ) THEN
             ! concentration
             zamsk = 1._wp
@@ -328,23 +348,52 @@
             CALL adv_umx( zamsk, kn_umx, jt, kt, zdt, zudy , zvdx , zua_ho , zva_ho , zcu_box, zcv_box, &
                &                                      zhvar, pv_ip, zua_ups, zva_ups )
+            ! lid
+            IF ( ln_pnd_lids ) THEN
+               zamsk = 0._wp
+               zhvar(:,:,:) = pv_il(:,:,:) * z1_aip(:,:,:)
+               CALL adv_umx( zamsk, kn_umx, jt, kt, zdt, zudy , zvdx , zua_ho , zva_ho , zcu_box, zcv_box, &
+                  &                                      zhvar, pv_il, zua_ups, zva_ups )
+            ENDIF
          ENDIF
+
+         ! --- Lateral boundary conditions --- !
+         IF    ( ln_pnd_LEV .AND. ln_pnd_lids ) THEN
+            CALL lbc_lnk_multi( 'icedyn_adv_umx', pa_i,'T',1._wp, pv_i,'T',1._wp, pv_s,'T',1._wp, psv_i,'T',1._wp, poa_i,'T',1._wp &
+               &                                , pa_ip,'T',1._wp, pv_ip,'T',1._wp, pv_il,'T',1._wp )
+         ELSEIF( ln_pnd_LEV .AND. .NOT.ln_pnd_lids ) THEN
+            CALL lbc_lnk_multi( 'icedyn_adv_umx', pa_i,'T',1._wp, pv_i,'T',1._wp, pv_s,'T',1._wp, psv_i,'T',1._wp, poa_i,'T',1._wp &
+               &                                , pa_ip,'T',1._wp, pv_ip,'T',1._wp )
+         ELSE
+            CALL lbc_lnk_multi( 'icedyn_adv_umx', pa_i,'T',1._wp, pv_i,'T',1._wp, pv_s,'T',1._wp, psv_i,'T',1._wp, poa_i,'T',1._wp )
+         ENDIF
+         CALL lbc_lnk( 'icedyn_adv_umx', pe_i, 'T', 1._wp )
+         CALL lbc_lnk( 'icedyn_adv_umx', pe_s, 'T', 1._wp )
          !
          !== Open water area ==!
          zati2(:,:) = SUM( pa_i(:,:,:), dim=3 )
-         DO_2D_00_00
+         DO_2D( 0, 0, 0, 0 )
             pato_i(ji,jj) = pato_i(ji,jj) - ( zati2(ji,jj) - zati1(ji,jj) ) & 
                &                          - ( zudy(ji,jj) - zudy(ji-1,jj) + zvdx(ji,jj) - zvdx(ji,jj-1) ) * r1_e1e2t(ji,jj) * zdt
          END_2D
-         CALL lbc_lnk( 'icedyn_adv_umx', pato_i, 'T',  1. )
-         !
+         CALL lbc_lnk( 'icedyn_adv_umx', pato_i, 'T',  1._wp )
+         !
+         ! --- diagnostics --- !
+         diag_adv_mass(:,:) = diag_adv_mass(:,:) + (   SUM( pv_i(:,:,:) , dim=3 ) * rhoi + SUM( pv_s(:,:,:) , dim=3 ) * rhos &
+            &                                        - zdiag_adv_mass(:,:) ) * z1_dt
+         diag_adv_salt(:,:) = diag_adv_salt(:,:) + (   SUM( psv_i(:,:,:) , dim=3 ) * rhoi &
+            &                                        - zdiag_adv_salt(:,:) ) * z1_dt
+         diag_adv_heat(:,:) = diag_adv_heat(:,:) + ( - SUM(SUM( pe_i(:,:,1:nlay_i,:) , dim=4 ), dim=3 ) &
+            &                                        - SUM(SUM( pe_s(:,:,1:nlay_s,:) , dim=4 ), dim=3 ) &
+            &                                        - zdiag_adv_heat(:,:) ) * z1_dt
          !
          ! --- Ensure non-negative fields and in-bound thicknesses --- !
          ! Remove negative values (conservation is ensured)
          !    (because advected fields are not perfectly bounded and tiny negative values can occur, e.g. -1.e-20)
-         CALL ice_var_zapneg( zdt, pato_i, pv_i, pv_s, psv_i, poa_i, pa_i, pa_ip, pv_ip, pe_s, pe_i )
+         CALL ice_var_zapneg( zdt, pato_i, pv_i, pv_s, psv_i, poa_i, pa_i, pa_ip, pv_ip, pv_il, pe_s, pe_i )
          !
          ! --- Make sure ice thickness is not too big --- !
          !     (because ice thickness can be too large where ice concentration is very small)
-         CALL Hbig( zdt, zhi_max, zhs_max, zhip_max, pv_i, pv_s, pa_i, pa_ip, pv_ip, pe_s )
+         CALL Hbig( zdt, zhi_max, zhs_max, zhip_max, zsi_max, zes_max, zei_max, &
+            &            pv_i, pv_s, pa_i, pa_ip, pv_ip, psv_i, pe_s, pe_i )
          !
          ! --- Ensure snow load is not too big --- !
@@ -396,6 +445,5 @@
       !!             work on H (and not V). It is partly related to the multi-category approach
       !!             Therefore, after advection we limit the thickness to the largest value of the 9-points around (only if ice
-      !!             concentration is small). Since we do not limit S and T, large values can occur at the edge but it does not really matter
-      !!             since sv_i and e_i are still good.
+      !!             concentration is small). We also limit S and T.
       !!----------------------------------------------------------------------
       REAL(wp)                        , INTENT(in   )           ::   pamsk            ! advection of concentration (1) or other tracers (0)
@@ -441,5 +489,5 @@
       IF( pamsk == 0._wp ) THEN
          DO jl = 1, jpl
-            DO_2D_10_10
+            DO_2D( 0, 0, 1, 0 )
                IF( ABS( pu(ji,jj) ) > epsi10 ) THEN
                   zfu_ho (ji,jj,jl) = zfu_ho (ji,jj,jl) * puc    (ji,jj,jl) / pu(ji,jj)
@@ -450,4 +498,6 @@
                ENDIF
                !
+            END_2D
+            DO_2D( 1, 0, 0, 0 )
                IF( ABS( pv(ji,jj) ) > epsi10 ) THEN
                   zfv_ho (ji,jj,jl) = zfv_ho (ji,jj,jl) * pvc    (ji,jj,jl) / pv(ji,jj)
@@ -463,5 +513,5 @@
          ! thus we calculate the upstream solution and apply a limiter again
          DO jl = 1, jpl
-            DO_2D_00_00
+            DO_2D( 0, 0, 0, 0 )
                ztra = - ( zfu_ups(ji,jj,jl) - zfu_ups(ji-1,jj,jl) + zfv_ups(ji,jj,jl) - zfv_ups(ji,jj-1,jl) )
                !
@@ -469,5 +519,5 @@
             END_2D
          END DO
-         CALL lbc_lnk( 'icedyn_adv_umx', zt_ups, 'T',  1. )
+         CALL lbc_lnk( 'icedyn_adv_umx', zt_ups, 'T',  1.0_wp )
          !
          IF    ( np_limiter == 1 ) THEN
@@ -484,7 +534,11 @@
       IF( PRESENT( pua_ho ) ) THEN
          DO jl = 1, jpl
-            DO_2D_10_10
-               pua_ho (ji,jj,jl) = zfu_ho (ji,jj,jl) ; pva_ho (ji,jj,jl) = zfv_ho (ji,jj,jl)
-               pua_ups(ji,jj,jl) = zfu_ups(ji,jj,jl) ; pva_ups(ji,jj,jl) = zfv_ups(ji,jj,jl)
+            DO_2D( 0, 0, 1, 0 )
+               pua_ho (ji,jj,jl) = zfu_ho (ji,jj,jl)
+               pua_ups(ji,jj,jl) = zfu_ups(ji,jj,jl)
+            END_2D
+            DO_2D( 1, 0, 0, 0 )
+               pva_ho (ji,jj,jl) = zfv_ho (ji,jj,jl)
+               pva_ups(ji,jj,jl) = zfv_ups(ji,jj,jl)
             END_2D
          END DO
@@ -494,5 +548,5 @@
       ! ---------------------------------
       DO jl = 1, jpl
-         DO_2D_00_00
+         DO_2D( 0, 0, 0, 0 )
             ztra = - ( zfu_ho(ji,jj,jl) - zfu_ho(ji-1,jj,jl) + zfv_ho(ji,jj,jl) - zfv_ho(ji,jj-1,jl) )  
             !
@@ -500,5 +554,4 @@
          END_2D
       END DO
-      CALL lbc_lnk( 'icedyn_adv_umx', ptc, 'T',  1. )
       !
    END SUBROUTINE adv_umx
@@ -528,5 +581,5 @@
          !
          DO jl = 1, jpl
-            DO_2D_10_10
+            DO_2D( 1, 0, 1, 0 )
                pfu_ups(ji,jj,jl) = MAX( pu(ji,jj), 0._wp ) * pt(ji,jj,jl) + MIN( pu(ji,jj), 0._wp ) * pt(ji+1,jj,jl)
                pfv_ups(ji,jj,jl) = MAX( pv(ji,jj), 0._wp ) * pt(ji,jj,jl) + MIN( pv(ji,jj), 0._wp ) * pt(ji,jj+1,jl)
@@ -539,5 +592,5 @@
             !
             DO jl = 1, jpl              !-- flux in x-direction
-               DO_2D_10_10
+               DO_2D( 1, 1, 1, 0 )
                   pfu_ups(ji,jj,jl) = MAX( pu(ji,jj), 0._wp ) * pt(ji,jj,jl) + MIN( pu(ji,jj), 0._wp ) * pt(ji+1,jj,jl)
                END_2D
@@ -545,5 +598,5 @@
             !
             DO jl = 1, jpl              !-- first guess of tracer from u-flux
-               DO_2D_00_00
+               DO_2D( 1, 1, 0, 0 )
                   ztra = - ( pfu_ups(ji,jj,jl) - pfu_ups(ji-1,jj,jl) )              &
                      &   + ( pu     (ji,jj   ) - pu     (ji-1,jj   ) ) * pt(ji,jj,jl) * (1.-pamsk)
@@ -552,8 +605,7 @@
                END_2D
             END DO
-            CALL lbc_lnk( 'icedyn_adv_umx', zpt, 'T', 1. )
             !
             DO jl = 1, jpl              !-- flux in y-direction
-               DO_2D_10_10
+               DO_2D( 1, 0, 0, 0 )
                   pfv_ups(ji,jj,jl) = MAX( pv(ji,jj), 0._wp ) * zpt(ji,jj,jl) + MIN( pv(ji,jj), 0._wp ) * zpt(ji,jj+1,jl)
                END_2D
@@ -563,5 +615,5 @@
             !
             DO jl = 1, jpl              !-- flux in y-direction
-               DO_2D_10_10
+               DO_2D( 1, 0, 1, 1 )
                   pfv_ups(ji,jj,jl) = MAX( pv(ji,jj), 0._wp ) * pt(ji,jj,jl) + MIN( pv(ji,jj), 0._wp ) * pt(ji,jj+1,jl)
                END_2D
@@ -569,5 +621,5 @@
             !
             DO jl = 1, jpl              !-- first guess of tracer from v-flux
-               DO_2D_00_00
+               DO_2D( 0, 0, 1, 1 )
                   ztra = - ( pfv_ups(ji,jj,jl) - pfv_ups(ji,jj-1,jl) )  &
                      &   + ( pv     (ji,jj   ) - pv     (ji,jj-1   ) ) * pt(ji,jj,jl) * (1.-pamsk)
@@ -576,8 +628,7 @@
                END_2D
             END DO
-            CALL lbc_lnk( 'icedyn_adv_umx', zpt, 'T', 1. )
             !
             DO jl = 1, jpl              !-- flux in x-direction
-               DO_2D_10_10
+               DO_2D( 0, 0, 1, 0 )
                   pfu_ups(ji,jj,jl) = MAX( pu(ji,jj), 0._wp ) * zpt(ji,jj,jl) + MIN( pu(ji,jj), 0._wp ) * zpt(ji+1,jj,jl)
                END_2D
@@ -589,5 +640,5 @@
       !
       DO jl = 1, jpl                    !-- after tracer with upstream scheme
-         DO_2D_00_00
+         DO_2D( 0, 0, 0, 0 )
             ztra = - (   pfu_ups(ji,jj,jl) - pfu_ups(ji-1,jj  ,jl)   &
                &       + pfv_ups(ji,jj,jl) - pfv_ups(ji  ,jj-1,jl) ) &
@@ -598,5 +649,5 @@
          END_2D
       END DO
-      CALL lbc_lnk( 'icedyn_adv_umx', pt_ups, 'T', 1. )
+      CALL lbc_lnk( 'icedyn_adv_umx', pt_ups, 'T', 1.0_wp )
 
    END SUBROUTINE upstream
@@ -628,6 +679,8 @@
          !
          DO jl = 1, jpl
-            DO_2D_10_10
+            DO_2D( 1, 1, 1, 0 )
                pfu_ho(ji,jj,jl) = 0.5_wp * pu(ji,jj) * ( pt(ji,jj,jl) + pt(ji+1,jj  ,jl) )
+            END_2D
+            DO_2D( 1, 0, 1, 1 )
                pfv_ho(ji,jj,jl) = 0.5_wp * pv(ji,jj) * ( pt(ji,jj,jl) + pt(ji  ,jj+1,jl) )
             END_2D
@@ -646,5 +699,5 @@
             !
             DO jl = 1, jpl              !-- flux in x-direction
-               DO_2D_10_10
+               DO_2D( 1, 1, 1, 0 )
                   pfu_ho(ji,jj,jl) = 0.5_wp * pu(ji,jj) * ( pt(ji,jj,jl) + pt(ji+1,jj,jl) )
                END_2D
@@ -653,5 +706,5 @@
 
             DO jl = 1, jpl              !-- first guess of tracer from u-flux
-               DO_2D_00_00
+               DO_2D( 1, 1, 0, 0 )
                   ztra = - ( pfu_ho(ji,jj,jl) - pfu_ho(ji-1,jj,jl) )              &
                      &   + ( pu    (ji,jj   ) - pu    (ji-1,jj   ) ) * pt(ji,jj,jl) * (1.-pamsk)
@@ -660,8 +713,7 @@
                END_2D
             END DO
-            CALL lbc_lnk( 'icedyn_adv_umx', zpt, 'T', 1. )
 
             DO jl = 1, jpl              !-- flux in y-direction
-               DO_2D_10_10
+               DO_2D( 1, 0, 0, 0 )
                   pfv_ho(ji,jj,jl) = 0.5_wp * pv(ji,jj) * ( zpt(ji,jj,jl) + zpt(ji,jj+1,jl) )
                END_2D
@@ -672,5 +724,5 @@
             !
             DO jl = 1, jpl              !-- flux in y-direction
-               DO_2D_10_10
+               DO_2D( 1, 0, 1, 1 )
                   pfv_ho(ji,jj,jl) = 0.5_wp * pv(ji,jj) * ( pt(ji,jj,jl) + pt(ji,jj+1,jl) )
                END_2D
@@ -679,5 +731,5 @@
             !
             DO jl = 1, jpl              !-- first guess of tracer from v-flux
-               DO_2D_00_00
+               DO_2D( 0, 0, 1, 1 )
                   ztra = - ( pfv_ho(ji,jj,jl) - pfv_ho(ji,jj-1,jl) )  &
                      &   + ( pv    (ji,jj   ) - pv    (ji,jj-1   ) ) * pt(ji,jj,jl) * (1.-pamsk)
@@ -686,8 +738,7 @@
                END_2D
             END DO
-            CALL lbc_lnk( 'icedyn_adv_umx', zpt, 'T', 1. )
             !
             DO jl = 1, jpl              !-- flux in x-direction
-               DO_2D_10_10
+               DO_2D( 0, 0, 1, 0 )
                   pfu_ho(ji,jj,jl) = 0.5_wp * pu(ji,jj) * ( zpt(ji,jj,jl) + zpt(ji+1,jj,jl) )
                END_2D
@@ -737,5 +788,5 @@
          !                                                        !--  advective form update in zpt  --!
          DO jl = 1, jpl
-            DO_2D_00_00
+            DO_2D( 0, 0, 0, 0 )
                zpt(ji,jj,jl) = ( pt(ji,jj,jl) - (  pubox(ji,jj   ) * ( zt_u(ji,jj,jl) - zt_u(ji-1,jj,jl) ) * r1_e1t  (ji,jj) &
                   &                              + pt   (ji,jj,jl) * ( pu  (ji,jj   ) - pu  (ji-1,jj   ) ) * r1_e1e2t(ji,jj) &
@@ -744,5 +795,5 @@
             END_2D
          END DO
-         CALL lbc_lnk( 'icedyn_adv_umx', zpt, 'T', 1. )
+         CALL lbc_lnk( 'icedyn_adv_umx', zpt, 'T', 1.0_wp )
          !
          !                                                        !--  ultimate interpolation of pt at v-point  --!
@@ -764,5 +815,5 @@
          !                                                        !--  advective form update in zpt  --!
          DO jl = 1, jpl
-            DO_2D_00_00
+            DO_2D( 0, 0, 0, 0 )
                zpt(ji,jj,jl) = ( pt(ji,jj,jl) - (  pvbox(ji,jj   ) * ( zt_v(ji,jj,jl) - zt_v(ji,jj-1,jl) ) * r1_e2t  (ji,jj) &
                   &                              + pt   (ji,jj,jl) * ( pv  (ji,jj   ) - pv  (ji,jj-1   ) ) * r1_e1e2t(ji,jj) &
@@ -771,5 +822,5 @@
             END_2D
          END DO
-         CALL lbc_lnk( 'icedyn_adv_umx', zpt, 'T', 1. )
+         CALL lbc_lnk( 'icedyn_adv_umx', zpt, 'T', 1.0_wp )
          !
          !                                                        !--  ultimate interpolation of pt at u-point  --!
@@ -824,5 +875,5 @@
          END DO
       END DO
-      CALL lbc_lnk( 'icedyn_adv_umx', ztu2, 'T', 1. )
+      CALL lbc_lnk( 'icedyn_adv_umx', ztu2, 'T', 1.0_wp )
       !
       !                                                     !--  BiLaplacian in i-direction  --!
@@ -838,5 +889,5 @@
          END DO
       END DO
-      CALL lbc_lnk( 'icedyn_adv_umx', ztu4, 'T', 1. )
+      CALL lbc_lnk( 'icedyn_adv_umx', ztu4, 'T', 1.0_wp )
       !
       !
@@ -846,5 +897,5 @@
          !        
          DO jl = 1, jpl
-            DO_2D_10_10
+            DO_2D( 0, 0, 1, 0 )
                pt_u(ji,jj,jl) = 0.5_wp * umask(ji,jj,1) * (                                pt(ji+1,jj,jl) + pt(ji,jj,jl)   &
                   &                                         - SIGN( 1._wp, pu(ji,jj) ) * ( pt(ji+1,jj,jl) - pt(ji,jj,jl) ) )
@@ -855,5 +906,5 @@
          !
          DO jl = 1, jpl
-            DO_2D_10_10
+            DO_2D( 0, 0, 1, 0 )
                zcu  = pu(ji,jj) * r1_e2u(ji,jj) * pdt * r1_e1u(ji,jj)
                pt_u(ji,jj,jl) = 0.5_wp * umask(ji,jj,1) * (                                pt(ji+1,jj,jl) + pt(ji,jj,jl)   &
@@ -865,5 +916,5 @@
          !
          DO jl = 1, jpl
-            DO_2D_10_10
+            DO_2D( 0, 0, 1, 0 )
                zcu  = pu(ji,jj) * r1_e2u(ji,jj) * pdt * r1_e1u(ji,jj)
                zdx2 = e1u(ji,jj) * e1u(ji,jj)
@@ -879,5 +930,5 @@
          !
          DO jl = 1, jpl
-            DO_2D_10_10
+            DO_2D( 0, 0, 1, 0 )
                zcu  = pu(ji,jj) * r1_e2u(ji,jj) * pdt * r1_e1u(ji,jj)
                zdx2 = e1u(ji,jj) * e1u(ji,jj)
@@ -893,5 +944,5 @@
          !
          DO jl = 1, jpl
-            DO_2D_10_10
+            DO_2D( 0, 0, 1, 0 )
                zcu  = pu(ji,jj) * r1_e2u(ji,jj) * pdt * r1_e1u(ji,jj)
                zdx2 = e1u(ji,jj) * e1u(ji,jj)
@@ -914,5 +965,5 @@
       IF( ll_neg ) THEN
          DO jl = 1, jpl
-            DO_2D_10_10
+            DO_2D( 0, 0, 1, 0 )
                IF( pt_u(ji,jj,jl) < 0._wp .OR. ( imsk_small(ji,jj,jl) == 0 .AND. pamsk == 0. ) ) THEN
                   pt_u(ji,jj,jl) = 0.5_wp * umask(ji,jj,1) * (                                pt(ji+1,jj,jl) + pt(ji,jj,jl)   &
@@ -924,5 +975,5 @@
       !                                                     !-- High order flux in i-direction  --!
       DO jl = 1, jpl
-         DO_2D_10_10
+         DO_2D( 0, 0, 1, 0 )
             pfu_ho(ji,jj,jl) = pu(ji,jj) * pt_u(ji,jj,jl)
          END_2D
@@ -957,23 +1008,23 @@
       !                                                     !--  Laplacian in j-direction  --!
       DO jl = 1, jpl
-         DO_2D_10_00
+         DO_2D( 1, 0, 0, 0 )         ! First derivative (gradient)
             ztv1(ji,jj,jl) = ( pt(ji,jj+1,jl) - pt(ji,jj,jl) ) * r1_e2v(ji,jj) * vmask(ji,jj,1)
          END_2D
-         DO_2D_00_00
+         DO_2D( 0, 0, 0, 0 )         ! Second derivative (Laplacian)
             ztv2(ji,jj,jl) = ( ztv1(ji,jj,jl) - ztv1(ji,jj-1,jl) ) * r1_e2t(ji,jj)
          END_2D
       END DO
-      CALL lbc_lnk( 'icedyn_adv_umx', ztv2, 'T', 1. )
+      CALL lbc_lnk( 'icedyn_adv_umx', ztv2, 'T', 1.0_wp )
       !
       !                                                     !--  BiLaplacian in j-direction  --!
       DO jl = 1, jpl
-         DO_2D_10_00
+         DO_2D( 1, 0, 0, 0 )         ! First derivative
             ztv3(ji,jj,jl) = ( ztv2(ji,jj+1,jl) - ztv2(ji,jj,jl) ) * r1_e2v(ji,jj) * vmask(ji,jj,1)
          END_2D
-         DO_2D_00_00
+         DO_2D( 0, 0, 0, 0 )         ! Second derivative
             ztv4(ji,jj,jl) = ( ztv3(ji,jj,jl) - ztv3(ji,jj-1,jl) ) * r1_e2t(ji,jj)
          END_2D
       END DO
-      CALL lbc_lnk( 'icedyn_adv_umx', ztv4, 'T', 1. )
+      CALL lbc_lnk( 'icedyn_adv_umx', ztv4, 'T', 1.0_wp )
       !
       !
@@ -982,5 +1033,5 @@
       CASE( 1 )                                                !==  1st order central TIM  ==! (Eq. 21)
          DO jl = 1, jpl
-            DO_2D_10_10
+            DO_2D( 1, 0, 0, 0 )
                pt_v(ji,jj,jl) = 0.5_wp * vmask(ji,jj,1) * (                                pt(ji,jj+1,jl) + pt(ji,jj,jl)   &
                   &                                         - SIGN( 1._wp, pv(ji,jj) ) * ( pt(ji,jj+1,jl) - pt(ji,jj,jl) ) )
@@ -990,5 +1041,5 @@
       CASE( 2 )                                                !==  2nd order central TIM  ==! (Eq. 23)
          DO jl = 1, jpl
-            DO_2D_10_10
+            DO_2D( 1, 0, 0, 0 )
                zcv  = pv(ji,jj) * r1_e1v(ji,jj) * pdt * r1_e2v(ji,jj)
                pt_v(ji,jj,jl) = 0.5_wp * vmask(ji,jj,1) * (                                pt(ji,jj+1,jl) + pt(ji,jj,jl)   &
@@ -999,5 +1050,5 @@
       CASE( 3 )                                                !==  3rd order central TIM  ==! (Eq. 24)
          DO jl = 1, jpl
-            DO_2D_10_10
+            DO_2D( 1, 0, 0, 0 )
                zcv  = pv(ji,jj) * r1_e1v(ji,jj) * pdt * r1_e2v(ji,jj)
                zdy2 = e2v(ji,jj) * e2v(ji,jj)
@@ -1012,5 +1063,5 @@
       CASE( 4 )                                                !==  4th order central TIM  ==! (Eq. 27)
          DO jl = 1, jpl
-            DO_2D_10_10
+            DO_2D( 1, 0, 0, 0 )
                zcv  = pv(ji,jj) * r1_e1v(ji,jj) * pdt * r1_e2v(ji,jj)
                zdy2 = e2v(ji,jj) * e2v(ji,jj)
@@ -1025,5 +1076,5 @@
       CASE( 5 )                                                !==  5th order central TIM  ==! (Eq. 29)
          DO jl = 1, jpl
-            DO_2D_10_10
+            DO_2D( 1, 0, 0, 0 )
                zcv  = pv(ji,jj) * r1_e1v(ji,jj) * pdt * r1_e2v(ji,jj)
                zdy2 = e2v(ji,jj) * e2v(ji,jj)
@@ -1046,5 +1097,5 @@
       IF( ll_neg ) THEN
          DO jl = 1, jpl
-            DO_2D_10_10
+            DO_2D( 1, 0, 0, 0 )
                IF( pt_v(ji,jj,jl) < 0._wp .OR. ( jmsk_small(ji,jj,jl) == 0 .AND. pamsk == 0. ) ) THEN
                   pt_v(ji,jj,jl) = 0.5_wp * vmask(ji,jj,1) * (                              ( pt(ji,jj+1,jl) + pt(ji,jj,jl) )  &
@@ -1056,5 +1107,5 @@
       !                                                     !-- High order flux in j-direction  --!
       DO jl = 1, jpl
-         DO_2D_10_10
+         DO_2D( 1, 0, 0, 0 )
             pfv_ho(ji,jj,jl) = pv(ji,jj) * pt_v(ji,jj,jl)
          END_2D
@@ -1092,6 +1143,8 @@
       ! --------------------------------------------------
       DO jl = 1, jpl
-         DO_2D_10_10
+         DO_2D( 0, 0, 1, 0 )
             pfu_ho(ji,jj,jl) = pfu_ho(ji,jj,jl) - pfu_ups(ji,jj,jl)
+         END_2D
+         DO_2D( 1, 0, 0, 0 )
             pfv_ho(ji,jj,jl) = pfv_ho(ji,jj,jl) - pfv_ups(ji,jj,jl)
          END_2D
@@ -1109,13 +1162,13 @@
          
          DO jl = 1, jpl
-            DO_2D_00_00
+            DO_2D( 0, 0, 0, 0 )
                zti_ups(ji,jj,jl)= pt_ups(ji+1,jj  ,jl)
                ztj_ups(ji,jj,jl)= pt_ups(ji  ,jj+1,jl)
             END_2D
          END DO
-         CALL lbc_lnk_multi( 'icedyn_adv_umx', zti_ups, 'T', 1., ztj_ups, 'T', 1. )
-
-         DO jl = 1, jpl
-            DO_2D_00_00
+         CALL lbc_lnk_multi( 'icedyn_adv_umx', zti_ups, 'T', 1.0_wp, ztj_ups, 'T', 1.0_wp )
+
+         DO jl = 1, jpl
+            DO_2D( 0, 0, 0, 0 )
                IF ( pfu_ho(ji,jj,jl) * ( pt_ups(ji+1,jj  ,jl) - pt_ups(ji,jj,jl) ) <= 0._wp .AND.  &
                   & pfv_ho(ji,jj,jl) * ( pt_ups(ji  ,jj+1,jl) - pt_ups(ji,jj,jl) ) <= 0._wp ) THEN
@@ -1136,5 +1189,5 @@
             END_2D
          END DO
-         CALL lbc_lnk_multi( 'icedyn_adv_umx', pfu_ho, 'U', -1., pfv_ho, 'V', -1. )   ! lateral boundary cond.
+         CALL lbc_lnk_multi( 'icedyn_adv_umx', pfu_ho, 'U', -1.0_wp, pfv_ho, 'V', -1.0_wp )   ! lateral boundary cond.
 
       ENDIF
@@ -1146,5 +1199,5 @@
       DO jl = 1, jpl
          
-         DO_2D_11_11
+         DO_2D( 1, 1, 1, 1 )
             IF    ( pt(ji,jj,jl) <= 0._wp .AND. pt_ups(ji,jj,jl) <= 0._wp ) THEN
                zbup(ji,jj) = -zbig
@@ -1162,5 +1215,5 @@
          END_2D
 
-         DO_2D_00_00
+         DO_2D( 0, 0, 0, 0 )
             !
             zup  = MAX( zbup(ji,jj), zbup(ji-1,jj), zbup(ji+1,jj), zbup(ji,jj-1), zbup(ji,jj+1) )  ! search max/min in neighbourhood
@@ -1193,5 +1246,5 @@
          END_2D
       END DO
-      CALL lbc_lnk_multi( 'icedyn_adv_umx', zbetup, 'T', 1., zbetdo, 'T', 1. )   ! lateral boundary cond. (unchanged sign)
+      CALL lbc_lnk_multi( 'icedyn_adv_umx', zbetup, 'T', 1.0_wp, zbetdo, 'T', 1.0_wp )   ! lateral boundary cond. (unchanged sign)
 
       
@@ -1199,5 +1252,5 @@
       ! ---------------------------------
       DO jl = 1, jpl
-         DO_2D_10_10
+         DO_2D( 0, 0, 1, 0 )
             zau = MIN( 1._wp , zbetdo(ji,jj,jl) , zbetup(ji+1,jj,jl) )
             zbu = MIN( 1._wp , zbetup(ji,jj,jl) , zbetdo(ji+1,jj,jl) )
@@ -1210,5 +1263,5 @@
          END_2D
 
-         DO_2D_10_10
+         DO_2D( 1, 0, 0, 0 )
             zav = MIN( 1._wp , zbetdo(ji,jj,jl) , zbetup(ji,jj+1,jl) )
             zbv = MIN( 1._wp , zbetup(ji,jj,jl) , zbetdo(ji,jj+1,jl) )
@@ -1244,12 +1297,12 @@
       !
       DO jl = 1, jpl
-         DO_2D_00_00
+         DO_2D( 0, 0, 0, 0 )
             zslpx(ji,jj,jl) = ( pt(ji+1,jj,jl) - pt(ji,jj,jl) ) * umask(ji,jj,1)
          END_2D
       END DO
-      CALL lbc_lnk( 'icedyn_adv_umx', zslpx, 'U', -1.)   ! lateral boundary cond.
+      CALL lbc_lnk( 'icedyn_adv_umx', zslpx, 'U', -1.0_wp)   ! lateral boundary cond.
       
       DO jl = 1, jpl
-         DO_2D_00_00
+         DO_2D( 0, 0, 0, 0 )
             uCFL = pdt * ABS( pu(ji,jj) ) * r1_e1e2t(ji,jj)
             
@@ -1312,5 +1365,5 @@
          END_2D
       END DO
-      CALL lbc_lnk( 'icedyn_adv_umx', pfu_ho, 'U', -1.)   ! lateral boundary cond.
+      CALL lbc_lnk( 'icedyn_adv_umx', pfu_ho, 'U', -1.0_wp)   ! lateral boundary cond.
       !
    END SUBROUTINE limiter_x
@@ -1335,12 +1388,12 @@
       !
       DO jl = 1, jpl
-         DO_2D_00_00
+         DO_2D( 0, 0, 0, 0 )
             zslpy(ji,jj,jl) = ( pt(ji,jj+1,jl) - pt(ji,jj,jl) ) * vmask(ji,jj,1)
          END_2D
       END DO
-      CALL lbc_lnk( 'icedyn_adv_umx', zslpy, 'V', -1.)   ! lateral boundary cond.
-
-      DO jl = 1, jpl
-         DO_2D_00_00
+      CALL lbc_lnk( 'icedyn_adv_umx', zslpy, 'V', -1.0_wp)   ! lateral boundary cond.
+
+      DO jl = 1, jpl
+         DO_2D( 0, 0, 0, 0 )
             vCFL = pdt * ABS( pv(ji,jj) ) * r1_e1e2t(ji,jj)
 
@@ -1404,10 +1457,11 @@
          END_2D
       END DO
-      CALL lbc_lnk( 'icedyn_adv_umx', pfv_ho, 'V', -1.)   ! lateral boundary cond.
+      CALL lbc_lnk( 'icedyn_adv_umx', pfv_ho, 'V', -1.0_wp)   ! lateral boundary cond.
       !
    END SUBROUTINE limiter_y
 
 
-   SUBROUTINE Hbig( pdt, phi_max, phs_max, phip_max, pv_i, pv_s, pa_i, pa_ip, pv_ip, pe_s )
+   SUBROUTINE Hbig( pdt, phi_max, phs_max, phip_max, psi_max, pes_max, pei_max, &
+      &                  pv_i, pv_s, pa_i, pa_ip, pv_ip, psv_i, pe_s, pe_i )
       !!-------------------------------------------------------------------
       !!                  ***  ROUTINE Hbig  ***
@@ -1423,11 +1477,14 @@
       !! ** input   : Max thickness of the surrounding 9-points
       !!-------------------------------------------------------------------
-      REAL(wp)                    , INTENT(in   ) ::   pdt                          ! tracer time-step
-      REAL(wp), DIMENSION(:,:,:)  , INTENT(in   ) ::   phi_max, phs_max, phip_max   ! max ice thick from surrounding 9-pts
-      REAL(wp), DIMENSION(:,:,:)  , INTENT(inout) ::   pv_i, pv_s, pa_i, pa_ip, pv_ip
+      REAL(wp)                    , INTENT(in   ) ::   pdt                                   ! tracer time-step
+      REAL(wp), DIMENSION(:,:,:)  , INTENT(in   ) ::   phi_max, phs_max, phip_max, psi_max   ! max ice thick from surrounding 9-pts
+      REAL(wp), DIMENSION(:,:,:,:), INTENT(in   ) ::   pes_max
+      REAL(wp), DIMENSION(:,:,:,:), INTENT(in   ) ::   pei_max
+      REAL(wp), DIMENSION(:,:,:)  , INTENT(inout) ::   pv_i, pv_s, pa_i, pa_ip, pv_ip, psv_i
       REAL(wp), DIMENSION(:,:,:,:), INTENT(inout) ::   pe_s
-      !
-      INTEGER  ::   ji, jj, jl         ! dummy loop indices
-      REAL(wp) ::   z1_dt, zhip, zhi, zhs, zfra
+      REAL(wp), DIMENSION(:,:,:,:), INTENT(inout) ::   pe_i
+      !
+      INTEGER  ::   ji, jj, jk, jl         ! dummy loop indices
+      REAL(wp) ::   z1_dt, zhip, zhi, zhs, zsi, zes, zei, zfra
       !!-------------------------------------------------------------------
       !
@@ -1435,11 +1492,10 @@
       !
       DO jl = 1, jpl
-
-         DO_2D_11_11
+         DO_2D( 1, 1, 1, 1 )
             IF ( pv_i(ji,jj,jl) > 0._wp ) THEN
                !
                !                               ! -- check h_ip -- !
                ! if h_ip is larger than the surrounding 9 pts => reduce h_ip and increase a_ip
-               IF( ln_pnd_H12 .AND. pv_ip(ji,jj,jl) > 0._wp ) THEN
+               IF( ln_pnd_LEV .AND. pv_ip(ji,jj,jl) > 0._wp ) THEN
                   zhip = pv_ip(ji,jj,jl) / MAX( epsi20, pa_ip(ji,jj,jl) )
                   IF( zhip > phip_max(ji,jj,jl) .AND. pa_ip(ji,jj,jl) < 0.15 ) THEN
@@ -1468,7 +1524,45 @@
                ENDIF           
                !                  
+               !                               ! -- check s_i -- !
+               ! if s_i is larger than the surrounding 9 pts => put salt excess in the ocean
+               zsi = psv_i(ji,jj,jl) / pv_i(ji,jj,jl)
+               IF( zsi > psi_max(ji,jj,jl) .AND. pa_i(ji,jj,jl) < 0.15 ) THEN
+                  zfra = psi_max(ji,jj,jl) / zsi
+                  sfx_res(ji,jj) = sfx_res(ji,jj) + psv_i(ji,jj,jl) * ( 1._wp - zfra ) * rhoi * z1_dt
+                  psv_i(ji,jj,jl) = psv_i(ji,jj,jl) * zfra
+               ENDIF
+               !
             ENDIF
          END_2D
       END DO 
+      !
+      !                                           ! -- check e_i/v_i -- !
+      DO jl = 1, jpl
+         DO_3D( 1, 1, 1, 1, 1, nlay_i )
+            IF ( pv_i(ji,jj,jl) > 0._wp ) THEN
+               ! if e_i/v_i is larger than the surrounding 9 pts => put the heat excess in the ocean
+               zei = pe_i(ji,jj,jk,jl) / pv_i(ji,jj,jl)
+               IF( zei > pei_max(ji,jj,jk,jl) .AND. pa_i(ji,jj,jl) < 0.15 ) THEN
+                  zfra = pei_max(ji,jj,jk,jl) / zei
+                  hfx_res(ji,jj) = hfx_res(ji,jj) - pe_i(ji,jj,jk,jl) * ( 1._wp - zfra ) * z1_dt ! W.m-2 <0
+                  pe_i(ji,jj,jk,jl) = pe_i(ji,jj,jk,jl) * zfra
+               ENDIF
+            ENDIF
+         END_3D
+      END DO
+      !                                           ! -- check e_s/v_s -- !
+      DO jl = 1, jpl
+         DO_3D( 1, 1, 1, 1, 1, nlay_s )
+            IF ( pv_s(ji,jj,jl) > 0._wp ) THEN
+               ! if e_s/v_s is larger than the surrounding 9 pts => put the heat excess in the ocean
+               zes = pe_s(ji,jj,jk,jl) / pv_s(ji,jj,jl)
+               IF( zes > pes_max(ji,jj,jk,jl) .AND. pa_i(ji,jj,jl) < 0.15 ) THEN
+                  zfra = pes_max(ji,jj,jk,jl) / zes
+                  hfx_res(ji,jj) = hfx_res(ji,jj) - pe_s(ji,jj,jk,jl) * ( 1._wp - zfra ) * z1_dt ! W.m-2 <0
+                  pe_s(ji,jj,jk,jl) = pe_s(ji,jj,jk,jl) * zfra
+               ENDIF
+            ENDIF
+         END_3D
+      END DO
       !
    END SUBROUTINE Hbig
@@ -1502,5 +1596,5 @@
       ! -- check snow load -- !
       DO jl = 1, jpl
-         DO_2D_11_11
+         DO_2D( 1, 1, 1, 1 )
             IF ( pv_i(ji,jj,jl) > 0._wp ) THEN
                !
@@ -1526,4 +1620,54 @@
    END SUBROUTINE Hsnow
 
+   SUBROUTINE icemax3D( pice , pmax )
+      !!---------------------------------------------------------------------
+      !!                   ***  ROUTINE icemax3D ***                     
+      !! ** Purpose :  compute the max of the 9 points around
+      !!----------------------------------------------------------------------
+      REAL(wp), DIMENSION(:,:,:)      , INTENT(in ) ::   pice   ! input
+      REAL(wp), DIMENSION(:,:,:)      , INTENT(out) ::   pmax   ! output
+      REAL(wp), DIMENSION(2:jpim1,jpj)              ::   zmax   ! temporary array
+      INTEGER  ::   ji, jj, jl   ! dummy loop indices
+      !!----------------------------------------------------------------------
+      DO jl = 1, jpl
+         DO jj = Njs0-1, Nje0+1    
+            DO ji = Nis0, Nie0
+               zmax(ji,jj) = MAX( epsi20, pice(ji,jj,jl), pice(ji-1,jj,jl), pice(ji+1,jj,jl) )
+            END DO
+         END DO
+         DO jj = Njs0, Nje0    
+            DO ji = Nis0, Nie0
+               pmax(ji,jj,jl) = MAX( epsi20, zmax(ji,jj), zmax(ji,jj-1), zmax(ji,jj+1) )
+            END DO
+         END DO
+      END DO
+   END SUBROUTINE icemax3D
+
+   SUBROUTINE icemax4D( pice , pmax )
+      !!---------------------------------------------------------------------
+      !!                   ***  ROUTINE icemax4D ***                     
+      !! ** Purpose :  compute the max of the 9 points around
+      !!----------------------------------------------------------------------
+      REAL(wp), DIMENSION(:,:,:,:)    , INTENT(in ) ::   pice   ! input
+      REAL(wp), DIMENSION(:,:,:,:)    , INTENT(out) ::   pmax   ! output
+      REAL(wp), DIMENSION(2:jpim1,jpj)              ::   zmax   ! temporary array
+      INTEGER  ::   jlay, ji, jj, jk, jl   ! dummy loop indices
+      !!----------------------------------------------------------------------
+      jlay = SIZE( pice , 3 )   ! size of input arrays
+      DO jl = 1, jpl
+         DO jk = 1, jlay
+            DO jj = Njs0-1, Nje0+1    
+               DO ji = Nis0, Nie0
+                  zmax(ji,jj) = MAX( epsi20, pice(ji,jj,jk,jl), pice(ji-1,jj,jk,jl), pice(ji+1,jj,jk,jl) )
+               END DO
+            END DO
+            DO jj = Njs0, Nje0    
+               DO ji = Nis0, Nie0
+                  pmax(ji,jj,jk,jl) = MAX( epsi20, zmax(ji,jj), zmax(ji,jj-1), zmax(ji,jj+1) )
+               END DO
+            END DO
+         END DO
+      END DO
+   END SUBROUTINE icemax4D
 
 #else
Index: NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icedyn_rdgrft.F90
===================================================================
--- NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icedyn_rdgrft.F90	(revision 13033)
+++ NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icedyn_rdgrft.F90	(revision 13727)
@@ -161,5 +161,5 @@
       npti = 0   ;   nptidx(:) = 0
       ipti = 0   ;   iptidx(:) = 0
-      DO_2D_11_11
+      DO_2D( 1, 1, 1, 1 )
          IF ( at_i(ji,jj) > epsi10 ) THEN
             npti           = npti + 1
@@ -300,5 +300,13 @@
 
       !                       ! Ice thickness needed for rafting
+      ! In single precision there were floating point invalids due a sqrt of zhi which happens to have negative values
+      ! To solve that an extra check about the value of pv_i was added.
+      ! Although adding this condition is safe, the double definition (one for single other for double) has been kept to preserve the results of the sette test.
+#if defined key_single
+
+      WHERE( pa_i(1:npti,:) > epsi10 .and. pv_i(1:npti,:) > epsi10 )   ;   zhi(1:npti,:) = pv_i(1:npti,:) / pa_i(1:npti,:)
+#else
       WHERE( pa_i(1:npti,:) > epsi10 )   ;   zhi(1:npti,:) = pv_i(1:npti,:) / pa_i(1:npti,:)
+#endif
       ELSEWHERE                          ;   zhi(1:npti,:) = 0._wp
       END WHERE
@@ -341,5 +349,5 @@
                ELSEIF( zGsum(ji,jl-1) < rn_gstar ) THEN
                   apartf(ji,jl) = z1_gstar * ( rn_gstar     - zGsum(ji,jl-1) ) *  &
-                     &                       ( 2._wp - ( zGsum(ji,jl-1) + rn_gstar        ) * z1_gstar )
+                     &                       ( 2._wp - ( zGsum(ji,jl-1) + rn_gstar     ) * z1_gstar )
                ELSE
                   apartf(ji,jl) = 0._wp
@@ -494,6 +502,6 @@
       REAL(wp)                  ::   airdg1, oirdg1, aprdg1, virdg1, sirdg1
       REAL(wp)                  ::   airft1, oirft1, aprft1
-      REAL(wp), DIMENSION(jpij) ::   airdg2, oirdg2, aprdg2, virdg2, sirdg2, vsrdg, vprdg  ! area etc of new ridges
-      REAL(wp), DIMENSION(jpij) ::   airft2, oirft2, aprft2, virft , sirft , vsrft, vprft  ! area etc of rafted ice
+      REAL(wp), DIMENSION(jpij) ::   airdg2, oirdg2, aprdg2, virdg2, sirdg2, vsrdg, vprdg, vlrdg  ! area etc of new ridges
+      REAL(wp), DIMENSION(jpij) ::   airft2, oirft2, aprft2, virft , sirft , vsrft, vprft, vlrft  ! area etc of rafted ice
       !
       REAL(wp), DIMENSION(jpij) ::   ersw             ! enth of water trapped into ridges
@@ -522,5 +530,7 @@
       DO jl1 = 1, jpl
 
-         CALL tab_2d_1d( npti, nptidx(1:npti), s_i_1d(1:npti), s_i(:,:,jl1) )
+         IF( nn_icesal /= 2 )  THEN      
+            CALL tab_2d_1d( npti, nptidx(1:npti), s_i_1d(1:npti), s_i(:,:,jl1) )
+         ENDIF
 
          DO ji = 1, npti
@@ -565,5 +575,5 @@
                oirft2(ji) = oa_i_2d(ji,jl1)   * afrft * hi_hrft 
 
-               IF ( ln_pnd_H12 ) THEN
+               IF ( ln_pnd_LEV ) THEN
                   aprdg1     = a_ip_2d(ji,jl1) * afrdg
                   aprdg2(ji) = a_ip_2d(ji,jl1) * afrdg * hi_hrdg(ji,jl1)
@@ -572,4 +582,8 @@
                   aprft2(ji) = a_ip_2d(ji,jl1) * afrft * hi_hrft
                   vprft (ji) = v_ip_2d(ji,jl1) * afrft
+                  IF ( ln_pnd_lids ) THEN
+                     vlrdg (ji) = v_il_2d(ji,jl1) * afrdg
+                     vlrft (ji) = v_il_2d(ji,jl1) * afrft
+                  ENDIF
                ENDIF
 
@@ -598,7 +612,10 @@
                sv_i_2d(ji,jl1) = sv_i_2d(ji,jl1) - sirdg1    - sirft(ji)
                oa_i_2d(ji,jl1) = oa_i_2d(ji,jl1) - oirdg1    - oirft1
-               IF ( ln_pnd_H12 ) THEN
+               IF ( ln_pnd_LEV ) THEN
                   a_ip_2d(ji,jl1) = a_ip_2d(ji,jl1) - aprdg1    - aprft1
                   v_ip_2d(ji,jl1) = v_ip_2d(ji,jl1) - vprdg(ji) - vprft(ji)
+                  IF ( ln_pnd_lids ) THEN
+                     v_il_2d(ji,jl1) = v_il_2d(ji,jl1) - vlrdg(ji) - vlrft(ji)
+                  ENDIF
                ENDIF
             ENDIF
@@ -692,9 +709,13 @@
                   v_s_2d (ji,jl2) = v_s_2d (ji,jl2) + ( vsrdg (ji) * rn_fsnwrdg * fvol(ji)  +  &
                      &                                  vsrft (ji) * rn_fsnwrft * zswitch(ji) )
-                  IF ( ln_pnd_H12 ) THEN
+                  IF ( ln_pnd_LEV ) THEN
                      v_ip_2d (ji,jl2) = v_ip_2d(ji,jl2) + (   vprdg (ji) * rn_fpndrdg * fvol   (ji)   &
                         &                                   + vprft (ji) * rn_fpndrft * zswitch(ji)   )
                      a_ip_2d (ji,jl2) = a_ip_2d(ji,jl2) + (   aprdg2(ji) * rn_fpndrdg * farea         & 
                         &                                   + aprft2(ji) * rn_fpndrft * zswitch(ji)   )
+                     IF ( ln_pnd_lids ) THEN
+                        v_il_2d (ji,jl2) = v_il_2d(ji,jl2) + (   vlrdg(ji) * rn_fpndrdg * fvol   (ji) &
+                           &                                   + vlrft(ji) * rn_fpndrft * zswitch(ji) )
+                     ENDIF
                   ENDIF
                   
@@ -727,5 +748,5 @@
       !----------------
       ! In case ridging/rafting lead to very small negative values (sometimes it happens)
-      CALL ice_var_roundoff( a_i_2d, v_i_2d, v_s_2d, sv_i_2d, oa_i_2d, a_ip_2d, v_ip_2d, ze_s_2d, ze_i_2d )
+      CALL ice_var_roundoff( a_i_2d, v_i_2d, v_s_2d, sv_i_2d, oa_i_2d, a_ip_2d, v_ip_2d, v_il_2d, ze_s_2d, ze_i_2d )
       !
    END SUBROUTINE rdgrft_shift
@@ -766,5 +787,5 @@
       !                              !--------------------------------------------------!
       CASE( 1 )               !--- Spatial smoothing
-         DO_2D_00_00
+         DO_2D( 0, 0, 0, 0 )
             IF ( SUM( a_i(ji,jj,:) ) > 0._wp ) THEN 
                zworka(ji,jj) = ( 4.0 * strength(ji,jj)              &
@@ -777,8 +798,8 @@
          END_2D
          
-         DO_2D_00_00
+         DO_2D( 0, 0, 0, 0 )
             strength(ji,jj) = zworka(ji,jj)
          END_2D
-         CALL lbc_lnk( 'icedyn_rdgrft', strength, 'T', 1. )
+         CALL lbc_lnk( 'icedyn_rdgrft', strength, 'T', 1.0_wp )
          !
       CASE( 2 )               !--- Temporal smoothing
@@ -788,5 +809,5 @@
          ENDIF
          !
-         DO_2D_00_00
+         DO_2D( 0, 0, 0, 0 )
             IF ( SUM( a_i(ji,jj,:) ) > 0._wp ) THEN 
                itframe = 1 ! number of time steps for the running mean
@@ -799,5 +820,5 @@
             ENDIF
          END_2D
-         CALL lbc_lnk( 'icedyn_rdgrft', strength, 'T', 1. )
+         CALL lbc_lnk( 'icedyn_rdgrft', strength, 'T', 1.0_wp )
          !
       END SELECT
@@ -833,4 +854,5 @@
          CALL tab_3d_2d( npti, nptidx(1:npti), a_ip_2d(1:npti,1:jpl), a_ip(:,:,:) )
          CALL tab_3d_2d( npti, nptidx(1:npti), v_ip_2d(1:npti,1:jpl), v_ip(:,:,:) )
+         CALL tab_3d_2d( npti, nptidx(1:npti), v_il_2d(1:npti,1:jpl), v_il(:,:,:) )
          DO jl = 1, jpl
             DO jk = 1, nlay_s
@@ -859,4 +881,5 @@
          CALL tab_2d_3d( npti, nptidx(1:npti), a_ip_2d(1:npti,1:jpl), a_ip(:,:,:) )
          CALL tab_2d_3d( npti, nptidx(1:npti), v_ip_2d(1:npti,1:jpl), v_ip(:,:,:) )
+         CALL tab_2d_3d( npti, nptidx(1:npti), v_il_2d(1:npti,1:jpl), v_il(:,:,:) )
          DO jl = 1, jpl
             DO jk = 1, nlay_s
Index: NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icedyn_rhg.F90
===================================================================
--- NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icedyn_rhg.F90	(revision 13033)
+++ NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icedyn_rhg.F90	(revision 13727)
@@ -108,5 +108,5 @@
       INTEGER ::   ios, ioptio   ! Local integer output status for namelist read
       !!
-      NAMELIST/namdyn_rhg/  ln_rhg_EVP, ln_aEVP, rn_creepl, rn_ecc , nn_nevp, rn_relast
+      NAMELIST/namdyn_rhg/  ln_rhg_EVP, ln_aEVP, rn_creepl, rn_ecc , nn_nevp, rn_relast, nn_rhg_chkcvg
       !!-------------------------------------------------------------------
       !
@@ -122,10 +122,15 @@
          WRITE(numout,*) '~~~~~~~~~~~~~~~'
          WRITE(numout,*) '   Namelist : namdyn_rhg:'
-         WRITE(numout,*) '      rheology EVP (icedyn_rhg_evp)                        ln_rhg_EVP = ', ln_rhg_EVP
-         WRITE(numout,*) '         use adaptive EVP (aEVP)                           ln_aEVP    = ', ln_aEVP
-         WRITE(numout,*) '         creep limit                                       rn_creepl  = ', rn_creepl
-         WRITE(numout,*) '         eccentricity of the elliptical yield curve        rn_ecc     = ', rn_ecc
-         WRITE(numout,*) '         number of iterations for subcycling               nn_nevp    = ', nn_nevp
-         WRITE(numout,*) '         ratio of elastic timescale over ice time step     rn_relast  = ', rn_relast
+         WRITE(numout,*) '      rheology EVP (icedyn_rhg_evp)                        ln_rhg_EVP    = ', ln_rhg_EVP
+         WRITE(numout,*) '         use adaptive EVP (aEVP)                           ln_aEVP       = ', ln_aEVP
+         WRITE(numout,*) '         creep limit                                       rn_creepl     = ', rn_creepl
+         WRITE(numout,*) '         eccentricity of the elliptical yield curve        rn_ecc        = ', rn_ecc
+         WRITE(numout,*) '         number of iterations for subcycling               nn_nevp       = ', nn_nevp
+         WRITE(numout,*) '         ratio of elastic timescale over ice time step     rn_relast     = ', rn_relast
+         WRITE(numout,*) '      check convergence of rheology                        nn_rhg_chkcvg = ', nn_rhg_chkcvg
+         IF    ( nn_rhg_chkcvg == 0 ) THEN   ;   WRITE(numout,*) '         no check'
+         ELSEIF( nn_rhg_chkcvg == 1 ) THEN   ;   WRITE(numout,*) '         check cvg at the main time step'
+         ELSEIF( nn_rhg_chkcvg == 2 ) THEN   ;   WRITE(numout,*) '         check cvg at both main and rheology time steps'
+         ENDIF
       ENDIF
       !
Index: NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icedyn_rhg_evp.F90
===================================================================
--- NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icedyn_rhg_evp.F90	(revision 13033)
+++ NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icedyn_rhg_evp.F90	(revision 13727)
@@ -41,4 +41,5 @@
    USE prtctl         ! Print control
 
+   USE netcdf         ! NetCDF library for convergence test
    IMPLICIT NONE
    PRIVATE
@@ -49,4 +50,10 @@
    !! * Substitutions
 #  include "do_loop_substitute.h90"
+#  include "domzgr_substitute.h90"
+
+   !! for convergence tests
+   INTEGER ::   ncvgid   ! netcdf file id
+   INTEGER ::   nvarid   ! netcdf variable id
+   REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zmsk00, zmsk15
    !!----------------------------------------------------------------------
    !! NEMO/ICE 4.0 , NEMO Consortium (2018)
@@ -120,16 +127,16 @@
       REAL(wp) ::   ecc2, z1_ecc2                                       ! square of yield ellipse eccenticity
       REAL(wp) ::   zalph1, z1_alph1, zalph2, z1_alph2                  ! alpha coef from Bouillon 2009 or Kimmritz 2017
+      REAl(wp) ::   zbetau, zbetav
       REAL(wp) ::   zm1, zm2, zm3, zmassU, zmassV, zvU, zvV             ! ice/snow mass and volume
-      REAL(wp) ::   zdelta, zp_delf, zds2, zdt, zdt2, zdiv, zdiv2       ! temporary scalars
+      REAL(wp) ::   zp_delf, zds2, zdt, zdt2, zdiv, zdiv2               ! temporary scalars
       REAL(wp) ::   zTauO, zTauB, zRHS, zvel                            ! temporary scalars
       REAL(wp) ::   zkt                                                 ! isotropic tensile strength for landfast ice
       REAL(wp) ::   zvCr                                                ! critical ice volume above which ice is landfast
       !
-      REAL(wp) ::   zresm                                               ! Maximal error on ice velocity
       REAL(wp) ::   zintb, zintn                                        ! dummy argument
       REAL(wp) ::   zfac_x, zfac_y
       REAL(wp) ::   zshear, zdum1, zdum2
       !
-      REAL(wp), DIMENSION(jpi,jpj) ::   zp_delt                         ! P/delta at T points
+      REAL(wp), DIMENSION(jpi,jpj) ::   zdelta, zp_delt                 ! delta and P/delta at T points
       REAL(wp), DIMENSION(jpi,jpj) ::   zbeta                           ! beta coef from Kimmritz 2017
       !
@@ -138,9 +145,9 @@
       REAL(wp), DIMENSION(jpi,jpj) ::   zmU_t, zmV_t                    ! (ice-snow_mass / dt) on U/V points
       REAL(wp), DIMENSION(jpi,jpj) ::   zmf                             ! coriolis parameter at T points
-      REAL(wp), DIMENSION(jpi,jpj) ::   v_oceU, u_oceV, v_iceU, u_iceV  ! ocean/ice u/v component on V/U points                           
+      REAL(wp), DIMENSION(jpi,jpj) ::   v_oceU, u_oceV, v_iceU, u_iceV  ! ocean/ice u/v component on V/U points
       !
       REAL(wp), DIMENSION(jpi,jpj) ::   zds                             ! shear
+      REAL(wp), DIMENSION(jpi,jpj) ::   zten_i                          ! tension
       REAL(wp), DIMENSION(jpi,jpj) ::   zs1, zs2, zs12                  ! stress tensor components
-!!$      REAL(wp), DIMENSION(jpi,jpj) ::   zu_ice, zv_ice, zresr           ! check convergence
       REAL(wp), DIMENSION(jpi,jpj) ::   zsshdyn                         ! array used for the calculation of ice surface slope:
       !                                                                 !    ocean surface (ssh_m) if ice is not embedded
@@ -156,12 +163,14 @@
       REAL(wp), DIMENSION(jpi,jpj) ::   zmsk01x, zmsk01y                ! dummy arrays
       REAL(wp), DIMENSION(jpi,jpj) ::   zmsk00x, zmsk00y                ! mask for ice presence
-      REAL(wp), DIMENSION(jpi,jpj) ::   zfmask, zwf                     ! mask at F points for the ice
+      REAL(wp), DIMENSION(jpi,jpj) ::   zfmask                          ! mask at F points for the ice
 
       REAL(wp), PARAMETER          ::   zepsi  = 1.0e-20_wp             ! tolerance parameter
       REAL(wp), PARAMETER          ::   zmmin  = 1._wp                  ! ice mass (kg/m2)  below which ice velocity becomes very small
       REAL(wp), PARAMETER          ::   zamin  = 0.001_wp               ! ice concentration below which ice velocity becomes very small
+      !! --- check convergence
+      REAL(wp), DIMENSION(jpi,jpj) ::   zu_ice, zv_ice
       !! --- diags
-      REAL(wp), DIMENSION(jpi,jpj) ::   zmsk00
-      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zsig1, zsig2, zsig3
+      REAL(wp) ::   zsig1, zsig2, zsig12, zfac, z1_strength
+      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zsig_I, zsig_II, zsig1_p, zsig2_p         
       !! --- SIMIP diags
       REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zdiag_xmtrp_ice ! X-component of ice mass transport (kg/s)
@@ -175,10 +184,17 @@
       IF( kt == nit000 .AND. lwp )   WRITE(numout,*) '-- ice_dyn_rhg_evp: EVP sea-ice rheology'
       !
-!!gm for Clem:  OPTIMIZATION:  I think zfmask can be computed one for all at the initialization....
+      ! for diagnostics and convergence tests
+      ALLOCATE( zmsk00(jpi,jpj), zmsk15(jpi,jpj) )
+      DO_2D( 1, 1, 1, 1 )
+         zmsk00(ji,jj) = MAX( 0._wp , SIGN( 1._wp , at_i(ji,jj) - epsi06  ) ) ! 1 if ice    , 0 if no ice
+         zmsk15(ji,jj) = MAX( 0._wp , SIGN( 1._wp , at_i(ji,jj) - 0.15_wp ) ) ! 1 if 15% ice, 0 if less
+      END_2D
+      !
+      !!gm for Clem:  OPTIMIZATION:  I think zfmask can be computed one for all at the initialization....
       !------------------------------------------------------------------------------!
       ! 0) mask at F points for the ice
       !------------------------------------------------------------------------------!
       ! ocean/land mask
-      DO_2D_10_10
+      DO_2D( 1, 0, 1, 0 )
          zfmask(ji,jj) = tmask(ji,jj,1) * tmask(ji+1,jj,1) * tmask(ji,jj+1,1) * tmask(ji+1,jj+1,1)
       END_2D
@@ -186,24 +202,24 @@
 
       ! Lateral boundary conditions on velocity (modify zfmask)
-      zwf(:,:) = zfmask(:,:)
-      DO_2D_00_00
+      DO_2D( 0, 0, 0, 0 )
          IF( zfmask(ji,jj) == 0._wp ) THEN
-            zfmask(ji,jj) = rn_ishlat * MIN( 1._wp , MAX( zwf(ji+1,jj), zwf(ji,jj+1), zwf(ji-1,jj), zwf(ji,jj-1) ) )
+            zfmask(ji,jj) = rn_ishlat * MIN( 1._wp , MAX( umask(ji,jj,1), umask(ji,jj+1,1), &
+               &                                          vmask(ji,jj,1), vmask(ji+1,jj,1) ) )
          ENDIF
       END_2D
       DO jj = 2, jpjm1
          IF( zfmask(1,jj) == 0._wp ) THEN
-            zfmask(1  ,jj) = rn_ishlat * MIN( 1._wp , MAX( zwf(2,jj), zwf(1,jj+1), zwf(1,jj-1) ) )
+            zfmask(1  ,jj) = rn_ishlat * MIN( 1._wp , MAX( vmask(2,jj,1), umask(1,jj+1,1), umask(1,jj,1) ) )
          ENDIF
          IF( zfmask(jpi,jj) == 0._wp ) THEN
-            zfmask(jpi,jj) = rn_ishlat * MIN( 1._wp , MAX( zwf(jpi,jj+1), zwf(jpim1,jj), zwf(jpi,jj-1) ) )
-         ENDIF
+            zfmask(jpi,jj) = rn_ishlat * MIN( 1._wp , MAX( umask(jpi,jj+1,1), vmask(jpim1,jj,1), umask(jpi,jj-1,1) ) )
+        ENDIF
       END DO
       DO ji = 2, jpim1
          IF( zfmask(ji,1) == 0._wp ) THEN
-            zfmask(ji,1  ) = rn_ishlat * MIN( 1._wp , MAX( zwf(ji+1,1), zwf(ji,2), zwf(ji-1,1) ) )
+            zfmask(ji, 1 ) = rn_ishlat * MIN( 1._wp , MAX( vmask(ji+1,1,1), umask(ji,2,1), vmask(ji,1,1) ) )
          ENDIF
          IF( zfmask(ji,jpj) == 0._wp ) THEN
-            zfmask(ji,jpj) = rn_ishlat * MIN( 1._wp , MAX( zwf(ji+1,jpj), zwf(ji-1,jpj), zwf(ji,jpjm1) ) )
+            zfmask(ji,jpj) = rn_ishlat * MIN( 1._wp , MAX( vmask(ji+1,jpj,1), vmask(ji-1,jpj,1), umask(ji,jpjm1,1) ) )
          ENDIF
       END DO
@@ -219,16 +235,17 @@
       z1_ecc2 = 1._wp / ecc2
 
-      ! Time step for subcycling
-      zdtevp   = rDt_ice / REAL( nn_nevp )
-      z1_dtevp = 1._wp / zdtevp
-
       ! alpha parameters (Bouillon 2009)
       IF( .NOT. ln_aEVP ) THEN
-         zalph1 = ( 2._wp * rn_relast * rDt_ice ) * z1_dtevp
+         zdtevp   = rDt_ice / REAL( nn_nevp )
+         zalph1 =   2._wp * rn_relast * REAL( nn_nevp )
          zalph2 = zalph1 * z1_ecc2
 
          z1_alph1 = 1._wp / ( zalph1 + 1._wp )
          z1_alph2 = 1._wp / ( zalph2 + 1._wp )
-      ENDIF
+      ELSE
+         zdtevp   = rdt_ice
+         ! zalpha parameters set later on adaptatively
+      ENDIF
+      z1_dtevp = 1._wp / zdtevp
          
       ! Initialise stress tensor 
@@ -241,5 +258,5 @@
 
       ! landfast param from Lemieux(2016): add isotropic tensile strength (following Konig Beatty and Holland, 2010)
-      IF( ln_landfast_L16 ) THEN   ;   zkt = rn_tensile
+      IF( ln_landfast_L16 ) THEN   ;   zkt = rn_lf_tensile
       ELSE                         ;   zkt = 0._wp
       ENDIF
@@ -253,5 +270,5 @@
       zsshdyn(:,:) = ice_var_sshdyn( ssh_m, snwice_mass, snwice_mass_b)
 
-      DO_2D_00_00
+      DO_2D( 0, 0, 0, 0 )
 
          ! ice fraction at U-V points
@@ -299,27 +316,27 @@
 
       END_2D
-      CALL lbc_lnk_multi( 'icedyn_rhg_evp', zmf, 'T', 1., zdt_m, 'T', 1. )
+      CALL lbc_lnk_multi( 'icedyn_rhg_evp', zmf, 'T', 1.0_wp, zdt_m, 'T', 1.0_wp )
       !
       !                                  !== Landfast ice parameterization ==!
       !
       IF( ln_landfast_L16 ) THEN         !-- Lemieux 2016
-         DO_2D_00_00
+         DO_2D( 0, 0, 0, 0 )
             ! ice thickness at U-V points
             zvU = 0.5_wp * ( vt_i(ji,jj) * e1e2t(ji,jj) + vt_i(ji+1,jj) * e1e2t(ji+1,jj) ) * r1_e1e2u(ji,jj) * umask(ji,jj,1)
             zvV = 0.5_wp * ( vt_i(ji,jj) * e1e2t(ji,jj) + vt_i(ji,jj+1) * e1e2t(ji,jj+1) ) * r1_e1e2v(ji,jj) * vmask(ji,jj,1)
             ! ice-bottom stress at U points
-            zvCr = zaU(ji,jj) * rn_depfra * hu(ji,jj,Kmm)
-            ztaux_base(ji,jj) = - rn_icebfr * MAX( 0._wp, zvU - zvCr ) * EXP( -rn_crhg * ( 1._wp - zaU(ji,jj) ) )
+            zvCr = zaU(ji,jj) * rn_lf_depfra * hu(ji,jj,Kmm)
+            ztaux_base(ji,jj) = - rn_lf_bfr * MAX( 0._wp, zvU - zvCr ) * EXP( -rn_crhg * ( 1._wp - zaU(ji,jj) ) )
             ! ice-bottom stress at V points
-            zvCr = zaV(ji,jj) * rn_depfra * hv(ji,jj,Kmm)
-            ztauy_base(ji,jj) = - rn_icebfr * MAX( 0._wp, zvV - zvCr ) * EXP( -rn_crhg * ( 1._wp - zaV(ji,jj) ) )
+            zvCr = zaV(ji,jj) * rn_lf_depfra * hv(ji,jj,Kmm)
+            ztauy_base(ji,jj) = - rn_lf_bfr * MAX( 0._wp, zvV - zvCr ) * EXP( -rn_crhg * ( 1._wp - zaV(ji,jj) ) )
             ! ice_bottom stress at T points
-            zvCr = at_i(ji,jj) * rn_depfra * ht(ji,jj)
-            tau_icebfr(ji,jj) = - rn_icebfr * MAX( 0._wp, vt_i(ji,jj) - zvCr ) * EXP( -rn_crhg * ( 1._wp - at_i(ji,jj) ) )
+            zvCr = at_i(ji,jj) * rn_lf_depfra * ht(ji,jj)
+            tau_icebfr(ji,jj) = - rn_lf_bfr * MAX( 0._wp, vt_i(ji,jj) - zvCr ) * EXP( -rn_crhg * ( 1._wp - at_i(ji,jj) ) )
          END_2D
-         CALL lbc_lnk( 'icedyn_rhg_evp', tau_icebfr(:,:), 'T', 1. )
+         CALL lbc_lnk( 'icedyn_rhg_evp', tau_icebfr(:,:), 'T', 1.0_wp )
          !
       ELSE                               !-- no landfast
-         DO_2D_00_00
+         DO_2D( 0, 0, 0, 0 )
             ztaux_base(ji,jj) = 0._wp
             ztauy_base(ji,jj) = 0._wp
@@ -336,13 +353,14 @@
          l_full_nf_update = jter == nn_nevp   ! false: disable full North fold update (performances) for iter = 1 to nn_nevp-1
          !
-!!$         IF(sn_cfctl%l_prtctl) THEN   ! Convergence test
-!!$            DO jj = 1, jpjm1
-!!$               zu_ice(:,jj) = u_ice(:,jj) ! velocity at previous time step
-!!$               zv_ice(:,jj) = v_ice(:,jj)
-!!$            END DO
-!!$         ENDIF
+         ! convergence test
+         IF( nn_rhg_chkcvg == 1 .OR. nn_rhg_chkcvg == 2  ) THEN
+            DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
+               zu_ice(ji,jj) = u_ice(ji,jj) * umask(ji,jj,1) ! velocity at previous time step
+               zv_ice(ji,jj) = v_ice(ji,jj) * vmask(ji,jj,1)
+            END_2D
+         ENDIF
 
          ! --- divergence, tension & shear (Appendix B of Hunke & Dukowicz, 2002) --- !
-         DO_2D_10_10
+         DO_2D( 1, 0, 1, 0 )
 
             ! shear at F points
@@ -352,7 +370,6 @@
 
          END_2D
-         CALL lbc_lnk( 'icedyn_rhg_evp', zds, 'F', 1. )
-
-         DO_2D_01_01
+
+         DO_2D( 0, 0, 0, 0 )
 
             ! shear**2 at T points (doc eq. A16)
@@ -374,10 +391,27 @@
             
             ! delta at T points
-            zdelta = SQRT( zdiv2 + ( zdt2 + zds2 ) * z1_ecc2 )  
-
-            ! P/delta at T points
-            zp_delt(ji,jj) = strength(ji,jj) / ( zdelta + rn_creepl )
-
-            ! alpha & beta for aEVP
+            zdelta(ji,jj) = SQRT( zdiv2 + ( zdt2 + zds2 ) * z1_ecc2 )  
+
+         END_2D
+         CALL lbc_lnk( 'icedyn_rhg_evp', zdelta, 'T', 1.0_wp )
+
+         ! P/delta at T points
+         DO_2D( 1, 1, 1, 1 )
+            zp_delt(ji,jj) = strength(ji,jj) / ( zdelta(ji,jj) + rn_creepl )
+         END_2D
+
+         DO_2D( 0, 1, 0, 1 )   ! loop ends at jpi,jpj so that no lbc_lnk are needed for zs1 and zs2
+
+            ! divergence at T points (duplication to avoid communications)
+            zdiv  = ( e2u(ji,jj) * u_ice(ji,jj) - e2u(ji-1,jj) * u_ice(ji-1,jj)   &
+               &    + e1v(ji,jj) * v_ice(ji,jj) - e1v(ji,jj-1) * v_ice(ji,jj-1)   &
+               &    ) * r1_e1e2t(ji,jj)
+            
+            ! tension at T points (duplication to avoid communications)
+            zdt  = ( ( u_ice(ji,jj) * r1_e2u(ji,jj) - u_ice(ji-1,jj) * r1_e2u(ji-1,jj) ) * e2t(ji,jj) * e2t(ji,jj)   &
+               &   - ( v_ice(ji,jj) * r1_e1v(ji,jj) - v_ice(ji,jj-1) * r1_e1v(ji,jj-1) ) * e1t(ji,jj) * e1t(ji,jj)   &
+               &   ) * r1_e1e2t(ji,jj)
+            
+            ! alpha for aEVP
             !   gamma = 0.5*P/(delta+creepl) * (c*pi)**2/Area * dt/m
             !   alpha = beta = sqrt(4*gamma)
@@ -387,20 +421,33 @@
                zalph2   = zalph1
                z1_alph2 = z1_alph1
+               ! explicit:
+               ! z1_alph1 = 1._wp / zalph1
+               ! z1_alph2 = 1._wp / zalph1
+               ! zalph1 = zalph1 - 1._wp
+               ! zalph2 = zalph1
             ENDIF
             
             ! stress at T points (zkt/=0 if landfast)
-            zs1(ji,jj) = ( zs1(ji,jj) * zalph1 + zp_delt(ji,jj) * ( zdiv * (1._wp + zkt) - zdelta * (1._wp - zkt) ) ) * z1_alph1
-            zs2(ji,jj) = ( zs2(ji,jj) * zalph2 + zp_delt(ji,jj) * ( zdt * z1_ecc2 * (1._wp + zkt) ) ) * z1_alph2
+            zs1(ji,jj) = ( zs1(ji,jj)*zalph1 + zp_delt(ji,jj) * ( zdiv*(1._wp + zkt) - zdelta(ji,jj)*(1._wp - zkt) ) ) * z1_alph1
+            zs2(ji,jj) = ( zs2(ji,jj)*zalph2 + zp_delt(ji,jj) * ( zdt * z1_ecc2 * (1._wp + zkt) ) ) * z1_alph2
           
          END_2D
-         CALL lbc_lnk( 'icedyn_rhg_evp', zp_delt, 'T', 1. )
-
-         DO_2D_10_10
-
-            ! alpha & beta for aEVP
+
+         ! Save beta at T-points for further computations
+         IF( ln_aEVP ) THEN
+            DO_2D( 1, 1, 1, 1 )
+               zbeta(ji,jj) = MAX( 50._wp, rpi * SQRT( 0.5_wp * zp_delt(ji,jj) * r1_e1e2t(ji,jj) * zdt_m(ji,jj) ) )
+            END_2D
+         ENDIF
+         
+         DO_2D( 1, 0, 1, 0 )
+
+            ! alpha for aEVP
             IF( ln_aEVP ) THEN
-               zalph2   = MAX( 50._wp, rpi * SQRT( 0.5_wp * zp_delt(ji,jj) * r1_e1e2t(ji,jj) * zdt_m(ji,jj) ) )
+               zalph2   = MAX( zbeta(ji,jj), zbeta(ji+1,jj), zbeta(ji,jj+1), zbeta(ji+1,jj+1) )
                z1_alph2 = 1._wp / ( zalph2 + 1._wp )
-               zbeta(ji,jj) = zalph2
+               ! explicit:
+               ! z1_alph2 = 1._wp / zalph2
+               ! zalph2 = zalph2 - 1._wp
             ENDIF
             
@@ -414,5 +461,5 @@
 
          ! --- Ice internal stresses (Appendix C of Hunke and Dukowicz, 2002) --- !
-         DO_2D_00_00
+         DO_2D( 0, 0, 0, 0 )
             !                   !--- U points
             zfU(ji,jj) = 0.5_wp * ( ( zs1(ji+1,jj) - zs1(ji,jj) ) * e2u(ji,jj)                                             &
@@ -442,5 +489,5 @@
          IF( MOD(jter,2) == 0 ) THEN ! even iterations
             !
-            DO_2D_00_00
+            DO_2D( 0, 0, 0, 0 )
                !                 !--- tau_io/(v_oce - v_ice)
                zTauO = zaV(ji,jj) * zrhoco * SQRT( ( v_ice (ji,jj) - v_oce (ji,jj) ) * ( v_ice (ji,jj) - v_oce (ji,jj) )  &
@@ -468,20 +515,23 @@
                !
                IF( ln_aEVP ) THEN !--- ice velocity using aEVP (Kimmritz et al 2016 & 2017)
-                  v_ice(ji,jj) = ( (          rswitch * ( zmV_t(ji,jj) * ( zbeta(ji,jj) * v_ice(ji,jj) + v_ice_b(ji,jj) )       & ! previous velocity
-                     &                                  + zRHS + zTauO * v_ice(ji,jj) )                                         & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
-                     &                                  / MAX( zepsi, zmV_t(ji,jj) * ( zbeta(ji,jj) + 1._wp ) + zTauO - zTauB ) & ! m/dt + tau_io(only ice part) + landfast
-                     &               + ( 1._wp - rswitch ) * v_ice(ji,jj) * MAX( 0._wp, 1._wp - zdtevp * rn_lfrelax )           & ! static friction => slow decrease to v=0
-                     &             ) * zmsk01y(ji,jj) + v_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01y(ji,jj) )                     & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin
+                  zbetav = MAX( zbeta(ji,jj), zbeta(ji,jj+1) )
+                  v_ice(ji,jj) = ( (          rswitch   * ( zmV_t(ji,jj) * ( zbetav * v_ice(ji,jj) + v_ice_b(ji,jj) )         & ! previous velocity
+                     &                                    + zRHS + zTauO * v_ice(ji,jj)                                       & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
+                     &                                    ) / MAX( zepsi, zmV_t(ji,jj) * ( zbetav + 1._wp ) + zTauO - zTauB ) & ! m/dt + tau_io(only ice part) + landfast
+                     &            + ( 1._wp - rswitch ) * (  v_ice_b(ji,jj)                                                   & 
+                     &                                     + v_ice  (ji,jj) * MAX( 0._wp, zbetav - zdtevp * rn_lf_relax )     & ! static friction => slow decrease to v=0
+                     &                                    ) / ( zbetav + 1._wp )                                              &
+                     &             ) * zmsk01y(ji,jj) + v_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01y(ji,jj) )                   & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin
                      &           )   * zmsk00y(ji,jj)
                ELSE               !--- ice velocity using EVP implicit formulation (cf Madec doc & Bouillon 2009)
-                  v_ice(ji,jj) = ( (           rswitch   * ( zmV_t(ji,jj)  * v_ice(ji,jj)                                       & ! previous velocity
-                     &                                     + zRHS + zTauO * v_ice(ji,jj) )                                      & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
-                     &                                     / MAX( zepsi, zmV_t(ji,jj) + zTauO - zTauB )                         & ! m/dt + tau_io(only ice part) + landfast
-                     &                + ( 1._wp - rswitch ) * v_ice(ji,jj) * MAX( 0._wp, 1._wp - zdtevp * rn_lfrelax )          & ! static friction => slow decrease to v=0
-                     &              ) * zmsk01y(ji,jj) + v_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01y(ji,jj) )                    & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin
-                     &            )   * zmsk00y(ji,jj)
+                  v_ice(ji,jj) = ( (          rswitch   * ( zmV_t(ji,jj) * v_ice(ji,jj)                                       & ! previous velocity
+                     &                                    + zRHS + zTauO * v_ice(ji,jj)                                       & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
+                     &                                    ) / MAX( zepsi, zmV_t(ji,jj) + zTauO - zTauB )                      & ! m/dt + tau_io(only ice part) + landfast
+                     &            + ( 1._wp - rswitch ) *   v_ice(ji,jj) * MAX( 0._wp, 1._wp - zdtevp * rn_lf_relax )         & ! static friction => slow decrease to v=0
+                     &             ) * zmsk01y(ji,jj) + v_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01y(ji,jj) )                   & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin
+                     &            )  * zmsk00y(ji,jj)
                ENDIF
             END_2D
-            CALL lbc_lnk( 'icedyn_rhg_evp', v_ice, 'V', -1. )
+            CALL lbc_lnk( 'icedyn_rhg_evp', v_ice, 'V', -1.0_wp )
             !
 #if defined key_agrif
@@ -491,5 +541,5 @@
             IF( ln_bdy )   CALL bdy_ice_dyn( 'V' )
             !
-            DO_2D_00_00
+            DO_2D( 0, 0, 0, 0 )
                !                 !--- tau_io/(u_oce - u_ice)
                zTauO = zaU(ji,jj) * zrhoco * SQRT( ( u_ice (ji,jj) - u_oce (ji,jj) ) * ( u_ice (ji,jj) - u_oce (ji,jj) )  &
@@ -517,20 +567,23 @@
                !
                IF( ln_aEVP ) THEN !--- ice velocity using aEVP (Kimmritz et al 2016 & 2017)
-                  u_ice(ji,jj) = ( (          rswitch * ( zmU_t(ji,jj) * ( zbeta(ji,jj) * u_ice(ji,jj) + u_ice_b(ji,jj) )       & ! previous velocity
-                     &                                  + zRHS + zTauO * u_ice(ji,jj) )                                         & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
-                     &                                  / MAX( zepsi, zmU_t(ji,jj) * ( zbeta(ji,jj) + 1._wp ) + zTauO - zTauB ) & ! m/dt + tau_io(only ice part) + landfast
-                     &               + ( 1._wp - rswitch ) * u_ice(ji,jj) * MAX( 0._wp, 1._wp - zdtevp * rn_lfrelax )           & ! static friction => slow decrease to v=0
-                     &             ) * zmsk01x(ji,jj) + u_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01x(ji,jj) )                     & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin 
+                  zbetau = MAX( zbeta(ji,jj), zbeta(ji+1,jj) )
+                  u_ice(ji,jj) = ( (          rswitch   * ( zmU_t(ji,jj) * ( zbetau * u_ice(ji,jj) + u_ice_b(ji,jj) )         & ! previous velocity
+                     &                                    + zRHS + zTauO * u_ice(ji,jj)                                       & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
+                     &                                    ) / MAX( zepsi, zmU_t(ji,jj) * ( zbetau + 1._wp ) + zTauO - zTauB ) & ! m/dt + tau_io(only ice part) + landfast
+                     &            + ( 1._wp - rswitch ) * (  u_ice_b(ji,jj)                                                   &
+                     &                                     + u_ice  (ji,jj) * MAX( 0._wp, zbetau - zdtevp * rn_lf_relax )     & ! static friction => slow decrease to v=0
+                     &                                    ) / ( zbetau + 1._wp )                                              &
+                     &             ) * zmsk01x(ji,jj) + u_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01x(ji,jj) )                   & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin 
                      &           )   * zmsk00x(ji,jj)
                ELSE               !--- ice velocity using EVP implicit formulation (cf Madec doc & Bouillon 2009)
-                  u_ice(ji,jj) = ( (           rswitch   * ( zmU_t(ji,jj)  * u_ice(ji,jj)                                       & ! previous velocity
-                     &                                     + zRHS + zTauO * u_ice(ji,jj) )                                      & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
-                     &                                     / MAX( zepsi, zmU_t(ji,jj) + zTauO - zTauB )                         & ! m/dt + tau_io(only ice part) + landfast
-                     &                + ( 1._wp - rswitch ) * u_ice(ji,jj) * MAX( 0._wp, 1._wp - zdtevp * rn_lfrelax )          & ! static friction => slow decrease to v=0
-                     &              ) * zmsk01x(ji,jj) + u_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01x(ji,jj) )                    & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin 
-                     &            )   * zmsk00x(ji,jj)
+                  u_ice(ji,jj) = ( (          rswitch   * ( zmU_t(ji,jj) * u_ice(ji,jj)                                       & ! previous velocity
+                     &                                    + zRHS + zTauO * u_ice(ji,jj)                                       & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
+                     &                                    ) / MAX( zepsi, zmU_t(ji,jj) + zTauO - zTauB )                      & ! m/dt + tau_io(only ice part) + landfast
+                     &            + ( 1._wp - rswitch ) *   u_ice(ji,jj) * MAX( 0._wp, 1._wp - zdtevp * rn_lf_relax )         & ! static friction => slow decrease to v=0
+                     &             ) * zmsk01x(ji,jj) + u_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01x(ji,jj) )                   & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin 
+                     &           )   * zmsk00x(ji,jj)
                ENDIF
             END_2D
-            CALL lbc_lnk( 'icedyn_rhg_evp', u_ice, 'U', -1. )
+            CALL lbc_lnk( 'icedyn_rhg_evp', u_ice, 'U', -1.0_wp )
             !
 #if defined key_agrif
@@ -542,5 +595,5 @@
          ELSE ! odd iterations
             !
-            DO_2D_00_00
+            DO_2D( 0, 0, 0, 0 )
                !                 !--- tau_io/(u_oce - u_ice)
                zTauO = zaU(ji,jj) * zrhoco * SQRT( ( u_ice (ji,jj) - u_oce (ji,jj) ) * ( u_ice (ji,jj) - u_oce (ji,jj) )  &
@@ -568,20 +621,23 @@
                !
                IF( ln_aEVP ) THEN !--- ice velocity using aEVP (Kimmritz et al 2016 & 2017)
-                  u_ice(ji,jj) = ( (          rswitch * ( zmU_t(ji,jj) * ( zbeta(ji,jj) * u_ice(ji,jj) + u_ice_b(ji,jj) )       & ! previous velocity
-                     &                                  + zRHS + zTauO * u_ice(ji,jj) )                                         & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
-                     &                                  / MAX( zepsi, zmU_t(ji,jj) * ( zbeta(ji,jj) + 1._wp ) + zTauO - zTauB ) & ! m/dt + tau_io(only ice part) + landfast
-                     &               + ( 1._wp - rswitch ) * u_ice(ji,jj) * MAX( 0._wp, 1._wp - zdtevp * rn_lfrelax )           & ! static friction => slow decrease to v=0
-                     &             ) * zmsk01x(ji,jj) + u_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01x(ji,jj) )                     & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin 
+                  zbetau = MAX( zbeta(ji,jj), zbeta(ji+1,jj) )
+                  u_ice(ji,jj) = ( (          rswitch   * ( zmU_t(ji,jj) * ( zbetau * u_ice(ji,jj) + u_ice_b(ji,jj) )         & ! previous velocity
+                     &                                    + zRHS + zTauO * u_ice(ji,jj)                                       & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
+                     &                                    ) / MAX( zepsi, zmU_t(ji,jj) * ( zbetau + 1._wp ) + zTauO - zTauB ) & ! m/dt + tau_io(only ice part) + landfast
+                     &            + ( 1._wp - rswitch ) * (  u_ice_b(ji,jj)                                                   &
+                     &                                     + u_ice  (ji,jj) * MAX( 0._wp, zbetau - zdtevp * rn_lf_relax )     & ! static friction => slow decrease to v=0
+                     &                                    ) / ( zbetau + 1._wp )                                              &
+                     &             ) * zmsk01x(ji,jj) + u_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01x(ji,jj) )                   & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin 
                      &           )   * zmsk00x(ji,jj)
                ELSE               !--- ice velocity using EVP implicit formulation (cf Madec doc & Bouillon 2009)
-                  u_ice(ji,jj) = ( (           rswitch   * ( zmU_t(ji,jj)  * u_ice(ji,jj)                                       & ! previous velocity
-                     &                                     + zRHS + zTauO * u_ice(ji,jj) )                                      & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
-                     &                                     / MAX( zepsi, zmU_t(ji,jj) + zTauO - zTauB )                         & ! m/dt + tau_io(only ice part) + landfast
-                     &                + ( 1._wp - rswitch ) * u_ice(ji,jj) * MAX( 0._wp, 1._wp - zdtevp * rn_lfrelax )          & ! static friction => slow decrease to v=0
-                     &              ) * zmsk01x(ji,jj) + u_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01x(ji,jj) )                    & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin
-                     &            )   * zmsk00x(ji,jj)
+                  u_ice(ji,jj) = ( (          rswitch   * ( zmU_t(ji,jj) * u_ice(ji,jj)                                       & ! previous velocity
+                     &                                    + zRHS + zTauO * u_ice(ji,jj)                                       & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
+                     &                                    ) / MAX( zepsi, zmU_t(ji,jj) + zTauO - zTauB )                      & ! m/dt + tau_io(only ice part) + landfast
+                     &            + ( 1._wp - rswitch ) *   u_ice(ji,jj) * MAX( 0._wp, 1._wp - zdtevp * rn_lf_relax )         & ! static friction => slow decrease to v=0
+                     &             ) * zmsk01x(ji,jj) + u_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01x(ji,jj) )                   & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin
+                     &           )   * zmsk00x(ji,jj)
                ENDIF
             END_2D
-            CALL lbc_lnk( 'icedyn_rhg_evp', u_ice, 'U', -1. )
+            CALL lbc_lnk( 'icedyn_rhg_evp', u_ice, 'U', -1.0_wp )
             !
 #if defined key_agrif
@@ -591,5 +647,5 @@
             IF( ln_bdy )   CALL bdy_ice_dyn( 'U' )
             !
-            DO_2D_00_00
+            DO_2D( 0, 0, 0, 0 )
                !                 !--- tau_io/(v_oce - v_ice)
                zTauO = zaV(ji,jj) * zrhoco * SQRT( ( v_ice (ji,jj) - v_oce (ji,jj) ) * ( v_ice (ji,jj) - v_oce (ji,jj) )  &
@@ -617,20 +673,23 @@
                !
                IF( ln_aEVP ) THEN !--- ice velocity using aEVP (Kimmritz et al 2016 & 2017)
-                  v_ice(ji,jj) = ( (          rswitch * ( zmV_t(ji,jj) * ( zbeta(ji,jj) * v_ice(ji,jj) + v_ice_b(ji,jj) )       & ! previous velocity
-                     &                                  + zRHS + zTauO * v_ice(ji,jj) )                                         & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
-                     &                                  / MAX( zepsi, zmV_t(ji,jj) * ( zbeta(ji,jj) + 1._wp ) + zTauO - zTauB ) & ! m/dt + tau_io(only ice part) + landfast
-                     &               + ( 1._wp - rswitch ) * v_ice(ji,jj) * MAX( 0._wp, 1._wp - zdtevp * rn_lfrelax )           & ! static friction => slow decrease to v=0
-                     &             ) * zmsk01y(ji,jj) + v_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01y(ji,jj) )                     & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin
+                  zbetav = MAX( zbeta(ji,jj), zbeta(ji,jj+1) )
+                  v_ice(ji,jj) = ( (          rswitch   * ( zmV_t(ji,jj) * ( zbetav * v_ice(ji,jj) + v_ice_b(ji,jj) )         & ! previous velocity
+                     &                                    + zRHS + zTauO * v_ice(ji,jj)                                       & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
+                     &                                    ) / MAX( zepsi, zmV_t(ji,jj) * ( zbetav + 1._wp ) + zTauO - zTauB ) & ! m/dt + tau_io(only ice part) + landfast
+                     &            + ( 1._wp - rswitch ) * (  v_ice_b(ji,jj)                                                   &
+                     &                                     + v_ice  (ji,jj) * MAX( 0._wp, zbetav - zdtevp * rn_lf_relax )     & ! static friction => slow decrease to v=0
+                     &                                    ) / ( zbetav + 1._wp )                                              & 
+                     &             ) * zmsk01y(ji,jj) + v_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01y(ji,jj) )                   & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin
                      &           )   * zmsk00y(ji,jj)
                ELSE               !--- ice velocity using EVP implicit formulation (cf Madec doc & Bouillon 2009)
-                  v_ice(ji,jj) = ( (           rswitch   * ( zmV_t(ji,jj)  * v_ice(ji,jj)                                       & ! previous velocity
-                     &                                     + zRHS + zTauO * v_ice(ji,jj) )                                      & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
-                     &                                     / MAX( zepsi, zmV_t(ji,jj) + zTauO - zTauB )                         & ! m/dt + tau_io(only ice part) + landfast
-                     &                + ( 1._wp - rswitch ) * v_ice(ji,jj) * MAX( 0._wp, 1._wp - zdtevp * rn_lfrelax )          & ! static friction => slow decrease to v=0
-                     &              ) * zmsk01y(ji,jj) + v_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01y(ji,jj) )                    & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin
-                     &            )   * zmsk00y(ji,jj)
+                  v_ice(ji,jj) = ( (          rswitch   * ( zmV_t(ji,jj) * v_ice(ji,jj)                                       & ! previous velocity
+                     &                                    + zRHS + zTauO * v_ice(ji,jj)                                       & ! F + tau_ia + Coriolis + spg + tau_io(only ocean part)
+                     &                                    ) / MAX( zepsi, zmV_t(ji,jj) + zTauO - zTauB )                      & ! m/dt + tau_io(only ice part) + landfast
+                     &            + ( 1._wp - rswitch ) *   v_ice(ji,jj) * MAX( 0._wp, 1._wp - zdtevp * rn_lf_relax )         & ! static friction => slow decrease to v=0
+                     &             ) * zmsk01y(ji,jj) + v_oce(ji,jj) * 0.01_wp * ( 1._wp - zmsk01y(ji,jj) )                   & ! v_ice = v_oce/100 if mass < zmmin & conc < zamin
+                     &           )   * zmsk00y(ji,jj)
                ENDIF
             END_2D
-            CALL lbc_lnk( 'icedyn_rhg_evp', v_ice, 'V', -1. )
+            CALL lbc_lnk( 'icedyn_rhg_evp', v_ice, 'V', -1.0_wp )
             !
 #if defined key_agrif
@@ -642,20 +701,16 @@
          ENDIF
 
-!!$         IF(sn_cfctl%l_prtctl) THEN   ! Convergence test
-!!$            DO jj = 2 , jpjm1
-!!$               zresr(:,jj) = MAX( ABS( u_ice(:,jj) - zu_ice(:,jj) ), ABS( v_ice(:,jj) - zv_ice(:,jj) ) )
-!!$            END DO
-!!$            zresm = MAXVAL( zresr( 1:jpi, 2:jpjm1 ) )
-!!$            CALL mpp_max( 'icedyn_rhg_evp', zresm )   ! max over the global domain
-!!$         ENDIF
+         ! convergence test
+         IF( nn_rhg_chkcvg == 2 )   CALL rhg_cvg( kt, jter, nn_nevp, u_ice, v_ice, zu_ice, zv_ice )
          !
          !                                                ! ==================== !
       END DO                                              !  end loop over jter  !
       !                                                   ! ==================== !
+      IF( ln_aEVP )   CALL iom_put( 'beta_evp' , zbeta )
       !
       !------------------------------------------------------------------------------!
       ! 4) Recompute delta, shear and div (inputs for mechanical redistribution) 
       !------------------------------------------------------------------------------!
-      DO_2D_10_10
+      DO_2D( 1, 0, 1, 0 )
 
          ! shear at F points
@@ -666,5 +721,5 @@
       END_2D
       
-      DO_2D_00_00
+      DO_2D( 0, 0, 0, 0 )   ! no vector loop
          
          ! tension**2 at T points
@@ -673,4 +728,6 @@
             &   ) * r1_e1e2t(ji,jj)
          zdt2 = zdt * zdt
+
+         zten_i(ji,jj) = zdt
          
          ! shear**2 at T points (doc eq. A16)
@@ -688,13 +745,13 @@
          
          ! delta at T points
-         zdelta         = SQRT( pdivu_i(ji,jj) * pdivu_i(ji,jj) + ( zdt2 + zds2 ) * z1_ecc2 )  
-         rswitch        = 1._wp - MAX( 0._wp, SIGN( 1._wp, -zdelta ) ) ! 0 if delta=0
-         pdelta_i(ji,jj) = zdelta + rn_creepl * rswitch
+         zfac            = SQRT( pdivu_i(ji,jj) * pdivu_i(ji,jj) + ( zdt2 + zds2 ) * z1_ecc2 ) ! delta  
+         rswitch         = 1._wp - MAX( 0._wp, SIGN( 1._wp, -zfac ) ) ! 0 if delta=0
+         pdelta_i(ji,jj) = zfac + rn_creepl * rswitch ! delta+creepl
 
       END_2D
-      CALL lbc_lnk_multi( 'icedyn_rhg_evp', pshear_i, 'T', 1., pdivu_i, 'T', 1., pdelta_i, 'T', 1. )
+      CALL lbc_lnk_multi( 'icedyn_rhg_evp', pshear_i, 'T', 1._wp, pdivu_i, 'T', 1._wp, pdelta_i, 'T', 1._wp, zten_i, 'T', 1._wp, &
+         &                                  zs1     , 'T', 1._wp, zs2    , 'T', 1._wp, zs12    , 'F', 1._wp )
       
       ! --- Store the stress tensor for the next time step --- !
-      CALL lbc_lnk_multi( 'icedyn_rhg_evp', zs1, 'T', 1., zs2, 'T', 1., zs12, 'F', 1. )
       pstress1_i (:,:) = zs1 (:,:)
       pstress2_i (:,:) = zs2 (:,:)
@@ -705,14 +762,10 @@
       ! 5) diagnostics
       !------------------------------------------------------------------------------!
-      DO_2D_11_11
-         zmsk00(ji,jj) = MAX( 0._wp , SIGN( 1._wp , at_i(ji,jj) - epsi06 ) ) ! 1 if ice, 0 if no ice
-      END_2D
-
       ! --- ice-ocean, ice-atm. & ice-oceanbottom(landfast) stresses --- !
       IF(  iom_use('utau_oi') .OR. iom_use('vtau_oi') .OR. iom_use('utau_ai') .OR. iom_use('vtau_ai') .OR. &
          & iom_use('utau_bi') .OR. iom_use('vtau_bi') ) THEN
          !
-         CALL lbc_lnk_multi( 'icedyn_rhg_evp', ztaux_oi, 'U', -1., ztauy_oi, 'V', -1., ztaux_ai, 'U', -1., ztauy_ai, 'V', -1., &
-            &                                  ztaux_bi, 'U', -1., ztauy_bi, 'V', -1. )
+         CALL lbc_lnk_multi( 'icedyn_rhg_evp', ztaux_oi, 'U', -1.0_wp, ztauy_oi, 'V', -1.0_wp, ztaux_ai, 'U', -1.0_wp, ztauy_ai, 'V', -1.0_wp, &
+            &                                  ztaux_bi, 'U', -1.0_wp, ztauy_bi, 'V', -1.0_wp )
          !
          CALL iom_put( 'utau_oi' , ztaux_oi * zmsk00 )
@@ -729,45 +782,75 @@
       IF( iom_use('icestr') )   CALL iom_put( 'icestr' , strength * zmsk00 )   ! strength
 
-      ! --- stress tensor --- !
-      IF( iom_use('isig1') .OR. iom_use('isig2') .OR. iom_use('isig3') .OR. iom_use('normstr') .OR. iom_use('sheastr') ) THEN
-         !
-         ALLOCATE( zsig1(jpi,jpj) , zsig2(jpi,jpj) , zsig3(jpi,jpj) )
+      ! --- Stress tensor invariants (SIMIP diags) --- !
+      IF( iom_use('normstr') .OR. iom_use('sheastr') ) THEN
+         !
+         ALLOCATE( zsig_I(jpi,jpj) , zsig_II(jpi,jpj) )
          !         
-         DO_2D_00_00
-            zdum1 = ( zmsk00(ji-1,jj) * pstress12_i(ji-1,jj) + zmsk00(ji  ,jj-1) * pstress12_i(ji  ,jj-1) +  &  ! stress12_i at T-point
-               &      zmsk00(ji  ,jj) * pstress12_i(ji  ,jj) + zmsk00(ji-1,jj-1) * pstress12_i(ji-1,jj-1) )  &
-               &    / MAX( 1._wp, zmsk00(ji-1,jj) + zmsk00(ji,jj-1) + zmsk00(ji,jj) + zmsk00(ji-1,jj-1) )
-
-            zshear = SQRT( pstress2_i(ji,jj) * pstress2_i(ji,jj) + 4._wp * zdum1 * zdum1 ) ! shear stress  
-
-            zdum2 = zmsk00(ji,jj) / MAX( 1._wp, strength(ji,jj) )
-
-!!               zsig1(ji,jj) = 0.5_wp * zdum2 * ( pstress1_i(ji,jj) + zshear ) ! principal stress (y-direction, see Hunke & Dukowicz 2002)
-!!               zsig2(ji,jj) = 0.5_wp * zdum2 * ( pstress1_i(ji,jj) - zshear ) ! principal stress (x-direction, see Hunke & Dukowicz 2002)
-!!               zsig3(ji,jj) = zdum2**2 * ( ( pstress1_i(ji,jj) + strength(ji,jj) )**2 + ( rn_ecc * zshear )**2 ) ! quadratic relation linking compressive stress to shear stress
-!!                                                                                                               ! (scheme converges if this value is ~1, see Bouillon et al 2009 (eq. 11))
-            zsig1(ji,jj) = 0.5_wp * zdum2 * ( pstress1_i(ji,jj) )          ! compressive stress, see Bouillon et al. 2015
-            zsig2(ji,jj) = 0.5_wp * zdum2 * ( zshear )                     ! shear stress
-            zsig3(ji,jj) = zdum2**2 * ( ( pstress1_i(ji,jj) + strength(ji,jj) )**2 + ( rn_ecc * zshear )**2 )
-         END_2D
-         CALL lbc_lnk_multi( 'icedyn_rhg_evp', zsig1, 'T', 1., zsig2, 'T', 1., zsig3, 'T', 1. )
-         !
-         CALL iom_put( 'isig1' , zsig1 )
-         CALL iom_put( 'isig2' , zsig2 )
-         CALL iom_put( 'isig3' , zsig3 )
-         !
-         ! Stress tensor invariants (normal and shear stress N/m)
-         IF( iom_use('normstr') )   CALL iom_put( 'normstr' ,       ( zs1(:,:) + zs2(:,:) )                       * zmsk00(:,:) ) ! Normal stress
-         IF( iom_use('sheastr') )   CALL iom_put( 'sheastr' , SQRT( ( zs1(:,:) - zs2(:,:) )**2 + 4*zs12(:,:)**2 ) * zmsk00(:,:) ) ! Shear stress
-
-         DEALLOCATE( zsig1 , zsig2 , zsig3 )
-      ENDIF
-      
+         DO_2D( 1, 1, 1, 1 )
+            
+            ! Ice stresses
+            ! sigma1, sigma2, sigma12 are some useful recombination of the stresses (Hunke and Dukowicz MWR 2002, Bouillon et al., OM2013)
+            ! These are NOT stress tensor components, neither stress invariants, neither stress principal components
+            ! I know, this can be confusing...
+            zfac             =   strength(ji,jj) / ( pdelta_i(ji,jj) + rn_creepl ) 
+            zsig1            =   zfac * ( pdivu_i(ji,jj) - pdelta_i(ji,jj) )
+            zsig2            =   zfac * z1_ecc2 * zten_i(ji,jj)
+            zsig12           =   zfac * z1_ecc2 * pshear_i(ji,jj)
+            
+            ! Stress invariants (sigma_I, sigma_II, Coon 1974, Feltham 2008)
+            zsig_I (ji,jj)   =   zsig1 * 0.5_wp                                           ! 1st stress invariant, aka average normal stress, aka negative pressure
+            zsig_II(ji,jj)   =   SQRT ( MAX( 0._wp, zsig2 * zsig2 * 0.25_wp + zsig12 ) )  ! 2nd  ''       '', aka maximum shear stress
+               
+         END_2D         
+         !
+         ! Stress tensor invariants (normal and shear stress N/m) - SIMIP diags - definitions following Coon (1974) and Feltham (2008)
+         IF( iom_use('normstr') )   CALL iom_put( 'normstr', zsig_I (:,:) * zmsk00(:,:) ) ! Normal stress
+         IF( iom_use('sheastr') )   CALL iom_put( 'sheastr', zsig_II(:,:) * zmsk00(:,:) ) ! Maximum shear stress
+         
+         DEALLOCATE ( zsig_I, zsig_II )
+         
+      ENDIF
+
+      ! --- Normalized stress tensor principal components --- !
+      ! This are used to plot the normalized yield curve, see Lemieux & Dupont, 2020
+      ! Recommendation 1 : we use ice strength, not replacement pressure
+      ! Recommendation 2 : need to use deformations at PREVIOUS iterate for viscosities
+      IF( iom_use('sig1_pnorm') .OR. iom_use('sig2_pnorm') ) THEN
+         !
+         ALLOCATE( zsig1_p(jpi,jpj) , zsig2_p(jpi,jpj) , zsig_I(jpi,jpj) , zsig_II(jpi,jpj) )         
+         !         
+         DO_2D( 1, 1, 1, 1 )
+            
+            ! Ice stresses computed with **viscosities** (delta, p/delta) at **previous** iterates 
+            !                        and **deformations** at current iterates
+            !                        following Lemieux & Dupont (2020)
+            zfac             =   zp_delt(ji,jj)
+            zsig1            =   zfac * ( pdivu_i(ji,jj) - ( zdelta(ji,jj) + rn_creepl ) )
+            zsig2            =   zfac * z1_ecc2 * zten_i(ji,jj)
+            zsig12           =   zfac * z1_ecc2 * pshear_i(ji,jj)
+            
+            ! Stress invariants (sigma_I, sigma_II, Coon 1974, Feltham 2008), T-point
+            zsig_I(ji,jj)    =   zsig1 * 0.5_wp                                            ! 1st stress invariant, aka average normal stress, aka negative pressure
+            zsig_II(ji,jj)   =   SQRT ( MAX( 0._wp, zsig2 * zsig2 * 0.25_wp + zsig12 ) )   ! 2nd  ''       '', aka maximum shear stress
+            
+            ! Normalized  principal stresses (used to display the ellipse)
+            z1_strength      =   1._wp / MAX( 1._wp, strength(ji,jj) )
+            zsig1_p(ji,jj)   =   ( zsig_I(ji,jj) + zsig_II(ji,jj) ) * z1_strength
+            zsig2_p(ji,jj)   =   ( zsig_I(ji,jj) - zsig_II(ji,jj) ) * z1_strength
+         END_2D              
+         !
+         CALL iom_put( 'sig1_pnorm' , zsig1_p ) 
+         CALL iom_put( 'sig2_pnorm' , zsig2_p ) 
+
+         DEALLOCATE( zsig1_p , zsig2_p , zsig_I, zsig_II )
+         
+      ENDIF
+
       ! --- SIMIP --- !
       IF(  iom_use('dssh_dx') .OR. iom_use('dssh_dy') .OR. &
          & iom_use('corstrx') .OR. iom_use('corstry') .OR. iom_use('intstrx') .OR. iom_use('intstry') ) THEN
          !
-         CALL lbc_lnk_multi( 'icedyn_rhg_evp', zspgU, 'U', -1., zspgV, 'V', -1., &
-            &                                  zCorU, 'U', -1., zCorV, 'V', -1., zfU, 'U', -1., zfV, 'V', -1. )
+         CALL lbc_lnk_multi( 'icedyn_rhg_evp', zspgU, 'U', -1.0_wp, zspgV, 'V', -1.0_wp, &
+            &                                  zCorU, 'U', -1.0_wp, zCorV, 'V', -1.0_wp, zfU, 'U', -1.0_wp, zfV, 'V', -1.0_wp )
 
          CALL iom_put( 'dssh_dx' , zspgU * zmsk00 )   ! Sea-surface tilt term in force balance (x)
@@ -785,5 +868,5 @@
             &      zdiag_xmtrp_snw(jpi,jpj) , zdiag_ymtrp_snw(jpi,jpj) , zdiag_xatrp(jpi,jpj) , zdiag_yatrp(jpi,jpj) )
          !
-         DO_2D_00_00
+         DO_2D( 0, 0, 0, 0 )
             ! 2D ice mass, snow mass, area transport arrays (X, Y)
             zfac_x = 0.5 * u_ice(ji,jj) * e2u(ji,jj) * zmsk00(ji,jj)
@@ -801,7 +884,7 @@
          END_2D
 
-         CALL lbc_lnk_multi( 'icedyn_rhg_evp', zdiag_xmtrp_ice, 'U', -1., zdiag_ymtrp_ice, 'V', -1., &
-            &                                  zdiag_xmtrp_snw, 'U', -1., zdiag_ymtrp_snw, 'V', -1., &
-            &                                  zdiag_xatrp    , 'U', -1., zdiag_yatrp    , 'V', -1. )
+         CALL lbc_lnk_multi( 'icedyn_rhg_evp', zdiag_xmtrp_ice, 'U', -1.0_wp, zdiag_ymtrp_ice, 'V', -1.0_wp, &
+            &                                  zdiag_xmtrp_snw, 'U', -1.0_wp, zdiag_ymtrp_snw, 'V', -1.0_wp, &
+            &                                  zdiag_xatrp    , 'U', -1.0_wp, zdiag_yatrp    , 'V', -1.0_wp )
 
          CALL iom_put( 'xmtrpice' , zdiag_xmtrp_ice )   ! X-component of sea-ice mass transport (kg/s)
@@ -817,5 +900,88 @@
       ENDIF
       !
+      ! --- convergence tests --- !
+      IF( nn_rhg_chkcvg == 1 .OR. nn_rhg_chkcvg == 2 ) THEN
+         IF( iom_use('uice_cvg') ) THEN
+            IF( ln_aEVP ) THEN   ! output: beta * ( u(t=nn_nevp) - u(t=nn_nevp-1) )
+               CALL iom_put( 'uice_cvg', MAX( ABS( u_ice(:,:) - zu_ice(:,:) ) * zbeta(:,:) * umask(:,:,1) , &
+                  &                           ABS( v_ice(:,:) - zv_ice(:,:) ) * zbeta(:,:) * vmask(:,:,1) ) * zmsk15(:,:) )
+            ELSE                 ! output: nn_nevp * ( u(t=nn_nevp) - u(t=nn_nevp-1) )
+               CALL iom_put( 'uice_cvg', REAL( nn_nevp ) * MAX( ABS( u_ice(:,:) - zu_ice(:,:) ) * umask(:,:,1) , &
+                  &                                             ABS( v_ice(:,:) - zv_ice(:,:) ) * vmask(:,:,1) ) * zmsk15(:,:) )
+            ENDIF
+         ENDIF
+      ENDIF      
+      !
+      DEALLOCATE( zmsk00, zmsk15 )
+      !
    END SUBROUTINE ice_dyn_rhg_evp
+
+
+   SUBROUTINE rhg_cvg( kt, kiter, kitermax, pu, pv, pub, pvb )
+      !!----------------------------------------------------------------------
+      !!                    ***  ROUTINE rhg_cvg  ***
+      !!                     
+      !! ** Purpose :   check convergence of oce rheology
+      !!
+      !! ** Method  :   create a file ice_cvg.nc containing the convergence of ice velocity
+      !!                during the sub timestepping of rheology so as:
+      !!                  uice_cvg = MAX( u(t+1) - u(t) , v(t+1) - v(t) )
+      !!                This routine is called every sub-iteration, so it is cpu expensive
+      !!
+      !! ** Note    :   for the first sub-iteration, uice_cvg is set to 0 (too large otherwise)   
+      !!----------------------------------------------------------------------
+      INTEGER ,                 INTENT(in) ::   kt, kiter, kitermax       ! ocean time-step index
+      REAL(wp), DIMENSION(:,:), INTENT(in) ::   pu, pv, pub, pvb          ! now and before velocities
+      !!
+      INTEGER           ::   it, idtime, istatus
+      INTEGER           ::   ji, jj          ! dummy loop indices
+      REAL(wp)          ::   zresm           ! local real 
+      CHARACTER(len=20) ::   clname
+      REAL(wp), DIMENSION(jpi,jpj) ::   zres           ! check convergence
+      !!----------------------------------------------------------------------
+
+      ! create file
+      IF( kt == nit000 .AND. kiter == 1 ) THEN
+         !
+         IF( lwp ) THEN
+            WRITE(numout,*)
+            WRITE(numout,*) 'rhg_cvg : ice rheology convergence control'
+            WRITE(numout,*) '~~~~~~~'
+         ENDIF
+         !
+         IF( lwm ) THEN
+            clname = 'ice_cvg.nc'
+            IF( .NOT. Agrif_Root() )   clname = TRIM(Agrif_CFixed())//"_"//TRIM(clname)
+            istatus = NF90_CREATE( TRIM(clname), NF90_CLOBBER, ncvgid )
+            istatus = NF90_DEF_DIM( ncvgid, 'time'  , NF90_UNLIMITED, idtime )
+            istatus = NF90_DEF_VAR( ncvgid, 'uice_cvg', NF90_DOUBLE   , (/ idtime /), nvarid )
+            istatus = NF90_ENDDEF(ncvgid)
+         ENDIF
+         !
+      ENDIF
+
+      ! time
+      it = ( kt - 1 ) * kitermax + kiter
+      
+      ! convergence
+      IF( kiter == 1 ) THEN ! remove the first iteration for calculations of convergence (always very large)
+         zresm = 0._wp
+      ELSE
+         DO_2D( 1, 1, 1, 1 )
+            zres(ji,jj) = MAX( ABS( pu(ji,jj) - pub(ji,jj) ) * umask(ji,jj,1), &
+               &               ABS( pv(ji,jj) - pvb(ji,jj) ) * vmask(ji,jj,1) ) * zmsk15(ji,jj)
+         END_2D
+         zresm = MAXVAL( zres )
+         CALL mpp_max( 'icedyn_rhg_evp', zresm )   ! max over the global domain
+      ENDIF
+
+      IF( lwm ) THEN
+         ! write variables
+         istatus = NF90_PUT_VAR( ncvgid, nvarid, (/zresm/), (/it/), (/1/) )
+         ! close file
+         IF( kt == nitend - nn_fsbc + 1 )   istatus = NF90_CLOSE(ncvgid)
+      ENDIF
+      
+   END SUBROUTINE rhg_cvg
 
 
@@ -845,7 +1011,7 @@
             !
             IF( MIN( id1, id2, id3 ) > 0 ) THEN      ! fields exist
-               CALL iom_get( numrir, jpdom_autoglo, 'stress1_i' , stress1_i,  ldxios = lrixios )
-               CALL iom_get( numrir, jpdom_autoglo, 'stress2_i' , stress2_i,  ldxios = lrixios )
-               CALL iom_get( numrir, jpdom_autoglo, 'stress12_i', stress12_i, ldxios = lrixios )
+               CALL iom_get( numrir, jpdom_auto, 'stress1_i' , stress1_i , cd_type = 'T', ldxios = lrixios )
+               CALL iom_get( numrir, jpdom_auto, 'stress2_i' , stress2_i , cd_type = 'T', ldxios = lrixios )
+               CALL iom_get( numrir, jpdom_auto, 'stress12_i', stress12_i, cd_type = 'F', ldxios = lrixios )
             ELSE                                     ! start rheology from rest
                IF(lwp) WRITE(numout,*)
@@ -879,4 +1045,5 @@
    END SUBROUTINE rhg_evp_rst
 
+   
 #else
    !!----------------------------------------------------------------------
Index: NEMO/branches/2020/dev_12905_xios_restart/src/ICE/iceistate.F90
===================================================================
--- NEMO/branches/2020/dev_12905_xios_restart/src/ICE/iceistate.F90	(revision 13033)
+++ NEMO/branches/2020/dev_12905_xios_restart/src/ICE/iceistate.F90	(revision 13727)
@@ -33,4 +33,10 @@
    USE fldread        ! read input fields
 
+# if defined key_agrif
+   USE agrif_oce
+   USE agrif_ice
+   USE agrif_ice_interp 
+# endif   
+
    IMPLICIT NONE
    PRIVATE
@@ -41,13 +47,16 @@
    !                             !! ** namelist (namini) **
    LOGICAL, PUBLIC  ::   ln_iceini        !: Ice initialization or not
-   LOGICAL, PUBLIC  ::   ln_iceini_file   !: Ice initialization from 2D netcdf file
+   INTEGER, PUBLIC  ::   nn_iceini_file   !: Ice initialization:
+                                  !        0 = Initialise sea ice based on SSTs
+                                  !        1 = Initialise sea ice from single category netcdf file
+                                  !        2 = Initialise sea ice from multi category restart file
    REAL(wp) ::   rn_thres_sst
    REAL(wp) ::   rn_hti_ini_n, rn_hts_ini_n, rn_ati_ini_n, rn_smi_ini_n, rn_tmi_ini_n, rn_tsu_ini_n, rn_tms_ini_n
    REAL(wp) ::   rn_hti_ini_s, rn_hts_ini_s, rn_ati_ini_s, rn_smi_ini_s, rn_tmi_ini_s, rn_tsu_ini_s, rn_tms_ini_s
-   REAL(wp) ::   rn_apd_ini_n, rn_hpd_ini_n
-   REAL(wp) ::   rn_apd_ini_s, rn_hpd_ini_s
+   REAL(wp) ::   rn_apd_ini_n, rn_hpd_ini_n, rn_hld_ini_n
+   REAL(wp) ::   rn_apd_ini_s, rn_hpd_ini_s, rn_hld_ini_s
    !
-   !                              ! if ln_iceini_file = T
-   INTEGER , PARAMETER ::   jpfldi = 9           ! maximum number of files to read
+   !                              ! if nn_iceini_file = 1
+   INTEGER , PARAMETER ::   jpfldi = 10          ! maximum number of files to read
    INTEGER , PARAMETER ::   jp_hti = 1           ! index of ice thickness    (m)
    INTEGER , PARAMETER ::   jp_hts = 2           ! index of snw thickness    (m)
@@ -59,6 +68,7 @@
    INTEGER , PARAMETER ::   jp_apd = 8           ! index of pnd fraction     (-)
    INTEGER , PARAMETER ::   jp_hpd = 9           ! index of pnd depth        (m)
+   INTEGER , PARAMETER ::   jp_hld = 10          ! index of pnd lid depth    (m)
    TYPE(FLD), ALLOCATABLE, DIMENSION(:) ::   si  ! structure of input fields (file informations, fields read)
-   !   
+
    !! * Substitutions
 #  include "do_loop_substitute.h90"
@@ -83,8 +93,6 @@
       !! ** Steps   :   1) Set initial surface and basal temperatures
       !!                2) Recompute or read sea ice state variables
-      !!                3) Fill in the ice thickness distribution using gaussian
-      !!                4) Fill in space-dependent arrays for state variables
-      !!                5) snow-ice mass computation
-      !!                6) store before fields
+      !!                3) Fill in space-dependent arrays for state variables
+      !!                4) snow-ice mass computation
       !!
       !! ** Notes   : o_i, t_su, t_s, t_i, sz_i must be filled everywhere, even
@@ -101,8 +109,8 @@
       REAL(wp), DIMENSION(jpi,jpj)     ::   zht_i_ini, zat_i_ini, ztm_s_ini            !data from namelist or nc file
       REAL(wp), DIMENSION(jpi,jpj)     ::   zt_su_ini, zht_s_ini, zsm_i_ini, ztm_i_ini !data from namelist or nc file
-      REAL(wp), DIMENSION(jpi,jpj)     ::   zapnd_ini, zhpnd_ini                       !data from namelist or nc file
+      REAL(wp), DIMENSION(jpi,jpj)     ::   zapnd_ini, zhpnd_ini, zhlid_ini            !data from namelist or nc file
       REAL(wp), DIMENSION(jpi,jpj,jpl) ::   zti_3d , zts_3d                            !temporary arrays
       !!
-      REAL(wp), DIMENSION(:,:), ALLOCATABLE ::   zhi_2d, zhs_2d, zai_2d, zti_2d, zts_2d, ztsu_2d, zsi_2d, zaip_2d, zhip_2d
+      REAL(wp), DIMENSION(:,:), ALLOCATABLE ::   zhi_2d, zhs_2d, zai_2d, zti_2d, zts_2d, ztsu_2d, zsi_2d, zaip_2d, zhip_2d, zhil_2d
       !--------------------------------------------------------------------
 
@@ -158,6 +166,8 @@
       a_ip     (:,:,:) = 0._wp
       v_ip     (:,:,:) = 0._wp
-      a_ip_frac(:,:,:) = 0._wp
+      v_il     (:,:,:) = 0._wp
+      a_ip_eff (:,:,:) = 0._wp
       h_ip     (:,:,:) = 0._wp
+      h_il     (:,:,:) = 0._wp
       !
       ! ice velocities
@@ -169,203 +179,250 @@
       !------------------------------------------------------------------------
       IF( ln_iceini ) THEN
-         !                             !---------------!
-         IF( ln_iceini_file )THEN      ! Read a file   !
-            !                          !---------------!
-            WHERE( ff_t(:,:) >= 0._wp )   ;   zswitch(:,:) = 1._wp
-            ELSEWHERE                     ;   zswitch(:,:) = 0._wp
-            END WHERE
+         !
+         IF( Agrif_Root() ) THEN
+            !                             !---------------!
+            IF( nn_iceini_file == 1 )THEN ! Read a file   !
+               !                          !---------------!
+               WHERE( ff_t(:,:) >= 0._wp )   ;   zswitch(:,:) = 1._wp
+               ELSEWHERE                     ;   zswitch(:,:) = 0._wp
+               END WHERE
+               !
+               CALL fld_read( kt, 1, si ) ! input fields provided at the current time-step
+               !
+               ! -- mandatory fields -- !
+               zht_i_ini(:,:) = si(jp_hti)%fnow(:,:,1) * tmask(:,:,1)
+               zht_s_ini(:,:) = si(jp_hts)%fnow(:,:,1) * tmask(:,:,1)
+               zat_i_ini(:,:) = si(jp_ati)%fnow(:,:,1) * tmask(:,:,1)
+
+               ! -- optional fields -- !
+               !    if fields do not exist then set them to the values present in the namelist (except for temperatures)
+               !
+               ! ice salinity
+               IF( TRIM(si(jp_smi)%clrootname) == 'NOT USED' ) &
+                  &     si(jp_smi)%fnow(:,:,1) = ( rn_smi_ini_n * zswitch + rn_smi_ini_s * (1._wp - zswitch) ) * tmask(:,:,1)
+               !
+               ! temperatures
+               IF    ( TRIM(si(jp_tmi)%clrootname) == 'NOT USED' .AND. TRIM(si(jp_tsu)%clrootname) == 'NOT USED' .AND. &
+                  &    TRIM(si(jp_tms)%clrootname) == 'NOT USED' ) THEN
+                  si(jp_tmi)%fnow(:,:,1) = ( rn_tmi_ini_n * zswitch + rn_tmi_ini_s * (1._wp - zswitch) ) * tmask(:,:,1)
+                  si(jp_tsu)%fnow(:,:,1) = ( rn_tsu_ini_n * zswitch + rn_tsu_ini_s * (1._wp - zswitch) ) * tmask(:,:,1)
+                  si(jp_tms)%fnow(:,:,1) = ( rn_tms_ini_n * zswitch + rn_tms_ini_s * (1._wp - zswitch) ) * tmask(:,:,1)
+               ENDIF
+               IF( TRIM(si(jp_tmi)%clrootname) == 'NOT USED' .AND. TRIM(si(jp_tms)%clrootname) /= 'NOT USED' ) & ! if T_s is read and not T_i, set T_i = (T_s + T_freeze)/2
+                  &     si(jp_tmi)%fnow(:,:,1) = 0.5_wp * ( si(jp_tms)%fnow(:,:,1) + 271.15 )
+               IF( TRIM(si(jp_tmi)%clrootname) == 'NOT USED' .AND. TRIM(si(jp_tsu)%clrootname) /= 'NOT USED' ) & ! if T_su is read and not T_i, set T_i = (T_su + T_freeze)/2
+                  &     si(jp_tmi)%fnow(:,:,1) = 0.5_wp * ( si(jp_tsu)%fnow(:,:,1) + 271.15 )
+               IF( TRIM(si(jp_tsu)%clrootname) == 'NOT USED' .AND. TRIM(si(jp_tms)%clrootname) /= 'NOT USED' ) & ! if T_s is read and not T_su, set T_su = T_s
+                  &     si(jp_tsu)%fnow(:,:,1) = si(jp_tms)%fnow(:,:,1)
+               IF( TRIM(si(jp_tsu)%clrootname) == 'NOT USED' .AND. TRIM(si(jp_tmi)%clrootname) /= 'NOT USED' ) & ! if T_i is read and not T_su, set T_su = T_i
+                  &     si(jp_tsu)%fnow(:,:,1) = si(jp_tmi)%fnow(:,:,1)
+               IF( TRIM(si(jp_tms)%clrootname) == 'NOT USED' .AND. TRIM(si(jp_tsu)%clrootname) /= 'NOT USED' ) & ! if T_su is read and not T_s, set T_s = T_su
+                  &     si(jp_tms)%fnow(:,:,1) = si(jp_tsu)%fnow(:,:,1)
+               IF( TRIM(si(jp_tms)%clrootname) == 'NOT USED' .AND. TRIM(si(jp_tmi)%clrootname) /= 'NOT USED' ) & ! if T_i is read and not T_s, set T_s = T_i
+                  &     si(jp_tms)%fnow(:,:,1) = si(jp_tmi)%fnow(:,:,1)
+               !
+               ! pond concentration
+               IF( TRIM(si(jp_apd)%clrootname) == 'NOT USED' ) &
+                  &     si(jp_apd)%fnow(:,:,1) = ( rn_apd_ini_n * zswitch + rn_apd_ini_s * (1._wp - zswitch) ) * tmask(:,:,1) & ! rn_apd = pond fraction => rn_apnd * a_i = pond conc.
+                  &                              * si(jp_ati)%fnow(:,:,1) 
+               !
+               ! pond depth
+               IF( TRIM(si(jp_hpd)%clrootname) == 'NOT USED' ) &
+                  &     si(jp_hpd)%fnow(:,:,1) = ( rn_hpd_ini_n * zswitch + rn_hpd_ini_s * (1._wp - zswitch) ) * tmask(:,:,1)
+               !
+               ! pond lid depth
+               IF( TRIM(si(jp_hld)%clrootname) == 'NOT USED' ) &
+                  &     si(jp_hld)%fnow(:,:,1) = ( rn_hld_ini_n * zswitch + rn_hld_ini_s * (1._wp - zswitch) ) * tmask(:,:,1)
+               !
+               zsm_i_ini(:,:) = si(jp_smi)%fnow(:,:,1) * tmask(:,:,1)
+               ztm_i_ini(:,:) = si(jp_tmi)%fnow(:,:,1) * tmask(:,:,1)
+               zt_su_ini(:,:) = si(jp_tsu)%fnow(:,:,1) * tmask(:,:,1)
+               ztm_s_ini(:,:) = si(jp_tms)%fnow(:,:,1) * tmask(:,:,1)
+               zapnd_ini(:,:) = si(jp_apd)%fnow(:,:,1) * tmask(:,:,1)
+               zhpnd_ini(:,:) = si(jp_hpd)%fnow(:,:,1) * tmask(:,:,1)
+               zhlid_ini(:,:) = si(jp_hld)%fnow(:,:,1) * tmask(:,:,1)
+               !
+               ! change the switch for the following
+               WHERE( zat_i_ini(:,:) > 0._wp )   ;   zswitch(:,:) = tmask(:,:,1) 
+               ELSEWHERE                         ;   zswitch(:,:) = 0._wp
+               END WHERE
+
+               !                          !---------------!
+            ELSE                          ! Read namelist !
+               !                          !---------------!
+               ! no ice if (sst - Tfreez) >= thresold
+               WHERE( ( sst_m(:,:) - (t_bo(:,:) - rt0) ) * tmask(:,:,1) >= rn_thres_sst )   ;   zswitch(:,:) = 0._wp 
+               ELSEWHERE                                                                    ;   zswitch(:,:) = tmask(:,:,1)
+               END WHERE
+               !
+               ! assign initial thickness, concentration, snow depth and salinity to an hemisphere-dependent array
+               WHERE( ff_t(:,:) >= 0._wp )
+                  zht_i_ini(:,:) = rn_hti_ini_n * zswitch(:,:)
+                  zht_s_ini(:,:) = rn_hts_ini_n * zswitch(:,:)
+                  zat_i_ini(:,:) = rn_ati_ini_n * zswitch(:,:)
+                  zsm_i_ini(:,:) = rn_smi_ini_n * zswitch(:,:)
+                  ztm_i_ini(:,:) = rn_tmi_ini_n * zswitch(:,:)
+                  zt_su_ini(:,:) = rn_tsu_ini_n * zswitch(:,:)
+                  ztm_s_ini(:,:) = rn_tms_ini_n * zswitch(:,:)
+                  zapnd_ini(:,:) = rn_apd_ini_n * zswitch(:,:) * zat_i_ini(:,:) ! rn_apd = pond fraction => rn_apd * a_i = pond conc. 
+                  zhpnd_ini(:,:) = rn_hpd_ini_n * zswitch(:,:)
+                  zhlid_ini(:,:) = rn_hld_ini_n * zswitch(:,:)
+               ELSEWHERE
+                  zht_i_ini(:,:) = rn_hti_ini_s * zswitch(:,:)
+                  zht_s_ini(:,:) = rn_hts_ini_s * zswitch(:,:)
+                  zat_i_ini(:,:) = rn_ati_ini_s * zswitch(:,:)
+                  zsm_i_ini(:,:) = rn_smi_ini_s * zswitch(:,:)
+                  ztm_i_ini(:,:) = rn_tmi_ini_s * zswitch(:,:)
+                  zt_su_ini(:,:) = rn_tsu_ini_s * zswitch(:,:)
+                  ztm_s_ini(:,:) = rn_tms_ini_s * zswitch(:,:)
+                  zapnd_ini(:,:) = rn_apd_ini_s * zswitch(:,:) * zat_i_ini(:,:) ! rn_apd = pond fraction => rn_apd * a_i = pond conc.
+                  zhpnd_ini(:,:) = rn_hpd_ini_s * zswitch(:,:)
+                  zhlid_ini(:,:) = rn_hld_ini_s * zswitch(:,:)
+               END WHERE
+               !
+            ENDIF
+
+
+
+            ! make sure ponds = 0 if no ponds scheme
+            IF ( .NOT.ln_pnd ) THEN
+               zapnd_ini(:,:) = 0._wp
+               zhpnd_ini(:,:) = 0._wp
+               zhlid_ini(:,:) = 0._wp
+            ENDIF
+            
+            IF ( .NOT.ln_pnd_lids ) THEN
+               zhlid_ini(:,:) = 0._wp
+            ENDIF
+            
+            !----------------!
+            ! 3) fill fields !
+            !----------------!
+            ! select ice covered grid points
+            npti = 0 ; nptidx(:) = 0
+            DO_2D( 1, 1, 1, 1 )
+               IF ( zht_i_ini(ji,jj) > 0._wp ) THEN
+                  npti         = npti  + 1
+                  nptidx(npti) = (jj - 1) * jpi + ji
+               ENDIF
+            END_2D
+
+            ! move to 1D arrays: (jpi,jpj) -> (jpi*jpj)
+            CALL tab_2d_1d( npti, nptidx(1:npti), h_i_1d (1:npti)  , zht_i_ini )
+            CALL tab_2d_1d( npti, nptidx(1:npti), h_s_1d (1:npti)  , zht_s_ini )
+            CALL tab_2d_1d( npti, nptidx(1:npti), at_i_1d(1:npti)  , zat_i_ini )
+            CALL tab_2d_1d( npti, nptidx(1:npti), t_i_1d (1:npti,1), ztm_i_ini )
+            CALL tab_2d_1d( npti, nptidx(1:npti), t_s_1d (1:npti,1), ztm_s_ini )
+            CALL tab_2d_1d( npti, nptidx(1:npti), t_su_1d(1:npti)  , zt_su_ini )
+            CALL tab_2d_1d( npti, nptidx(1:npti), s_i_1d (1:npti)  , zsm_i_ini )
+            CALL tab_2d_1d( npti, nptidx(1:npti), a_ip_1d(1:npti)  , zapnd_ini )
+            CALL tab_2d_1d( npti, nptidx(1:npti), h_ip_1d(1:npti)  , zhpnd_ini )
+            CALL tab_2d_1d( npti, nptidx(1:npti), h_il_1d(1:npti)  , zhlid_ini )
+            
+            ! allocate temporary arrays
+            ALLOCATE( zhi_2d (npti,jpl), zhs_2d (npti,jpl), zai_2d (npti,jpl), &
+               &      zti_2d (npti,jpl), zts_2d (npti,jpl), ztsu_2d(npti,jpl), zsi_2d(npti,jpl), &
+               &      zaip_2d(npti,jpl), zhip_2d(npti,jpl), zhil_2d(npti,jpl) )
+
+            ! distribute 1-cat into jpl-cat: (jpi*jpj) -> (jpi*jpj,jpl)
+            CALL ice_var_itd( h_i_1d(1:npti)  , h_s_1d(1:npti)  , at_i_1d(1:npti),                  &
+               &              zhi_2d          , zhs_2d          , zai_2d         ,                  &
+               &              t_i_1d(1:npti,1), t_s_1d(1:npti,1), t_su_1d(1:npti),                  &
+               &              s_i_1d(1:npti)  , a_ip_1d(1:npti) , h_ip_1d(1:npti), h_il_1d(1:npti), &
+               &              zti_2d          , zts_2d          , ztsu_2d        ,                  &
+               &              zsi_2d          , zaip_2d         , zhip_2d        , zhil_2d )
+
+            ! move to 3D arrays: (jpi*jpj,jpl) -> (jpi,jpj,jpl)
+            DO jl = 1, jpl
+               zti_3d(:,:,jl) = rt0 * tmask(:,:,1)
+               zts_3d(:,:,jl) = rt0 * tmask(:,:,1)
+            END DO
+            CALL tab_2d_3d( npti, nptidx(1:npti), zhi_2d   , h_i    )
+            CALL tab_2d_3d( npti, nptidx(1:npti), zhs_2d   , h_s    )
+            CALL tab_2d_3d( npti, nptidx(1:npti), zai_2d   , a_i    )
+            CALL tab_2d_3d( npti, nptidx(1:npti), zti_2d   , zti_3d )
+            CALL tab_2d_3d( npti, nptidx(1:npti), zts_2d   , zts_3d )
+            CALL tab_2d_3d( npti, nptidx(1:npti), ztsu_2d  , t_su   )
+            CALL tab_2d_3d( npti, nptidx(1:npti), zsi_2d   , s_i    )
+            CALL tab_2d_3d( npti, nptidx(1:npti), zaip_2d  , a_ip   )
+            CALL tab_2d_3d( npti, nptidx(1:npti), zhip_2d  , h_ip   )
+            CALL tab_2d_3d( npti, nptidx(1:npti), zhil_2d  , h_il   )
+
+            ! deallocate temporary arrays
+            DEALLOCATE( zhi_2d, zhs_2d, zai_2d , &
+               &        zti_2d, zts_2d, ztsu_2d, zsi_2d, zaip_2d, zhip_2d, zhil_2d )
+
+            ! calculate extensive and intensive variables
+            CALL ice_var_salprof ! for sz_i
+            DO jl = 1, jpl
+               DO_2D( 1, 1, 1, 1 )
+                  v_i (ji,jj,jl) = h_i(ji,jj,jl) * a_i(ji,jj,jl)
+                  v_s (ji,jj,jl) = h_s(ji,jj,jl) * a_i(ji,jj,jl)
+                  sv_i(ji,jj,jl) = MIN( MAX( rn_simin , s_i(ji,jj,jl) ) , rn_simax ) * v_i(ji,jj,jl)
+               END_2D
+            END DO
             !
-            CALL fld_read( kt, 1, si ) ! input fields provided at the current time-step
+            DO jl = 1, jpl
+               DO_3D( 1, 1, 1, 1, 1, nlay_s )
+                  t_s(ji,jj,jk,jl) = zts_3d(ji,jj,jl)
+                  e_s(ji,jj,jk,jl) = zswitch(ji,jj) * v_s(ji,jj,jl) * r1_nlay_s * &
+                     &               rhos * ( rcpi * ( rt0 - t_s(ji,jj,jk,jl) ) + rLfus )
+               END_3D
+            END DO
             !
-            ! -- mandatory fields -- !
-            zht_i_ini(:,:) = si(jp_hti)%fnow(:,:,1) * tmask(:,:,1)
-            zht_s_ini(:,:) = si(jp_hts)%fnow(:,:,1) * tmask(:,:,1)
-            zat_i_ini(:,:) = si(jp_ati)%fnow(:,:,1) * tmask(:,:,1)
-
-            ! -- optional fields -- !
-            !    if fields do not exist then set them to the values present in the namelist (except for snow and surface temperature)
-            !
-            ! ice salinity
-            IF( TRIM(si(jp_smi)%clrootname) == 'NOT USED' ) &
-               &     si(jp_smi)%fnow(:,:,1) = ( rn_smi_ini_n * zswitch + rn_smi_ini_s * (1._wp - zswitch) ) * tmask(:,:,1)
-            !
-            ! temperatures
-            IF    ( TRIM(si(jp_tmi)%clrootname) == 'NOT USED' .AND. TRIM(si(jp_tsu)%clrootname) == 'NOT USED' .AND. &
-               &    TRIM(si(jp_tms)%clrootname) == 'NOT USED' ) THEN
-               si(jp_tmi)%fnow(:,:,1) = ( rn_tmi_ini_n * zswitch + rn_tmi_ini_s * (1._wp - zswitch) ) * tmask(:,:,1)
-               si(jp_tsu)%fnow(:,:,1) = ( rn_tsu_ini_n * zswitch + rn_tsu_ini_s * (1._wp - zswitch) ) * tmask(:,:,1)
-               si(jp_tms)%fnow(:,:,1) = ( rn_tms_ini_n * zswitch + rn_tms_ini_s * (1._wp - zswitch) ) * tmask(:,:,1)
-            ELSEIF( TRIM(si(jp_tmi)%clrootname) == 'NOT USED' .AND. TRIM(si(jp_tms)%clrootname) /= 'NOT USED' ) THEN ! if T_s is read and not T_i, set T_i = (T_s + T_freeze)/2
-               si(jp_tmi)%fnow(:,:,1) = 0.5_wp * ( si(jp_tms)%fnow(:,:,1) + 271.15 )
-            ELSEIF( TRIM(si(jp_tmi)%clrootname) == 'NOT USED' .AND. TRIM(si(jp_tsu)%clrootname) /= 'NOT USED' ) THEN ! if T_su is read and not T_i, set T_i = (T_su + T_freeze)/2
-               si(jp_tmi)%fnow(:,:,1) = 0.5_wp * ( si(jp_tsu)%fnow(:,:,1) + 271.15 )
-            ELSEIF( TRIM(si(jp_tsu)%clrootname) == 'NOT USED' .AND. TRIM(si(jp_tms)%clrootname) /= 'NOT USED' ) THEN ! if T_s is read and not T_su, set T_su = T_s
-               si(jp_tsu)%fnow(:,:,1) = si(jp_tms)%fnow(:,:,1)
-            ELSEIF( TRIM(si(jp_tsu)%clrootname) == 'NOT USED' .AND. TRIM(si(jp_tmi)%clrootname) /= 'NOT USED' ) THEN ! if T_i is read and not T_su, set T_su = T_i
-               si(jp_tsu)%fnow(:,:,1) = si(jp_tmi)%fnow(:,:,1)
-            ELSEIF( TRIM(si(jp_tms)%clrootname) == 'NOT USED' .AND. TRIM(si(jp_tsu)%clrootname) /= 'NOT USED' ) THEN ! if T_su is read and not T_s, set T_s = T_su
-               si(jp_tms)%fnow(:,:,1) = si(jp_tsu)%fnow(:,:,1)
-            ELSEIF( TRIM(si(jp_tms)%clrootname) == 'NOT USED' .AND. TRIM(si(jp_tmi)%clrootname) /= 'NOT USED' ) THEN ! if T_i is read and not T_s, set T_s = T_i
-               si(jp_tms)%fnow(:,:,1) = si(jp_tmi)%fnow(:,:,1)
-            ENDIF
-            !
-            ! pond concentration
-            IF( TRIM(si(jp_apd)%clrootname) == 'NOT USED' ) &
-               &     si(jp_apd)%fnow(:,:,1) = ( rn_apd_ini_n * zswitch + rn_apd_ini_s * (1._wp - zswitch) ) * tmask(:,:,1) & ! rn_apd = pond fraction => rn_apnd * a_i = pond conc.
-               &                              * si(jp_ati)%fnow(:,:,1) 
-            !
-            ! pond depth
-            IF( TRIM(si(jp_hpd)%clrootname) == 'NOT USED' ) &
-               &     si(jp_hpd)%fnow(:,:,1) = ( rn_hpd_ini_n * zswitch + rn_hpd_ini_s * (1._wp - zswitch) ) * tmask(:,:,1)
-            !
-            zsm_i_ini(:,:) = si(jp_smi)%fnow(:,:,1) * tmask(:,:,1)
-            ztm_i_ini(:,:) = si(jp_tmi)%fnow(:,:,1) * tmask(:,:,1)
-            zt_su_ini(:,:) = si(jp_tsu)%fnow(:,:,1) * tmask(:,:,1)
-            ztm_s_ini(:,:) = si(jp_tms)%fnow(:,:,1) * tmask(:,:,1)
-            zapnd_ini(:,:) = si(jp_apd)%fnow(:,:,1) * tmask(:,:,1)
-            zhpnd_ini(:,:) = si(jp_hpd)%fnow(:,:,1) * tmask(:,:,1)
-            !
-            ! change the switch for the following
-            WHERE( zat_i_ini(:,:) > 0._wp )   ;   zswitch(:,:) = tmask(:,:,1) 
-            ELSEWHERE                         ;   zswitch(:,:) = 0._wp
-            END WHERE
-            !                          !---------------!
-         ELSE                          ! Read namelist !
-            !                          !---------------!
-            ! no ice if (sst - Tfreez) >= thresold
-            WHERE( ( sst_m(:,:) - (t_bo(:,:) - rt0) ) * tmask(:,:,1) >= rn_thres_sst )   ;   zswitch(:,:) = 0._wp 
-            ELSEWHERE                                                                    ;   zswitch(:,:) = tmask(:,:,1)
-            END WHERE
-            !
-            ! assign initial thickness, concentration, snow depth and salinity to an hemisphere-dependent array
-            WHERE( ff_t(:,:) >= 0._wp )
-               zht_i_ini(:,:) = rn_hti_ini_n * zswitch(:,:)
-               zht_s_ini(:,:) = rn_hts_ini_n * zswitch(:,:)
-               zat_i_ini(:,:) = rn_ati_ini_n * zswitch(:,:)
-               zsm_i_ini(:,:) = rn_smi_ini_n * zswitch(:,:)
-               ztm_i_ini(:,:) = rn_tmi_ini_n * zswitch(:,:)
-               zt_su_ini(:,:) = rn_tsu_ini_n * zswitch(:,:)
-               ztm_s_ini(:,:) = rn_tms_ini_n * zswitch(:,:)
-               zapnd_ini(:,:) = rn_apd_ini_n * zswitch(:,:) * zat_i_ini(:,:) ! rn_apd = pond fraction => rn_apd * a_i = pond conc. 
-               zhpnd_ini(:,:) = rn_hpd_ini_n * zswitch(:,:)
-            ELSEWHERE
-               zht_i_ini(:,:) = rn_hti_ini_s * zswitch(:,:)
-               zht_s_ini(:,:) = rn_hts_ini_s * zswitch(:,:)
-               zat_i_ini(:,:) = rn_ati_ini_s * zswitch(:,:)
-               zsm_i_ini(:,:) = rn_smi_ini_s * zswitch(:,:)
-               ztm_i_ini(:,:) = rn_tmi_ini_s * zswitch(:,:)
-               zt_su_ini(:,:) = rn_tsu_ini_s * zswitch(:,:)
-               ztm_s_ini(:,:) = rn_tms_ini_s * zswitch(:,:)
-               zapnd_ini(:,:) = rn_apd_ini_s * zswitch(:,:) * zat_i_ini(:,:) ! rn_apd = pond fraction => rn_apd * a_i = pond conc.
-               zhpnd_ini(:,:) = rn_hpd_ini_s * zswitch(:,:)
-            END WHERE
-            !
-         ENDIF
-
-         ! make sure ponds = 0 if no ponds scheme
-         IF ( .NOT.ln_pnd ) THEN
-            zapnd_ini(:,:) = 0._wp
-            zhpnd_ini(:,:) = 0._wp
-         ENDIF
-         
-         !-------------!
-         ! fill fields !
-         !-------------!
-         ! select ice covered grid points
-         npti = 0 ; nptidx(:) = 0
-         DO_2D_11_11
-            IF ( zht_i_ini(ji,jj) > 0._wp ) THEN
-               npti         = npti  + 1
-               nptidx(npti) = (jj - 1) * jpi + ji
-            ENDIF
-         END_2D
-
-         ! move to 1D arrays: (jpi,jpj) -> (jpi*jpj)
-         CALL tab_2d_1d( npti, nptidx(1:npti), h_i_1d (1:npti)  , zht_i_ini )
-         CALL tab_2d_1d( npti, nptidx(1:npti), h_s_1d (1:npti)  , zht_s_ini )
-         CALL tab_2d_1d( npti, nptidx(1:npti), at_i_1d(1:npti)  , zat_i_ini )
-         CALL tab_2d_1d( npti, nptidx(1:npti), t_i_1d (1:npti,1), ztm_i_ini )
-         CALL tab_2d_1d( npti, nptidx(1:npti), t_s_1d (1:npti,1), ztm_s_ini )
-         CALL tab_2d_1d( npti, nptidx(1:npti), t_su_1d(1:npti)  , zt_su_ini )
-         CALL tab_2d_1d( npti, nptidx(1:npti), s_i_1d (1:npti)  , zsm_i_ini )
-         CALL tab_2d_1d( npti, nptidx(1:npti), a_ip_1d(1:npti)  , zapnd_ini )
-         CALL tab_2d_1d( npti, nptidx(1:npti), h_ip_1d(1:npti)  , zhpnd_ini )
-
-         ! allocate temporary arrays
-         ALLOCATE( zhi_2d(npti,jpl), zhs_2d(npti,jpl), zai_2d (npti,jpl), &
-            &      zti_2d(npti,jpl), zts_2d(npti,jpl), ztsu_2d(npti,jpl), zsi_2d(npti,jpl), zaip_2d(npti,jpl), zhip_2d(npti,jpl) )
-         
-         ! distribute 1-cat into jpl-cat: (jpi*jpj) -> (jpi*jpj,jpl)
-         CALL ice_var_itd( h_i_1d(1:npti)  , h_s_1d(1:npti)  , at_i_1d(1:npti),                                                   &
-            &              zhi_2d          , zhs_2d          , zai_2d         ,                                                   &
-            &              t_i_1d(1:npti,1), t_s_1d(1:npti,1), t_su_1d(1:npti), s_i_1d(1:npti), a_ip_1d(1:npti), h_ip_1d(1:npti), &
-            &              zti_2d          , zts_2d          , ztsu_2d        , zsi_2d        , zaip_2d        , zhip_2d )
-
-         ! move to 3D arrays: (jpi*jpj,jpl) -> (jpi,jpj,jpl)
-         DO jl = 1, jpl
-            zti_3d(:,:,jl) = rt0 * tmask(:,:,1)
-            zts_3d(:,:,jl) = rt0 * tmask(:,:,1)
-         END DO
-         CALL tab_2d_3d( npti, nptidx(1:npti), zhi_2d   , h_i    )
-         CALL tab_2d_3d( npti, nptidx(1:npti), zhs_2d   , h_s    )
-         CALL tab_2d_3d( npti, nptidx(1:npti), zai_2d   , a_i    )
-         CALL tab_2d_3d( npti, nptidx(1:npti), zti_2d   , zti_3d )
-         CALL tab_2d_3d( npti, nptidx(1:npti), zts_2d   , zts_3d )
-         CALL tab_2d_3d( npti, nptidx(1:npti), ztsu_2d  , t_su   )
-         CALL tab_2d_3d( npti, nptidx(1:npti), zsi_2d   , s_i    )
-         CALL tab_2d_3d( npti, nptidx(1:npti), zaip_2d  , a_ip   )
-         CALL tab_2d_3d( npti, nptidx(1:npti), zhip_2d  , h_ip   )
-
-         ! deallocate temporary arrays
-         DEALLOCATE( zhi_2d, zhs_2d, zai_2d , &
-            &        zti_2d, zts_2d, ztsu_2d, zsi_2d, zaip_2d, zhip_2d )
-
-         ! calculate extensive and intensive variables
-         CALL ice_var_salprof ! for sz_i
-         DO jl = 1, jpl
-            DO_2D_11_11
-               v_i (ji,jj,jl) = h_i(ji,jj,jl) * a_i(ji,jj,jl)
-               v_s (ji,jj,jl) = h_s(ji,jj,jl) * a_i(ji,jj,jl)
-               sv_i(ji,jj,jl) = MIN( MAX( rn_simin , s_i(ji,jj,jl) ) , rn_simax ) * v_i(ji,jj,jl)
-            END_2D
-         END DO
-         !
-         DO jl = 1, jpl
-            DO_3D_11_11( 1, nlay_s )
-               t_s(ji,jj,jk,jl) = zts_3d(ji,jj,jl)
-               e_s(ji,jj,jk,jl) = zswitch(ji,jj) * v_s(ji,jj,jl) * r1_nlay_s * &
-                  &               rhos * ( rcpi * ( rt0 - t_s(ji,jj,jk,jl) ) + rLfus )
-            END_3D
-         END DO
-         !
-         DO jl = 1, jpl
-            DO_3D_11_11( 1, nlay_i )
-               t_i (ji,jj,jk,jl) = zti_3d(ji,jj,jl) 
-               ztmelts          = - rTmlt * sz_i(ji,jj,jk,jl) + rt0 ! melting temperature in K
-               e_i(ji,jj,jk,jl) = zswitch(ji,jj) * v_i(ji,jj,jl) * r1_nlay_i * &
-                  &               rhoi * (  rcpi  * ( ztmelts - t_i(ji,jj,jk,jl) ) + &
-                  &                         rLfus * ( 1._wp - (ztmelts-rt0) / MIN( (t_i(ji,jj,jk,jl)-rt0), -epsi20 ) ) &
-                  &                       - rcp   * ( ztmelts - rt0 ) )
-            END_3D
-         END DO
-
+            DO jl = 1, jpl
+               DO_3D( 1, 1, 1, 1, 1, nlay_i )
+                  t_i (ji,jj,jk,jl) = zti_3d(ji,jj,jl) 
+                  ztmelts          = - rTmlt * sz_i(ji,jj,jk,jl) + rt0 ! melting temperature in K
+                  e_i(ji,jj,jk,jl) = zswitch(ji,jj) * v_i(ji,jj,jl) * r1_nlay_i * &
+                     &               rhoi * (  rcpi  * ( ztmelts - t_i(ji,jj,jk,jl) ) + &
+                     &                         rLfus * ( 1._wp - (ztmelts-rt0) / MIN( (t_i(ji,jj,jk,jl)-rt0), -epsi20 ) ) &
+                     &                       - rcp   * ( ztmelts - rt0 ) )
+               END_3D
+            END DO
+            
+#if  defined key_agrif
+         ELSE
+ 
+            Agrif_SpecialValue    = -9999.
+            Agrif_UseSpecialValue = .TRUE.
+            CALL Agrif_init_variable(tra_iceini_id,procname=interp_tra_ice)
+            use_sign_north = .TRUE.
+            sign_north = -1.
+            CALL Agrif_init_variable(u_iceini_id  ,procname=interp_u_ice)
+            CALL Agrif_init_variable(v_iceini_id  ,procname=interp_v_ice)
+            Agrif_SpecialValue    = 0._wp
+            use_sign_north = .FALSE.
+            Agrif_UseSpecialValue = .FALSE.
+        ! lbc ???? 
+   ! Here we know : a_i, v_i, v_s, sv_i, oa_i, a_ip, v_ip, v_il, t_su, e_s, e_i
+            CALL ice_var_glo2eqv
+            CALL ice_var_zapsmall
+            CALL ice_var_agg(2)
+#endif
+         ENDIF ! Agrif_Root
+         !
          ! Melt ponds
-         WHERE( a_i > epsi10 )
-            a_ip_frac(:,:,:) = a_ip(:,:,:) / a_i(:,:,:)
-         ELSEWHERE
-            a_ip_frac(:,:,:) = 0._wp
+         WHERE( a_i > epsi10 )   ;   a_ip_eff(:,:,:) = a_ip(:,:,:) / a_i(:,:,:)
+         ELSEWHERE               ;   a_ip_eff(:,:,:) = 0._wp
          END WHERE
          v_ip(:,:,:) = h_ip(:,:,:) * a_ip(:,:,:)
-          
+         v_il(:,:,:) = h_il(:,:,:) * a_ip(:,:,:)
+         
          ! specific temperatures for coupled runs
          tn_ice(:,:,:) = t_su(:,:,:)
          t1_ice(:,:,:) = t_i (:,:,1,:)
          !
+         ! ice concentration should not exceed amax
+         at_i(:,:) = SUM( a_i, dim=3 )
+         DO jl = 1, jpl
+            WHERE( at_i(:,:) > rn_amax_2d(:,:) )   a_i(:,:,jl) = a_i(:,:,jl) * rn_amax_2d(:,:) / at_i(:,:)
+         END DO
+         at_i(:,:) = SUM( a_i, dim=3 )
+         !
       ENDIF ! ln_iceini
       !
-      at_i(:,:) = SUM( a_i, dim=3 )
-      !
       !----------------------------------------------
-      ! 3) Snow-ice mass (case ice is fully embedded)
+      ! 4) Snow-ice mass (case ice is fully embedded)
       !----------------------------------------------
       snwice_mass  (:,:) = tmask(:,:,1) * SUM( rhos * v_s(:,:,:) + rhoi * v_i(:,:,:), dim=3  )   ! snow+ice mass
@@ -377,64 +434,50 @@
          ssh(:,:,Kbb) = ssh(:,:,Kbb) - snwice_mass(:,:) * r1_rho0
          !
-         IF( .NOT.ln_linssh ) THEN
-            !
-            WHERE( ht_0(:,:) > 0 )   ;   z2d(:,:) = 1._wp + ssh(:,:,Kmm)*tmask(:,:,1) / ht_0(:,:)
-            ELSEWHERE                ;   z2d(:,:) = 1._wp   ;   END WHERE
-            !
-            DO jk = 1,jpkm1                     ! adjust initial vertical scale factors                
-               e3t(:,:,jk,Kmm) = e3t_0(:,:,jk) * z2d(:,:)
-               e3t(:,:,jk,Kbb) = e3t(:,:,jk,Kmm)
-               e3t(:,:,jk,Kaa) = e3t(:,:,jk,Kmm)
-            END DO
-            !
-            ! Reconstruction of all vertical scale factors at now and before time-steps
-            ! =========================================================================
-            ! Horizontal scale factor interpolations
-            ! --------------------------------------
-            CALL dom_vvl_interpol( e3t(:,:,:,Kbb), e3u(:,:,:,Kbb), 'U' )
-            CALL dom_vvl_interpol( e3t(:,:,:,Kbb), e3v(:,:,:,Kbb), 'V' )
-            CALL dom_vvl_interpol( e3t(:,:,:,Kmm), e3u(:,:,:,Kmm), 'U' )
-            CALL dom_vvl_interpol( e3t(:,:,:,Kmm), e3v(:,:,:,Kmm), 'V' )
-            CALL dom_vvl_interpol( e3u(:,:,:,Kmm), e3f(:,:,:), 'F' )
-            ! Vertical scale factor interpolations
-            ! ------------------------------------
-            CALL dom_vvl_interpol( e3t(:,:,:,Kmm), e3w (:,:,:,Kmm), 'W'  )
-            CALL dom_vvl_interpol( e3u(:,:,:,Kmm), e3uw(:,:,:,Kmm), 'UW' )
-            CALL dom_vvl_interpol( e3v(:,:,:,Kmm), e3vw(:,:,:,Kmm), 'VW' )
-            CALL dom_vvl_interpol( e3u(:,:,:,Kbb), e3uw(:,:,:,Kbb), 'UW' )
-            CALL dom_vvl_interpol( e3v(:,:,:,Kbb), e3vw(:,:,:,Kbb), 'VW' )
-            ! t- and w- points depth
-            ! ----------------------
-            !!gm not sure of that....
-            gdept(:,:,1,Kmm) = 0.5_wp * e3w(:,:,1,Kmm)
-            gdepw(:,:,1,Kmm) = 0.0_wp
-            gde3w(:,:,1) = gdept(:,:,1,Kmm) - ssh(:,:,Kmm)
-            DO jk = 2, jpk
-               gdept(:,:,jk,Kmm) = gdept(:,:,jk-1,Kmm) + e3w(:,:,jk  ,Kmm)
-               gdepw(:,:,jk,Kmm) = gdepw(:,:,jk-1,Kmm) + e3t(:,:,jk-1,Kmm)
-               gde3w(:,:,jk) = gdept(:,:,jk  ,Kmm) - ssh (:,:,Kmm)
-            END DO
-         ENDIF
+         IF( .NOT.ln_linssh )   CALL dom_vvl_zgr( Kbb, Kmm, Kaa )   ! interpolation scale factor, depth and water column
+! !!st
+!          IF( .NOT.ln_linssh ) THEN
+!             !
+!             WHERE( ht_0(:,:) > 0 )   ;   z2d(:,:) = 1._wp + ssh(:,:,Kmm)*tmask(:,:,1) / ht_0(:,:)
+!             ELSEWHERE                ;   z2d(:,:) = 1._wp   ;   END WHERE
+!             !
+!             DO jk = 1,jpkm1                     ! adjust initial vertical scale factors
+!                e3t(:,:,jk,Kmm) = e3t_0(:,:,jk) * z2d(:,:)
+!                e3t(:,:,jk,Kbb) = e3t(:,:,jk,Kmm)
+!                e3t(:,:,jk,Kaa) = e3t(:,:,jk,Kmm)
+!             END DO
+!             !
+!             ! Reconstruction of all vertical scale factors at now and before time-steps
+!             ! =========================================================================
+!             ! Horizontal scale factor interpolations
+!             ! --------------------------------------
+!             CALL dom_vvl_interpol( e3t(:,:,:,Kbb), e3u(:,:,:,Kbb), 'U' )
+!             CALL dom_vvl_interpol( e3t(:,:,:,Kbb), e3v(:,:,:,Kbb), 'V' )
+!             CALL dom_vvl_interpol( e3t(:,:,:,Kmm), e3u(:,:,:,Kmm), 'U' )
+!             CALL dom_vvl_interpol( e3t(:,:,:,Kmm), e3v(:,:,:,Kmm), 'V' )
+!             CALL dom_vvl_interpol( e3u(:,:,:,Kmm), e3f(:,:,:), 'F' )
+!             ! Vertical scale factor interpolations
+!             ! ------------------------------------
+!             CALL dom_vvl_interpol( e3t(:,:,:,Kmm), e3w (:,:,:,Kmm), 'W'  )
+!             CALL dom_vvl_interpol( e3u(:,:,:,Kmm), e3uw(:,:,:,Kmm), 'UW' )
+!             CALL dom_vvl_interpol( e3v(:,:,:,Kmm), e3vw(:,:,:,Kmm), 'VW' )
+!             CALL dom_vvl_interpol( e3u(:,:,:,Kbb), e3uw(:,:,:,Kbb), 'UW' )
+!             CALL dom_vvl_interpol( e3v(:,:,:,Kbb), e3vw(:,:,:,Kbb), 'VW' )
+!             ! t- and w- points depth
+!             ! ----------------------
+!             !!gm not sure of that....
+!             gdept(:,:,1,Kmm) = 0.5_wp * e3w(:,:,1,Kmm)
+!             gdepw(:,:,1,Kmm) = 0.0_wp
+!             gde3w(:,:,1) = gdept(:,:,1,Kmm) - ssh(:,:,Kmm)
+!             DO jk = 2, jpk
+!                gdept(:,:,jk,Kmm) = gdept(:,:,jk-1,Kmm) + e3w(:,:,jk  ,Kmm)
+!                gdepw(:,:,jk,Kmm) = gdepw(:,:,jk-1,Kmm) + e3t(:,:,jk-1,Kmm)
+!                gde3w(:,:,jk) = gdept(:,:,jk  ,Kmm) - ssh (:,:,Kmm)
+!             END DO
+!          ENDIF
       ENDIF
-      
-      !------------------------------------
-      ! 4) store fields at before time-step
-      !------------------------------------
-      ! it is only necessary for the 1st interpolation by Agrif
-      a_i_b  (:,:,:)   = a_i  (:,:,:)
-      e_i_b  (:,:,:,:) = e_i  (:,:,:,:)
-      v_i_b  (:,:,:)   = v_i  (:,:,:)
-      v_s_b  (:,:,:)   = v_s  (:,:,:)
-      e_s_b  (:,:,:,:) = e_s  (:,:,:,:)
-      sv_i_b (:,:,:)   = sv_i (:,:,:)
-      oa_i_b (:,:,:)   = oa_i (:,:,:)
-      u_ice_b(:,:)     = u_ice(:,:)
-      v_ice_b(:,:)     = v_ice(:,:)
-      ! total concentration is needed for Lupkes parameterizations
-      at_i_b (:,:)     = at_i (:,:) 
-
-!!clem: output of initial state should be written here but it is impossible because
-!!      the ocean and ice are in the same file
-!!      CALL dia_wri_state( Kmm, 'output.init' )
+
+      !!clem: output of initial state should be written here but it is impossible because
+      !!      the ocean and ice are in the same file
+      !!      CALL dia_wri_state( 'output.init' )
       !
    END SUBROUTINE ice_istate
@@ -457,13 +500,13 @@
       !
       CHARACTER(len=256) ::  cn_dir          ! Root directory for location of ice files
-      TYPE(FLD_N)                    ::   sn_hti, sn_hts, sn_ati, sn_smi, sn_tmi, sn_tsu, sn_tms, sn_apd, sn_hpd
+      TYPE(FLD_N)                    ::   sn_hti, sn_hts, sn_ati, sn_smi, sn_tmi, sn_tsu, sn_tms, sn_apd, sn_hpd, sn_hld
       TYPE(FLD_N), DIMENSION(jpfldi) ::   slf_i                 ! array of namelist informations on the fields to read
       !
-      NAMELIST/namini/ ln_iceini, ln_iceini_file, rn_thres_sst, &
+      NAMELIST/namini/ ln_iceini, nn_iceini_file, rn_thres_sst, &
          &             rn_hti_ini_n, rn_hti_ini_s, rn_hts_ini_n, rn_hts_ini_s, &
          &             rn_ati_ini_n, rn_ati_ini_s, rn_smi_ini_n, rn_smi_ini_s, &
          &             rn_tmi_ini_n, rn_tmi_ini_s, rn_tsu_ini_n, rn_tsu_ini_s, rn_tms_ini_n, rn_tms_ini_s, &
-         &             rn_apd_ini_n, rn_apd_ini_s, rn_hpd_ini_n, rn_hpd_ini_s, &
-         &             sn_hti, sn_hts, sn_ati, sn_tsu, sn_tmi, sn_smi, sn_tms, sn_apd, sn_hpd, cn_dir
+         &             rn_apd_ini_n, rn_apd_ini_s, rn_hpd_ini_n, rn_hpd_ini_s, rn_hld_ini_n, rn_hld_ini_s, &
+         &             sn_hti, sn_hts, sn_ati, sn_tsu, sn_tmi, sn_smi, sn_tms, sn_apd, sn_hpd, sn_hld, cn_dir
       !!-----------------------------------------------------------------------------
       !
@@ -477,5 +520,5 @@
       slf_i(jp_ati) = sn_ati  ;  slf_i(jp_smi) = sn_smi
       slf_i(jp_tmi) = sn_tmi  ;  slf_i(jp_tsu) = sn_tsu   ;   slf_i(jp_tms) = sn_tms
-      slf_i(jp_apd) = sn_apd  ;  slf_i(jp_hpd) = sn_hpd
+      slf_i(jp_apd) = sn_apd  ;  slf_i(jp_hpd) = sn_hpd   ;   slf_i(jp_hld) = sn_hld
       !
       IF(lwp) THEN                          ! control print
@@ -485,7 +528,7 @@
          WRITE(numout,*) '   Namelist namini:'
          WRITE(numout,*) '      ice initialization (T) or not (F)                ln_iceini      = ', ln_iceini
-         WRITE(numout,*) '      ice initialization from a netcdf file            ln_iceini_file = ', ln_iceini_file
+         WRITE(numout,*) '      ice initialization from a netcdf file            nn_iceini_file = ', nn_iceini_file
          WRITE(numout,*) '      max ocean temp. above Tfreeze with initial ice   rn_thres_sst   = ', rn_thres_sst
-         IF( ln_iceini .AND. .NOT.ln_iceini_file ) THEN
+         IF( ln_iceini .AND. nn_iceini_file == 0 ) THEN
             WRITE(numout,*) '      initial snw thickness in the north-south         rn_hts_ini     = ', rn_hts_ini_n,rn_hts_ini_s 
             WRITE(numout,*) '      initial ice thickness in the north-south         rn_hti_ini     = ', rn_hti_ini_n,rn_hti_ini_s
@@ -497,8 +540,9 @@
             WRITE(numout,*) '      initial pnd fraction  in the north-south         rn_apd_ini     = ', rn_apd_ini_n,rn_apd_ini_s
             WRITE(numout,*) '      initial pnd depth     in the north-south         rn_hpd_ini     = ', rn_hpd_ini_n,rn_hpd_ini_s
+            WRITE(numout,*) '      initial pnd lid depth in the north-south         rn_hld_ini     = ', rn_hld_ini_n,rn_hld_ini_s
          ENDIF
       ENDIF
       !
-      IF( ln_iceini_file ) THEN                      ! Ice initialization using input file
+      IF( nn_iceini_file == 1 ) THEN                      ! Ice initialization using input file
          !
          ! set si structure
@@ -521,5 +565,10 @@
          rn_apd_ini_n = 0. ; rn_apd_ini_s = 0.
          rn_hpd_ini_n = 0. ; rn_hpd_ini_s = 0.
-         CALL ctl_warn( 'rn_apd_ini & rn_hpd_ini = 0 when no ponds' )
+         rn_hld_ini_n = 0. ; rn_hld_ini_s = 0.
+         CALL ctl_warn( 'rn_apd_ini & rn_hpd_ini = 0 & rn_hld_ini = 0 when no ponds' )
+      ENDIF
+      !
+      IF( .NOT.ln_pnd_lids ) THEN
+         rn_hld_ini_n = 0. ; rn_hld_ini_s = 0.
       ENDIF
       !
Index: NEMO/branches/2020/dev_12905_xios_restart/src/ICE/iceitd.F90
===================================================================
--- NEMO/branches/2020/dev_12905_xios_restart/src/ICE/iceitd.F90	(revision 13033)
+++ NEMO/branches/2020/dev_12905_xios_restart/src/ICE/iceitd.F90	(revision 13727)
@@ -47,4 +47,5 @@
    LOGICAL                    ::   ln_cat_usr   ! ice categories are defined by rn_catbnd
    REAL(wp), DIMENSION(0:100) ::   rn_catbnd    ! ice categories bounds
+   REAL(wp)                   ::   rn_himax     ! maximum ice thickness allowed
    !
    !! * Substitutions
@@ -98,5 +99,5 @@
       !
       npti = 0   ;   nptidx(:) = 0
-      DO_2D_11_11
+      DO_2D( 1, 1, 1, 1 )
          IF ( at_i(ji,jj) > epsi10 ) THEN
             npti = npti + 1
@@ -148,6 +149,11 @@
                !    Note: hn(t+1) must not be too close to either HR or HL otherwise a division by nearly 0 is possible 
                !          in itd_glinear in the case (HR-HL) = 3(Hice - HL) or = 3(HR - Hice)
+# if defined key_single
+               IF( a_i_2d(ji,jl  ) > epsi10 .AND. h_i_2d(ji,jl  ) > ( zhbnew(ji,jl) - epsi06 ) )   nptidx(ji) = 0
+               IF( a_i_2d(ji,jl+1) > epsi10 .AND. h_i_2d(ji,jl+1) < ( zhbnew(ji,jl) + epsi06 ) )   nptidx(ji) = 0
+# else
                IF( a_i_2d(ji,jl  ) > epsi10 .AND. h_i_2d(ji,jl  ) > ( zhbnew(ji,jl) - epsi10 ) )   nptidx(ji) = 0
                IF( a_i_2d(ji,jl+1) > epsi10 .AND. h_i_2d(ji,jl+1) < ( zhbnew(ji,jl) + epsi10 ) )   nptidx(ji) = 0
+# endif
                !
                ! 2) Hn-1 < Hn* < Hn+1  
@@ -170,6 +176,11 @@
             !    h1(t) must not be too close to either HR or HL otherwise a division by nearly 0 is possible 
             !    in itd_glinear in the case (HR-HL) = 3(Hice - HL) or = 3(HR - Hice)
+# if defined key_single
+            IF( h_ib_2d(ji,1) < ( hi_max(0) + epsi06 ) )   nptidx(ji) = 0
+            IF( h_ib_2d(ji,1) > ( hi_max(1) - epsi06 ) )   nptidx(ji) = 0
+# else
             IF( h_ib_2d(ji,1) < ( hi_max(0) + epsi10 ) )   nptidx(ji) = 0
             IF( h_ib_2d(ji,1) > ( hi_max(1) - epsi10 ) )   nptidx(ji) = 0
+# endif
          END DO
          !
@@ -304,5 +315,5 @@
             IF ( a_i_1d(ji) > epsi10 .AND. h_i_1d(ji) < rn_himin ) THEN
                a_i_1d(ji) = a_i_1d(ji) * h_i_1d(ji) / rn_himin 
-               IF( ln_pnd_H12 )   a_ip_1d(ji) = a_ip_1d(ji) * h_i_1d(ji) / rn_himin
+               IF( ln_pnd_LEV )   a_ip_1d(ji) = a_ip_1d(ji) * h_i_1d(ji) / rn_himin
                h_i_1d(ji) = rn_himin
             ENDIF
@@ -410,4 +421,5 @@
       CALL tab_3d_2d( npti, nptidx(1:npti), a_ip_2d(1:npti,1:jpl), a_ip )
       CALL tab_3d_2d( npti, nptidx(1:npti), v_ip_2d(1:npti,1:jpl), v_ip )
+      CALL tab_3d_2d( npti, nptidx(1:npti), v_il_2d(1:npti,1:jpl), v_il )
       CALL tab_3d_2d( npti, nptidx(1:npti), t_su_2d(1:npti,1:jpl), t_su )
       DO jl = 1, jpl
@@ -474,5 +486,5 @@
                zaTsfn(ji,jl2)  = zaTsfn(ji,jl2) + ztrans
                !  
-               IF ( ln_pnd_H12 ) THEN
+               IF ( ln_pnd_LEV ) THEN
                   ztrans          = a_ip_2d(ji,jl1) * zworka(ji)     ! Pond fraction
                   a_ip_2d(ji,jl1) = a_ip_2d(ji,jl1) - ztrans
@@ -482,4 +494,10 @@
                   v_ip_2d(ji,jl1) = v_ip_2d(ji,jl1) - ztrans
                   v_ip_2d(ji,jl2) = v_ip_2d(ji,jl2) + ztrans
+                  !
+                  IF ( ln_pnd_lids ) THEN                            ! Pond lid volume
+                     ztrans          = v_il_2d(ji,jl1) * zworka(ji)
+                     v_il_2d(ji,jl1) = v_il_2d(ji,jl1) - ztrans
+                     v_il_2d(ji,jl2) = v_il_2d(ji,jl2) + ztrans
+                  ENDIF
                ENDIF
                !
@@ -526,5 +544,5 @@
       ! clem: The transfer between one category to another can lead to very small negative values (-1.e-20)
       !       because of truncation error ( i.e. 1. - 1. /= 0 )
-      CALL ice_var_roundoff( a_i_2d, v_i_2d, v_s_2d, sv_i_2d, oa_i_2d, a_ip_2d, v_ip_2d, ze_s_2d, ze_i_2d )
+      CALL ice_var_roundoff( a_i_2d, v_i_2d, v_s_2d, sv_i_2d, oa_i_2d, a_ip_2d, v_ip_2d, v_il_2d, ze_s_2d, ze_i_2d )
 
       ! at_i must be <= rn_amax
@@ -538,5 +556,9 @@
       ! 4) Update ice thickness and temperature
       !-------------------------------------------------------------------------------
+# if defined key_single
+      WHERE( a_i_2d(1:npti,:) >= epsi06 )
+# else
       WHERE( a_i_2d(1:npti,:) >= epsi20 )
+# endif
          h_i_2d (1:npti,:)  =  v_i_2d(1:npti,:) / a_i_2d(1:npti,:) 
          t_su_2d(1:npti,:)  =  zaTsfn(1:npti,:) / a_i_2d(1:npti,:) 
@@ -554,4 +576,5 @@
       CALL tab_2d_3d( npti, nptidx(1:npti), a_ip_2d(1:npti,1:jpl), a_ip )
       CALL tab_2d_3d( npti, nptidx(1:npti), v_ip_2d(1:npti,1:jpl), v_ip )
+      CALL tab_2d_3d( npti, nptidx(1:npti), v_il_2d(1:npti,1:jpl), v_il )
       CALL tab_2d_3d( npti, nptidx(1:npti), t_su_2d(1:npti,1:jpl), t_su )
       DO jl = 1, jpl
@@ -597,5 +620,5 @@
          !                    !---------------------------------------
          npti = 0   ;   nptidx(:) = 0
-         DO_2D_11_11
+         DO_2D( 1, 1, 1, 1 )
             IF( a_i(ji,jj,jl) > 0._wp .AND. v_i(ji,jj,jl) > (a_i(ji,jj,jl) * hi_max(jl)) ) THEN
                npti = npti + 1
@@ -604,23 +627,23 @@
          END_2D
          !
-!!clem   CALL tab_2d_1d( npti, nptidx(1:npti), h_i_1d(1:npti), h_i(:,:,jl) )
-         CALL tab_2d_1d( npti, nptidx(1:npti), a_i_1d(1:npti), a_i(:,:,jl) )
-         CALL tab_2d_1d( npti, nptidx(1:npti), v_i_1d(1:npti), v_i(:,:,jl) )
-         !
-         DO ji = 1, npti
-            jdonor(ji,jl)  = jl 
-            ! how much of a_i you send in cat sup is somewhat arbitrary
-!!clem: these do not work properly after a restart (I do not know why) => not sure it is still true
-!!          zdaice(ji,jl)  = a_i_1d(ji) * ( h_i_1d(ji) - hi_max(jl) + epsi10 ) / h_i_1d(ji)  
-!!          zdvice(ji,jl)  = v_i_1d(ji) - ( a_i_1d(ji) - zdaice(ji,jl) ) * ( hi_max(jl) - epsi10 )
-!!clem: these do not work properly after a restart (I do not know why) => not sure it is still true
-!!          zdaice(ji,jl)  = a_i_1d(ji)
-!!          zdvice(ji,jl)  = v_i_1d(ji)
-!!clem: these are from UCL and work ok
-            zdaice(ji,jl)  = a_i_1d(ji) * 0.5_wp
-            zdvice(ji,jl)  = v_i_1d(ji) - zdaice(ji,jl) * ( hi_max(jl) + hi_max(jl-1) ) * 0.5_wp
-         END DO
-         !
-         IF( npti > 0 ) THEN
+         IF( npti > 0 ) THEN            
+            !!clem   CALL tab_2d_1d( npti, nptidx(1:npti), h_i_1d(1:npti), h_i(:,:,jl) )
+            CALL tab_2d_1d( npti, nptidx(1:npti), a_i_1d(1:npti), a_i(:,:,jl) )
+            CALL tab_2d_1d( npti, nptidx(1:npti), v_i_1d(1:npti), v_i(:,:,jl) )
+            !
+            DO ji = 1, npti
+               jdonor(ji,jl)  = jl 
+               ! how much of a_i you send in cat sup is somewhat arbitrary
+               !!clem: these do not work properly after a restart (I do not know why) => not sure it is still true
+               !!          zdaice(ji,jl)  = a_i_1d(ji) * ( h_i_1d(ji) - hi_max(jl) + epsi10 ) / h_i_1d(ji)  
+               !!          zdvice(ji,jl)  = v_i_1d(ji) - ( a_i_1d(ji) - zdaice(ji,jl) ) * ( hi_max(jl) - epsi10 )
+               !!clem: these do not work properly after a restart (I do not know why) => not sure it is still true
+               !!          zdaice(ji,jl)  = a_i_1d(ji)
+               !!          zdvice(ji,jl)  = v_i_1d(ji)
+               !!clem: these are from UCL and work ok
+               zdaice(ji,jl)  = a_i_1d(ji) * 0.5_wp
+               zdvice(ji,jl)  = v_i_1d(ji) - zdaice(ji,jl) * ( hi_max(jl) + hi_max(jl-1) ) * 0.5_wp
+            END DO
+            !
             CALL itd_shiftice( jdonor(1:npti,:), zdaice(1:npti,:), zdvice(1:npti,:) )  ! Shift jl=>jl+1
             ! Reset shift parameters
@@ -636,5 +659,5 @@
          !                    !-----------------------------------------
          npti = 0 ; nptidx(:) = 0
-         DO_2D_11_11
+         DO_2D( 1, 1, 1, 1 )
             IF( a_i(ji,jj,jl+1) > 0._wp .AND. v_i(ji,jj,jl+1) <= (a_i(ji,jj,jl+1) * hi_max(jl)) ) THEN
                npti = npti + 1
@@ -643,13 +666,13 @@
          END_2D
          !
-         CALL tab_2d_1d( npti, nptidx(1:npti), a_i_1d(1:npti), a_i(:,:,jl+1) ) ! jl+1 is ok
-         CALL tab_2d_1d( npti, nptidx(1:npti), v_i_1d(1:npti), v_i(:,:,jl+1) ) ! jl+1 is ok
-         DO ji = 1, npti
-            jdonor(ji,jl) = jl + 1
-            zdaice(ji,jl) = a_i_1d(ji) 
-            zdvice(ji,jl) = v_i_1d(ji)
-         END DO
-         !
          IF( npti > 0 ) THEN
+            CALL tab_2d_1d( npti, nptidx(1:npti), a_i_1d(1:npti), a_i(:,:,jl+1) ) ! jl+1 is ok
+            CALL tab_2d_1d( npti, nptidx(1:npti), v_i_1d(1:npti), v_i(:,:,jl+1) ) ! jl+1 is ok
+            DO ji = 1, npti
+               jdonor(ji,jl) = jl + 1
+               zdaice(ji,jl) = a_i_1d(ji) 
+               zdvice(ji,jl) = v_i_1d(ji)
+            END DO
+            !
             CALL itd_shiftice( jdonor(1:npti,:), zdaice(1:npti,:), zdvice(1:npti,:) )  ! Shift jl+1=>jl
             ! Reset shift parameters
@@ -679,5 +702,5 @@
       REAL(wp) ::   zhmax, znum, zden, zalpha   !   -      -
       !
-      NAMELIST/namitd/ ln_cat_hfn, rn_himean, ln_cat_usr, rn_catbnd, rn_himin
+      NAMELIST/namitd/ ln_cat_hfn, rn_himean, ln_cat_usr, rn_catbnd, rn_himin, rn_himax
       !!------------------------------------------------------------------
       !
@@ -696,5 +719,6 @@
          WRITE(numout,*) '         mean ice thickness in the domain                               rn_himean  = ', rn_himean
          WRITE(numout,*) '      Ice categories are defined by rn_catbnd                           ln_cat_usr = ', ln_cat_usr
-         WRITE(numout,*) '      minimum ice thickness                                             rn_himin   = ', rn_himin 
+         WRITE(numout,*) '      minimum ice thickness allowed                                     rn_himin   = ', rn_himin 
+         WRITE(numout,*) '      maximum ice thickness allowed                                     rn_himax   = ', rn_himax 
       ENDIF
       !
@@ -733,5 +757,5 @@
       END DO
       !
-      hi_max(jpl) = 99._wp          ! set to a big value to ensure that all ice is thinner than hi_max(jpl)
+      hi_max(jpl) = rn_himax        ! set to a big value to ensure that all ice is thinner than hi_max(jpl)
       !
       IF(lwp) WRITE(numout,*)
Index: NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icerst.F90
===================================================================
--- NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icerst.F90	(revision 13033)
+++ NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icerst.F90	(revision 13727)
@@ -18,4 +18,8 @@
    USE phycst  , ONLY : rt0
    USE sbc_oce , ONLY : nn_fsbc, ln_cpl
+   USE sbc_oce , ONLY : nn_components, jp_iam_sas   ! SAS ss[st]_m init
+   USE sbc_oce , ONLY : sst_m, sss_m                ! SAS ss[st]_m init
+   USE oce     , ONLY : ts                          ! SAS ss[st]_m init
+   USE eosbn2  , ONLY : l_useCT, eos_pt_from_ct     ! SAS ss[st]_m init
    USE iceistate      ! sea-ice: initial state
    USE icectl         ! sea-ice: control
@@ -141,14 +145,15 @@
 
       ! Prognostic variables
-      CALL iom_rstput( iter, nitrst, numriw, 'v_i'  , v_i,   ldxios = lwxios )
-      CALL iom_rstput( iter, nitrst, numriw, 'v_s'  , v_s,   ldxios = lwxios )
-      CALL iom_rstput( iter, nitrst, numriw, 'sv_i' , sv_i,  ldxios = lwxios )
-      CALL iom_rstput( iter, nitrst, numriw, 'a_i'  , a_i,   ldxios = lwxios )
-      CALL iom_rstput( iter, nitrst, numriw, 't_su' , t_su,  ldxios = lwxios )
+      CALL iom_rstput( iter, nitrst, numriw, 'v_i'  , v_i  , ldxios = lwxios )
+      CALL iom_rstput( iter, nitrst, numriw, 'v_s'  , v_s  , ldxios = lwxios )
+      CALL iom_rstput( iter, nitrst, numriw, 'sv_i' , sv_i , ldxios = lwxios )
+      CALL iom_rstput( iter, nitrst, numriw, 'a_i'  , a_i  , ldxios = lwxios )
+      CALL iom_rstput( iter, nitrst, numriw, 't_su' , t_su , ldxios = lwxios )
       CALL iom_rstput( iter, nitrst, numriw, 'u_ice', u_ice, ldxios = lwxios )
       CALL iom_rstput( iter, nitrst, numriw, 'v_ice', v_ice, ldxios = lwxios )
-      CALL iom_rstput( iter, nitrst, numriw, 'oa_i' , oa_i,  ldxios = lwxios )
-      CALL iom_rstput( iter, nitrst, numriw, 'a_ip' , a_ip,  ldxios = lwxios )
-      CALL iom_rstput( iter, nitrst, numriw, 'v_ip' , v_ip,  ldxios = lwxios )
+      CALL iom_rstput( iter, nitrst, numriw, 'oa_i' , oa_i , ldxios = lwxios )
+      CALL iom_rstput( iter, nitrst, numriw, 'a_ip' , a_ip , ldxios = lwxios )
+      CALL iom_rstput( iter, nitrst, numriw, 'v_ip' , v_ip , ldxios = lwxios )
+      CALL iom_rstput( iter, nitrst, numriw, 'v_il' , v_il , ldxios = lwxios )
       ! Snow enthalpy
       DO jk = 1, nlay_s 
@@ -196,5 +201,5 @@
       INTEGER           ::   jk
       LOGICAL           ::   llok
-      INTEGER           ::   id0, id1, id2, id3, id4   ! local integer
+      INTEGER           ::   id0, id1, id2, id3, id4, id5   ! local integer
       CHARACTER(len=25) ::   znam
       CHARACTER(len=2)  ::   zchar, zchar1
@@ -250,16 +255,16 @@
 
          ! --- mandatory fields --- ! 
-         CALL iom_get( numrir, jpdom_autoglo, 'v_i'  , v_i,   ldxios = lrixios )
-         CALL iom_get( numrir, jpdom_autoglo, 'v_s'  , v_s,   ldxios = lrixios )
-         CALL iom_get( numrir, jpdom_autoglo, 'sv_i' , sv_i,  ldxios = lrixios )
-         CALL iom_get( numrir, jpdom_autoglo, 'a_i'  , a_i,   ldxios = lrixios )
-         CALL iom_get( numrir, jpdom_autoglo, 't_su' , t_su,  ldxios = lrixios )
-         CALL iom_get( numrir, jpdom_autoglo, 'u_ice', u_ice, ldxios = lrixios )
-         CALL iom_get( numrir, jpdom_autoglo, 'v_ice', v_ice, ldxios = lrixios )
+         CALL iom_get( numrir, jpdom_auto, 'v_i'  , v_i  , ldxios = lrixios )
+         CALL iom_get( numrir, jpdom_auto, 'v_s'  , v_s  , ldxios = lrixios )
+         CALL iom_get( numrir, jpdom_auto, 'sv_i' , sv_i , ldxios = lrixios )
+         CALL iom_get( numrir, jpdom_auto, 'a_i'  , a_i  , ldxios = lrixios )
+         CALL iom_get( numrir, jpdom_auto, 't_su' , t_su , ldxios = lrixios )
+         CALL iom_get( numrir, jpdom_auto, 'u_ice', u_ice, cd_type = 'U', psgn = -1._wp, ldxios = lrixios )
+         CALL iom_get( numrir, jpdom_auto, 'v_ice', v_ice, cd_type = 'V', psgn = -1._wp, ldxios = lrixios )
          ! Snow enthalpy
          DO jk = 1, nlay_s
             WRITE(zchar1,'(I2.2)') jk
             znam = 'e_s'//'_l'//zchar1
-            CALL iom_get( numrir, jpdom_autoglo, znam , z3d, ldxios = lrixios )
+            CALL iom_get( numrir, jpdom_auto, znam , z3d, ldxios = lrixios )
             e_s(:,:,jk,:) = z3d(:,:,:)
          END DO
@@ -268,5 +273,5 @@
             WRITE(zchar1,'(I2.2)') jk
             znam = 'e_i'//'_l'//zchar1
-            CALL iom_get( numrir, jpdom_autoglo, znam , z3d, ldxios = lrixios )
+            CALL iom_get( numrir, jpdom_auto, znam , z3d, ldxios = lrixios )
             e_i(:,:,jk,:) = z3d(:,:,:)
          END DO
@@ -275,5 +280,5 @@
          id1 = iom_varid( numrir, 'oa_i' , ldstop = .FALSE. )
          IF( id1 > 0 ) THEN                       ! fields exist
-            CALL iom_get( numrir, jpdom_autoglo, 'oa_i', oa_i, ldxios = lrixios )
+            CALL iom_get( numrir, jpdom_auto, 'oa_i', oa_i, ldxios = lrixios )
          ELSE                                     ! start from rest
             IF(lwp) WRITE(numout,*) '   ==>>   previous run without ice age output then set it to zero'
@@ -283,6 +288,6 @@
          id2 = iom_varid( numrir, 'a_ip' , ldstop = .FALSE. )
          IF( id2 > 0 ) THEN                       ! fields exist
-            CALL iom_get( numrir, jpdom_autoglo, 'a_ip' , a_ip, ldxios = lrixios )
-            CALL iom_get( numrir, jpdom_autoglo, 'v_ip' , v_ip, ldxios = lrixios )
+            CALL iom_get( numrir, jpdom_auto, 'a_ip' , a_ip, ldxios = lrixios )
+            CALL iom_get( numrir, jpdom_auto, 'v_ip' , v_ip, ldxios = lrixios )
          ELSE                                     ! start from rest
             IF(lwp) WRITE(numout,*) '   ==>>   previous run without melt ponds output then set it to zero'
@@ -290,11 +295,19 @@
             v_ip(:,:,:) = 0._wp
          ENDIF
+         ! melt pond lids
+         id3 = iom_varid( numrir, 'v_il' , ldstop = .FALSE. )
+         IF( id3 > 0 ) THEN
+            CALL iom_get( numrir, jpdom_auto, 'v_il', v_il, ldxios = lrixios)
+         ELSE
+            IF(lwp) WRITE(numout,*) '   ==>>   previous run without melt ponds lids output then set it to zero'
+            v_il(:,:,:) = 0._wp
+         ENDIF
          ! fields needed for Met Office (Jules) coupling
          IF( ln_cpl ) THEN
-            id3 = iom_varid( numrir, 'cnd_ice' , ldstop = .FALSE. )
-            id4 = iom_varid( numrir, 't1_ice'  , ldstop = .FALSE. )
-            IF( id3 > 0 .AND. id4 > 0 ) THEN         ! fields exist
-               CALL iom_get( numrir, jpdom_autoglo, 'cnd_ice', cnd_ice, ldxios = lrixios )
-               CALL iom_get( numrir, jpdom_autoglo, 't1_ice' , t1_ice,  ldxios = lrixios )
+            id4 = iom_varid( numrir, 'cnd_ice' , ldstop = .FALSE. )
+            id5 = iom_varid( numrir, 't1_ice'  , ldstop = .FALSE. )
+            IF( id4 > 0 .AND. id5 > 0 ) THEN         ! fields exist
+               CALL iom_get( numrir, jpdom_auto, 'cnd_ice', cnd_ice, ldxios = lrixios )
+               CALL iom_get( numrir, jpdom_auto, 't1_ice' , t1_ice , ldxios = lrixios )
             ELSE                                     ! start from rest
                IF(lwp) WRITE(numout,*) '   ==>>   previous run without conductivity output then set it to zero'
@@ -309,12 +322,23 @@
       ELSE                 ! == case of a simplified restart == !
          !                 ! ---------------------------------- !
-         CALL ctl_warn('ice_rst_read: you are using a simplified ice restart')
+         CALL ctl_warn('ice_rst_read: you are attempting to use an unsuitable ice restart')
          !
-         CALL ice_istate_init
+         IF( .NOT. ln_iceini .OR. nn_iceini_file == 2 ) THEN
+            CALL ctl_stop('STOP', 'ice_rst_read: you need ln_ice_ini=T and nn_iceini_file=0 or 1')
+         ELSE
+            CALL ctl_warn('ice_rst_read: using ice_istate to set initial conditions instead')
+         ENDIF
+         !
+         IF( nn_components == jp_iam_sas ) THEN   ! SAS case: ss[st]_m were not initialized by sbc_ssm_init
+            !
+            IF(lwp) WRITE(numout,*) '  SAS: default initialisation of ss[st]_m arrays used in ice_istate'
+            IF( l_useCT )  THEN    ;   sst_m(:,:) = eos_pt_from_ct( ts(:,:,1,jp_tem, Kmm), ts(:,:,1,jp_sal, Kmm) )
+            ELSE                   ;   sst_m(:,:) = ts(:,:,1,jp_tem, Kmm)
+            ENDIF
+            sss_m(:,:) = ts(:,:,1,jp_sal, Kmm)
+         ENDIF
+         !
          CALL ice_istate( nit000, Kbb, Kmm, Kaa )
          !
-         IF( .NOT.ln_iceini .OR. .NOT.ln_iceini_file ) &
-            &   CALL ctl_stop('STOP', 'ice_rst_read: you need ln_ice_ini=T and ln_iceini_file=T')
-         !
       ENDIF
 
Index: NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icesbc.F90
===================================================================
--- NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icesbc.F90	(revision 13033)
+++ NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icesbc.F90	(revision 13727)
@@ -82,9 +82,9 @@
       IF( ln_mixcpl) THEN                                                        ! Case of a mixed Bulk/Coupled formulation
                                    CALL sbc_cpl_ice_tau( zutau_ice , zvtau_ice )
-         DO_2D_00_00
+         DO_2D( 0, 0, 0, 0 )
             utau_ice(ji,jj) = utau_ice(ji,jj) * xcplmask(ji,jj,0) + zutau_ice(ji,jj) * ( 1. - xcplmask(ji,jj,0) )
             vtau_ice(ji,jj) = vtau_ice(ji,jj) * xcplmask(ji,jj,0) + zvtau_ice(ji,jj) * ( 1. - xcplmask(ji,jj,0) )
          END_2D
-         CALL lbc_lnk_multi( 'icesbc', utau_ice, 'U', -1., vtau_ice, 'V', -1. )
+         CALL lbc_lnk_multi( 'icesbc', utau_ice, 'U', -1.0_wp, vtau_ice, 'V', -1.0_wp )
       ENDIF
       !
@@ -119,6 +119,5 @@
       INTEGER  ::   ji, jj, jl      ! dummy loop index
       REAL(wp) ::   zmiss_val       ! missing value retrieved from xios 
-      REAL(wp), DIMENSION(jpi,jpj,jpl)              ::   zalb_os, zalb_cs  ! ice albedo under overcast/clear sky
-      REAL(wp), DIMENSION(:,:)        , ALLOCATABLE ::   zalb, zmsk00      ! 2D workspace
+      REAL(wp), DIMENSION(:,:), ALLOCATABLE ::   zalb, zmsk00      ! 2D workspace
       !!--------------------------------------------------------------------
       !
@@ -134,11 +133,7 @@
       CALL iom_miss_val( "icetemp", zmiss_val )
 
-      ! --- cloud-sky and overcast-sky ice albedos --- !
-      CALL ice_alb( t_su, h_i, h_s, ln_pnd_alb, a_ip_frac, h_ip, zalb_cs, zalb_os )
-
-      ! albedo depends on cloud fraction because of non-linear spectral effects
-!!gm cldf_ice is a real, DOCTOR naming rule: start with cd means CHARACTER passed in argument !
-      alb_ice(:,:,:) = ( 1. - cldf_ice ) * zalb_cs(:,:,:) + cldf_ice * zalb_os(:,:,:)
-      !
+      ! --- ice albedo --- !
+      CALL ice_alb( t_su, h_i, h_s, ln_pnd_alb, a_ip_eff, h_ip, cloud_fra, alb_ice )
+
       !
       SELECT CASE( ksbc )   !== fluxes over sea ice ==!
@@ -285,5 +280,5 @@
       INTEGER ::   ios, ioptio   ! Local integer
       !!
-      NAMELIST/namsbc/ rn_cio, rn_blow_s, nn_flxdist, ln_cndflx, ln_cndemulate
+      NAMELIST/namsbc/ rn_cio, nn_snwfra, rn_snwblow, nn_flxdist, ln_cndflx, ln_cndemulate, nn_qtrice
       !!-------------------------------------------------------------------
       !
@@ -299,9 +294,13 @@
          WRITE(numout,*) '~~~~~~~~~~~~~~~~'
          WRITE(numout,*) '   Namelist namsbc:'
-         WRITE(numout,*) '      drag coefficient for oceanic stress              rn_cio        = ', rn_cio
-         WRITE(numout,*) '      coefficient for ice-lead partition of snowfall   rn_blow_s     = ', rn_blow_s
-         WRITE(numout,*) '      Multicategory heat flux formulation              nn_flxdist    = ', nn_flxdist
-         WRITE(numout,*) '      Use conduction flux as surface condition         ln_cndflx     = ', ln_cndflx
-         WRITE(numout,*) '         emulate conduction flux                       ln_cndemulate = ', ln_cndemulate
+         WRITE(numout,*) '      drag coefficient for oceanic stress                       rn_cio        = ', rn_cio
+         WRITE(numout,*) '      fraction of ice covered by snow (options 0,1,2)           nn_snwfra     = ', nn_snwfra
+         WRITE(numout,*) '      coefficient for ice-lead partition of snowfall            rn_snwblow    = ', rn_snwblow
+         WRITE(numout,*) '      Multicategory heat flux formulation                       nn_flxdist    = ', nn_flxdist
+         WRITE(numout,*) '      Use conduction flux as surface condition                  ln_cndflx     = ', ln_cndflx
+         WRITE(numout,*) '         emulate conduction flux                                ln_cndemulate = ', ln_cndemulate
+         WRITE(numout,*) '      solar flux transmitted thru the surface scattering layer  nn_qtrice     = ', nn_qtrice
+         WRITE(numout,*) '         = 0  Grenfell and Maykut 1977'
+         WRITE(numout,*) '         = 1  Lebrun 2019'
       ENDIF
       !
Index: NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icestp.F90
===================================================================
--- NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icestp.F90	(revision 13033)
+++ NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icestp.F90	(revision 13727)
@@ -55,5 +55,4 @@
    USE icedyn         ! sea-ice: dynamics
    USE icethd         ! sea-ice: thermodynamics
-   USE icecor         ! sea-ice: corrections
    USE iceupdate      ! sea-ice: sea surface boundary condition update
    USE icedia         ! sea-ice: budget diagnostics
@@ -86,4 +85,6 @@
    PUBLIC   ice_init   ! called by sbcmod.F90
 
+   !! * Substitutions
+#  include "do_loop_substitute.h90"
    !!----------------------------------------------------------------------
    !! NEMO/ICE 4.0 , NEMO Consortium (2018)
@@ -160,4 +161,6 @@
          IF( ln_icedyn .AND. .NOT.lk_c1d )   &
             &                           CALL ice_dyn( kt, Kmm )       ! -- Ice dynamics
+         !
+                                        CALL diag_trends( 1 )         ! record dyn trends
          !
          !                          !==  lateral boundary conditions  ==!
@@ -188,6 +191,5 @@
          IF( ln_icethd )                CALL ice_thd( kt )            ! -- Ice thermodynamics      
          !
-                                        CALL ice_cor( kt , 2 )        ! -- Corrections
-         !
+                                        CALL diag_trends( 2 )         ! record thermo trends
                                         CALL ice_var_glo2eqv          ! necessary calls (at least for coupling)
                                         CALL ice_var_agg( 2 )         ! necessary calls (at least for coupling)
@@ -197,9 +199,11 @@
          IF( ln_icediahsb )             CALL ice_dia( kt )            ! -- Diagnostics outputs 
          !
+         IF( ln_icediachk )             CALL ice_drift_wri( kt )      ! -- Diagnostics outputs for conservation 
+         !
                                         CALL ice_wri( kt )            ! -- Ice outputs 
          !
          IF( lrst_ice )                 CALL ice_rst_write( kt )      ! -- Ice restart file 
          !
-         IF( ln_icectl )                CALL ice_ctl( kt )            ! -- alerts in case of model crash
+         IF( ln_icectl )                CALL ice_ctl( kt )            ! -- Control checks
          !
       ENDIF   ! End sea-ice time step only
@@ -224,5 +228,5 @@
       INTEGER, INTENT(in) :: Kbb, Kmm, Kaa
       !
-      INTEGER :: ji, jj, ierr
+      INTEGER ::   ierr
       !!----------------------------------------------------------------------
       IF(lwp) WRITE(numout,*)
@@ -240,4 +244,8 @@
       CALL par_init                ! set some ice run parameters
       !
+#if defined key_agrif
+      CALL Agrif_Declare_Var_ice  !  "      "   "   "      "  Sea ice
+#endif
+      !
       !                                ! Allocate the ice arrays (sbc_ice already allocated in sbc_init)
       ierr =        ice_alloc        ()      ! ice variables
@@ -248,36 +256,39 @@
       IF( ierr /= 0 )   CALL ctl_stop('STOP', 'ice_init : unable to allocate ice arrays')
       !
-      CALL ice_itd_init                ! ice thickness distribution initialization
-      !
-      CALL ice_thd_init                ! set ice thermodynics parameters (clem: important to call it first for melt ponds)
-      !
-      !                                ! Initial sea-ice state
-      IF( .NOT. ln_rstart ) THEN              ! start from rest: sea-ice deduced from sst
-         CALL ice_istate_init
-         CALL ice_istate( nit000, Kbb, Kmm, Kaa )
-      ELSE                                    ! start from a restart file
-         CALL ice_rst_read( Kbb, Kmm, Kaa )
-      ENDIF
-      CALL ice_var_glo2eqv
-      CALL ice_var_agg(1)
-      !
-      CALL ice_sbc_init                ! set ice-ocean and ice-atm. coupling parameters
-      !
-      CALL ice_dyn_init                ! set ice dynamics parameters
-      !
-      CALL ice_update_init             ! ice surface boundary condition
-      !
-      CALL ice_alb_init                ! ice surface albedo
-      !
-      CALL ice_dia_init                ! initialization for diags
-      !
-      fr_i  (:,:)   = at_i(:,:)        ! initialisation of sea-ice fraction
-      tn_ice(:,:,:) = t_su(:,:,:)      ! initialisation of surface temp for coupled simu
-      !
       !                                ! set max concentration in both hemispheres
       WHERE( gphit(:,:) > 0._wp )   ;   rn_amax_2d(:,:) = rn_amax_n  ! NH
       ELSEWHERE                     ;   rn_amax_2d(:,:) = rn_amax_s  ! SH
       END WHERE
-
+      !
+      CALL diag_set0                   ! set diag of mass, heat and salt fluxes to 0: needed for Agrif child grids
+      !
+      CALL ice_itd_init                ! ice thickness distribution initialization
+      !
+      CALL ice_thd_init                ! set ice thermodynics parameters (clem: important to call it first for melt ponds)
+      !
+      CALL ice_sbc_init                ! set ice-ocean and ice-atm. coupling parameters
+      !
+      CALL ice_istate_init             ! Initial sea-ice state
+      IF ( ln_rstart .OR. nn_iceini_file == 2 ) THEN
+         CALL ice_rst_read( Kbb, Kmm, Kaa )         ! start from a restart file
+      ELSE
+         CALL ice_istate( nit000, Kbb, Kmm, Kaa )   ! start from rest or read a file
+      ENDIF
+      CALL ice_var_glo2eqv
+      CALL ice_var_agg(1)
+      !
+      CALL ice_dyn_init                ! set ice dynamics parameters
+      !
+      CALL ice_update_init             ! ice surface boundary condition
+      !
+      CALL ice_alb_init                ! ice surface albedo
+      !
+      CALL ice_dia_init                ! initialization for diags
+      !
+      CALL ice_drift_init              ! initialization for diags of conservation
+      !
+      fr_i  (:,:)   = at_i(:,:)        ! initialisation of sea-ice fraction
+      tn_ice(:,:,:) = t_su(:,:,:)      ! initialisation of surface temp for coupled simu
+      !
       IF( ln_rstart )  THEN
           CALL iom_close( numrir )  ! close input ice restart file
@@ -339,6 +350,4 @@
       ENDIF
       !
-      IF( ln_bdy .AND. ln_icediachk )   CALL ctl_warn('par_init: online conservation check does not work with BDY')
-      !
       rDt_ice   = REAL(nn_fsbc) * rn_Dt          !--- sea-ice timestep and its inverse
       r1_Dt_ice = 1._wp / rDt_ice
@@ -365,5 +374,4 @@
       v_s_b (:,:,:)   = v_s (:,:,:)     ! snow volume
       sv_i_b(:,:,:)   = sv_i(:,:,:)     ! salt content
-      oa_i_b(:,:,:)   = oa_i(:,:,:)     ! areal age content
       e_s_b (:,:,:,:) = e_s (:,:,:,:)   ! snow thermal energy
       e_i_b (:,:,:,:) = e_i (:,:,:,:)   ! ice thermal energy
@@ -375,10 +383,4 @@
          h_s_b(:,:,:) = 0._wp
       END WHERE
-      
-      WHERE( a_ip(:,:,:) >= epsi20 )
-         h_ip_b(:,:,:) = v_ip(:,:,:) / a_ip(:,:,:)   ! ice pond thickness
-      ELSEWHERE
-         h_ip_b(:,:,:) = 0._wp
-      END WHERE
       !
       ! ice velocities & total concentration
@@ -397,53 +399,107 @@
       !!               of the time step
       !!----------------------------------------------------------------------
-      INTEGER  ::   ji, jj      ! dummy loop index
-      !!----------------------------------------------------------------------
-      sfx    (:,:) = 0._wp   ;
-      sfx_bri(:,:) = 0._wp   ;   sfx_lam(:,:) = 0._wp
-      sfx_sni(:,:) = 0._wp   ;   sfx_opw(:,:) = 0._wp
-      sfx_bog(:,:) = 0._wp   ;   sfx_dyn(:,:) = 0._wp
-      sfx_bom(:,:) = 0._wp   ;   sfx_sum(:,:) = 0._wp
-      sfx_res(:,:) = 0._wp   ;   sfx_sub(:,:) = 0._wp
-      !
-      wfx_snw(:,:) = 0._wp   ;   wfx_ice(:,:) = 0._wp
-      wfx_sni(:,:) = 0._wp   ;   wfx_opw(:,:) = 0._wp
-      wfx_bog(:,:) = 0._wp   ;   wfx_dyn(:,:) = 0._wp
-      wfx_bom(:,:) = 0._wp   ;   wfx_sum(:,:) = 0._wp
-      wfx_res(:,:) = 0._wp   ;   wfx_sub(:,:) = 0._wp
-      wfx_spr(:,:) = 0._wp   ;   wfx_lam(:,:) = 0._wp  
-      wfx_snw_dyn(:,:) = 0._wp ; wfx_snw_sum(:,:) = 0._wp
-      wfx_snw_sub(:,:) = 0._wp ; wfx_ice_sub(:,:) = 0._wp
-      wfx_snw_sni(:,:) = 0._wp 
-      wfx_pnd(:,:) = 0._wp
-
-      hfx_thd(:,:) = 0._wp   ;
-      hfx_snw(:,:) = 0._wp   ;   hfx_opw(:,:) = 0._wp
-      hfx_bog(:,:) = 0._wp   ;   hfx_dyn(:,:) = 0._wp
-      hfx_bom(:,:) = 0._wp   ;   hfx_sum(:,:) = 0._wp
-      hfx_res(:,:) = 0._wp   ;   hfx_sub(:,:) = 0._wp
-      hfx_spr(:,:) = 0._wp   ;   hfx_dif(:,:) = 0._wp
-      hfx_err_rem(:,:) = 0._wp
-      hfx_err_dif(:,:) = 0._wp
-      wfx_err_sub(:,:) = 0._wp
-      !
-      diag_heat(:,:) = 0._wp ;   diag_sice(:,:) = 0._wp
-      diag_vice(:,:) = 0._wp ;   diag_vsnw(:,:) = 0._wp
-
-      ! SIMIP diagnostics
-      qcn_ice_bot(:,:,:) = 0._wp ; qcn_ice_top(:,:,:) = 0._wp ! conductive fluxes
-      t_si       (:,:,:) = rt0   ! temp at the ice-snow interface
-
-      tau_icebfr (:,:)   = 0._wp   ! landfast ice param only (clem: important to keep the init here)
-      cnd_ice    (:,:,:) = 0._wp   ! initialisation: effective conductivity at the top of ice/snow (ln_cndflx=T)
-      qcn_ice    (:,:,:) = 0._wp   ! initialisation: conductive flux (ln_cndflx=T & ln_cndemule=T)
-      qtr_ice_bot(:,:,:) = 0._wp   ! initialization: part of solar radiation transmitted through the ice needed at least for outputs
-      qsb_ice_bot(:,:)   = 0._wp   ! (needed if ln_icethd=F)
-      !
-      ! for control checks (ln_icediachk)
-      diag_trp_vi(:,:) = 0._wp   ;   diag_trp_vs(:,:) = 0._wp
-      diag_trp_ei(:,:) = 0._wp   ;   diag_trp_es(:,:) = 0._wp
-      diag_trp_sv(:,:) = 0._wp
+      INTEGER  ::   ji, jj, jl      ! dummy loop index
+      !!----------------------------------------------------------------------
+
+      DO_2D( 1, 1, 1, 1 )
+         sfx    (ji,jj) = 0._wp   ;
+         sfx_bri(ji,jj) = 0._wp   ;   sfx_lam(ji,jj) = 0._wp
+         sfx_sni(ji,jj) = 0._wp   ;   sfx_opw(ji,jj) = 0._wp
+         sfx_bog(ji,jj) = 0._wp   ;   sfx_dyn(ji,jj) = 0._wp
+         sfx_bom(ji,jj) = 0._wp   ;   sfx_sum(ji,jj) = 0._wp
+         sfx_res(ji,jj) = 0._wp   ;   sfx_sub(ji,jj) = 0._wp
+         !
+         wfx_snw(ji,jj) = 0._wp   ;   wfx_ice(ji,jj) = 0._wp
+         wfx_sni(ji,jj) = 0._wp   ;   wfx_opw(ji,jj) = 0._wp
+         wfx_bog(ji,jj) = 0._wp   ;   wfx_dyn(ji,jj) = 0._wp
+         wfx_bom(ji,jj) = 0._wp   ;   wfx_sum(ji,jj) = 0._wp
+         wfx_res(ji,jj) = 0._wp   ;   wfx_sub(ji,jj) = 0._wp
+         wfx_spr(ji,jj) = 0._wp   ;   wfx_lam(ji,jj) = 0._wp  
+         wfx_snw_dyn(ji,jj) = 0._wp ; wfx_snw_sum(ji,jj) = 0._wp
+         wfx_snw_sub(ji,jj) = 0._wp ; wfx_ice_sub(ji,jj) = 0._wp
+         wfx_snw_sni(ji,jj) = 0._wp 
+         wfx_pnd(ji,jj) = 0._wp
+
+         hfx_thd(ji,jj) = 0._wp   ;
+         hfx_snw(ji,jj) = 0._wp   ;   hfx_opw(ji,jj) = 0._wp
+         hfx_bog(ji,jj) = 0._wp   ;   hfx_dyn(ji,jj) = 0._wp
+         hfx_bom(ji,jj) = 0._wp   ;   hfx_sum(ji,jj) = 0._wp
+         hfx_res(ji,jj) = 0._wp   ;   hfx_sub(ji,jj) = 0._wp
+         hfx_spr(ji,jj) = 0._wp   ;   hfx_dif(ji,jj) = 0._wp
+         hfx_err_dif(ji,jj) = 0._wp
+         wfx_err_sub(ji,jj) = 0._wp
+         !
+         diag_heat(ji,jj) = 0._wp ;   diag_sice(ji,jj) = 0._wp
+         diag_vice(ji,jj) = 0._wp ;   diag_vsnw(ji,jj) = 0._wp
+
+         tau_icebfr (ji,jj) = 0._wp   ! landfast ice param only (clem: important to keep the init here)
+         qsb_ice_bot(ji,jj) = 0._wp   ! (needed if ln_icethd=F)
+
+         fhld(ji,jj) = 0._wp   ! needed if ln_icethd=F
+
+         ! for control checks (ln_icediachk)
+         diag_trp_vi(ji,jj) = 0._wp   ;   diag_trp_vs(ji,jj) = 0._wp
+         diag_trp_ei(ji,jj) = 0._wp   ;   diag_trp_es(ji,jj) = 0._wp
+         diag_trp_sv(ji,jj) = 0._wp
+         !
+         diag_adv_mass(ji,jj) = 0._wp
+         diag_adv_salt(ji,jj) = 0._wp
+         diag_adv_heat(ji,jj) = 0._wp
+      END_2D
+
+      DO jl = 1, jpl
+         DO_2D( 1, 1, 1, 1 )
+            ! SIMIP diagnostics
+            t_si       (ji,jj,jl) = rt0     ! temp at the ice-snow interface
+            qcn_ice_bot(ji,jj,jl) = 0._wp
+            qcn_ice_top(ji,jj,jl) = 0._wp   ! conductive fluxes
+            cnd_ice    (ji,jj,jl) = 0._wp   ! effective conductivity at the top of ice/snow (ln_cndflx=T)
+            qcn_ice    (ji,jj,jl) = 0._wp   ! conductive flux (ln_cndflx=T & ln_cndemule=T)
+            qtr_ice_bot(ji,jj,jl) = 0._wp   ! part of solar radiation transmitted through the ice needed at least for outputs
+         END_2D
+      ENDDO
 
    END SUBROUTINE diag_set0
+
+
+   SUBROUTINE diag_trends( kn )
+      !!----------------------------------------------------------------------
+      !!                  ***  ROUTINE diag_trends  ***
+      !!
+      !! ** purpose : diagnostics of the trends. Used for conservation purposes
+      !!              and outputs
+      !!----------------------------------------------------------------------
+      INTEGER, INTENT(in) ::   kn    ! 1 = after dyn ; 2 = after thermo
+      !!----------------------------------------------------------------------
+      !
+      ! --- trends of heat, salt, mass (used for conservation controls)
+      IF( ln_icediachk .OR. iom_use('hfxdhc') ) THEN
+         !
+         diag_heat(:,:) = diag_heat(:,:) &
+            &             - SUM(SUM( e_i (:,:,1:nlay_i,:) - e_i_b (:,:,1:nlay_i,:), dim=4 ), dim=3 ) * r1_Dt_ice &
+            &             - SUM(SUM( e_s (:,:,1:nlay_s,:) - e_s_b (:,:,1:nlay_s,:), dim=4 ), dim=3 ) * r1_Dt_ice
+         diag_sice(:,:) = diag_sice(:,:) &
+            &             + SUM(     sv_i(:,:,:)          - sv_i_b(:,:,:)                  , dim=3 ) * r1_Dt_ice * rhoi
+         diag_vice(:,:) = diag_vice(:,:) &
+            &             + SUM(     v_i (:,:,:)          - v_i_b (:,:,:)                  , dim=3 ) * r1_Dt_ice * rhoi
+         diag_vsnw(:,:) = diag_vsnw(:,:) &
+            &             + SUM(     v_s (:,:,:)          - v_s_b (:,:,:)                  , dim=3 ) * r1_Dt_ice * rhos
+         !
+         IF( kn == 2 )    CALL iom_put ( 'hfxdhc' , diag_heat )   ! output of heat trend
+         !
+      ENDIF
+      !
+      ! --- trends of concentration (used for simip outputs)
+      IF( iom_use('afxdyn') .OR. iom_use('afxthd') .OR. iom_use('afxtot') ) THEN
+         !
+         diag_aice(:,:) = diag_aice(:,:) + SUM( a_i(:,:,:) - a_i_b(:,:,:), dim=3 ) * r1_Dt_ice
+         !
+         IF( kn == 1 )   CALL iom_put( 'afxdyn' , diag_aice )                                           ! dyn trend
+         IF( kn == 2 )   CALL iom_put( 'afxthd' , SUM( a_i(:,:,:) - a_i_b(:,:,:), dim=3 ) * r1_Dt_ice ) ! thermo trend
+         IF( kn == 2 )   CALL iom_put( 'afxtot' , diag_aice )                                           ! total trend
+         !
+      ENDIF
+      !
+   END SUBROUTINE diag_trends
 
 #else
Index: NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icethd.F90
===================================================================
--- NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icethd.F90	(revision 13033)
+++ NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icethd.F90	(revision 13727)
@@ -18,5 +18,5 @@
    USE ice            ! sea-ice: variables
 !!gm list trop longue ==>>> why not passage en argument d'appel ?
-   USE sbc_oce , ONLY : sss_m, sst_m, e3t_m, utau, vtau, ssu_m, ssv_m, frq_m, qns_tot, qsr_tot, sprecip, ln_cpl
+   USE sbc_oce , ONLY : sss_m, sst_m, e3t_m, utau, vtau, ssu_m, ssv_m, frq_m, sprecip, ln_cpl
    USE sbc_ice , ONLY : qsr_oce, qns_oce, qemp_oce, qsr_ice, qns_ice, dqns_ice, evap_ice, qprec_ice, qevap_ice, &
       &                 qml_ice, qcn_ice, qtr_ice_top
@@ -30,4 +30,5 @@
    USE icethd_pnd     ! sea-ice: melt ponds
    USE iceitd         ! sea-ice: remapping thickness distribution
+   USE icecor         ! sea-ice: corrections
    USE icetab         ! sea-ice: 1D <==> 2D transformation
    USE icevar         ! sea-ice: operations
@@ -35,4 +36,5 @@
    !
    USE in_out_manager ! I/O manager
+   USE iom            ! I/O manager library
    USE lib_mpp        ! MPP library
    USE lib_fortran    ! fortran utilities (glob_sum + no signed zero)
@@ -51,4 +53,8 @@
    LOGICAL ::   ln_icedO         ! activate ice growth in open-water (T) or not (F)
    LOGICAL ::   ln_icedS         ! activate gravity drainage and flushing (T) or not (F)
+   LOGICAL ::   ln_leadhfx       ! heat in the leads is used to melt sea-ice before warming the ocean
+
+   !! for convergence tests
+   REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) ::   ztice_cvgerr, ztice_cvgstp
 
    !! * Substitutions
@@ -86,8 +92,8 @@
       !
       INTEGER  :: ji, jj, jk, jl   ! dummy loop indices
-      REAL(wp) :: zfric_u, zqld, zqfr, zqfr_neg
-      REAL(wp), PARAMETER :: zfric_umin = 0._wp           ! lower bound for the friction velocity (cice value=5.e-04)
-      REAL(wp), PARAMETER :: zch        = 0.0057_wp       ! heat transfer coefficient
-      REAL(wp), DIMENSION(jpi,jpj) ::   zu_io, zv_io, zfric   ! ice-ocean velocity (m/s) and frictional velocity (m2/s2)
+      REAL(wp) :: zfric_u, zqld, zqfr, zqfr_neg, zqfr_pos
+      REAL(wp), PARAMETER :: zfric_umin = 0._wp       ! lower bound for the friction velocity (cice value=5.e-04)
+      REAL(wp), PARAMETER :: zch        = 0.0057_wp   ! heat transfer coefficient
+      REAL(wp), DIMENSION(jpi,jpj) ::   zu_io, zv_io, zfric, zvel   ! ice-ocean velocity (m/s) and frictional velocity (m2/s2)
       !
       !!-------------------------------------------------------------------
@@ -101,4 +107,10 @@
          WRITE(numout,*) 'ice_thd: sea-ice thermodynamics'
          WRITE(numout,*) '~~~~~~~'
+      ENDIF
+
+      ! convergence tests
+      IF( ln_zdf_chkcvg ) THEN
+         ALLOCATE( ztice_cvgerr(jpi,jpj,jpl) , ztice_cvgstp(jpi,jpj,jpl) )
+         ztice_cvgerr = 0._wp ; ztice_cvgstp = 0._wp
       ENDIF
       
@@ -109,29 +121,26 @@
          zu_io(:,:) = u_ice(:,:) - ssu_m(:,:)
          zv_io(:,:) = v_ice(:,:) - ssv_m(:,:)
-         DO_2D_00_00
+         DO_2D( 0, 0, 0, 0 )
             zfric(ji,jj) = rn_cio * ( 0.5_wp *  &
                &                    (  zu_io(ji,jj) * zu_io(ji,jj) + zu_io(ji-1,jj) * zu_io(ji-1,jj)   &
                &                     + zv_io(ji,jj) * zv_io(ji,jj) + zv_io(ji,jj-1) * zv_io(ji,jj-1) ) ) * tmask(ji,jj,1)
+            zvel(ji,jj) = 0.5_wp * SQRT( ( u_ice(ji-1,jj) + u_ice(ji,jj) ) * ( u_ice(ji-1,jj) + u_ice(ji,jj) ) + &
+               &                         ( v_ice(ji,jj-1) + v_ice(ji,jj) ) * ( v_ice(ji,jj-1) + v_ice(ji,jj) ) )
          END_2D
       ELSE      !  if no ice dynamics => transmit directly the atmospheric stress to the ocean
-         DO_2D_00_00
+         DO_2D( 0, 0, 0, 0 )
             zfric(ji,jj) = r1_rho0 * SQRT( 0.5_wp *  &
                &                         (  utau(ji,jj) * utau(ji,jj) + utau(ji-1,jj) * utau(ji-1,jj)   &
                &                          + vtau(ji,jj) * vtau(ji,jj) + vtau(ji,jj-1) * vtau(ji,jj-1) ) ) * tmask(ji,jj,1)
+            zvel(ji,jj) = 0._wp
          END_2D
       ENDIF
-      CALL lbc_lnk( 'icethd', zfric, 'T',  1. )
+      CALL lbc_lnk_multi( 'icethd', zfric, 'T',  1.0_wp, zvel, 'T', 1.0_wp )
       !
       !--------------------------------------------------------------------!
       ! Partial computation of forcing for the thermodynamic sea ice model
       !--------------------------------------------------------------------!
-      DO_2D_11_11
+      DO_2D( 1, 1, 1, 1 )
          rswitch  = tmask(ji,jj,1) * MAX( 0._wp , SIGN( 1._wp , at_i(ji,jj) - epsi10 ) ) ! 0 if no ice
-         !
-         !           !  solar irradiance transmission at the mixed layer bottom and used in the lead heat budget
-         !           !  practically no "direct lateral ablation"
-         !           
-         !           !  net downward heat flux from the ice to the ocean, expressed as a function of ocean 
-         !           !  temperature and turbulent mixing (McPhee, 1992)
          !
          ! --- Energy received in the lead from atm-oce exchanges, zqld is defined everywhere (J.m-2) --- !
@@ -140,32 +149,56 @@
             &      ( 1._wp - at_i_b(ji,jj) ) * qns_oce(ji,jj) + qemp_oce(ji,jj) )
 
-         ! --- Energy needed to bring ocean surface layer until its freezing (mostly<0 but >0 if supercooling, J.m-2) --- !
+         ! --- Energy needed to bring ocean surface layer until its freezing, zqfr is defined everywhere (J.m-2) --- !
+         !     (mostly<0 but >0 if supercooling)
          zqfr     = rho0 * rcp * e3t_m(ji,jj) * ( t_bo(ji,jj) - ( sst_m(ji,jj) + rt0 ) ) * tmask(ji,jj,1)  ! both < 0 (t_bo < sst) and > 0 (t_bo > sst)
          zqfr_neg = MIN( zqfr , 0._wp )                                                                    ! only < 0
-
-         ! --- Sensible ocean-to-ice heat flux (mostly>0 but <0 if supercooling, W/m2)
+         zqfr_pos = MAX( zqfr , 0._wp )                                                                    ! only > 0
+
+         ! --- Sensible ocean-to-ice heat flux (W/m2) --- !
+         !     (mostly>0 but <0 if supercooling)
          zfric_u            = MAX( SQRT( zfric(ji,jj) ), zfric_umin ) 
-         qsb_ice_bot(ji,jj) = rswitch * rho0 * rcp * zch * zfric_u * ( ( sst_m(ji,jj) + rt0 ) - t_bo(ji,jj) ) ! W.m-2
-
-         qsb_ice_bot(ji,jj) = rswitch * MIN( qsb_ice_bot(ji,jj), - zqfr_neg * r1_Dt_ice / MAX( at_i(ji,jj), epsi10 ) )
+         qsb_ice_bot(ji,jj) = rswitch * rho0 * rcp * zch * zfric_u * ( ( sst_m(ji,jj) + rt0 ) - t_bo(ji,jj) )
+         
          ! upper bound for qsb_ice_bot: the heat retrieved from the ocean must be smaller than the heat necessary to reach 
          !                              the freezing point, so that we do not have SST < T_freeze
-         !                              This implies: - ( qsb_ice_bot(ji,jj) * at_i(ji,jj) * rtdice ) - zqfr >= 0
-
-         !-- Energy Budget of the leads (J.m-2), source of ice growth in open water. Must be < 0 to form ice
-         qlead(ji,jj) = MIN( 0._wp , zqld - ( qsb_ice_bot(ji,jj) * at_i(ji,jj) * rDt_ice ) - zqfr )
-
-         ! If there is ice and leads are warming => transfer energy from the lead budget and use it for bottom melting 
-         ! If the grid cell is fully covered by ice (no leads) => transfer energy from the lead budget to the ice bottom budget
-         IF( ( zqld >= 0._wp .AND. at_i(ji,jj) > 0._wp ) .OR. at_i(ji,jj) >= (1._wp - epsi10) ) THEN
-            fhld (ji,jj) = rswitch * zqld * r1_Dt_ice / MAX( at_i(ji,jj), epsi10 ) ! divided by at_i since this is (re)multiplied by a_i in icethd_dh.F90
+         !                              This implies: qsb_ice_bot(ji,jj) * at_i(ji,jj) * rtdice <= - zqfr_neg
+         !                              The following formulation is ok for both normal conditions and supercooling
+         qsb_ice_bot(ji,jj) = rswitch * MIN( qsb_ice_bot(ji,jj), - zqfr_neg * r1_Dt_ice / MAX( at_i(ji,jj), epsi10 ) )
+
+         ! --- Energy Budget of the leads (qlead, J.m-2) --- !
+         !     qlead is the energy received from the atm. in the leads.
+         !     If warming (zqld >= 0), then the energy in the leads is used to melt ice (bottom melting) => fhld  (W/m2)
+         !     If cooling (zqld <  0), then the energy in the leads is used to grow ice in open water    => qlead (J.m-2)
+         IF( zqld >= 0._wp .AND. at_i(ji,jj) > 0._wp ) THEN
+            ! upper bound for fhld: fhld should be equal to zqld
+            !                        but we have to make sure that this heat will not make the sst drop below the freezing point
+            !                        so the max heat that can be pulled out of the ocean is zqld - qsb - zqfr_pos
+            !                        The following formulation is ok for both normal conditions and supercooling
+            fhld (ji,jj) = rswitch * MAX( 0._wp, ( zqld - zqfr_pos ) * r1_Dt_ice / MAX( at_i(ji,jj), epsi10 ) &  ! divided by at_i since this is (re)multiplied by a_i in icethd_dh.F90
+               &                                 - qsb_ice_bot(ji,jj) )
             qlead(ji,jj) = 0._wp
          ELSE
             fhld (ji,jj) = 0._wp
+            ! upper bound for qlead: qlead should be equal to zqld
+            !                        but before using this heat for ice formation, we suppose that the ocean cools down till the freezing point.
+            !                        The energy for this cooling down is zqfr. Also some heat will be removed from the ocean from turbulent fluxes (qsb)
+            !                        and freezing point is reached if zqfr = zqld - qsb*a/dt
+            !                        so the max heat that can be pulled out of the ocean is zqld - qsb - zqfr
+            !                        The following formulation is ok for both normal conditions and supercooling
+            qlead(ji,jj) = MIN( 0._wp , zqld - ( qsb_ice_bot(ji,jj) * at_i(ji,jj) * rDt_ice ) - zqfr )
          ENDIF
          !
-         ! Net heat flux on top of the ice-ocean [W.m-2]
-         ! ---------------------------------------------
-         qt_atm_oi(ji,jj) = qns_tot(ji,jj) + qsr_tot(ji,jj) 
+         ! If ice is landfast and ice concentration reaches its max
+         ! => stop ice formation in open water
+         IF(  zvel(ji,jj) <= 5.e-04_wp .AND. at_i(ji,jj) >= rn_amax_2d(ji,jj)-epsi06 )   qlead(ji,jj) = 0._wp
+         !
+         ! If the grid cell is almost fully covered by ice (no leads)
+         ! => stop ice formation in open water
+         IF( at_i(ji,jj) >= (1._wp - epsi10) )   qlead(ji,jj) = 0._wp
+         !
+         ! If ln_leadhfx is false
+         ! => do not use energy of the leads to melt sea-ice
+         IF( .NOT.ln_leadhfx )   fhld(ji,jj) = 0._wp
+         !
       END_2D
       
@@ -178,15 +211,4 @@
       ENDIF
 
-      ! ---------------------------------------------------------------------
-      ! Net heat flux on top of the ocean after ice thermo (1st step) [W.m-2]
-      ! ---------------------------------------------------------------------
-      !     First  step here              :  non solar + precip - qlead - qsensible
-      !     Second step in icethd_dh      :  heat remaining if total melt (zq_rema) 
-      !     Third  step in iceupdate.F90  :  heat from ice-ocean mass exchange (zf_mass) + solar
-      qt_oce_ai(:,:) = ( 1._wp - at_i_b(:,:) ) * qns_oce(:,:) + qemp_oce(:,:)  &  ! Non solar heat flux received by the ocean               
-         &             - qlead(:,:) * r1_Dt_ice                                &  ! heat flux taken from the ocean where there is open water ice formation
-         &             - at_i (:,:) * qsb_ice_bot(:,:)                         &  ! heat flux taken by sensible flux
-         &             - at_i (:,:) * fhld       (:,:)                            ! heat flux taken during bottom growth/melt 
-      !                                                                           !    (fhld should be 0 while bott growth)
       !-------------------------------------------------------------------------------------------!
       ! Thermodynamic computation (only on grid points covered by ice) => loop over ice categories
@@ -196,5 +218,5 @@
          ! select ice covered grid points
          npti = 0 ; nptidx(:) = 0
-         DO_2D_11_11
+         DO_2D( 1, 1, 1, 1 )
             IF ( a_i(ji,jj,jl) > epsi10 ) THEN     
                npti         = npti  + 1
@@ -208,5 +230,5 @@
             !                                                       ! --- & Change units of e_i, e_s from J/m2 to J/m3 --- !
             !
-            s_i_new   (1:npti) = 0._wp ; dh_s_tot(1:npti) = 0._wp  ! --- some init --- !  (important to have them here) 
+            s_i_new   (1:npti) = 0._wp ; dh_s_tot(1:npti) = 0._wp   ! --- some init --- !  (important to have them here) 
             dh_i_sum  (1:npti) = 0._wp ; dh_i_bom(1:npti) = 0._wp ; dh_i_itm  (1:npti) = 0._wp 
             dh_i_sub  (1:npti) = 0._wp ; dh_i_bog(1:npti) = 0._wp
@@ -242,4 +264,14 @@
       IF( ln_icedO )          CALL ice_thd_do                       ! --- Frazil ice growth in leads --- !
       !
+                              CALL ice_cor( kt , 2 )                ! --- Corrections --- !
+      !
+      oa_i(:,:,:) = oa_i(:,:,:) + a_i(:,:,:) * rdt_ice              ! ice natural aging incrementation     
+      !
+      ! convergence tests
+      IF( ln_zdf_chkcvg ) THEN
+         CALL iom_put( 'tice_cvgerr', ztice_cvgerr ) ; DEALLOCATE( ztice_cvgerr )
+         CALL iom_put( 'tice_cvgstp', ztice_cvgstp ) ; DEALLOCATE( ztice_cvgstp )
+      ENDIF
+      !
       ! controls
       IF( ln_icectl )   CALL ice_prt    (kt, iiceprt, jiceprt, 1, ' - ice thermodyn. - ') ! prints
@@ -347,5 +379,5 @@
          CALL tab_2d_1d( npti, nptidx(1:npti), a_ip_1d     (1:npti), a_ip     (:,:,kl) )
          CALL tab_2d_1d( npti, nptidx(1:npti), h_ip_1d     (1:npti), h_ip     (:,:,kl) )
-         CALL tab_2d_1d( npti, nptidx(1:npti), a_ip_frac_1d(1:npti), a_ip_frac(:,:,kl) )
+         CALL tab_2d_1d( npti, nptidx(1:npti), h_il_1d     (1:npti), h_il     (:,:,kl) )
          !
          CALL tab_2d_1d( npti, nptidx(1:npti), qprec_ice_1d  (1:npti), qprec_ice            )
@@ -399,10 +431,9 @@
          CALL tab_2d_1d( npti, nptidx(1:npti), hfx_res_1d    (1:npti), hfx_res       )
          CALL tab_2d_1d( npti, nptidx(1:npti), hfx_err_dif_1d(1:npti), hfx_err_dif   )
-         CALL tab_2d_1d( npti, nptidx(1:npti), hfx_err_rem_1d(1:npti), hfx_err_rem   )
-         CALL tab_2d_1d( npti, nptidx(1:npti), qt_oce_ai_1d  (1:npti), qt_oce_ai     )
          !
          ! ocean surface fields
          CALL tab_2d_1d( npti, nptidx(1:npti), sst_1d(1:npti), sst_m )
          CALL tab_2d_1d( npti, nptidx(1:npti), sss_1d(1:npti), sss_m )
+         CALL tab_2d_1d( npti, nptidx(1:npti), frq_m_1d(1:npti), frq_m )
          !
          ! to update ice age
@@ -434,4 +465,5 @@
          sv_i_1d(1:npti) = s_i_1d (1:npti) * v_i_1d (1:npti)
          v_ip_1d(1:npti) = h_ip_1d(1:npti) * a_ip_1d(1:npti)
+         v_il_1d(1:npti) = h_il_1d(1:npti) * a_ip_1d(1:npti)
          oa_i_1d(1:npti) = o_i_1d (1:npti) * a_i_1d (1:npti)
          
@@ -453,5 +485,5 @@
          CALL tab_1d_2d( npti, nptidx(1:npti), a_ip_1d     (1:npti), a_ip     (:,:,kl) )
          CALL tab_1d_2d( npti, nptidx(1:npti), h_ip_1d     (1:npti), h_ip     (:,:,kl) )
-         CALL tab_1d_2d( npti, nptidx(1:npti), a_ip_frac_1d(1:npti), a_ip_frac(:,:,kl) )
+         CALL tab_1d_2d( npti, nptidx(1:npti), h_il_1d     (1:npti), h_il     (:,:,kl) )
          !
          CALL tab_1d_2d( npti, nptidx(1:npti), wfx_snw_sni_1d(1:npti), wfx_snw_sni )
@@ -491,6 +523,4 @@
          CALL tab_1d_2d( npti, nptidx(1:npti), hfx_res_1d    (1:npti), hfx_res     )
          CALL tab_1d_2d( npti, nptidx(1:npti), hfx_err_dif_1d(1:npti), hfx_err_dif )
-         CALL tab_1d_2d( npti, nptidx(1:npti), hfx_err_rem_1d(1:npti), hfx_err_rem )
-         CALL tab_1d_2d( npti, nptidx(1:npti), qt_oce_ai_1d  (1:npti), qt_oce_ai   )
          !
          CALL tab_1d_2d( npti, nptidx(1:npti), qns_ice_1d    (1:npti), qns_ice    (:,:,kl) )
@@ -508,5 +538,11 @@
          CALL tab_1d_2d( npti, nptidx(1:npti), sv_i_1d(1:npti), sv_i(:,:,kl) )
          CALL tab_1d_2d( npti, nptidx(1:npti), v_ip_1d(1:npti), v_ip(:,:,kl) )
+         CALL tab_1d_2d( npti, nptidx(1:npti), v_il_1d(1:npti), v_il(:,:,kl) )
          CALL tab_1d_2d( npti, nptidx(1:npti), oa_i_1d(1:npti), oa_i(:,:,kl) )
+         ! check convergence of heat diffusion scheme
+         IF( ln_zdf_chkcvg ) THEN
+            CALL tab_1d_2d( npti, nptidx(1:npti), tice_cvgerr_1d(1:npti), ztice_cvgerr(:,:,kl) )
+            CALL tab_1d_2d( npti, nptidx(1:npti), tice_cvgstp_1d(1:npti), ztice_cvgstp(:,:,kl) )
+         ENDIF
          !
       END SELECT
@@ -529,5 +565,5 @@
       INTEGER  ::   ios   ! Local integer output status for namelist read
       !!
-      NAMELIST/namthd/ ln_icedH, ln_icedA, ln_icedO, ln_icedS
+      NAMELIST/namthd/ ln_icedH, ln_icedA, ln_icedO, ln_icedS, ln_leadhfx
       !!-------------------------------------------------------------------
       !
@@ -543,8 +579,9 @@
          WRITE(numout,*) '~~~~~~~~~~~~'
          WRITE(numout,*) '   Namelist namthd:'
-         WRITE(numout,*) '      activate ice thick change from top/bot (T) or not (F)   ln_icedH  = ', ln_icedH
-         WRITE(numout,*) '      activate lateral melting (T) or not (F)                 ln_icedA  = ', ln_icedA
-         WRITE(numout,*) '      activate ice growth in open-water (T) or not (F)        ln_icedO  = ', ln_icedO
-         WRITE(numout,*) '      activate gravity drainage and flushing (T) or not (F)   ln_icedS  = ', ln_icedS
+         WRITE(numout,*) '      activate ice thick change from top/bot (T) or not (F)                ln_icedH   = ', ln_icedH
+         WRITE(numout,*) '      activate lateral melting (T) or not (F)                              ln_icedA   = ', ln_icedA
+         WRITE(numout,*) '      activate ice growth in open-water (T) or not (F)                     ln_icedO   = ', ln_icedO
+         WRITE(numout,*) '      activate gravity drainage and flushing (T) or not (F)                ln_icedS   = ', ln_icedS
+         WRITE(numout,*) '      heat in the leads is used to melt sea-ice before warming the ocean   ln_leadhfx = ', ln_leadhfx
      ENDIF
       !
Index: NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icethd_dh.F90
===================================================================
--- NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icethd_dh.F90	(revision 13033)
+++ NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icethd_dh.F90	(revision 13727)
@@ -13,6 +13,5 @@
    !!----------------------------------------------------------------------
    !!   ice_thd_dh        : vertical sea-ice growth and melt
-   !!   ice_thd_snwblow   : distribute snow fall between ice and ocean
-  !!----------------------------------------------------------------------
+   !!----------------------------------------------------------------------
    USE dom_oce        ! ocean space and time domain
    USE phycst         ! physical constants
@@ -20,4 +19,5 @@
    USE ice1D          ! sea-ice: thermodynamics variables
    USE icethd_sal     ! sea-ice: salinity profiles
+   USE icevar         ! for CALL ice_var_snwblow
    !
    USE in_out_manager ! I/O manager
@@ -29,9 +29,4 @@
 
    PUBLIC   ice_thd_dh        ! called by ice_thd
-   PUBLIC   ice_thd_snwblow   ! called in sbcblk/sbccpl and here
-
-   INTERFACE ice_thd_snwblow
-      MODULE PROCEDURE ice_thd_snwblow_1d, ice_thd_snwblow_2d
-   END INTERFACE
 
    !!----------------------------------------------------------------------
@@ -144,5 +139,5 @@
       !
       DO ji = 1, npti
-         zf_tt(ji)         = qcn_ice_bot_1d(ji) + qsb_ice_bot_1d(ji) + fhld_1d(ji) 
+         zf_tt(ji)         = qcn_ice_bot_1d(ji) + qsb_ice_bot_1d(ji) + fhld_1d(ji) + qtr_ice_bot_1d(ji) * frq_m_1d(ji) 
          zq_bot(ji)        = MAX( 0._wp, zf_tt(ji) * rDt_ice )
       END DO
@@ -186,5 +181,5 @@
       ! Snow precipitation
       !-------------------
-      CALL ice_thd_snwblow( 1. - at_i_1d(1:npti), zsnw(1:npti) )   ! snow distribution over ice after wind blowing
+      CALL ice_var_snwblow( 1.0_wp - at_i_1d(1:npti), zsnw(1:npti) )   ! snow distribution over ice after wind blowing
 
       zdeltah(1:npti,:) = 0._wp
@@ -442,5 +437,5 @@
                
                zEi           = rcpi * ( zt_i_new - (ztmelts+rt0) ) &                                  ! Specific enthalpy of forming ice (J/kg, <0)
-                  &            - rLfus * ( 1.0 - ztmelts / ( zt_i_new - rt0 ) ) + rcp  * ztmelts
+                  &            - rLfus * ( 1.0 - ztmelts / ( MIN( zt_i_new - rt0, -epsi10 ) ) ) + rcp  * ztmelts
 
                zEw           = rcp  * ( t_bo_1d(ji) - rt0 )                                           ! Specific enthalpy of seawater (J/kg, < 0)
@@ -561,5 +556,5 @@
          !    
          ! Remaining heat flux (W.m-2) is sent to the ocean heat budget
-         qt_oce_ai_1d(ji) = qt_oce_ai_1d(ji) + ( zq_rema(ji) * a_i_1d(ji) ) * r1_Dt_ice
+         !!hfx_res_1d(ji) = hfx_res_1d(ji) + ( zq_rema(ji) * a_i_1d(ji) ) * r1_Dt_ice
 
          IF( ln_icectl .AND. zq_rema(ji) < 0. .AND. lwp ) WRITE(numout,*) 'ALERTE zq_rema <0 = ', zq_rema(ji)
@@ -636,33 +631,4 @@
    END SUBROUTINE ice_thd_dh
 
-
-   !!--------------------------------------------------------------------------
-   !! INTERFACE ice_thd_snwblow
-   !!
-   !! ** Purpose :   Compute distribution of precip over the ice
-   !!
-   !!                Snow accumulation in one thermodynamic time step
-   !!                snowfall is partitionned between leads and ice.
-   !!                If snow fall was uniform, a fraction (1-at_i) would fall into leads
-   !!                but because of the winds, more snow falls on leads than on sea ice
-   !!                and a greater fraction (1-at_i)^beta of the total mass of snow 
-   !!                (beta < 1) falls in leads.
-   !!                In reality, beta depends on wind speed, 
-   !!                and should decrease with increasing wind speed but here, it is 
-   !!                considered as a constant. an average value is 0.66
-   !!--------------------------------------------------------------------------
-!!gm  I think it can be usefull to set this as a FUNCTION, not a SUBROUTINE....
-   SUBROUTINE ice_thd_snwblow_2d( pin, pout )
-      REAL(wp), DIMENSION(:,:), INTENT(in   ) :: pin   ! previous fraction lead ( 1. - a_i_b )
-      REAL(wp), DIMENSION(:,:), INTENT(inout) :: pout
-      pout = ( 1._wp - ( pin )**rn_blow_s )
-   END SUBROUTINE ice_thd_snwblow_2d
-
-   SUBROUTINE ice_thd_snwblow_1d( pin, pout )
-      REAL(wp), DIMENSION(:), INTENT(in   ) :: pin
-      REAL(wp), DIMENSION(:), INTENT(inout) :: pout
-      pout = ( 1._wp - ( pin )**rn_blow_s )
-   END SUBROUTINE ice_thd_snwblow_1d
-
 #else
    !!----------------------------------------------------------------------
Index: NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icethd_do.F90
===================================================================
--- NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icethd_do.F90	(revision 13033)
+++ NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icethd_do.F90	(revision 13727)
@@ -131,6 +131,8 @@
 
       ! Default new ice thickness
-      WHERE( qlead(:,:) < 0._wp  .AND. tau_icebfr(:,:) == 0._wp )   ;   ht_i_new(:,:) = rn_hinew ! if cooling and no landfast
-      ELSEWHERE                                                     ;   ht_i_new(:,:) = 0._wp
+      WHERE( qlead(:,:) < 0._wp ) ! cooling
+         ht_i_new(:,:) = rn_hinew
+      ELSEWHERE
+         ht_i_new(:,:) = 0._wp
       END WHERE
 
@@ -145,6 +147,6 @@
          zgamafr = 0.03
          !
-         DO_2D_00_00
-            IF ( qlead(ji,jj) < 0._wp .AND. tau_icebfr(ji,jj) == 0._wp ) THEN ! activated if cooling and no landfast
+         DO_2D( 0, 0, 0, 0 )
+            IF ( qlead(ji,jj) < 0._wp ) THEN ! cooling
                ! -- Wind stress -- !
                ztaux         = ( utau_ice(ji-1,jj  ) * umask(ji-1,jj  ,1)   &
@@ -191,5 +193,5 @@
          END_2D
          ! 
-         CALL lbc_lnk_multi( 'icethd_do', zvrel, 'T', 1., ht_i_new, 'T', 1.  )
+         CALL lbc_lnk_multi( 'icethd_do', zvrel, 'T', 1.0_wp, ht_i_new, 'T', 1.0_wp  )
 
       ENDIF
@@ -198,10 +200,10 @@
       ! 2) Compute thickness, salinity, enthalpy, age, area and volume of new ice
       !------------------------------------------------------------------------------!
-      ! This occurs if open water energy budget is negative (cooling) and there is no landfast ice
+      ! it occurs if cooling
 
       ! Identify grid points where new ice forms
       npti = 0   ;   nptidx(:) = 0
-      DO_2D_11_11
-         IF ( qlead(ji,jj)  <  0._wp .AND. tau_icebfr(ji,jj) == 0._wp ) THEN
+      DO_2D( 1, 1, 1, 1 )
+         IF ( qlead(ji,jj)  <  0._wp ) THEN
             npti = npti + 1
             nptidx( npti ) = (jj - 1) * jpi + ji
Index: NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icethd_ent.F90
===================================================================
--- NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icethd_ent.F90	(revision 13033)
+++ NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icethd_ent.F90	(revision 13727)
@@ -128,8 +128,8 @@
       ! comment: if input h_i_old and eh_i_old are already multiplied by a_i (as in icethd_do), 
       ! then we should not (* a_i) again but not important since this is just to check that remap error is ~0
-      DO ji = 1, npti
-         hfx_err_rem_1d(ji) = hfx_err_rem_1d(ji) + a_i_1d(ji) * r1_Dt_ice *  &
-            &               ( SUM( qnew(ji,1:nlay_i) ) * zhnew(ji) - SUM( eh_i_old(ji,0:nlay_i+1) ) ) 
-      END DO
+      !DO ji = 1, npti
+      !   hfx_err_rem_1d(ji) = hfx_err_rem_1d(ji) + a_i_1d(ji) * r1_Dt_ice *  &
+      !      &               ( SUM( qnew(ji,1:nlay_i) ) * zhnew(ji) - SUM( eh_i_old(ji,0:nlay_i+1) ) ) 
+      !END DO
       
    END SUBROUTINE ice_thd_ent
Index: NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icethd_pnd.F90
===================================================================
--- NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icethd_pnd.F90	(revision 13033)
+++ NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icethd_pnd.F90	(revision 13727)
@@ -35,6 +35,6 @@
    !                                   ! associated indices:
    INTEGER, PARAMETER ::   np_pndNO  = 0   ! No pond scheme
-   INTEGER, PARAMETER ::   np_pndCST = 1   ! Constant pond scheme
-   INTEGER, PARAMETER ::   np_pndH12 = 2   ! Evolutive pond scheme (Holland et al. 2012)
+   INTEGER, PARAMETER ::   np_pndCST = 1   ! Constant ice pond scheme
+   INTEGER, PARAMETER ::   np_pndLEV = 2   ! Level ice pond scheme
 
    !!----------------------------------------------------------------------
@@ -49,7 +49,6 @@
       !!               ***  ROUTINE ice_thd_pnd   ***
       !!               
-      !! ** Purpose :   change melt pond fraction
+      !! ** Purpose :   change melt pond fraction and thickness
       !!                
-      !! ** Method  :   brut force
       !!-------------------------------------------------------------------
       !
@@ -58,5 +57,5 @@
       CASE (np_pndCST)   ;   CALL pnd_CST    !==  Constant melt ponds  ==!
          !
-      CASE (np_pndH12)   ;   CALL pnd_H12    !==  Holland et al 2012 melt ponds  ==!
+      CASE (np_pndLEV)   ;   CALL pnd_LEV    !==  Level ice melt ponds  ==!
          !
       END SELECT
@@ -86,11 +85,11 @@
          !
          IF( a_i_1d(ji) > 0._wp .AND. t_su_1d(ji) >= rt0 ) THEN
-            a_ip_frac_1d(ji) = rn_apnd
             h_ip_1d(ji)      = rn_hpnd    
-            a_ip_1d(ji)      = a_ip_frac_1d(ji) * a_i_1d(ji)
+            a_ip_1d(ji)      = rn_apnd * a_i_1d(ji)
+            h_il_1d(ji)      = 0._wp    ! no pond lids whatsoever
          ELSE
-            a_ip_frac_1d(ji) = 0._wp
             h_ip_1d(ji)      = 0._wp    
             a_ip_1d(ji)      = 0._wp
+            h_il_1d(ji)      = 0._wp
          ENDIF
          !
@@ -100,91 +99,204 @@
 
 
-   SUBROUTINE pnd_H12
-      !!-------------------------------------------------------------------
-      !!                ***  ROUTINE pnd_H12  ***
-      !!
-      !! ** Purpose    : Compute melt pond evolution
-      !!
-      !! ** Method     : Empirical method. A fraction of meltwater is accumulated in ponds 
-      !!                 and sent to ocean when surface is freezing
-      !!
-      !!                 pond growth:      Vp = Vp + dVmelt
-      !!                    with dVmelt = R/rhow * ( rhoi*dh_i + rhos*dh_s ) * a_i
-      !!                 pond contraction: Vp = Vp * exp(0.01*MAX(Tp-Tsu,0)/Tp)
-      !!                    with Tp = -2degC
-      !!  
-      !! ** Tunable parameters : (no real expertise yet, ideas?)
+   SUBROUTINE pnd_LEV
+      !!-------------------------------------------------------------------
+      !!                ***  ROUTINE pnd_LEV  ***
+      !!
+      !! ** Purpose : Compute melt pond evolution
+      !!
+      !! ** Method  : A fraction of meltwater is accumulated in ponds and sent to ocean when surface is freezing
+      !!              We  work with volumes and then redistribute changes into thickness and concentration
+      !!              assuming linear relationship between the two. 
+      !!
+      !! ** Action  : - pond growth:      Vp = Vp + dVmelt                                          --- from Holland et al 2012 ---
+      !!                                     dVmelt = (1-r)/rhow * ( rhoi*dh_i + rhos*dh_s ) * a_i
+      !!                                        dh_i  = meltwater from ice surface melt
+      !!                                        dh_s  = meltwater from snow melt
+      !!                                        (1-r) = fraction of melt water that is not flushed
+      !!
+      !!              - limtations:       a_ip must not exceed (1-r)*a_i
+      !!                                  h_ip must not exceed 0.5*h_i
+      !!
+      !!              - pond shrinking:
+      !!                       if lids:   Vp = Vp -dH * a_ip
+      !!                                     dH = lid thickness change. Retrieved from this eq.:    --- from Flocco et al 2010 ---
+      !!
+      !!                                                                   rhoi * Lf * dH/dt = ki * MAX(Tp-Tsu,0) / H 
+      !!                                                                      H = lid thickness
+      !!                                                                      Lf = latent heat of fusion
+      !!                                                                      Tp = -2C
+      !!
+      !!                                                                And solved implicitely as:
+      !!                                                                   H(t+dt)**2 -H(t) * H(t+dt) -ki * (Tp-Tsu) * dt / (rhoi*Lf) = 0
+      !!
+      !!                    if no lids:   Vp = Vp * exp(0.01*MAX(Tp-Tsu,0)/Tp)                      --- from Holland et al 2012 ---
+      !!
+      !!              - Flushing:         w = -perm/visc * rho_oce * grav * Hp / Hi                 --- from Flocco et al 2007 ---
+      !!                                     perm = permability of sea-ice
+      !!                                     visc = water viscosity
+      !!                                     Hp   = height of top of the pond above sea-level
+      !!                                     Hi   = ice thickness thru which there is flushing
+      !!
+      !!              - Corrections:      remove melt ponds when lid thickness is 10 times the pond thickness
+      !!
+      !!              - pond thickness and area is retrieved from pond volume assuming a linear relationship between h_ip and a_ip:
+      !!                                  a_ip/a_i = a_ip_frac = h_ip / zaspect
+      !!
+      !! ** Tunable parameters : ln_pnd_lids, rn_apnd_max, rn_apnd_min
       !! 
-      !! ** Note       : Stolen from CICE for quick test of the melt pond
-      !!                 radiation and freshwater interfaces
-      !!                 Coupling can be radiative AND freshwater
-      !!                 Advection, ridging, rafting are called
-      !!
-      !! ** References : Holland, M. M. et al (J Clim 2012)
-      !!-------------------------------------------------------------------
-      REAL(wp), PARAMETER ::   zrmin       = 0.15_wp  ! minimum fraction of available meltwater retained for melt ponding
-      REAL(wp), PARAMETER ::   zrmax       = 0.70_wp  ! maximum     -           -         -         -            -
-      REAL(wp), PARAMETER ::   zpnd_aspect = 0.8_wp   ! pond aspect ratio
-      REAL(wp), PARAMETER ::   zTp         = -2._wp   ! reference temperature
-      !
-      REAL(wp) ::   zfr_mlt          ! fraction of available meltwater retained for melt ponding
-      REAL(wp) ::   zdv_mlt          ! available meltwater for melt ponding
-      REAL(wp) ::   z1_Tp            ! inverse reference temperature
-      REAL(wp) ::   z1_rhow          ! inverse freshwater density
-      REAL(wp) ::   z1_zpnd_aspect   ! inverse pond aspect ratio
-      REAL(wp) ::   zfac, zdum
-      !
-      INTEGER  ::   ji   ! loop indices
-      !!-------------------------------------------------------------------
-      z1_rhow        = 1._wp / rhow 
-      z1_zpnd_aspect = 1._wp / zpnd_aspect
-      z1_Tp          = 1._wp / zTp 
+      !! ** Note       :   mostly stolen from CICE
+      !!
+      !! ** References :   Flocco and Feltham (JGR, 2007)
+      !!                   Flocco et al       (JGR, 2010)
+      !!                   Holland et al      (J. Clim, 2012)
+      !!-------------------------------------------------------------------
+      REAL(wp), DIMENSION(nlay_i) ::   ztmp           ! temporary array
+      !!
+      REAL(wp), PARAMETER ::   zaspect =  0.8_wp      ! pond aspect ratio
+      REAL(wp), PARAMETER ::   zTp     = -2._wp       ! reference temperature
+      REAL(wp), PARAMETER ::   zvisc   =  1.79e-3_wp  ! water viscosity
+      !!
+      REAL(wp) ::   zfr_mlt, zdv_mlt                  ! fraction and volume of available meltwater retained for melt ponding
+      REAL(wp) ::   zdv_frz, zdv_flush                ! Amount of melt pond that freezes, flushes
+      REAL(wp) ::   zhp                               ! heigh of top of pond lid wrt ssh
+      REAL(wp) ::   zv_ip_max                         ! max pond volume allowed
+      REAL(wp) ::   zdT                               ! zTp-t_su
+      REAL(wp) ::   zsbr                              ! Brine salinity
+      REAL(wp) ::   zperm                             ! permeability of sea ice
+      REAL(wp) ::   zfac, zdum                        ! temporary arrays
+      REAL(wp) ::   z1_rhow, z1_aspect, z1_Tp         ! inverse
+      !!
+      INTEGER  ::   ji, jk                            ! loop indices
+      !!-------------------------------------------------------------------
+      z1_rhow   = 1._wp / rhow 
+      z1_aspect = 1._wp / zaspect
+      z1_Tp     = 1._wp / zTp 
 
       DO ji = 1, npti
-         !                                                        !--------------------------------!
-         IF( h_i_1d(ji) < rn_himin) THEN                          ! Case ice thickness < rn_himin  !
-            !                                                     !--------------------------------!
-            !--- Remove ponds on thin ice
+         !                                                            !----------------------------------------------------!
+         IF( h_i_1d(ji) < rn_himin .OR. a_i_1d(ji) < epsi10 ) THEN    ! Case ice thickness < rn_himin or tiny ice fraction !
+            !                                                         !----------------------------------------------------!
+            !--- Remove ponds on thin ice or tiny ice fractions
             a_ip_1d(ji)      = 0._wp
-            a_ip_frac_1d(ji) = 0._wp
             h_ip_1d(ji)      = 0._wp
-            !                                                     !--------------------------------!
-         ELSE                                                     ! Case ice thickness >= rn_himin !
-            !                                                     !--------------------------------!
-            v_ip_1d(ji) = h_ip_1d(ji) * a_ip_1d(ji)   ! record pond volume at previous time step
-            !
-            ! available meltwater for melt ponding [m, >0] and fraction
-            zdv_mlt = -( dh_i_sum(ji)*rhoi + dh_s_mlt(ji)*rhos ) * z1_rhow * a_i_1d(ji)
-            zfr_mlt = zrmin + ( zrmax - zrmin ) * a_i_1d(ji)  ! from CICE doc
-            !zfr_mlt = zrmin + zrmax * a_i_1d(ji)             ! from Holland paper 
-            !
-            !--- Pond gowth ---!
-            ! v_ip should never be negative, otherwise code crashes
-            v_ip_1d(ji) = MAX( 0._wp, v_ip_1d(ji) + zfr_mlt * zdv_mlt )
-            !
-            ! melt pond mass flux (<0)
+            h_il_1d(ji)      = 0._wp
+            !                                                         !--------------------------------!
+         ELSE                                                         ! Case ice thickness >= rn_himin !
+            !                                                         !--------------------------------!
+            v_ip_1d(ji) = h_ip_1d(ji) * a_ip_1d(ji)   ! retrieve volume from thickness
+            v_il_1d(ji) = h_il_1d(ji) * a_ip_1d(ji)
+            !
+            !------------------!
+            ! case ice melting !
+            !------------------!
+            !
+            !--- available meltwater for melt ponding ---!
+            zdum    = -( dh_i_sum(ji)*rhoi + dh_s_mlt(ji)*rhos ) * z1_rhow * a_i_1d(ji)
+            zfr_mlt = rn_apnd_min + ( rn_apnd_max - rn_apnd_min ) * at_i_1d(ji) !  = ( 1 - r ) = fraction of melt water that is not flushed
+            zdv_mlt = MAX( 0._wp, zfr_mlt * zdum ) ! max for roundoff errors? 
+            !
+            !--- overflow ---!
+            ! If pond area exceeds zfr_mlt * a_i_1d(ji) then reduce the pond volume
+            !    a_ip_max = zfr_mlt * a_i
+            !    => from zaspect = h_ip / (a_ip / a_i), set v_ip_max as: 
+            zv_ip_max = zfr_mlt**2 * a_i_1d(ji) * zaspect
+            zdv_mlt = MAX( 0._wp, MIN( zdv_mlt, zv_ip_max - v_ip_1d(ji) ) )
+
+            ! If pond depth exceeds half the ice thickness then reduce the pond volume
+            !    h_ip_max = 0.5 * h_i
+            !    => from zaspect = h_ip / (a_ip / a_i), set v_ip_max as: 
+            zv_ip_max = z1_aspect * a_i_1d(ji) * 0.25 * h_i_1d(ji) * h_i_1d(ji)
+            zdv_mlt = MAX( 0._wp, MIN( zdv_mlt, zv_ip_max - v_ip_1d(ji) ) )
+            
+            !--- Pond growing ---!
+            v_ip_1d(ji) = v_ip_1d(ji) + zdv_mlt
+            !
+            !--- Lid melting ---!
+            IF( ln_pnd_lids )   v_il_1d(ji) = MAX( 0._wp, v_il_1d(ji) - zdv_mlt ) ! must be bounded by 0
+            !
+            !--- mass flux ---!
             IF( zdv_mlt > 0._wp ) THEN
-               zfac = zfr_mlt * zdv_mlt * rhow * r1_Dt_ice
+               zfac = zdv_mlt * rhow * r1_Dt_ice                        ! melt pond mass flux < 0 [kg.m-2.s-1]
                wfx_pnd_1d(ji) = wfx_pnd_1d(ji) - zfac
                !
-               ! adjust ice/snow melting flux to balance melt pond flux (>0)
-               zdum = zfac / ( wfx_snw_sum_1d(ji) + wfx_sum_1d(ji) )
+               zdum = zfac / ( wfx_snw_sum_1d(ji) + wfx_sum_1d(ji) )    ! adjust ice/snow melting flux > 0 to balance melt pond flux
                wfx_snw_sum_1d(ji) = wfx_snw_sum_1d(ji) * (1._wp + zdum)
                wfx_sum_1d(ji)     = wfx_sum_1d(ji)     * (1._wp + zdum)
             ENDIF
+
+            !-------------------!
+            ! case ice freezing ! i.e. t_su_1d(ji) < (zTp+rt0)
+            !-------------------!
+            !
+            zdT = MAX( zTp+rt0 - t_su_1d(ji), 0._wp )
             !
             !--- Pond contraction (due to refreezing) ---!
-            v_ip_1d(ji) = v_ip_1d(ji) * EXP( 0.01_wp * MAX( zTp+rt0 - t_su_1d(ji), 0._wp ) * z1_Tp )
-            !
-            ! Set new pond area and depth assuming linear relation between h_ip and a_ip_frac
-            !    h_ip = zpnd_aspect * a_ip_frac = zpnd_aspect * a_ip/a_i
-            a_ip_1d(ji)      = SQRT( v_ip_1d(ji) * z1_zpnd_aspect * a_i_1d(ji) )
-            a_ip_frac_1d(ji) = a_ip_1d(ji) / a_i_1d(ji)
-            h_ip_1d(ji)      = zpnd_aspect * a_ip_frac_1d(ji)
+            IF( ln_pnd_lids ) THEN
+               !
+               !--- Lid growing and subsequent pond shrinking ---! 
+               zdv_frz = 0.5_wp * MAX( 0._wp, -v_il_1d(ji) + & ! Flocco 2010 (eq. 5) solved implicitly as aH**2 + bH + c = 0
+                  &                    SQRT( v_il_1d(ji)**2 + a_ip_1d(ji)**2 * 4._wp * rcnd_i * zdT * rdt_ice / (rLfus * rhow) ) ) ! max for roundoff errors
+               
+               ! Lid growing
+               v_il_1d(ji) = MAX( 0._wp, v_il_1d(ji) + zdv_frz )
+               
+               ! Pond shrinking
+               v_ip_1d(ji) = MAX( 0._wp, v_ip_1d(ji) - zdv_frz )
+
+            ELSE
+               ! Pond shrinking
+               v_ip_1d(ji) = v_ip_1d(ji) * EXP( 0.01_wp * zdT * z1_Tp ) ! Holland 2012 (eq. 6)
+            ENDIF
+            !
+            !--- Set new pond area and depth ---! assuming linear relation between h_ip and a_ip_frac
+            ! v_ip     = h_ip * a_ip
+            ! a_ip/a_i = a_ip_frac = h_ip / zaspect (cf Holland 2012, fitting SHEBA so that knowing v_ip we can distribute it to a_ip and h_ip)
+            a_ip_1d(ji)      = MIN( a_i_1d(ji), SQRT( v_ip_1d(ji) * z1_aspect * a_i_1d(ji) ) ) ! make sure a_ip < a_i
+            h_ip_1d(ji)      = zaspect * a_ip_1d(ji) / a_i_1d(ji)
+
+            !---------------!            
+            ! Pond flushing !
+            !---------------!
+            ! height of top of the pond above sea-level
+            zhp = ( h_i_1d(ji) * ( rho0 - rhoi ) + h_ip_1d(ji) * ( rho0 - rhow * a_ip_1d(ji) / a_i_1d(ji) ) ) * r1_rho0
+            
+            ! Calculate the permeability of the ice (Assur 1958, see Flocco 2010)
+            DO jk = 1, nlay_i
+               zsbr = - 1.2_wp                                  &
+                  &   - 21.8_wp    * ( t_i_1d(ji,jk) - rt0 )    &
+                  &   - 0.919_wp   * ( t_i_1d(ji,jk) - rt0 )**2 &
+                  &   - 0.0178_wp  * ( t_i_1d(ji,jk) - rt0 )**3
+               ztmp(jk) = sz_i_1d(ji,jk) / zsbr
+            END DO
+            zperm = MAX( 0._wp, 3.e-08_wp * MINVAL(ztmp)**3 )
+            
+            ! Do the drainage using Darcy's law
+            zdv_flush   = -zperm * rho0 * grav * zhp * rdt_ice / (zvisc * h_i_1d(ji)) * a_ip_1d(ji)
+            zdv_flush   = MAX( zdv_flush, -v_ip_1d(ji) )
+            v_ip_1d(ji) = v_ip_1d(ji) + zdv_flush
+            
+            !--- Set new pond area and depth ---! assuming linear relation between h_ip and a_ip_frac
+            a_ip_1d(ji)      = MIN( a_i_1d(ji), SQRT( v_ip_1d(ji) * z1_aspect * a_i_1d(ji) ) ) ! make sure a_ip < a_i
+            h_ip_1d(ji)      = zaspect * a_ip_1d(ji) / a_i_1d(ji)
+
+            !--- Corrections and lid thickness ---!
+            IF( ln_pnd_lids ) THEN
+               !--- retrieve lid thickness from volume ---!
+               IF( a_ip_1d(ji) > epsi10 ) THEN   ;   h_il_1d(ji) = v_il_1d(ji) / a_ip_1d(ji)
+               ELSE                              ;   h_il_1d(ji) = 0._wp
+               ENDIF
+               !--- remove ponds if lids are much larger than ponds ---!
+               IF ( h_il_1d(ji) > h_ip_1d(ji) * 10._wp ) THEN
+                  a_ip_1d(ji)      = 0._wp
+                  h_ip_1d(ji)      = 0._wp
+                  h_il_1d(ji)      = 0._wp
+               ENDIF
+            ENDIF
             !
          ENDIF
+         
       END DO
       !
-   END SUBROUTINE pnd_H12
+   END SUBROUTINE pnd_LEV
 
 
@@ -203,5 +315,7 @@
       INTEGER  ::   ios, ioptio   ! Local integer
       !!
-      NAMELIST/namthd_pnd/  ln_pnd, ln_pnd_H12, ln_pnd_CST, rn_apnd, rn_hpnd, ln_pnd_alb
+      NAMELIST/namthd_pnd/  ln_pnd, ln_pnd_LEV , rn_apnd_min, rn_apnd_max, &
+         &                          ln_pnd_CST , rn_apnd, rn_hpnd,         &
+         &                          ln_pnd_lids, ln_pnd_alb
       !!-------------------------------------------------------------------
       !
@@ -217,10 +331,13 @@
          WRITE(numout,*) '~~~~~~~~~~~~~~~~'
          WRITE(numout,*) '   Namelist namicethd_pnd:'
-         WRITE(numout,*) '      Melt ponds activated or not                                     ln_pnd     = ', ln_pnd
-         WRITE(numout,*) '         Evolutive  melt pond fraction and depth (Holland et al 2012) ln_pnd_H12 = ', ln_pnd_H12
-         WRITE(numout,*) '         Prescribed melt pond fraction and depth                      ln_pnd_CST = ', ln_pnd_CST
-         WRITE(numout,*) '            Prescribed pond fraction                                  rn_apnd    = ', rn_apnd
-         WRITE(numout,*) '            Prescribed pond depth                                     rn_hpnd    = ', rn_hpnd
-         WRITE(numout,*) '         Melt ponds affect albedo or not                              ln_pnd_alb = ', ln_pnd_alb
+         WRITE(numout,*) '      Melt ponds activated or not                                 ln_pnd       = ', ln_pnd
+         WRITE(numout,*) '         Level ice melt pond scheme                               ln_pnd_LEV   = ', ln_pnd_LEV
+         WRITE(numout,*) '            Minimum ice fraction that contributes to melt ponds   rn_apnd_min  = ', rn_apnd_min
+         WRITE(numout,*) '            Maximum ice fraction that contributes to melt ponds   rn_apnd_max  = ', rn_apnd_max
+         WRITE(numout,*) '         Constant ice melt pond scheme                            ln_pnd_CST   = ', ln_pnd_CST
+         WRITE(numout,*) '            Prescribed pond fraction                              rn_apnd      = ', rn_apnd
+         WRITE(numout,*) '            Prescribed pond depth                                 rn_hpnd      = ', rn_hpnd
+         WRITE(numout,*) '         Frozen lids on top of melt ponds                         ln_pnd_lids  = ', ln_pnd_lids
+         WRITE(numout,*) '         Melt ponds affect albedo or not                          ln_pnd_alb   = ', ln_pnd_alb
       ENDIF
       !
@@ -229,11 +346,14 @@
       IF( .NOT.ln_pnd ) THEN   ;   ioptio = ioptio + 1   ;   nice_pnd = np_pndNO     ;   ENDIF
       IF( ln_pnd_CST  ) THEN   ;   ioptio = ioptio + 1   ;   nice_pnd = np_pndCST    ;   ENDIF
-      IF( ln_pnd_H12  ) THEN   ;   ioptio = ioptio + 1   ;   nice_pnd = np_pndH12    ;   ENDIF
+      IF( ln_pnd_LEV  ) THEN   ;   ioptio = ioptio + 1   ;   nice_pnd = np_pndLEV    ;   ENDIF
       IF( ioptio /= 1 )   &
-         & CALL ctl_stop( 'ice_thd_pnd_init: choose either none (ln_pnd=F) or only one pond scheme (ln_pnd_H12 or ln_pnd_CST)' )
+         & CALL ctl_stop( 'ice_thd_pnd_init: choose either none (ln_pnd=F) or only one pond scheme (ln_pnd_LEV or ln_pnd_CST)' )
       !
       SELECT CASE( nice_pnd )
       CASE( np_pndNO )         
-         IF( ln_pnd_alb ) THEN ; ln_pnd_alb = .FALSE. ; CALL ctl_warn( 'ln_pnd_alb=false when no ponds' ) ; ENDIF
+         IF( ln_pnd_alb  ) THEN ; ln_pnd_alb  = .FALSE. ; CALL ctl_warn( 'ln_pnd_alb=false when no ponds' )  ; ENDIF
+         IF( ln_pnd_lids ) THEN ; ln_pnd_lids = .FALSE. ; CALL ctl_warn( 'ln_pnd_lids=false when no ponds' ) ; ENDIF
+      CASE( np_pndCST )         
+         IF( ln_pnd_lids ) THEN ; ln_pnd_lids = .FALSE. ; CALL ctl_warn( 'ln_pnd_lids=false when constant ponds' ) ; ENDIF
       END SELECT
       !
Index: NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icethd_sal.F90
===================================================================
--- NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icethd_sal.F90	(revision 13033)
+++ NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icethd_sal.F90	(revision 13727)
@@ -55,9 +55,8 @@
       !!               -> nn_icesal = 3 -> Sice = S(z)   [multiyear ice]
       !!---------------------------------------------------------------------
-      LOGICAL, INTENT(in) ::   ld_sal            ! gravity drainage and flushing or not 
+      LOGICAL, INTENT(in) ::   ld_sal          ! gravity drainage and flushing or not 
       !
-      INTEGER  ::   ji, jk                       ! dummy loop indices 
-      REAL(wp) ::   iflush, igravdr              ! local scalars
-      REAL(wp) ::   zs_sni, zs_i_gd, zs_i_fl, zs_i_si, zs_i_bg   ! local scalars
+      INTEGER  ::   ji                         ! dummy loop indices 
+      REAL(wp) ::   zs_sni, zds                ! local scalars
       REAL(wp) ::   z1_time_gd, z1_time_fl
       !!---------------------------------------------------------------------
@@ -68,36 +67,43 @@
       CASE( 2 )       !  time varying salinity with linear profile  !
          !            !---------------------------------------------!
-         z1_time_gd = 1._wp / rn_time_gd * rDt_ice
-         z1_time_fl = 1._wp / rn_time_fl * rDt_ice
+         z1_time_gd = rDt_ice / rn_time_gd
+         z1_time_fl = rDt_ice / rn_time_fl
          !
          DO ji = 1, npti
             !
-            !---------------------------------------------------------
-            !  Update ice salinity from snow-ice and bottom growth
-            !---------------------------------------------------------
             IF( h_i_1d(ji) > 0._wp ) THEN
-               zs_sni  = sss_1d(ji) * ( rhoi - rhos ) * r1_rhoi                     ! Salinity of snow ice
-               zs_i_si = ( zs_sni      - s_i_1d(ji) ) * dh_snowice(ji) / h_i_1d(ji) ! snow-ice    
-               zs_i_bg = ( s_i_new(ji) - s_i_1d(ji) ) * dh_i_bog  (ji) / h_i_1d(ji) ! bottom growth
-               ! Update salinity (nb: salt flux already included in icethd_dh)
-               s_i_1d(ji) = s_i_1d(ji) + zs_i_bg + zs_i_si
+               !
+               ! --- Update ice salinity from snow-ice and bottom growth --- !
+               zs_sni = sss_1d(ji) * ( rhoi - rhos ) * r1_rhoi                           ! salinity of snow ice
+               zds    =       ( zs_sni      - s_i_1d(ji) ) * dh_snowice(ji) / h_i_1d(ji) ! snow-ice    
+               zds    = zds + ( s_i_new(ji) - s_i_1d(ji) ) * dh_i_bog  (ji) / h_i_1d(ji) ! bottom growth
+               ! update salinity (nb: salt flux already included in icethd_dh)
+               s_i_1d(ji) = s_i_1d(ji) + zds
+               !
+               ! --- Update ice salinity from brine drainage and flushing --- !
+               IF( ld_sal ) THEN
+                  IF( t_su_1d(ji) >= rt0 ) THEN             ! flushing (summer time)
+                     zds = - MAX( s_i_1d(ji) - rn_sal_fl , 0._wp ) * z1_time_fl
+                  ELSEIF( t_su_1d(ji) <= t_bo_1d(ji) ) THEN ! gravity drainage
+                     zds = - MAX( s_i_1d(ji) - rn_sal_gd , 0._wp ) * z1_time_gd
+                  ELSE
+                     zds = 0._wp
+                  ENDIF
+                  ! update salinity
+                  s_i_1d(ji) = s_i_1d(ji) + zds
+                  ! salt flux
+                  sfx_bri_1d(ji) = sfx_bri_1d(ji) - rhoi * a_i_1d(ji) * h_i_1d(ji) * zds * r1_Dt_ice
+               ENDIF
+               !
+               ! --- salinity must stay inbounds --- !
+               zds =       MAX( 0._wp, rn_simin - s_i_1d(ji) ) ! > 0 if s_i < simin
+               zds = zds + MIN( 0._wp, rn_simax - s_i_1d(ji) ) ! < 0 if s_i > simax
+               ! update salinity
+               s_i_1d(ji) = s_i_1d(ji) + zds
+               ! salt flux
+               sfx_res_1d(ji) = sfx_res_1d(ji) - rhoi * a_i_1d(ji) * h_i_1d(ji) * zds * r1_Dt_ice
+               !
             ENDIF
             !
-            IF( ld_sal ) THEN
-               !---------------------------------------------------------
-               !  Update ice salinity from brine drainage and flushing
-               !---------------------------------------------------------
-               iflush   = MAX( 0._wp , SIGN( 1._wp , t_su_1d(ji) - rt0         ) )  ! =1 if summer 
-               igravdr  = MAX( 0._wp , SIGN( 1._wp , t_bo_1d(ji) - t_su_1d(ji) ) )  ! =1 if t_su < t_bo
-
-               zs_i_gd = - igravdr * MAX( s_i_1d(ji) - rn_sal_gd , 0._wp ) * z1_time_gd  ! gravity drainage 
-               zs_i_fl = - iflush  * MAX( s_i_1d(ji) - rn_sal_fl , 0._wp ) * z1_time_fl  ! flushing
-               
-               ! Update salinity   
-               s_i_1d(ji) = s_i_1d(ji) + zs_i_fl + zs_i_gd
-               
-               ! Salt flux
-               sfx_bri_1d(ji) = sfx_bri_1d(ji) - rhoi * a_i_1d(ji) * h_i_1d(ji) * ( zs_i_fl + zs_i_gd ) * r1_Dt_ice
-            ENDIF
          END DO
          !
Index: NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icethd_zdf.F90
===================================================================
--- NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icethd_zdf.F90	(revision 13033)
+++ NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icethd_zdf.F90	(revision 13727)
@@ -85,5 +85,6 @@
       INTEGER  ::   ios, ioptio   ! Local integer
       !!
-      NAMELIST/namthd_zdf/ ln_zdf_BL99, ln_cndi_U64, ln_cndi_P07, rn_cnd_s, rn_kappa_i
+      NAMELIST/namthd_zdf/ ln_zdf_BL99, ln_cndi_U64, ln_cndi_P07, rn_cnd_s, &
+         &                 rn_kappa_i, rn_kappa_s, rn_kappa_smlt, rn_kappa_sdry, ln_zdf_chkcvg
       !!-------------------------------------------------------------------
       !
@@ -99,9 +100,13 @@
          WRITE(numout,*) '~~~~~~~~~~~~~~~~'
          WRITE(numout,*) '   Namelist namthd_zdf:'
-         WRITE(numout,*) '      Bitz and Lipscomb (1999) formulation                    ln_zdf_BL99  = ', ln_zdf_BL99
-         WRITE(numout,*) '      thermal conductivity in the ice (Untersteiner 1964)     ln_cndi_U64  = ', ln_cndi_U64
-         WRITE(numout,*) '      thermal conductivity in the ice (Pringle et al 2007)    ln_cndi_P07  = ', ln_cndi_P07
-         WRITE(numout,*) '      thermal conductivity in the snow                        rn_cnd_s     = ', rn_cnd_s
-         WRITE(numout,*) '      extinction radiation parameter in sea ice               rn_kappa_i   = ', rn_kappa_i
+         WRITE(numout,*) '      Bitz and Lipscomb (1999) formulation                      ln_zdf_BL99   = ', ln_zdf_BL99
+         WRITE(numout,*) '      thermal conductivity in the ice (Untersteiner 1964)       ln_cndi_U64   = ', ln_cndi_U64
+         WRITE(numout,*) '      thermal conductivity in the ice (Pringle et al 2007)      ln_cndi_P07   = ', ln_cndi_P07
+         WRITE(numout,*) '      thermal conductivity in the snow                          rn_cnd_s      = ', rn_cnd_s
+         WRITE(numout,*) '      extinction radiation parameter in sea ice                 rn_kappa_i    = ', rn_kappa_i
+         WRITE(numout,*) '      extinction radiation parameter in snw      (nn_qtrice=0)  rn_kappa_s    = ', rn_kappa_s
+         WRITE(numout,*) '      extinction radiation parameter in melt snw (nn_qtrice=1)  rn_kappa_smlt = ', rn_kappa_smlt
+         WRITE(numout,*) '      extinction radiation parameter in dry  snw (nn_qtrice=1)  rn_kappa_sdry = ', rn_kappa_sdry
+         WRITE(numout,*) '      check convergence of heat diffusion scheme                ln_zdf_chkcvg = ', ln_zdf_chkcvg
       ENDIF
       !
Index: NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icethd_zdf_bl99.F90
===================================================================
--- NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icethd_zdf_bl99.F90	(revision 13033)
+++ NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icethd_zdf_bl99.F90	(revision 13727)
@@ -85,21 +85,21 @@
 
       LOGICAL, DIMENSION(jpij) ::   l_T_converged   ! true when T converges (per grid point)
-!
+      !
       REAL(wp) ::   zg1s      =  2._wp        ! for the tridiagonal system
       REAL(wp) ::   zg1       =  2._wp        !
       REAL(wp) ::   zgamma    =  18009._wp    ! for specific heat
       REAL(wp) ::   zbeta     =  0.117_wp     ! for thermal conductivity (could be 0.13)
-      REAL(wp) ::   zraext_s  =  10._wp       ! extinction coefficient of radiation in the snow
       REAL(wp) ::   zkimin    =  0.10_wp      ! minimum ice thermal conductivity
       REAL(wp) ::   ztsu_err  =  1.e-5_wp     ! range around which t_su is considered at 0C 
       REAL(wp) ::   zdti_bnd  =  1.e-4_wp     ! maximal authorized error on temperature 
-      REAL(wp) ::   zhs_min   =  0.01_wp      ! minimum snow thickness for conductivity calculation 
+      REAL(wp) ::   zhs_ssl   =  0.03_wp      ! surface scattering layer in the snow 
+      REAL(wp) ::   zhi_ssl   =  0.10_wp      ! surface scattering layer in the ice
+      REAL(wp) ::   zh_min    =  1.e-3_wp     ! minimum ice/snow thickness for conduction
       REAL(wp) ::   ztmelts                   ! ice melting temperature
       REAL(wp) ::   zdti_max                  ! current maximal error on temperature 
       REAL(wp) ::   zcpi                      ! Ice specific heat
       REAL(wp) ::   zhfx_err, zdq             ! diag errors on heat
-      REAL(wp) ::   zfac                      ! dummy factor
-      !
-      REAL(wp), DIMENSION(jpij) ::   isnow        ! switch for presence (1) or absence (0) of snow
+      !
+      REAL(wp), DIMENSION(jpij) ::   zraext_s     ! extinction coefficient of radiation in the snow
       REAL(wp), DIMENSION(jpij) ::   ztsub        ! surface temperature at previous iteration
       REAL(wp), DIMENSION(jpij) ::   zh_i, z1_h_i ! ice layer thickness
@@ -124,4 +124,5 @@
       REAL(wp), DIMENSION(jpij,0:nlay_s)   ::   zkappa_s    ! Kappa factor in the snow
       REAL(wp), DIMENSION(jpij,0:nlay_s)   ::   zeta_s      ! Eta factor in the snow
+      REAL(wp), DIMENSION(jpij)            ::   zkappa_comb ! Combined snow and ice surface conductivity
       REAL(wp), DIMENSION(jpij,nlay_i+3)   ::   zindterm    ! 'Ind'ependent term
       REAL(wp), DIMENSION(jpij,nlay_i+3)   ::   zindtbis    ! Temporary 'ind'ependent term
@@ -130,4 +131,7 @@
       REAL(wp), DIMENSION(jpij)            ::   zq_ini      ! diag errors on heat
       REAL(wp), DIMENSION(jpij)            ::   zghe        ! G(he), th. conduct enhancement factor, mono-cat
+      REAL(wp), DIMENSION(jpij)            ::   za_s_fra    ! ice fraction covered by snow 
+      REAL(wp), DIMENSION(jpij)            ::   isnow       ! snow presence (1) or not (0) 
+      REAL(wp), DIMENSION(jpij)            ::   isnow_comb  ! snow presence for met-office 
       !
       ! Mono-category
@@ -143,27 +147,52 @@
       END DO
 
+      ! calculate ice fraction covered by snow for radiation
+      CALL ice_var_snwfra( h_s_1d(1:npti), za_s_fra(1:npti) )
+      
       !------------------
       ! 1) Initialization
       !------------------
+      !
+      ! extinction radiation in the snow
+      IF    ( nn_qtrice == 0 ) THEN   ! constant 
+         zraext_s(1:npti) = rn_kappa_s
+      ELSEIF( nn_qtrice == 1 ) THEN   ! depends on melting/freezing conditions
+         WHERE( t_su_1d(1:npti) < rt0 )   ;   zraext_s(1:npti) = rn_kappa_sdry   ! no surface melting
+         ELSEWHERE                        ;   zraext_s(1:npti) = rn_kappa_smlt   !    surface melting
+         END WHERE
+      ENDIF
+      !
+      ! thicknesses
       DO ji = 1, npti
-         isnow(ji) = 1._wp - MAX( 0._wp , SIGN(1._wp, - h_s_1d(ji) ) )  ! is there snow or not
-         ! layer thickness
-         zh_i(ji) = h_i_1d(ji) * r1_nlay_i
-         zh_s(ji) = h_s_1d(ji) * r1_nlay_s
+         ! ice thickness
+         IF( h_i_1d(ji) > 0._wp ) THEN 
+            zh_i  (ji) = MAX( zh_min , h_i_1d(ji) ) * r1_nlay_i ! set a minimum thickness for conduction
+            z1_h_i(ji) = 1._wp / zh_i(ji)                       !       it must be very small
+         ELSE
+            zh_i  (ji) = 0._wp
+            z1_h_i(ji) = 0._wp
+         ENDIF
+         ! snow thickness
+         IF( h_s_1d(ji) > 0._wp ) THEN
+            zh_s  (ji) = MAX( zh_min , h_s_1d(ji) ) * r1_nlay_s ! set a minimum thickness for conduction
+            z1_h_s(ji) = 1._wp / zh_s(ji)                       !       it must be very small
+            isnow (ji) = 1._wp
+         ELSE
+            zh_s  (ji) = 0._wp
+            z1_h_s(ji) = 0._wp
+            isnow (ji) = 0._wp
+         ENDIF
+         ! for Met-Office
+         IF( h_s_1d(ji) < zh_min ) THEN
+            isnow_comb(ji) = h_s_1d(ji) / zh_min
+         ELSE
+            isnow_comb(ji) = 1._wp
+         ENDIF
       END DO
-      !
-      WHERE( zh_i(1:npti) >= epsi10 )   ;   z1_h_i(1:npti) = 1._wp / zh_i(1:npti)
-      ELSEWHERE                         ;   z1_h_i(1:npti) = 0._wp
-      END WHERE
-      !
-      WHERE( zh_s(1:npti) > 0._wp   )       zh_s(1:npti) = MAX( zhs_min * r1_nlay_s, zh_s(1:npti) )
-      !
-      WHERE( zh_s(1:npti) > 0._wp   )   ;   z1_h_s(1:npti) = 1._wp / zh_s(1:npti)
-      ELSEWHERE                         ;   z1_h_s(1:npti) = 0._wp
-      END WHERE
+      ! clem: we should apply correction on snow thickness to take into account snow fraction
+      !       it must be a distribution, so it is a bit complicated
       !
       ! Store initial temperatures and non solar heat fluxes
       IF( k_cnd == np_cnd_OFF .OR. k_cnd == np_cnd_EMU ) THEN
-         !
          ztsub      (1:npti) = t_su_1d(1:npti)                          ! surface temperature at iteration n-1
          ztsuold    (1:npti) = t_su_1d(1:npti)                          ! surface temperature initial value
@@ -185,5 +214,5 @@
          DO ji = 1, npti
             !                             ! radiation transmitted below the layer-th snow layer
-            zradtr_s(ji,jk) = zradtr_s(ji,0) * EXP( - zraext_s * h_s_1d(ji) * r1_nlay_s * REAL(jk) )
+            zradtr_s(ji,jk) = zradtr_s(ji,0) * EXP( - zraext_s(ji) * MAX( 0._wp, zh_s(ji) * REAL(jk) - zhs_ssl ) )
             !                             ! radiation absorbed by the layer-th snow layer
             zradab_s(ji,jk) = zradtr_s(ji,jk-1) - zradtr_s(ji,jk)
@@ -191,9 +220,12 @@
       END DO
       !
-      zradtr_i(1:npti,0) = zradtr_s(1:npti,nlay_s) * isnow(1:npti) + qtr_ice_top_1d(1:npti) * ( 1._wp - isnow(1:npti) )
+      zradtr_i(1:npti,0) = zradtr_s(1:npti,nlay_s) * za_s_fra(1:npti) + qtr_ice_top_1d(1:npti) * ( 1._wp - za_s_fra(1:npti) )
       DO jk = 1, nlay_i 
          DO ji = 1, npti
             !                             ! radiation transmitted below the layer-th ice layer
-            zradtr_i(ji,jk) = zradtr_i(ji,0) * EXP( - rn_kappa_i * zh_i(ji) * REAL(jk) )
+            zradtr_i(ji,jk) =           za_s_fra(ji)   * zradtr_s(ji,nlay_s)                       &   ! part covered by snow
+               &                                       * EXP( - rn_kappa_i * MAX( 0._wp, zh_i(ji) * REAL(jk) - zh_min  ) ) &
+               &            + ( 1._wp - za_s_fra(ji) ) * qtr_ice_top_1d(ji)                        &   ! part snow free
+               &                                       * EXP( - rn_kappa_i * MAX( 0._wp, zh_i(ji) * REAL(jk) - zhi_ssl ) )            
             !                             ! radiation absorbed by the layer-th ice layer
             zradab_i(ji,jk) = zradtr_i(ji,jk-1) - zradtr_i(ji,jk)
@@ -203,5 +235,5 @@
       qtr_ice_bot_1d(1:npti) = zradtr_i(1:npti,nlay_i)   ! record radiation transmitted below the ice
       !
-      iconv    = 0          ! number of iterations
+      iconv = 0          ! number of iterations
       !
       l_T_converged(:) = .FALSE.
@@ -230,5 +262,5 @@
                DO ji = 1, npti
                   ztcond_i_cp(ji,jk) = rcnd_i + zbeta * 0.5_wp * ( sz_i_1d(ji,jk) + sz_i_1d(ji,jk+1) ) /  &
-                     &                         MIN( -epsi10, 0.5_wp * (t_i_1d(ji,jk) + t_i_1d(ji,jk+1)) - rt0 )
+                     &                    MIN( -epsi10, 0.5_wp * (  t_i_1d(ji,jk) +  t_i_1d(ji,jk+1) ) - rt0 )
                END DO
             END DO
@@ -238,13 +270,13 @@
             DO ji = 1, npti
                ztcond_i_cp(ji,0)      = rcnd_i + 0.09_wp  *  sz_i_1d(ji,1)      / MIN( -epsi10, t_i_1d(ji,1) - rt0 )  &
-                  &                           - 0.011_wp * ( t_i_1d(ji,1) - rt0 )
+                  &                            - 0.011_wp * ( t_i_1d(ji,1) - rt0 )
                ztcond_i_cp(ji,nlay_i) = rcnd_i + 0.09_wp  *  sz_i_1d(ji,nlay_i) / MIN( -epsi10, t_bo_1d(ji)  - rt0 )  &
-                  &                           - 0.011_wp * ( t_bo_1d(ji) - rt0 )
+                  &                            - 0.011_wp * ( t_bo_1d(ji) - rt0 )
             END DO
             DO jk = 1, nlay_i-1
                DO ji = 1, npti
-                  ztcond_i_cp(ji,jk) = rcnd_i + 0.09_wp  *   0.5_wp * ( sz_i_1d(ji,jk) + sz_i_1d(ji,jk+1) ) /        &
-                     &                        MIN( -epsi10, 0.5_wp * ( t_i_1d (ji,jk) + t_i_1d (ji,jk+1) ) - rt0 )  &
-                     &                       - 0.011_wp * ( 0.5_wp * ( t_i_1d (ji,jk) + t_i_1d (ji,jk+1) ) - rt0 )
+                  ztcond_i_cp(ji,jk) = rcnd_i + 0.09_wp  *   0.5_wp * ( sz_i_1d(ji,jk) + sz_i_1d(ji,jk+1) ) /       &
+                     &                         MIN( -epsi10, 0.5_wp * (  t_i_1d(ji,jk) +  t_i_1d(ji,jk+1) ) - rt0 ) &
+                     &                        - 0.011_wp * ( 0.5_wp * (  t_i_1d(ji,jk) +  t_i_1d(ji,jk+1) ) - rt0 )
                END DO
             END DO
@@ -290,12 +322,7 @@
          END DO
          DO ji = 1, npti   ! Snow-ice interface
-            IF ( .NOT. l_T_converged(ji) ) THEN
-               zfac = 0.5_wp * ( ztcond_i(ji,0) * zh_s(ji) + rn_cnd_s * zh_i(ji) )
-               IF( zfac > epsi10 ) THEN
-                  zkappa_s(ji,nlay_s) = zghe(ji) * rn_cnd_s * ztcond_i(ji,0) / zfac
-               ELSE
-                  zkappa_s(ji,nlay_s) = 0._wp
-               ENDIF
-            ENDIF
+            IF ( .NOT. l_T_converged(ji) ) &
+               zkappa_s(ji,nlay_s) = isnow(ji) * zghe(ji) * rn_cnd_s * ztcond_i(ji,0) &
+                  &                            / ( 0.5_wp * ( ztcond_i(ji,0) * zh_s(ji) + rn_cnd_s * zh_i(ji) ) )
          END DO
 
@@ -310,6 +337,10 @@
          END DO
          DO ji = 1, npti   ! Snow-ice interface
-            IF ( .NOT. l_T_converged(ji) ) &
-               zkappa_i(ji,0) = zkappa_s(ji,nlay_s) * isnow(ji) + zkappa_i(ji,0) * ( 1._wp - isnow(ji) )
+            IF ( .NOT. l_T_converged(ji) ) THEN
+               ! Calculate combined surface snow and ice conductivity to pass through the coupler (met-office)
+               zkappa_comb(ji) = isnow_comb(ji) * zkappa_s(ji,0) + ( 1._wp - isnow_comb(ji) ) * zkappa_i(ji,0)
+               ! If there is snow then use the same snow-ice interface conductivity for the top layer of ice
+               IF( h_s_1d(ji) > 0._wp )   zkappa_i(ji,0) = zkappa_s(ji,nlay_s)
+           ENDIF
          END DO
          !
@@ -320,5 +351,5 @@
             DO ji = 1, npti
                zcpi = rcpi + zgamma * sz_i_1d(ji,jk) / MAX( ( t_i_1d(ji,jk) - rt0 ) * ( ztiold(ji,jk) - rt0 ), epsi10 )
-               zeta_i(ji,jk) = rDt_ice * r1_rhoi * z1_h_i(ji) / MAX( epsi10, zcpi ) 
+               zeta_i(ji,jk) = rDt_ice * r1_rhoi * z1_h_i(ji) / zcpi
             END DO
          END DO
@@ -544,9 +575,10 @@
                   ztsub(ji) = t_su_1d(ji)
                   IF( t_su_1d(ji) < rt0 ) THEN
-                     t_su_1d(ji) = ( zindtbis(ji,jm_min(ji)) - ztrid(ji,jm_min(ji),3) *  &
-                        &          ( isnow(ji) * t_s_1d(ji,1) + ( 1._wp - isnow(ji) ) * t_i_1d(ji,1) ) ) / zdiagbis(ji,jm_min(ji))
+                     t_su_1d(ji) = (  zindtbis(ji,jm_min(ji)) - ztrid(ji,jm_min(ji),3) *  &
+                        &           ( isnow(ji) * t_s_1d(ji,1) + ( 1._wp - isnow(ji) ) *  t_i_1d(ji,1) ) ) / zdiagbis(ji,jm_min(ji))
                   ENDIF
                ENDIF
             END DO
+            !clem: in order to have several layers of snow, there is a missing loop here for t_s_1d(1:nlay_s-1)
             !
             !--------------------------------------------------------------
@@ -561,9 +593,14 @@
 
                IF ( .NOT. l_T_converged(ji) ) THEN
+
                   t_su_1d(ji) = MAX( MIN( t_su_1d(ji) , rt0 ) , rt0 - 100._wp )
                   zdti_max    = MAX( zdti_max, ABS( t_su_1d(ji) - ztsub(ji) ) )
 
-                  t_s_1d(ji,1:nlay_s) = MAX( MIN( t_s_1d(ji,1:nlay_s), rt0 ), rt0 - 100._wp )
-                  zdti_max = MAX ( zdti_max , MAXVAL( ABS( t_s_1d(ji,1:nlay_s) - ztsb(ji,1:nlay_s) ) ) )
+                  IF( h_s_1d(ji) > 0._wp ) THEN
+                     DO jk = 1, nlay_s
+                        t_s_1d(ji,jk) = MAX( MIN( t_s_1d(ji,jk), rt0 ), rt0 - 100._wp )
+                        zdti_max      = MAX ( zdti_max , ABS( t_s_1d(ji,jk) - ztsb(ji,jk) ) )
+                     END DO
+                  ENDIF
 
                   DO jk = 1, nlay_i
@@ -572,6 +609,12 @@
                      zdti_max      =  MAX( zdti_max, ABS( t_i_1d(ji,jk) - ztib(ji,jk) ) )
                   END DO
-
-                  IF ( zdti_max < zdti_bnd ) l_T_converged(ji) = .TRUE.
+                  
+                  ! convergence test
+                  IF( ln_zdf_chkcvg ) THEN
+                     tice_cvgerr_1d(ji) = zdti_max
+                     tice_cvgstp_1d(ji) = REAL(iconv)
+                  ENDIF
+
+                  IF( zdti_max < zdti_bnd )   l_T_converged(ji) = .TRUE.
 
                ENDIF
@@ -726,4 +769,5 @@
                ENDIF
             END DO
+            !clem: in order to have several layers of snow, there is a missing loop here for t_s_1d(1:nlay_s-1)
             !
             !--------------------------------------------------------------
@@ -738,8 +782,12 @@
 
                IF ( .NOT. l_T_converged(ji) ) THEN
-                  ! t_s
-                  t_s_1d(ji,1:nlay_s) = MAX( MIN( t_s_1d(ji,1:nlay_s), rt0 ), rt0 - 100._wp )
-                  zdti_max = MAX ( zdti_max , MAXVAL( ABS( t_s_1d(ji,1:nlay_s) - ztsb(ji,1:nlay_s) ) ) )
-                  ! t_i
+
+                  IF( h_s_1d(ji) > 0._wp ) THEN
+                     DO jk = 1, nlay_s
+                        t_s_1d(ji,jk) = MAX( MIN( t_s_1d(ji,jk), rt0 ), rt0 - 100._wp )
+                        zdti_max      = MAX ( zdti_max , ABS( t_s_1d(ji,jk) - ztsb(ji,jk) ) )
+                     END DO
+                  ENDIF
+
                   DO jk = 1, nlay_i
                      ztmelts       = -rTmlt * sz_i_1d(ji,jk) + rt0 
@@ -748,5 +796,11 @@
                   END DO
 
-                  IF ( zdti_max < zdti_bnd ) l_T_converged(ji) = .TRUE.
+                  ! convergence test
+                  IF( ln_zdf_chkcvg ) THEN
+                     tice_cvgerr_1d(ji) = zdti_max
+                     tice_cvgstp_1d(ji) = REAL(iconv)
+                  ENDIF
+
+                  IF( zdti_max < zdti_bnd )   l_T_converged(ji) = .TRUE.
 
                ENDIF
@@ -755,12 +809,6 @@
 
          ENDIF ! k_cnd
-         
+
       END DO  ! End of the do while iterative procedure
-      
-      IF( ln_icectl .AND. lwp ) THEN
-         WRITE(numout,*) ' zdti_max : ', zdti_max
-         WRITE(numout,*) ' iconv    : ', iconv
-      ENDIF
-      
       !
       !-----------------------------
@@ -771,5 +819,5 @@
       !     bottom ice conduction flux
       DO ji = 1, npti
-         qcn_ice_bot_1d(ji) = - zkappa_i(ji,nlay_i) * zg1  * ( t_bo_1d(ji ) - t_i_1d (ji,nlay_i) )
+         qcn_ice_bot_1d(ji) = - zkappa_i(ji,nlay_i) * zg1 * ( t_bo_1d(ji ) - t_i_1d (ji,nlay_i) )
       END DO
       !     surface ice conduction flux
@@ -777,6 +825,6 @@
          !
          DO ji = 1, npti
-            qcn_ice_top_1d(ji) =  -           isnow(ji)   * zkappa_s(ji,0) * zg1s * ( t_s_1d(ji,1) - t_su_1d(ji) )  &
-               &                  - ( 1._wp - isnow(ji) ) * zkappa_i(ji,0) * zg1  * ( t_i_1d(ji,1) - t_su_1d(ji) )
+            qcn_ice_top_1d(ji) = -           isnow(ji)   * zkappa_s(ji,0) * zg1s * ( t_s_1d(ji,1) - t_su_1d(ji) ) &
+               &                 - ( 1._wp - isnow(ji) ) * zkappa_i(ji,0) * zg1  * ( t_i_1d(ji,1) - t_su_1d(ji) )
          END DO
          !
@@ -792,8 +840,7 @@
          !
          DO ji = 1, npti
-            t_su_1d(ji) = (  qcn_ice_top_1d(ji) &            ! calculate surface temperature
-               &           +           isnow(ji)   * zkappa_s(ji,0) * zg1s * t_s_1d(ji,1) &
-               &           + ( 1._wp - isnow(ji) ) * zkappa_i(ji,0) * zg1  * t_i_1d(ji,1) &
-               &          ) / MAX( epsi10, isnow(ji) * zkappa_s(ji,0) * zg1s + ( 1._wp - isnow(ji) ) * zkappa_i(ji,0) * zg1 )
+            t_su_1d(ji) = ( qcn_ice_top_1d(ji) +          isnow(ji)   * zkappa_s(ji,0) * zg1s * t_s_1d(ji,1) + &
+               &                                ( 1._wp - isnow(ji) ) * zkappa_i(ji,0) * zg1  * t_i_1d(ji,1) ) &
+               &          / MAX( epsi10, isnow(ji) * zkappa_s(ji,0) * zg1s + ( 1._wp - isnow(ji) ) * zkappa_i(ji,0) * zg1 )
             t_su_1d(ji) = MAX( MIN( t_su_1d(ji), rt0 ), rt0 - 100._wp )  ! cap t_su
          END DO
@@ -853,13 +900,11 @@
       !--------------------------------------------------------------------
       ! effective conductivity and 1st layer temperature (needed by Met Office)
+      ! this is a conductivity at mid-layer, hence the factor 2
       DO ji = 1, npti
-         IF( h_s_1d(ji) > 0.1_wp ) THEN 
-            cnd_ice_1d(ji) = 2._wp * zkappa_s(ji,0)
+         IF( h_i_1d(ji) >= zhi_ssl ) THEN
+            cnd_ice_1d(ji) = 2._wp * zkappa_comb(ji)
+            !!cnd_ice_1d(ji) = 2._wp * zkappa_i(ji,0)
          ELSE
-            IF( h_i_1d(ji) > 0.1_wp ) THEN
-               cnd_ice_1d(ji) = 2._wp * zkappa_i(ji,0)
-            ELSE
-               cnd_ice_1d(ji) = 2._wp * ztcond_i(ji,0) * 10._wp
-            ENDIF
+            cnd_ice_1d(ji) = 2._wp * ztcond_i(ji,0) / zhi_ssl ! cnd_ice is capped by: cond_i/zhi_ssl
          ENDIF
          t1_ice_1d(ji) = isnow(ji) * t_s_1d(ji,1) + ( 1._wp - isnow(ji) ) * t_i_1d(ji,1)
@@ -877,8 +922,9 @@
       DO ji = 1, npti         
          !--- Snow-ice interfacial temperature (diagnostic SIMIP)
-         zfac = rn_cnd_s * zh_i(ji) + ztcond_i(ji,1) * zh_s(ji)
-         IF( h_s_1d(ji) >= zhs_min ) THEN
-            t_si_1d(ji) = ( rn_cnd_s       * zh_i(ji) * t_s_1d(ji,1) +   &
-               &            ztcond_i(ji,1) * zh_s(ji) * t_i_1d(ji,1) ) / MAX( epsi10, zfac )
+         IF( h_s_1d(ji) >= zhs_ssl ) THEN
+            t_si_1d(ji) = (   rn_cnd_s       * h_i_1d(ji) * r1_nlay_i * t_s_1d(ji,1)   &
+               &            + ztcond_i(ji,1) * h_s_1d(ji) * r1_nlay_s * t_i_1d(ji,1) ) &
+               &          / ( rn_cnd_s       * h_i_1d(ji) * r1_nlay_i &
+               &            + ztcond_i(ji,1) * h_s_1d(ji) * r1_nlay_s )
          ELSE
             t_si_1d(ji) = t_su_1d(ji)
Index: NEMO/branches/2020/dev_12905_xios_restart/src/ICE/iceupdate.F90
===================================================================
--- NEMO/branches/2020/dev_12905_xios_restart/src/ICE/iceupdate.F90	(revision 13033)
+++ NEMO/branches/2020/dev_12905_xios_restart/src/ICE/iceupdate.F90	(revision 13727)
@@ -24,5 +24,5 @@
    USE traqsr         ! add penetration of solar flux in the calculation of heat budget
    USE icectl         ! sea-ice: control prints
-   USE bdy_oce , ONLY : ln_bdy
+   USE zdfdrg  , ONLY : ln_drgice_imp
    !
    USE in_out_manager ! I/O manager
@@ -91,8 +91,6 @@
       !
       INTEGER  ::   ji, jj, jl, jk   ! dummy loop indices
-      REAL(wp) ::   zqmass           ! Heat flux associated with mass exchange ice->ocean (W.m-2)
       REAL(wp) ::   zqsr             ! New solar flux received by the ocean
-      REAL(wp), DIMENSION(jpi,jpj)     ::   z2d                  ! 2D workspace
-      REAL(wp), DIMENSION(jpi,jpj,jpl) ::   zalb_cs, zalb_os     ! 3D workspace
+      REAL(wp), DIMENSION(jpi,jpj) ::   z2d                  ! 2D workspace
       !!---------------------------------------------------------------------
       IF( ln_timing )   CALL timing_start('ice_update')
@@ -103,4 +101,8 @@
          WRITE(numout,*)'~~~~~~~~~~~~~~'
       ENDIF
+
+      ! Net heat flux on top of the ice-ocean (W.m-2)
+      !----------------------------------------------
+      qt_atm_oi(:,:) = qns_tot(:,:) + qsr_tot(:,:) 
 
       ! --- case we bypass ice thermodynamics --- !
@@ -113,7 +115,7 @@
       ENDIF
       
-      DO_2D_11_11
-
-         ! Solar heat flux reaching the ocean = zqsr (W.m-2) 
+      DO_2D( 1, 1, 1, 1 )
+
+         ! Solar heat flux reaching the ocean (max) = zqsr (W.m-2) 
          !---------------------------------------------------
          zqsr = qsr_tot(ji,jj) - SUM( a_i_b(ji,jj,:) * ( qsr_ice(ji,jj,:) - qtr_ice_bot(ji,jj,:) ) )
@@ -121,17 +123,27 @@
          ! Total heat flux reaching the ocean = qt_oce_ai (W.m-2) 
          !---------------------------------------------------
-         zqmass           = hfx_thd(ji,jj) + hfx_dyn(ji,jj) + hfx_res(ji,jj) ! heat flux from snow is 0 (T=0 degC)
-         qt_oce_ai(ji,jj) = qt_oce_ai(ji,jj) + zqmass + zqsr
-
-         ! Add the residual from heat diffusion equation and sublimation (W.m-2)
-         !----------------------------------------------------------------------
-         qt_oce_ai(ji,jj) = qt_oce_ai(ji,jj) + hfx_err_dif(ji,jj) +   &
-            &             ( hfx_sub(ji,jj) - SUM( qevap_ice(ji,jj,:) * a_i_b(ji,jj,:) ) )
-
+         qt_oce_ai(ji,jj) = qt_atm_oi(ji,jj) - hfx_sum(ji,jj) - hfx_bom(ji,jj) - hfx_bog(ji,jj) &
+            &                                - hfx_dif(ji,jj) - hfx_opw(ji,jj) - hfx_snw(ji,jj) &
+            &                                + hfx_thd(ji,jj) + hfx_dyn(ji,jj) + hfx_res(ji,jj) &
+            &                                + hfx_sub(ji,jj) - SUM( qevap_ice(ji,jj,:) * a_i_b(ji,jj,:) ) + hfx_spr(ji,jj)                 
+         
          ! New qsr and qns used to compute the oceanic heat flux at the next time step
          !----------------------------------------------------------------------------
-         qsr(ji,jj) = zqsr                                      
+         ! if warming and some ice remains, then we suppose that the whole solar flux has been consumed to melt the ice
+         ! else ( cooling or no ice left ), then we suppose that     no    solar flux has been consumed
+         !
+         IF( fhld(ji,jj) > 0._wp .AND. at_i(ji,jj) > 0._wp ) THEN   !-- warming and some ice remains
+            !                                        solar flux transmitted thru the 1st level of the ocean (i.e. not used by sea-ice)
+            qsr(ji,jj) = ( 1._wp - at_i_b(ji,jj) ) * qsr_oce(ji,jj) * ( 1._wp - frq_m(ji,jj) ) &
+               !                                   + solar flux transmitted thru ice and the 1st ocean level (also not used by sea-ice)
+               &             + SUM( a_i_b(ji,jj,:) * qtr_ice_bot(ji,jj,:) ) * ( 1._wp - frq_m(ji,jj) )
+            !
+         ELSE                                                       !-- cooling or no ice left
+            qsr(ji,jj) = zqsr
+         ENDIF
+         !
+         ! the non-solar is simply derived from the solar flux
          qns(ji,jj) = qt_oce_ai(ji,jj) - zqsr              
-
+         
          ! Mass flux at the atm. surface       
          !-----------------------------------
@@ -140,23 +152,14 @@
          ! Mass flux at the ocean surface      
          !------------------------------------
-         !  case of realistic freshwater flux (Tartinville et al., 2001) (presently ACTIVATED)
-         !  ------------------------------------------------------------------------------------- 
-         !  The idea of this approach is that the system that we consider is the ICE-OCEAN system
-         !  Thus  FW  flux  =  External ( E-P+snow melt)
-         !       Salt flux  =  Exchanges in the ice-ocean system then converted into FW
-         !                     Associated to Ice formation AND Ice melting
-         !                     Even if i see Ice melting as a FW and SALT flux
-         !        
-         ! mass flux from ice/ocean
+         ! ice-ocean  mass flux
          wfx_ice(ji,jj) = wfx_bog(ji,jj) + wfx_bom(ji,jj) + wfx_sum(ji,jj) + wfx_sni(ji,jj)   &
             &           + wfx_opw(ji,jj) + wfx_dyn(ji,jj) + wfx_res(ji,jj) + wfx_lam(ji,jj) + wfx_pnd(ji,jj)
-
-         ! add the snow melt water to snow mass flux to the ocean
+         
+         ! snw-ocean mass flux
          wfx_snw(ji,jj) = wfx_snw_sni(ji,jj) + wfx_snw_dyn(ji,jj) + wfx_snw_sum(ji,jj)
-
-         ! mass flux at the ocean/ice interface
-         fmmflx(ji,jj) = - ( wfx_ice(ji,jj) + wfx_snw(ji,jj) + wfx_err_sub(ji,jj) )              ! F/M mass flux save at least for biogeochemical model
-         emp(ji,jj)    = emp_oce(ji,jj) - wfx_ice(ji,jj) - wfx_snw(ji,jj) - wfx_err_sub(ji,jj)   ! mass flux + F/M mass flux (always ice/ocean mass exchange)
-
+         
+         ! total mass flux at the ocean/ice interface
+         fmmflx(ji,jj) =                - wfx_ice(ji,jj) - wfx_snw(ji,jj) - wfx_err_sub(ji,jj)   ! ice-ocean mass flux saved at least for biogeochemical model
+         emp   (ji,jj) = emp_oce(ji,jj) - wfx_ice(ji,jj) - wfx_snw(ji,jj) - wfx_err_sub(ji,jj)   ! atm-ocean + ice-ocean mass flux
 
          ! Salt flux at the ocean surface      
@@ -182,7 +185,6 @@
       ! Snow/ice albedo (only if sent to coupler, useless in forced mode)
       !------------------------------------------------------------------
-      CALL ice_alb( t_su, h_i, h_s, ln_pnd_alb, a_ip_frac, h_ip, zalb_cs, zalb_os ) ! cloud-sky and overcast-sky ice albedos
-      !
-      alb_ice(:,:,:) = ( 1._wp - cldf_ice ) * zalb_cs(:,:,:) + cldf_ice * zalb_os(:,:,:)
+      CALL ice_alb( t_su, h_i, h_s, ln_pnd_alb, a_ip_eff, h_ip, cloud_fra, alb_ice ) ! ice albedo
+
       !
       IF( lrst_ice ) THEN                       !* write snwice_mass fields in the restart file
@@ -263,5 +265,5 @@
       CALL iom_put ('hfxdif'     , hfx_dif     )   ! heat flux used for ice temperature change
       CALL iom_put ('hfxsnw'     , hfx_snw     )   ! heat flux used for snow melt 
-      CALL iom_put ('hfxerr'     , hfx_err_dif )   ! heat flux error after heat diffusion (included in qt_oce_ai)
+      CALL iom_put ('hfxerr'     , hfx_err_dif )   ! heat flux error after heat diffusion
 
       ! heat fluxes associated with mass exchange (freeze/melt/precip...)
@@ -280,9 +282,9 @@
       !---------
 #if ! defined key_agrif
-      IF( ln_icediachk .AND. .NOT. ln_bdy)   CALL ice_cons_final('iceupdate')                                       ! conservation
+      IF( ln_icediachk      )   CALL ice_cons_final('iceupdate')                                       ! conservation
 #endif
-      IF( ln_icectl                      )   CALL ice_prt       (kt, iiceprt, jiceprt, 3, 'Final state ice_update') ! prints
-      IF( sn_cfctl%l_prtctl              )   CALL ice_prt3D     ('iceupdate')                                       ! prints
-      IF( ln_timing                      )   CALL timing_stop   ('ice_update')                                      ! timing
+      IF( ln_icectl         )   CALL ice_prt       (kt, iiceprt, jiceprt, 3, 'Final state ice_update') ! prints
+      IF( sn_cfctl%l_prtctl )   CALL ice_prt3D     ('iceupdate')                                       ! prints
+      IF( ln_timing         )   CALL timing_stop   ('ice_update')                                      ! timing
       !
    END SUBROUTINE ice_update_flx
@@ -320,4 +322,5 @@
       REAL(wp) ::   zat_u, zutau_ice, zu_t, zmodt   ! local scalar
       REAL(wp) ::   zat_v, zvtau_ice, zv_t, zrhoco  !   -      -
+      REAL(wp) ::   zflagi                          !   -      -
       !!---------------------------------------------------------------------
       IF( ln_timing )   CALL timing_start('ice_update_tau')
@@ -332,5 +335,5 @@
       !
       IF( MOD( kt-1, nn_fsbc ) == 0 ) THEN     !==  Ice time-step only  ==!   (i.e. surface module time-step)
-         DO_2D_00_00
+         DO_2D( 0, 0, 0, 0 )                          !* update the modulus of stress at ocean surface (T-point)
             !                                               ! 2*(U_ice-U_oce) at T-point
             zu_t = u_ice(ji,jj) + u_ice(ji-1,jj) - u_oce(ji,jj) - u_oce(ji-1,jj)   
@@ -342,5 +345,5 @@
             tmod_io(ji,jj) = zrhoco * SQRT( zmodt )          ! rhoco * |U_ice-U_oce| at T-point
          END_2D
-         CALL lbc_lnk_multi( 'iceupdate', taum, 'T', 1., tmod_io, 'T', 1. )
+         CALL lbc_lnk_multi( 'iceupdate', taum, 'T', 1.0_wp, tmod_io, 'T', 1.0_wp )
          !
          utau_oce(:,:) = utau(:,:)                    !* save the air-ocean stresses at ice time-step
@@ -350,6 +353,13 @@
       !
       !                                      !==  every ocean time-step  ==!
-      !
-      DO_2D_00_00
+      IF ( ln_drgice_imp ) THEN
+         ! Save drag with right sign to update top drag in the ocean implicit friction 
+         rCdU_ice(:,:) = -r1_rho0 * tmod_io(:,:) * at_i(:,:) * tmask(:,:,1) 
+         zflagi = 0._wp
+      ELSE
+         zflagi = 1._wp
+      ENDIF
+      !
+      DO_2D( 0, 0, 0, 0 )                             !* update the stress WITHOUT an ice-ocean rotation angle
          ! ice area at u and v-points 
          zat_u  = ( at_i(ji,jj) * tmask(ji,jj,1) + at_i (ji+1,jj    ) * tmask(ji+1,jj  ,1) )  &
@@ -364,5 +374,5 @@
          vtau(ji,jj) = ( 1._wp - zat_v ) * vtau_oce(ji,jj) + zat_v * zvtau_ice
       END_2D
-      CALL lbc_lnk_multi( 'iceupdate', utau, 'U', -1., vtau, 'V', -1. )   ! lateral boundary condition
+      CALL lbc_lnk_multi( 'iceupdate', utau, 'U', -1.0_wp, vtau, 'V', -1.0_wp )   ! lateral boundary condition
       !
       IF( ln_timing )   CALL timing_stop('ice_update_tau')
@@ -417,7 +427,7 @@
             !
             IF( id1 > 0 ) THEN                       ! fields exist
-               IF(lrixios) CALL iom_swap(crixios_context) 
-               CALL iom_get( numrir, jpdom_autoglo, 'snwice_mass'  , snwice_mass,   ldxios = lrixios )
-               CALL iom_get( numrir, jpdom_autoglo, 'snwice_mass_b', snwice_mass_b, ldxios = lrixios )
+               IF(lrixios) CALL iom_swap(crixios_context)
+               CALL iom_get( numrir, jpdom_auto, 'snwice_mass'  , snwice_mass  , ldxios = lrixios )
+               CALL iom_get( numrir, jpdom_auto, 'snwice_mass_b', snwice_mass_b, ldxios = lrixios )
                IF(lrixios) CALL iom_swap(cxios_context)
             ELSE                                     ! start from rest
Index: NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icevar.F90
===================================================================
--- NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icevar.F90	(revision 13033)
+++ NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icevar.F90	(revision 13727)
@@ -51,4 +51,6 @@
    !!   ice_var_sshdyn    : compute equivalent ssh in lead
    !!   ice_var_itd       : convert N-cat to M-cat
+   !!   ice_var_snwfra    : fraction of ice covered by snow
+   !!   ice_var_snwblow   : distribute snow fall between ice and ocean
    !!----------------------------------------------------------------------
    USE dom_oce        ! ocean space and time domain
@@ -77,4 +79,6 @@
    PUBLIC   ice_var_sshdyn
    PUBLIC   ice_var_itd
+   PUBLIC   ice_var_snwfra
+   PUBLIC   ice_var_snwblow
 
    INTERFACE ice_var_itd
@@ -84,4 +88,13 @@
    !! * Substitutions
 #  include "do_loop_substitute.h90"
+
+   INTERFACE ice_var_snwfra
+      MODULE PROCEDURE ice_var_snwfra_1d, ice_var_snwfra_2d, ice_var_snwfra_3d
+   END INTERFACE
+
+   INTERFACE ice_var_snwblow
+      MODULE PROCEDURE ice_var_snwblow_1d, ice_var_snwblow_2d
+   END INTERFACE
+
    !!----------------------------------------------------------------------
    !! NEMO/ICE 4.0 , NEMO Consortium (2018)
@@ -115,4 +128,5 @@
       at_ip(:,:) = SUM( a_ip(:,:,:), dim=3 ) ! melt ponds
       vt_ip(:,:) = SUM( v_ip(:,:,:), dim=3 )
+      vt_il(:,:) = SUM( v_il(:,:,:), dim=3 )
       !
       ato_i(:,:) = 1._wp - at_i(:,:)         ! open water fraction  
@@ -166,6 +180,6 @@
          !
          !                           ! mean melt pond depth
-         WHERE( at_ip(:,:) > epsi20 )   ;   hm_ip(:,:) = vt_ip(:,:) / at_ip(:,:)
-         ELSEWHERE                      ;   hm_ip(:,:) = 0._wp
+         WHERE( at_ip(:,:) > epsi20 )   ;   hm_ip(:,:) = vt_ip(:,:) / at_ip(:,:)   ;   hm_il(:,:) = vt_il(:,:) / at_ip(:,:)
+         ELSEWHERE                      ;   hm_ip(:,:) = 0._wp                     ;   hm_il(:,:) = 0._wp
          END WHERE         
          !
@@ -191,5 +205,7 @@
       REAL(wp) ::   zhmax, z1_zhmax                 !   -      -
       REAL(wp) ::   zlay_i, zlay_s                  !   -      -
-      REAL(wp), DIMENSION(jpi,jpj,jpl) ::   z1_a_i, z1_v_i
+      REAL(wp), PARAMETER ::   zhl_max =  0.015_wp  ! pond lid thickness above which the ponds disappear from the albedo calculation
+      REAL(wp), PARAMETER ::   zhl_min =  0.005_wp  ! pond lid thickness below which the full pond area is used in the albedo calculation
+      REAL(wp), DIMENSION(jpi,jpj,jpl) ::   z1_a_i, z1_v_i, z1_a_ip, za_s_fra
       !!-------------------------------------------------------------------
 
@@ -210,4 +226,8 @@
       ELSEWHERE                      ;   z1_v_i(:,:,:) = 0._wp
       END WHERE
+      !
+      WHERE( a_ip(:,:,:) > epsi20 )  ;   z1_a_ip(:,:,:) = 1._wp / a_ip(:,:,:)
+      ELSEWHERE                      ;   z1_a_ip(:,:,:) = 0._wp
+      END WHERE
       !                                           !--- ice thickness
       h_i(:,:,:) = v_i (:,:,:) * z1_a_i(:,:,:)
@@ -224,9 +244,17 @@
       !                                           !--- ice age      
       o_i(:,:,:) = oa_i(:,:,:) * z1_a_i(:,:,:)
-      !                                           !--- pond fraction and thickness      
+      !                                           !--- pond and lid thickness      
+      h_ip(:,:,:) = v_ip(:,:,:) * z1_a_ip(:,:,:)
+      h_il(:,:,:) = v_il(:,:,:) * z1_a_ip(:,:,:)
+      !                                           !--- melt pond effective area (used for albedo)
       a_ip_frac(:,:,:) = a_ip(:,:,:) * z1_a_i(:,:,:)
-      WHERE( a_ip_frac(:,:,:) > epsi20 )   ;   h_ip(:,:,:) = v_ip(:,:,:) * z1_a_i(:,:,:) / a_ip_frac(:,:,:)
-      ELSEWHERE                            ;   h_ip(:,:,:) = 0._wp
-      END WHERE
+      WHERE    ( h_il(:,:,:) <= zhl_min )  ;   a_ip_eff(:,:,:) = a_ip_frac(:,:,:)       ! lid is very thin.  Expose all the pond
+      ELSEWHERE( h_il(:,:,:) >= zhl_max )  ;   a_ip_eff(:,:,:) = 0._wp                  ! lid is very thick. Cover all the pond up with ice and snow
+      ELSEWHERE                            ;   a_ip_eff(:,:,:) = a_ip_frac(:,:,:) * &   ! lid is in between. Expose part of the pond
+         &                                                       ( h_il(:,:,:) - zhl_min ) / ( zhl_max - zhl_min )
+      END WHERE
+      !
+      CALL ice_var_snwfra( h_s, za_s_fra )           ! calculate ice fraction covered by snow
+      a_ip_eff = MIN( a_ip_eff, 1._wp - za_s_fra )   ! make sure (a_ip_eff + a_s_fra) <= 1
       !
       !                                           !---  salinity (with a minimum value imposed everywhere)     
@@ -243,5 +271,5 @@
       zlay_i   = REAL( nlay_i , wp )    ! number of layers
       DO jl = 1, jpl
-         DO_3D_11_11( 1, nlay_i )
+         DO_3D( 1, 1, 1, 1, 1, nlay_i )
             IF ( v_i(ji,jj,jl) > epsi20 ) THEN     !--- icy area 
                !
@@ -292,4 +320,5 @@
       sv_i(:,:,:) = s_i (:,:,:) * v_i (:,:,:)
       v_ip(:,:,:) = h_ip(:,:,:) * a_ip(:,:,:)
+      v_il(:,:,:) = h_il(:,:,:) * a_ip(:,:,:)
       !
    END SUBROUTINE ice_var_eqv2glo
@@ -347,5 +376,5 @@
          z1_dS = 1._wp / ( zsi1 - zsi0 )
          DO jl = 1, jpl
-            DO_2D_11_11
+            DO_2D( 1, 1, 1, 1 )
                zalpha(ji,jj,jl) = MAX(  0._wp , MIN( ( zsi1 - s_i(ji,jj,jl) ) * z1_dS , 1._wp )  )
                !                             ! force a constant profile when SSS too low (Baltic Sea)
@@ -356,5 +385,5 @@
          ! Computation of the profile
          DO jl = 1, jpl
-            DO_3D_11_11( 1, nlay_i )
+            DO_3D( 1, 1, 1, 1, 1, nlay_i )
                !                          ! linear profile with 0 surface value
                zs0 = z_slope_s(ji,jj,jl) * ( REAL(jk,wp) - 0.5_wp ) * h_i(ji,jj,jl) * r1_nlay_i
@@ -486,5 +515,5 @@
          ! Zap ice energy and use ocean heat to melt ice
          !-----------------------------------------------------------------
-         DO_3D_11_11( 1, nlay_i )
+         DO_3D( 1, 1, 1, 1, 1, nlay_i )
             ! update exchanges with ocean
             hfx_res(ji,jj)   = hfx_res(ji,jj) - (1._wp - zswitch(ji,jj) ) * e_i(ji,jj,jk,jl) * r1_Dt_ice ! W.m-2 <0
@@ -493,5 +522,5 @@
          END_3D
          !
-         DO_3D_11_11( 1, nlay_s )
+         DO_3D( 1, 1, 1, 1, 1, nlay_s )
             ! update exchanges with ocean
             hfx_res(ji,jj)   = hfx_res(ji,jj) - (1._wp - zswitch(ji,jj) ) * e_s(ji,jj,jk,jl) * r1_Dt_ice ! W.m-2 <0
@@ -503,5 +532,5 @@
          ! zap ice and snow volume, add water and salt to ocean
          !-----------------------------------------------------------------
-         DO_2D_11_11
+         DO_2D( 1, 1, 1, 1 )
             ! update exchanges with ocean
             sfx_res(ji,jj)  = sfx_res(ji,jj) + (1._wp - zswitch(ji,jj) ) * sv_i(ji,jj,jl)   * rhoi * r1_Dt_ice
@@ -521,4 +550,5 @@
             a_ip (ji,jj,jl) = a_ip (ji,jj,jl) * zswitch(ji,jj)
             v_ip (ji,jj,jl) = v_ip (ji,jj,jl) * zswitch(ji,jj)
+            v_il (ji,jj,jl) = v_il (ji,jj,jl) * zswitch(ji,jj)
             !
          END_2D
@@ -542,5 +572,5 @@
 
 
-   SUBROUTINE ice_var_zapneg( pdt, pato_i, pv_i, pv_s, psv_i, poa_i, pa_i, pa_ip, pv_ip, pe_s, pe_i )
+   SUBROUTINE ice_var_zapneg( pdt, pato_i, pv_i, pv_s, psv_i, poa_i, pa_i, pa_ip, pv_ip, pv_il, pe_s, pe_i )
       !!-------------------------------------------------------------------
       !!                   ***  ROUTINE ice_var_zapneg ***
@@ -557,4 +587,5 @@
       REAL(wp), DIMENSION(:,:,:)  , INTENT(inout) ::   pa_ip      ! melt pond fraction
       REAL(wp), DIMENSION(:,:,:)  , INTENT(inout) ::   pv_ip      ! melt pond volume
+      REAL(wp), DIMENSION(:,:,:)  , INTENT(inout) ::   pv_il      ! melt pond lid volume
       REAL(wp), DIMENSION(:,:,:,:), INTENT(inout) ::   pe_s       ! snw heat content
       REAL(wp), DIMENSION(:,:,:,:), INTENT(inout) ::   pe_i       ! ice heat content
@@ -574,5 +605,5 @@
          ! zap ice energy and send it to the ocean
          !----------------------------------------
-         DO_3D_11_11( 1, nlay_i )
+         DO_3D( 1, 1, 1, 1, 1, nlay_i )
             IF( pe_i(ji,jj,jk,jl) < 0._wp .OR. pa_i(ji,jj,jl) <= 0._wp ) THEN
                hfx_res(ji,jj)   = hfx_res(ji,jj) - pe_i(ji,jj,jk,jl) * z1_dt ! W.m-2 >0
@@ -581,5 +612,5 @@
          END_3D
          !
-         DO_3D_11_11( 1, nlay_s )
+         DO_3D( 1, 1, 1, 1, 1, nlay_s )
             IF( pe_s(ji,jj,jk,jl) < 0._wp .OR. pa_i(ji,jj,jl) <= 0._wp ) THEN
                hfx_res(ji,jj)   = hfx_res(ji,jj) - pe_s(ji,jj,jk,jl) * z1_dt ! W.m-2 <0
@@ -591,5 +622,5 @@
          ! zap ice and snow volume, add water and salt to ocean
          !-----------------------------------------------------
-         DO_2D_11_11
+         DO_2D( 1, 1, 1, 1 )
             IF( pv_i(ji,jj,jl) < 0._wp .OR. pa_i(ji,jj,jl) <= 0._wp ) THEN
                wfx_res(ji,jj)    = wfx_res(ji,jj) + pv_i (ji,jj,jl) * rhoi * z1_dt
@@ -613,10 +644,10 @@
       WHERE( pa_ip (:,:,:) < 0._wp )   pa_ip (:,:,:) = 0._wp
       WHERE( pv_ip (:,:,:) < 0._wp )   pv_ip (:,:,:) = 0._wp ! in theory one should change wfx_pnd(-) and wfx_sum(+)
-      !                                                        but it does not change conservation, so keep it this way is ok
+      WHERE( pv_il (:,:,:) < 0._wp )   pv_il (:,:,:) = 0._wp !    but it does not change conservation, so keep it this way is ok
       !
    END SUBROUTINE ice_var_zapneg
 
 
-   SUBROUTINE ice_var_roundoff( pa_i, pv_i, pv_s, psv_i, poa_i, pa_ip, pv_ip, pe_s, pe_i )
+   SUBROUTINE ice_var_roundoff( pa_i, pv_i, pv_s, psv_i, poa_i, pa_ip, pv_ip, pv_il, pe_s, pe_i )
       !!-------------------------------------------------------------------
       !!                   ***  ROUTINE ice_var_roundoff ***
@@ -631,18 +662,23 @@
       REAL(wp), DIMENSION(:,:)  , INTENT(inout) ::   pa_ip      ! melt pond fraction
       REAL(wp), DIMENSION(:,:)  , INTENT(inout) ::   pv_ip      ! melt pond volume
+      REAL(wp), DIMENSION(:,:)  , INTENT(inout) ::   pv_il      ! melt pond lid volume
       REAL(wp), DIMENSION(:,:,:), INTENT(inout) ::   pe_s       ! snw heat content
       REAL(wp), DIMENSION(:,:,:), INTENT(inout) ::   pe_i       ! ice heat content
       !!-------------------------------------------------------------------
       !
-      WHERE( pa_i (1:npti,:)   < 0._wp .AND. pa_i (1:npti,:)   > -epsi10 )   pa_i (1:npti,:)   = 0._wp   !  a_i must be >= 0
-      WHERE( pv_i (1:npti,:)   < 0._wp .AND. pv_i (1:npti,:)   > -epsi10 )   pv_i (1:npti,:)   = 0._wp   !  v_i must be >= 0
-      WHERE( pv_s (1:npti,:)   < 0._wp .AND. pv_s (1:npti,:)   > -epsi10 )   pv_s (1:npti,:)   = 0._wp   !  v_s must be >= 0
-      WHERE( psv_i(1:npti,:)   < 0._wp .AND. psv_i(1:npti,:)   > -epsi10 )   psv_i(1:npti,:)   = 0._wp   ! sv_i must be >= 0
-      WHERE( poa_i(1:npti,:)   < 0._wp .AND. poa_i(1:npti,:)   > -epsi10 )   poa_i(1:npti,:)   = 0._wp   ! oa_i must be >= 0
-      WHERE( pe_i (1:npti,:,:) < 0._wp .AND. pe_i (1:npti,:,:) > -epsi06 )   pe_i (1:npti,:,:) = 0._wp   !  e_i must be >= 0
-      WHERE( pe_s (1:npti,:,:) < 0._wp .AND. pe_s (1:npti,:,:) > -epsi06 )   pe_s (1:npti,:,:) = 0._wp   !  e_s must be >= 0
-      IF( ln_pnd_H12 ) THEN
-         WHERE( pa_ip(1:npti,:) < 0._wp .AND. pa_ip(1:npti,:) > -epsi10 )    pa_ip(1:npti,:)   = 0._wp   ! a_ip must be >= 0
-         WHERE( pv_ip(1:npti,:) < 0._wp .AND. pv_ip(1:npti,:) > -epsi10 )    pv_ip(1:npti,:)   = 0._wp   ! v_ip must be >= 0
+
+      WHERE( pa_i (1:npti,:)   < 0._wp )   pa_i (1:npti,:)   = 0._wp   !  a_i must be >= 0
+      WHERE( pv_i (1:npti,:)   < 0._wp )   pv_i (1:npti,:)   = 0._wp   !  v_i must be >= 0
+      WHERE( pv_s (1:npti,:)   < 0._wp )   pv_s (1:npti,:)   = 0._wp   !  v_s must be >= 0
+      WHERE( psv_i(1:npti,:)   < 0._wp )   psv_i(1:npti,:)   = 0._wp   ! sv_i must be >= 0
+      WHERE( poa_i(1:npti,:)   < 0._wp )   poa_i(1:npti,:)   = 0._wp   ! oa_i must be >= 0
+      WHERE( pe_i (1:npti,:,:) < 0._wp )   pe_i (1:npti,:,:) = 0._wp   !  e_i must be >= 0
+      WHERE( pe_s (1:npti,:,:) < 0._wp )   pe_s (1:npti,:,:) = 0._wp   !  e_s must be >= 0
+      IF( ln_pnd_LEV ) THEN
+         WHERE( pa_ip(1:npti,:) < 0._wp )    pa_ip(1:npti,:)   = 0._wp   ! a_ip must be >= 0
+         WHERE( pv_ip(1:npti,:) < 0._wp )    pv_ip(1:npti,:)   = 0._wp   ! v_ip must be >= 0
+         IF( ln_pnd_lids ) THEN
+            WHERE( pv_il(1:npti,:) < 0._wp .AND. pv_il(1:npti,:) > -epsi10 ) pv_il(1:npti,:)   = 0._wp   ! v_il must be >= 0
+         ENDIF
       ENDIF
       !
@@ -763,6 +799,6 @@
    !! ** Purpose :  converting N-cat ice to jpl ice categories
    !!-------------------------------------------------------------------
-   SUBROUTINE ice_var_itd_1c1c( phti, phts, pati ,                       ph_i, ph_s, pa_i, &
-      &                         ptmi, ptms, ptmsu, psmi, patip, phtip,   pt_i, pt_s, pt_su, ps_i, pa_ip, ph_ip )
+   SUBROUTINE ice_var_itd_1c1c( phti, phts, pati ,                             ph_i, ph_s, pa_i, &
+      &                         ptmi, ptms, ptmsu, psmi, patip, phtip, phtil,  pt_i, pt_s, pt_su, ps_i, pa_ip, ph_ip, ph_il )
       !!-------------------------------------------------------------------
       !! ** Purpose :  converting 1-cat ice to 1 ice category
@@ -770,6 +806,6 @@
       REAL(wp), DIMENSION(:), INTENT(in)    ::   phti, phts, pati    ! input  ice/snow variables
       REAL(wp), DIMENSION(:), INTENT(inout) ::   ph_i, ph_s, pa_i    ! output ice/snow variables
-      REAL(wp), DIMENSION(:), INTENT(in)    ::   ptmi, ptms, ptmsu, psmi, patip, phtip    ! input  ice/snow temp & sal & ponds
-      REAL(wp), DIMENSION(:), INTENT(inout) ::   pt_i, pt_s, pt_su, ps_i, pa_ip, ph_ip    ! output ice/snow temp & sal & ponds
+      REAL(wp), DIMENSION(:), INTENT(in)    ::   ptmi, ptms, ptmsu, psmi, patip, phtip, phtil    ! input  ice/snow temp & sal & ponds
+      REAL(wp), DIMENSION(:), INTENT(inout) ::   pt_i, pt_s, pt_su, ps_i, pa_ip, ph_ip, ph_il    ! output ice/snow temp & sal & ponds
       !!-------------------------------------------------------------------
       ! == thickness and concentration == !
@@ -785,9 +821,10 @@
       pa_ip(:) = patip(:)
       ph_ip(:) = phtip(:)
+      ph_il(:) = phtil(:)
       
    END SUBROUTINE ice_var_itd_1c1c
 
-   SUBROUTINE ice_var_itd_Nc1c( phti, phts, pati ,                       ph_i, ph_s, pa_i, &
-      &                         ptmi, ptms, ptmsu, psmi, patip, phtip,   pt_i, pt_s, pt_su, ps_i, pa_ip, ph_ip )
+   SUBROUTINE ice_var_itd_Nc1c( phti, phts, pati ,                             ph_i, ph_s, pa_i, &
+      &                         ptmi, ptms, ptmsu, psmi, patip, phtip, phtil,  pt_i, pt_s, pt_su, ps_i, pa_ip, ph_ip, ph_il )
       !!-------------------------------------------------------------------
       !! ** Purpose :  converting N-cat ice to 1 ice category
@@ -795,6 +832,6 @@
       REAL(wp), DIMENSION(:,:), INTENT(in)    ::   phti, phts, pati    ! input  ice/snow variables
       REAL(wp), DIMENSION(:)  , INTENT(inout) ::   ph_i, ph_s, pa_i    ! output ice/snow variables
-      REAL(wp), DIMENSION(:,:), INTENT(in)    ::   ptmi, ptms, ptmsu, psmi, patip, phtip    ! input  ice/snow temp & sal & ponds
-      REAL(wp), DIMENSION(:)  , INTENT(inout) ::   pt_i, pt_s, pt_su, ps_i, pa_ip, ph_ip    ! output ice/snow temp & sal & ponds
+      REAL(wp), DIMENSION(:,:), INTENT(in)    ::   ptmi, ptms, ptmsu, psmi, patip, phtip, phtil    ! input  ice/snow temp & sal & ponds
+      REAL(wp), DIMENSION(:)  , INTENT(inout) ::   pt_i, pt_s, pt_su, ps_i, pa_ip, ph_ip, ph_il    ! output ice/snow temp & sal & ponds
       !
       REAL(wp), ALLOCATABLE, DIMENSION(:) ::   z1_ai, z1_vi, z1_vs
@@ -831,6 +868,10 @@
       ! == ponds == !
       pa_ip(:) = SUM( patip(:,:), dim=2 )
-      WHERE( pa_ip(:) /= 0._wp )   ;   ph_ip(:) = SUM( phtip(:,:) * patip(:,:), dim=2 ) / pa_ip(:)
-      ELSEWHERE                    ;   ph_ip(:) = 0._wp
+      WHERE( pa_ip(:) /= 0._wp )
+         ph_ip(:) = SUM( phtip(:,:) * patip(:,:), dim=2 ) / pa_ip(:)
+         ph_il(:) = SUM( phtil(:,:) * patip(:,:), dim=2 ) / pa_ip(:)
+      ELSEWHERE
+         ph_ip(:) = 0._wp
+         ph_il(:) = 0._wp
       END WHERE
       !
@@ -839,6 +880,6 @@
    END SUBROUTINE ice_var_itd_Nc1c
    
-   SUBROUTINE ice_var_itd_1cMc( phti, phts, pati ,                       ph_i, ph_s, pa_i, &
-      &                         ptmi, ptms, ptmsu, psmi, patip, phtip,   pt_i, pt_s, pt_su, ps_i, pa_ip, ph_ip )
+   SUBROUTINE ice_var_itd_1cMc( phti, phts, pati ,                             ph_i, ph_s, pa_i, &
+      &                         ptmi, ptms, ptmsu, psmi, patip, phtip, phtil,  pt_i, pt_s, pt_su, ps_i, pa_ip, ph_ip, ph_il )
       !!-------------------------------------------------------------------
       !!
@@ -862,6 +903,6 @@
       REAL(wp), DIMENSION(:),   INTENT(in)    ::   phti, phts, pati    ! input  ice/snow variables
       REAL(wp), DIMENSION(:,:), INTENT(inout) ::   ph_i, ph_s, pa_i    ! output ice/snow variables
-      REAL(wp), DIMENSION(:)  , INTENT(in)    ::   ptmi, ptms, ptmsu, psmi, patip, phtip    ! input  ice/snow temp & sal & ponds
-      REAL(wp), DIMENSION(:,:), INTENT(inout) ::   pt_i, pt_s, pt_su, ps_i, pa_ip, ph_ip    ! output ice/snow temp & sal & ponds
+      REAL(wp), DIMENSION(:)  , INTENT(in)    ::   ptmi, ptms, ptmsu, psmi, patip, phtip, phtil    ! input  ice/snow temp & sal & ponds
+      REAL(wp), DIMENSION(:,:), INTENT(inout) ::   pt_i, pt_s, pt_su, ps_i, pa_ip, ph_ip, ph_il    ! output ice/snow temp & sal & ponds
       !
       REAL(wp), ALLOCATABLE, DIMENSION(:) ::   zfra, z1_hti
@@ -953,5 +994,4 @@
          pt_su(:,jl) = ptmsu(:)
          ps_i (:,jl) = psmi (:)
-         ps_i (:,jl) = psmi (:)         
       END DO
       !
@@ -974,10 +1014,19 @@
          END WHERE
       END DO
+      ! keep the same v_il/v_i ratio for each category
+      WHERE( ( phti(:) * pati(:) ) /= 0._wp )   ;   zfra(:) = ( phtil(:) * patip(:) ) / ( phti(:) * pati(:) )
+      ELSEWHERE                                 ;   zfra(:) = 0._wp
+      END WHERE
+      DO jl = 1, jpl
+         WHERE( pa_ip(:,jl) /= 0._wp )   ;   ph_il(:,jl) = zfra(:) * ( ph_i(:,jl) * pa_i(:,jl) ) / pa_ip(:,jl)
+         ELSEWHERE                       ;   ph_il(:,jl) = 0._wp
+         END WHERE
+      END DO
       DEALLOCATE( zfra )
       !
    END SUBROUTINE ice_var_itd_1cMc
 
-   SUBROUTINE ice_var_itd_NcMc( phti, phts, pati ,                       ph_i, ph_s, pa_i, &
-      &                         ptmi, ptms, ptmsu, psmi, patip, phtip,   pt_i, pt_s, pt_su, ps_i, pa_ip, ph_ip )
+   SUBROUTINE ice_var_itd_NcMc( phti, phts, pati ,                             ph_i, ph_s, pa_i, &
+      &                         ptmi, ptms, ptmsu, psmi, patip, phtip, phtil,  pt_i, pt_s, pt_su, ps_i, pa_ip, ph_ip, ph_il )
       !!-------------------------------------------------------------------
       !!
@@ -994,5 +1043,5 @@
       !!
       !!               2) Expand the filling to the cat jlmin-1 and jlmax+1
-       !!                   by removing 25% ice area from jlmin and jlmax (resp.) 
+      !!                   by removing 25% ice area from jlmin and jlmax (resp.) 
       !!              
       !!               3) Expand the filling to the empty cat between jlmin and jlmax 
@@ -1010,6 +1059,6 @@
       REAL(wp), DIMENSION(:,:), INTENT(in)    ::   phti, phts, pati    ! input  ice/snow variables
       REAL(wp), DIMENSION(:,:), INTENT(inout) ::   ph_i, ph_s, pa_i    ! output ice/snow variables
-      REAL(wp), DIMENSION(:,:), INTENT(in)    ::   ptmi, ptms, ptmsu, psmi, patip, phtip    ! input  ice/snow temp & sal & ponds
-      REAL(wp), DIMENSION(:,:), INTENT(inout) ::   pt_i, pt_s, pt_su, ps_i, pa_ip, ph_ip    ! output ice/snow temp & sal & ponds
+      REAL(wp), DIMENSION(:,:), INTENT(in)    ::   ptmi, ptms, ptmsu, psmi, patip, phtip, phtil    ! input  ice/snow temp & sal & ponds
+      REAL(wp), DIMENSION(:,:), INTENT(inout) ::   pt_i, pt_s, pt_su, ps_i, pa_ip, ph_ip, ph_il    ! output ice/snow temp & sal & ponds
       !
       INTEGER , ALLOCATABLE, DIMENSION(:,:) ::   jlfil, jlfil2
@@ -1040,4 +1089,5 @@
          pa_ip(:,:) = patip(:,:)
          ph_ip(:,:) = phtip(:,:)
+         ph_il(:,:) = phtil(:,:)
          !                              ! ---------------------- !
       ELSEIF( icat == 1 ) THEN          ! input cat = 1          !
@@ -1045,6 +1095,6 @@
          CALL  ice_var_itd_1cMc( phti(:,1), phts(:,1), pati (:,1), &
             &                    ph_i(:,:), ph_s(:,:), pa_i (:,:), &
-            &                    ptmi(:,1), ptms(:,1), ptmsu(:,1), psmi(:,1), patip(:,1), phtip(:,1), &
-            &                    pt_i(:,:), pt_s(:,:), pt_su(:,:), ps_i(:,:), pa_ip(:,:), ph_ip(:,:)  )
+            &                    ptmi(:,1), ptms(:,1), ptmsu(:,1), psmi(:,1), patip(:,1), phtip(:,1), phtil(:,1), &
+            &                    pt_i(:,:), pt_s(:,:), pt_su(:,:), ps_i(:,:), pa_ip(:,:), ph_ip(:,:), ph_il(:,:)  )
          !                              ! ---------------------- !
       ELSEIF( jpl == 1 ) THEN           ! output cat = 1         !
@@ -1052,6 +1102,6 @@
          CALL  ice_var_itd_Nc1c( phti(:,:), phts(:,:), pati (:,:), &
             &                    ph_i(:,1), ph_s(:,1), pa_i (:,1), &
-            &                    ptmi(:,:), ptms(:,:), ptmsu(:,:), psmi(:,:), patip(:,:), phtip(:,:), &
-            &                    pt_i(:,1), pt_s(:,1), pt_su(:,1), ps_i(:,1), pa_ip(:,1), ph_ip(:,1)  )
+            &                    ptmi(:,:), ptms(:,:), ptmsu(:,:), psmi(:,:), patip(:,:), phtip(:,:), phtil(:,:), &
+            &                    pt_i(:,1), pt_s(:,1), pt_su(:,1), ps_i(:,1), pa_ip(:,1), ph_ip(:,1), ph_il(:,1)  )
          !                              ! ----------------------- !
       ELSE                              ! input cat /= output cat !
@@ -1195,4 +1245,15 @@
             END WHERE
          END DO
+         ! keep the same v_il/v_i ratio for each category
+         WHERE( SUM( phti(:,:) * pati(:,:), dim=2 ) /= 0._wp )
+            zfra(:) = SUM( phtil(:,:) * patip(:,:), dim=2 ) / SUM( phti(:,:) * pati(:,:), dim=2 )
+         ELSEWHERE
+            zfra(:) = 0._wp
+         END WHERE
+         DO jl = 1, jpl
+            WHERE( pa_ip(:,jl) /= 0._wp )   ;   ph_il(:,jl) = zfra(:) * ( ph_i(:,jl) * pa_i(:,jl) ) / pa_ip(:,jl)
+            ELSEWHERE                       ;   ph_il(:,jl) = 0._wp
+            END WHERE
+         END DO
          DEALLOCATE( zfra )
          !
@@ -1200,4 +1261,88 @@
       !
    END SUBROUTINE ice_var_itd_NcMc
+
+   !!-------------------------------------------------------------------
+   !! INTERFACE ice_var_snwfra
+   !!
+   !! ** Purpose :  fraction of ice covered by snow
+   !!
+   !! ** Method  :  In absence of proper snow model on top of sea ice,
+   !!               we argue that snow does not cover the whole ice because
+   !!               of wind blowing...
+   !!                
+   !! ** Arguments : ph_s: snow thickness
+   !!                
+   !! ** Output    : pa_s_fra: fraction of ice covered by snow
+   !!
+   !!-------------------------------------------------------------------
+   SUBROUTINE ice_var_snwfra_3d( ph_s, pa_s_fra )
+      REAL(wp), DIMENSION(:,:,:), INTENT(in   ) ::   ph_s        ! snow thickness
+      REAL(wp), DIMENSION(:,:,:), INTENT(  out) ::   pa_s_fra    ! ice fraction covered by snow
+      IF    ( nn_snwfra == 0 ) THEN   ! basic 0 or 1 snow cover
+         WHERE( ph_s > 0._wp ) ; pa_s_fra = 1._wp
+         ELSEWHERE             ; pa_s_fra = 0._wp
+         END WHERE
+      ELSEIF( nn_snwfra == 1 ) THEN   ! snow cover depends on hsnow (met-office style)
+         pa_s_fra = 1._wp - EXP( -0.2_wp * rhos * ph_s )
+      ELSEIF( nn_snwfra == 2 ) THEN   ! snow cover depends on hsnow (cice style)
+         pa_s_fra = ph_s / ( ph_s + 0.02_wp )
+      ENDIF
+   END SUBROUTINE ice_var_snwfra_3d
+
+   SUBROUTINE ice_var_snwfra_2d( ph_s, pa_s_fra )
+      REAL(wp), DIMENSION(:,:), INTENT(in   ) ::   ph_s        ! snow thickness
+      REAL(wp), DIMENSION(:,:), INTENT(  out) ::   pa_s_fra    ! ice fraction covered by snow
+      IF    ( nn_snwfra == 0 ) THEN   ! basic 0 or 1 snow cover
+         WHERE( ph_s > 0._wp ) ; pa_s_fra = 1._wp
+         ELSEWHERE             ; pa_s_fra = 0._wp
+         END WHERE
+      ELSEIF( nn_snwfra == 1 ) THEN   ! snow cover depends on hsnow (met-office style)
+         pa_s_fra = 1._wp - EXP( -0.2_wp * rhos * ph_s )
+      ELSEIF( nn_snwfra == 2 ) THEN   ! snow cover depends on hsnow (cice style)
+         pa_s_fra = ph_s / ( ph_s + 0.02_wp )
+      ENDIF
+   END SUBROUTINE ice_var_snwfra_2d
+
+   SUBROUTINE ice_var_snwfra_1d( ph_s, pa_s_fra )
+      REAL(wp), DIMENSION(:), INTENT(in   ) ::   ph_s        ! snow thickness
+      REAL(wp), DIMENSION(:), INTENT(  out) ::   pa_s_fra    ! ice fraction covered by snow
+      IF    ( nn_snwfra == 0 ) THEN   ! basic 0 or 1 snow cover
+         WHERE( ph_s > 0._wp ) ; pa_s_fra = 1._wp
+         ELSEWHERE             ; pa_s_fra = 0._wp
+         END WHERE
+      ELSEIF( nn_snwfra == 1 ) THEN   ! snow cover depends on hsnow (met-office style)
+         pa_s_fra = 1._wp - EXP( -0.2_wp * rhos * ph_s )
+      ELSEIF( nn_snwfra == 2 ) THEN   ! snow cover depends on hsnow (cice style)
+         pa_s_fra = ph_s / ( ph_s + 0.02_wp )
+      ENDIF
+   END SUBROUTINE ice_var_snwfra_1d
+   
+   !!--------------------------------------------------------------------------
+   !! INTERFACE ice_var_snwblow
+   !!
+   !! ** Purpose :   Compute distribution of precip over the ice
+   !!
+   !!                Snow accumulation in one thermodynamic time step
+   !!                snowfall is partitionned between leads and ice.
+   !!                If snow fall was uniform, a fraction (1-at_i) would fall into leads
+   !!                but because of the winds, more snow falls on leads than on sea ice
+   !!                and a greater fraction (1-at_i)^beta of the total mass of snow 
+   !!                (beta < 1) falls in leads.
+   !!                In reality, beta depends on wind speed, 
+   !!                and should decrease with increasing wind speed but here, it is 
+   !!                considered as a constant. an average value is 0.66
+   !!--------------------------------------------------------------------------
+!!gm  I think it can be usefull to set this as a FUNCTION, not a SUBROUTINE....
+   SUBROUTINE ice_var_snwblow_2d( pin, pout )
+      REAL(wp), DIMENSION(:,:), INTENT(in   ) :: pin   ! previous fraction lead ( 1. - a_i_b )
+      REAL(wp), DIMENSION(:,:), INTENT(inout) :: pout
+      pout = ( 1._wp - ( pin )**rn_snwblow )
+   END SUBROUTINE ice_var_snwblow_2d
+
+   SUBROUTINE ice_var_snwblow_1d( pin, pout )
+      REAL(wp), DIMENSION(:), INTENT(in   ) :: pin
+      REAL(wp), DIMENSION(:), INTENT(inout) :: pout
+      pout = ( 1._wp - ( pin )**rn_snwblow )
+   END SUBROUTINE ice_var_snwblow_1d
 
 #else
Index: NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icewri.F90
===================================================================
--- NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icewri.F90	(revision 13033)
+++ NEMO/branches/2020/dev_12905_xios_restart/src/ICE/icewri.F90	(revision 13727)
@@ -71,5 +71,5 @@
 
       ! tresholds for outputs
-      DO_2D_11_11
+      DO_2D( 1, 1, 1, 1 )
          zmsk00(ji,jj) = MAX( 0._wp , SIGN( 1._wp , at_i(ji,jj) - epsi06  ) ) ! 1 if ice    , 0 if no ice
          zmsk05(ji,jj) = MAX( 0._wp , SIGN( 1._wp , at_i(ji,jj) - 0.05_wp ) ) ! 1 if 5% ice , 0 if less
@@ -78,5 +78,5 @@
       END_2D
       DO jl = 1, jpl
-         DO_2D_11_11
+         DO_2D( 1, 1, 1, 1 )
             zmsk00l(ji,jj,jl)  = MAX( 0._wp , SIGN( 1._wp , a_i(ji,jj,jl) - epsi06 ) )
             zmsksnl(ji,jj,jl)  = MAX( 0._wp , SIGN( 1._wp , v_s(ji,jj,jl) - epsi06 ) )
@@ -114,4 +114,6 @@
       IF( iom_use('icehpnd' ) )   CALL iom_put( 'icehpnd', hm_ip  * zmsk00      )                                           ! melt pond depth
       IF( iom_use('icevpnd' ) )   CALL iom_put( 'icevpnd', vt_ip  * zmsk00      )                                           ! melt pond total volume per unit area
+      IF( iom_use('icehlid' ) )   CALL iom_put( 'icehlid', hm_il  * zmsk00      )                                           ! melt pond lid depth
+      IF( iom_use('icevlid' ) )   CALL iom_put( 'icevlid', vt_il  * zmsk00      )                                           ! melt pond lid total volume per unit area
       ! salt
       IF( iom_use('icesalt' ) )   CALL iom_put( 'icesalt', sm_i                 * zmsk00 + zmiss_val * ( 1._wp - zmsk00 ) ) ! mean ice salinity
@@ -130,10 +132,10 @@
       !
       IF( iom_use('icevel') .OR. iom_use('fasticepres') ) THEN                                                              ! module of ice velocity
-         DO_2D_00_00
+         DO_2D( 0, 0, 0, 0 )
             z2da  = u_ice(ji,jj) + u_ice(ji-1,jj)
             z2db  = v_ice(ji,jj) + v_ice(ji,jj-1)
             z2d(ji,jj) = 0.5_wp * SQRT( z2da * z2da + z2db * z2db )
          END_2D
-         CALL lbc_lnk( 'icewri', z2d, 'T', 1. )
+         CALL lbc_lnk( 'icewri', z2d, 'T', 1.0_wp )
          CALL iom_put( 'icevel', z2d )
 
@@ -158,6 +160,8 @@
       IF( iom_use('icebrv_cat'  ) )   CALL iom_put( 'icebrv_cat'  ,   bv_i * 100.  * zmsk00l + zmiss_val * ( 1._wp - zmsk00l ) ) ! brine volume
       IF( iom_use('iceapnd_cat' ) )   CALL iom_put( 'iceapnd_cat' ,   a_ip         * zmsk00l                                   ) ! melt pond frac for categories
-      IF( iom_use('icehpnd_cat' ) )   CALL iom_put( 'icehpnd_cat' ,   h_ip         * zmsk00l + zmiss_val * ( 1._wp - zmsk00l ) ) ! melt pond frac for categories
+      IF( iom_use('icehpnd_cat' ) )   CALL iom_put( 'icehpnd_cat' ,   h_ip         * zmsk00l + zmiss_val * ( 1._wp - zmsk00l ) ) ! melt pond thickness for categories
+      IF( iom_use('icehlid_cat' ) )   CALL iom_put( 'icehlid_cat' ,   h_il         * zmsk00l + zmiss_val * ( 1._wp - zmsk00l ) ) ! melt pond lid thickness for categories
       IF( iom_use('iceafpnd_cat') )   CALL iom_put( 'iceafpnd_cat',   a_ip_frac    * zmsk00l                                   ) ! melt pond frac for categories
+      IF( iom_use('iceaepnd_cat') )   CALL iom_put( 'iceaepnd_cat',   a_ip_eff     * zmsk00l                                   ) ! melt pond effective frac for categories
       IF( iom_use('icealb_cat'  ) )   CALL iom_put( 'icealb_cat'  ,   alb_ice      * zmsk00l + zmiss_val * ( 1._wp - zmsk00l ) ) ! ice albedo for categories
 
@@ -173,4 +177,5 @@
       IF( iom_use('dmisum') )   CALL iom_put( 'dmisum', - wfx_sum                                                             ) ! Sea-ice mass change through surface melting
       IF( iom_use('dmibom') )   CALL iom_put( 'dmibom', - wfx_bom                                                             ) ! Sea-ice mass change through bottom melting
+      IF( iom_use('dmilam') )   CALL iom_put( 'dmilam', - wfx_lam                                                             ) ! Sea-ice mass change through lateral melting
       IF( iom_use('dmtsub') )   CALL iom_put( 'dmtsub', - wfx_sub                                                             ) ! Sea-ice mass change through evaporation and sublimation
       IF( iom_use('dmssub') )   CALL iom_put( 'dmssub', - wfx_snw_sub                                                         ) ! Snow mass change through sublimation
