diff --git a/src/OCE/DYN/dynadv.F90 b/src/OCE/DYN/dynadv.F90
index bda2c3a4f806cd4fab1bcc5a6b3bc1ff89f77dd1..6d59583ffb868f71fdaf9900ca231e9419030b8d 100644
--- a/src/OCE/DYN/dynadv.F90
+++ b/src/OCE/DYN/dynadv.F90
@@ -7,6 +7,7 @@ MODULE dynadv
    !!            3.3  !  2010-10  (C. Ethe, G. Madec)  reorganisation of initialisation phase
    !!            3.6  !  2015-05  (N. Ducousso, G. Madec)  add Hollingsworth scheme as an option 
    !!            4.0  !  2017-07  (G. Madec)  add a linear dynamics option
+   !!            4.5  !  2022-06  (S. Techene, G, Madec) refactorization to reduce local memory usage
    !!----------------------------------------------------------------------
 
    !!----------------------------------------------------------------------
@@ -50,7 +51,7 @@ MODULE dynadv
    !!----------------------------------------------------------------------
 CONTAINS
 
-   SUBROUTINE dyn_adv( kt, Kbb, Kmm, puu, pvv, Krhs, pau, pav, paw, no_zad )
+   SUBROUTINE dyn_adv( kt, Kbb, Kmm, puu, pvv, Krhs, pau, pav, paw )
       !!---------------------------------------------------------------------
       !!                  ***  ROUTINE dyn_adv  ***
       !!                
@@ -64,7 +65,6 @@ CONTAINS
       !!      (see dynvor module).
       !!----------------------------------------------------------------------
       INTEGER                                     , INTENT(in   ) ::   kt , Kbb, Kmm, Krhs   ! ocean time step and level indices
-      INTEGER                   , OPTIONAL        , INTENT(in   ) ::   no_zad                ! no vertical advection compotation
       REAL(wp), DIMENSION(:,:,:), OPTIONAL, TARGET, INTENT(in   ) ::   pau, pav, paw         ! advective velocity
       REAL(wp), DIMENSION(jpi,jpj,jpk,jpt), TARGET, INTENT(inout) ::   puu, pvv              ! ocean velocities and RHS of momentum Eq.
       !!----------------------------------------------------------------------
@@ -73,12 +73,23 @@ CONTAINS
       !
       SELECT CASE( n_dynadv )    !==  compute advection trend and add it to general trend  ==!
       CASE( np_VEC_c2  )                                                         != vector form =!
-         CALL dyn_keg     ( kt, nn_dynkeg     , Kmm, puu, pvv, Krhs )                          ! horizontal gradient of kinetic energy
-         CALL dyn_zad     ( kt                , Kmm, puu, pvv, Krhs )                          ! vertical advection
+         !                                                                             !* horizontal gradient of kinetic energy
+         IF (nn_hls==1) THEN                                                               ! halo 1 case
+            CALL dyn_keg_hls1( kt, nn_dynkeg  , Kmm, puu, pvv, Krhs )                          ! lbc needed with Hollingsworth scheme
+         ELSE                                                                              ! halo 2 case
+            CALL dyn_keg     ( kt, nn_dynkeg  , Kmm, puu, pvv, Krhs )
+         ENDIF
+         CALL dyn_zad     ( kt                , Kmm, puu, pvv, Krhs )                  !* vertical advection
+         !
       CASE( np_FLX_c2  )                                                         !=  flux form  =!
-         CALL dyn_adv_cen2( kt                , Kmm, puu, pvv, Krhs, pau, pav, paw, no_zad )   ! 2nd order centered scheme
-      CASE( np_FLX_ubs )   
-         CALL dyn_adv_ubs ( kt           , Kbb, Kmm, puu, pvv, Krhs, pau, pav, paw, no_zad )   ! 3rd order UBS      scheme (UP3)
+         CALL dyn_adv_cen2( kt                , Kmm, puu, pvv, Krhs, pau, pav, paw )   !* 2nd order centered scheme
+         !
+      CASE( np_FLX_ubs )                                                               !* 3rd order UBS      scheme (UP3)
+         IF (nn_hls==1) THEN                                                               ! halo 1 case
+            CALL dyn_adv_ubs_hls1( kt         , Kbb, Kmm, puu, pvv, Krhs, pau, pav, paw )
+         ELSE                                                                              ! halo 2 case
+            CALL dyn_adv_ubs     ( kt         , Kbb, Kmm, puu, pvv, Krhs, pau, pav, paw )
+         ENDIF
       END SELECT
       !
       IF( ln_timing )   CALL timing_stop( 'dyn_adv' )
diff --git a/src/OCE/DYN/dynadv_cen2.F90 b/src/OCE/DYN/dynadv_cen2.F90
index 7fd7f65f5c19ca959bd2437cb7352cf5bb1fd1b6..07dd931129ed0b4474092915e3b6c83abcaf2ff5 100644
--- a/src/OCE/DYN/dynadv_cen2.F90
+++ b/src/OCE/DYN/dynadv_cen2.F90
@@ -6,6 +6,7 @@ MODULE dynadv_cen2
    !!======================================================================
    !! History :  2.0  ! 2006-08  (G. Madec, S. Theetten)  Original code
    !!            3.2  ! 2009-07  (R. Benshila)  Suppression of rigid-lid option
+   !!            4.5  ! 2022-06  (S. Techene, G, Madec) refactorization to reduce local memory usage
    !!----------------------------------------------------------------------
 
    !!----------------------------------------------------------------------
@@ -35,7 +36,7 @@ MODULE dynadv_cen2
    !!----------------------------------------------------------------------
 CONTAINS
 
-   SUBROUTINE dyn_adv_cen2( kt, Kmm, puu, pvv, Krhs, pau, pav, paw, no_zad )
+   SUBROUTINE dyn_adv_cen2( kt, Kmm, puu, pvv, Krhs, pau, pav, paw )
       !!----------------------------------------------------------------------
       !!                  ***  ROUTINE dyn_adv_cen2  ***
       !!
@@ -51,15 +52,17 @@ CONTAINS
       !! ** Action  :   (puu,pvv)(:,:,:,Krhs)   updated with the advective trend
       !!----------------------------------------------------------------------
       INTEGER                                     , INTENT(in   ) ::   kt , Kmm, Krhs   ! ocean time-step and level indices
-      INTEGER                   , OPTIONAL        , INTENT(in   ) ::   no_zad                ! no vertical advection computation
       REAL(wp), DIMENSION(jpi,jpj,jpk,jpt), TARGET, INTENT(inout) ::   puu, pvv         ! ocean velocities and RHS of momentum equation
       REAL(wp), DIMENSION(:,:,:), OPTIONAL, TARGET, INTENT(in   ) ::   pau, pav, paw    ! advective velocity
       !
       INTEGER  ::   ji, jj, jk   ! dummy loop indices
-      REAL(wp) ::   zzu, zzv     ! local scalars
-      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zfu_t, zfu_f, zfu_uw, zfu
-      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zfv_t, zfv_f, zfv_vw, zfv, zfw
+      REAL(wp) ::   zzu, zzfu_kp1     ! local scalars
+      REAL(wp) ::   zzv, zzfv_kp1     !   -      -
+      REAL(wp), DIMENSION(A2D(1)) ::   zfu_t, zfu_f, zfu
+      REAL(wp), DIMENSION(A2D(1)) ::   zfv_t, zfv_f, zfv
+      REAL(wp), DIMENSION(A2D(1)) ::   zfu_uw, zfv_vw, zfw
       REAL(wp), DIMENSION(:,:,:) , POINTER ::   zpt_u, zpt_v, zpt_w
+      REAL(wp), DIMENSION(:,:,:) , ALLOCATABLE ::   zu_trd, zv_trd
       !!----------------------------------------------------------------------
       !
       IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
@@ -71,8 +74,9 @@ CONTAINS
       ENDIF
       !
       IF( l_trddyn ) THEN           ! trends: store the input trends
-         zfu_uw(:,:,:) = puu(:,:,:,Krhs)
-         zfv_vw(:,:,:) = pvv(:,:,:,Krhs)
+         ALLOCATE( zu_trd(A2D(0),jpkm1), zv_trd(A2D(0),jpkm1) )
+         zu_trd(A2D(0),:) = puu(A2D(0),:,Krhs)
+         zv_trd(A2D(0),:) = pvv(A2D(0),:,Krhs)
       ENDIF
       !
       IF( PRESENT( pau ) ) THEN     ! RK3: advective velocity (pau,pav,paw) /= advected velocity (puu,pvv,ww)
@@ -89,84 +93,86 @@ CONTAINS
       !
       DO jk = 1, jpkm1                    ! horizontal transport
          DO_2D( 1, 1, 1, 1 )
-            zfu(ji,jj,jk) = 0.25_wp * e2u(ji,jj) * e3u(ji,jj,jk,Kmm) * zpt_u(ji,jj,jk)
-            zfv(ji,jj,jk) = 0.25_wp * e1v(ji,jj) * e3v(ji,jj,jk,Kmm) * zpt_v(ji,jj,jk)
+            zfu(ji,jj) = 0.25_wp * e2u(ji,jj) * e3u(ji,jj,jk,Kmm) * zpt_u(ji,jj,jk)
+            zfv(ji,jj) = 0.25_wp * e1v(ji,jj) * e3v(ji,jj,jk,Kmm) * zpt_v(ji,jj,jk)
          END_2D
          DO_2D( 1, 0, 1, 0 )              ! horizontal momentum fluxes (at T- and F-point)
-            zfu_t(ji+1,jj  ,jk) = ( zfu(ji,jj,jk) + zfu(ji+1,jj,jk) ) * ( puu(ji,jj,jk,Kmm) + puu(ji+1,jj  ,jk,Kmm) )
-            zfv_f(ji  ,jj  ,jk) = ( zfv(ji,jj,jk) + zfv(ji+1,jj,jk) ) * ( puu(ji,jj,jk,Kmm) + puu(ji  ,jj+1,jk,Kmm) )
-            zfu_f(ji  ,jj  ,jk) = ( zfu(ji,jj,jk) + zfu(ji,jj+1,jk) ) * ( pvv(ji,jj,jk,Kmm) + pvv(ji+1,jj  ,jk,Kmm) )
-            zfv_t(ji  ,jj+1,jk) = ( zfv(ji,jj,jk) + zfv(ji,jj+1,jk) ) * ( pvv(ji,jj,jk,Kmm) + pvv(ji  ,jj+1,jk,Kmm) )
+            zfu_t(ji+1,jj  ) = ( zfu(ji,jj) + zfu(ji+1,jj) ) * ( puu(ji,jj,jk,Kmm) + puu(ji+1,jj  ,jk,Kmm) )
+            zfv_f(ji  ,jj  ) = ( zfv(ji,jj) + zfv(ji+1,jj) ) * ( puu(ji,jj,jk,Kmm) + puu(ji  ,jj+1,jk,Kmm) )
+            zfu_f(ji  ,jj  ) = ( zfu(ji,jj) + zfu(ji,jj+1) ) * ( pvv(ji,jj,jk,Kmm) + pvv(ji+1,jj  ,jk,Kmm) )
+            zfv_t(ji  ,jj+1) = ( zfv(ji,jj) + zfv(ji,jj+1) ) * ( pvv(ji,jj,jk,Kmm) + pvv(ji  ,jj+1,jk,Kmm) )
          END_2D
          DO_2D( 0, 0, 0, 0 )              ! divergence of horizontal momentum fluxes
-            puu(ji,jj,jk,Krhs) = puu(ji,jj,jk,Krhs) - (  zfu_t(ji+1,jj,jk) - zfu_t(ji,jj  ,jk)    &
-               &                                       + zfv_f(ji  ,jj,jk) - zfv_f(ji,jj-1,jk)  ) * r1_e1e2u(ji,jj)   &
+            puu(ji,jj,jk,Krhs) = puu(ji,jj,jk,Krhs) - (  zfu_t(ji+1,jj) - zfu_t(ji,jj  )    &
+               &                                       + zfv_f(ji  ,jj) - zfv_f(ji,jj-1)  ) * r1_e1e2u(ji,jj)   &
                &                                    / e3u(ji,jj,jk,Kmm)
-            pvv(ji,jj,jk,Krhs) = pvv(ji,jj,jk,Krhs) - (  zfu_f(ji,jj  ,jk) - zfu_f(ji-1,jj,jk)    &
-               &                                       + zfv_t(ji,jj+1,jk) - zfv_t(ji  ,jj,jk)  ) * r1_e1e2v(ji,jj)   &
+            pvv(ji,jj,jk,Krhs) = pvv(ji,jj,jk,Krhs) - (  zfu_f(ji,jj  ) - zfu_f(ji-1,jj)    &
+               &                                       + zfv_t(ji,jj+1) - zfv_t(ji  ,jj)  ) * r1_e1e2v(ji,jj)   &
                &                                    / e3v(ji,jj,jk,Kmm)
          END_2D
       END DO
       !
       IF( l_trddyn ) THEN           ! trends: send trend to trddyn for diagnostic
-         zfu_uw(:,:,:) = puu(:,:,:,Krhs) - zfu_uw(:,:,:)
-         zfv_vw(:,:,:) = pvv(:,:,:,Krhs) - zfv_vw(:,:,:)
-         CALL trd_dyn( zfu_uw, zfv_vw, jpdyn_keg, kt, Kmm )
-         zfu_t(:,:,:) = puu(:,:,:,Krhs)
-         zfv_t(:,:,:) = pvv(:,:,:,Krhs)
+         zu_trd(A2D(0),:) = puu(A2D(0),:,Krhs) - zu_trd(A2D(0),:)
+         zv_trd(A2D(0),:) = pvv(A2D(0),:,Krhs) - zv_trd(A2D(0),:)
+         CALL trd_dyn( zu_trd, zv_trd, jpdyn_keg, kt, Kmm )
+         zu_trd(A2D(0),:) = puu(A2D(0),:,Krhs)
+         zv_trd(A2D(0),:) = pvv(A2D(0),:,Krhs)
       ENDIF
       !
-      IF( PRESENT( no_zad ) ) THEN  !==  No vertical advection  ==!   (except if linear free surface)
-         !                               ==
-         IF( ln_linssh ) THEN                ! linear free surface: advection through the surface z=0
-            DO_2D( 0, 0, 0, 0 )
-               zzu = 0.5_wp * ( e1e2t(ji,jj) * zpt_w(ji,jj,1) + e1e2t(ji+1,jj) * zpt_w(ji+1,jj,1) ) * puu(ji,jj,1,Kmm)
-               zzv = 0.5_wp * ( e1e2t(ji,jj) * zpt_w(ji,jj,1) + e1e2t(ji,jj+1) * zpt_w(ji,jj+1,1) ) * pvv(ji,jj,1,Kmm)
-               puu(ji,jj,1,Krhs) = puu(ji,jj,1,Krhs) - zzu * r1_e1e2u(ji,jj)   &
-                  &                                        / e3u(ji,jj,1,Kmm)
-               pvv(ji,jj,1,Krhs) = pvv(ji,jj,1,Krhs) - zzv * r1_e1e2v(ji,jj)   &
-                  &                                        / e3v(ji,jj,1,Kmm)
-            END_2D
-         ENDIF
-         !
-      ELSE                          !==  Vertical advection  ==!
+      !                          !==  Vertical advection  ==!
+      !
+      !                              ! surface vertical fluxes
+      !
+      IF( ln_linssh ) THEN                ! linear free surface: advection through the surface z=0
+         DO_2D( 0, 0, 0, 0 )
+            zfu_uw(ji,jj) = 0.5_wp * ( e1e2t(ji,jj) * zpt_w(ji,jj,1) + e1e2t(ji+1,jj) * zpt_w(ji+1,jj,1) ) * puu(ji,jj,1,Kmm)
+            zfv_vw(ji,jj) = 0.5_wp * ( e1e2t(ji,jj) * zpt_w(ji,jj,1) + e1e2t(ji,jj+1) * zpt_w(ji,jj+1,1) ) * pvv(ji,jj,1,Kmm)
+         END_2D
+      ELSE                                ! non linear free: surface advective fluxes set to zero
+         DO_2D( 0, 0, 0, 0 )
+            zfu_uw(ji,jj) = 0._wp
+            zfv_vw(ji,jj) = 0._wp
+         END_2D
+      ENDIF
+      ! 
+      DO jk = 1, jpk-2               !  divergence of advective fluxes
          !
-         DO_2D( 0, 0, 0, 0 )                 ! surface/bottom advective fluxes set to zero
-            zfu_uw(ji,jj,jpk) = 0._wp   ;   zfv_vw(ji,jj,jpk) = 0._wp
-            zfu_uw(ji,jj, 1 ) = 0._wp   ;   zfv_vw(ji,jj, 1 ) = 0._wp
+         DO_2D( 0, 1, 0, 1 )                  ! 1/4 * Vertical transport at level k+1
+            zfw(ji,jj) = 0.25_wp * e1e2t(ji,jj) * zpt_w(ji,jj,jk+1)
          END_2D
-         IF( ln_linssh ) THEN                ! linear free surface: advection through the surface z=0
-            DO_2D( 0, 0, 0, 0 )
-               zfu_uw(ji,jj,1) = 0.5_wp * ( e1e2t(ji,jj) * zpt_w(ji,jj,1) + e1e2t(ji+1,jj) * zpt_w(ji+1,jj,1) ) * puu(ji,jj,1,Kmm)
-               zfv_vw(ji,jj,1) = 0.5_wp * ( e1e2t(ji,jj) * zpt_w(ji,jj,1) + e1e2t(ji,jj+1) * zpt_w(ji,jj+1,1) ) * pvv(ji,jj,1,Kmm)
-            END_2D
-         ENDIF
-         DO jk = 2, jpkm1                    ! interior advective fluxes
-            DO_2D( 0, 1, 0, 1 )                  ! 1/4 * Vertical transport
-               zfw(ji,jj,jk) = 0.25_wp * e1e2t(ji,jj) * zpt_w(ji,jj,jk)
-            END_2D
-            DO_2D( 0, 0, 0, 0 )
-               zfu_uw(ji,jj,jk) = ( zfw(ji,jj,jk) + zfw(ji+1,jj  ,jk) ) * ( puu(ji,jj,jk,Kmm) + puu(ji,jj,jk-1,Kmm) )
-               zfv_vw(ji,jj,jk) = ( zfw(ji,jj,jk) + zfw(ji  ,jj+1,jk) ) * ( pvv(ji,jj,jk,Kmm) + pvv(ji,jj,jk-1,Kmm) )
-            END_2D
-         END DO
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )       ! divergence of vertical momentum flux divergence
-            puu(ji,jj,jk,Krhs) = puu(ji,jj,jk,Krhs) - ( zfu_uw(ji,jj,jk) - zfu_uw(ji,jj,jk+1) ) * r1_e1e2u(ji,jj)   &
+         DO_2D( 0, 0, 0, 0 )
+            !                                       ! vertical flux at level k+1
+            zzfu_kp1 = ( zfw(ji,jj) + zfw(ji+1,jj  ) ) * ( puu(ji,jj,jk+1,Kmm) + puu(ji,jj,jk,Kmm) )
+            zzfv_kp1 = ( zfw(ji,jj) + zfw(ji  ,jj+1) ) * ( pvv(ji,jj,jk+1,Kmm) + pvv(ji,jj,jk,Kmm) )
+            !                                       ! divergence of vertical momentum flux
+            puu(ji,jj,jk,Krhs) = puu(ji,jj,jk,Krhs) - ( zfu_uw(ji,jj) - zzfu_kp1 ) * r1_e1e2u(ji,jj)   &
                &                                      / e3u(ji,jj,jk,Kmm)
-            pvv(ji,jj,jk,Krhs) = pvv(ji,jj,jk,Krhs) - ( zfv_vw(ji,jj,jk) - zfv_vw(ji,jj,jk+1) ) * r1_e1e2v(ji,jj)   &
-               &                                      / e3v(ji,jj,jk,Kmm)
-         END_3D
-         !
-         IF( l_trddyn ) THEN                 ! trends: send trend to trddyn for diagnostic
-            zfu_t(:,:,:) = puu(:,:,:,Krhs) - zfu_t(:,:,:)
-            zfv_t(:,:,:) = pvv(:,:,:,Krhs) - zfv_t(:,:,:)
-            CALL trd_dyn( zfu_t, zfv_t, jpdyn_zad, kt, Kmm )
-         ENDIF
-         !                                   ! Control print
-         IF(sn_cfctl%l_prtctl)   CALL prt_ctl( tab3d_1=puu(:,:,:,Krhs), clinfo1=' cen2 adv - Ua: ', mask1=umask,   &
-            &                                  tab3d_2=pvv(:,:,:,Krhs), clinfo2=           ' Va: ', mask2=vmask, clinfo3='dyn' )
-         !
+            pvv(ji,jj,jk,Krhs) = pvv(ji,jj,jk,Krhs) - ( zfv_vw(ji,jj) - zzfv_kp1 ) * r1_e1e2v(ji,jj)   &
+               &                                      / e3v(ji,jj,jk,Kmm) 
+            !                                       ! store vertical flux for next level calculation
+            zfu_uw(ji,jj) = zzfu_kp1
+            zfv_vw(ji,jj) = zzfv_kp1
+         END_2D
+      END DO
+      !
+      jk = jpkm1
+      DO_2D( 0, 0, 0, 0 )
+         puu(ji,jj,jk,Krhs) = puu(ji,jj,jk,Krhs) - zfu_uw(ji,jj) * r1_e1e2u(ji,jj)   &
+            &                                      / e3u(ji,jj,jk,Kmm)
+         pvv(ji,jj,jk,Krhs) = pvv(ji,jj,jk,Krhs) - zfv_vw(ji,jj) * r1_e1e2v(ji,jj)   &
+            &                                      / e3v(ji,jj,jk,Kmm) 
+      END_2D
+      !
+      IF( l_trddyn ) THEN                 ! trends: send trend to trddyn for diagnostic
+         zu_trd(A2D(0),:) = puu(A2D(0),:,Krhs) - zu_trd(A2D(0),:)
+         zv_trd(A2D(0),:) = pvv(A2D(0),:,Krhs) - zv_trd(A2D(0),:)
+         CALL trd_dyn( zu_trd, zv_trd, jpdyn_zad, kt, Kmm )
+         DEALLOCATE( zu_trd, zv_trd )
       ENDIF
+      !                                   ! Control print
+      IF(sn_cfctl%l_prtctl)   CALL prt_ctl( tab3d_1=puu(:,:,:,Krhs), clinfo1=' cen2 adv - Ua: ', mask1=umask,   &
+         &                                  tab3d_2=pvv(:,:,:,Krhs), clinfo2=           ' Va: ', mask2=vmask, clinfo3='dyn' )
       !
    END SUBROUTINE dyn_adv_cen2
 
diff --git a/src/OCE/DYN/dynadv_ubs.F90 b/src/OCE/DYN/dynadv_ubs.F90
index 645f6fa800606d41375281e38c4bc077f1a848e8..8ab908124d5b85beb120d5726d2d6ec12b8d28f7 100644
--- a/src/OCE/DYN/dynadv_ubs.F90
+++ b/src/OCE/DYN/dynadv_ubs.F90
@@ -6,6 +6,7 @@ MODULE dynadv_ubs
    !!======================================================================
    !! History :  2.0  ! 2006-08  (R. Benshila, L. Debreu)  Original code
    !!            3.2  ! 2009-07  (R. Benshila)  Suppression of rigid-lid option
+   !!            4.5  ! 2022-06  (S. Techene, G, Madec) refactorization to reduce local memory usage
    !!----------------------------------------------------------------------
 
    !!----------------------------------------------------------------------
@@ -29,7 +30,8 @@ MODULE dynadv_ubs
    REAL(wp), PARAMETER :: gamma1 = 1._wp/3._wp  ! =1/4 quick      ; =1/3  3rd order UBS
    REAL(wp), PARAMETER :: gamma2 = 1._wp/32._wp ! =0   2nd order  ; =1/32 4th order centred
 
-   PUBLIC   dyn_adv_ubs   ! routine called by step.F90
+   PUBLIC   dyn_adv_ubs        ! routine called by dynadv.F90
+   PUBLIC   dyn_adv_ubs_hls1   ! routine called by dynadv.F90
 
    !! * Substitutions
 #  include "do_loop_substitute.h90"
@@ -41,7 +43,243 @@ MODULE dynadv_ubs
    !!----------------------------------------------------------------------
 CONTAINS
 
-   SUBROUTINE dyn_adv_ubs( kt, Kbb, Kmm, puu, pvv, Krhs, pau, pav, paw, no_zad )
+   SUBROUTINE dyn_adv_ubs( kt, Kbb, Kmm, puu, pvv, Krhs, pau, pav, paw )
+      !!----------------------------------------------------------------------
+      !!                  ***  ROUTINE dyn_adv_ubs  ***
+      !!
+      !! ** Purpose :   Compute the now momentum advection trend in flux form
+      !!              and the general trend of the momentum equation.
+      !!
+      !! ** Method  :   The scheme is the one implemeted in ROMS. It depends 
+      !!      on two parameter gamma1 and gamma2. The former control the 
+      !!      upstream baised part of the scheme and the later the centred 
+      !!      part:     gamma1 = 0    pure centered  (no diffusive part)
+      !!                       = 1/4  Quick scheme
+      !!                       = 1/3  3rd order Upstream biased scheme
+      !!                gamma2 = 0    2nd order finite differencing 
+      !!                       = 1/32 4th order finite differencing
+      !!      For stability reasons, the first term of the fluxes which cor-
+      !!      responds to a second order centered scheme is evaluated using  
+      !!      the now velocity (centered in time) while the second term which  
+      !!      is the diffusive part of the scheme, is evaluated using the 
+      !!      before velocity (forward in time). 
+      !!      Default value (hard coded in the begining of the module) are 
+      !!      gamma1=1/3 and gamma2=1/32.
+      !!
+      !!                In RK3 time stepping case, the optional arguments 
+      !!      (pau,pav,paw) are present. They are used as advective velocity  
+      !!      while the advected velocity remains (puu,pvv). 
+      !!
+      !! ** Action  :   (puu,pvv)(:,:,:,Krhs)   updated with the advective trend
+      !!
+      !! Reference : Shchepetkin & McWilliams, 2005, Ocean Modelling. 
+      !!----------------------------------------------------------------------
+      INTEGER                                     , INTENT(in   ) ::   kt , Kbb, Kmm, Krhs   ! ocean time-step and level indices
+      REAL(wp), DIMENSION(jpi,jpj,jpk,jpt), TARGET, INTENT(inout) ::   puu, pvv              ! ocean velocities and RHS of momentum equation
+      REAL(wp), DIMENSION(:,:,:), OPTIONAL, TARGET, INTENT(in   ) ::   pau, pav, paw         ! advective velocity
+      !
+      INTEGER  ::   ji, jj, jk   ! dummy loop indices
+      REAL(wp) ::   zzu, zui, zfuj, zl_u, zzfu_kp1     ! local scalars
+      REAL(wp) ::   zzv, zvj, zfvi, zl_v, zzfv_kp1     !   -      -
+      REAL(wp), DIMENSION(A2D(2))   ::   zfu_t, zfu_f, zfu
+      REAL(wp), DIMENSION(A2D(2))   ::   zfv_t, zfv_f, zfv
+      REAL(wp), DIMENSION(A2D(2),2) ::   zlu_uu, zlu_uv
+      REAL(wp), DIMENSION(A2D(2),2) ::   zlv_vv, zlv_vu
+      REAL(wp), DIMENSION(:,:,:) , POINTER ::   zpt_u, zpt_v, zpt_w
+      REAL(wp), DIMENSION(:,:,:) , ALLOCATABLE ::   zu_trd, zv_trd
+      !!----------------------------------------------------------------------
+      !
+      IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+         IF( kt == nit000 ) THEN
+            IF(lwp) WRITE(numout,*)
+            IF(lwp) WRITE(numout,*) 'dyn_adv_ubs : UBS flux form momentum advection'
+            IF(lwp) WRITE(numout,*) '~~~~~~~~~~~'
+         ENDIF
+      ENDIF
+      !
+      IF( l_trddyn ) THEN           ! trends: send trend to trddyn for diagnostic  
+         ALLOCATE( zu_trd(A2D(0),jpkm1), zv_trd(A2D(0),jpkm1) )
+         zu_trd(A2D(0),:) = puu(A2D(0),:,Krhs)
+         zv_trd(A2D(0),:) = pvv(A2D(0),:,Krhs)
+      ENDIF
+      !
+      IF( PRESENT( pau ) ) THEN     ! RK3: advective velocity (pau,pav,paw) /= advected velocity (puu,pvv,ww)
+         zpt_u => pau(:,:,:)
+         zpt_v => pav(:,:,:)
+         zpt_w => paw(:,:,:)
+      ELSE                          ! MLF: advective velocity = (puu,pvv,ww)
+         zpt_u => puu(:,:,:,Kmm)
+         zpt_v => pvv(:,:,:,Kmm)
+         zpt_w => ww (:,:,:    )
+      ENDIF
+      !
+      !                                      ! =========================== !
+      DO jk = 1, jpkm1                       !  Laplacian of the velocity  !
+         !                                   ! =========================== !
+         !                                         ! horizontal volume fluxes
+         DO_2D( 2, 2, 2, 2 )
+            zfu(ji,jj) = e2u(ji,jj) * e3u(ji,jj,jk,Kmm) * zpt_u(ji,jj,jk)
+            zfv(ji,jj) = e1v(ji,jj) * e3v(ji,jj,jk,Kmm) * zpt_v(ji,jj,jk)
+         END_2D
+         !            
+         DO_2D( 1, 1, 1, 1 )                       ! laplacian
+            ! round brackets added to fix the order of floating point operations
+            ! needed to ensure halo 1 - halo 2 compatibility (north fold)
+!!            zlu_uu(ji,jj,1) = (  ( puu(ji+1,jj  ,jk,Kbb) + puu(ji-1,jj  ,jk,Kbb) ) - 2._wp * puu(ji,jj,jk,Kbb)  ) * umask(ji,jj,jk)
+!!            zlv_vv(ji,jj,1) = (  ( pvv(ji  ,jj+1,jk,Kbb) + pvv(ji  ,jj-1,jk,Kbb) ) - 2._wp * pvv(ji,jj,jk,Kbb)  ) * vmask(ji,jj,jk)
+            zlu_uu(ji,jj,1) = ( ( puu (ji+1,jj  ,jk,Kbb) - puu (ji  ,jj  ,jk,Kbb) &
+               &                )                                                 & ! bracket for halo 1 - halo 2 compatibility
+               &              + ( puu (ji-1,jj  ,jk,Kbb) - puu (ji  ,jj  ,jk,Kbb) &
+               &                )                                                   ) * umask(ji  ,jj  ,jk)
+            zlv_vv(ji,jj,1) = ( ( pvv (ji  ,jj+1,jk,Kbb) - pvv (ji  ,jj  ,jk,Kbb) &
+               &                )                                                 & ! bracket for halo 1 - halo 2 compatibility
+               &              + ( pvv (ji  ,jj-1,jk,Kbb) - pvv (ji  ,jj  ,jk,Kbb) &
+               &                )                                                   ) * vmask(ji  ,jj  ,jk)
+            zlu_uv(ji,jj,1) = (    puu(ji  ,jj+1,jk,Kbb) - puu(ji  ,jj  ,jk,Kbb)    ) * fmask(ji  ,jj  ,jk)   &
+               &            - (    puu(ji  ,jj  ,jk,Kbb) - puu(ji  ,jj-1,jk,Kbb)    ) * fmask(ji  ,jj-1,jk)
+            zlv_vu(ji,jj,1) = (    pvv(ji+1,jj  ,jk,Kbb) - pvv(ji  ,jj  ,jk,Kbb)    ) * fmask(ji  ,jj  ,jk)   &
+               &            - (    pvv(ji  ,jj  ,jk,Kbb) - pvv(ji-1,jj  ,jk,Kbb)    ) * fmask(ji-1,jj  ,jk)
+            !
+!!            zlu_uu(ji,jj,2) = (  ( zfu(ji+1,jj  ) + zfu(ji-1,jj  ) ) - 2._wp * zfu(ji,jj)  ) * umask(ji  ,jj  ,jk)
+!!            zlv_vv(ji,jj,2) = (  ( zfv(ji  ,jj+1) + zfv(ji  ,jj-1) ) - 2._wp * zfv(ji,jj)  ) * vmask(ji  ,jj  ,jk)
+            zlu_uu(ji,jj,2) = ( ( zfu(ji+1,jj  ) - zfu(ji  ,jj  )           &
+               &                )                                           & ! bracket for halo 1 - halo 2 compatibility
+               &              + ( zfu(ji-1,jj  ) - zfu(ji  ,jj  )           &
+               &                )                                             ) * umask(ji  ,jj  ,jk)
+            zlv_vv(ji,jj,2) = ( ( zfv(ji  ,jj+1) - zfv(ji  ,jj  )           &
+               &                )                                           & ! bracket for halo 1 - halo 2 compatibility
+               &              + ( zfv(ji  ,jj-1) - zfv(ji  ,jj  )           &
+               &                )                                             ) * vmask(ji  ,jj  ,jk)
+            zlu_uv(ji,jj,2) = (    zfu(ji  ,jj+1) - zfu(ji  ,jj  )    ) * fmask(ji  ,jj  ,jk)             &
+               &            - (    zfu(ji  ,jj  ) - zfu(ji  ,jj-1)    ) * fmask(ji  ,jj-1,jk)
+            zlv_vu(ji,jj,2) = (    zfv(ji+1,jj  ) - zfv(ji  ,jj  )    ) * fmask(ji  ,jj  ,jk)             &
+               &            - (    zfv(ji  ,jj  ) - zfv(ji-1,jj  )    ) * fmask(ji-1,jj  ,jk)
+         END_2D
+         !
+         !                                      ! ====================== !
+         !                                      !  Horizontal advection  !
+         !                                      ! ====================== !
+         !                                         ! horizontal volume fluxes
+         DO_2D( 1, 1, 1, 1 )
+            zfu(ji,jj) = 0.25_wp * zfu(ji,jj)
+            zfv(ji,jj) = 0.25_wp * zfv(ji,jj)
+         END_2D
+         !
+         DO_2D( 1, 0, 1, 0 )                       ! horizontal momentum fluxes at T- and F-point
+            zui = ( puu(ji,jj,jk,Kmm) + puu(ji+1,jj  ,jk,Kmm) )
+            zvj = ( pvv(ji,jj,jk,Kmm) + pvv(ji  ,jj+1,jk,Kmm) )
+            !
+            IF( zui > 0 ) THEN   ;   zl_u = zlu_uu(ji  ,jj,1)
+            ELSE                 ;   zl_u = zlu_uu(ji+1,jj,1)
+            ENDIF
+            IF( zvj > 0 ) THEN   ;   zl_v = zlv_vv(ji,jj  ,1)
+            ELSE                 ;   zl_v = zlv_vv(ji,jj+1,1)
+            ENDIF
+            !
+            zfu_t(ji+1,jj  ) = ( zfu(ji,jj) + zfu(ji+1,jj  ) - gamma2 * ( zlu_uu(ji,jj,2) + zlu_uu(ji+1,jj  ,2) )  )   &
+               &             * ( zui - gamma1 * zl_u )
+            zfv_t(ji  ,jj+1) = ( zfv(ji,jj) + zfv(ji  ,jj+1) - gamma2 * ( zlv_vv(ji,jj,2) + zlv_vv(ji  ,jj+1,2) )  )   &
+               &             * ( zvj - gamma1 * zl_v )
+            !
+            zfuj = ( zfu(ji,jj) + zfu(ji  ,jj+1) )
+            zfvi = ( zfv(ji,jj) + zfv(ji+1,jj  ) )
+            IF( zfuj > 0 ) THEN   ;    zl_v = zlv_vu(ji  ,jj,1)
+            ELSE                  ;    zl_v = zlv_vu(ji+1,jj,1)
+            ENDIF
+            IF( zfvi > 0 ) THEN   ;    zl_u = zlu_uv(ji,jj  ,1)
+            ELSE                  ;    zl_u = zlu_uv(ji,jj+1,1)
+            ENDIF
+            !
+            zfv_f(ji  ,jj  ) = ( zfvi - gamma2 * ( zlv_vu(ji,jj,2) + zlv_vu(ji+1,jj  ,2) )  )   &
+               &             * ( puu(ji,jj,jk,Kmm) + puu(ji  ,jj+1,jk,Kmm) - gamma1 * zl_u )
+            zfu_f(ji  ,jj  ) = ( zfuj - gamma2 * ( zlu_uv(ji,jj,2) + zlu_uv(ji  ,jj+1,2) )  )   &
+               &             * ( pvv(ji,jj,jk,Kmm) + pvv(ji+1,jj  ,jk,Kmm) - gamma1 * zl_v )
+         END_2D
+         DO_2D( 0, 0, 0, 0 )                       ! divergence of horizontal momentum fluxes
+            puu(ji,jj,jk,Krhs) = puu(ji,jj,jk,Krhs) - (  zfu_t(ji+1,jj) - zfu_t(ji,jj  )    &
+               &                                       + zfv_f(ji  ,jj) - zfv_f(ji,jj-1)  ) * r1_e1e2u(ji,jj)   &
+               &                                    / e3u(ji,jj,jk,Kmm)
+            pvv(ji,jj,jk,Krhs) = pvv(ji,jj,jk,Krhs) - (  zfu_f(ji,jj  ) - zfu_f(ji-1,jj)    &
+               &                                       + zfv_t(ji,jj+1) - zfv_t(ji  ,jj)  ) * r1_e1e2v(ji,jj)   &
+               &                                    / e3v(ji,jj,jk,Kmm)
+         END_2D
+      END DO
+      !
+      IF( l_trddyn ) THEN           ! trends: send trend to trddyn for diagnostic
+         zu_trd(A2D(0),:) = puu(A2D(0),:,Krhs) - zu_trd(A2D(0),:)
+         zv_trd(A2D(0),:) = pvv(A2D(0),:,Krhs) - zv_trd(A2D(0),:)
+         CALL trd_dyn( zu_trd, zv_trd, jpdyn_keg, kt, Kmm )
+         zu_trd(A2D(0),:) = puu(A2D(0),:,Krhs)
+         zv_trd(A2D(0),:) = pvv(A2D(0),:,Krhs)
+      ENDIF
+      !                                      ! ==================== !
+      !                                      !  Vertical advection  !
+      !                                      ! ==================== !
+      !
+#define zfu_uw   zfu_t
+#define zfv_vw   zfv_t
+#define zfw      zfu
+      !
+      !                              ! surface vertical fluxes
+      !
+      IF( ln_linssh ) THEN                ! linear free surface: advection through the surface z=0
+         DO_2D( 0, 0, 0, 0 )
+            zfu_uw(ji,jj) = 0.5_wp * ( e1e2t(ji,jj) * zpt_w(ji,jj,1) + e1e2t(ji+1,jj) * zpt_w(ji+1,jj,1) ) * puu(ji,jj,1,Kmm)
+            zfv_vw(ji,jj) = 0.5_wp * ( e1e2t(ji,jj) * zpt_w(ji,jj,1) + e1e2t(ji,jj+1) * zpt_w(ji,jj+1,1) ) * pvv(ji,jj,1,Kmm)
+         END_2D
+      ELSE                                ! non linear free: surface advective fluxes set to zero
+         DO_2D( 0, 0, 0, 0 )
+            zfu_uw(ji,jj) = 0._wp
+            zfv_vw(ji,jj) = 0._wp
+         END_2D
+      ENDIF
+      ! 
+      DO jk = 1, jpk-2               !  divergence of advective fluxes
+         !
+         DO_2D( 0, 1, 0, 1 )                  ! 1/4 * Vertical transport at level k+1
+            zfw(ji,jj) = 0.25_wp * e1e2t(ji,jj) * zpt_w(ji,jj,jk+1)
+         END_2D
+         DO_2D( 0, 0, 0, 0 )
+            !                                 ! vertical flux at level k+1
+            zzfu_kp1 = ( zfw(ji,jj) + zfw(ji+1,jj  ) ) * ( puu(ji,jj,jk+1,Kmm) + puu(ji,jj,jk,Kmm) )
+            zzfv_kp1 = ( zfw(ji,jj) + zfw(ji  ,jj+1) ) * ( pvv(ji,jj,jk+1,Kmm) + pvv(ji,jj,jk,Kmm) )
+            !                                 ! divergence of vertical momentum flux
+            puu(ji,jj,jk,Krhs) = puu(ji,jj,jk,Krhs) - ( zfu_uw(ji,jj) - zzfu_kp1 ) * r1_e1e2u(ji,jj)   &
+               &                                      / e3u(ji,jj,jk,Kmm)
+            pvv(ji,jj,jk,Krhs) = pvv(ji,jj,jk,Krhs) - ( zfv_vw(ji,jj) - zzfv_kp1 ) * r1_e1e2v(ji,jj)   &
+               &                                      / e3v(ji,jj,jk,Kmm) 
+            !                                 ! store vertical flux for next level calculation
+            zfu_uw(ji,jj) = zzfu_kp1
+            zfv_vw(ji,jj) = zzfv_kp1
+         END_2D
+      END DO
+      !
+      jk = jpkm1                              ! compute last level (zzfu_kp1 = 0)
+      DO_2D( 0, 0, 0, 0 )
+         puu(ji,jj,jk,Krhs) = puu(ji,jj,jk,Krhs) - zfu_uw(ji,jj) * r1_e1e2u(ji,jj)   &
+            &                                      / e3u(ji,jj,jk,Kmm)
+         pvv(ji,jj,jk,Krhs) = pvv(ji,jj,jk,Krhs) - zfv_vw(ji,jj) * r1_e1e2v(ji,jj)   &
+            &                                      / e3v(ji,jj,jk,Kmm) 
+      END_2D
+      !
+      IF( l_trddyn ) THEN                     ! trends: send trend to trddyn for diagnostic
+         zu_trd(A2D(0),:) = puu(A2D(0),:,Krhs) - zu_trd(A2D(0),:)
+         zv_trd(A2D(0),:) = pvv(A2D(0),:,Krhs) - zv_trd(A2D(0),:)
+         CALL trd_dyn( zu_trd, zv_trd, jpdyn_zad, kt, Kmm )
+         DEALLOCATE( zu_trd, zv_trd )
+      ENDIF
+      !
+#undef zfu_uw
+#undef zfv_vw
+#undef zfw
+      !                                         ! Control print
+      IF(sn_cfctl%l_prtctl)   CALL prt_ctl( tab3d_1=puu(:,:,:,Krhs), clinfo1=' ubs2 adv - Ua: ', mask1=umask,   &
+         &                                  tab3d_2=pvv(:,:,:,Krhs), clinfo2=           ' Va: ', mask2=vmask, clinfo3='dyn' )
+      !
+   END SUBROUTINE dyn_adv_ubs
+
+
+   SUBROUTINE dyn_adv_ubs_hls1( kt, Kbb, Kmm, puu, pvv, Krhs, pau, pav, paw )
       !!----------------------------------------------------------------------
       !!                  ***  ROUTINE dyn_adv_ubs  ***
       !!
@@ -73,7 +311,6 @@ CONTAINS
       !! Reference : Shchepetkin & McWilliams, 2005, Ocean Modelling. 
       !!----------------------------------------------------------------------
       INTEGER                                     , INTENT(in   ) ::   kt , Kbb, Kmm, Krhs   ! ocean time-step and level indices
-      INTEGER                   , OPTIONAL        , INTENT(in   ) ::   no_zad                ! no vertical advection compotation
       REAL(wp), DIMENSION(jpi,jpj,jpk,jpt), TARGET, INTENT(inout) ::   puu, pvv              ! ocean velocities and RHS of momentum equation
       REAL(wp), DIMENSION(:,:,:), OPTIONAL, TARGET, INTENT(in   ) ::   pau, pav, paw         ! advective velocity
       !
@@ -89,7 +326,7 @@ CONTAINS
       IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
          IF( kt == nit000 ) THEN
             IF(lwp) WRITE(numout,*)
-            IF(lwp) WRITE(numout,*) 'dyn_adv_ubs : UBS flux form momentum advection'
+            IF(lwp) WRITE(numout,*) 'dyn_adv_ubs_hls1 : UBS flux form momentum advection'
             IF(lwp) WRITE(numout,*) '~~~~~~~~~~~'
          ENDIF
       ENDIF
@@ -230,63 +467,44 @@ CONTAINS
       !                                      !  Vertical advection  !
       !                                      ! ==================== !
       !
-      !                                      ! ======================== !
-      IF( PRESENT( no_zad ) ) THEN           !  No vertical advection   !   (except if linear free surface)
-         !                                   ! ======================== !    ------
-         !
-         IF( ln_linssh ) THEN                      ! linear free surface: advection through the surface z=0
-            DO_2D( 0, 0, 0, 0 )
-               zzu = 0.5_wp * ( e1e2t(ji,jj) * zpt_w(ji,jj,1) + e1e2t(ji+1,jj) * zpt_w(ji+1,jj,1) ) * puu(ji,jj,1,Kmm)
-               zzv = 0.5_wp * ( e1e2t(ji,jj) * zpt_w(ji,jj,1) + e1e2t(ji,jj+1) * zpt_w(ji,jj+1,1) ) * pvv(ji,jj,1,Kmm)
-               puu(ji,jj,1,Krhs) = puu(ji,jj,1,Krhs) - zzu * r1_e1e2u(ji,jj)   &
-                  &                                        / e3u(ji,jj,1,Kmm)
-               pvv(ji,jj,1,Krhs) = pvv(ji,jj,1,Krhs) - zzv * r1_e1e2v(ji,jj)   &
-                  &                                        / e3v(ji,jj,1,Kmm)
-            END_2D
-         ENDIF
-         !                                   ! =================== !
-      ELSE                                   !  Vertical advection !
-         !                                   ! =================== !
-         DO_2D( 0, 0, 0, 0 )                          ! surface/bottom advective fluxes set to zero
-            zfu_uw(ji,jj,jpk) = 0._wp
-            zfv_vw(ji,jj,jpk) = 0._wp
-            zfu_uw(ji,jj, 1 ) = 0._wp
-            zfv_vw(ji,jj, 1 ) = 0._wp
+      DO_2D( 0, 0, 0, 0 )                          ! surface/bottom advective fluxes set to zero
+         zfu_uw(ji,jj,jpk) = 0._wp
+         zfv_vw(ji,jj,jpk) = 0._wp
+         zfu_uw(ji,jj, 1 ) = 0._wp
+         zfv_vw(ji,jj, 1 ) = 0._wp
+      END_2D
+      IF( ln_linssh ) THEN                         ! constant volume : advection through the surface
+         DO_2D( 0, 0, 0, 0 )
+            zfu_uw(ji,jj,1) = 0.5_wp * ( e1e2t(ji,jj) * zpt_w(ji,jj,1) + e1e2t(ji+1,jj) * zpt_w(ji+1,jj,1) ) * puu(ji,jj,1,Kmm)
+            zfv_vw(ji,jj,1) = 0.5_wp * ( e1e2t(ji,jj) * zpt_w(ji,jj,1) + e1e2t(ji,jj+1) * zpt_w(ji,jj+1,1) ) * pvv(ji,jj,1,Kmm)
          END_2D
-         IF( ln_linssh ) THEN                         ! constant volume : advection through the surface
-            DO_2D( 0, 0, 0, 0 )
-               zfu_uw(ji,jj,1) = 0.5_wp * ( e1e2t(ji,jj) * zpt_w(ji,jj,1) + e1e2t(ji+1,jj) * zpt_w(ji+1,jj,1) ) * puu(ji,jj,1,Kmm)
-               zfv_vw(ji,jj,1) = 0.5_wp * ( e1e2t(ji,jj) * zpt_w(ji,jj,1) + e1e2t(ji,jj+1) * zpt_w(ji,jj+1,1) ) * pvv(ji,jj,1,Kmm)
-            END_2D
-         ENDIF
-         DO jk = 2, jpkm1                          ! interior fluxes
-            DO_2D( 0, 1, 0, 1 )
-               zfw(ji,jj,jk) = 0.25_wp * e1e2t(ji,jj) * zpt_w(ji,jj,jk)
-            END_2D
-            DO_2D( 0, 0, 0, 0 )
-               zfu_uw(ji,jj,jk) = ( zfw(ji,jj,jk)+ zfw(ji+1,jj,jk) ) * ( puu(ji,jj,jk,Kmm) + puu(ji,jj,jk-1,Kmm) )
-               zfv_vw(ji,jj,jk) = ( zfw(ji,jj,jk)+ zfw(ji,jj+1,jk) ) * ( pvv(ji,jj,jk,Kmm) + pvv(ji,jj,jk-1,Kmm) )
-            END_2D
-         END DO
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )             ! divergence of vertical momentum flux divergence
-            puu(ji,jj,jk,Krhs) =  puu(ji,jj,jk,Krhs) - ( zfu_uw(ji,jj,jk) - zfu_uw(ji,jj,jk+1) ) * r1_e1e2u(ji,jj)   &
-               &                                       / e3u(ji,jj,jk,Kmm)
-            pvv(ji,jj,jk,Krhs) =  pvv(ji,jj,jk,Krhs) - ( zfv_vw(ji,jj,jk) - zfv_vw(ji,jj,jk+1) ) * r1_e1e2v(ji,jj)   &
-               &                                       / e3v(ji,jj,jk,Kmm)
-         END_3D
-         !
-         IF( l_trddyn ) THEN                       ! save the vertical advection trend for diagnostic
-            zfu_t(:,:,:) = puu(:,:,:,Krhs) - zfu_t(:,:,:)
-            zfv_t(:,:,:) = pvv(:,:,:,Krhs) - zfv_t(:,:,:)
-            CALL trd_dyn( zfu_t, zfv_t, jpdyn_zad, kt, Kmm )
-         ENDIF
-         !                                         ! Control print
-         IF(sn_cfctl%l_prtctl)   CALL prt_ctl( tab3d_1=puu(:,:,:,Krhs), clinfo1=' ubs2 adv - Ua: ', mask1=umask,   &
-            &                                  tab3d_2=pvv(:,:,:,Krhs), clinfo2=           ' Va: ', mask2=vmask, clinfo3='dyn' )
-         !
       ENDIF
+      DO jk = 2, jpkm1                          ! interior fluxes
+         DO_2D( 0, 1, 0, 1 )
+            zfw(ji,jj,jk) = 0.25_wp * e1e2t(ji,jj) * zpt_w(ji,jj,jk)
+         END_2D
+         DO_2D( 0, 0, 0, 0 )
+            zfu_uw(ji,jj,jk) = ( zfw(ji,jj,jk)+ zfw(ji+1,jj,jk) ) * ( puu(ji,jj,jk,Kmm) + puu(ji,jj,jk-1,Kmm) )
+            zfv_vw(ji,jj,jk) = ( zfw(ji,jj,jk)+ zfw(ji,jj+1,jk) ) * ( pvv(ji,jj,jk,Kmm) + pvv(ji,jj,jk-1,Kmm) )
+         END_2D
+      END DO
+      DO_3D( 0, 0, 0, 0, 1, jpkm1 )             ! divergence of vertical momentum flux divergence
+         puu(ji,jj,jk,Krhs) =  puu(ji,jj,jk,Krhs) - ( zfu_uw(ji,jj,jk) - zfu_uw(ji,jj,jk+1) ) * r1_e1e2u(ji,jj)   &
+            &                                       / e3u(ji,jj,jk,Kmm)
+         pvv(ji,jj,jk,Krhs) =  pvv(ji,jj,jk,Krhs) - ( zfv_vw(ji,jj,jk) - zfv_vw(ji,jj,jk+1) ) * r1_e1e2v(ji,jj)   &
+            &                                       / e3v(ji,jj,jk,Kmm)
+      END_3D
       !
-   END SUBROUTINE dyn_adv_ubs
+      IF( l_trddyn ) THEN                       ! save the vertical advection trend for diagnostic
+         zfu_t(:,:,:) = puu(:,:,:,Krhs) - zfu_t(:,:,:)
+         zfv_t(:,:,:) = pvv(:,:,:,Krhs) - zfv_t(:,:,:)
+         CALL trd_dyn( zfu_t, zfv_t, jpdyn_zad, kt, Kmm )
+      ENDIF
+      !                                         ! Control print
+      IF(sn_cfctl%l_prtctl)   CALL prt_ctl( tab3d_1=puu(:,:,:,Krhs), clinfo1=' ubs2 adv - Ua: ', mask1=umask,   &
+         &                                  tab3d_2=pvv(:,:,:,Krhs), clinfo2=           ' Va: ', mask2=vmask, clinfo3='dyn' )
+      !
+   END SUBROUTINE dyn_adv_ubs_hls1
 
    !!==============================================================================
 END MODULE dynadv_ubs
diff --git a/src/OCE/DYN/dynkeg.F90 b/src/OCE/DYN/dynkeg.F90
index d751899d0de9266477ed7f9ecc26941906cba84d..10e4134b8a2d1efd9ab751ce09b5b8b82c23a6f2 100644
--- a/src/OCE/DYN/dynkeg.F90
+++ b/src/OCE/DYN/dynkeg.F90
@@ -6,7 +6,8 @@ MODULE dynkeg
    !! History :  1.0  !  1987-09  (P. Andrich, M.-A. Foujols)  Original code
    !!            7.0  !  1997-05  (G. Madec)  Split dynber into dynkeg and dynhpg
    !!  NEMO      1.0  !  2002-07  (G. Madec)  F90: Free form and module
-   !!            3.6  !  2015-05  (N. Ducousso, G. Madec)  add Hollingsworth scheme as an option 
+   !!            3.6  !  2015-05  (N. Ducousso, G. Madec)  add Hollingsworth scheme as an option
+   !!            4.5  !  2022-06  (S. Techene, G, Madec) refactorization to reduce local memory usage
    !!----------------------------------------------------------------------
    
    !!----------------------------------------------------------------------
@@ -27,7 +28,8 @@ MODULE dynkeg
    IMPLICIT NONE
    PRIVATE
 
-   PUBLIC   dyn_keg    ! routine called by step module
+   PUBLIC   dyn_keg        ! routine called by step module
+   PUBLIC   dyn_keg_hls1   ! routine called by step module
    
    INTEGER, PARAMETER, PUBLIC  ::   nkeg_C2  = 0   !: 2nd order centered scheme (standard scheme)
    INTEGER, PARAMETER, PUBLIC  ::   nkeg_HW  = 1   !: Hollingsworth et al., QJRMS, 1983
@@ -44,6 +46,123 @@ MODULE dynkeg
 CONTAINS
 
    SUBROUTINE dyn_keg( kt, kscheme, Kmm, puu, pvv, Krhs )
+      !!----------------------------------------------------------------------
+      !!                  ***  ROUTINE dyn_keg  ***
+      !!
+      !! ** Purpose :   Compute the now momentum trend due to the horizontal
+      !!      gradient of the horizontal kinetic energy and add it to the 
+      !!      general momentum trend.
+      !!
+      !! ** Method  : * kscheme = nkeg_C2 : 2nd order centered scheme that 
+      !!      conserve kinetic energy. Compute the now horizontal kinetic energy 
+      !!         zhke = 1/2 [ mi-1( un^2 ) + mj-1( vn^2 ) ]
+      !!              * kscheme = nkeg_HW : Hollingsworth correction following
+      !!      Arakawa (2001). The now horizontal kinetic energy is given by:
+      !!         zhke = 1/6 [ mi-1(  2 * un^2 + ((u(j+1)+u(j-1))/2)^2  )
+      !!                    + mj-1(  2 * vn^2 + ((v(i+1)+v(i-1))/2)^2  ) ]
+      !!      
+      !!      Take its horizontal gradient and add it to the general momentum
+      !!      trend.
+      !!         u(rhs) = u(rhs) - 1/e1u di[ zhke ]
+      !!         v(rhs) = v(rhs) - 1/e2v dj[ zhke ]
+      !!
+      !! ** Action : - Update the (puu(:,:,:,Krhs), pvv(:,:,:,Krhs)) with the hor. ke gradient trend
+      !!             - send this trends to trd_dyn (l_trddyn=T) for post-processing
+      !!
+      !! ** References : Arakawa, A., International Geophysics 2001.
+      !!                 Hollingsworth et al., Quart. J. Roy. Meteor. Soc., 1983.
+      !!----------------------------------------------------------------------
+      INTEGER                             , INTENT(in   ) ::   kt          ! ocean time-step index
+      INTEGER                             , INTENT(in   ) ::   kscheme     ! =0/1   type of KEG scheme 
+      INTEGER                             , INTENT(in   ) ::   Kmm, Krhs   ! ocean time level indices
+      REAL(wp), DIMENSION(jpi,jpj,jpk,jpt), INTENT(inout) ::   puu, pvv    ! ocean velocities and RHS of momentum equation
+      !
+      INTEGER  ::   ji, jj, jk   ! dummy loop indices
+      REAL(wp) ::   zu, zv       ! local scalars
+      REAL(wp), DIMENSION(:,:  ) , ALLOCATABLE ::   zhke
+      REAL(wp), DIMENSION(:,:,:) , ALLOCATABLE ::   zu_trd, zv_trd
+      !!----------------------------------------------------------------------
+      !
+      IF( ln_timing )   CALL timing_start('dyn_keg')
+      !
+      IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+         IF( kt == nit000 ) THEN
+            IF(lwp) WRITE(numout,*)
+            IF(lwp) WRITE(numout,*) 'dyn_keg : kinetic energy gradient trend, scheme number=', kscheme
+            IF(lwp) WRITE(numout,*) '~~~~~~~'
+         ENDIF
+      ENDIF
+      !
+      IF( l_trddyn ) THEN                       ! Save the input trends
+         ALLOCATE( zu_trd(A2D(0),jpk), zv_trd(A2D(0),jpk) )
+         zu_trd(A2D(0),:) = puu(A2D(0),:,Krhs)
+         zv_trd(A2D(0),:) = pvv(A2D(0),:,Krhs)
+      ENDIF
+      !
+      SELECT CASE ( kscheme )
+      !
+      CASE ( nkeg_C2 )                    !==  Standard scheme  ==!
+         ALLOCATE( zhke(A2D(1)) )
+         DO jk = 1, jpkm1
+            DO_2D( 0, 1, 0, 1 )                 !* Horizontal kinetic energy at T-point
+               zu =    puu(ji-1,jj  ,jk,Kmm) * puu(ji-1,jj  ,jk,Kmm)   &
+                  &  + puu(ji  ,jj  ,jk,Kmm) * puu(ji  ,jj  ,jk,Kmm)
+               zv =    pvv(ji  ,jj-1,jk,Kmm) * pvv(ji  ,jj-1,jk,Kmm)   &
+                  &  + pvv(ji  ,jj  ,jk,Kmm) * pvv(ji  ,jj  ,jk,Kmm)
+               zhke(ji,jj) = 0.25_wp * ( zv + zu )
+            END_2D
+            !
+            DO_2D( 0, 0, 0, 0 )                  !* grad( KE ) added to the general momentum trends
+               puu(ji,jj,jk,Krhs) = puu(ji,jj,jk,Krhs) - ( zhke(ji+1,jj  ) - zhke(ji,jj) ) * r1_e1u(ji,jj)
+               pvv(ji,jj,jk,Krhs) = pvv(ji,jj,jk,Krhs) - ( zhke(ji  ,jj+1) - zhke(ji,jj) ) * r1_e2v(ji,jj)
+            END_2D
+         END DO
+         DEALLOCATE( zhke )
+         !
+      CASE ( nkeg_HW )                           !* Hollingsworth scheme
+         ALLOCATE( zhke(A2D(1)) )
+         DO jk = 1, jpkm1
+            DO_2D( 0, 1, 0, 1 )
+               ! round brackets added to fix the order of floating point operations
+               ! needed to ensure halo 1 - halo 2 compatibility
+               zu =   (   puu(ji-1,jj  ,jk,Kmm) * puu(ji-1,jj  ,jk,Kmm)               &
+                  &     + puu(ji  ,jj  ,jk,Kmm) * puu(ji  ,jj  ,jk,Kmm)   ) * 8._wp   &
+                  & + ( ( puu(ji-1,jj-1,jk,Kmm) + puu(ji-1,jj+1,jk,Kmm) ) * ( puu(ji-1,jj-1,jk,Kmm) + puu(ji-1,jj+1,jk,Kmm) )   &
+                  & +   ( puu(ji  ,jj-1,jk,Kmm) + puu(ji  ,jj+1,jk,Kmm) ) * ( puu(ji  ,jj-1,jk,Kmm) + puu(ji  ,jj+1,jk,Kmm) )   &
+                  &   )                                                    ! bracket for halo 1 - halo 2 compatibility
+               zv =   (   pvv(ji  ,jj-1,jk,Kmm) * pvv(ji  ,jj-1,jk,Kmm)               &
+                  &     + pvv(ji  ,jj  ,jk,Kmm) * pvv(ji  ,jj  ,jk,Kmm)   ) * 8._wp   &
+                  & + ( ( pvv(ji-1,jj-1,jk,Kmm) + pvv(ji+1,jj-1,jk,Kmm) ) * ( pvv(ji-1,jj-1,jk,Kmm) + pvv(ji+1,jj-1,jk,Kmm) )   &
+                  & +   ( pvv(ji-1,jj  ,jk,Kmm) + pvv(ji+1,jj  ,jk,Kmm) ) * ( pvv(ji-1,jj  ,jk,Kmm) + pvv(ji+1,jj  ,jk,Kmm) )   &
+                  &   )                                                    ! bracket for halo 1 - halo 2 compatibility
+               zhke(ji,jj) = r1_48 * ( zv + zu )
+            END_2D
+            !
+            DO_2D( 0, 0, 0, 0 )                  !* grad( KE ) added to the general momentum trends
+               puu(ji,jj,jk,Krhs) = puu(ji,jj,jk,Krhs) - ( zhke(ji+1,jj  ) - zhke(ji,jj) ) * r1_e1u(ji,jj)
+               pvv(ji,jj,jk,Krhs) = pvv(ji,jj,jk,Krhs) - ( zhke(ji  ,jj+1) - zhke(ji,jj) ) * r1_e2v(ji,jj)
+            END_2D
+         END DO
+         DEALLOCATE( zhke )
+         !
+      END SELECT
+      !
+      IF( l_trddyn ) THEN                        ! save the Kinetic Energy trends for diagnostic
+         zu_trd(A2D(0),:) = puu(A2D(0),:,Krhs) - zu_trd(A2D(0),:)
+         zv_trd(A2D(0),:) = pvv(A2D(0),:,Krhs) - zv_trd(A2D(0),:)
+         CALL trd_dyn( zu_trd, zv_trd, jpdyn_keg, kt, Kmm )
+         DEALLOCATE( zu_trd, zv_trd )
+      ENDIF
+      !
+      IF(sn_cfctl%l_prtctl)   CALL prt_ctl( tab3d_1=puu(:,:,:,Krhs), clinfo1=' keg  - Ua: ', mask1=umask,   &
+         &                                  tab3d_2=pvv(:,:,:,Krhs), clinfo2=       ' Va: ', mask2=vmask, clinfo3='dyn' )
+      !
+      IF( ln_timing )   CALL timing_stop('dyn_keg')
+      !
+   END SUBROUTINE dyn_keg
+
+
+   SUBROUTINE dyn_keg_hls1( kt, kscheme, Kmm, puu, pvv, Krhs )
       !!----------------------------------------------------------------------
       !!                  ***  ROUTINE dyn_keg  ***
       !!
@@ -86,7 +205,7 @@ CONTAINS
       IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
          IF( kt == nit000 ) THEN
             IF(lwp) WRITE(numout,*)
-            IF(lwp) WRITE(numout,*) 'dyn_keg : kinetic energy gradient trend, scheme number=', kscheme
+            IF(lwp) WRITE(numout,*) 'dyn_keg_hls1 : kinetic energy gradient trend, scheme number=', kscheme
             IF(lwp) WRITE(numout,*) '~~~~~~~'
          ENDIF
       ENDIF
@@ -147,7 +266,7 @@ CONTAINS
       !
       IF( ln_timing )   CALL timing_stop('dyn_keg')
       !
-   END SUBROUTINE dyn_keg
+   END SUBROUTINE dyn_keg_hls1
 
    !!======================================================================
 END MODULE dynkeg
diff --git a/src/OCE/DYN/dynvor.F90 b/src/OCE/DYN/dynvor.F90
index 03dda78ceb4f6ce993419062208a9240e3ae7d75..b7a84124a27df69f6ea82b1622683c7a2be8470b 100644
--- a/src/OCE/DYN/dynvor.F90
+++ b/src/OCE/DYN/dynvor.F90
@@ -22,6 +22,7 @@ MODULE dynvor
    !!             -   ! 2018-04  (G. Madec)  add pre-computed gradient for metric term calculation
    !!            4.x  ! 2020-03  (G. Madec, A. Nasser)  make ln_dynvor_msk truly efficient on relative vorticity
    !!            4.2  ! 2020-12  (G. Madec, E. Clementi) add vortex force trends (ln_vortex_force=T)
+   !!            4.5  ! 2022-06  (S. Techene, G, Madec) refactorization to reduce local memory usage
    !!----------------------------------------------------------------------
 
    !!----------------------------------------------------------------------
@@ -172,11 +173,20 @@ CONTAINS
                              CALL vor_enT( kt, Kmm, ntot, usd, vsd, puu(:,:,:,Krhs), pvv(:,:,:,Krhs) )   ! add the Stokes-Coriolis trend and vortex force
             ENDIF
          CASE( np_EET )                        !* energy conserving scheme (een scheme using e3t)
+            IF( nn_hls == 1 ) THEN
+                             CALL vor_eeT_hls1( kt, Kmm, ntot, puu(:,:,:,Kmm) , pvv(:,:,:,Kmm) , puu(:,:,:,Krhs), pvv(:,:,:,Krhs) )   ! total vorticity trend
+               IF( ln_stcor .AND. .NOT. ln_vortex_force )  THEN
+                             CALL vor_eeT_hls1( kt, Kmm, ncor, usd, vsd, puu(:,:,:,Krhs), pvv(:,:,:,Krhs) )   ! add the Stokes-Coriolis trend
+               ELSE IF( ln_stcor .AND. ln_vortex_force )   THEN
+                             CALL vor_eeT_hls1( kt, Kmm, ntot, usd, vsd, puu(:,:,:,Krhs), pvv(:,:,:,Krhs) )   ! add the Stokes-Coriolis trend and vortex force
+               ENDIF
+            ELSE
                              CALL vor_eeT( kt, Kmm, ntot, puu(:,:,:,Kmm) , pvv(:,:,:,Kmm) , puu(:,:,:,Krhs), pvv(:,:,:,Krhs) )   ! total vorticity trend
-            IF( ln_stcor .AND. .NOT. ln_vortex_force )  THEN
+               IF( ln_stcor .AND. .NOT. ln_vortex_force )  THEN
                              CALL vor_eeT( kt, Kmm, ncor, usd, vsd, puu(:,:,:,Krhs), pvv(:,:,:,Krhs) )   ! add the Stokes-Coriolis trend
-            ELSE IF( ln_stcor .AND. ln_vortex_force )   THEN
+               ELSE IF( ln_stcor .AND. ln_vortex_force )   THEN
                              CALL vor_eeT( kt, Kmm, ntot, usd, vsd, puu(:,:,:,Krhs), pvv(:,:,:,Krhs) )   ! add the Stokes-Coriolis trend and vortex force
+               ENDIF
             ENDIF
          CASE( np_ENE )                        !* energy conserving scheme
                              CALL vor_ene( kt, Kmm, ntot, puu(:,:,:,Kmm) , pvv(:,:,:,Kmm) , puu(:,:,:,Krhs), pvv(:,:,:,Krhs) )   ! total vorticity trend
@@ -199,11 +209,20 @@ CONTAINS
             IF( ln_stcor )        CALL vor_ene( kt, Kmm, ncor, usd, vsd, puu(:,:,:,Krhs), pvv(:,:,:,Krhs) )        ! add the Stokes-Coriolis trend
             IF( ln_vortex_force ) CALL vor_ens( kt, Kmm, nrvm, usd, vsd, puu(:,:,:,Krhs), pvv(:,:,:,Krhs) )   ! add vortex force
          CASE( np_EEN )                        !* energy and enstrophy conserving scheme
+            IF( nn_hls == 1 ) THEN
+                             CALL vor_een_hls1( kt, Kmm, ntot, puu(:,:,:,Kmm) , pvv(:,:,:,Kmm) , puu(:,:,:,Krhs), pvv(:,:,:,Krhs) )   ! total vorticity trend
+               IF( ln_stcor .AND. .NOT. ln_vortex_force )  THEN
+                             CALL vor_een_hls1( kt, Kmm, ncor, usd, vsd, puu(:,:,:,Krhs), pvv(:,:,:,Krhs) )   ! add the Stokes-Coriolis trend
+               ELSE IF( ln_stcor .AND. ln_vortex_force )   THEN
+                             CALL vor_een_hls1( kt, Kmm, ntot, usd, vsd, puu(:,:,:,Krhs), pvv(:,:,:,Krhs) )   ! add the Stokes-Coriolis trend and vortex force
+               ENDIF
+            ELSE
                              CALL vor_een( kt, Kmm, ntot, puu(:,:,:,Kmm) , pvv(:,:,:,Kmm) , puu(:,:,:,Krhs), pvv(:,:,:,Krhs) )   ! total vorticity trend
-            IF( ln_stcor .AND. .NOT. ln_vortex_force )  THEN
+               IF( ln_stcor .AND. .NOT. ln_vortex_force )  THEN
                              CALL vor_een( kt, Kmm, ncor, usd, vsd, puu(:,:,:,Krhs), pvv(:,:,:,Krhs) )   ! add the Stokes-Coriolis trend
-            ELSE IF( ln_stcor .AND. ln_vortex_force )   THEN
+               ELSE IF( ln_stcor .AND. ln_vortex_force )   THEN
                              CALL vor_een( kt, Kmm, ntot, usd, vsd, puu(:,:,:,Krhs), pvv(:,:,:,Krhs) )   ! add the Stokes-Coriolis trend and vortex force
+               ENDIF
             ENDIF
          END SELECT
          !
@@ -320,7 +339,122 @@ CONTAINS
       !
       INTEGER  ::   ji, jj, jk           ! dummy loop indices
       REAL(wp) ::   zx1, zy1, zx2, zy2   ! local scalars
-      REAL(wp), DIMENSION(A2D(nn_hls))        ::   zwx, zwy, zwt   ! 2D workspace
+      REAL(wp), DIMENSION(A2D(1))           ::   zwx, zwy, zwt   ! 2D workspace
+      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zwz             ! 3D workspace, jpkm1 -> avoid lbc_lnk on jpk that is not defined
+      !!----------------------------------------------------------------------
+      !
+      IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+         IF( kt == nit000 ) THEN
+            IF(lwp) WRITE(numout,*)
+            IF(lwp) WRITE(numout,*) 'dyn:vor_enT : vorticity term: t-point energy conserving scheme'
+            IF(lwp) WRITE(numout,*) '~~~~~~~~~~~'
+         ENDIF
+      ENDIF
+      !
+      !
+      !                                                ! ===============
+      DO jk = 1, jpkm1                                 ! Horizontal slab
+         !                                             ! ===============
+         !
+         SELECT CASE( kvor )                 !== relative vorticity considered  ==!
+            !
+         CASE ( np_RVO , np_CRV )                  !* relative vorticity at f-point is used
+            ALLOCATE( zwz(A2D(1)) )
+            DO_2D( 1, 1, 1, 1 )
+               zwz(ji,jj) = (  e2v(ji+1,jj) * pv(ji+1,jj,jk) - e2v(ji,jj) * pv(ji,jj,jk)  &
+                  &          - e1u(ji,jj+1) * pu(ji,jj+1,jk) + e1u(ji,jj) * pu(ji,jj,jk)  ) * r1_e1e2f(ji,jj)
+            END_2D
+            IF( ln_dynvor_msk ) THEN                     ! mask relative vorticity
+               DO_2D( 1, 1, 1, 1 )
+                  zwz(ji,jj) = zwz(ji,jj) * fmask(ji,jj,jk)
+               END_2D
+            ENDIF
+            !
+         END SELECT
+         !
+         SELECT CASE( kvor )                 !==  volume weighted vorticity considered  ==!
+         !
+         CASE ( np_COR )                           !* Coriolis (planetary vorticity)
+            DO_2D( 0, 1, 0, 1 )
+               zwt(ji,jj) = ff_t(ji,jj) * e1e2t(ji,jj)*e3t(ji,jj,jk,Kmm)
+            END_2D
+         CASE ( np_RVO )                           !* relative vorticity
+            DO_2D( 0, 1, 0, 1 )
+               zwt(ji,jj) = r1_4 * (   zwz(ji-1,jj  ) + zwz(ji,jj  )       &
+                  &                  + zwz(ji-1,jj-1) + zwz(ji,jj-1)   )   &
+                  &              * e1e2t(ji,jj)*e3t(ji,jj,jk,Kmm)
+            END_2D
+         CASE ( np_MET )                           !* metric term
+            DO_2D( 0, 1, 0, 1 )
+               zwt(ji,jj) = (   ( pv(ji,jj,jk) + pv(ji,jj-1,jk) ) * di_e2u_2(ji,jj)       &
+                  &           - ( pu(ji,jj,jk) + pu(ji-1,jj,jk) ) * dj_e1v_2(ji,jj)   )   &
+                  &       * e3t(ji,jj,jk,Kmm)
+            END_2D
+         CASE ( np_CRV )                           !* Coriolis + relative vorticity
+            DO_2D( 0, 1, 0, 1 )
+               zwt(ji,jj) = (  ff_t(ji,jj) + r1_4 * ( zwz(ji-1,jj  ) + zwz(ji,jj  )        &
+                  &                                 + zwz(ji-1,jj-1) + zwz(ji,jj-1) )  )   &
+                  &       * e1e2t(ji,jj)*e3t(ji,jj,jk,Kmm)
+            END_2D
+         CASE ( np_CME )                           !* Coriolis + metric
+            DO_2D( 0, 1, 0, 1 )
+               zwt(ji,jj) = (  ff_t(ji,jj) * e1e2t(ji,jj)                               &
+                    &        + ( pv(ji,jj,jk) + pv(ji,jj-1,jk) ) * di_e2u_2(ji,jj)      &
+                    &        - ( pu(ji,jj,jk) + pu(ji-1,jj,jk) ) * dj_e1v_2(ji,jj)  )   &
+                    &     * e3t(ji,jj,jk,Kmm)
+            END_2D
+         CASE DEFAULT                                             ! error
+            CALL ctl_stop('STOP','dyn_vor: wrong value for kvor')
+         END SELECT
+         !
+         !                                   !==  compute and add the vorticity term trend  =!
+         DO_2D( 0, 0, 0, 0 )
+            pu_rhs(ji,jj,jk) = pu_rhs(ji,jj,jk) + r1_4 * r1_e1e2u(ji,jj) / e3u(ji,jj,jk,Kmm)                    &
+               &                                * (  zwt(ji+1,jj) * ( pv(ji+1,jj,jk) + pv(ji+1,jj-1,jk) )   &
+               &                                   + zwt(ji  ,jj) * ( pv(ji  ,jj,jk) + pv(ji  ,jj-1,jk) )   )
+               !
+            pv_rhs(ji,jj,jk) = pv_rhs(ji,jj,jk) - r1_4 * r1_e1e2v(ji,jj) / e3v(ji,jj,jk,Kmm)                    &
+               &                                * (  zwt(ji,jj+1) * ( pu(ji,jj+1,jk) + pu(ji-1,jj+1,jk) )   &
+               &                                   + zwt(ji,jj  ) * ( pu(ji,jj  ,jk) + pu(ji-1,jj  ,jk) )   )
+         END_2D
+         !                                             ! ===============
+      END DO                                           !   End of slab
+      !                                                ! ===============
+      !
+      SELECT CASE( kvor )        ! deallocate zwz if necessary
+      CASE ( np_RVO , np_CRV )   ;   DEALLOCATE( zwz )
+      END SELECT
+      !
+   END SUBROUTINE vor_enT
+
+
+   SUBROUTINE vor_enT_hls1( kt, Kmm, kvor, pu, pv, pu_rhs, pv_rhs )
+      !!----------------------------------------------------------------------
+      !!                  ***  ROUTINE vor_enT  ***
+      !!
+      !! ** Purpose :   Compute the now total vorticity trend and add it to
+      !!      the general trend of the momentum equation.
+      !!
+      !! ** Method  :   Trend evaluated using now fields (centered in time)
+      !!       and t-point evaluation of vorticity (planetary and relative).
+      !!       conserves the horizontal kinetic energy.
+      !!         The general trend of momentum is increased due to the vorticity
+      !!       term which is given by:
+      !!          voru = 1/bu  mj[ ( mi(mj(bf*rvor))+bt*f_t)/e3t  mj[vn] ]
+      !!          vorv = 1/bv  mi[ ( mi(mj(bf*rvor))+bt*f_t)/e3f  mj[un] ]
+      !!       where rvor is the relative vorticity at f-point
+      !!
+      !! ** Action : - Update (pu_rhs,pv_rhs) with the now vorticity term trend
+      !!----------------------------------------------------------------------
+      INTEGER                         , INTENT(in   ) ::   kt               ! ocean time-step index
+      INTEGER                         , INTENT(in   ) ::   Kmm              ! ocean time level index
+      INTEGER                         , INTENT(in   ) ::   kvor             ! total, planetary, relative, or metric
+      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   pu, pv           ! now velocities
+      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   pu_rhs, pv_rhs   ! total v-trend
+      !
+      INTEGER  ::   ji, jj, jk           ! dummy loop indices
+      REAL(wp) ::   zx1, zy1, zx2, zy2   ! local scalars
+      REAL(wp), DIMENSION(A2D(1))             ::   zwx, zwy, zwt   ! 2D workspace
       REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) ::   zwz             ! 3D workspace, jpkm1 -> avoid lbc_lnk on jpk that is not defined
       !!----------------------------------------------------------------------
       !
@@ -336,7 +470,7 @@ CONTAINS
       SELECT CASE( kvor )                 !== relative vorticity considered  ==!
       !
       CASE ( np_RVO , np_CRV )                  !* relative vorticity at f-point is used
-         ALLOCATE( zwz(A2D(nn_hls),jpk) )
+         ALLOCATE( zwz(A2D(1),jpk) )
          DO jk = 1, jpkm1                                ! Horizontal slab
             DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
                zwz(ji,jj,jk) = (  e2v(ji+1,jj) * pv(ji+1,jj,jk) - e2v(ji,jj) * pv(ji,jj,jk)  &
@@ -409,7 +543,7 @@ CONTAINS
       CASE ( np_RVO , np_CRV )   ;   DEALLOCATE( zwz )
       END SELECT
       !
-   END SUBROUTINE vor_enT
+   END SUBROUTINE vor_enT_hls1
 
 
    SUBROUTINE vor_ene( kt, Kmm, kvor, pu, pv, pu_rhs, pv_rhs )
@@ -440,7 +574,7 @@ CONTAINS
       !
       INTEGER  ::   ji, jj, jk           ! dummy loop indices
       REAL(wp) ::   zx1, zy1, zx2, zy2, ze3f, zmsk   ! local scalars
-      REAL(wp), DIMENSION(A2D(nn_hls)) ::   zwx, zwy, zwz   ! 2D workspace
+      REAL(wp), DIMENSION(A2D(1)) ::   zwx, zwy, zwz   ! 2D workspace
       !!----------------------------------------------------------------------
       !
       IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
@@ -573,7 +707,7 @@ CONTAINS
       !
       INTEGER  ::   ji, jj, jk   ! dummy loop indices
       REAL(wp) ::   zuav, zvau, ze3f, zmsk   ! local scalars
-      REAL(wp), DIMENSION(A2D(nn_hls)) ::   zwx, zwy, zwz   ! 2D workspace
+      REAL(wp), DIMENSION(A2D(1)) ::   zwx, zwy, zwz   ! 2D workspace
       !!----------------------------------------------------------------------
       !
       IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
@@ -705,16 +839,176 @@ CONTAINS
       INTEGER  ::   ierr         ! local integer
       REAL(wp) ::   zua, zva     ! local scalars
       REAL(wp) ::   zmsk, ze3f   ! local scalars
-      REAL(wp), DIMENSION(A2D(nn_hls))       ::   z1_e3f
+      REAL(wp), DIMENSION(A2D(1))       ::   z1_e3f
 #if defined key_loop_fusion
       REAL(wp) ::   ztne, ztnw, ztnw_ip1, ztse, ztse_jp1, ztsw_jp1, ztsw_ip1
       REAL(wp) ::   zwx, zwx_im1, zwx_jp1, zwx_im1_jp1
       REAL(wp) ::   zwy, zwy_ip1, zwy_jm1, zwy_ip1_jm1
 #else
-      REAL(wp), DIMENSION(A2D(nn_hls))       ::   zwx , zwy
-      REAL(wp), DIMENSION(A2D(nn_hls))       ::   ztnw, ztne, ztsw, ztse
+      REAL(wp), DIMENSION(A2D(1)) ::   zwx , zwy
+      REAL(wp), DIMENSION(A2D(1)) ::   ztnw, ztne, ztsw, ztse
 #endif
-      REAL(wp), DIMENSION(A2D(nn_hls),jpkm1) ::   zwz   ! 3D workspace, jpkm1 -> jpkm1 -> avoid lbc_lnk on jpk that is not defined
+      REAL(wp), DIMENSION(A2D(1)) ::   zwz   ! 3D workspace, jpkm1 -> jpkm1 -> avoid lbc_lnk on jpk that is not defined
+      !!----------------------------------------------------------------------
+      !
+      IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+         IF( kt == nit000 ) THEN
+            IF(lwp) WRITE(numout,*)
+            IF(lwp) WRITE(numout,*) 'dyn:vor_een : vorticity term: energy and enstrophy conserving scheme'
+            IF(lwp) WRITE(numout,*) '~~~~~~~~~~~'
+         ENDIF
+      ENDIF
+      !
+      !                                                ! ===============
+      DO jk = 1, jpkm1                                 ! Horizontal slab
+         !                                             ! ===============
+         !
+#if defined key_qco   ||   defined key_linssh
+         DO_2D( 1, 1, 1, 1 )                 ! == reciprocal of e3 at F-point (key_qco)
+            z1_e3f(ji,jj) = 1._wp / e3f_vor(ji,jj,jk)
+         END_2D
+#else
+         SELECT CASE( nn_e3f_typ )           ! == reciprocal of e3 at F-point
+         CASE ( 0 )                                   ! original formulation  (masked averaging of e3t divided by 4)
+            DO_2D( 1, 1, 1, 1 )
+               ! round brackets added to fix the order of floating point operations
+               ! needed to ensure halo 1 - halo 2 compatibility
+               ze3f = (  (e3t(ji  ,jj+1,jk,Kmm)*tmask(ji  ,jj+1,jk)    &
+                  &    +  e3t(ji+1,jj+1,jk,Kmm)*tmask(ji+1,jj+1,jk))   &
+                  &    + (e3t(ji  ,jj  ,jk,Kmm)*tmask(ji  ,jj  ,jk)    &
+                  &    +  e3t(ji+1,jj  ,jk,Kmm)*tmask(ji+1,jj  ,jk))  )
+               IF( ze3f /= 0._wp ) THEN   ;   z1_e3f(ji,jj) = 4._wp / ze3f
+               ELSE                       ;   z1_e3f(ji,jj) = 0._wp
+               ENDIF
+            END_2D
+         CASE ( 1 )                                   ! new formulation  (masked averaging of e3t divided by the sum of mask)
+            DO_2D( 1, 1, 1, 1 )
+               ! round brackets added to fix the order of floating point operations
+               ! needed to ensure halo 1 - halo 2 compatibility
+               ze3f = (  (e3t(ji  ,jj+1,jk,Kmm)*tmask(ji  ,jj+1,jk)    &
+                  &    +  e3t(ji+1,jj+1,jk,Kmm)*tmask(ji+1,jj+1,jk))   &
+                  &    + (e3t(ji  ,jj  ,jk,Kmm)*tmask(ji  ,jj  ,jk)    &
+                  &    +  e3t(ji+1,jj  ,jk,Kmm)*tmask(ji+1,jj  ,jk))  )
+               zmsk = (                    tmask(ji,jj+1,jk) +                     tmask(ji+1,jj+1,jk)   &
+                  &                      + tmask(ji,jj  ,jk) +                     tmask(ji+1,jj  ,jk)  )
+               IF( ze3f /= 0._wp ) THEN   ;   z1_e3f(ji,jj) = zmsk / ze3f
+               ELSE                       ;   z1_e3f(ji,jj) = 0._wp
+               ENDIF
+            END_2D
+         END SELECT
+#endif
+         !
+         SELECT CASE( kvor )                 !==  vorticity considered  ==!
+         !
+         CASE ( np_COR )                           !* Coriolis (planetary vorticity)
+            DO_2D( 1, 1, 1, 1 )
+               zwz(ji,jj) = ff_f(ji,jj) * z1_e3f(ji,jj)
+            END_2D
+         CASE ( np_RVO )                           !* relative vorticity
+            DO_2D( 1, 1, 1, 1 )
+               zwz(ji,jj) = ( e2v(ji+1,jj  ) * pv(ji+1,jj,jk) - e2v(ji,jj) * pv(ji,jj,jk)  &
+                  &         - e1u(ji  ,jj+1) * pu(ji,jj+1,jk) + e1u(ji,jj) * pu(ji,jj,jk)  ) * r1_e1e2f(ji,jj)*z1_e3f(ji,jj)
+            END_2D
+            IF( ln_dynvor_msk ) THEN                     ! mask the relative vorticity
+               DO_2D( 1, 1, 1, 1 )
+                  zwz(ji,jj) = zwz(ji,jj) * fmask(ji,jj,jk)
+               END_2D
+            ENDIF
+         CASE ( np_MET )                           !* metric term
+            DO_2D( 1, 1, 1, 1 )
+               zwz(ji,jj) = (   ( pv(ji+1,jj,jk) + pv(ji,jj,jk) ) * di_e2v_2e1e2f(ji,jj)   &
+                  &           - ( pu(ji,jj+1,jk) + pu(ji,jj,jk) ) * dj_e1u_2e1e2f(ji,jj)   ) * z1_e3f(ji,jj)
+            END_2D
+         CASE ( np_CRV )                           !* Coriolis + relative vorticity
+            DO_2D( 1, 1, 1, 1 )
+            ! round brackets added to fix the order of floating point operations
+            ! needed to ensure halo 1 - halo 2 compatibility
+               zwz(ji,jj) = (  ff_f(ji,jj) + ( ( e2v(ji+1,jj  ) * pv(ji+1,jj,jk) - e2v(ji,jj) * pv(ji,jj,jk)      &
+                  &                            )                                                                  & ! bracket for halo 1 - halo 2 compatibility
+                  &                          - ( e1u(ji  ,jj+1) * pu(ji,jj+1,jk) - e1u(ji,jj) * pu(ji,jj,jk)      &
+                  &                            )                                                                  & ! bracket for halo 1 - halo 2 compatibility
+                  &                          ) * r1_e1e2f(ji,jj)   ) * z1_e3f(ji,jj)
+            END_2D
+            IF( ln_dynvor_msk ) THEN                     ! mask the relative vorticity
+               DO_2D( 1, 1, 1, 1 )
+                  zwz(ji,jj) = ( zwz(ji,jj) - ff_f(ji,jj) ) * fmask(ji,jj,jk) + ff_f(ji,jj)
+               END_2D
+            ENDIF
+         CASE ( np_CME )                           !* Coriolis + metric
+            DO_2D( 1, 1, 1, 1 )
+               zwz(ji,jj) = (   ff_f(ji,jj) + ( pv(ji+1,jj  ,jk) + pv(ji,jj,jk) ) * di_e2v_2e1e2f(ji,jj)   &
+                  &                         - ( pu(ji  ,jj+1,jk) + pu(ji,jj,jk) ) * dj_e1u_2e1e2f(ji,jj)   ) * z1_e3f(ji,jj)
+            END_2D
+         CASE DEFAULT                                             ! error
+            CALL ctl_stop('STOP','dyn_vor: wrong value for kvor'  )
+         END SELECT
+         !
+         !                                   !==  horizontal fluxes  ==!
+         DO_2D( 1, 1, 1, 1 )
+            zwx(ji,jj) = e2u(ji,jj) * e3u(ji,jj,jk,Kmm) * pu(ji,jj,jk)
+            zwy(ji,jj) = e1v(ji,jj) * e3v(ji,jj,jk,Kmm) * pv(ji,jj,jk)
+         END_2D
+         !
+         !                                   !==  compute and add the vorticity term trend  =!
+         DO_2D( 0, 1, 0, 1 )
+            ztne(ji,jj) = zwz(ji-1,jj  ) + zwz(ji  ,jj  ) + zwz(ji  ,jj-1)
+            ztnw(ji,jj) = zwz(ji-1,jj-1) + zwz(ji-1,jj  ) + zwz(ji  ,jj  )
+            ztse(ji,jj) = zwz(ji  ,jj  ) + zwz(ji  ,jj-1) + zwz(ji-1,jj-1)
+            ztsw(ji,jj) = zwz(ji  ,jj-1) + zwz(ji-1,jj-1) + zwz(ji-1,jj  )
+         END_2D
+         !
+         DO_2D( 0, 0, 0, 0 )
+            zua = + r1_12 * r1_e1u(ji,jj) * (  ztne(ji,jj  ) * zwy(ji  ,jj  ) + ztnw(ji+1,jj) * zwy(ji+1,jj  )   &
+               &                             + ztse(ji,jj  ) * zwy(ji  ,jj-1) + ztsw(ji+1,jj) * zwy(ji+1,jj-1) )
+            zva = - r1_12 * r1_e2v(ji,jj) * (  ztsw(ji,jj+1) * zwx(ji-1,jj+1) + ztse(ji,jj+1) * zwx(ji  ,jj+1)   &
+               &                             + ztnw(ji,jj  ) * zwx(ji-1,jj  ) + ztne(ji,jj  ) * zwx(ji  ,jj  ) )
+            pu_rhs(ji,jj,jk) = pu_rhs(ji,jj,jk) + zua
+            pv_rhs(ji,jj,jk) = pv_rhs(ji,jj,jk) + zva
+         END_2D
+      END DO
+      !                                                ! ===============
+      !                                                !   End of slab
+      !                                                ! ===============
+   END SUBROUTINE vor_een
+
+
+   SUBROUTINE vor_een_hls1( kt, Kmm, kvor, pu, pv, pu_rhs, pv_rhs )
+      !!----------------------------------------------------------------------
+      !!                ***  ROUTINE vor_een  ***
+      !!
+      !! ** Purpose :   Compute the now total vorticity trend and add it to
+      !!      the general trend of the momentum equation.
+      !!
+      !! ** Method  :   Trend evaluated using now fields (centered in time)
+      !!      and the Arakawa and Lamb (1980) flux form formulation : conserves
+      !!      both the horizontal kinetic energy and the potential enstrophy
+      !!      when horizontal divergence is zero (see the NEMO documentation)
+      !!      Add this trend to the general momentum trend (pu_rhs,pv_rhs).
+      !!
+      !! ** Action : - Update (pu_rhs,pv_rhs) with the now vorticity term trend
+      !!
+      !! References : Arakawa and Lamb 1980, Mon. Wea. Rev., 109, 18-36
+      !!----------------------------------------------------------------------
+      INTEGER                         , INTENT(in   ) ::   kt          ! ocean time-step index
+      INTEGER                         , INTENT(in   ) ::   Kmm              ! ocean time level index
+      INTEGER                         , INTENT(in   ) ::   kvor        ! total, planetary, relative, or metric
+      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   pu, pv    ! now velocities
+      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   pu_rhs, pv_rhs    ! total v-trend
+      !
+      INTEGER  ::   ji, jj, jk   ! dummy loop indices
+      INTEGER  ::   ierr         ! local integer
+      REAL(wp) ::   zua, zva     ! local scalars
+      REAL(wp) ::   zmsk, ze3f   ! local scalars
+      REAL(wp), DIMENSION(A2D(1))       ::   z1_e3f
+#if defined key_loop_fusion
+      REAL(wp) ::   ztne, ztnw, ztnw_ip1, ztse, ztse_jp1, ztsw_jp1, ztsw_ip1
+      REAL(wp) ::   zwx, zwx_im1, zwx_jp1, zwx_im1_jp1
+      REAL(wp) ::   zwy, zwy_ip1, zwy_jm1, zwy_ip1_jm1
+#else
+      REAL(wp), DIMENSION(A2D(1))       ::   zwx , zwy
+      REAL(wp), DIMENSION(A2D(1))       ::   ztnw, ztne, ztsw, ztse
+#endif
+      REAL(wp), DIMENSION(A2D(1),jpkm1) ::   zwz   ! 3D workspace, jpkm1 -> jpkm1 -> avoid lbc_lnk on jpk that is not defined
       !!----------------------------------------------------------------------
       !
       IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
@@ -874,7 +1168,7 @@ CONTAINS
          !                                             ! ===============
          !                                             !   End of slab
       !                                                ! ===============
-   END SUBROUTINE vor_een
+   END SUBROUTINE vor_een_hls1
 
 
    SUBROUTINE vor_eeT( kt, Kmm, kvor, pu, pv, pu_rhs, pv_rhs )
@@ -904,9 +1198,129 @@ CONTAINS
       INTEGER  ::   ierr           ! local integer
       REAL(wp) ::   zua, zva       ! local scalars
       REAL(wp) ::   zmsk, z1_e3t   ! local scalars
-      REAL(wp), DIMENSION(A2D(nn_hls))       ::   zwx , zwy
-      REAL(wp), DIMENSION(A2D(nn_hls))       ::   ztnw, ztne, ztsw, ztse
-      REAL(wp), DIMENSION(A2D(nn_hls),jpkm1) ::   zwz   ! 3D workspace, avoid lbc_lnk on jpk that is not defined
+      REAL(wp), DIMENSION(A2D(1)) ::   zwx , zwy
+      REAL(wp), DIMENSION(A2D(1)) ::   ztnw, ztne, ztsw, ztse
+      REAL(wp), DIMENSION(A2D(1)) ::   zwz   ! 3D workspace, avoid lbc_lnk on jpk that is not defined
+      !!----------------------------------------------------------------------
+      !
+      IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+         IF( kt == nit000 ) THEN
+            IF(lwp) WRITE(numout,*)
+            IF(lwp) WRITE(numout,*) 'dyn:vor_eeT : vorticity term: energy and enstrophy conserving scheme'
+            IF(lwp) WRITE(numout,*) '~~~~~~~~~~~'
+         ENDIF
+      ENDIF
+      !
+      !                                                ! ===============
+      DO jk = 1, jpkm1                                 ! Horizontal slab
+         !                                             ! ===============
+         !
+         !
+         SELECT CASE( kvor )                 !==  vorticity considered  ==!
+         CASE ( np_COR )                           !* Coriolis (planetary vorticity)
+            DO_2D( 1, 1, 1, 1 )
+               zwz(ji,jj) = ff_f(ji,jj)
+            END_2D
+         CASE ( np_RVO )                           !* relative vorticity
+            DO_2D( 1, 1, 1, 1 )
+               ! round brackets added to fix the order of floating point operations
+               ! needed to ensure halo 1 - halo 2 compatibility
+               zwz(ji,jj) = (  (e2v(ji+1,jj  ) * pv(ji+1,jj  ,jk) - e2v(ji,jj) * pv(ji,jj,jk))    &
+                  &          - (e1u(ji  ,jj+1) * pu(ji  ,jj+1,jk) - e1u(ji,jj) * pu(ji,jj,jk))  ) &
+                  &       * r1_e1e2f(ji,jj)
+            END_2D
+            IF( ln_dynvor_msk ) THEN                     ! mask the relative vorticity
+               DO_2D( 1, 1, 1, 1 )
+                  zwz(ji,jj) = zwz(ji,jj) * fmask(ji,jj,jk)
+               END_2D
+            ENDIF
+         CASE ( np_MET )                           !* metric term
+            DO_2D( 1, 1, 1, 1 )
+               zwz(ji,jj) = ( pv(ji+1,jj  ,jk) + pv(ji,jj,jk) ) * di_e2v_2e1e2f(ji,jj)   &
+                  &       - ( pu(ji  ,jj+1,jk) + pu(ji,jj,jk) ) * dj_e1u_2e1e2f(ji,jj)
+            END_2D
+         CASE ( np_CRV )                           !* Coriolis + relative vorticity
+            DO_2D( 1, 1, 1, 1 )
+               ! round brackets added to fix the order of floating point operations
+               ! needed to ensure halo 1 - halo 2 compatibility
+               zwz(ji,jj) = (  ff_f(ji,jj) + (  (e2v(ji+1,jj  ) * pv(ji+1,jj  ,jk) - e2v(ji,jj) * pv(ji,jj,jk))    &
+                  &                           - (e1u(ji  ,jj+1) * pu(ji  ,jj+1,jk) - e1u(ji,jj) * pu(ji,jj,jk))  ) &
+                  &                        * r1_e1e2f(ji,jj)    )
+            END_2D
+            IF( ln_dynvor_msk ) THEN                     ! mask the relative vorticity
+               DO_2D( 1, 1, 1, 1 )
+                  zwz(ji,jj) = ( zwz(ji,jj) - ff_f(ji,jj) ) * fmask(ji,jj,jk) + ff_f(ji,jj)
+               END_2D
+            ENDIF
+         CASE ( np_CME )                           !* Coriolis + metric
+            DO_2D( 1, 1, 1, 1 )
+               zwz(ji,jj) = ff_f(ji,jj) + ( pv(ji+1,jj  ,jk) + pv(ji,jj,jk) ) * di_e2v_2e1e2f(ji,jj)   &
+                  &                     - ( pu(ji  ,jj+1,jk) + pu(ji,jj,jk) ) * dj_e1u_2e1e2f(ji,jj)
+            END_2D
+         CASE DEFAULT                                             ! error
+            CALL ctl_stop('STOP','dyn_vor: wrong value for kvor'  )
+         END SELECT
+         !
+         !
+         !                                   !==  horizontal fluxes  ==!
+         DO_2D( 1, 1, 1, 1 )
+            zwx(ji,jj) = e2u(ji,jj) * e3u(ji,jj,jk,Kmm) * pu(ji,jj,jk)
+            zwy(ji,jj) = e1v(ji,jj) * e3v(ji,jj,jk,Kmm) * pv(ji,jj,jk)
+         END_2D
+         !
+         !                                   !==  compute and add the vorticity term trend  =!
+         DO_2D( 0, 1, 0, 1 )
+            z1_e3t = 1._wp / e3t(ji,jj,jk,Kmm)
+            ztne(ji,jj) = ( zwz(ji-1,jj  ) + zwz(ji  ,jj  ) + zwz(ji  ,jj-1) ) * z1_e3t
+            ztnw(ji,jj) = ( zwz(ji-1,jj-1) + zwz(ji-1,jj  ) + zwz(ji  ,jj  ) ) * z1_e3t
+            ztse(ji,jj) = ( zwz(ji  ,jj  ) + zwz(ji  ,jj-1) + zwz(ji-1,jj-1) ) * z1_e3t
+            ztsw(ji,jj) = ( zwz(ji  ,jj-1) + zwz(ji-1,jj-1) + zwz(ji-1,jj  ) ) * z1_e3t
+         END_2D
+         !
+         DO_2D( 0, 0, 0, 0 )
+            zua = + r1_12 * r1_e1u(ji,jj) * (  ztne(ji,jj  ) * zwy(ji  ,jj  ) + ztnw(ji+1,jj) * zwy(ji+1,jj  )   &
+               &                             + ztse(ji,jj  ) * zwy(ji  ,jj-1) + ztsw(ji+1,jj) * zwy(ji+1,jj-1) )
+            zva = - r1_12 * r1_e2v(ji,jj) * (  ztsw(ji,jj+1) * zwx(ji-1,jj+1) + ztse(ji,jj+1) * zwx(ji  ,jj+1)   &
+               &                             + ztnw(ji,jj  ) * zwx(ji-1,jj  ) + ztne(ji,jj  ) * zwx(ji  ,jj  ) )
+            pu_rhs(ji,jj,jk) = pu_rhs(ji,jj,jk) + zua
+            pv_rhs(ji,jj,jk) = pv_rhs(ji,jj,jk) + zva
+         END_2D
+         !                                             ! ===============
+      END DO                                           !   End of slab
+      !                                                ! ===============
+   END SUBROUTINE vor_eeT
+
+
+   SUBROUTINE vor_eeT_hls1( kt, Kmm, kvor, pu, pv, pu_rhs, pv_rhs )
+      !!----------------------------------------------------------------------
+      !!                ***  ROUTINE vor_eeT  ***
+      !!
+      !! ** Purpose :   Compute the now total vorticity trend and add it to
+      !!      the general trend of the momentum equation.
+      !!
+      !! ** Method  :   Trend evaluated using now fields (centered in time)
+      !!      and the Arakawa and Lamb (1980) vector form formulation using
+      !!      a modified version of Arakawa and Lamb (1980) scheme (see vor_een).
+      !!      The change consists in
+      !!      Add this trend to the general momentum trend (pu_rhs,pv_rhs).
+      !!
+      !! ** Action : - Update (pu_rhs,pv_rhs) with the now vorticity term trend
+      !!
+      !! References : Arakawa and Lamb 1980, Mon. Wea. Rev., 109, 18-36
+      !!----------------------------------------------------------------------
+      INTEGER                         , INTENT(in   ) ::   kt               ! ocean time-step index
+      INTEGER                         , INTENT(in   ) ::   Kmm              ! ocean time level index
+      INTEGER                         , INTENT(in   ) ::   kvor             ! total, planetary, relative, or metric
+      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   pu, pv           ! now velocities
+      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   pu_rhs, pv_rhs   ! total v-trend
+      !
+      INTEGER  ::   ji, jj, jk     ! dummy loop indices
+      INTEGER  ::   ierr           ! local integer
+      REAL(wp) ::   zua, zva       ! local scalars
+      REAL(wp) ::   zmsk, z1_e3t   ! local scalars
+      REAL(wp), DIMENSION(A2D(1))       ::   zwx , zwy
+      REAL(wp), DIMENSION(A2D(1))       ::   ztnw, ztne, ztsw, ztse
+      REAL(wp), DIMENSION(A2D(1),jpkm1) ::   zwz   ! 3D workspace, avoid lbc_lnk on jpk that is not defined
       !!----------------------------------------------------------------------
       !
       IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
@@ -1003,7 +1417,7 @@ CONTAINS
          !                                             ! ===============
       END DO                                           !   End of slab
       !                                                ! ===============
-   END SUBROUTINE vor_eeT
+   END SUBROUTINE vor_eeT_hls1
 
 
    SUBROUTINE dyn_vor_init
diff --git a/src/OCE/DYN/dynzdf.F90 b/src/OCE/DYN/dynzdf.F90
index 98c65e4604e951f0119fbd4767381487ec3596a0..fed10f23182fea2131de19cd81d668d71ed3aec5 100644
--- a/src/OCE/DYN/dynzdf.F90
+++ b/src/OCE/DYN/dynzdf.F90
@@ -6,6 +6,7 @@ MODULE dynzdf
    !! History :  1.0  !  2005-11  (G. Madec)  Original code
    !!            3.3  !  2010-10  (C. Ethe, G. Madec) reorganisation of initialisation phase
    !!            4.0  !  2017-06  (G. Madec) remove the explicit time-stepping option + avm at t-point
+   !!            4.5  !  2022-06  (S. Techene, G, Madec) refactorization to reduce local memory usage
    !!----------------------------------------------------------------------
 
    !!----------------------------------------------------------------------
@@ -79,7 +80,7 @@ CONTAINS
       REAL(wp) ::   zWu , zWv            !   -      -
       REAL(wp) ::   zWui, zWvi           !   -      -
       REAL(wp) ::   zWus, zWvs           !   -      -
-      REAL(wp), DIMENSION(A2D(nn_hls),jpk)        ::  zwi, zwd, zws   ! 3D workspace
+      REAL(wp), DIMENSION(A1Di(0),jpk)        ::   zwi, zwd, zws  ! 2D workspace
       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::   ztrdu, ztrdv   !  -      -
       !!---------------------------------------------------------------------
       !
@@ -105,315 +106,329 @@ CONTAINS
          ztrdv(:,:,:) = pvv(:,:,:,Krhs)
       ENDIF
       !
-      !              !==  RHS: Leap-Frog time stepping on all trends but the vertical mixing  ==!   (put in puu(:,:,:,Kaa),pvv(:,:,:,Kaa))
-      !
-      !                    ! time stepping except vertical diffusion
-      IF( ln_dynadv_vec .OR. ln_linssh ) THEN   ! applied on velocity
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
-            puu(ji,jj,jk,Kaa) = ( puu(ji,jj,jk,Kbb) + rDt * puu(ji,jj,jk,Krhs) ) * umask(ji,jj,jk)
-            pvv(ji,jj,jk,Kaa) = ( pvv(ji,jj,jk,Kbb) + rDt * pvv(ji,jj,jk,Krhs) ) * vmask(ji,jj,jk)
-         END_3D
-      ELSE                                      ! applied on thickness weighted velocity
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
-            puu(ji,jj,jk,Kaa) = (         e3u(ji,jj,jk,Kbb) * puu(ji,jj,jk,Kbb )  &
-               &                  + rDt * e3u(ji,jj,jk,Kmm) * puu(ji,jj,jk,Krhs)  ) &
-               &                        / e3u(ji,jj,jk,Kaa) * umask(ji,jj,jk)
-            pvv(ji,jj,jk,Kaa) = (         e3v(ji,jj,jk,Kbb) * pvv(ji,jj,jk,Kbb )  &
-               &                  + rDt * e3v(ji,jj,jk,Kmm) * pvv(ji,jj,jk,Krhs)  ) &
-               &                        / e3v(ji,jj,jk,Kaa) * vmask(ji,jj,jk)
-         END_3D
-      ENDIF
-      !                    ! add top/bottom friction 
-      !     With split-explicit free surface, barotropic stress is treated explicitly Update velocities at the bottom.
-      !     J. Chanut: The bottom stress is computed considering after barotropic velocities, which does 
-      !                not lead to the effective stress seen over the whole barotropic loop. 
-      !     G. Madec : in linear free surface, e3u(:,:,:,Kaa) = e3u(:,:,:,Kmm) = e3u_0, so systematic use of e3u(:,:,:,Kaa)
-      IF( ln_drgimp .AND. ln_dynspg_ts ) THEN
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )      ! remove barotropic velocities
-            puu(ji,jj,jk,Kaa) = ( puu(ji,jj,jk,Kaa) - uu_b(ji,jj,Kaa) ) * umask(ji,jj,jk)
-            pvv(ji,jj,jk,Kaa) = ( pvv(ji,jj,jk,Kaa) - vv_b(ji,jj,Kaa) ) * vmask(ji,jj,jk)
-         END_3D
-         DO_2D( 0, 0, 0, 0 )      ! Add bottom/top stress due to barotropic component only
-            iku = mbku(ji,jj)         ! ocean bottom level at u- and v-points 
-            ikv = mbkv(ji,jj)         ! (deepest ocean u- and v-points)
-            puu(ji,jj,iku,Kaa) = puu(ji,jj,iku,Kaa) + zDt_2 *( rCdU_bot(ji+1,jj)+rCdU_bot(ji,jj) ) * uu_b(ji,jj,Kaa)   &
-               &                                            / e3u(ji,jj,iku,Kaa)
-            pvv(ji,jj,ikv,Kaa) = pvv(ji,jj,ikv,Kaa) + zDt_2 *( rCdU_bot(ji,jj+1)+rCdU_bot(ji,jj) ) * vv_b(ji,jj,Kaa)   &
-               &                                            / e3v(ji,jj,ikv,Kaa)
-         END_2D
-         IF( ln_isfcav.OR.ln_drgice_imp ) THEN    ! Ocean cavities (ISF)
-            DO_2D( 0, 0, 0, 0 )
-               iku = miku(ji,jj)         ! top ocean level at u- and v-points 
-               ikv = mikv(ji,jj)         ! (first wet ocean u- and v-points)
-               puu(ji,jj,iku,Kaa) = puu(ji,jj,iku,Kaa) + zDt_2 *( rCdU_top(ji+1,jj)+rCdU_top(ji,jj) ) * uu_b(ji,jj,Kaa)   &
+      !                                               ! ================= !
+      DO_1Dj( 0, 0 )                                  !  i-k slices loop  !
+         !                                            ! ================= !
+         !
+         !              !==  RHS: Leap-Frog time stepping on all trends but the vertical mixing  ==!   (put in puu(:,:,:,Kaa),pvv(:,:,:,Kaa))
+         !
+         !                    ! time stepping except vertical diffusion
+         IF( ln_dynadv_vec .OR. ln_linssh ) THEN   ! applied on velocity
+            DO_2Dik( 0, 0,    1, jpkm1, 1 )
+               puu(ji,jj,jk,Kaa) = ( puu(ji,jj,jk,Kbb) + rDt * puu(ji,jj,jk,Krhs) ) * umask(ji,jj,jk)
+               pvv(ji,jj,jk,Kaa) = ( pvv(ji,jj,jk,Kbb) + rDt * pvv(ji,jj,jk,Krhs) ) * vmask(ji,jj,jk)
+            END_2D
+         ELSE                                      ! applied on thickness weighted velocity
+            DO_2Dik( 0, 0,    1, jpkm1, 1 )
+               puu(ji,jj,jk,Kaa) = (         e3u(ji,jj,jk,Kbb) * puu(ji,jj,jk,Kbb )  &
+                  &                  + rDt * e3u(ji,jj,jk,Kmm) * puu(ji,jj,jk,Krhs)  ) &
+                  &                        / e3u(ji,jj,jk,Kaa) * umask(ji,jj,jk)
+               pvv(ji,jj,jk,Kaa) = (         e3v(ji,jj,jk,Kbb) * pvv(ji,jj,jk,Kbb )  &
+                  &                  + rDt * e3v(ji,jj,jk,Kmm) * pvv(ji,jj,jk,Krhs)  ) &
+                  &                        / e3v(ji,jj,jk,Kaa) * vmask(ji,jj,jk)
+            END_2D
+         ENDIF
+         !                    ! add top/bottom friction 
+         !     With split-explicit free surface, barotropic stress is treated explicitly Update velocities at the bottom.
+         !     J. Chanut: The bottom stress is computed considering after barotropic velocities, which does 
+         !                not lead to the effective stress seen over the whole barotropic loop. 
+         !     G. Madec : in linear free surface, e3u(:,:,:,Kaa) = e3u(:,:,:,Kmm) = e3u_0, so systematic use of e3u(:,:,:,Kaa)
+         IF( ln_drgimp .AND. ln_dynspg_ts ) THEN
+            DO_2Dik( 0, 0,     1, jpkm1, 1 )      ! remove barotropic velocities
+               puu(ji,jj,jk,Kaa) = ( puu(ji,jj,jk,Kaa) - uu_b(ji,jj,Kaa) ) * umask(ji,jj,jk)
+               pvv(ji,jj,jk,Kaa) = ( pvv(ji,jj,jk,Kaa) - vv_b(ji,jj,Kaa) ) * vmask(ji,jj,jk)
+            END_2D
+            DO_1Di( 0, 0 )      ! Add bottom/top stress due to barotropic component only
+               iku = mbku(ji,jj)         ! ocean bottom level at u- and v-points 
+               ikv = mbkv(ji,jj)         ! (deepest ocean u- and v-points)
+               puu(ji,jj,iku,Kaa) = puu(ji,jj,iku,Kaa) + zDt_2 *( rCdU_bot(ji+1,jj)+rCdU_bot(ji,jj) ) * uu_b(ji,jj,Kaa)   &
                   &                                            / e3u(ji,jj,iku,Kaa)
-               pvv(ji,jj,ikv,Kaa) = pvv(ji,jj,ikv,Kaa) + zDt_2 *( rCdU_top(ji,jj+1)+rCdU_top(ji,jj) ) * vv_b(ji,jj,Kaa)   &
+               pvv(ji,jj,ikv,Kaa) = pvv(ji,jj,ikv,Kaa) + zDt_2 *( rCdU_bot(ji,jj+1)+rCdU_bot(ji,jj) ) * vv_b(ji,jj,Kaa)   &
                   &                                            / e3v(ji,jj,ikv,Kaa)
-            END_2D
-         END IF
-      ENDIF
-      !
-      !              !==  Vertical diffusion on u  ==!
-      !
-      !                    !* Matrix construction
-      IF( ln_zad_Aimp ) THEN   !!
-         SELECT CASE( nldf_dyn )
-         CASE( np_lap_i )           ! rotated lateral mixing: add its vertical mixing (akzu)
-            DO_3D( 0, 0, 0, 0, 1, jpkm1 )
-               z1_e3ua =  1._wp  / e3u(ji,jj,jk,Kaa)   ! after scale factor at U-point
-               zzwi = - zDt_2 * ( avm(ji+1,jj,jk  ) + avm(ji,jj,jk  ) + akzu(ji,jj,jk  ) )   &
-                  &         / e3uw(ji,jj,jk  ,Kmm) * z1_e3ua * wumask(ji,jj,jk  )
-               zzws = - zDt_2 * ( avm(ji+1,jj,jk+1) + avm(ji,jj,jk+1) + akzu(ji,jj,jk+1) )   &
-                  &         / e3uw(ji,jj,jk+1,Kmm) * z1_e3ua * wumask(ji,jj,jk+1)
-               zWui = ( wi(ji,jj,jk  ) + wi(ji+1,jj,jk  ) ) * z1_e3ua
-               zWus = ( wi(ji,jj,jk+1) + wi(ji+1,jj,jk+1) ) * z1_e3ua
-               zwi(ji,jj,jk) = zzwi + zDt_2 * MIN( zWui, 0._wp ) 
-               zws(ji,jj,jk) = zzws - zDt_2 * MAX( zWus, 0._wp )
-               zwd(ji,jj,jk) = 1._wp - zzwi - zzws + zDt_2 * ( MAX( zWui, 0._wp ) - MIN( zWus, 0._wp ) )
-            END_3D
-         CASE DEFAULT               ! iso-level lateral mixing
-            DO_3D( 0, 0, 0, 0, 1, jpkm1 )
-               z1_e3ua =  1._wp  / e3u(ji,jj,jk,Kaa)   ! after scale factor at U-point
-               zzwi = - zDt_2 * ( avm(ji+1,jj,jk  ) + avm(ji,jj,jk  ) )   &
-                  &         / e3uw(ji,jj,jk  ,Kmm) * z1_e3ua * wumask(ji,jj,jk  )
-               zzws = - zDt_2 * ( avm(ji+1,jj,jk+1) + avm(ji,jj,jk+1) )   &
-                  &         / e3uw(ji,jj,jk+1,Kmm) * z1_e3ua * wumask(ji,jj,jk+1)
-               zWui = ( wi(ji,jj,jk  ) + wi(ji+1,jj,jk  ) ) * z1_e3ua
-               zWus = ( wi(ji,jj,jk+1) + wi(ji+1,jj,jk+1) ) * z1_e3ua
-               zwi(ji,jj,jk) = zzwi + zDt_2 * MIN( zWui, 0._wp )
-               zws(ji,jj,jk) = zzws - zDt_2 * MAX( zWus, 0._wp )
-               zwd(ji,jj,jk) = 1._wp - zzwi - zzws + zDt_2 * ( MAX( zWui, 0._wp ) - MIN( zWus, 0._wp ) )
-            END_3D
-         END SELECT
-         DO_2D( 0, 0, 0, 0 )     !* Surface boundary conditions
-            zwi(ji,jj,1) = 0._wp
-            zzws = - zDt_2 * ( avm(ji+1,jj,2) + avm(ji  ,jj,2) )   &
-               &         / ( e3u(ji,jj,1,Kaa) * e3uw(ji,jj,2,Kmm) ) * wumask(ji,jj,2)
-            zWus = ( wi(ji  ,jj,2) +  wi(ji+1,jj,2) ) / e3u(ji,jj,1,Kaa)
-            zws(ji,jj,1 ) = zzws - zDt_2 * MAX( zWus, 0._wp )
-            zwd(ji,jj,1 ) = 1._wp - zzws - zDt_2 * ( MIN( zWus, 0._wp ) )
-         END_2D
-      ELSE
-         SELECT CASE( nldf_dyn )
-         CASE( np_lap_i )           ! rotated lateral mixing: add its vertical mixing (akzu)
-            DO_3D( 0, 0, 0, 0, 1, jpkm1 )
-               zzwi = - zDt_2 * ( avm(ji+1,jj,jk  ) + avm(ji,jj,jk  ) + akzu(ji,jj,jk  ) )   &
-                  &         / ( e3u(ji,jj,jk,Kaa) * e3uw(ji,jj,jk  ,Kmm) ) * wumask(ji,jj,jk  )
-               zzws = - zDt_2 * ( avm(ji+1,jj,jk+1) + avm(ji,jj,jk+1) + akzu(ji,jj,jk+1) )   &
-                  &         / ( e3u(ji,jj,jk,Kaa) * e3uw(ji,jj,jk+1,Kmm) ) * wumask(ji,jj,jk+1)
-               zwi(ji,jj,jk) = zzwi
-               zws(ji,jj,jk) = zzws
-               zwd(ji,jj,jk) = 1._wp - zzwi - zzws
-            END_3D
-         CASE DEFAULT               ! iso-level lateral mixing
-            DO_3D( 0, 0, 0, 0, 1, jpkm1 )
-               zzwi = - zDt_2 * ( avm(ji+1,jj,jk  ) + avm(ji,jj,jk  ) )    &
-                  &         / ( e3u(ji,jj,jk,Kaa) * e3uw(ji,jj,jk  ,Kmm) ) * wumask(ji,jj,jk  )
-               zzws = - zDt_2 * ( avm(ji+1,jj,jk+1) + avm(ji,jj,jk+1) )    &
-                  &         / ( e3u(ji,jj,jk,Kaa) * e3uw(ji,jj,jk+1,Kmm) ) * wumask(ji,jj,jk+1)
-               zwi(ji,jj,jk) = zzwi
-               zws(ji,jj,jk) = zzws
-               zwd(ji,jj,jk) = 1._wp - zzwi - zzws
-            END_3D
-         END SELECT
-         DO_2D( 0, 0, 0, 0 )     !* Surface boundary conditions
-            zwi(ji,jj,1) = 0._wp
-            zwd(ji,jj,1) = 1._wp - zws(ji,jj,1)
-         END_2D
-      ENDIF
-      !
-      !
-      !              !==  Apply semi-implicit bottom friction  ==!
-      !
-      !     Only needed for semi-implicit bottom friction setup. The explicit
-      !     bottom friction has been included in "u(v)a" which act as the R.H.S
-      !     column vector of the tri-diagonal matrix equation
-      !
-      IF ( ln_drgimp ) THEN      ! implicit bottom friction
-         DO_2D( 0, 0, 0, 0 )
-            iku = mbku(ji,jj)       ! ocean bottom level at u- and v-points
-            zwd(ji,jj,iku) = zwd(ji,jj,iku) - zDt_2 *( rCdU_bot(ji+1,jj)+rCdU_bot(ji,jj) )   &
-               &                                    / e3u(ji,jj,iku,Kaa)
-         END_2D
-         IF ( ln_isfcav.OR.ln_drgice_imp ) THEN   ! top friction (always implicit)
-            DO_2D( 0, 0, 0, 0 )
-               !!gm   top Cd is masked (=0 outside cavities) no need of test on mik>=2  ==>> it has been suppressed
-               iku = miku(ji,jj)       ! ocean top level at u- and v-points 
-               zwd(ji,jj,iku) = zwd(ji,jj,iku) - zDt_2 *( rCdU_top(ji+1,jj)+rCdU_top(ji,jj) )    &
+            END_1D
+            IF( ln_isfcav.OR.ln_drgice_imp ) THEN    ! Ocean cavities (ISF)
+               DO_1Di( 0, 0 )
+                  iku = miku(ji,jj)         ! top ocean level at u- and v-points 
+                  ikv = mikv(ji,jj)         ! (first wet ocean u- and v-points)
+                  puu(ji,jj,iku,Kaa) = puu(ji,jj,iku,Kaa) + zDt_2 *( rCdU_top(ji+1,jj)+rCdU_top(ji,jj) ) * uu_b(ji,jj,Kaa)   &
+                     &                                            / e3u(ji,jj,iku,Kaa)
+                  pvv(ji,jj,ikv,Kaa) = pvv(ji,jj,ikv,Kaa) + zDt_2 *( rCdU_top(ji,jj+1)+rCdU_top(ji,jj) ) * vv_b(ji,jj,Kaa)   &
+                     &                                            / e3v(ji,jj,ikv,Kaa)
+               END_1D
+            END IF
+         ENDIF
+         !
+         !              !==  Vertical diffusion on u  ==!
+         !
+         !
+         !                    !* Matrix construction
+         IF( ln_zad_Aimp ) THEN      !- including terms associated with partly implicit vertical advection 
+            SELECT CASE( nldf_dyn )
+            CASE( np_lap_i )           ! rotated lateral mixing: add its vertical mixing (akzu)
+               DO_2Dik( 0, 0,   1, jpkm1, 1 )
+                  z1_e3ua =  1._wp  / e3u(ji,jj,jk,Kaa)   ! after scale factor at U-point
+                  zzwi = - zDt_2 * ( avm(ji+1,jj,jk  ) + avm(ji,jj,jk  ) + akzu(ji,jj,jk  ) )   &
+                     &         / e3uw(ji,jj,jk  ,Kmm) * z1_e3ua * wumask(ji,jj,jk  )
+                  zzws = - zDt_2 * ( avm(ji+1,jj,jk+1) + avm(ji,jj,jk+1) + akzu(ji,jj,jk+1) )   &
+                     &         / e3uw(ji,jj,jk+1,Kmm) * z1_e3ua * wumask(ji,jj,jk+1)
+                  zWui = ( wi(ji,jj,jk  ) + wi(ji+1,jj,jk  ) ) * z1_e3ua
+                  zWus = ( wi(ji,jj,jk+1) + wi(ji+1,jj,jk+1) ) * z1_e3ua
+                  zwi(ji,jk) = zzwi + zDt_2 * MIN( zWui, 0._wp ) 
+                  zws(ji,jk) = zzws - zDt_2 * MAX( zWus, 0._wp )
+                  zwd(ji,jk) = 1._wp - zzwi - zzws + zDt_2 * ( MAX( zWui, 0._wp ) - MIN( zWus, 0._wp ) )
+               END_2D
+            CASE DEFAULT               ! iso-level lateral mixing
+               DO_2Dik( 0, 0,   1, jpkm1, 1 )
+                  z1_e3ua =  1._wp  / e3u(ji,jj,jk,Kaa)   ! after scale factor at U-point
+                  zzwi = - zDt_2 * ( avm(ji+1,jj,jk  ) + avm(ji,jj,jk  ) )   &
+                     &         / e3uw(ji,jj,jk  ,Kmm) * z1_e3ua * wumask(ji,jj,jk  )
+                  zzws = - zDt_2 * ( avm(ji+1,jj,jk+1) + avm(ji,jj,jk+1) )   &
+                     &         / e3uw(ji,jj,jk+1,Kmm) * z1_e3ua * wumask(ji,jj,jk+1)
+                  zWui = ( wi(ji,jj,jk  ) + wi(ji+1,jj,jk  ) ) * z1_e3ua
+                  zWus = ( wi(ji,jj,jk+1) + wi(ji+1,jj,jk+1) ) * z1_e3ua
+                  zwi(ji,jk) = zzwi + zDt_2 * MIN( zWui, 0._wp )
+                  zws(ji,jk) = zzws - zDt_2 * MAX( zWus, 0._wp )
+                  zwd(ji,jk) = 1._wp - zzwi - zzws + zDt_2 * ( MAX( zWui, 0._wp ) - MIN( zWus, 0._wp ) )
+               END_2D
+            END SELECT
+            !
+            zwi(:,1) = 0._wp
+            DO_1Di( 0, 0 )     !* Surface boundary conditions
+               zwi(ji,1) = 0._wp
+               zzws = - zDt_2 * ( avm(ji+1,jj,2) + avm(ji  ,jj,2) )   &
+                  &         / ( e3u(ji,jj,1,Kaa) * e3uw(ji,jj,2,Kmm) ) * wumask(ji,jj,2)
+               zWus = ( wi(ji  ,jj,2) +  wi(ji+1,jj,2) ) / e3u(ji,jj,1,Kaa)
+               zws(ji,1) = zzws - zDt_2 * MAX( zWus, 0._wp )
+               zwd(ji,1) = 1._wp - zzws - zDt_2 * ( MIN( zWus, 0._wp ) )
+            END_1D
+         ELSE                       !- only vertical diffusive terms
+            SELECT CASE( nldf_dyn )
+            CASE( np_lap_i )           ! rotated lateral mixing: add its vertical mixing (akzu)
+               DO_2Dik( 0, 0,   1, jpkm1, 1 )
+                  zzwi = - zDt_2 * ( avm(ji+1,jj,jk  ) + avm(ji,jj,jk  ) + akzu(ji,jj,jk  ) )   &
+                     &         / ( e3u(ji,jj,jk,Kaa) * e3uw(ji,jj,jk  ,Kmm) ) * wumask(ji,jj,jk  )
+                  zzws = - zDt_2 * ( avm(ji+1,jj,jk+1) + avm(ji,jj,jk+1) + akzu(ji,jj,jk+1) )   &
+                     &         / ( e3u(ji,jj,jk,Kaa) * e3uw(ji,jj,jk+1,Kmm) ) * wumask(ji,jj,jk+1)
+                  zwi(ji,jk) = zzwi
+                  zws(ji,jk) = zzws
+                  zwd(ji,jk) = 1._wp - zzwi - zzws
+               END_2D
+            CASE DEFAULT               ! iso-level lateral mixing
+               DO_2Dik( 0, 0,   1, jpkm1, 1 )
+                  zzwi = - zDt_2 * ( avm(ji+1,jj,jk  ) + avm(ji,jj,jk  ) )    &
+                     &         / ( e3u(ji,jj,jk,Kaa) * e3uw(ji,jj,jk  ,Kmm) ) * wumask(ji,jj,jk  )
+                  zzws = - zDt_2 * ( avm(ji+1,jj,jk+1) + avm(ji,jj,jk+1) )    &
+                     &         / ( e3u(ji,jj,jk,Kaa) * e3uw(ji,jj,jk+1,Kmm) ) * wumask(ji,jj,jk+1)
+                  zwi(ji,jk) = zzwi
+                  zws(ji,jk) = zzws
+                  zwd(ji,jk) = 1._wp - zzwi - zzws
+               END_2D
+            END SELECT
+            !
+            zwi(:,1) = 0._wp
+            DO_1Di( 0, 0 )     !* Surface boundary conditions
+               zwd(ji,1) = 1._wp - zws(ji,1)
+            END_1D
+         ENDIF
+         !
+         !
+         !              !==  Apply semi-implicit bottom friction  ==!
+         !
+         !     Only needed for semi-implicit bottom friction setup. The explicit
+         !     bottom friction has been included in "u(v)a" which act as the R.H.S
+         !     column vector of the tri-diagonal matrix equation
+         !
+         IF ( ln_drgimp ) THEN      ! implicit bottom friction
+            DO_1Di( 0, 0 )
+               iku = mbku(ji,jj)       ! ocean bottom level at u- and v-points
+               zwd(ji,iku) = zwd(ji,iku) - zDt_2 *( rCdU_bot(ji+1,jj)+rCdU_bot(ji,jj) )   &
                   &                                    / e3u(ji,jj,iku,Kaa)
-            END_2D
-         END IF
-      ENDIF
-      !
-      ! Matrix inversion starting from the first level
-      !-----------------------------------------------------------------------
-      !   solve m.x = y  where m is a tri diagonal matrix ( jpk*jpk )
-      !
-      !        ( zwd1 zws1   0    0    0  )( zwx1 ) ( zwy1 )
-      !        ( zwi2 zwd2 zws2   0    0  )( zwx2 ) ( zwy2 )
-      !        (  0   zwi3 zwd3 zws3   0  )( zwx3 )=( zwy3 )
-      !        (        ...               )( ...  ) ( ...  )
-      !        (  0    0    0   zwik zwdk )( zwxk ) ( zwyk )
-      !
-      !   m is decomposed in the product of an upper and a lower triangular matrix
-      !   The 3 diagonal terms are in 2d arrays: zwd, zws, zwi
-      !   The solution (the after velocity) is in puu(:,:,:,Kaa)
-      !-----------------------------------------------------------------------
-      !
-      DO_3D( 0, 0, 0, 0, 2, jpkm1 )   !==  First recurrence : Dk = Dk - Lk * Uk-1 / Dk-1   (increasing k)  ==
-         zwd(ji,jj,jk) = zwd(ji,jj,jk) - zwi(ji,jj,jk) * zws(ji,jj,jk-1) / zwd(ji,jj,jk-1)
-      END_3D
-      !
-      DO_2D( 0, 0, 0, 0 )             !==  second recurrence:    SOLk = RHSk - Lk / Dk-1  Lk-1  ==!
+            END_1D
+            IF ( ln_isfcav.OR.ln_drgice_imp ) THEN   ! top friction (always implicit)
+               DO_1Di( 0, 0 )
+               !!gm   top Cd is masked (=0 outside cavities) no need of test on mik>=2  ==>> it has been suppressed
+                  iku = miku(ji,jj)       ! ocean top level at u- and v-points 
+                  zwd(ji,iku) = zwd(ji,iku) - zDt_2 *( rCdU_top(ji+1,jj)+rCdU_top(ji,jj) )    &
+                     &                                    / e3u(ji,jj,iku,Kaa)
+               END_1D
+            ENDIF
+         ENDIF
+         !
+         ! Matrix inversion starting from the first level
+         !-----------------------------------------------------------------------
+         !   solve m.x = y  where m is a tri diagonal matrix ( jpk*jpk )
+         !
+         !        ( zwd1 zws1   0    0    0  )( zwx1 ) ( zwy1 )
+         !        ( zwi2 zwd2 zws2   0    0  )( zwx2 ) ( zwy2 )
+         !        (  0   zwi3 zwd3 zws3   0  )( zwx3 )=( zwy3 )
+         !        (        ...               )( ...  ) ( ...  )
+         !        (  0    0    0   zwik zwdk )( zwxk ) ( zwyk )
+         !
+         !   m is decomposed in the product of an upper and a lower triangular matrix
+         !   The 3 diagonal terms are in 2d arrays: zwd, zws, zwi
+         !   The solution (the after velocity) is in puu(:,:,:,Kaa)
+         !-----------------------------------------------------------------------
+         !
+         DO_2Dik( 0, 0,    2, jpkm1, 1 )   !==  First recurrence : Dk = Dk - Lk * Uk-1 / Dk-1   (increasing k)  ==
+            zwd(ji,jk) = zwd(ji,jk) - zwi(ji,jk) * zws(ji,jk-1) / zwd(ji,jk-1)
+         END_2D
+         !
+         DO_1Di( 0, 0 )                    !==  second recurrence:    SOLk = RHSk - Lk / Dk-1  Lk-1  ==!
 #if defined key_RK3
-         !                                  ! RK3: use only utau (not utau_b)
-         puu(ji,jj,1,Kaa) = puu(ji,jj,1,Kaa) + rDt * utauU(ji,jj)   &
-              &                                 / ( e3u(ji,jj,1,Kaa) * rho0 ) * umask(ji,jj,1)
+            !                                  ! RK3: use only utau (not utau_b)
+            puu(ji,jj,1,Kaa) = puu(ji,jj,1,Kaa) + rDt * utauU(ji,jj)   &
+                 &                                 / ( e3u(ji,jj,1,Kaa) * rho0 ) * umask(ji,jj,1)
 #else
-         puu(ji,jj,1,Kaa) = puu(ji,jj,1,Kaa) + zDt_2 * ( utau_b(ji,jj) + utauU(ji,jj) )   &
-              &                                 / ( e3u(ji,jj,1,Kaa) * rho0 ) * umask(ji,jj,1)
+            !                                  ! MLF: average of utau and utau_b
+            puu(ji,jj,1,Kaa) = puu(ji,jj,1,Kaa) + zDt_2 * ( utau_b(ji,jj) + utauU(ji,jj) )   &
+                 &                                 / ( e3u(ji,jj,1,Kaa) * rho0 ) * umask(ji,jj,1)
 #endif
-      END_2D
-      DO_3D( 0, 0, 0, 0, 2, jpkm1 )
-         puu(ji,jj,jk,Kaa) = puu(ji,jj,jk,Kaa) - zwi(ji,jj,jk) / zwd(ji,jj,jk-1) * puu(ji,jj,jk-1,Kaa)
-      END_3D
-      !
-      DO_2D( 0, 0, 0, 0 )             !==  thrid recurrence : SOLk = ( Lk - Uk * Ek+1 ) / Dk  ==!
-         puu(ji,jj,jpkm1,Kaa) = puu(ji,jj,jpkm1,Kaa) / zwd(ji,jj,jpkm1)
-      END_2D
-      DO_3DS( 0, 0, 0, 0, jpk-2, 1, -1 )
-         puu(ji,jj,jk,Kaa) = ( puu(ji,jj,jk,Kaa) - zws(ji,jj,jk) * puu(ji,jj,jk+1,Kaa) ) / zwd(ji,jj,jk)
-      END_3D
-      !
-      !              !==  Vertical diffusion on v  ==!
-      !
-      !                       !* Matrix construction
-      IF( ln_zad_Aimp ) THEN   !!
-         SELECT CASE( nldf_dyn )
-         CASE( np_lap_i )           ! rotated lateral mixing: add its vertical mixing (akzv)
-            DO_3D( 0, 0, 0, 0, 1, jpkm1 )
-               z1_e3va = 1._wp / e3v(ji,jj,jk,Kaa)   ! after scale factor at V-point
-               zzwi = - zDt_2 * ( avm(ji,jj+1,jk  ) + avm(ji,jj,jk  ) + akzv(ji,jj,jk  ) )   &
-                  &         / e3vw(ji,jj,jk  ,Kmm) * z1_e3va * wvmask(ji,jj,jk  )
-               zzws = - zDt_2 * ( avm(ji,jj+1,jk+1) + avm(ji,jj,jk+1) + akzv(ji,jj,jk+1) )   &
-                  &         / e3vw(ji,jj,jk+1,Kmm) * z1_e3va * wvmask(ji,jj,jk+1)
-               zWvi = ( wi(ji,jj,jk  ) + wi(ji,jj+1,jk  ) ) * z1_e3va
-               zWvs = ( wi(ji,jj,jk+1) + wi(ji,jj+1,jk+1) ) * z1_e3va
-               zwi(ji,jj,jk) = zzwi + zDt_2 * MIN( zWvi, 0._wp )
-               zws(ji,jj,jk) = zzws - zDt_2 * MAX( zWvs, 0._wp )
-               zwd(ji,jj,jk) = 1._wp - zzwi - zzws - zDt_2 * ( - MAX( zWvi, 0._wp ) + MIN( zWvs, 0._wp ) )
-            END_3D
-         CASE DEFAULT               ! iso-level lateral mixing
-            DO_3D( 0, 0, 0, 0, 1, jpkm1 )
-               z1_e3va = 1._wp / e3v(ji,jj,jk,Kaa)   ! after scale factor at V-point
-               zzwi = - zDt_2 * ( avm(ji,jj+1,jk  ) + avm(ji,jj,jk  ) )    &
-                  &         / e3vw(ji,jj,jk  ,Kmm) * z1_e3va * wvmask(ji,jj,jk  )
-               zzws = - zDt_2 * ( avm(ji,jj+1,jk+1) + avm(ji,jj,jk+1) )    &
-                  &         / e3vw(ji,jj,jk+1,Kmm) * z1_e3va * wvmask(ji,jj,jk+1)
-               zWvi = ( wi(ji,jj,jk  ) + wi(ji,jj+1,jk  ) ) * z1_e3va
-               zWvs = ( wi(ji,jj,jk+1) + wi(ji,jj+1,jk+1) ) * z1_e3va
-               zwi(ji,jj,jk) = zzwi  + zDt_2 * MIN( zWvi, 0._wp )
-               zws(ji,jj,jk) = zzws  - zDt_2 * MAX( zWvs, 0._wp )
-               zwd(ji,jj,jk) = 1._wp - zzwi - zzws - zDt_2 * ( - MAX( zWvi, 0._wp ) + MIN( zWvs, 0._wp ) )
-            END_3D
-         END SELECT
-         DO_2D( 0, 0, 0, 0 )   !* Surface boundary conditions
-            zwi(ji,jj,1) = 0._wp
-            zzws = - zDt_2 * ( avm(ji,jj+1,2) + avm(ji,jj,2) )    &
-               &         / ( e3v(ji,jj,1,Kaa) * e3vw(ji,jj,2,Kmm) ) * wvmask(ji,jj,2)
-            zWvs = ( wi(ji,jj  ,2) +  wi(ji,jj+1,2) ) / e3v(ji,jj,1,Kaa)
-            zws(ji,jj,1 ) = zzws - zDt_2 * MAX( zWvs, 0._wp )
-            zwd(ji,jj,1 ) = 1._wp - zzws - zDt_2 * ( MIN( zWvs, 0._wp ) )
-         END_2D
-      ELSE
-         SELECT CASE( nldf_dyn )
-         CASE( np_lap_i )           ! rotated lateral mixing: add its vertical mixing (akzu)
-            DO_3D( 0, 0, 0, 0, 1, jpkm1 )
-               zzwi = - zDt_2 * ( avm(ji,jj+1,jk  ) + avm(ji,jj,jk  ) + akzv(ji,jj,jk  ) )   &
-                  &         / ( e3v(ji,jj,jk,Kaa) * e3vw(ji,jj,jk  ,Kmm) ) * wvmask(ji,jj,jk  )
-               zzws = - zDt_2 * ( avm(ji,jj+1,jk+1) + avm(ji,jj,jk+1) + akzv(ji,jj,jk+1) )   &
-                  &         / ( e3v(ji,jj,jk,Kaa) * e3vw(ji,jj,jk+1,Kmm) ) * wvmask(ji,jj,jk+1)
-               zwi(ji,jj,jk) = zzwi
-               zws(ji,jj,jk) = zzws
-               zwd(ji,jj,jk) = 1._wp - zzwi - zzws
-            END_3D
-         CASE DEFAULT               ! iso-level lateral mixing
-            DO_3D( 0, 0, 0, 0, 1, jpkm1 )
-               zzwi = - zDt_2 * ( avm(ji,jj+1,jk  ) + avm(ji,jj,jk  ) )    &
-                  &         / ( e3v(ji,jj,jk,Kaa) * e3vw(ji,jj,jk  ,Kmm) ) * wvmask(ji,jj,jk  )
-               zzws = - zDt_2 * ( avm(ji,jj+1,jk+1) + avm(ji,jj,jk+1) )    &
-                  &         / ( e3v(ji,jj,jk,Kaa) * e3vw(ji,jj,jk+1,Kmm) ) * wvmask(ji,jj,jk+1)
-               zwi(ji,jj,jk) = zzwi
-               zws(ji,jj,jk) = zzws
-               zwd(ji,jj,jk) = 1._wp - zzwi - zzws
-            END_3D
-         END SELECT
-         DO_2D( 0, 0, 0, 0 )        !* Surface boundary conditions
-            zwi(ji,jj,1) = 0._wp
-            zwd(ji,jj,1) = 1._wp - zws(ji,jj,1)
+         END_1D
+         DO_2Dik( 0, 0,     2, jpkm1, 1 )
+            puu(ji,jj,jk,Kaa) = puu(ji,jj,jk,Kaa) - zwi(ji,jk) / zwd(ji,jk-1) * puu(ji,jj,jk-1,Kaa)
          END_2D
-      ENDIF
-      !
-      !              !==  Apply semi-implicit top/bottom friction  ==!
-      !
-      !     Only needed for semi-implicit bottom friction setup. The explicit
-      !     bottom friction has been included in "u(v)a" which act as the R.H.S
-      !     column vector of the tri-diagonal matrix equation
-      !
-      IF( ln_drgimp ) THEN
-         DO_2D( 0, 0, 0, 0 )
-            ikv = mbkv(ji,jj)       ! (deepest ocean u- and v-points)
-            zwd(ji,jj,ikv) = zwd(ji,jj,ikv) - zDt_2*( rCdU_bot(ji,jj+1)+rCdU_bot(ji,jj) )   &
-               &                                   / e3v(ji,jj,ikv,Kaa)
+         !
+         DO_1Di( 0, 0 )                    !==  thrid recurrence : SOLk = ( Lk - Uk * Ek+1 ) / Dk  ==!
+            puu(ji,jj,jpkm1,Kaa) = puu(ji,jj,jpkm1,Kaa) / zwd(ji,jpkm1)
+         END_1D
+         DO_2Dik( 0, 0,    jpk-2, 1, -1 )
+            puu(ji,jj,jk,Kaa) = ( puu(ji,jj,jk,Kaa) - zws(ji,jk) * puu(ji,jj,jk+1,Kaa) ) / zwd(ji,jk)
          END_2D
-         IF ( ln_isfcav.OR.ln_drgice_imp ) THEN
-            DO_2D( 0, 0, 0, 0 )
-               ikv = mikv(ji,jj)       ! (first wet ocean u- and v-points)
-               zwd(ji,jj,ikv) = zwd(ji,jj,ikv) - zDt_2*( rCdU_top(ji,jj+1)+rCdU_top(ji,jj) )   &
+         !
+         !
+         !              !==  Vertical diffusion on v  ==!
+         !
+         !                       !* Matrix construction
+         IF( ln_zad_Aimp ) THEN   !!
+            SELECT CASE( nldf_dyn )
+            CASE( np_lap_i )           ! rotated lateral mixing: add its vertical mixing (akzv)
+               DO_2Dik( 0, 0,    1, jpkm1, 1 )
+                  z1_e3va = 1._wp / e3v(ji,jj,jk,Kaa)   ! after scale factor at V-point
+                  zzwi = - zDt_2 * ( avm(ji,jj+1,jk  ) + avm(ji,jj,jk  ) + akzv(ji,jj,jk  ) )   &
+                     &         / e3vw(ji,jj,jk  ,Kmm) * z1_e3va * wvmask(ji,jj,jk  )
+                  zzws = - zDt_2 * ( avm(ji,jj+1,jk+1) + avm(ji,jj,jk+1) + akzv(ji,jj,jk+1) )   &
+                     &         / e3vw(ji,jj,jk+1,Kmm) * z1_e3va * wvmask(ji,jj,jk+1)
+                  zWvi = ( wi(ji,jj,jk  ) + wi(ji,jj+1,jk  ) ) * z1_e3va
+                  zWvs = ( wi(ji,jj,jk+1) + wi(ji,jj+1,jk+1) ) * z1_e3va
+                  zwi(ji,jk) = zzwi + zDt_2 * MIN( zWvi, 0._wp )
+                  zws(ji,jk) = zzws - zDt_2 * MAX( zWvs, 0._wp )
+                  zwd(ji,jk) = 1._wp - zzwi - zzws - zDt_2 * ( - MAX( zWvi, 0._wp ) + MIN( zWvs, 0._wp ) )
+               END_2D
+            CASE DEFAULT               ! iso-level lateral mixing
+               DO_2Dik( 0, 0,    1, jpkm1, 1 )
+                  z1_e3va = 1._wp / e3v(ji,jj,jk,Kaa)   ! after scale factor at V-point
+                  zzwi = - zDt_2 * ( avm(ji,jj+1,jk  ) + avm(ji,jj,jk  ) )    &
+                     &         / e3vw(ji,jj,jk  ,Kmm) * z1_e3va * wvmask(ji,jj,jk  )
+                  zzws = - zDt_2 * ( avm(ji,jj+1,jk+1) + avm(ji,jj,jk+1) )    &
+                     &         / e3vw(ji,jj,jk+1,Kmm) * z1_e3va * wvmask(ji,jj,jk+1)
+                  zWvi = ( wi(ji,jj,jk  ) + wi(ji,jj+1,jk  ) ) * z1_e3va
+                  zWvs = ( wi(ji,jj,jk+1) + wi(ji,jj+1,jk+1) ) * z1_e3va
+                  zwi(ji,jk) = zzwi  + zDt_2 * MIN( zWvi, 0._wp )
+                  zws(ji,jk) = zzws  - zDt_2 * MAX( zWvs, 0._wp )
+                  zwd(ji,jk) = 1._wp - zzwi - zzws - zDt_2 * ( - MAX( zWvi, 0._wp ) + MIN( zWvs, 0._wp ) )
+               END_2D
+            END SELECT
+            DO_1Di( 0, 0 )   !* Surface boundary conditions
+               zwi(ji,1) = 0._wp
+               zzws = - zDt_2 * ( avm(ji,jj+1,2) + avm(ji,jj,2) )    &
+                  &         / ( e3v(ji,jj,1,Kaa) * e3vw(ji,jj,2,Kmm) ) * wvmask(ji,jj,2)
+               zWvs = ( wi(ji,jj  ,2) +  wi(ji,jj+1,2) ) / e3v(ji,jj,1,Kaa)
+               zws(ji,1 ) = zzws - zDt_2 * MAX( zWvs, 0._wp )
+               zwd(ji,1 ) = 1._wp - zzws - zDt_2 * ( MIN( zWvs, 0._wp ) )
+            END_1D
+         ELSE
+            SELECT CASE( nldf_dyn )
+            CASE( np_lap_i )           ! rotated lateral mixing: add its vertical mixing (akzu)
+               DO_2Dik( 0, 0,    1, jpkm1, 1 )
+                  zzwi = - zDt_2 * ( avm(ji,jj+1,jk  ) + avm(ji,jj,jk  ) + akzv(ji,jj,jk  ) )   &
+                     &         / ( e3v(ji,jj,jk,Kaa) * e3vw(ji,jj,jk  ,Kmm) ) * wvmask(ji,jj,jk  )
+                  zzws = - zDt_2 * ( avm(ji,jj+1,jk+1) + avm(ji,jj,jk+1) + akzv(ji,jj,jk+1) )   &
+                     &         / ( e3v(ji,jj,jk,Kaa) * e3vw(ji,jj,jk+1,Kmm) ) * wvmask(ji,jj,jk+1)
+                  zwi(ji,jk) = zzwi
+                  zws(ji,jk) = zzws
+                  zwd(ji,jk) = 1._wp - zzwi - zzws
+               END_2D
+            CASE DEFAULT               ! iso-level lateral mixing
+               DO_2Dik( 0, 0,    1, jpkm1, 1 )
+                  zzwi = - zDt_2 * ( avm(ji,jj+1,jk  ) + avm(ji,jj,jk  ) )    &
+                     &         / ( e3v(ji,jj,jk,Kaa) * e3vw(ji,jj,jk  ,Kmm) ) * wvmask(ji,jj,jk  )
+                  zzws = - zDt_2 * ( avm(ji,jj+1,jk+1) + avm(ji,jj,jk+1) )    &
+                     &         / ( e3v(ji,jj,jk,Kaa) * e3vw(ji,jj,jk+1,Kmm) ) * wvmask(ji,jj,jk+1)
+                  zwi(ji,jk) = zzwi
+                  zws(ji,jk) = zzws
+                  zwd(ji,jk) = 1._wp - zzwi - zzws
+               END_2D
+            END SELECT
+            DO_1Di( 0, 0 )        !* Surface boundary conditions
+               zwi(ji,1) = 0._wp
+               zwd(ji,1) = 1._wp - zws(ji,1)
+            END_1D
+         ENDIF
+         !
+         !              !==  Apply semi-implicit top/bottom friction  ==!
+         !
+         !     Only needed for semi-implicit bottom friction setup. The explicit
+         !     bottom friction has been included in "u(v)a" which act as the R.H.S
+         !     column vector of the tri-diagonal matrix equation
+         !
+         IF( ln_drgimp ) THEN
+            DO_1Di( 0, 0 )
+               ikv = mbkv(ji,jj)       ! (deepest ocean u- and v-points)
+               zwd(ji,ikv) = zwd(ji,ikv) - zDt_2*( rCdU_bot(ji,jj+1)+rCdU_bot(ji,jj) )   &
                   &                                   / e3v(ji,jj,ikv,Kaa)
-            END_2D
+            END_1D
+            IF ( ln_isfcav.OR.ln_drgice_imp ) THEN
+               DO_1Di( 0, 0 )
+                  ikv = mikv(ji,jj)       ! (first wet ocean u- and v-points)
+                  zwd(ji,ikv) = zwd(ji,ikv) - zDt_2*( rCdU_top(ji,jj+1)+rCdU_top(ji,jj) )   &
+                     &                                   / e3v(ji,jj,ikv,Kaa)
+               END_1D
+            ENDIF
          ENDIF
-      ENDIF
-
-      ! Matrix inversion
-      !-----------------------------------------------------------------------
-      !   solve m.x = y  where m is a tri diagonal matrix ( jpk*jpk )
-      !
-      !        ( zwd1 zws1   0    0    0  )( zwx1 ) ( zwy1 )
-      !        ( zwi2 zwd2 zws2   0    0  )( zwx2 ) ( zwy2 )
-      !        (  0   zwi3 zwd3 zws3   0  )( zwx3 )=( zwy3 )
-      !        (        ...               )( ...  ) ( ...  )
-      !        (  0    0    0   zwik zwdk )( zwxk ) ( zwyk )
-      !
-      !   m is decomposed in the product of an upper and lower triangular matrix
-      !   The 3 diagonal terms are in 2d arrays: zwd, zws, zwi
-      !   The solution (after velocity) is in 2d array va
-      !-----------------------------------------------------------------------
-      !
-      DO_3D( 0, 0, 0, 0, 2, jpkm1 )   !==  First recurrence : Dk = Dk - Lk * Uk-1 / Dk-1   (increasing k)  ==
-         zwd(ji,jj,jk) = zwd(ji,jj,jk) - zwi(ji,jj,jk) * zws(ji,jj,jk-1) / zwd(ji,jj,jk-1)
-      END_3D
-      !
-      DO_2D( 0, 0, 0, 0 )             !==  second recurrence:    SOLk = RHSk - Lk / Dk-1  Lk-1  ==!
+   
+         ! Matrix inversion
+         !-----------------------------------------------------------------------
+         !   solve m.x = y  where m is a tri diagonal matrix ( jpk*jpk )
+         !
+         !        ( zwd1 zws1   0    0    0  )( zwx1 ) ( zwy1 )
+         !        ( zwi2 zwd2 zws2   0    0  )( zwx2 ) ( zwy2 )
+         !        (  0   zwi3 zwd3 zws3   0  )( zwx3 )=( zwy3 )
+         !        (        ...               )( ...  ) ( ...  )
+         !        (  0    0    0   zwik zwdk )( zwxk ) ( zwyk )
+         !
+         !   m is decomposed in the product of an upper and lower triangular matrix
+         !   The 3 diagonal terms are in 2d arrays: zwd, zws, zwi
+         !   The solution (after velocity) is in 2d array va
+         !-----------------------------------------------------------------------
+         !
+         DO_2Dik( 0, 0,    2, jpkm1, 1 )   !==  First recurrence : Dk = Dk - Lk * Uk-1 / Dk-1   (increasing k)  ==
+            zwd(ji,jk) = zwd(ji,jk) - zwi(ji,jk) * zws(ji,jk-1) / zwd(ji,jk-1)
+         END_2D
+         !
+         DO_1Di( 0, 0 )                    !==  second recurrence:    SOLk = RHSk - Lk / Dk-1  Lk-1  ==!
 #if defined key_RK3
-         !                                  ! RK3: use only vtau (not vtau_b)
-         pvv(ji,jj,1,Kaa) = pvv(ji,jj,1,Kaa) + rDt * vtauV(ji,jj)   &
-            &                                   / ( e3v(ji,jj,1,Kaa) * rho0 ) * vmask(ji,jj,1)
+            !                                  ! RK3: use only vtau (not vtau_b)
+            pvv(ji,jj,1,Kaa) = pvv(ji,jj,1,Kaa) + rDt * vtauV(ji,jj)   &
+               &                                   / ( e3v(ji,jj,1,Kaa) * rho0 ) * vmask(ji,jj,1)
 #else
-         pvv(ji,jj,1,Kaa) = pvv(ji,jj,1,Kaa) + zDt_2 * ( vtau_b(ji,jj) + vtauV(ji,jj) )   &
-              &                                 / ( e3v(ji,jj,1,Kaa) * rho0 ) * vmask(ji,jj,1)
+            !                                  ! MLF: average of vtau and vtau_b
+            pvv(ji,jj,1,Kaa) = pvv(ji,jj,1,Kaa) + zDt_2*( vtau_b(ji,jj) + vtauV(ji,jj) )   &
+                 &                                 / ( e3v(ji,jj,1,Kaa) * rho0 ) * vmask(ji,jj,1)
 #endif
-      END_2D
-      DO_3D( 0, 0, 0, 0, 2, jpkm1 )
-         pvv(ji,jj,jk,Kaa) = pvv(ji,jj,jk,Kaa) - zwi(ji,jj,jk) / zwd(ji,jj,jk-1) * pvv(ji,jj,jk-1,Kaa)
-      END_3D
-      !
-      DO_2D( 0, 0, 0, 0 )             !==  third recurrence : SOLk = ( Lk - Uk * SOLk+1 ) / Dk  ==!
-         pvv(ji,jj,jpkm1,Kaa) = pvv(ji,jj,jpkm1,Kaa) / zwd(ji,jj,jpkm1)
-      END_2D
-      DO_3DS( 0, 0, 0, 0, jpk-2, 1, -1 )
-         pvv(ji,jj,jk,Kaa) = ( pvv(ji,jj,jk,Kaa) - zws(ji,jj,jk) * pvv(ji,jj,jk+1,Kaa) ) / zwd(ji,jj,jk)
-      END_3D
+         END_1D
+         DO_2Dik( 0, 0,    2, jpkm1, 1 )
+            pvv(ji,jj,jk,Kaa) = pvv(ji,jj,jk,Kaa) - zwi(ji,jk) / zwd(ji,jk-1) * pvv(ji,jj,jk-1,Kaa)
+         END_2D
+         !
+         DO_1Di( 0, 0 )                    !==  third recurrence : SOLk = ( Lk - Uk * SOLk+1 ) / Dk  ==!
+            pvv(ji,jj,jpkm1,Kaa) = pvv(ji,jj,jpkm1,Kaa) / zwd(ji,jpkm1)
+         END_1D
+         DO_2Dik( 0, 0,   jpk-2, 1, -1 )
+            pvv(ji,jj,jk,Kaa) = ( pvv(ji,jj,jk,Kaa) - zws(ji,jk) * pvv(ji,jj,jk+1,Kaa) ) / zwd(ji,jk)
+         END_2D
+         !                                            ! ================= !
+      END_1D                                          !  i-k slices loop  !      
+      !                                               ! ================= !
       !
       IF( l_trddyn )   THEN                      ! save the vertical diffusive trends for further diagnostics
          ztrdu(:,:,:) = ( puu(:,:,:,Kaa) - puu(:,:,:,Kbb) )*r1_Dt - ztrdu(:,:,:)
diff --git a/src/OCE/TRA/traadv.F90 b/src/OCE/TRA/traadv.F90
index 190a6a7ad3cc55d62bed5e3023620e3177faf32e..924ee9331d45c6343a8ee7ab12ad8041909ee983 100644
--- a/src/OCE/TRA/traadv.F90
+++ b/src/OCE/TRA/traadv.F90
@@ -10,6 +10,7 @@ MODULE traadv
    !!             -   !  2014-12  (G. Madec) suppression of cross land advection option
    !!            3.6  !  2015-06  (E. Clementi) Addition of Stokes drift in case of wave coupling
    !!            4.5  !  2021-04  (G. Madec, S. Techene) add advective velocities as optional arguments
+   !!            4.5  !  2022-06  (S. Techene, G, Madec) refactorization to reduce local memory usage
    !!----------------------------------------------------------------------
 
    !!----------------------------------------------------------------------
@@ -178,7 +179,7 @@ CONTAINS
          !
 !!gm ???
          ! TEMP: [tiling] This copy-in not necessary after all lbc_lnks removed in the nn_hls = 2 case in tra_adv_fct
-         IF( l_diaptr ) CALL dia_ptr( kt, Kmm, zvv(A2D(0),:) )                                    ! diagnose the effective MSF
+         IF( l_diaptr ) CALL dia_ptr( kt, Kmm, zvv(A2D(nn_hls),:) )                                    ! diagnose the effective MSF
 !!gm ???
          !
 
@@ -191,11 +192,19 @@ CONTAINS
          SELECT CASE ( nadv )                      !==  compute advection trend and add it to general trend  ==!
          !
          CASE ( np_CEN )                                 ! Centered scheme : 2nd / 4th order
-            CALL tra_adv_cen    ( kt, nit000, 'TRA',      zuu, zvv, zww, Kmm, pts, jpts, Krhs, nn_cen_h, nn_cen_v      )
+            IF( nn_hls == 1 ) THEN
+               CALL tra_adv_cen_hls1( kt, nit000, 'TRA',      zuu, zvv, zww, Kmm, pts, jpts, Krhs, nn_cen_h, nn_cen_v  )
+            ELSE
+               CALL tra_adv_cen    ( kt, nit000, 'TRA',      zuu, zvv, zww, Kmm, pts, jpts, Krhs, nn_cen_h, nn_cen_v   )
+            ENDIF
          CASE ( np_FCT )                                 ! FCT scheme      : 2nd / 4th order
                CALL tra_adv_fct ( kt, nit000, 'TRA', rDt, zuu, zvv, zww, Kbb, Kmm, pts, jpts, Krhs, nn_fct_h, nn_fct_v )
          CASE ( np_MUS )                                 ! MUSCL
+            IF( nn_hls == 1 ) THEN
+                CALL tra_adv_mus_hls1( kt, nit000, 'TRA', rDt, zuu, zvv, zww, Kbb, Kmm, pts, jpts, Krhs, ln_mus_ups    )
+             ELSE
                 CALL tra_adv_mus( kt, nit000, 'TRA', rDt, zuu, zvv, zww, Kbb, Kmm, pts, jpts, Krhs, ln_mus_ups         )
+             END IF
          CASE ( np_UBS )                                 ! UBS
             CALL tra_adv_ubs    ( kt, nit000, 'TRA', rDt, zuu, zvv, zww, Kbb, Kmm, pts, jpts, Krhs, nn_ubs_v           )
          CASE ( np_QCK )                                 ! QUICKEST
diff --git a/src/OCE/TRA/traadv_cen.F90 b/src/OCE/TRA/traadv_cen.F90
index 3351e1935a5503648b2e9e0ca590bb5a7813c037..1666eee41455854145befb571038452abd560ceb 100644
--- a/src/OCE/TRA/traadv_cen.F90
+++ b/src/OCE/TRA/traadv_cen.F90
@@ -4,6 +4,7 @@ MODULE traadv_cen
    !! Ocean  tracers:   advective trend (2nd/4th order centered)
    !!======================================================================
    !! History :  3.7  ! 2014-05  (G. Madec)  original code
+   !!            4.5  ! 2022-06  (S. Techene, G, Madec) refactorization to reduce local memory usage
    !!----------------------------------------------------------------------
 
    !!----------------------------------------------------------------------
@@ -29,7 +30,8 @@ MODULE traadv_cen
    IMPLICIT NONE
    PRIVATE
 
-   PUBLIC   tra_adv_cen   ! called by traadv.F90
+   PUBLIC   tra_adv_cen        ! called by traadv.F90
+   PUBLIC   tra_adv_cen_hls1   ! called by traadv.F90
 
    REAL(wp) ::   r1_6 = 1._wp / 6._wp   ! =1/6
 
@@ -47,7 +49,321 @@ MODULE traadv_cen
    !!----------------------------------------------------------------------
 CONTAINS
 
+   SUBROUTINE tra_adv_cen_test( kt, kit000, cdtype, pU, pV, pW,     &
+      &                    Kmm, pt, kjpt, Krhs, kn_cen_h, kn_cen_v )
+      !!----------------------------------------------------------------------
+      !!                  ***  ROUTINE tra_adv_cen  ***
+      !!
+      !! ** Purpose :   Compute the now trend due to the advection of tracers
+      !!      and add it to the general trend of passive tracer equations.
+      !!
+      !! ** Method  :   The advection is evaluated by a 2nd or 4th order scheme
+      !!               using now fields (leap-frog scheme).
+      !!       kn_cen_h = 2  ==>> 2nd order centered scheme on the horizontal
+      !!                = 4  ==>> 4th order    -        -       -      -
+      !!       kn_cen_v = 2  ==>> 2nd order centered scheme on the vertical
+      !!                = 4  ==>> 4th order COMPACT  scheme     -      -
+      !!
+      !! ** Action : - update pt(:,:,:,:,Krhs)  with the now advective tracer trends
+      !!             - send trends to trdtra module for further diagnostcs (l_trdtra=T)
+      !!             - poleward advective heat and salt transport (l_diaptr=T)
+      !!----------------------------------------------------------------------
+      INTEGER                                  , INTENT(in   ) ::   kt              ! ocean time-step index
+      INTEGER                                  , INTENT(in   ) ::   Kmm, Krhs       ! ocean time level indices
+      INTEGER                                  , INTENT(in   ) ::   kit000          ! first time step index
+      CHARACTER(len=3)                         , INTENT(in   ) ::   cdtype          ! =TRA or TRC (tracer indicator)
+      INTEGER                                  , INTENT(in   ) ::   kjpt            ! number of tracers
+      INTEGER                                  , INTENT(in   ) ::   kn_cen_h        ! =2/4 (2nd or 4th order scheme)
+      INTEGER                                  , INTENT(in   ) ::   kn_cen_v        ! =2/4 (2nd or 4th order scheme)
+      ! TEMP: [tiling] This can be A2D(nn_hls) after all lbc_lnks removed in the nn_hls = 2 case in tra_adv_fct
+      REAL(wp), DIMENSION(jpi,jpj,jpk         ), INTENT(in   ) ::   pU, pV, pW      ! 3 ocean volume flux components
+      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt,jpt), INTENT(inout) ::   pt              ! tracers and RHS of tracer equation
+      !
+      INTEGER  ::   ji, jj, jk, jn   ! dummy loop indices
+      INTEGER  ::   ierr             ! local integer
+      REAL(wp) ::   zC2t_u, zC4t_u   ! local scalars
+      REAL(wp) ::   zC2t_v, zC4t_v   !   -      -
+      REAL(wp) ::   zftw_kp1
+      REAL(wp), DIMENSION(A2D(1))              ::   zft_u, zft_v !, zft_w
+      REAL(wp), DIMENSION(:,:)   , ALLOCATABLE ::   zdt_u, zdt_v
+      REAL(wp), DIMENSION(:,:,:) , ALLOCATABLE ::   ztw
+      !!----------------------------------------------------------------------
+      !
+#if defined key_loop_fusion
+      CALL tra_adv_cen_lf    ( kt, nit000, cdtype, pU, pV, pW, Kmm, pt, kjpt, Krhs, kn_cen_h, kn_cen_v )
+#else
+      IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+         IF( kt == kit000 )  THEN
+            IF(lwp) WRITE(numout,*)
+            IF(lwp) WRITE(numout,*) 'tra_adv_cen : centered advection scheme on ', cdtype, ' order h/v =', kn_cen_h,'/', kn_cen_v
+            IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~ '
+         ENDIF
+         !                          ! set local switches
+         l_trd = .FALSE.
+         l_hst = .FALSE.
+         l_ptr = .FALSE.
+         IF( ( cdtype == 'TRA' .AND. l_trdtra ) .OR. ( cdtype == 'TRC' .AND. l_trdtrc ) )       l_trd = .TRUE.
+         IF(   cdtype == 'TRA' .AND. ( iom_use( 'sophtadv' ) .OR. iom_use( 'sophtadv' ) )  )    l_ptr = .TRUE.
+         IF(   cdtype == 'TRA' .AND. ( iom_use("uadv_heattr") .OR. iom_use("vadv_heattr") .OR. &
+            &                          iom_use("uadv_salttr") .OR. iom_use("vadv_salttr")  ) )  l_hst = .TRUE.
+      ENDIF
+      !
+      !                          !* 2nd order centered
+      DO jn = 1, kjpt            !==  loop over the tracers  ==!
+         !
+         DO jk = 1, jpkm1
+            !
+            DO_2D( 1, 0, 1, 0 )                     ! Horizontal fluxes at layer jk
+               zft_u(ji,jj) = 0.5_wp * pU(ji,jj,jk) * ( pt(ji,jj,jk,jn,Kmm) + pt(ji+1,jj  ,jk,jn,Kmm) )
+               zft_v(ji,jj) = 0.5_wp * pV(ji,jj,jk) * ( pt(ji,jj,jk,jn,Kmm) + pt(ji  ,jj+1,jk,jn,Kmm) )
+            END_2D
+            !
+            DO_2D( 0, 0, 0, 0 )                     ! Horizontal divergence of advective fluxes
+               pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) - (  zft_u(ji,jj) - zft_u(ji-1,jj  )    &
+                  &                                           + zft_v(ji,jj) - zft_v(ji  ,jj-1)  ) * r1_e1e2t(ji,jj)   &
+                  &                                        / e3t(ji,jj,jk,Kmm)
+            END_2D
+         END DO
+         !
+#define zft_w zft_u
+         IF( ln_linssh ) THEN                !* top value   (linear free surf. only as zwz is multiplied by wmask)
+            DO_2D( 0, 0, 0, 0 )
+               zft_w(ji,jj) = pW(ji,jj,1) * pt(ji,jj,1,jn,Kmm)
+            END_2D
+         ELSE
+            DO_2D( 0, 0, 0, 0 )
+               zft_w(ji,jj) = 0._wp
+            END_2D
+         ENDIF
+         DO jk = 1, jpk-2
+            DO_2D( 0, 0, 0, 0 )                             ! Vertical fluxes
+               zftw_kp1 = 0.5 * pW(ji,jj,jk+1) * ( pt(ji,jj,jk+1,jn,Kmm) + pt(ji,jj,jk,jn,Kmm) ) * wmask(ji,jj,jk+1)
+               !
+               pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) - (  zft_w(ji,jj) - zftw_kp1  ) * r1_e1e2t(ji,jj)   &
+                    &                                        / e3t(ji,jj,jk,Kmm)
+               zft_w(ji,jj) = zftw_kp1
+            END_2D
+         END DO
+         jk = jpkm1                                         ! bottom vertical flux set to zero for all tracers
+         DO_2D( 0, 0, 0, 0 )
+            pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) - zft_w(ji,jj) * r1_e1e2t(ji,jj)   &
+               &                                        / e3t(ji,jj,jk,Kmm)
+         END_2D
+         !
+      END DO
+      !
+         
+         !
+#undef zft_w
+         !                               ! trend diagnostics
+!!gm + !!st to be done with the whole rewritting of trd  
+!!          trd routine arguments MUST be changed adding jk and zwx, zwy in 2D
+!!         IF( l_trd ) THEN
+!!            CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_xad, zwx, pU, pt(:,:,:,jn,Kmm) )
+!!            CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_yad, zwy, pV, pt(:,:,:,jn,Kmm) )
+!!            CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_zad, zwz, pW, pt(:,:,:,jn,Kmm) )
+!!         ENDIF
+!!         !                                 ! "Poleward" heat and salt transports
+!!         IF( l_ptr )   CALL dia_ptr_hst( jn, 'adv', zwy(:,:,:) )
+!!         !                                 !  heat and salt transport
+!!         IF( l_hst )   CALL dia_ar5_hst( jn, 'adv', zwx(:,:,:), zwy(:,:,:) )
+         !
+      !
+      !
+#endif
+   END SUBROUTINE tra_adv_cen_test
+
+
    SUBROUTINE tra_adv_cen( kt, kit000, cdtype, pU, pV, pW,     &
+      &                    Kmm, pt, kjpt, Krhs, kn_cen_h, kn_cen_v )
+      !!----------------------------------------------------------------------
+      !!                  ***  ROUTINE tra_adv_cen  ***
+      !!
+      !! ** Purpose :   Compute the now trend due to the advection of tracers
+      !!      and add it to the general trend of passive tracer equations.
+      !!
+      !! ** Method  :   The advection is evaluated by a 2nd or 4th order scheme
+      !!               using now fields (leap-frog scheme).
+      !!       kn_cen_h = 2  ==>> 2nd order centered scheme on the horizontal
+      !!                = 4  ==>> 4th order    -        -       -      -
+      !!       kn_cen_v = 2  ==>> 2nd order centered scheme on the vertical
+      !!                = 4  ==>> 4th order COMPACT  scheme     -      -
+      !!
+      !! ** Action : - update pt(:,:,:,:,Krhs)  with the now advective tracer trends
+      !!             - send trends to trdtra module for further diagnostcs (l_trdtra=T)
+      !!             - poleward advective heat and salt transport (l_diaptr=T)
+      !!----------------------------------------------------------------------
+      INTEGER                                  , INTENT(in   ) ::   kt              ! ocean time-step index
+      INTEGER                                  , INTENT(in   ) ::   Kmm, Krhs       ! ocean time level indices
+      INTEGER                                  , INTENT(in   ) ::   kit000          ! first time step index
+      CHARACTER(len=3)                         , INTENT(in   ) ::   cdtype          ! =TRA or TRC (tracer indicator)
+      INTEGER                                  , INTENT(in   ) ::   kjpt            ! number of tracers
+      INTEGER                                  , INTENT(in   ) ::   kn_cen_h        ! =2/4 (2nd or 4th order scheme)
+      INTEGER                                  , INTENT(in   ) ::   kn_cen_v        ! =2/4 (2nd or 4th order scheme)
+      ! TEMP: [tiling] This can be A2D(nn_hls) after all lbc_lnks removed in the nn_hls = 2 case in tra_adv_fct
+      REAL(wp), DIMENSION(jpi,jpj,jpk         ), INTENT(in   ) ::   pU, pV, pW      ! 3 ocean volume flux components
+      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt,jpt), INTENT(inout) ::   pt              ! tracers and RHS of tracer equation
+      !
+      INTEGER  ::   ji, jj, jk, jn   ! dummy loop indices
+      INTEGER  ::   ierr             ! local integer
+      REAL(wp) ::   zC2t_u, zC4t_u   ! local scalars
+      REAL(wp) ::   zC2t_v, zC4t_v   !   -      -
+      REAL(wp) ::   zftw_kp1
+      REAL(wp), DIMENSION(A2D(1))              ::   zft_u, zft_v
+      REAL(wp), DIMENSION(:,:)   , ALLOCATABLE ::   zdt_u, zdt_v
+      REAL(wp), DIMENSION(:,:,:) , ALLOCATABLE ::   ztw
+      !!----------------------------------------------------------------------
+      !
+#if defined key_loop_fusion
+      CALL tra_adv_cen_lf    ( kt, nit000, cdtype, pU, pV, pW, Kmm, pt, kjpt, Krhs, kn_cen_h, kn_cen_v )
+#else
+      IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+         IF( kt == kit000 )  THEN
+            IF(lwp) WRITE(numout,*)
+            IF(lwp) WRITE(numout,*) 'tra_adv_cen : centered advection scheme on ', cdtype, ' order h/v =', kn_cen_h,'/', kn_cen_v
+            IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~ '
+         ENDIF
+         !                          ! set local switches
+         l_trd = .FALSE.
+         l_hst = .FALSE.
+         l_ptr = .FALSE.
+         IF( ( cdtype == 'TRA' .AND. l_trdtra ) .OR. ( cdtype == 'TRC' .AND. l_trdtrc ) )       l_trd = .TRUE.
+         IF(   cdtype == 'TRA' .AND. ( iom_use( 'sophtadv' ) .OR. iom_use( 'sophtadv' ) )  )    l_ptr = .TRUE.
+         IF(   cdtype == 'TRA' .AND. ( iom_use("uadv_heattr") .OR. iom_use("vadv_heattr") .OR. &
+            &                          iom_use("uadv_salttr") .OR. iom_use("vadv_salttr")  ) )  l_hst = .TRUE.
+      ENDIF
+      !
+      IF( kn_cen_h == 4 )   ALLOCATE( zdt_u(A2D(2)) , zdt_v(A2D(2)) )   ! horizontal 4th order only
+      IF( kn_cen_v == 4 )   ALLOCATE( ztw(A2D(nn_hls),jpk) )            ! vertical   4th order only
+      !
+      DO jn = 1, kjpt            !==  loop over the tracers  ==!
+         !
+         SELECT CASE( kn_cen_h )       !--  Horizontal divergence of advective fluxes  --!
+         !
+!!st limitation : does not take into acccount iceshelf specificity 
+!!                in case of linssh
+         CASE(  2  )                         !* 2nd order centered
+             DO jk = 1, jpkm1
+               !
+               DO_2D( 1, 0, 1, 0 )                     ! Horizontal fluxes at layer jk
+                  zft_u(ji,jj) = 0.5_wp * pU(ji,jj,jk) * ( pt(ji,jj,jk,jn,Kmm) + pt(ji+1,jj  ,jk,jn,Kmm) )
+                  zft_v(ji,jj) = 0.5_wp * pV(ji,jj,jk) * ( pt(ji,jj,jk,jn,Kmm) + pt(ji  ,jj+1,jk,jn,Kmm) )
+               END_2D
+               !
+               DO_2D( 0, 0, 0, 0 )                     ! Horizontal divergence of advective fluxes
+                  pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) - (  zft_u(ji,jj) - zft_u(ji-1,jj  )    &
+                     &                                           + zft_v(ji,jj) - zft_v(ji  ,jj-1)  ) * r1_e1e2t(ji,jj)   &
+                     &                                        / e3t(ji,jj,jk,Kmm)
+               END_2D
+            END DO
+            !
+         CASE(  4  )                         !* 4th order centered
+            DO jk = 1, jpkm1
+               DO_2D( 2, 1, 2, 1 )          ! masked gradient
+                  zdt_u(ji,jj) = ( pt(ji+1,jj  ,jk,jn,Kmm) - pt(ji,jj,jk,jn,Kmm) ) * umask(ji,jj,jk)
+                  zdt_v(ji,jj) = ( pt(ji  ,jj+1,jk,jn,Kmm) - pt(ji,jj,jk,jn,Kmm) ) * vmask(ji,jj,jk)
+               END_2D
+               !
+               DO_2D( 1, 0, 1, 0 )                    ! Horizontal advective fluxes
+                  zC2t_u = pt(ji,jj,jk,jn,Kmm) + pt(ji+1,jj  ,jk,jn,Kmm)   ! C2 interpolation of T at u- & v-points (x2)
+                  zC2t_v = pt(ji,jj,jk,jn,Kmm) + pt(ji  ,jj+1,jk,jn,Kmm)
+                  !                                                        ! C4 interpolation of T at u- & v-points (x2)
+                  zC4t_u =  zC2t_u + r1_6 * ( zdt_u(ji-1,jj  ) - zdt_u(ji+1,jj  ) )
+                  zC4t_v =  zC2t_v + r1_6 * ( zdt_v(ji  ,jj-1) - zdt_v(ji  ,jj+1) )
+                  !                                                        ! C4 fluxes
+                  zft_u(ji,jj) =  0.5_wp * pU(ji,jj,jk) * zC4t_u
+                  zft_v(ji,jj) =  0.5_wp * pV(ji,jj,jk) * zC4t_v
+               END_2D
+               !
+               DO_2D( 0, 0, 0, 0 )                                         ! Horizontal divergence of advective fluxes
+                  pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) - (  zft_u(ji,jj) - zft_u(ji-1,jj  )    &
+                     &                                           + zft_v(ji,jj) - zft_v(ji  ,jj-1)  ) * r1_e1e2t(ji,jj)   &
+                     &                                        / e3t(ji,jj,jk,Kmm)
+               END_2D
+            END DO
+            !
+         CASE DEFAULT
+            CALL ctl_stop( 'traadv_cen: wrong value for nn_cen' )
+         END SELECT
+         !
+#define zft_w  zft_u
+         !
+         IF( ln_linssh ) THEN                !* top value   (linear free surf. only as zwz is multiplied by wmask)
+            DO_2D( 0, 0, 0, 0 )
+               zft_w(ji,jj) = pW(ji,jj,1) * pt(ji,jj,1,jn,Kmm)
+            END_2D
+         ELSE
+            DO_2D( 0, 0, 0, 0 )
+               zft_w(ji,jj) = 0._wp
+            END_2D
+         ENDIF
+         !
+         SELECT CASE( kn_cen_v )       !--  Vertical divergence of advective fluxes  --!   (interior)
+         !
+         CASE(  2  )                         !* 2nd order centered
+            DO jk = 1, jpk-2
+               DO_2D( 0, 0, 0, 0 )                             ! Vertical fluxes
+                  zftw_kp1 = 0.5 * pW(ji,jj,jk+1) * ( pt(ji,jj,jk+1,jn,Kmm) + pt(ji,jj,jk,jn,Kmm) ) * wmask(ji,jj,jk+1)
+                  !
+                  pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) - (  zft_w(ji,jj) - zftw_kp1  ) * r1_e1e2t(ji,jj)   &
+                       &                                        / e3t(ji,jj,jk,Kmm)
+                  zft_w(ji,jj) = zftw_kp1
+               END_2D
+            END DO
+            jk = jpkm1                                         ! bottom vertical flux set to zero for all tracers
+            DO_2D( 0, 0, 0, 0 )
+               pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) - zft_w(ji,jj) * r1_e1e2t(ji,jj)   &
+                  &                                        / e3t(ji,jj,jk,Kmm)
+            END_2D
+            !
+         CASE(  4  )                         !* 4th order compact
+            CALL interp_4th_cpt( pt(:,:,:,jn,Kmm) , ztw )      ! ztw = interpolated value of T at w-point
+            !
+            DO jk = 1, jpk-2
+               !
+               DO_2D( 0, 0, 0, 0 )
+                  zftw_kp1 = pW(ji,jj,jk+1) * ztw(ji,jj,jk+1) * wmask(ji,jj,jk+1)
+                  !                          ! Divergence of advective fluxes
+                  pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) - (  zft_w(ji,jj) - zftw_kp1  ) * r1_e1e2t(ji,jj)   &
+                     &                                        / e3t(ji,jj,jk,Kmm)
+                  !                          ! update
+                  zft_w(ji,jj) = zftw_kp1
+               END_2D
+               !
+            END DO
+            !
+            jk = jpkm1       ! bottom vertical flux set to zero for all tracers
+            DO_2D( 0, 0, 0, 0 )
+               pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) - zft_w(ji,jj) * r1_e1e2t(ji,jj)   &
+                  &                                        / e3t(ji,jj,jk,Kmm)
+            END_2D
+            !
+         END SELECT
+         !
+#undef zft_w
+         !                               ! trend diagnostics
+!!gm + !!st to be done with the whole rewritting of trd  
+!!          trd routine arguments MUST be changed adding jk and zwx, zwy in 2D
+!!         IF( l_trd ) THEN
+!!            CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_xad, zwx, pU, pt(:,:,:,jn,Kmm) )
+!!            CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_yad, zwy, pV, pt(:,:,:,jn,Kmm) )
+!!            CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_zad, zwz, pW, pt(:,:,:,jn,Kmm) )
+!!         ENDIF
+!!         !                                 ! "Poleward" heat and salt transports
+!!         IF( l_ptr )   CALL dia_ptr_hst( jn, 'adv', zwy(:,:,:) )
+!!         !                                 !  heat and salt transport
+!!         IF( l_hst )   CALL dia_ar5_hst( jn, 'adv', zwx(:,:,:), zwy(:,:,:) )
+         !
+      END DO
+      !
+      IF( kn_cen_h == 4 )   DEALLOCATE( zdt_u , zdt_v )   ! horizontal 4th order only
+      IF( kn_cen_v == 4 )   DEALLOCATE( ztw )             ! vertical   4th order only
+      !
+#endif
+   END SUBROUTINE tra_adv_cen
+
+
+   SUBROUTINE tra_adv_cen_hls1( kt, kit000, cdtype, pU, pV, pW,     &
       &                    Kmm, pt, kjpt, Krhs, kn_cen_h, kn_cen_v )
       !!----------------------------------------------------------------------
       !!                  ***  ROUTINE tra_adv_cen  ***
@@ -141,6 +457,12 @@ CONTAINS
          CASE DEFAULT
             CALL ctl_stop( 'traadv_cen: wrong value for nn_cen' )
          END SELECT
+         DO_3D( 0, 0, 0, 0, 1, jpkm1 )   !--  Divergence of advective fluxes  --!
+            pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs)    &
+               &             - (  zwx(ji,jj,jk) - zwx(ji-1,jj  ,jk  )    &
+               &                + zwy(ji,jj,jk) - zwy(ji  ,jj-1,jk  )  ) &
+               &                * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
+         END_3D
          !
          SELECT CASE( kn_cen_v )       !--  Vertical fluxes  --!   (interior)
          !
@@ -171,11 +493,17 @@ CONTAINS
          !
          DO_3D( 0, 0, 0, 0, 1, jpkm1 )   !--  Divergence of advective fluxes  --!
             pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs)    &
-               &             - (  zwx(ji,jj,jk) - zwx(ji-1,jj  ,jk  )    &
-               &                + zwy(ji,jj,jk) - zwy(ji  ,jj-1,jk  )    &
-               &                + zwz(ji,jj,jk) - zwz(ji  ,jj  ,jk+1)  ) &
+               &             - (  zwz(ji,jj,jk) - zwz(ji  ,jj  ,jk+1)  ) &
                &                * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
          END_3D
+!
+!!st         DO_3D( 0, 0, 0, 0, 1, jpkm1 )   !--  Divergence of advective fluxes  --!
+!!st            pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs)    &
+!!st               &             - (  zwx(ji,jj,jk) - zwx(ji-1,jj  ,jk  )    &
+!!st               &                + zwy(ji,jj,jk) - zwy(ji  ,jj-1,jk  )    &
+!!st               &                + zwz(ji,jj,jk) - zwz(ji  ,jj  ,jk+1)  ) &
+!!st               &                * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
+!!st         END_3D
          !                               ! trend diagnostics
          IF( l_trd ) THEN
             CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_xad, zwx, pU, pt(:,:,:,jn,Kmm) )
@@ -190,7 +518,7 @@ CONTAINS
       END DO
       !
 #endif
-   END SUBROUTINE tra_adv_cen
+   END SUBROUTINE tra_adv_cen_hls1
 
    !!======================================================================
 END MODULE traadv_cen
diff --git a/src/OCE/TRA/traadv_mus.F90 b/src/OCE/TRA/traadv_mus.F90
index 4c4b0437ca01cb250cf6f560527e8b0b5a632803..c22fcfd01f44ed4ad18071d829c32b6853371ade 100644
--- a/src/OCE/TRA/traadv_mus.F90
+++ b/src/OCE/TRA/traadv_mus.F90
@@ -9,6 +9,7 @@ MODULE traadv_mus
    !!            3.2  !  2010-05  (C. Ethe, G. Madec)  merge TRC-TRA + switch from velocity to transport
    !!            3.4  !  2012-06  (P. Oddo, M. Vichi) include the upstream where needed
    !!            3.7  !  2015-09  (G. Madec) add the ice-shelf cavities boundary condition
+   !!            4.5  !  2022-06  (S. Techene, G, Madec) refactorization to reduce local memory usage
    !!----------------------------------------------------------------------
 
    !!----------------------------------------------------------------------
@@ -34,7 +35,9 @@ MODULE traadv_mus
    IMPLICIT NONE
    PRIVATE
 
-   PUBLIC   tra_adv_mus   ! routine called by traadv.F90
+   PUBLIC   tra_adv_mus        ! routine called by traadv.F90
+   PUBLIC   tra_adv_mus_hls1   ! routine called by traadv.F90
+
 
    REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   upsmsk   !: mixed upstream/centered scheme near some straits
    !                                                           !  and in closed seas (orca 2 and 1 configurations)
@@ -55,6 +58,217 @@ MODULE traadv_mus
 CONTAINS
 
    SUBROUTINE tra_adv_mus( kt, kit000, cdtype, p2dt, pU, pV, pW,             &
+      &                    Kbb, Kmm, pt, kjpt, Krhs, ld_msc_ups )
+      !!----------------------------------------------------------------------
+      !!                    ***  ROUTINE tra_adv_mus  ***
+      !!
+      !! ** Purpose :   Compute the now trend due to total advection of tracers
+      !!              using a MUSCL scheme (Monotone Upstream-centered Scheme for
+      !!              Conservation Laws) and add it to the general tracer trend.
+      !!
+      !! ** Method  : MUSCL scheme plus centered scheme at ocean boundaries
+      !!              ld_msc_ups=T :
+      !!
+      !! ** Action : - update pt(:,:,:,:,Krhs)  with the now advective tracer trends
+      !!             - send trends to trdtra module for further diagnostcs (l_trdtra=T)
+      !!             - poleward advective heat and salt transport (ln_diaptr=T)
+      !!
+      !! References : Estubier, A., and M. Levy, Notes Techn. Pole de Modelisation
+      !!              IPSL, Sept. 2000 (http://www.lodyc.jussieu.fr/opa)
+      !!----------------------------------------------------------------------
+      INTEGER                                  , INTENT(in   ) ::   kt              ! ocean time-step index
+      INTEGER                                  , INTENT(in   ) ::   Kbb, Kmm, Krhs  ! ocean time level indices
+      INTEGER                                  , INTENT(in   ) ::   kit000          ! first time step index
+      CHARACTER(len=3)                         , INTENT(in   ) ::   cdtype          ! =TRA or TRC (tracer indicator)
+      INTEGER                                  , INTENT(in   ) ::   kjpt            ! number of tracers
+      LOGICAL                                  , INTENT(in   ) ::   ld_msc_ups      ! use upstream scheme within muscl
+      REAL(wp)                                 , INTENT(in   ) ::   p2dt            ! tracer time-step
+      ! TEMP: [tiling] This can be A2D(nn_hls) after all lbc_lnks removed in the nn_hls = 2 case in tra_adv_fct
+      REAL(wp), DIMENSION(jpi,jpj,jpk         ), INTENT(in   ) ::   pU, pV, pW      ! 3 ocean volume flux components
+      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt,jpt), INTENT(inout) ::   pt              ! tracers and RHS of tracer equation
+      !
+      INTEGER  ::   ji, jj, jk, jn   ! dummy loop indices
+      INTEGER  ::   ierr             ! local integer
+      INTEGER  ::   ik
+      REAL(wp) ::   zu, z0u, zzslpx, zzwx, zw , zalpha   ! local scalars
+      REAL(wp) ::   zv, z0v, zzslpy, zzwy, z0w           !   -      -
+      REAL(wp) ::   zdzt_kp2, zslpz_kp1, zfW_kp1
+      REAL(wp), DIMENSION(A2D(2)) ::   zdxt, zslpx, zwx  ! 2D workspace
+      REAL(wp), DIMENSION(A2D(2)) ::   zdyt, zslpy, zwy  ! -      -
+      !!----------------------------------------------------------------------
+      !
+      IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+         IF( kt == kit000 )  THEN
+            IF(lwp) WRITE(numout,*)
+            IF(lwp) WRITE(numout,*) 'tra_adv : MUSCL advection scheme on ', cdtype
+            IF(lwp) WRITE(numout,*) '        : mixed up-stream           ', ld_msc_ups
+            IF(lwp) WRITE(numout,*) '~~~~~~~'
+            IF(lwp) WRITE(numout,*)
+            !
+            ! Upstream / MUSCL scheme indicator
+            !
+            ALLOCATE( xind(jpi,jpj,jpk), STAT=ierr )
+            xind(:,:,:) = 1._wp              ! set equal to 1 where up-stream is not needed
+            IF( ld_msc_ups ) THEN            ! define the upstream indicator (if asked)
+               DO jk = 1, jpkm1
+                  xind(:,:,jk) = 1._wp                              &                 ! =>1 where up-stream is not needed
+                     &                -  rnfmsk(:,:) * rnfmsk_z(jk) * tmask(:,:,jk)   ! =>0 near runoff mouths (& closed sea outflows) 
+               END DO
+            ENDIF
+            !
+         ENDIF
+         !
+         l_trd = .FALSE.
+         l_hst = .FALSE.
+         l_ptr = .FALSE.
+         IF(              ( cdtype == 'TRA' .AND. l_trdtra ) .OR. ( cdtype == 'TRC' .AND. l_trdtrc ) )        l_trd = .TRUE.
+         IF( l_diaptr .AND. cdtype == 'TRA' .AND. ( iom_use( 'sophtadv' ) .OR. iom_use( 'sophtadv' ) )  )     l_ptr = .TRUE.
+         IF( l_iom    .AND. cdtype == 'TRA' .AND. ( iom_use("uadv_heattr") .OR. iom_use("vadv_heattr") .OR. &
+            &                                       iom_use("uadv_salttr") .OR. iom_use("vadv_salttr")  ) )   l_hst = .TRUE.
+      ENDIF
+      !
+      !
+      DO jn = 1, kjpt            !==  loop over the tracers  ==!
+         !
+         DO jk = 1, jpkm1
+            !                          !* Horizontal advective fluxes
+            !
+            !                                !-- first guess of the slopes
+            DO_2D( 2, 1, 2, 1 )
+               zdxt(ji,jj) = ( pt(ji+1,jj  ,jk,jn,Kbb) - pt(ji,jj,jk,jn,Kbb) ) * umask(ji,jj,jk)
+               zdyt(ji,jj) = ( pt(ji  ,jj+1,jk,jn,Kbb) - pt(ji,jj,jk,jn,Kbb) ) * vmask(ji,jj,jk)
+            END_2D
+            !                                !-- Slopes of tracer
+            DO_2D( 1, 1, 1, 1 )
+               !                                 ! 1/2 Slopes at T-point (set to 0 if adjectent slopes are of opposite sign)
+               zzslpx =                          ( zdxt(ji,jj) + zdxt(ji-1,jj  ) )   &
+                  &   * ( 0.25_wp + SIGN( 0.25_wp, zdxt(ji,jj) * zdxt(ji-1,jj  ) ) )
+               zzslpy =                          ( zdyt(ji,jj) + zdyt(ji  ,jj-1) )   &
+                  &   * ( 0.25_wp + SIGN( 0.25_wp, zdyt(ji,jj) * zdyt(ji  ,jj-1) ) )
+               !                                 ! Slopes limitation
+               zslpx(ji,jj) = SIGN( 1.0_wp, zzslpx ) * MIN(       ABS( zzslpx         ),   &
+                  &                                         2._wp*ABS( zdxt (ji-1,jj) ),   &
+                  &                                         2._wp*ABS( zdxt (ji  ,jj) )    )
+               zslpy(ji,jj) = SIGN( 1.0_wp, zzslpy ) * MIN(       ABS( zzslpy         ),   &
+                  &                                         2._wp*ABS( zdyt (ji,jj-1) ),   &
+                  &                                         2._wp*ABS( zdyt (ji,jj  ) )    )
+            END_2D
+!!gm + !!st ticket ? comparaison pommes et carrottes ABS(zzslpx) et 2._wp*ABS( zdxt (ji-1,jj) )
+            !
+            DO_2D( 1, 0, 1, 0 )              !-- MUSCL horizontal advective fluxes
+               z0u = SIGN( 0.5_wp, pU(ji,jj,jk) )
+               zalpha = 0.5_wp - z0u
+               zu  = z0u - 0.5_wp * pU(ji,jj,jk) * p2dt * r1_e1e2u(ji,jj) / e3u(ji,jj,jk,Kmm)
+               zzwx = pt(ji+1,jj,jk,jn,Kbb) + xind(ji,jj,jk) * zu * zslpx(ji+1,jj)
+               zzwy = pt(ji  ,jj,jk,jn,Kbb) + xind(ji,jj,jk) * zu * zslpx(ji  ,jj)
+               zwx(ji,jj) = pU(ji,jj,jk) * ( zalpha * zzwx + (1._wp-zalpha) * zzwy )
+               !
+               z0v = SIGN( 0.5_wp, pV(ji,jj,jk) )
+               zalpha = 0.5_wp - z0v
+               zv  = z0v - 0.5_wp * pV(ji,jj,jk) * p2dt * r1_e1e2v(ji,jj) / e3v(ji,jj,jk,Kmm)
+               zzwx = pt(ji,jj+1,jk,jn,Kbb) + xind(ji,jj,jk) * zv * zslpy(ji,jj+1)
+               zzwy = pt(ji,jj  ,jk,jn,Kbb) + xind(ji,jj,jk) * zv * zslpy(ji,jj  )
+               zwy(ji,jj) = pV(ji,jj,jk) * ( zalpha * zzwx + (1._wp-zalpha) * zzwy )
+            END_2D
+            !
+            DO_2D( 0, 0, 0, 0 )              !-- Tracer advective trend
+               pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) - ( zwx(ji,jj) - zwx(ji-1,jj  )       &
+               &                                             + zwy(ji,jj) - zwy(ji  ,jj-1) )     &
+               &                                   * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
+            END_2D
+         END DO
+!!gm + !!st to be done with the whole rewritting of trd  
+!!          trd routine arguments MUST be changed adding jk and zwx, zwy in 2D
+!!
+!!         !                                ! trend diagnostics
+!!         IF( l_trd )  THEN
+!!            CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jk, jptra_xad, zwx(:,:), pU, pt(:,:,:,jn,Kbb) )
+!!            CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jk, jptra_yad, zwy(:,:), pV, pt(:,:,:,jn,Kbb) )
+!!         END IF
+!!         !                                 ! "Poleward" heat and salt transports
+!!         IF( l_ptr )  CALL dia_ptr_hst( jn, jk, 'adv', zwy(:,:) )
+!!         !                                 !  heat transport
+!!         IF( l_hst )  CALL dia_ar5_hst( jn, jk, 'adv', zwx(:,:), zwy(:,:) )
+         !
+         !                          !* Vertical advective fluxes
+         !
+#define zdzt_kp1 zdxt 
+#define zslpz zslpx
+#define zfW zwx 
+
+         zfW     (A2D(0)) = 0._wp    ! anciennement zwx at jk = 1
+         !                          ! anciennement zwx at jk = 2
+         DO_2D( 0, 0, 0, 0 )
+            zdzt_kp1(ji,jj) = tmask(ji,jj,2) * ( pt(ji,jj,1,jn,Kbb) - pt(ji,jj,2,jn,Kbb) )
+         END_2D
+         zslpz   (A2D(0)) = 0._wp    ! anciennement zslpx at jk = 1
+         !
+         IF( ln_linssh ) THEN                !-- linear ssh : non zero top values
+            DO_2D( 0, 0, 0, 0 )                       ! at the ocean surface
+               zfW(ji,jj) = pW(ji,jj,1) * pt(ji,jj,1,jn,Kbb)    ! surface flux
+            END_2D
+            IF( ln_isfcav ) THEN                      ! ice-shelf cavities (top of the ocean)
+               DO_2D( 0, 0, 0, 0 )                              ! update pt(Krhs) under the ice-shelf  
+                  ik = mikt(ji,jj)                              ! the flux at ik-1 is zero ( inside ice-shelf )
+                  IF( ik > 1 ) THEN
+                     pt(ji,jj,ik,jn,Krhs) =  pt(ji,jj,ik,jn,Krhs) - pW(ji,jj,ik) * pt(ji,jj,ik,jn,Kbb)   &
+                        &                                         * r1_e1e2t(ji,jj) / e3t(ji,jj,ik,Kmm)
+                  ENDIF
+               END_2D              
+            ENDIF
+         ENDIF
+         !
+         ! wmask usage for computing zw and zwk is needed in isf case and linear ssh
+         ! 
+         !
+         DO jk = 1, jpkm1
+            IF( jk < jpkm1 ) THEN
+               DO_2D( 0, 0, 0, 0 )
+                  !                          !-- Slopes of tracer
+                  !                                   ! masked vertical gradient at jk+2
+                  zdzt_kp2 = ( pt(ji,jj,jk+1,jn,Kbb) - pt(ji,jj,jk+2,jn,Kbb) ) * tmask(ji,jj,jk+2) !!st wmask(ji,jj,jk+2)
+                  !                                   ! vertical slope at jk+1
+                  zslpz_kp1 =                           ( zdzt_kp1(ji,jj) + zdzt_kp2 )  &
+                  &         * (  0.25_wp + SIGN( 0.25_wp, zdzt_kp1(ji,jj) * zdzt_kp2 )  )
+                  !                                   ! slope limitation
+                  zslpz_kp1 = SIGN( 1.0_wp, zslpz_kp1 ) * MIN(    ABS( zslpz_kp1 ),   &
+                  &                                            2.*ABS( zdzt_kp2 ),   &
+                  &                                            2.*ABS( zdzt_kp1(ji,jj) )  )
+                  !                          !-- vertical advective flux at jk+1
+                  !                          !    caution: zfW_kp1 is masked for ice-shelf cavities
+                  !                          !    since top fluxes already added to pt(Krhs) before the vertical loop  
+                  z0w = SIGN( 0.5_wp, pW(ji,jj,jk+1) )
+                  zalpha = 0.5_wp + z0w
+                  zw  = z0w - 0.5_wp * pW(ji,jj,jk+1) * p2dt * r1_e1e2t(ji,jj) / e3w(ji,jj,jk+1,Kmm)
+                  zzwx = pt(ji,jj,jk+1,jn,Kbb) + xind(ji,jj,jk) * zw * zslpz_kp1
+                  zzwy = pt(ji,jj,jk  ,jn,Kbb) + xind(ji,jj,jk) * zw * zslpz(ji,jj)
+                  zfW_kp1 = pW(ji,jj,jk+1) * ( zalpha * zzwx + (1.-zalpha) * zzwy ) * wmask(ji,jj,jk)!!st * wmask(ji,jj,jk+1)
+                  !                         !-- vertical advective trend at jk
+                  pt(ji,jj,jk,jn,Krhs) =  pt(ji,jj,jk,jn,Krhs) - ( zfW(ji,jj) - zfW_kp1 )   &
+                     &                                      * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
+                  !                                   ! updates for next level
+                  zdzt_kp1(ji,jj) = zdzt_kp2
+                  zslpz   (ji,jj) = zslpz_kp1
+                  zfW     (ji,jj) = zfW_kp1
+               END_2D
+            ELSE
+               DO_2D( 0, 0, 0, 0 )          !-- vertical advective trend at jpkm1
+                  pt(ji,jj,jk,jn,Krhs) =  pt(ji,jj,jk,jn,Krhs) - zfW(ji,jj)    &
+                     &                                      * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
+               END_2D
+            ENDIF
+	 END DO                  ! end of jk loop
+         !
+!!gm + !!st idem see above
+!!         !                                ! send trends for diagnostic
+!!         IF( l_trd )  CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_zad, zwx, pW, pt(:,:,:,jn,Kbb) )
+         !
+      END DO                     ! end of tracer loop
+      !
+   END SUBROUTINE tra_adv_mus
+
+
+   SUBROUTINE tra_adv_mus_hls1( kt, kit000, cdtype, p2dt, pU, pV, pW,             &
       &                    Kbb, Kmm, pt, kjpt, Krhs, ld_msc_ups )
       !!----------------------------------------------------------------------
       !!                    ***  ROUTINE tra_adv_mus  ***
@@ -178,7 +392,7 @@ CONTAINS
          !
          DO_3D( 0, 0, 0, 0, 1, jpkm1 )    !-- Tracer advective trend
             pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) - ( zwx(ji,jj,jk) - zwx(ji-1,jj  ,jk  )       &
-            &                                     + zwy(ji,jj,jk) - zwy(ji  ,jj-1,jk  ) )     &
+            &                                             + zwy(ji,jj,jk) - zwy(ji  ,jj-1,jk  ) )     &
             &                                   * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
          END_3D
          !                                ! trend diagnostics
@@ -239,7 +453,7 @@ CONTAINS
          !
       END DO                     ! end of tracer loop
       !
-   END SUBROUTINE tra_adv_mus
+   END SUBROUTINE tra_adv_mus_hls1
 
    !!======================================================================
 END MODULE traadv_mus
diff --git a/src/OCE/TRA/trazdf.F90 b/src/OCE/TRA/trazdf.F90
index 6e7dd9a249bebc44102a67bf2ff140da9282c1de..7123aeba37c7fe1419e207dd89407a28d569e25e 100644
--- a/src/OCE/TRA/trazdf.F90
+++ b/src/OCE/TRA/trazdf.F90
@@ -6,6 +6,7 @@ MODULE trazdf
    !! History :  1.0  !  2005-11  (G. Madec)  Original code
    !!            3.0  !  2008-01  (C. Ethe, G. Madec)  merge TRC-TRA
    !!            4.0  !  2017-06  (G. Madec)  remove explict time-stepping option
+   !!            4.5  !  2022-06  (G. Madec)  refactoring to reduce memory usage (j-k-i loops)
    !!----------------------------------------------------------------------
 
    !!----------------------------------------------------------------------
@@ -22,7 +23,7 @@ MODULE trazdf
    USE ldfslp         ! lateral diffusion: iso-neutral slope
    USE trd_oce        ! trends: ocean variables
    USE trdtra         ! trends: tracer trend manager
-   USE eosbn2, ONLY: ln_SEOS, rn_b0
+   USE eosbn2   , ONLY: ln_SEOS, rn_b0
    !
    USE in_out_manager ! I/O manager
    USE prtctl         ! Print control
@@ -77,7 +78,7 @@ CONTAINS
       ENDIF
       !
       !                                      !* compute lateral mixing trend and add it to the general trend
-      CALL tra_zdf_imp( kt, nit000, 'TRA', rDt, Kbb, Kmm, Krhs, pts, Kaa, jpts )
+      CALL tra_zdf_imp( 'TRA', Kbb, Kmm, Krhs, pts, Kaa, jpts )
 
 !!gm WHY here !   and I don't like that !
       ! DRAKKAR SSS control {
@@ -116,7 +117,7 @@ CONTAINS
    END SUBROUTINE tra_zdf
 
 
-   SUBROUTINE tra_zdf_imp( kt, kit000, cdtype, p2dt, Kbb, Kmm, Krhs, pt, Kaa, kjpt )
+   SUBROUTINE tra_zdf_imp( cdtype, Kbb, Kmm, Krhs, pt, Kaa, kjpt )
       !!----------------------------------------------------------------------
       !!                  ***  ROUTINE tra_zdf_imp  ***
       !!
@@ -136,128 +137,177 @@ CONTAINS
       !!
       !! ** Action  : - pt(:,:,:,:,Kaa)  becomes the after tracer
       !!---------------------------------------------------------------------
-      INTEGER                                  , INTENT(in   ) ::   kt       ! ocean time-step index
       INTEGER                                  , INTENT(in   ) ::   Kbb, Kmm, Krhs, Kaa  ! ocean time level indices
-      INTEGER                                  , INTENT(in   ) ::   kit000   ! first time step index
       CHARACTER(len=3)                         , INTENT(in   ) ::   cdtype   ! =TRA or TRC (tracer indicator)
       INTEGER                                  , INTENT(in   ) ::   kjpt     ! number of tracers
-      REAL(wp)                                 , INTENT(in   ) ::   p2dt     ! tracer time-step
       REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt,jpt), INTENT(inout) ::   pt       ! tracers and RHS of tracer equation
       !
       INTEGER  ::  ji, jj, jk, jn   ! dummy loop indices
       REAL(wp) ::  zrhs, zzwi, zzws ! local scalars
-      REAL(wp), DIMENSION(A2D(0),jpk) ::  zwi, zwt, zwd, zws
+      REAL(wp), DIMENSION(A1Di(0),jpk) ::  zwi, zwt, zwd, zws
       !!---------------------------------------------------------------------
       !
-      !                                               ! ============= !
-      DO jn = 1, kjpt                                 !  tracer loop  !
-         !                                            ! ============= !
-         !  Matrix construction
-         ! --------------------
-         ! Build matrix if temperature or salinity (only in double diffusion case) or first passive tracer
-         !
-         IF(  ( cdtype == 'TRA' .AND. ( jn == jp_tem .OR. ( jn == jp_sal .AND. ln_zdfddm ) ) ) .OR.   &
-            & ( cdtype == 'TRC' .AND. jn == 1 )  )  THEN
+      !                                               ! ================= !
+      DO_1Dj( 0, 0 )                                  !  i-k slices loop  !
+         !                                            ! ================= !
+         DO jn = 1, kjpt                              !    tracer loop    !
+            !                                         ! ================= !
             !
-            ! vertical mixing coef.: avt for temperature, avs for salinity and passive tracers
-            IF( cdtype == 'TRA' .AND. jn == jp_tem ) THEN
-               DO_3D( 0, 0, 0, 0, 2, jpk )
-                  zwt(ji,jj,jk) = avt(ji,jj,jk)
-               END_3D
-            ELSE
-               DO_3D( 0, 0, 0, 0, 2, jpk )
-                  zwt(ji,jj,jk) = avs(ji,jj,jk)
-               END_3D
-            ENDIF
-            zwt(:,:,1) = 0._wp
+            !  Matrix construction
+            ! --------------------
+            ! Build matrix if temperature or salinity (only in double diffusion case) or first passive tracer
             !
-            IF( l_ldfslp ) THEN            ! isoneutral diffusion: add the contribution
-               IF( ln_traldf_msc  ) THEN     ! MSC iso-neutral operator
-                  DO_3D( 0, 0, 0, 0, 2, jpkm1 )
-                     zwt(ji,jj,jk) = zwt(ji,jj,jk) + akz(ji,jj,jk)
-                  END_3D
-               ELSE                          ! standard or triad iso-neutral operator
-                  DO_3D( 0, 0, 0, 0, 2, jpkm1 )
-                     zwt(ji,jj,jk) = zwt(ji,jj,jk) + ah_wslp2(ji,jj,jk)
-                  END_3D
+            IF(  ( cdtype == 'TRA' .AND. ( jn == jp_tem .OR. ( jn == jp_sal .AND. ln_zdfddm ) ) ) .OR.   &
+               & ( cdtype == 'TRC' .AND. jn == 1 )  )  THEN
+               !
+               ! vertical mixing coef.: avt for temperature, avs for salinity and passive tracers
+               !
+               IF( cdtype == 'TRA' .AND. jn == jp_tem ) THEN     ! use avt  for temperature
+                  !
+                  IF( l_ldfslp ) THEN            ! use avt + isoneutral diffusion contribution
+                     IF( ln_traldf_msc  ) THEN        ! MSC iso-neutral operator
+                        DO_2Dik( 0, 0,   2, jpk, 1 )
+                           zwt(ji,jk) = avt(ji,jj,jk) + akz(ji,jj,jk)
+                        END_2D
+                     ELSE                             ! standard or triad iso-neutral operator
+                        DO_2Dik( 0, 0,   2, jpk, 1 )
+                           zwt(ji,jk) = avt(ji,jj,jk) + ah_wslp2(ji,jj,jk)
+                        END_2D
+                     ENDIF
+                  ELSE                          ! use avt only
+                     DO_2Dik( 0, 0,   2, jpk, 1 )
+                        zwt(ji,jk) = avt(ji,jj,jk)
+                     END_2D
+                  ENDIF
+                  !
+               ELSE                                               ! use avs for salinty or passive tracers
+                  !
+                  IF( l_ldfslp ) THEN            ! use avs + isoneutral diffusion contribution
+                     IF( ln_traldf_msc  ) THEN        ! MSC iso-neutral operator
+                        DO_2Dik( 0, 0,   2, jpk, 1 )
+                           zwt(ji,jk) = avs(ji,jj,jk) + akz(ji,jj,jk)
+                        END_2D
+                     ELSE                             ! standard or triad iso-neutral operator
+                        DO_2Dik( 0, 0,   2, jpk, 1 )
+                           zwt(ji,jk) = avs(ji,jj,jk) + ah_wslp2(ji,jj,jk)
+                        END_2D
+                     ENDIF
+                  ELSE                          ! 
+                     DO_2Dik( 0, 0,   2, jpk, 1 )
+                        zwt(ji,jk) = avs(ji,jj,jk)
+                     END_2D
+                  ENDIF
                ENDIF
+               zwt(:,1) = 0._wp
+               !
+               ! Diagonal, lower (i), upper (s)  (including the bottom boundary condition since avt is masked)
+               IF( ln_zad_Aimp ) THEN         ! Adaptive implicit vertical advection
+                  DO_2Dik( 0, 0,   1, jpkm1, 1 )
+                     zzwi = - rDt * zwt(ji,jk  ) / e3w(ji,jj,jk  ,Kmm)
+                     zzws = - rDt * zwt(ji,jk+1) / e3w(ji,jj,jk+1,Kmm)
+                     zwd(ji,jk) = e3t(ji,jj,jk,Kaa) - zzwi - zzws   &
+                        &              + rDt * ( MAX( wi(ji,jj,jk  ) , 0._wp ) &
+                        &                      - MIN( wi(ji,jj,jk+1) , 0._wp ) )
+                     zwi(ji,jk) = zzwi + rDt *   MIN( wi(ji,jj,jk  ) , 0._wp )
+                     zws(ji,jk) = zzws - rDt *   MAX( wi(ji,jj,jk+1) , 0._wp )
+                  END_2D
+               ELSE
+                  DO_2Dik( 0, 0,   1, jpkm1, 1 )
+                     zwi(ji,jk) = - rDt * zwt(ji,jk  ) / e3w(ji,jj,jk,Kmm)
+                     zws(ji,jk) = - rDt * zwt(ji,jk+1) / e3w(ji,jj,jk+1,Kmm)
+                     zwd(ji,jk) = e3t(ji,jj,jk,Kaa) - zwi(ji,jk) - zws(ji,jk)
+                  END_2D
+               ENDIF
+               !
+!!gm  BUG?? : if edmfm is equivalent to a w  ==>>>   just add +/-  rDt * edmfm(ji,jj,jk+1/jk  )
+!!            but edmfm is at t-point !!!!   crazy???  why not keep it at w-point????
+               !
+               IF( ln_zdfmfc ) THEN    ! add upward Mass Flux in the matrix
+                  DO_2Dik( 0, 0,   1, jpkm1, 1 )
+                     zws(ji,jk) = zws(ji,jk) + e3t(ji,jj,jk,Kaa) * rDt * edmfm(ji,jj,jk+1) / e3w(ji,jj,jk+1,Kmm)
+                     zwd(ji,jk) = zwd(ji,jk) - e3t(ji,jj,jk,Kaa) * rDt * edmfm(ji,jj,jk  ) / e3w(ji,jj,jk+1,Kmm)
+                  END_2D
+               ENDIF
+!       DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+!          edmfa(ji,jj,jk) =  0._wp
+!          edmfb(ji,jj,jk) = -edmfm(ji,jj,jk  ) / e3w(ji,jj,jk+1,Kmm)
+!          edmfc(ji,jj,jk) =  edmfm(ji,jj,jk+1) / e3w(ji,jj,jk+1,Kmm)
+!       END_3D
+!!gm    BUG :  level jpk never used in the inversion
+!       DO_2D( 0, 0, 0, 0 )
+!          edmfa(ji,jj,jpk)   = -edmfm(ji,jj,jpk-1) / e3w(ji,jj,jpk,Kmm)
+!          edmfb(ji,jj,jpk)   =  edmfm(ji,jj,jpk  ) / e3w(ji,jj,jpk,Kmm)
+!          edmfc(ji,jj,jpk)   =  0._wp
+!       END_2D
+!!
+!!gm   BUG ???   below  e3t_Kmm  should be used ?  
+!!               or even no multiplication by e3t unless there is a bug in wi calculation
+!!
+!                   DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+!!gm edmfa = 0._wp except at jpk which is not used  ==>>  zdiagi update is useless !
+!                      zdiagi(ji,jj,jk) = zdiagi(ji,jj,jk) + e3t(ji,jj,jk,Kaa) * p2dt *edmfa(ji,jj,jk)
+!                      zdiags(ji,jj,jk) = zdiags(ji,jj,jk) + e3t(ji,jj,jk,Kaa) * p2dt *edmfc(ji,jj,jk)
+!                      zdiagd(ji,jj,jk) = zdiagd(ji,jj,jk) + e3t(ji,jj,jk,Kaa) * p2dt *edmfb(ji,jj,jk)
+!                   END_3D
+!!gm                  CALL diag_mfc( zwi, zwd, zws, rDt, Kaa )
+!!gm   SUBROUTINE diag_mfc( zdiagi, zdiagd, zdiags, p2dt, Kaa )
+               !
+               !! Matrix inversion from the first level
+               !!----------------------------------------------------------------------
+               !   solve m.x = y  where m is a tri diagonal matrix ( jpk*jpk )
+               !
+               !        ( zwd1 zws1   0    0    0  )( zwx1 ) ( zwy1 )
+               !        ( zwi2 zwd2 zws2   0    0  )( zwx2 ) ( zwy2 )
+               !        (  0   zwi3 zwd3 zws3   0  )( zwx3 )=( zwy3 )
+               !        (        ...               )( ...  ) ( ...  )
+               !        (  0    0    0   zwik zwdk )( zwxk ) ( zwyk )
+               !
+               !   m is decomposed in the product of an upper and lower triangular matrix.
+               !   The 3 diagonal terms are in 3d arrays: zwd, zws, zwi.
+               !   Suffices i,s and d indicate "inferior" (below diagonal), diagonal
+               !   and "superior" (above diagonal) components of the tridiagonal system.
+               !   The solution will be in the 4d array pta.
+               !   The 3d array zwt is used as a work space array.
+               !   En route to the solution pt(:,:,:,:,Kaa) is used a to evaluate the rhs and then
+               !   used as a work space array: its value is modified.
+               !
+               DO_1Di( 0, 0 )          !* 1st recurrence:   Tk = Dk - Ik Sk-1 / Tk-1   (increasing k) ! done one for all passive tracers (so included in the IF instruction)
+                  zwt(ji,1) = zwd(ji,1)
+               END_1D
+               DO_2Dik( 0, 0,   2, jpkm1, 1 )
+                  zwt(ji,jk) = zwd(ji,jk) - zwi(ji,jk) * zws(ji,jk-1) / zwt(ji,jk-1)
+               END_2D
+               !
             ENDIF
             !
-            ! Diagonal, lower (i), upper (s)  (including the bottom boundary condition since avt is masked)
-            IF( ln_zad_Aimp ) THEN         ! Adaptive implicit vertical advection
-               DO_3D( 0, 0, 0, 0, 1, jpkm1 )
-                  zzwi = - p2dt * zwt(ji,jj,jk  ) / e3w(ji,jj,jk  ,Kmm)
-                  zzws = - p2dt * zwt(ji,jj,jk+1) / e3w(ji,jj,jk+1,Kmm)
-                  zwd(ji,jj,jk) = e3t(ji,jj,jk,Kaa) - zzwi - zzws   &
-                     &                 + p2dt * ( MAX( wi(ji,jj,jk  ) , 0._wp ) - MIN( wi(ji,jj,jk+1) , 0._wp ) )
-                  zwi(ji,jj,jk) = zzwi + p2dt *   MIN( wi(ji,jj,jk  ) , 0._wp )
-                  zws(ji,jj,jk) = zzws - p2dt *   MAX( wi(ji,jj,jk+1) , 0._wp )
-               END_3D
-            ELSE
-               DO_3D( 0, 0, 0, 0, 1, jpkm1 )
-                  zwi(ji,jj,jk) = - p2dt * zwt(ji,jj,jk  ) / e3w(ji,jj,jk,Kmm)
-                  zws(ji,jj,jk) = - p2dt * zwt(ji,jj,jk+1) / e3w(ji,jj,jk+1,Kmm)
-                  zwd(ji,jj,jk) = e3t(ji,jj,jk,Kaa) - zwi(ji,jj,jk) - zws(ji,jj,jk)
-               END_3D
+            IF( ln_zdfmfc ) THEN    ! add Mass Flux to the RHS 
+               DO_2Dik( 0, 0,   1, jpkm1, 1 )
+                  pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) + edmftra(ji,jj,jk,jn)
+               END_2D
+!!gm               CALL rhs_mfc( pt(:,:,:,jn,Krhs), jn )
             ENDIF
             !
-            ! Modification of diagonal to add MF scheme
-            IF ( ln_zdfmfc ) THEN
-               CALL diag_mfc( zwi, zwd, zws, p2dt, Kaa )
-            END IF
-            !
-            !! Matrix inversion from the first level
-            !!----------------------------------------------------------------------
-            !   solve m.x = y  where m is a tri diagonal matrix ( jpk*jpk )
-            !
-            !        ( zwd1 zws1   0    0    0  )( zwx1 ) ( zwy1 )
-            !        ( zwi2 zwd2 zws2   0    0  )( zwx2 ) ( zwy2 )
-            !        (  0   zwi3 zwd3 zws3   0  )( zwx3 )=( zwy3 )
-            !        (        ...               )( ...  ) ( ...  )
-            !        (  0    0    0   zwik zwdk )( zwxk ) ( zwyk )
-            !
-            !   m is decomposed in the product of an upper and lower triangular matrix.
-            !   The 3 diagonal terms are in 3d arrays: zwd, zws, zwi.
-            !   Suffices i,s and d indicate "inferior" (below diagonal), diagonal
-            !   and "superior" (above diagonal) components of the tridiagonal system.
-            !   The solution will be in the 4d array pta.
-            !   The 3d array zwt is used as a work space array.
-            !   En route to the solution pt(:,:,:,:,Kaa) is used a to evaluate the rhs and then
-            !   used as a work space array: its value is modified.
-            !
-            DO_2D( 0, 0, 0, 0 )      !* 1st recurrence:   Tk = Dk - Ik Sk-1 / Tk-1   (increasing k) ! done one for all passive tracers (so included in the IF instruction)
-               zwt(ji,jj,1) = zwd(ji,jj,1)
+            DO_1Di( 0, 0 )             !* 2nd recurrence:    Zk = Yk - Ik / Tk-1  Zk-1
+               pt(ji,jj,1,jn,Kaa) =       e3t(ji,jj,1,Kbb) * pt(ji,jj,1,jn,Kbb )    &
+                  &               + rDt * e3t(ji,jj,1,Kmm) * pt(ji,jj,1,jn,Krhs)
+            END_1D
+            DO_2Dik( 0, 0,   2, jpkm1, 1 )
+               zrhs =       e3t(ji,jj,jk,Kbb) * pt(ji,jj,jk,jn,Kbb )   &
+                  & + rDt * e3t(ji,jj,jk,Kmm) * pt(ji,jj,jk,jn,Krhs)   ! zrhs=right hand side
+               pt(ji,jj,jk,jn,Kaa) = zrhs - zwi(ji,jk) / zwt(ji,jk-1) * pt(ji,jj,jk-1,jn,Kaa)
             END_2D
-            DO_3D( 0, 0, 0, 0, 2, jpkm1 )
-               zwt(ji,jj,jk) = zwd(ji,jj,jk) - zwi(ji,jj,jk) * zws(ji,jj,jk-1) / zwt(ji,jj,jk-1)
-            END_3D
             !
-         ENDIF
-         !
-         ! Modification of rhs to add MF scheme
-         IF ( ln_zdfmfc ) THEN
-            CALL rhs_mfc( pt(:,:,:,jn,Krhs), jn )
-         END IF
-         !
-         DO_2D( 0, 0, 0, 0 )         !* 2nd recurrence:    Zk = Yk - Ik / Tk-1  Zk-1
-            pt(ji,jj,1,jn,Kaa) =        e3t(ji,jj,1,Kbb) * pt(ji,jj,1,jn,Kbb)    &
-               &               + p2dt * e3t(ji,jj,1,Kmm) * pt(ji,jj,1,jn,Krhs)
-         END_2D
-         DO_3D( 0, 0, 0, 0, 2, jpkm1 )
-            zrhs =        e3t(ji,jj,jk,Kbb) * pt(ji,jj,jk,jn,Kbb)    &
-               & + p2dt * e3t(ji,jj,jk,Kmm) * pt(ji,jj,jk,jn,Krhs)   ! zrhs=right hand side
-            pt(ji,jj,jk,jn,Kaa) = zrhs - zwi(ji,jj,jk) / zwt(ji,jj,jk-1) * pt(ji,jj,jk-1,jn,Kaa)
-         END_3D
-         !
-         DO_2D( 0, 0, 0, 0 )         !* 3d recurrence:    Xk = (Zk - Sk Xk+1 ) / Tk   (result is the after tracer)
-            pt(ji,jj,jpkm1,jn,Kaa) = pt(ji,jj,jpkm1,jn,Kaa) / zwt(ji,jj,jpkm1) * tmask(ji,jj,jpkm1)
-         END_2D
-         DO_3DS( 0, 0, 0, 0, jpk-2, 1, -1 )
-            pt(ji,jj,jk,jn,Kaa) = ( pt(ji,jj,jk,jn,Kaa) - zws(ji,jj,jk) * pt(ji,jj,jk+1,jn,Kaa) )   &
-               &             / zwt(ji,jj,jk) * tmask(ji,jj,jk)
-         END_3D
+            DO_1Di( 0, 0 )             !* 3d recurrence:    Xk = (Zk - Sk Xk+1 ) / Tk   (result is the after tracer)
+               pt(ji,jj,jpkm1,jn,Kaa) = pt(ji,jj,jpkm1,jn,Kaa) / zwt(ji,jpkm1) * tmask(ji,jj,jpkm1)
+            END_1D
+            DO_2Dik( 0, 0,   jpk-2, 1, -1 )
+               pt(ji,jj,jk,jn,Kaa) = ( pt(ji,jj,jk,jn,Kaa) - zws(ji,jk) * pt(ji,jj,jk+1,jn,Kaa) )   &
+                  &             / zwt(ji,jk) * tmask(ji,jj,jk)
+            END_2D
+            !                                         ! ================= !
+         END DO                                       !    tracer loop    !
          !                                            ! ================= !
-      END DO                                          !  end tracer loop  !
+      END_1D                                          !  i-k slices loop  !      
       !                                               ! ================= !
    END SUBROUTINE tra_zdf_imp
 
diff --git a/src/OCE/do_loop_substitute.h90 b/src/OCE/do_loop_substitute.h90
index f957d0741b54399e90fba13f4876ae152b2ea041..c6db00d51aef101b5ca421abf373c001deeffedc 100644
--- a/src/OCE/do_loop_substitute.h90
+++ b/src/OCE/do_loop_substitute.h90
@@ -58,7 +58,10 @@
 !
 #endif
 
-#define DO_2D(L, R, B, T) DO jj = ntsj-(B), ntej+(T) ; DO ji = ntsi-(L), ntei+(R)
+#define DO_1Di(L, R)        DO ji = ntsi-(L), ntei+(R)
+#define DO_1Dj(B, T)        DO jj = ntsj-(B), ntej+(T)
+#define DO_2Dik(L, R, ks, ke, ki)   DO jk = ks, ke, ki   ;   DO_1Di(L, R)
+#define DO_2D(L, R, B, T)   DO_1Dj(B, T)   ;   DO_1Di(L, R)
 #define DO_2D_OVR(L, R, B, T) DO_2D(L-(L+R)*nthl, R-(R+L)*nthr, B-(B+T)*nthb, T-(T+B)*ntht)
 #define A1Di(H) ntsi-(H):ntei+(H)
 #define A1Dj(H) ntsj-(H):ntej+(H)
@@ -76,5 +79,6 @@
 #define DO_3DS(L, R, B, T, ks, ke, ki) DO jk = ks, ke, ki ; DO_2D(L, R, B, T)
 #define DO_3DS_OVR(L, R, B, T, ks, ke, ki) DO jk = ks, ke, ki ; DO_2D_OVR(L, R, B, T)
 
+#define END_1D   END DO
 #define END_2D   END DO   ;   END DO
-#define END_3D   END DO   ;   END DO   ;   END DO
+#define END_3D   END DO   ;   END DO   ;   END DO
\ No newline at end of file
diff --git a/src/TOP/TRP/trcadv.F90 b/src/TOP/TRP/trcadv.F90
index e98590e1693612ef16395d623624c477273d89d9..fd1b0aeaac3911aee54cb4ec5cd942eaca372cc1 100644
--- a/src/TOP/TRP/trcadv.F90
+++ b/src/TOP/TRP/trcadv.F90
@@ -8,6 +8,7 @@ MODULE trcadv
    !!            3.7  !  2014-05  (G. Madec, C. Ethe)  Add 2nd/4th order cases for CEN and FCT schemes 
    !!            4.0  !  2017-09  (G. Madec)  remove vertical time-splitting option
    !!            4.5  !  2021-08  (G. Madec, S. Techene) add advective velocities as optional arguments
+   !!             -   !  2022-06  (S. Techene, G, Madec) refactorization to reduce local memory usage
    !!----------------------------------------------------------------------
 #if defined key_top
    !!----------------------------------------------------------------------
@@ -156,11 +157,19 @@ CONTAINS
       SELECT CASE ( nadv )                      !==  compute advection trend and add it to general trend  ==!
       !
       CASE ( np_CEN )                                 ! Centered : 2nd / 4th order
-         CALL tra_adv_cen   ( kt, nittrc000,'TRC',          zuu, zvv, zww,      Kmm, ptr, jptra, Krhs, nn_cen_h, nn_cen_v )
+         IF( nn_hls == 1 ) THEN
+            CALL tra_adv_cen_hls1( kt, nittrc000,'TRC',     zuu, zvv, zww,      Kmm, ptr, jptra, Krhs, nn_cen_h, nn_cen_v )
+         ELSE
+            CALL tra_adv_cen ( kt, nittrc000,'TRC',         zuu, zvv, zww,      Kmm, ptr, jptra, Krhs, nn_cen_h, nn_cen_v )
+         ENDIF
       CASE ( np_FCT )                                 ! FCT      : 2nd / 4th order
             CALL tra_adv_fct( kt, nittrc000,'TRC', rDt_trc, zuu, zvv, zww, Kbb, Kmm, ptr, jptra, Krhs, nn_fct_h, nn_fct_v )
       CASE ( np_MUS )                                 ! MUSCL
+         IF( nn_hls == 1 ) THEN
+            CALL tra_adv_mus_hls1( kt, nittrc000,'TRC', rDt_trc, zuu, zvv, zww, Kbb, Kmm, ptr, jptra, Krhs, ln_mus_ups    )
+         ELSE
             CALL tra_adv_mus( kt, nittrc000,'TRC', rDt_trc, zuu, zvv, zww, Kbb, Kmm, ptr, jptra, Krhs, ln_mus_ups         )
+         ENDIF
       CASE ( np_UBS )                                 ! UBS
          CALL tra_adv_ubs   ( kt, nittrc000,'TRC', rDt_trc, zuu, zvv, zww, Kbb, Kmm, ptr, jptra, Krhs, nn_ubs_v           )
       CASE ( np_QCK )                                 ! QUICKEST
diff --git a/src/TOP/TRP/trczdf.F90 b/src/TOP/TRP/trczdf.F90
index 2f0b5a8f2dbebb0ba09b1467a6b1b7831777b741..b5a9dd4ccd34296c7f3ba759cc8830496b836d95 100644
--- a/src/TOP/TRP/trczdf.F90
+++ b/src/TOP/TRP/trczdf.F90
@@ -53,7 +53,7 @@ CONTAINS
       !
       IF( l_trdtrc )   ztrtrd(:,:,:,:)  = ptr(:,:,:,:,Krhs)
       !
-      CALL tra_zdf_imp( kt, nittrc000, 'TRC', rDt_trc, Kbb, Kmm, Krhs, ptr, Kaa, jptra )    !   implicit scheme          
+      CALL tra_zdf_imp( 'TRC', Kbb, Kmm, Krhs, ptr, Kaa, jptra )    !   implicit scheme          
       !
       IF( l_trdtrc )   THEN                      ! save the vertical diffusive trends for further diagnostics
          DO jn = 1, jptra