Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/AGRIF_DEMO/EXPREF/1_namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/AGRIF_DEMO/EXPREF/1_namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/AGRIF_DEMO/EXPREF/1_namelist_cfg	(revision 14852)
@@ -40,4 +40,8 @@
       ln_closea    = .false.    !  F => suppress closed seas (defined by closea_mask field) 
       !                         !       from the bathymetry at runtime.
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
 /
 !-----------------------------------------------------------------------
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/AGRIF_DEMO/EXPREF/2_namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/AGRIF_DEMO/EXPREF/2_namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/AGRIF_DEMO/EXPREF/2_namelist_cfg	(revision 14852)
@@ -38,4 +38,8 @@
    ln_read_cfg = .true.    !  (=T) read the domain configuration file
       cn_domcfg = "ORCA_R05_zps_domcfg_agrif"    ! domain configuration filename
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
 /
 !-----------------------------------------------------------------------
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/AGRIF_DEMO/EXPREF/3_namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/AGRIF_DEMO/EXPREF/3_namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/AGRIF_DEMO/EXPREF/3_namelist_cfg	(revision 14852)
@@ -38,4 +38,8 @@
    ln_read_cfg = .true.    !  (=T) read the domain configuration file
       cn_domcfg = "ORCA_R017_zps_domcfg_agrif"    ! domain configuration filename
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
 /
 !-----------------------------------------------------------------------
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/AGRIF_DEMO/EXPREF/namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/AGRIF_DEMO/EXPREF/namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/AGRIF_DEMO/EXPREF/namelist_cfg	(revision 14852)
@@ -40,4 +40,8 @@
       ln_closea    = .false.    !  F => suppress closed seas (defined by closea_mask field) 
       !                         !       from the bathymetry at runtime.
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
 /
 !-----------------------------------------------------------------------
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/AMM12/EXPREF/namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/AMM12/EXPREF/namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/AMM12/EXPREF/namelist_cfg	(revision 14852)
@@ -40,4 +40,8 @@
    ln_read_cfg = .true.   !  (=T) read the domain configuration file
       cn_domcfg = "AMM_R12_sco_domcfg" ! domain configuration filename
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
 /
 !!======================================================================
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/C1D_PAPA/EXPREF/namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/C1D_PAPA/EXPREF/namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/C1D_PAPA/EXPREF/namelist_cfg	(revision 14852)
@@ -58,4 +58,8 @@
 /
 !-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
+/
+!-----------------------------------------------------------------------
 &namtsd        !    Temperature & Salinity Data  (init/dmp)             (default: OFF)
 !-----------------------------------------------------------------------
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/GYRE_BFM/EXPREF/namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/GYRE_BFM/EXPREF/namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/GYRE_BFM/EXPREF/namelist_cfg	(revision 14852)
@@ -32,4 +32,8 @@
 !-----------------------------------------------------------------------
    ln_read_cfg = .false.   !  (=F) user defined configuration           (F => create/check namusr_def)
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
 /
 !-----------------------------------------------------------------------
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/GYRE_PISCES/EXPREF/namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/GYRE_PISCES/EXPREF/namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/GYRE_PISCES/EXPREF/namelist_cfg	(revision 14852)
@@ -32,4 +32,8 @@
 !-----------------------------------------------------------------------
    ln_read_cfg = .false.   !  (=F) user defined configuration           (F => create/check namusr_def)
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
 /
 !-----------------------------------------------------------------------
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/ORCA2_ICE_ABL/EXPREF/namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/ORCA2_ICE_ABL/EXPREF/namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/ORCA2_ICE_ABL/EXPREF/namelist_cfg	(revision 14852)
@@ -41,4 +41,8 @@
       ln_closea    = .false.    !  F => suppress closed seas (defined by closea_mask field) 
       !                         !       from the bathymetry at runtime.
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
 /
 !-----------------------------------------------------------------------
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/ORCA2_ICE_PISCES/EXPREF/namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/ORCA2_ICE_PISCES/EXPREF/namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/ORCA2_ICE_PISCES/EXPREF/namelist_cfg	(revision 14852)
@@ -38,4 +38,11 @@
       ln_closea    = .false.    !  F => suppress closed seas (defined by closea_mask field) 
       !                         !       from the bathymetry at runtime.
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
+   ln_tile = .false.     !  Use tiling (T) or not (F)
+   nn_ltile_i = 10       !  Length of tiles in i
+   nn_ltile_j = 10       !  Length of tiles in j
 /
 !-----------------------------------------------------------------------
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/ORCA2_OFF_PISCES/EXPREF/namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/ORCA2_OFF_PISCES/EXPREF/namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/ORCA2_OFF_PISCES/EXPREF/namelist_cfg	(revision 14852)
@@ -43,4 +43,8 @@
       cn_domcfg = "ORCA_R2_zps_domcfg"   ! domain configuration filename
       !
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
 /
 !-----------------------------------------------------------------------
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/ORCA2_OFF_TRC/EXPREF/namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/ORCA2_OFF_TRC/EXPREF/namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/ORCA2_OFF_TRC/EXPREF/namelist_cfg	(revision 14852)
@@ -42,4 +42,8 @@
       cn_domcfg = "ORCA_R2_zps_domcfg"   ! domain configuration filename
       !
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
 /
 !-----------------------------------------------------------------------
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/ORCA2_SAS_ICE/EXPREF/namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/ORCA2_SAS_ICE/EXPREF/namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/ORCA2_SAS_ICE/EXPREF/namelist_cfg	(revision 14852)
@@ -35,4 +35,8 @@
    ln_read_cfg = .true.    !  (=T) read the domain configuration file
       cn_domcfg = "ORCA_R2_zps_domcfg"    ! domain configuration filename
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
 /
 !!======================================================================
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/SPITZ12/EXPREF/namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/SPITZ12/EXPREF/namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/SPITZ12/EXPREF/namelist_cfg	(revision 14852)
@@ -36,4 +36,8 @@
       !                    !  (=F) user defined configuration           (F => create/check namusr_def)
       cn_domcfg = "domain_cfg"  ! domain configuration filename
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
 /
 !-----------------------------------------------------------------------
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/WED025/EXPREF/namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/WED025/EXPREF/namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/cfgs/WED025/EXPREF/namelist_cfg	(revision 14852)
@@ -54,4 +54,8 @@
       !                    !  (=F) user defined configuration           (F => create/check namusr_def)
       cn_domcfg = "domain_cfg"  ! domain configuration filename
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
 /
 !-----------------------------------------------------------------------
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/ICE/icethd_ent.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/ICE/icethd_ent.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/ICE/icethd_ent.F90	(revision 14852)
@@ -121,5 +121,5 @@
          DO ji = 1, npti
             rswitch      = MAX( 0._wp , SIGN( 1._wp , zhnew(ji) - epsi20 ) ) 
-            qnew(ji,jk1) = rswitch * ( zeh_cum1(ji,jk1) - zeh_cum1(ji,jk1-1) ) / MAX( zhnew(ji), epsi20 )
+            qnew(ji,jk1) = rswitch * MAX( 0._wp, zeh_cum1(ji,jk1) - zeh_cum1(ji,jk1-1) ) / MAX( zhnew(ji), epsi20 ) ! max for roundoff error
          END DO
       END DO
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ASM/asminc.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ASM/asminc.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ASM/asminc.F90	(revision 14852)
@@ -26,5 +26,4 @@
    USE par_oce         ! Ocean space and time domain variables
    USE dom_oce         ! Ocean space and time domain
-   USE domtile
    USE domvvl          ! domain: variable volume level
    USE ldfdyn          ! lateral diffusion: eddy viscosity coefficients
@@ -519,5 +518,5 @@
       !
       INTEGER  :: ji, jj, jk
-      INTEGER  :: it, itile
+      INTEGER  :: it
       REAL(wp) :: zincwgt  ! IAU weight for current time step
       REAL(wp), DIMENSION(A2D(nn_hls),jpk) :: fzptnz ! 3d freezing point values
@@ -541,5 +540,5 @@
             zincwgt = wgtiau(it) / rn_Dt   ! IAU weight for the current time step
             !
-            IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+            IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
                IF(lwp) THEN
                   WRITE(numout,*)
@@ -578,5 +577,5 @@
          ENDIF
          !
-         IF( ntile == 0 .OR. ntile == nijtile )  THEN                ! Do only on the last tile
+         IF( .NOT. l_istiled .OR. ntile == nijtile )  THEN                ! Do only on the last tile
             IF ( kt == nitiaufin_r + 1  ) THEN   ! For bias crcn to work
                DEALLOCATE( t_bkginc )
@@ -595,27 +594,21 @@
             IF (ln_temnofreeze) THEN
                ! Do not apply negative increments if the temperature will fall below freezing
-               WHERE( t_bkginc(A2D(0),:) > 0.0_wp .OR. pts(A2D(0),:,jp_tem,Kmm) + t_bkginc(A2D(0),:) > fzptnz(:,:,:) )
-                  pts(A2D(0),:,jp_tem,Kmm) = t_bkg(A2D(0),:) + t_bkginc(A2D(0),:)
+               WHERE( t_bkginc(:,:,:) > 0.0_wp .OR. pts(:,:,:,jp_tem,Kmm) + t_bkginc(:,:,:) > fzptnz(:,:,:) )
+                  pts(:,:,:,jp_tem,Kmm) = t_bkg(:,:,:) + t_bkginc(:,:,:)
                END WHERE
             ELSE
-               DO_3D( 0, 0, 0, 0, 1, jpk )
-                  pts(ji,jj,jk,jp_tem,Kmm) = t_bkg(ji,jj,jk) + t_bkginc(ji,jj,jk)
-               END_3D
+               pts(:,:,:,jp_tem,Kmm) = t_bkg(:,:,:) + t_bkginc(:,:,:)
             ENDIF
             IF (ln_salfix) THEN
                ! Do not apply negative increments if the salinity will fall below a specified
                ! minimum value salfixmin
-               WHERE( s_bkginc(A2D(0),:) > 0.0_wp .OR. pts(A2D(0),:,jp_sal,Kmm) + s_bkginc(A2D(0),:) > salfixmin )
-                  pts(A2D(0),:,jp_sal,Kmm) = s_bkg(A2D(0),:) + s_bkginc(A2D(0),:)
+               WHERE( s_bkginc(:,:,:) > 0.0_wp .OR. pts(:,:,:,jp_sal,Kmm) + s_bkginc(:,:,:) > salfixmin )
+                  pts(:,:,:,jp_sal,Kmm) = s_bkg(:,:,:) + s_bkginc(:,:,:)
                END WHERE
             ELSE
-               DO_3D( 0, 0, 0, 0, 1, jpk )
-                  pts(ji,jj,jk,jp_sal,Kmm) = s_bkg(ji,jj,jk) + s_bkginc(ji,jj,jk)
-               END_3D
-            ENDIF
-
-            DO_3D( 0, 0, 0, 0, 1, jpk )
-               pts(ji,jj,jk,:,Kbb) = pts(ji,jj,jk,:,Kmm)             ! Update before fields
-            END_3D
+               pts(:,:,:,jp_sal,Kmm) = s_bkg(:,:,:) + s_bkginc(:,:,:)
+            ENDIF
+
+            pts(:,:,:,:,Kbb) = pts(:,:,:,:,Kmm)                 ! Update before fields
 
             CALL eos( pts(:,:,:,:,Kbb), rhd, rhop, gdept_0(:,:,:) )  ! Before potential and in situ densities
@@ -624,26 +617,15 @@
 !!gm
 
-            ! TEMP: [tiling] This change not necessary after extra haloes development (lbc_lnk removed from zps_hde*)
-            IF( ntile == 0 .OR. ntile == nijtile )  THEN                ! Do only for the full domain
-               itile = ntile
-               IF( ln_tile ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = 0 )            ! Use full domain
-
-               IF( ln_zps .AND. .NOT. lk_c1d .AND. .NOT. ln_isfcav)           &
-                  &  CALL zps_hde    ( kt, Kmm, jpts, pts(:,:,:,:,Kbb), gtsu, gtsv,        &  ! Partial steps: before horizontal gradient
-                  &                              rhd, gru , grv               )  ! of t, s, rd at the last ocean level
-               IF( ln_zps .AND. .NOT. lk_c1d .AND.       ln_isfcav)                       &
-                  &  CALL zps_hde_isf( nit000, Kmm, jpts, pts(:,:,:,:,Kbb), gtsu, gtsv, gtui, gtvi,    &  ! Partial steps for top cell (ISF)
-                  &                                  rhd, gru , grv , grui, grvi          )  ! of t, s, rd at the last ocean level
-
-               IF( ln_tile ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = itile )            ! Revert to tile domain
-            ENDIF
-
-            IF( ntile == 0 .OR. ntile == nijtile )  THEN                ! Do only on the last tile
-               DEALLOCATE( t_bkginc )
-               DEALLOCATE( s_bkginc )
-               DEALLOCATE( t_bkg    )
-               DEALLOCATE( s_bkg    )
-            ENDIF
-         !
+            IF( ln_zps .AND. .NOT. lk_c1d .AND. .NOT. ln_isfcav)           &
+               &  CALL zps_hde    ( kt, Kmm, jpts, pts(:,:,:,:,Kbb), gtsu, gtsv,        &  ! Partial steps: before horizontal gradient
+               &                              rhd, gru , grv               )  ! of t, s, rd at the last ocean level
+            IF( ln_zps .AND. .NOT. lk_c1d .AND.       ln_isfcav)                       &
+               &  CALL zps_hde_isf( nit000, Kmm, jpts, pts(:,:,:,:,Kbb), gtsu, gtsv, gtui, gtvi,    &  ! Partial steps for top cell (ISF)
+               &                                  rhd, gru , grv , grui, grvi          )  ! of t, s, rd at the last ocean level
+
+            DEALLOCATE( t_bkginc )
+            DEALLOCATE( s_bkginc )
+            DEALLOCATE( t_bkg    )
+            DEALLOCATE( s_bkg    )
          ENDIF
          !
@@ -669,5 +651,5 @@
       REAL(wp), DIMENSION(jpi,jpj,jpk,jpt), INTENT(inout) ::  puu, pvv       ! ocean velocities and RHS of momentum equation
       !
-      INTEGER :: jk
+      INTEGER :: ji, jj, jk
       INTEGER :: it
       REAL(wp) :: zincwgt  ! IAU weight for current time step
@@ -683,19 +665,23 @@
             zincwgt = wgtiau(it) / rn_Dt   ! IAU weight for the current time step
             !
-            IF(lwp) THEN
-               WRITE(numout,*)
-               WRITE(numout,*) 'dyn_asm_inc : Dynamics IAU at time step = ', kt,' with IAU weight = ', wgtiau(it)
-               WRITE(numout,*) '~~~~~~~~~~~~'
+            IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+               IF(lwp) THEN
+                  WRITE(numout,*)
+                  WRITE(numout,*) 'dyn_asm_inc : Dynamics IAU at time step = ', kt,' with IAU weight = ', wgtiau(it)
+                  WRITE(numout,*) '~~~~~~~~~~~~'
+               ENDIF
             ENDIF
             !
             ! Update the dynamic tendencies
-            DO jk = 1, jpkm1
-               puu(:,:,jk,Krhs) = puu(:,:,jk,Krhs) + u_bkginc(:,:,jk) * zincwgt
-               pvv(:,:,jk,Krhs) = pvv(:,:,jk,Krhs) + v_bkginc(:,:,jk) * zincwgt
-            END DO
-            !
-            IF ( kt == nitiaufin_r ) THEN
-               DEALLOCATE( u_bkginc )
-               DEALLOCATE( v_bkginc )
+            DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+               puu(ji,jj,jk,Krhs) = puu(ji,jj,jk,Krhs) + u_bkginc(ji,jj,jk) * zincwgt
+               pvv(ji,jj,jk,Krhs) = pvv(ji,jj,jk,Krhs) + v_bkginc(ji,jj,jk) * zincwgt
+            END_3D
+            !
+            IF( .NOT. l_istiled .OR. ntile == nijtile )  THEN                ! Do only on the last tile
+               IF ( kt == nitiaufin_r ) THEN
+                  DEALLOCATE( u_bkginc )
+                  DEALLOCATE( v_bkginc )
+               ENDIF
             ENDIF
             !
@@ -741,5 +727,5 @@
       !
       INTEGER :: it
-      INTEGER :: jk
+      INTEGER :: ji, jj, jk
       REAL(wp) :: zincwgt  ! IAU weight for current time step
       !!----------------------------------------------------------------------
@@ -754,9 +740,11 @@
             zincwgt = wgtiau(it) / rn_Dt   ! IAU weight for the current time step
             !
-            IF(lwp) THEN
-               WRITE(numout,*)
-               WRITE(numout,*) 'ssh_asm_inc : SSH IAU at time step = ', &
-                  &  kt,' with IAU weight = ', wgtiau(it)
-               WRITE(numout,*) '~~~~~~~~~~~~'
+            IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+               IF(lwp) THEN
+                  WRITE(numout,*)
+                  WRITE(numout,*) 'ssh_asm_inc : SSH IAU at time step = ', &
+                     &  kt,' with IAU weight = ', wgtiau(it)
+                  WRITE(numout,*) '~~~~~~~~~~~~'
+               ENDIF
             ENDIF
             !
@@ -764,5 +752,7 @@
             ! (applied in dynspg.*)
 #if defined key_asminc
-            ssh_iau(:,:) = ssh_bkginc(:,:) * zincwgt
+            DO_2D_OVR( nn_hls, nn_hls, nn_hls, nn_hls )
+               ssh_iau(ji,jj) = ssh_bkginc(ji,jj) * zincwgt
+            END_2D
 #endif
             !
@@ -770,8 +760,12 @@
             !
             ! test on ssh_bkginc needed as ssh_asm_inc is called twice by time step
-            IF (ALLOCATED(ssh_bkginc)) DEALLOCATE( ssh_bkginc )
+            IF( .NOT. l_istiled .OR. ntile == nijtile )  THEN                ! Do only on the last tile
+               IF (ALLOCATED(ssh_bkginc)) DEALLOCATE( ssh_bkginc )
+            ENDIF
             !
 #if defined key_asminc
-            ssh_iau(:,:) = 0._wp
+            DO_2D_OVR( nn_hls, nn_hls, nn_hls, nn_hls )
+               ssh_iau(ji,jj) = 0._wp
+            END_2D
 #endif
             !
@@ -820,5 +814,5 @@
       REAL(wp), DIMENSION(:,:,:), INTENT(inout) ::   phdivn   ! horizontal divergence
       !!
-      INTEGER  ::   jk                                        ! dummy loop index
+      INTEGER  ::   ji, jj, jk                                ! dummy loop index
       REAL(wp), DIMENSION(:,:)  , POINTER       ::   ztim     ! local array
       !!----------------------------------------------------------------------
@@ -828,11 +822,15 @@
       !
       IF( ln_linssh ) THEN
-         phdivn(:,:,1) = phdivn(:,:,1) - ssh_iau(:,:) / e3t(:,:,1,Kmm) * tmask(:,:,1)
+         DO_2D_OVR( nn_hls-1, nn_hls, nn_hls-1, nn_hls )
+            phdivn(ji,jj,1) = phdivn(ji,jj,1) - ssh_iau(ji,jj) / e3t(ji,jj,1,Kmm) * tmask(ji,jj,1)
+         END_2D
       ELSE
-         ALLOCATE( ztim(jpi,jpj) )
-         ztim(:,:) = ssh_iau(:,:) / ( ht(:,:) + 1.0 - ssmask(:,:) )
-         DO jk = 1, jpkm1
-            phdivn(:,:,jk) = phdivn(:,:,jk) - ztim(:,:) * tmask(:,:,jk)
-         END DO
+         ALLOCATE( ztim(A2D(nn_hls)) )
+         DO_2D_OVR( nn_hls-1, nn_hls, nn_hls-1, nn_hls )
+            ztim(ji,jj) = ssh_iau(ji,jj) / ( ht(ji,jj) + 1.0 - ssmask(ji,jj) )
+            DO jk = 1, jpkm1
+               phdivn(ji,jj,jk) = phdivn(ji,jj,jk) - ztim(ji,jj) * tmask(ji,jj,jk)
+            END DO
+         END_2D
          !
          DEALLOCATE(ztim)
@@ -876,5 +874,5 @@
             ! note this is not a tendency so should not be divided by rn_Dt (as with the tracer and other increments)
             !
-            IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+            IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
                IF(lwp) THEN
                   WRITE(numout,*)
@@ -920,5 +918,5 @@
 #endif
             !
-            IF( ntile == 0 .OR. ntile == nijtile )  THEN                ! Do only on the last tile
+            IF( .NOT. l_istiled .OR. ntile == nijtile )  THEN                ! Do only on the last tile
                IF ( kt == nitiaufin_r ) THEN
                   DEALLOCATE( seaice_bkginc )
@@ -979,5 +977,5 @@
             END_2D
 #endif
-            IF( ntile == 0 .OR. ntile == nijtile )  THEN                ! Do only on the last tile
+            IF( .NOT. l_istiled .OR. ntile == nijtile )  THEN                ! Do only on the last tile
                IF ( .NOT. PRESENT(kindic) ) THEN
                   DEALLOCATE( seaice_bkginc )
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/BDY/bdydyn3d.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/BDY/bdydyn3d.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/BDY/bdydyn3d.F90	(revision 14852)
@@ -349,4 +349,5 @@
       REAL(wp) ::   zwgt           ! boundary weight
       !!----------------------------------------------------------------------
+      IF( l_istiled .AND. ntile /= 1 ) RETURN                        ! Do only for the full domain
       !
       IF( ln_timing )   CALL timing_start('bdy_dyn3d_dmp')
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/BDY/bdytra.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/BDY/bdytra.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/BDY/bdytra.F90	(revision 14852)
@@ -158,5 +158,5 @@
       INTEGER  ::   ib_bdy         ! Loop index
       !!----------------------------------------------------------------------
-      IF( ntile /= 0 .AND. ntile /= 1 ) RETURN                        ! Do only for the full domain
+      IF( l_istiled .AND. ntile /= 1 ) RETURN                        ! Do only for the full domain
       !
       IF( ln_timing )   CALL timing_start('bdy_tra_dmp')
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DIA/diaar5.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DIA/diaar5.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DIA/diaar5.F90	(revision 14852)
@@ -34,5 +34,4 @@
    REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:  ) ::   thick0       ! ocean thickness (interior domain)
    REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   sn0          ! initial salinity
-   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:,:) ::   hstr_adv, hstr_ldf
 
    LOGICAL  :: l_ar5
@@ -55,6 +54,5 @@
       !!----------------------------------------------------------------------
       !
-      ALLOCATE( thick0(jpi,jpj) , sn0(jpi,jpj,jpk) , &
-         &      hstr_adv(jpi,jpj,jpts,2), hstr_ldf(jpi,jpj,jpts,2), STAT=dia_ar5_alloc )
+      ALLOCATE( thick0(jpi,jpj) , sn0(jpi,jpj,jpk), STAT=dia_ar5_alloc )
       !
       CALL mpp_sum ( 'diaar5', dia_ar5_alloc )
@@ -306,5 +304,5 @@
    END SUBROUTINE dia_ar5
 
-   ! TEMP: [tiling] These changes not necessary if using XIOS (subdomain support, will not output haloes)
+
    SUBROUTINE dia_ar5_hst( ktra, cptr, puflx, pvflx )
       !!----------------------------------------------------------------------
@@ -320,41 +318,30 @@
       !
       INTEGER    ::  ji, jj, jk
-
-      IF( cptr /= 'adv' .AND. cptr /= 'ldf' ) RETURN
-      IF( ktra /= jp_tem .AND. ktra /= jp_sal ) RETURN
+      REAL(wp), DIMENSION(A2D(nn_hls))  :: z2d
+
+      z2d(:,:) = puflx(:,:,1)
+      DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+         z2d(ji,jj) = z2d(ji,jj) + puflx(ji,jj,jk)
+      END_3D
 
       IF( cptr == 'adv' ) THEN
-         DO_2D( 0, 0, 0, 0 )
-            hstr_adv(ji,jj,ktra,1) = puflx(ji,jj,1)
-            hstr_adv(ji,jj,ktra,2) = pvflx(ji,jj,1)
-         END_2D
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
-            hstr_adv(ji,jj,ktra,1) = hstr_adv(ji,jj,ktra,1) + puflx(ji,jj,jk)
-            hstr_adv(ji,jj,ktra,2) = hstr_adv(ji,jj,ktra,2) + pvflx(ji,jj,jk)
-         END_3D
+         IF( ktra == jp_tem ) CALL iom_put( 'uadv_heattr' , rho0_rcp * z2d(:,:) )  ! advective heat transport in i-direction
+         IF( ktra == jp_sal ) CALL iom_put( 'uadv_salttr' , rho0     * z2d(:,:) )  ! advective salt transport in i-direction
       ELSE IF( cptr == 'ldf' ) THEN
-         DO_2D( 0, 0, 0, 0 )
-            hstr_ldf(ji,jj,ktra,1) = puflx(ji,jj,1)
-            hstr_ldf(ji,jj,ktra,2) = pvflx(ji,jj,1)
-         END_2D
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
-            hstr_ldf(ji,jj,ktra,1) = hstr_ldf(ji,jj,ktra,1) + puflx(ji,jj,jk)
-            hstr_ldf(ji,jj,ktra,2) = hstr_ldf(ji,jj,ktra,2) + pvflx(ji,jj,jk)
-         END_3D
-      ENDIF
-
-      IF( ntile == 0 .OR. ntile == nijtile ) THEN
-         IF( cptr == 'adv' ) THEN
-            IF( ktra == jp_tem ) CALL iom_put( 'uadv_heattr' , rho0_rcp * hstr_adv(:,:,ktra,1) )  ! advective heat transport in i-direction
-            IF( ktra == jp_sal ) CALL iom_put( 'uadv_salttr' , rho0     * hstr_adv(:,:,ktra,1) )  ! advective salt transport in i-direction
-            IF( ktra == jp_tem ) CALL iom_put( 'vadv_heattr' , rho0_rcp * hstr_adv(:,:,ktra,2) )  ! advective heat transport in j-direction
-            IF( ktra == jp_sal ) CALL iom_put( 'vadv_salttr' , rho0     * hstr_adv(:,:,ktra,2) )  ! advective salt transport in j-direction
-         ENDIF
-         IF( cptr == 'ldf' ) THEN
-            IF( ktra == jp_tem ) CALL iom_put( 'udiff_heattr' , rho0_rcp * hstr_ldf(:,:,ktra,1) ) ! diffusive heat transport in i-direction
-            IF( ktra == jp_sal ) CALL iom_put( 'udiff_salttr' , rho0     * hstr_ldf(:,:,ktra,1) ) ! diffusive salt transport in i-direction
-            IF( ktra == jp_tem ) CALL iom_put( 'vdiff_heattr' , rho0_rcp * hstr_ldf(:,:,ktra,2) ) ! diffusive heat transport in j-direction
-            IF( ktra == jp_sal ) CALL iom_put( 'vdiff_salttr' , rho0     * hstr_ldf(:,:,ktra,2) ) ! diffusive salt transport in j-direction
-         ENDIF
+         IF( ktra == jp_tem ) CALL iom_put( 'udiff_heattr' , rho0_rcp * z2d(:,:) ) ! diffusive heat transport in i-direction
+         IF( ktra == jp_sal ) CALL iom_put( 'udiff_salttr' , rho0     * z2d(:,:) ) ! diffusive salt transport in i-direction
+      ENDIF
+      !
+      z2d(:,:) = pvflx(:,:,1)
+      DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+         z2d(ji,jj) = z2d(ji,jj) + pvflx(ji,jj,jk)
+      END_3D
+
+      IF( cptr == 'adv' ) THEN
+         IF( ktra == jp_tem ) CALL iom_put( 'vadv_heattr' , rho0_rcp * z2d(:,:) )  ! advective heat transport in j-direction
+         IF( ktra == jp_sal ) CALL iom_put( 'vadv_salttr' , rho0     * z2d(:,:) )  ! advective salt transport in j-direction
+      ELSE IF( cptr == 'ldf' ) THEN
+         IF( ktra == jp_tem ) CALL iom_put( 'vdiff_heattr' , rho0_rcp * z2d(:,:) ) ! diffusive heat transport in j-direction
+         IF( ktra == jp_sal ) CALL iom_put( 'vdiff_salttr' , rho0     * z2d(:,:) ) ! diffusive salt transport in j-direction
       ENDIF
 
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DIA/diaptr.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DIA/diaptr.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DIA/diaptr.F90	(revision 14852)
@@ -71,4 +71,5 @@
 CONTAINS
 
+   ! NOTE: [tiling] tiling sometimes changes the diagnostics very slightly, usually where there are few zonal points e.g. the northern Indian Ocean basin. The difference is usually very small, for one point in one diagnostic. Presumably this is because of the additional zonal integration step over tiles.
    SUBROUTINE dia_ptr( kt, Kmm, pvtr )
       !!----------------------------------------------------------------------
@@ -93,5 +94,5 @@
 
          ! Calculate diagnostics only when zonal integrals have finished
-         IF( ntile == 0 .OR. ntile == nijtile ) CALL dia_ptr_iom(kt, Kmm, pvtr)
+         IF( .NOT. l_istiled .OR. ntile == nijtile ) CALL dia_ptr_iom(kt, Kmm, pvtr)
       ENDIF
 
@@ -317,9 +318,7 @@
          !
          IF( iom_use( 'uocetr_vsum_cumul' ) ) THEN
-            IF( ln_tile ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = 0 )         ! Use full domain
             CALL iom_get_var(  'uocetr_vsum_op', z2d ) ! get uocetr_vsum_op from xml
             z2d(:,:) = ptr_ci_2d( z2d(:,:) )
             CALL iom_put( 'uocetr_vsum_cumul', z2d )
-            IF( ln_tile ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = nijtile )   ! Revert to tile domain
          ENDIF
          !
@@ -589,5 +588,5 @@
 
 #if ! defined key_mpi_off
-      IF( ntile == 0 .OR. ntile == nijtile ) THEN
+      IF( .NOT. l_istiled .OR. ntile == nijtile ) THEN
          ish1d(1) = jpj*nbasin
          ish2d(1) = jpj ; ish2d(2) = nbasin
@@ -627,5 +626,5 @@
 
 #if ! defined key_mpi_off
-      IF( ntile == 0 .OR. ntile == nijtile ) THEN
+      IF( .NOT. l_istiled .OR. ntile == nijtile ) THEN
          ish1d(1) = jpj*jpk*nbasin
          ish3d(1) = jpj ; ish3d(2) = jpk ; ish3d(3) = nbasin
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DOM/dom_oce.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DOM/dom_oce.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DOM/dom_oce.F90	(revision 14852)
@@ -73,9 +73,10 @@
    INTEGER         ::   nn_ltile_i, nn_ltile_j
 
-   ! Domain tiling (all tiles)
+   ! Domain tiling
    INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   ntsi_a       !: start of internal part of tile domain
    INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   ntsj_a       !
    INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   ntei_a       !: end of internal part of tile domain
    INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:) ::   ntej_a       !
+   LOGICAL, PUBLIC                                  ::   l_istiled    ! whether tiling is currently active or not
 
    !                             !: domain MPP decomposition parameters
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DOM/domain.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DOM/domain.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DOM/domain.F90	(revision 14852)
@@ -125,7 +125,7 @@
       !           !==  Reference coordinate system  ==!
       !
-      CALL dom_glo                            ! global domain versus local domain
-      CALL dom_nam                            ! read namelist ( namrun, namdom )
-      CALL dom_tile( ntsi, ntsj, ntei, ntej ) ! Tile domain
+      CALL dom_glo                      ! global domain versus local domain
+      CALL dom_nam                      ! read namelist ( namrun, namdom )
+      CALL dom_tile_init                ! Tile domain
 
       !
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DOM/domqco.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DOM/domqco.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DOM/domqco.F90	(revision 14852)
@@ -123,4 +123,7 @@
       CALL dom_qco_r3c( ssh(:,:,Kmm), r3t(:,:,Kmm), r3u(:,:,Kmm), r3v(:,:,Kmm), r3f(:,:) )
 #endif
+      ! dom_qco_r3c defines over [nn_hls, nn_hls-1, nn_hls, nn_hls-1]
+      IF( nn_hls == 2 ) CALL lbc_lnk( 'dom_qco_zgr', r3u(:,:,Kbb), 'U', 1._wp, r3v(:,:,Kbb), 'V', 1._wp, &
+         &                                           r3u(:,:,Kmm), 'U', 1._wp, r3v(:,:,Kmm), 'V', 1._wp )
       !
    END SUBROUTINE dom_qco_zgr
@@ -146,5 +149,7 @@
       !
       !
-      pr3t(:,:) = pssh(:,:) * r1_ht_0(:,:)   !==  ratio at t-point  ==!
+      DO_2D_OVR( nn_hls, nn_hls, nn_hls, nn_hls )
+         pr3t(ji,jj) = pssh(ji,jj) * r1_ht_0(ji,jj)   !==  ratio at t-point  ==!
+      END_2D
       !
       !
@@ -154,21 +159,21 @@
 #if ! defined key_qcoTest_FluxForm
       !                                ! no 'key_qcoTest_FluxForm' : surface weighted ssh average
-         DO_2D( 0, 0, 0, 0 )
-            pr3u(ji,jj) = 0.5_wp * (  e1e2t(ji  ,jj) * pssh(ji  ,jj)  &
-               &                    + e1e2t(ji+1,jj) * pssh(ji+1,jj)  ) * r1_hu_0(ji,jj) * r1_e1e2u(ji,jj)
-            pr3v(ji,jj) = 0.5_wp * (  e1e2t(ji,jj  ) * pssh(ji,jj  )  &
-               &                    + e1e2t(ji,jj+1) * pssh(ji,jj+1)  ) * r1_hv_0(ji,jj) * r1_e1e2v(ji,jj)
-         END_2D
+      DO_2D_OVR( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )
+         pr3u(ji,jj) = 0.5_wp * (  e1e2t(ji  ,jj) * pssh(ji  ,jj)  &
+            &                    + e1e2t(ji+1,jj) * pssh(ji+1,jj)  ) * r1_hu_0(ji,jj) * r1_e1e2u(ji,jj)
+         pr3v(ji,jj) = 0.5_wp * (  e1e2t(ji,jj  ) * pssh(ji,jj  )  &
+            &                    + e1e2t(ji,jj+1) * pssh(ji,jj+1)  ) * r1_hv_0(ji,jj) * r1_e1e2v(ji,jj)
+      END_2D
 !!st      ELSE                                         !- Flux Form   (simple averaging)
 #else
-         DO_2D( 0, 0, 0, 0 )
-            pr3u(ji,jj) = 0.5_wp * (  pssh(ji,jj) + pssh(ji+1,jj  )  ) * r1_hu_0(ji,jj)
-            pr3v(ji,jj) = 0.5_wp * (  pssh(ji,jj) + pssh(ji  ,jj+1)  ) * r1_hv_0(ji,jj)
-         END_2D
+      DO_2D_OVR( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )
+         pr3u(ji,jj) = 0.5_wp * (  pssh(ji,jj) + pssh(ji+1,jj  )  ) * r1_hu_0(ji,jj)
+         pr3v(ji,jj) = 0.5_wp * (  pssh(ji,jj) + pssh(ji  ,jj+1)  ) * r1_hv_0(ji,jj)
+      END_2D
 !!st      ENDIF
 #endif         
       !
       IF( .NOT.PRESENT( pr3f ) ) THEN              !- lbc on ratio at u-, v-points only
-         CALL lbc_lnk( 'dom_qco_r3c', pr3u, 'U', 1._wp, pr3v, 'V', 1._wp )
+         IF (nn_hls==1) CALL lbc_lnk( 'dom_qco_r3c', pr3u, 'U', 1._wp, pr3v, 'V', 1._wp )
          !
          !
@@ -179,20 +184,29 @@
          !                                ! no 'key_qcoTest_FluxForm' : surface weighted ssh average
 
-            DO_2D( 0, 0, 0, 0 )                               ! start from 1 since lbc_lnk('F') doesn't update the 1st row/line
-               pr3f(ji,jj) = 0.25_wp * (  e1e2t(ji  ,jj  ) * pssh(ji  ,jj  )  &
-                  &                     + e1e2t(ji+1,jj  ) * pssh(ji+1,jj  )  &
-                  &                     + e1e2t(ji  ,jj+1) * pssh(ji  ,jj+1)  &
-                  &                     + e1e2t(ji+1,jj+1) * pssh(ji+1,jj+1)  ) * r1_hf_0(ji,jj) * r1_e1e2f(ji,jj)
-            END_2D
+      DO_2D_OVR( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )                               ! start from 1 since lbc_lnk('F') doesn't update the 1st row/line
+         ! round brackets added to fix the order of floating point operations
+         ! needed to ensure halo 1 - halo 2 compatibility
+         pr3f(ji,jj) = 0.25_wp * ( ( e1e2t(ji  ,jj  ) * pssh(ji  ,jj  )   &
+            &                      + e1e2t(ji+1,jj  ) * pssh(ji+1,jj  )   &
+            &                      )                                      & ! bracket for halo 1 - halo 2 compatibility
+            &                     + ( e1e2t(ji  ,jj+1) * pssh(ji  ,jj+1)  &
+            &                       + e1e2t(ji+1,jj+1) * pssh(ji+1,jj+1)  &
+            &                       )                                     & ! bracket for halo 1 - halo 2 compatibility
+            &                    ) * r1_hf_0(ji,jj) * r1_e1e2f(ji,jj)
+      END_2D
 !!st         ELSE                                      !- Flux Form   (simple averaging)
 #else
-            DO_2D( 0, 0, 0, 0 )                               ! start from 1 since lbc_lnk('F') doesn't update the 1st row/line
-               pr3f(ji,jj) = 0.25_wp * (  pssh(ji,jj  ) + pssh(ji+1,jj  )  &
-                  &                     + pssh(ji,jj+1) + pssh(ji+1,jj+1)  ) * r1_hf_0(ji,jj)
-            END_2D
+      DO_2D_OVR( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )
+         ! round brackets added to fix the order of floating point operations
+         ! needed to ensure halo 1 - halo 2 compatibility
+         pr3f(ji,jj) = 0.25_wp * ( ( pssh(ji,jj  ) + pssh(ji+1,jj  ) ) &
+            &                     + ( pssh(ji,jj+1) + pssh(ji+1,jj+1)  &
+            &                       )                                  & ! bracket for halo 1 - halo 2 compatibility
+            &                    ) * r1_hf_0(ji,jj)
+      END_2D
 !!st         ENDIF
 #endif
          !                                                 ! lbc on ratio at u-,v-,f-points
-         CALL lbc_lnk( 'dom_qco_r3c', pr3u, 'U', 1._wp, pr3v, 'V', 1._wp, pr3f, 'F', 1._wp )
+         IF (nn_hls==1) CALL lbc_lnk( 'dom_qco_r3c', pr3u, 'U', 1._wp, pr3v, 'V', 1._wp, pr3f, 'F', 1._wp )
          !
       ENDIF
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DOM/domtile.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DOM/domtile.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DOM/domtile.F90	(revision 14852)
@@ -13,4 +13,5 @@
    !
    USE prtctl         ! Print control (prt_ctl_info routine)
+   USE lib_mpp , ONLY : ctl_stop, ctl_warn
    USE in_out_manager ! I/O manager
 
@@ -18,5 +19,10 @@
    PRIVATE
 
-   PUBLIC dom_tile   ! called by step.F90
+   PUBLIC dom_tile         ! called by step.F90
+   PUBLIC dom_tile_start   ! called by various
+   PUBLIC dom_tile_stop    ! "      "
+   PUBLIC dom_tile_init    ! called by domain.F90
+
+   LOGICAL, ALLOCATABLE, DIMENSION(:) ::   l_tilefin    ! whether a tile is finished or not
 
    !!----------------------------------------------------------------------
@@ -27,86 +33,222 @@
 CONTAINS
 
-   SUBROUTINE dom_tile( ktsi, ktsj, ktei, ktej, ktile )
+   SUBROUTINE dom_tile_init
+      !!----------------------------------------------------------------------
+      !!                     ***  ROUTINE dom_tile_init  ***
+      !!
+      !! ** Purpose :   Initialise tile domain variables
+      !!
+      !! ** Action  : - ntsi, ntsj     : start of internal part of domain
+      !!              - ntei, ntej     : end of internal part of domain
+      !!              - ntile          : current tile number
+      !!              - nijtile        : total number of tiles
+      !!              - nthl, nthr     : modifier on DO loop macro bound offset (left, right)
+      !!              - nthb, ntht     :              "         "               (bottom, top)
+      !!              - l_istiled      : whether tiling is currently active or not
+      !!              - l_tilefin      : whether a tile is finished or not
+      !!----------------------------------------------------------------------
+      INTEGER ::   jt                                     ! dummy loop argument
+      INTEGER ::   iitile, ijtile                         ! Local integers
+      !!----------------------------------------------------------------------
+      IF( ln_tile .AND. nn_hls /= 2 ) CALL ctl_stop('dom_tile_init: Tiling is only supported for nn_hls = 2')
+
+      ntile = 0                     ! Initialise to full domain
+      nijtile = 1
+      ntsi = Nis0
+      ntsj = Njs0
+      ntei = Nie0
+      ntej = Nje0
+      nthl = 0
+      nthr = 0
+      nthb = 0
+      ntht = 0
+      l_istiled = .FALSE.
+
+      IF( ln_tile ) THEN            ! Calculate tile domain indices
+         iitile = Ni_0 / nn_ltile_i       ! Number of tiles
+         ijtile = Nj_0 / nn_ltile_j
+         IF( MOD( Ni_0, nn_ltile_i ) /= 0 ) iitile = iitile + 1
+         IF( MOD( Nj_0, nn_ltile_j ) /= 0 ) ijtile = ijtile + 1
+
+         nijtile = iitile * ijtile
+         ALLOCATE( ntsi_a(0:nijtile), ntsj_a(0:nijtile), ntei_a(0:nijtile), ntej_a(0:nijtile), l_tilefin(nijtile) )
+
+         l_tilefin(:) = .FALSE.
+
+         ntsi_a(0) = Nis0                 ! Full domain
+         ntsj_a(0) = Njs0
+         ntei_a(0) = Nie0
+         ntej_a(0) = Nje0
+
+         DO jt = 1, nijtile               ! Tile domains
+            ntsi_a(jt) = Nis0 + nn_ltile_i * MOD(jt - 1, iitile)
+            ntsj_a(jt) = Njs0 + nn_ltile_j * ((jt - 1) / iitile)
+            ntei_a(jt) = MIN(ntsi_a(jt) + nn_ltile_i - 1, Nie0)
+            ntej_a(jt) = MIN(ntsj_a(jt) + nn_ltile_j - 1, Nje0)
+         ENDDO
+      ENDIF
+
+      IF(lwp) THEN                  ! control print
+         WRITE(numout,*)
+         WRITE(numout,*) 'dom_tile : Domain tiling decomposition'
+         WRITE(numout,*) '~~~~~~~~'
+         IF( ln_tile ) THEN
+            WRITE(numout,*) iitile, 'tiles in i'
+            WRITE(numout,*) '    Starting indices'
+            WRITE(numout,*) '        ', (ntsi_a(jt), jt=1, iitile)
+            WRITE(numout,*) '    Ending indices'
+            WRITE(numout,*) '        ', (ntei_a(jt), jt=1, iitile)
+            WRITE(numout,*) ijtile, 'tiles in j'
+            WRITE(numout,*) '    Starting indices'
+            WRITE(numout,*) '        ', (ntsj_a(jt), jt=1, nijtile, iitile)
+            WRITE(numout,*) '    Ending indices'
+            WRITE(numout,*) '        ', (ntej_a(jt), jt=1, nijtile, iitile)
+         ELSE
+            WRITE(numout,*) 'No domain tiling'
+            WRITE(numout,*) '    i indices =', ntsi, ':', ntei
+            WRITE(numout,*) '    j indices =', ntsj, ':', ntej
+         ENDIF
+      ENDIF
+   END SUBROUTINE dom_tile_init
+
+
+   SUBROUTINE dom_tile( ktsi, ktsj, ktei, ktej, ktile, ldhold, cstr )
       !!----------------------------------------------------------------------
       !!                     ***  ROUTINE dom_tile  ***
       !!
-      !! ** Purpose :   Set tile domain variables
+      !! ** Purpose :   Set the current tile and its domain indices
       !!
       !! ** Action  : - ktsi, ktsj     : start of internal part of domain
       !!              - ktei, ktej     : end of internal part of domain
-      !!              - ntile          : current tile number
-      !!              - nijtile        : total number of tiles
+      !!              - nthl, nthr     : modifier on DO loop macro bound offset (left, right)
+      !!              - nthb, ntht     :              "         "               (bottom, top)
+      !!              - ktile          : set the current tile number (ntile)
       !!----------------------------------------------------------------------
       INTEGER, INTENT(out) :: ktsi, ktsj, ktei, ktej      ! Tile domain indices
-      INTEGER, INTENT(in), OPTIONAL :: ktile              ! Tile number
-      INTEGER ::   jt                                     ! dummy loop argument
-      INTEGER ::   iitile, ijtile                         ! Local integers
-      CHARACTER (len=11) ::   charout
-      !!----------------------------------------------------------------------
-      IF( PRESENT(ktile) .AND. ln_tile ) THEN
-         ntile = ktile                 ! Set domain indices for tile
-         ktsi = ntsi_a(ktile)
-         ktsj = ntsj_a(ktile)
-         ktei = ntei_a(ktile)
-         ktej = ntej_a(ktile)
-
+      INTEGER, INTENT(in)  :: ktile                       ! Tile number
+      LOGICAL, INTENT(in), OPTIONAL :: ldhold             ! Pause/resume (.true.) or set (.false.) current tile
+      CHARACTER(len=*), INTENT(in), OPTIONAL   :: cstr    ! Debug information (added to warnings)
+      CHARACTER(len=23) :: clstr
+      LOGICAL :: llhold
+      CHARACTER(len=11)   :: charout
+      INTEGER :: iitile
+      !!----------------------------------------------------------------------
+      llhold = .FALSE.
+      IF( PRESENT(ldhold) ) llhold = ldhold
+      clstr = ''
+      IF( PRESENT(cstr) ) clstr = TRIM(' ('//TRIM(cstr)//')')
+
+      IF( .NOT. ln_tile ) CALL ctl_stop('Cannot use dom_tile with ln_tile = .false.')
+      IF( .NOT. llhold ) THEN
+         IF( .NOT. l_istiled ) THEN
+            CALL ctl_warn('Cannot call dom_tile when tiling is inactive'//clstr)
+            RETURN
+         ENDIF
+
+         IF( ntile /= 0 ) l_tilefin(ntile) = .TRUE.         ! If setting a new tile, the current tile is complete
+
+         ntile = ktile                                      ! Set the new tile
          IF(sn_cfctl%l_prtctl) THEN
-            WRITE(charout, FMT="('ntile =', I4)") ktile
+            WRITE(charout, FMT="('ntile =', I4)") ntile
             CALL prt_ctl_info( charout )
          ENDIF
-      ELSE
-         ntile = 0                     ! Initialise to full domain
-         nijtile = 1
-         ktsi = Nis0
-         ktsj = Njs0
-         ktei = Nie0
-         ktej = Nje0
-
-         IF( ln_tile ) THEN            ! Calculate tile domain indices
-            iitile = Ni_0 / nn_ltile_i       ! Number of tiles
-            ijtile = Nj_0 / nn_ltile_j
-            IF( MOD( Ni_0, nn_ltile_i ) /= 0 ) iitile = iitile + 1
-            IF( MOD( Nj_0, nn_ltile_j ) /= 0 ) ijtile = ijtile + 1
-
-            nijtile = iitile * ijtile
-            ALLOCATE( ntsi_a(0:nijtile), ntsj_a(0:nijtile), ntei_a(0:nijtile), ntej_a(0:nijtile) )
-
-            ntsi_a(0) = ktsi                 ! Full domain
-            ntsj_a(0) = ktsj
-            ntei_a(0) = ktei
-            ntej_a(0) = ktej
-
-            DO jt = 1, nijtile               ! Tile domains
-               ntsi_a(jt) = Nis0 + nn_ltile_i * MOD(jt - 1, iitile)
-               ntsj_a(jt) = Njs0 + nn_ltile_j * ((jt - 1) / iitile)
-               ntei_a(jt) = MIN(ntsi_a(jt) + nn_ltile_i - 1, Nie0)
-               ntej_a(jt) = MIN(ntsj_a(jt) + nn_ltile_j - 1, Nje0)
-            ENDDO
-         ENDIF
-
-         IF(lwp) THEN                  ! control print
-            WRITE(numout,*)
-            WRITE(numout,*) 'dom_tile : Domain tiling decomposition'
-            WRITE(numout,*) '~~~~~~~~'
-            IF( ln_tile ) THEN
-               WRITE(numout,*) iitile, 'tiles in i'
-               WRITE(numout,*) '    Starting indices'
-               WRITE(numout,*) '        ', (ntsi_a(jt), jt=1, iitile)
-               WRITE(numout,*) '    Ending indices'
-               WRITE(numout,*) '        ', (ntei_a(jt), jt=1, iitile)
-               WRITE(numout,*) ijtile, 'tiles in j'
-               WRITE(numout,*) '    Starting indices'
-               WRITE(numout,*) '        ', (ntsj_a(jt), jt=1, nijtile, iitile)
-               WRITE(numout,*) '    Ending indices'
-               WRITE(numout,*) '        ', (ntej_a(jt), jt=1, nijtile, iitile)
-            ELSE
-               WRITE(numout,*) 'No domain tiling'
-               WRITE(numout,*) '    i indices =', ktsi, ':', ktei
-               WRITE(numout,*) '    j indices =', ktsj, ':', ktej
-            ENDIF
-         ENDIF
-      ENDIF
+      ENDIF
+
+      ktsi = ntsi_a(ktile)                                  ! Set the domain indices
+      ktsj = ntsj_a(ktile)
+      ktei = ntei_a(ktile)
+      ktej = ntej_a(ktile)
+
+      ! Calculate the modifying factor on DO loop bounds (1 = do not work on points that have already been processed by a neighbouring tile)
+      nthl = 0 ; nthr = 0 ; nthb = 0 ; ntht = 0
+      iitile = Ni_0 / nn_ltile_i
+      IF( MOD( Ni_0, nn_ltile_i ) /= 0 ) iitile = iitile + 1
+      IF( ktsi > Nis0 ) THEN ; IF( l_tilefin(ktile - 1     ) ) nthl = 1 ; ENDIF    ! Left adjacent tile
+      IF( ktei < Nie0 ) THEN ; IF( l_tilefin(ktile + 1     ) ) nthr = 1 ; ENDIF    ! Right  "  "
+      IF( ktsj > Njs0 ) THEN ; IF( l_tilefin(ktile - iitile) ) nthb = 1 ; ENDIF    ! Bottom "  "
+      IF( ktej < Nje0 ) THEN ; IF( l_tilefin(ktile + iitile) ) ntht = 1 ; ENDIF    ! Top    "  "
    END SUBROUTINE dom_tile
 
+
+   SUBROUTINE dom_tile_start( ldhold, cstr )
+      !!----------------------------------------------------------------------
+      !!                     ***  ROUTINE dom_tile_start  ***
+      !!
+      !! ** Purpose : Start or resume the use of tiling
+      !!
+      !! ** Method  : dom_tile_start & dom_tile_stop are used to declare a tiled region of code.
+      !!
+      !!              Tiling is active/inactive (l_istiled = .true./.false.) within/outside of this code region.
+      !!              After enabling tiling, no tile will initially be set (the full domain will be used) and dom_tile must
+      !!              be called to set a specific tile to work on. Furthermore, all tiles will be marked as incomplete
+      !!              (ln_tilefin(:) = .false.).
+      !!
+      !!              Tiling can be paused/resumed within the tiled code region by calling dom_tile_stop/dom_tile_start
+      !!              with ldhold = .true.. This can be used to temporarily revert back to using the full domain.
+      !!
+      !!                 CALL dom_tile_start                                  ! Enable tiling
+      !!                    CALL dom_tile(ntsi, ntei, ntsj, ntej, ktile=n)    ! Set current tile "n"
+      !!                    ...
+      !!                    CALL dom_tile_stop(.TRUE.)                        ! Pause tiling (temporarily disable)
+      !!                    ...
+      !!                    CALL dom_tile_start(.TRUE.)                       ! Resume tiling
+      !!                 CALL dom_tile_stop                                   ! Disable tiling
+      !!----------------------------------------------------------------------
+      LOGICAL, INTENT(in), OPTIONAL :: ldhold            ! Resume (.true.) or start (.false.)
+      LOGICAL :: llhold
+      CHARACTER(len=*), INTENT(in), OPTIONAL   :: cstr   ! Debug information (added to warnings)
+      CHARACTER(len=23) :: clstr
+      !!----------------------------------------------------------------------
+      llhold = .FALSE.
+      IF( PRESENT(ldhold) ) llhold = ldhold
+      clstr = ''
+      IF( PRESENT(cstr) ) clstr = TRIM(' ('//TRIM(cstr)//')')
+
+      IF( .NOT. ln_tile ) CALL ctl_stop('Cannot resume/start tiling as ln_tile = .false.')
+      IF( l_istiled ) THEN
+         CALL ctl_warn('Cannot resume/start tiling as it is already active'//clstr)
+         RETURN
+      ! TODO: [tiling] this warning will always be raised outside a tiling loop (cannot check for pause rather than stop)
+      ELSE IF( llhold .AND. ntile == 0 ) THEN
+         CALL ctl_warn('Cannot resume tiling as it is not paused'//clstr)
+         RETURN
+      ENDIF
+
+      ! Whether resumed or started, the tiling is made active. If resumed, the domain indices for the current tile are used.
+      IF( llhold ) CALL dom_tile(ntsi, ntsj, ntei, ntej, ktile=ntile, ldhold=.TRUE., cstr='dom_tile_start'//clstr)
+      l_istiled = .TRUE.
+   END SUBROUTINE dom_tile_start
+
+
+   SUBROUTINE dom_tile_stop( ldhold, cstr )
+      !!----------------------------------------------------------------------
+      !!                     ***  ROUTINE dom_tile_stop  ***
+      !!
+      !! ** Purpose : End or pause the use of tiling
+      !!
+      !! ** Method  : See dom_tile_start
+      !!----------------------------------------------------------------------
+      LOGICAL, INTENT(in), OPTIONAL :: ldhold            ! Pause (.true.) or stop (.false.)
+      LOGICAL :: llhold
+      CHARACTER(len=*), INTENT(in), OPTIONAL   :: cstr   ! Debug information (added to warnings)
+      CHARACTER(len=23) :: clstr
+      !!----------------------------------------------------------------------
+      llhold = .FALSE.
+      IF( PRESENT(ldhold) ) llhold = ldhold
+      clstr = ''
+      IF( PRESENT(cstr) ) clstr = TRIM(' ('//TRIM(cstr)//')')
+
+      IF( .NOT. ln_tile ) CALL ctl_stop('Cannot pause/stop tiling as ln_tile = .false.')
+      IF( .NOT. l_istiled ) THEN
+         CALL ctl_warn('Cannot pause/stop tiling as it is inactive'//clstr)
+         RETURN
+      ENDIF
+
+      ! Whether paused or stopped, the tiling is made inactive and the full domain indices are used.
+      ! If stopped, there is no active tile (ntile = 0) and the finished tile indicators are reset
+      CALL dom_tile(ntsi, ntsj, ntei, ntej, ktile=0, ldhold=llhold, cstr='dom_tile_stop'//clstr)
+      IF( .NOT. llhold ) l_tilefin(:) = .FALSE.
+      l_istiled = .FALSE.
+   END SUBROUTINE dom_tile_stop
    !!======================================================================
 END MODULE domtile
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DOM/domutl.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DOM/domutl.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DOM/domutl.F90	(revision 14852)
@@ -22,5 +22,5 @@
 
    INTERFACE is_tile
-      MODULE PROCEDURE is_tile_2d, is_tile_3d, is_tile_4d
+      MODULE PROCEDURE is_tile_2d_sp, is_tile_3d_sp, is_tile_4d_sp, is_tile_2d_dp, is_tile_3d_dp, is_tile_4d_dp
    END INTERFACE is_tile
 
@@ -116,42 +116,68 @@
 
 
-   FUNCTION is_tile_2d( pt )
-      !!
-      REAL(wp), DIMENSION(:,:), INTENT(in) ::   pt
-      INTEGER :: is_tile_2d
-      !!
-      IF( ln_tile .AND. (SIZE(pt, 1) < jpi .OR. SIZE(pt, 2) < jpj) ) THEN
-         is_tile_2d = 1
+   INTEGER FUNCTION is_tile_2d_sp( pt )
+      REAL(sp), DIMENSION(:,:), INTENT(in) ::   pt
+
+      IF( l_istiled .AND. (SIZE(pt, 1) < jpi .OR. SIZE(pt, 2) < jpj) ) THEN
+         is_tile_2d_sp = 1
       ELSE
-         is_tile_2d = 0
+         is_tile_2d_sp = 0
       ENDIF
-   END FUNCTION is_tile_2d
+   END FUNCTION is_tile_2d_sp
 
 
-   FUNCTION is_tile_3d( pt )
-      !!
-      REAL(wp), DIMENSION(:,:,:), INTENT(in) ::   pt
-      INTEGER :: is_tile_3d
-      !!
-      IF( ln_tile .AND. (SIZE(pt, 1) < jpi .OR. SIZE(pt, 2) < jpj) ) THEN
-         is_tile_3d = 1
+   INTEGER FUNCTION is_tile_2d_dp( pt )
+      REAL(dp), DIMENSION(:,:), INTENT(in) ::   pt
+
+      IF( l_istiled .AND. (SIZE(pt, 1) < jpi .OR. SIZE(pt, 2) < jpj) ) THEN
+         is_tile_2d_dp = 1
       ELSE
-         is_tile_3d = 0
+         is_tile_2d_dp = 0
       ENDIF
-   END FUNCTION is_tile_3d
+   END FUNCTION is_tile_2d_dp
 
 
-   FUNCTION is_tile_4d( pt )
-      !!
-      REAL(wp), DIMENSION(:,:,:,:), INTENT(in) ::   pt
-      INTEGER :: is_tile_4d
-      !!
-      IF( ln_tile .AND. (SIZE(pt, 1) < jpi .OR. SIZE(pt, 2) < jpj) ) THEN
-         is_tile_4d = 1
+   INTEGER FUNCTION is_tile_3d_sp( pt )
+      REAL(sp), DIMENSION(:,:,:), INTENT(in) ::   pt
+
+      IF( l_istiled .AND. (SIZE(pt, 1) < jpi .OR. SIZE(pt, 2) < jpj) ) THEN
+         is_tile_3d_sp = 1
       ELSE
-         is_tile_4d = 0
+         is_tile_3d_sp = 0
       ENDIF
-   END FUNCTION is_tile_4d
+   END FUNCTION is_tile_3d_sp
 
+
+   INTEGER FUNCTION is_tile_3d_dp( pt )
+      REAL(dp), DIMENSION(:,:,:), INTENT(in) ::   pt
+
+      IF( l_istiled .AND. (SIZE(pt, 1) < jpi .OR. SIZE(pt, 2) < jpj) ) THEN
+         is_tile_3d_dp = 1
+      ELSE
+         is_tile_3d_dp = 0
+      ENDIF
+   END FUNCTION is_tile_3d_dp
+
+
+   INTEGER FUNCTION is_tile_4d_sp( pt )
+      REAL(sp), DIMENSION(:,:,:,:), INTENT(in) ::   pt
+
+      IF( l_istiled .AND. (SIZE(pt, 1) < jpi .OR. SIZE(pt, 2) < jpj) ) THEN
+         is_tile_4d_sp = 1
+      ELSE
+         is_tile_4d_sp = 0
+      ENDIF
+   END FUNCTION is_tile_4d_sp
+
+
+   INTEGER FUNCTION is_tile_4d_dp( pt )
+      REAL(dp), DIMENSION(:,:,:,:), INTENT(in) ::   pt
+
+      IF( l_istiled .AND. (SIZE(pt, 1) < jpi .OR. SIZE(pt, 2) < jpj) ) THEN
+         is_tile_4d_dp = 1
+      ELSE
+         is_tile_4d_dp = 0
+      ENDIF
+   END FUNCTION is_tile_4d_dp
    !!======================================================================
 END MODULE domutl
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DOM/domvvl.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DOM/domvvl.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DOM/domvvl.F90	(revision 14852)
@@ -204,5 +204,5 @@
       gdept(:,:,1,Kbb) = 0.5_wp * e3w(:,:,1,Kbb)
       gdepw(:,:,1,Kbb) = 0.0_wp
-      DO_3D( 1, 1, 1, 1, 2, jpk )                     ! vertical sum
+      DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 2, jpk )                     ! vertical sum
          !    zcoef = tmask - wmask    ! 0 everywhere tmask = wmask, ie everywhere expect at jk = mikt
          !                             ! 1 everywhere from mbkt to mikt + 1 or 1 (if no isf)
@@ -404,5 +404,5 @@
          zwu(:,:) = 0._wp
          zwv(:,:) = 0._wp
-         DO_3D( 1, 0, 1, 0, 1, jpkm1 )   ! a - first derivative: diffusive fluxes
+         DO_3D( nn_hls, nn_hls-1, nn_hls, nn_hls-1, 1, jpkm1 )       ! a - first derivative: diffusive fluxes
             un_td(ji,jj,jk) = rn_ahe3 * umask(ji,jj,jk) * e2_e1u(ji,jj)           &
                &            * ( tilde_e3t_b(ji,jj,jk) - tilde_e3t_b(ji+1,jj  ,jk) )
@@ -412,5 +412,5 @@
             zwv(ji,jj) = zwv(ji,jj) + vn_td(ji,jj,jk)
          END_3D
-         DO_2D( 1, 1, 1, 1 )             ! b - correction for last oceanic u-v points
+         DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )                 ! b - correction for last oceanic u-v points
             un_td(ji,jj,mbku(ji,jj)) = un_td(ji,jj,mbku(ji,jj)) - zwu(ji,jj)
             vn_td(ji,jj,mbkv(ji,jj)) = vn_td(ji,jj,mbkv(ji,jj)) - zwv(ji,jj)
@@ -423,5 +423,5 @@
          !                               ! d - thickness diffusion transport: boundary conditions
          !                             (stored for tracer advction and continuity equation)
-         CALL lbc_lnk( 'domvvl', un_td , 'U' , -1._wp, vn_td , 'V' , -1._wp)
+         IF( nn_hls == 1 ) CALL lbc_lnk( 'domvvl', un_td , 'U' , -1._wp, vn_td , 'V' , -1._wp)
          ! 4 - Time stepping of baroclinic scale factors
          ! ---------------------------------------------
@@ -640,5 +640,5 @@
       gdepw(:,:,1,Kmm) = 0.0_wp
       gde3w(:,:,1) = gdept(:,:,1,Kmm) - ssh(:,:,Kmm)
-      DO_3D( 1, 1, 1, 1, 2, jpk )
+      DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 2, jpk )
         !    zcoef = (tmask(ji,jj,jk) - wmask(ji,jj,jk))   ! 0 everywhere tmask = wmask, ie everywhere expect at jk = mikt
                                                            ! 1 for jk = mikt
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DOM/dtatsd.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DOM/dtatsd.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DOM/dtatsd.F90	(revision 14852)
@@ -141,5 +141,4 @@
       INTEGER ::   ji, jj, jk, jl, jkk   ! dummy loop indicies
       INTEGER ::   ik, il0, il1, ii0, ii1, ij0, ij1   ! local integers
-      INTEGER ::   itile
       INTEGER, DIMENSION(jpts), SAVE :: irec_b, irec_n
       REAL(wp)::   zl, zi                             ! local scalars
@@ -147,7 +146,6 @@
       !!----------------------------------------------------------------------
       !
-      IF( ntile == 0 .OR. ntile == 1 )  THEN                                         ! Do only for the full domain
-         itile = ntile
-         IF( ln_tile ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = 0 )            ! Use full domain
+      IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                                         ! Do only for the full domain
+         IF( ln_tile ) CALL dom_tile_stop( ldhold=.TRUE. )             ! Use full domain
             CALL fld_read( kt, 1, sf_tsd )   !==   read T & S data at kt time step   ==!
       !
@@ -195,5 +193,5 @@
          ENDIF
 !!gm end
-         IF( ln_tile ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = itile )            ! Revert to tile domain
+         IF( ln_tile ) CALL dom_tile_start( ldhold=.TRUE. )            ! Revert to tile domain
       ENDIF
       !
@@ -205,5 +203,5 @@
       IF( ln_sco ) THEN                   !==   s- or mixed s-zps-coordinate   ==!
          !
-         IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+         IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
             IF( kt == nit000 .AND. lwp )THEN
                WRITE(numout,*)
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DOM/istate.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DOM/istate.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DOM/istate.F90	(revision 14852)
@@ -152,5 +152,5 @@
       !
 !!gm  the use of umsak & vmask is not necessary below as uu(:,:,:,Kmm), vv(:,:,:,Kmm), uu(:,:,:,Kbb), vv(:,:,:,Kbb) are always masked
-      DO_3D( 1, 1, 1, 1, 1, jpkm1 )
+      DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpkm1 )
          uu_b(ji,jj,Kmm) = uu_b(ji,jj,Kmm) + e3u(ji,jj,jk,Kmm) * uu(ji,jj,jk,Kmm) * umask(ji,jj,jk)
          vv_b(ji,jj,Kmm) = vv_b(ji,jj,Kmm) + e3v(ji,jj,jk,Kmm) * vv(ji,jj,jk,Kmm) * vmask(ji,jj,jk)
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/divhor.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/divhor.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/divhor.F90	(revision 14852)
@@ -64,6 +64,4 @@
       !
       INTEGER  ::   ji, jj, jk    ! dummy loop indices
-      REAL(wp) ::   zraur, zdep   ! local scalars
-      REAL(wp), DIMENSION(jpi,jpj) :: ztmp
       !!----------------------------------------------------------------------
       !
@@ -71,16 +69,24 @@
       !
       IF( kt == nit000 ) THEN
-         IF(lwp) WRITE(numout,*)
-         IF(lwp) WRITE(numout,*) 'div_hor : horizontal velocity divergence '
-         IF(lwp) WRITE(numout,*) '~~~~~~~   '
-         hdiv(:,:,:) = 0._wp    ! initialize hdiv for the halos at the first time step
+         IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+            IF(lwp) WRITE(numout,*)
+            IF(lwp) WRITE(numout,*) 'div_hor : horizontal velocity divergence '
+            IF(lwp) WRITE(numout,*) '~~~~~~~   '
+         ENDIF
+         DO_3D_OVR( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpk )
+            hdiv(ji,jj,jk) = 0._wp    ! initialize hdiv for the halos at the first time step
+         END_3D
       ENDIF
       !
-      DO_3D( 0, 0, 0, 0, 1, jpkm1 )                                    !==  Horizontal divergence  ==!
-         hdiv(ji,jj,jk) = (   e2u(ji  ,jj) * e3u(ji  ,jj,jk,Kmm) * uu(ji  ,jj,jk,Kmm)      &
-            &               - e2u(ji-1,jj) * e3u(ji-1,jj,jk,Kmm) * uu(ji-1,jj,jk,Kmm)      &
-            &               + e1v(ji,jj  ) * e3v(ji,jj  ,jk,Kmm) * vv(ji,jj  ,jk,Kmm)      &
-            &               - e1v(ji,jj-1) * e3v(ji,jj-1,jk,Kmm) * vv(ji,jj-1,jk,Kmm)  )   &
-            &            * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
+      DO_3D_OVR( nn_hls-1, nn_hls, nn_hls-1, nn_hls, 1, jpkm1 )                                    !==  Horizontal divergence  ==!
+         ! round brackets added to fix the order of floating point operations
+         ! needed to ensure halo 1 - halo 2 compatibility
+         hdiv(ji,jj,jk) = (  ( e2u(ji  ,jj) * e3u(ji  ,jj,jk,Kmm) * uu(ji  ,jj,jk,Kmm)     &
+            &                - e2u(ji-1,jj) * e3u(ji-1,jj,jk,Kmm) * uu(ji-1,jj,jk,Kmm)     &
+            &                )                                                             & ! bracket for halo 1 - halo 2 compatibility
+            &              + ( e1v(ji,jj  ) * e3v(ji,jj  ,jk,Kmm) * vv(ji,jj  ,jk,Kmm)     &
+            &                - e1v(ji,jj-1) * e3v(ji,jj-1,jk,Kmm) * vv(ji,jj-1,jk,Kmm)     &
+            &                )                                                             & ! bracket for halo 1 - halo 2 compatibility
+            &             )  * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
       END_3D
       !
@@ -91,8 +97,7 @@
       ! 
 #endif
-      !
       IF( ln_isf )                      CALL isf_hdiv( kt, Kmm, hdiv )           !==  ice shelf         ==!   (update hdiv field)
       !
-      CALL lbc_lnk( 'divhor', hdiv, 'T', 1.0_wp )   !   (no sign change)
+      IF (nn_hls==1) CALL lbc_lnk( 'divhor', hdiv, 'T', 1.0_wp )   !   (no sign change)
       !
       IF( ln_timing )   CALL timing_stop('div_hor')
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynadv_cen2.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynadv_cen2.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynadv_cen2.F90	(revision 14852)
@@ -52,12 +52,14 @@
       !
       INTEGER  ::   ji, jj, jk   ! dummy loop indices
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::  zfu_t, zfu_f, zfu_uw, zfu
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::  zfv_t, zfv_f, zfv_vw, zfv, zfw
+      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
       !!----------------------------------------------------------------------
       !
-      IF( kt == nit000 .AND. lwp ) THEN
-         WRITE(numout,*)
-         WRITE(numout,*) 'dyn_adv_cen2 : 2nd order flux form momentum advection'
-         WRITE(numout,*) '~~~~~~~~~~~~'
+      IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+         IF( kt == nit000 .AND. lwp ) THEN
+            WRITE(numout,*)
+            WRITE(numout,*) 'dyn_adv_cen2 : 2nd order flux form momentum advection'
+            WRITE(numout,*) '~~~~~~~~~~~~'
+         ENDIF
       ENDIF
       !
@@ -70,6 +72,8 @@
       !
       DO jk = 1, jpkm1                    ! horizontal transport
-         zfu(:,:,jk) = 0.25_wp * e2u(:,:) * e3u(:,:,jk,Kmm) * puu(:,:,jk,Kmm)
-         zfv(:,:,jk) = 0.25_wp * e1v(:,:) * e3v(:,:,jk,Kmm) * pvv(:,:,jk,Kmm)
+         DO_2D( 1, 1, 1, 1 )
+            zfu(ji,jj,jk) = 0.25_wp * e2u(ji,jj) * e3u(ji,jj,jk,Kmm) * puu(ji,jj,jk,Kmm)
+            zfv(ji,jj,jk) = 0.25_wp * e1v(ji,jj) * e3v(ji,jj,jk,Kmm) * pvv(ji,jj,jk,Kmm)
+         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) )
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynadv_ubs.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynadv_ubs.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynadv_ubs.F90	(revision 14852)
@@ -75,14 +75,16 @@
       INTEGER  ::   ji, jj, jk   ! dummy loop indices
       REAL(wp) ::   zui, zvj, zfuj, zfvi, zl_u, zl_v   ! local scalars
-      REAL(wp), DIMENSION(jpi,jpj,jpk)   ::   zfu_t, zfu_f, zfu_uw, zfu
-      REAL(wp), DIMENSION(jpi,jpj,jpk)   ::   zfv_t, zfv_f, zfv_vw, zfv, zfw
-      REAL(wp), DIMENSION(jpi,jpj,jpk,2) ::   zlu_uu, zlu_uv
-      REAL(wp), DIMENSION(jpi,jpj,jpk,2) ::   zlv_vv, zlv_vu
+      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), DIMENSION(A2D(nn_hls),jpk,2) ::   zlu_uu, zlu_uv
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk,2) ::   zlv_vv, zlv_vu
       !!----------------------------------------------------------------------
       !
-      IF( kt == nit000 ) THEN
-         IF(lwp) WRITE(numout,*)
-         IF(lwp) WRITE(numout,*) 'dyn_adv_ubs : UBS flux form momentum advection'
-         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~'
+      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
       !
@@ -105,27 +107,49 @@
          !                                   ! =========================== !
          !                                         ! horizontal volume fluxes
-         zfu(:,:,jk) = e2u(:,:) * e3u(:,:,jk,Kmm) * puu(:,:,jk,Kmm)
-         zfv(:,:,jk) = e1v(:,:) * e3v(:,:,jk,Kmm) * pvv(:,:,jk,Kmm)
+         DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
+            zfu(ji,jj,jk) = e2u(ji,jj) * e3u(ji,jj,jk,Kmm) * puu(ji,jj,jk,Kmm)
+            zfv(ji,jj,jk) = e1v(ji,jj) * e3v(ji,jj,jk,Kmm) * pvv(ji,jj,jk,Kmm)
+         END_2D
          !            
-         DO_2D( 0, 0, 0, 0 )                       ! laplacian
-            zlu_uu(ji,jj,jk,1) = ( puu (ji+1,jj  ,jk,Kbb) - 2.*puu (ji,jj,jk,Kbb) + puu (ji-1,jj  ,jk,Kbb) ) * umask(ji,jj,jk)
-            zlv_vv(ji,jj,jk,1) = ( pvv (ji  ,jj+1,jk,Kbb) - 2.*pvv (ji,jj,jk,Kbb) + pvv (ji  ,jj-1,jk,Kbb) ) * vmask(ji,jj,jk)
-            zlu_uv(ji,jj,jk,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,jk,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,jk,2) = ( zfu(ji+1,jj  ,jk) - 2.*zfu(ji,jj,jk) + zfu(ji-1,jj  ,jk) ) * umask(ji,jj,jk)
-            zlv_vv(ji,jj,jk,2) = ( zfv(ji  ,jj+1,jk) - 2.*zfv(ji,jj,jk) + zfv(ji  ,jj-1,jk) ) * vmask(ji,jj,jk)
-            zlu_uv(ji,jj,jk,2) = ( zfu(ji  ,jj+1,jk) - zfu(ji  ,jj  ,jk) ) * fmask(ji  ,jj  ,jk)   &
-               &               - ( zfu(ji  ,jj  ,jk) - zfu(ji  ,jj-1,jk) ) * fmask(ji  ,jj-1,jk)
-            zlv_vu(ji,jj,jk,2) = ( zfv(ji+1,jj  ,jk) - zfv(ji  ,jj  ,jk) ) * fmask(ji  ,jj  ,jk)   &
-               &               - ( zfv(ji  ,jj  ,jk) - zfv(ji-1,jj  ,jk) ) * fmask(ji-1,jj  ,jk)
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )                       ! laplacian
+            ! round brackets added to fix the order of floating point operations
+            ! needed to ensure halo 1 - halo 2 compatibility
+            zlu_uu(ji,jj,jk,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) &
+               &                   )                                                 & ! bracket for halo 1 - halo 2 compatibility
+               &                 ) * umask(ji  ,jj  ,jk)
+            zlv_vv(ji,jj,jk,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) &
+               &                   )                                                 & ! bracket for halo 1 - halo 2 compatibility
+               &                 ) * vmask(ji  ,jj  ,jk)
+            zlu_uv(ji,jj,jk,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,jk,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)
+            !
+            ! round brackets added to fix the order of floating point operations
+            ! needed to ensure halo 1 - halo 2 compatibility
+            zlu_uu(ji,jj,jk,2) = ( ( zfu(ji+1,jj  ,jk) - zfu(ji  ,jj  ,jk)           &
+               &                   )                                                 & ! bracket for halo 1 - halo 2 compatibility
+               &                 + ( zfu(ji-1,jj  ,jk) - zfu(ji  ,jj  ,jk)           &
+               &                   )                                                 & ! bracket for halo 1 - halo 2 compatibility
+               &                 ) * umask(ji  ,jj  ,jk)
+            zlv_vv(ji,jj,jk,2) = ( ( zfv(ji  ,jj+1,jk) - zfv(ji  ,jj  ,jk)           &
+               &                   )                                                 & ! bracket for halo 1 - halo 2 compatibility
+               &                 + ( zfv(ji  ,jj-1,jk) - zfv(ji  ,jj  ,jk)           &
+               &                   )                                                 & ! bracket for halo 1 - halo 2 compatibility
+               &                 ) * vmask(ji  ,jj  ,jk)
+            zlu_uv(ji,jj,jk,2) = (  zfu(ji  ,jj+1,jk) - zfu(ji  ,jj  ,jk)  ) * fmask(ji  ,jj  ,jk)             &
+               &               - (  zfu(ji  ,jj  ,jk) - zfu(ji  ,jj-1,jk)  ) * fmask(ji  ,jj-1,jk)
+            zlv_vu(ji,jj,jk,2) = (  zfv(ji+1,jj  ,jk) - zfv(ji  ,jj  ,jk)  ) * fmask(ji  ,jj  ,jk)             &
+               &               - (  zfv(ji  ,jj  ,jk) - zfv(ji-1,jj  ,jk)  ) * fmask(ji-1,jj  ,jk)
          END_2D
       END DO
-      CALL lbc_lnk( 'dynadv_ubs', zlu_uu(:,:,:,1), 'U', 1.0_wp , zlu_uv(:,:,:,1), 'U', 1.0_wp,  &
-         &                        zlu_uu(:,:,:,2), 'U', 1.0_wp , zlu_uv(:,:,:,2), 'U', 1.0_wp,  & 
-         &                        zlv_vv(:,:,:,1), 'V', 1.0_wp , zlv_vu(:,:,:,1), 'V', 1.0_wp,  &
-         &                        zlv_vv(:,:,:,2), 'V', 1.0_wp , zlv_vu(:,:,:,2), 'V', 1.0_wp   )
+      IF( nn_hls == 1 ) CALL lbc_lnk( 'dynadv_ubs', zlu_uu(:,:,:,1), 'U', -1.0_wp , zlu_uv(:,:,:,1), 'U', -1.0_wp,  &
+                                              &   zlu_uu(:,:,:,2), 'U', -1.0_wp , zlu_uv(:,:,:,2), 'U', -1.0_wp,  &
+                                              &   zlv_vv(:,:,:,1), 'V', -1.0_wp , zlv_vu(:,:,:,1), 'V', -1.0_wp,  &
+                                              &   zlv_vv(:,:,:,2), 'V', -1.0_wp , zlv_vu(:,:,:,2), 'V', -1.0_wp   )
       !
       !                                      ! ====================== !
@@ -133,6 +157,8 @@
       DO jk = 1, jpkm1                       ! ====================== !
          !                                         ! horizontal volume fluxes
-         zfu(:,:,jk) = 0.25_wp * e2u(:,:) * e3u(:,:,jk,Kmm) * puu(:,:,jk,Kmm)
-         zfv(:,:,jk) = 0.25_wp * e1v(:,:) * e3v(:,:,jk,Kmm) * pvv(:,:,jk,Kmm)
+         DO_2D( 1, 1, 1, 1 )
+            zfu(ji,jj,jk) = 0.25_wp * e2u(ji,jj) * e3u(ji,jj,jk,Kmm) * puu(ji,jj,jk,Kmm)
+            zfv(ji,jj,jk) = 0.25_wp * e1v(ji,jj) * e3v(ji,jj,jk,Kmm) * pvv(ji,jj,jk,Kmm)
+         END_2D
          !
          DO_2D( 1, 0, 1, 0 )                       ! horizontal momentum fluxes at T- and F-point
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynatf.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynatf.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynatf.F90	(revision 14852)
@@ -201,5 +201,5 @@
          IF( ln_linssh ) THEN             ! Fixed volume !
             !                             ! =============!
-            DO_3D( 1, 1, 1, 1, 1, jpkm1 )
+            DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpkm1 )
                puu(ji,jj,jk,Kmm) = puu(ji,jj,jk,Kmm) + rn_atfp * ( puu(ji,jj,jk,Kbb) - 2._wp * puu(ji,jj,jk,Kmm) + puu(ji,jj,jk,Kaa) )
                pvv(ji,jj,jk,Kmm) = pvv(ji,jj,jk,Kmm) + rn_atfp * ( pvv(ji,jj,jk,Kbb) - 2._wp * pvv(ji,jj,jk,Kmm) + pvv(ji,jj,jk,Kaa) )
@@ -237,5 +237,5 @@
                CALL dom_vvl_interpol( pe3t(:,:,:,Kmm), pe3u(:,:,:,Kmm), 'U' )
                CALL dom_vvl_interpol( pe3t(:,:,:,Kmm), pe3v(:,:,:,Kmm), 'V' )
-               DO_3D( 1, 1, 1, 1, 1, jpkm1 )
+               DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpkm1 )
                   puu(ji,jj,jk,Kmm) = puu(ji,jj,jk,Kmm) + rn_atfp * ( puu(ji,jj,jk,Kbb) - 2._wp * puu(ji,jj,jk,Kmm) + puu(ji,jj,jk,Kaa) )
                   pvv(ji,jj,jk,Kmm) = pvv(ji,jj,jk,Kmm) + rn_atfp * ( pvv(ji,jj,jk,Kbb) - 2._wp * pvv(ji,jj,jk,Kmm) + pvv(ji,jj,jk,Kaa) )
@@ -248,5 +248,5 @@
                CALL dom_vvl_interpol( pe3t(:,:,:,Kmm), ze3u_f, 'U' )
                CALL dom_vvl_interpol( pe3t(:,:,:,Kmm), ze3v_f, 'V' )
-               DO_3D( 1, 1, 1, 1, 1, jpkm1 )
+               DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpkm1 )
                   zue3a = pe3u(ji,jj,jk,Kaa) * puu(ji,jj,jk,Kaa)
                   zve3a = pe3v(ji,jj,jk,Kaa) * pvv(ji,jj,jk,Kaa)
@@ -285,4 +285,6 @@
       ENDIF ! .NOT. l_1st_euler
       !
+      ! This is needed for dyn_ldf_blp to be restartable
+      IF( nn_hls == 2 ) CALL lbc_lnk( 'dynatf', puu(:,:,:,Kmm), 'U', -1.0_wp, pvv(:,:,:,Kmm), 'V', -1.0_wp )
       ! Set "now" and "before" barotropic velocities for next time step:
       ! JC: Would be more clever to swap variables than to make a full vertical
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynatf_qco.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynatf_qco.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynatf_qco.F90	(revision 14852)
@@ -139,5 +139,5 @@
          IF( ln_linssh ) THEN             ! Fixed volume !
             !                             ! =============!
-            DO_3D( 1, 1, 1, 1, 1, jpkm1 )
+            DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpkm1 )
                puu(ji,jj,jk,Kmm) = puu(ji,jj,jk,Kmm) + rn_atfp * ( puu(ji,jj,jk,Kbb) - 2._wp * puu(ji,jj,jk,Kmm) + puu(ji,jj,jk,Kaa) )
                pvv(ji,jj,jk,Kmm) = pvv(ji,jj,jk,Kmm) + rn_atfp * ( pvv(ji,jj,jk,Kbb) - 2._wp * pvv(ji,jj,jk,Kmm) + pvv(ji,jj,jk,Kaa) )
@@ -149,5 +149,5 @@
             IF( ln_dynadv_vec ) THEN      ! Asselin filter applied on velocity
                ! Before filtered scale factor at (u/v)-points
-               DO_3D( 1, 1, 1, 1, 1, jpkm1 )
+               DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpkm1 )
                   puu(ji,jj,jk,Kmm) = puu(ji,jj,jk,Kmm) + rn_atfp * ( puu(ji,jj,jk,Kbb) - 2._wp * puu(ji,jj,jk,Kmm) + puu(ji,jj,jk,Kaa) )
                   pvv(ji,jj,jk,Kmm) = pvv(ji,jj,jk,Kmm) + rn_atfp * ( pvv(ji,jj,jk,Kbb) - 2._wp * pvv(ji,jj,jk,Kmm) + pvv(ji,jj,jk,Kaa) )
@@ -156,5 +156,5 @@
             ELSE                          ! Asselin filter applied on thickness weighted velocity
                !
-               DO_3D( 1, 1, 1, 1, 1, jpkm1 )
+               DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpkm1 )
                   zue3a = ( 1._wp + r3u(ji,jj,Kaa) * umask(ji,jj,jk) ) * puu(ji,jj,jk,Kaa)
                   zve3a = ( 1._wp + r3v(ji,jj,Kaa) * vmask(ji,jj,jk) ) * pvv(ji,jj,jk,Kaa)
@@ -195,4 +195,7 @@
       ENDIF ! .NOT. l_1st_euler
       !
+      ! This is needed for dyn_ldf_blp to be restartable
+      IF( nn_hls == 2 ) CALL lbc_lnk( 'dynatfqco', puu(:,:,:,Kmm), 'U', -1.0_wp, pvv(:,:,:,Kmm), 'V', -1.0_wp )
+
       ! Set "now" and "before" barotropic velocities for next time step:
       ! JC: Would be more clever to swap variables than to make a full vertical
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynhpg.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynhpg.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynhpg.F90	(revision 14852)
@@ -266,11 +266,13 @@
       INTEGER  ::   ji, jj, jk       ! dummy loop indices
       REAL(wp) ::   zcoef0, zcoef1   ! temporary scalars
-      REAL(wp), DIMENSION(jpi,jpj) ::  zhpi, zhpj
-      !!----------------------------------------------------------------------
-      !
-      IF( kt == nit000 ) THEN
-         IF(lwp) WRITE(numout,*)
-         IF(lwp) WRITE(numout,*) 'dyn:hpg_zco : hydrostatic pressure gradient trend'
-         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~   z-coordinate case '
+      REAL(wp), DIMENSION(A2D(nn_hls)) ::  zhpi, zhpj
+      !!----------------------------------------------------------------------
+      !
+      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:hpg_zco : hydrostatic pressure gradient trend'
+            IF(lwp) WRITE(numout,*) '~~~~~~~~~~~   z-coordinate case '
+         ENDIF
       ENDIF
       !
@@ -318,13 +320,15 @@
       INTEGER  ::   iku, ikv                         ! temporary integers
       REAL(wp) ::   zcoef0, zcoef1, zcoef2, zcoef3   ! temporary scalars
-      REAL(wp), DIMENSION(jpi,jpj,jpk) :: zhpi, zhpj
-      REAL(wp), DIMENSION(jpi,jpj,jpts)   :: zgtsu, zgtsv
-      REAL(wp), DIMENSION(jpi,jpj)     :: zgru, zgrv
-      !!----------------------------------------------------------------------
-      !
-      IF( kt == nit000 ) THEN
-         IF(lwp) WRITE(numout,*)
-         IF(lwp) WRITE(numout,*) 'dyn:hpg_zps : hydrostatic pressure gradient trend'
-         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~   z-coordinate with partial steps - vector optimization'
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk ) :: zhpi, zhpj
+      REAL(wp), DIMENSION(A2D(nn_hls),jpts) :: zgtsu, zgtsv
+      REAL(wp), DIMENSION(A2D(nn_hls)     ) :: zgru, zgrv
+      !!----------------------------------------------------------------------
+      !
+      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:hpg_zps : hydrostatic pressure gradient trend'
+            IF(lwp) WRITE(numout,*) '~~~~~~~~~~~   z-coordinate with partial steps - vector optimization'
+         ENDIF
       ENDIF
 
@@ -410,14 +414,16 @@
       REAL(wp) ::   zcoef0, zuap, zvap, ztmp       ! local scalars
       LOGICAL  ::   ll_tmp1, ll_tmp2               ! local logical variables
-      REAL(wp), DIMENSION(jpi,jpj,jpk)      ::   zhpi, zhpj
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk)  ::   zhpi, zhpj
       REAL(wp), DIMENSION(:,:), ALLOCATABLE ::   zcpx, zcpy   !W/D pressure filter
       !!----------------------------------------------------------------------
       !
-      IF( ln_wd_il ) ALLOCATE(zcpx(jpi,jpj), zcpy(jpi,jpj))
-      !
-      IF( kt == nit000 ) THEN
-         IF(lwp) WRITE(numout,*)
-         IF(lwp) WRITE(numout,*) 'dyn:hpg_sco : hydrostatic pressure gradient trend'
-         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~   s-coordinate case, OCE original scheme used'
+      IF( ln_wd_il ) ALLOCATE(zcpx(A2D(nn_hls)), zcpy(A2D(nn_hls)))
+      !
+      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:hpg_sco : hydrostatic pressure gradient trend'
+            IF(lwp) WRITE(numout,*) '~~~~~~~~~~~   s-coordinate case, OCE original scheme used'
+         ENDIF
       ENDIF
       !
@@ -462,5 +468,4 @@
           END IF
         END_2D
-        CALL lbc_lnk( 'dynhpg', zcpx, 'U', 1.0_wp, zcpy, 'V', 1.0_wp )
       END IF
       !
@@ -548,7 +553,7 @@
       REAL(wp) ::   ze3w, ze3wi1, ze3wj1   ! local scalars
       REAL(wp) ::   zcoef0, zuap, zvap     !   -      -
-      REAL(wp), DIMENSION(jpi,jpj,jpk ) ::  zhpi, zhpj
-      REAL(wp), DIMENSION(jpi,jpj,jpts) ::  zts_top
-      REAL(wp), DIMENSION(jpi,jpj)      ::  zrhdtop_oce
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk ) ::  zhpi, zhpj
+      REAL(wp), DIMENSION(A2D(nn_hls),jpts) ::  zts_top
+      REAL(wp), DIMENSION(A2D(nn_hls))      ::  zrhdtop_oce
       !!----------------------------------------------------------------------
       !
@@ -560,11 +565,9 @@
       ! compute rhd at the ice/oce interface (ocean side)
       ! usefull to reduce residual current in the test case ISOMIP with no melting
-      DO ji = 1, jpi
-        DO jj = 1, jpj
-          ikt = mikt(ji,jj)
-          zts_top(ji,jj,1) = ts(ji,jj,ikt,1,Kmm)
-          zts_top(ji,jj,2) = ts(ji,jj,ikt,2,Kmm)
-        END DO
-      END DO
+      DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
+         ikt = mikt(ji,jj)
+         zts_top(ji,jj,1) = ts(ji,jj,ikt,1,Kmm)
+         zts_top(ji,jj,2) = ts(ji,jj,ikt,2,Kmm)
+      END_2D
       CALL eos( zts_top, risfdep, zrhdtop_oce )
 
@@ -636,21 +639,21 @@
       INTEGER  ::   iktb, iktt          ! jk indices at tracer points for top and bottom points 
       REAL(wp) ::   zcoef0, zep, cffw   ! temporary scalars
-      REAL(wp) ::   z_grav_10, z1_12
+      REAL(wp) ::   z_grav_10, z1_12, z1_cff
       REAL(wp) ::   cffu, cffx          !    "         "
       REAL(wp) ::   cffv, cffy          !    "         "
       LOGICAL  ::   ll_tmp1, ll_tmp2    ! local logical variables
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zhpi, zhpj
- 
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zdzx, zdzy, zdzz                          ! Primitive grid differences ('delta_xyz')
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zdz_i, zdz_j, zdz_k                       ! Harmonic average of primitive grid differences ('d_xyz')
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zdrhox, zdrhoy, zdrhoz                    ! Primitive rho differences ('delta_rho')
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zdrho_i, zdrho_j, zdrho_k                 ! Harmonic average of primitive rho differences ('d_rho')
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   z_rho_i, z_rho_j, z_rho_k                 ! Face intergrals
-      REAL(wp), DIMENSION(jpi,jpj)     ::   zz_dz_i, zz_dz_j, zz_drho_i, zz_drho_j    ! temporary arrays 
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zhpi, zhpj
+
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zdzx, zdzy, zdzz                          ! Primitive grid differences ('delta_xyz')
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zdz_i, zdz_j, zdz_k                       ! Harmonic average of primitive grid differences ('d_xyz')
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zdrhox, zdrhoy, zdrhoz                    ! Primitive rho differences ('delta_rho')
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zdrho_i, zdrho_j, zdrho_k                 ! Harmonic average of primitive rho differences ('d_rho')
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   z_rho_i, z_rho_j, z_rho_k                 ! Face intergrals
+      REAL(wp), DIMENSION(A2D(nn_hls))     ::   zz_dz_i, zz_dz_j, zz_drho_i, zz_drho_j    ! temporary arrays
       REAL(wp), DIMENSION(:,:), ALLOCATABLE ::   zcpx, zcpy   !W/D pressure filter
       !!----------------------------------------------------------------------
       !
       IF( ln_wd_il ) THEN
-         ALLOCATE( zcpx(jpi,jpj) , zcpy(jpi,jpj) )
+         ALLOCATE( zcpx(A2D(nn_hls)) , zcpy(A2D(nn_hls)) )
         DO_2D( 0, 0, 0, 0 )
           ll_tmp1 = MIN(  ssh(ji,jj,Kmm)              ,  ssh(ji+1,jj,Kmm) ) >                &
@@ -689,11 +692,12 @@
           END IF
         END_2D
-        CALL lbc_lnk( 'dynhpg', zcpx, 'U', 1.0_wp, zcpy, 'V', 1.0_wp )
       END IF
 
-      IF( kt == nit000 ) THEN
-         IF(lwp) WRITE(numout,*)
-         IF(lwp) WRITE(numout,*) 'dyn:hpg_djc : hydrostatic pressure gradient trend'
-         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~   s-coordinate case, density Jacobian with cubic polynomial scheme'
+      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:hpg_djc : hydrostatic pressure gradient trend'
+            IF(lwp) WRITE(numout,*) '~~~~~~~~~~~   s-coordinate case, density Jacobian with cubic polynomial scheme'
+         ENDIF
       ENDIF
 
@@ -723,9 +727,8 @@
       zdz_k  (:,:,:) = 0._wp
 
-      DO_3D( 1, 1, 1, 1, 2, jpk-2 ) 
-         cffw = 2._wp * zdrhoz(ji  ,jj  ,jk) * zdrhoz(ji,jj,jk+1)
-         IF( cffw > zep) THEN
-            zdrho_k(ji,jj,jk) = cffw / ( zdrhoz(ji,jj,jk) + zdrhoz(ji,jj,jk+1) )
-         ENDIF
+      DO_3D( 1, 1, 1, 1, 2, jpk-2 )
+         cffw = MAX( 2._wp * zdrhoz(ji,jj,jk) * zdrhoz(ji,jj,jk+1), 0._wp )
+         z1_cff = zdrhoz(ji,jj,jk) + zdrhoz(ji,jj,jk+1)
+         zdrho_k(ji,jj,jk) = cffw / SIGN( MAX( ABS(z1_cff), zep ), z1_cff )
          zdz_k(ji,jj,jk) = 2._wp *   zdzz(ji,jj,jk) * zdzz(ji,jj,jk+1)   &
             &                  / ( zdzz(ji,jj,jk) + zdzz(ji,jj,jk+1) )
@@ -737,6 +740,8 @@
 
 ! mb for sea-ice shelves we will need to re-write this upper boundary condition in the same form as the lower boundary condition
-      zdrho_k(:,:,1) = aco_bc_vrt * ( rhd    (:,:,2) - rhd    (:,:,1) ) - bco_bc_vrt * zdrho_k(:,:,2)
-      zdz_k  (:,:,1) = aco_bc_vrt * (-gde3w(:,:,2) + gde3w(:,:,1) ) - bco_bc_vrt * zdz_k  (:,:,2)
+      DO_2D( 1, 1, 1, 1 )
+         zdrho_k(ji,jj,1) = aco_bc_vrt * ( rhd  (ji,jj,2) - rhd  (ji,jj,1) ) - bco_bc_vrt * zdrho_k(ji,jj,2)
+         zdz_k  (ji,jj,1) = aco_bc_vrt * (-gde3w(ji,jj,2) + gde3w(ji,jj,1) ) - bco_bc_vrt * zdz_k  (ji,jj,2)
+      END_2D
 
       DO_2D( 1, 1, 1, 1 )
@@ -785,13 +790,17 @@
       !  5. compute and store elementary horizontal differences in provisional arrays 
       !----------------------------------------------------------------------------------------
-
-      DO_3D( 1, 0, 1, 0, 1, jpkm1 )
-         zdrhox(ji,jj,jk) =   rhd    (ji+1,jj  ,jk) - rhd    (ji,jj,jk  )
-         zdzx  (ji,jj,jk) = - gde3w(ji+1,jj  ,jk) + gde3w(ji,jj,jk  )
-         zdrhoy(ji,jj,jk) =   rhd    (ji  ,jj+1,jk) - rhd    (ji,jj,jk  )
-         zdzy  (ji,jj,jk) = - gde3w(ji  ,jj+1,jk) + gde3w(ji,jj,jk  )
-      END_3D
-
-      CALL lbc_lnk( 'dynhpg', zdrhox, 'U', 1., zdzx, 'U', 1., zdrhoy, 'V', 1., zdzy, 'V', 1. ) 
+      zdrhox(:,:,:) = 0._wp
+      zdzx  (:,:,:) = 0._wp
+      zdrhoy(:,:,:) = 0._wp
+      zdzy  (:,:,:) = 0._wp
+
+      DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpkm1 )
+         zdrhox(ji,jj,jk) = rhd  (ji+1,jj  ,jk) - rhd  (ji  ,jj  ,jk)
+         zdzx  (ji,jj,jk) = gde3w(ji  ,jj  ,jk) - gde3w(ji+1,jj  ,jk)
+         zdrhoy(ji,jj,jk) = rhd  (ji  ,jj+1,jk) - rhd  (ji  ,jj  ,jk)
+         zdzy  (ji,jj,jk) = gde3w(ji  ,jj  ,jk) - gde3w(ji  ,jj+1,jk)
+      END_3D
+
+      IF( nn_hls == 1 ) CALL lbc_lnk( 'dynhpg', zdrhox, 'U', -1._wp, zdzx, 'U', -1._wp, zdrhoy, 'V', -1._wp, zdzy, 'V', -1._wp )
 
       !-------------------------------------------------------------------------
@@ -800,31 +809,19 @@
 
       DO_3D( 0, 1, 0, 1, 1, jpkm1 )
-         cffu = 2._wp * zdrhox(ji-1,jj  ,jk) * zdrhox(ji,jj,jk  )
-         IF( cffu > zep ) THEN
-            zdrho_i(ji,jj,jk) = cffu / ( zdrhox(ji-1,jj,jk) + zdrhox(ji,jj,jk) )
-         ELSE
-            zdrho_i(ji,jj,jk ) = 0._wp
-         ENDIF
-
-         cffx = 2._wp * zdzx  (ji-1,jj  ,jk) * zdzx  (ji,jj,jk  )
-         IF( cffx > zep ) THEN
-            zdz_i(ji,jj,jk) = cffx / ( zdzx(ji-1,jj,jk) + zdzx(ji,jj,jk) )
-         ELSE
-            zdz_i(ji,jj,jk) = 0._wp
-         ENDIF
-
-         cffv = 2._wp * zdrhoy(ji  ,jj-1,jk) * zdrhoy(ji,jj,jk  )
-         IF( cffv > zep ) THEN
-            zdrho_j(ji,jj,jk) = cffv / ( zdrhoy(ji,jj-1,jk) + zdrhoy(ji,jj,jk) )
-         ELSE
-            zdrho_j(ji,jj,jk) = 0._wp
-         ENDIF
-
-         cffy = 2._wp * zdzy  (ji  ,jj-1,jk) * zdzy  (ji,jj,jk  )
-         IF( cffy > zep ) THEN
-            zdz_j(ji,jj,jk) = cffy / ( zdzy(ji,jj-1,jk) + zdzy(ji,jj,jk) )
-         ELSE
-            zdz_j(ji,jj,jk) = 0._wp
-         ENDIF
+         cffu = MAX( 2._wp * zdrhox(ji-1,jj,jk) * zdrhox(ji,jj,jk), 0._wp )
+         z1_cff = zdrhox(ji-1,jj,jk) + zdrhox(ji,jj,jk)
+         zdrho_i(ji,jj,jk) = cffu / SIGN( MAX( ABS(z1_cff), zep ), z1_cff )
+
+         cffx = MAX( 2._wp * zdzx(ji-1,jj,jk)   * zdzx(ji,jj,jk), 0._wp )
+         z1_cff = zdzx(ji-1,jj,jk)   + zdzx(ji,jj,jk)
+         zdz_i(ji,jj,jk)   = cffx / SIGN( MAX( ABS(z1_cff), zep ), z1_cff )
+
+         cffv = MAX( 2._wp * zdrhoy(ji,jj-1,jk) * zdrhoy(ji,jj,jk), 0._wp )
+         z1_cff = zdrhoy(ji,jj-1,jk) + zdrhoy(ji,jj,jk)
+         zdrho_j(ji,jj,jk) = cffv / SIGN( MAX( ABS(z1_cff), zep ), z1_cff )
+
+         cffy = MAX( 2._wp * zdzy(ji,jj-1,jk)   * zdzy(ji,jj,jk), 0._wp )
+         z1_cff = zdzy(ji,jj-1,jk)   + zdzy(ji,jj,jk)
+         zdz_j(ji,jj,jk)   = cffy / SIGN( MAX( ABS(z1_cff), zep ), z1_cff )
       END_3D
       
@@ -840,32 +837,30 @@
          zz_drho_j(:,:) = zdrho_j(:,:,jk)
          zz_dz_j  (:,:) = zdz_j  (:,:,jk)
-         DO_2D( 0, 1, 0, 1)
-            ! Walls coming from left: should check from 2 to jpi-1 (and jpj=2-jpj)
-            IF (ji < jpi) THEN
-               IF ( umask(ji,jj,jk) > 0.5_wp .AND. umask(ji-1,jj,jk) < 0.5_wp .AND. umask(ji+1,jj,jk) > 0.5_wp)  THEN  
-                  zz_drho_i(ji,jj) = aco_bc_hor * ( rhd    (ji+1,jj,jk) - rhd    (ji,jj,jk) ) - bco_bc_hor * zdrho_i(ji+1,jj,jk) 
-                  zz_dz_i  (ji,jj) = aco_bc_hor * (-gde3w(ji+1,jj,jk) + gde3w(ji,jj,jk) ) - bco_bc_hor * zdz_i  (ji+1,jj,jk)
-               END IF
+         ! Walls coming from left: should check from 2 to jpi-1 (and jpj=2-jpj)
+         DO_2D( 0, 0, 0, 1 )
+            IF ( umask(ji,jj,jk) > 0.5_wp .AND. umask(ji-1,jj,jk) < 0.5_wp .AND. umask(ji+1,jj,jk) > 0.5_wp)  THEN
+               zz_drho_i(ji,jj) = aco_bc_hor * ( rhd    (ji+1,jj,jk) - rhd    (ji,jj,jk) ) - bco_bc_hor * zdrho_i(ji+1,jj,jk)
+               zz_dz_i  (ji,jj) = aco_bc_hor * (-gde3w(ji+1,jj,jk) + gde3w(ji,jj,jk) ) - bco_bc_hor * zdz_i  (ji+1,jj,jk)
             END IF
-            ! Walls coming from right: should check from 3 to jpi (and jpj=2-jpj)
-            IF (ji > 2) THEN
-               IF ( umask(ji,jj,jk) < 0.5_wp .AND. umask(ji-1,jj,jk) > 0.5_wp .AND. umask(ji-2,jj,jk) > 0.5_wp) THEN
-                  zz_drho_i(ji,jj) = aco_bc_hor * ( rhd    (ji,jj,jk) - rhd    (ji-1,jj,jk) ) - bco_bc_hor * zdrho_i(ji-1,jj,jk)  
-                  zz_dz_i  (ji,jj) = aco_bc_hor * (-gde3w(ji,jj,jk) + gde3w(ji-1,jj,jk) ) - bco_bc_hor * zdz_i  (ji-1,jj,jk)
-               END IF
+         END_2D
+         ! Walls coming from right: should check from 3 to jpi (and jpj=2-jpj)
+         DO_2D( -1, 1, 0, 1 )
+            IF ( umask(ji,jj,jk) < 0.5_wp .AND. umask(ji-1,jj,jk) > 0.5_wp .AND. umask(ji-2,jj,jk) > 0.5_wp) THEN
+               zz_drho_i(ji,jj) = aco_bc_hor * ( rhd    (ji,jj,jk) - rhd    (ji-1,jj,jk) ) - bco_bc_hor * zdrho_i(ji-1,jj,jk)
+               zz_dz_i  (ji,jj) = aco_bc_hor * (-gde3w(ji,jj,jk) + gde3w(ji-1,jj,jk) ) - bco_bc_hor * zdz_i  (ji-1,jj,jk)
             END IF
-            ! Walls coming from left: should check from 2 to jpj-1 (and jpi=2-jpi)
-            IF (jj < jpj) THEN
-               IF ( vmask(ji,jj,jk) > 0.5_wp .AND. vmask(ji,jj-1,jk) < 0.5_wp .AND. vmask(ji,jj+1,jk) > 0.5_wp)  THEN
-                  zz_drho_j(ji,jj) = aco_bc_hor * ( rhd    (ji,jj+1,jk) - rhd    (ji,jj,jk) ) - bco_bc_hor * zdrho_j(ji,jj+1,jk)
-                  zz_dz_j  (ji,jj) = aco_bc_hor * (-gde3w(ji,jj+1,jk) + gde3w(ji,jj,jk) ) - bco_bc_hor * zdz_j  (ji,jj+1,jk)
-               END IF
-            END IF 
-            ! Walls coming from right: should check from 3 to jpj (and jpi=2-jpi)
-            IF (jj > 2) THEN
-               IF ( vmask(ji,jj,jk) < 0.5_wp .AND. vmask(ji,jj-1,jk) > 0.5_wp .AND. vmask(ji,jj-2,jk) > 0.5_wp) THEN 
-                  zz_drho_j(ji,jj) = aco_bc_hor * ( rhd    (ji,jj,jk) - rhd    (ji,jj-1,jk) ) - bco_bc_hor * zdrho_j(ji,jj-1,jk) 
-                  zz_dz_j  (ji,jj) = aco_bc_hor * (-gde3w(ji,jj,jk) + gde3w(ji,jj-1,jk) ) - bco_bc_hor * zdz_j  (ji,jj-1,jk)
-               END IF
+         END_2D
+         ! Walls coming from left: should check from 2 to jpj-1 (and jpi=2-jpi)
+         DO_2D( 0, 1, 0, 0 )
+            IF ( vmask(ji,jj,jk) > 0.5_wp .AND. vmask(ji,jj-1,jk) < 0.5_wp .AND. vmask(ji,jj+1,jk) > 0.5_wp)  THEN
+               zz_drho_j(ji,jj) = aco_bc_hor * ( rhd    (ji,jj+1,jk) - rhd    (ji,jj,jk) ) - bco_bc_hor * zdrho_j(ji,jj+1,jk)
+               zz_dz_j  (ji,jj) = aco_bc_hor * (-gde3w(ji,jj+1,jk) + gde3w(ji,jj,jk) ) - bco_bc_hor * zdz_j  (ji,jj+1,jk)
+            END IF
+         END_2D
+         ! Walls coming from right: should check from 3 to jpj (and jpi=2-jpi)
+         DO_2D( 0, 1, -1, 1 )
+            IF ( vmask(ji,jj,jk) < 0.5_wp .AND. vmask(ji,jj-1,jk) > 0.5_wp .AND. vmask(ji,jj-2,jk) > 0.5_wp) THEN
+               zz_drho_j(ji,jj) = aco_bc_hor * ( rhd    (ji,jj,jk) - rhd    (ji,jj-1,jk) ) - bco_bc_hor * zdrho_j(ji,jj-1,jk)
+               zz_dz_j  (ji,jj) = aco_bc_hor * (-gde3w(ji,jj,jk) + gde3w(ji,jj-1,jk) ) - bco_bc_hor * zdz_j  (ji,jj-1,jk)
             END IF
          END_2D
@@ -974,15 +969,17 @@
       REAL(wp) :: zrhdt1
       REAL(wp) :: zdpdx1, zdpdx2, zdpdy1, zdpdy2
-      REAL(wp), DIMENSION(jpi,jpj)     ::   zpgu, zpgv   ! 2D workspace
-      REAL(wp), DIMENSION(jpi,jpj)     ::   zsshu_n, zsshv_n
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zdept, zrhh
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zhpi, zu, zv, fsp, xsp, asp, bsp, csp, dsp
+      REAL(wp), DIMENSION(A2D(nn_hls))     ::   zpgu, zpgv   ! 2D workspace
+      REAL(wp), DIMENSION(A2D(nn_hls))     ::   zsshu_n, zsshv_n
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zdept, zrhh
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zhpi, zu, zv, fsp, xsp, asp, bsp, csp, dsp
       REAL(wp), DIMENSION(:,:), ALLOCATABLE ::   zcpx, zcpy   !W/D pressure filter
       !!----------------------------------------------------------------------
       !
-      IF( kt == nit000 ) THEN
-         IF(lwp) WRITE(numout,*)
-         IF(lwp) WRITE(numout,*) 'dyn:hpg_prj : hydrostatic pressure gradient trend'
-         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~   s-coordinate case, cubic spline pressure Jacobian'
+      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:hpg_prj : hydrostatic pressure gradient trend'
+            IF(lwp) WRITE(numout,*) '~~~~~~~~~~~   s-coordinate case, cubic spline pressure Jacobian'
+         ENDIF
       ENDIF
 
@@ -1001,64 +998,61 @@
       !
       IF( ln_wd_il ) THEN
-         ALLOCATE( zcpx(jpi,jpj) , zcpy(jpi,jpj) )
+         ALLOCATE( zcpx(A2D(nn_hls)) , zcpy(A2D(nn_hls)) )
          DO_2D( 0, 0, 0, 0 )
-          ll_tmp1 = MIN(  ssh(ji,jj,Kmm)              ,  ssh(ji+1,jj,Kmm) ) >                &
-               &    MAX( -ht_0(ji,jj)              , -ht_0(ji+1,jj) ) .AND.            &
-               &    MAX(  ssh(ji,jj,Kmm) + ht_0(ji,jj),  ssh(ji+1,jj,Kmm) + ht_0(ji+1,jj) )  &
-               &                                                      > rn_wdmin1 + rn_wdmin2
-          ll_tmp2 = ( ABS( ssh(ji,jj,Kmm)             -  ssh(ji+1,jj,Kmm) ) > 1.E-12 ) .AND. (         &
-               &    MAX(   ssh(ji,jj,Kmm)             ,  ssh(ji+1,jj,Kmm) ) >                &
-               &    MAX(  -ht_0(ji,jj)             , -ht_0(ji+1,jj) ) + rn_wdmin1 + rn_wdmin2 )
-
-          IF(ll_tmp1) THEN
-            zcpx(ji,jj) = 1.0_wp
-          ELSE IF(ll_tmp2) THEN
-            ! no worries about  ssh(ji+1,jj,Kmm) -  ssh(ji  ,jj,Kmm) = 0, it won't happen ! here
-            zcpx(ji,jj) = ABS( (ssh(ji+1,jj,Kmm) + ht_0(ji+1,jj) - ssh(ji,jj,Kmm) - ht_0(ji,jj)) &
-                        &    / (ssh(ji+1,jj,Kmm) -  ssh(ji  ,jj,Kmm)) )
-           
-             zcpx(ji,jj) = max(min( zcpx(ji,jj) , 1.0_wp),0.0_wp)
-          ELSE
-            zcpx(ji,jj) = 0._wp
-          END IF
-   
-          ll_tmp1 = MIN(  ssh(ji,jj,Kmm)              ,  ssh(ji,jj+1,Kmm) ) >                &
-               &    MAX( -ht_0(ji,jj)              , -ht_0(ji,jj+1) ) .AND.            &
-               &    MAX(  ssh(ji,jj,Kmm) + ht_0(ji,jj),  ssh(ji,jj+1,Kmm) + ht_0(ji,jj+1) )  &
-               &                                                      > rn_wdmin1 + rn_wdmin2
-          ll_tmp2 = ( ABS( ssh(ji,jj,Kmm)             -  ssh(ji,jj+1,Kmm) ) > 1.E-12 ) .AND. (      &
-               &    MAX(   ssh(ji,jj,Kmm)             ,  ssh(ji,jj+1,Kmm) ) >                &
-               &    MAX(  -ht_0(ji,jj)             , -ht_0(ji,jj+1) ) + rn_wdmin1 + rn_wdmin2 )
-
-          IF(ll_tmp1) THEN
-            zcpy(ji,jj) = 1.0_wp
-          ELSE IF(ll_tmp2) THEN
-            ! no worries about  ssh(ji,jj+1,Kmm) -  ssh(ji,jj  ,Kmm) = 0, it won't happen ! here
-            zcpy(ji,jj) = ABS( (ssh(ji,jj+1,Kmm) + ht_0(ji,jj+1) - ssh(ji,jj,Kmm) - ht_0(ji,jj)) &
-                        &    / (ssh(ji,jj+1,Kmm) - ssh(ji,jj  ,Kmm)) )
-             zcpy(ji,jj) = max(min( zcpy(ji,jj) , 1.0_wp),0.0_wp)
-
+            ll_tmp1 = MIN(   ssh(ji,jj,Kmm)              ,   ssh(ji+1,jj,Kmm)                 ) >       &
+               &      MAX( -ht_0(ji,jj)                  , -ht_0(ji+1,jj)                     ) .AND.   &
+               &      MAX(   ssh(ji,jj,Kmm) + ht_0(ji,jj),   ssh(ji+1,jj,Kmm) + ht_0(ji+1,jj) ) >       &
+               &      rn_wdmin1 + rn_wdmin2
+            ll_tmp2 = ( ABS(   ssh(ji,jj,Kmm) -   ssh(ji+1,jj,Kmm) ) > 1.E-12 ) .AND.                   &
+               &      ( MAX(   ssh(ji,jj,Kmm) ,   ssh(ji+1,jj,Kmm) ) >                                  &
+               &        MAX( -ht_0(ji,jj)     , -ht_0(ji+1,jj)     ) + rn_wdmin1 + rn_wdmin2 )
+
+            IF(ll_tmp1) THEN
+               zcpx(ji,jj) = 1.0_wp
+            ELSE IF(ll_tmp2) THEN
+               ! no worries about  ssh(ji+1,jj,Kmm) -  ssh(ji  ,jj,Kmm) = 0, it won't happen ! here
+               zcpx(ji,jj) = ABS( (ssh(ji+1,jj,Kmm) + ht_0(ji+1,jj) - ssh(ji,jj,Kmm) - ht_0(ji,jj)) &
+                           &    / (ssh(ji+1,jj,Kmm) -  ssh(ji  ,jj,Kmm)) )
+               zcpx(ji,jj) = MAX(MIN( zcpx(ji,jj) , 1.0_wp),0.0_wp)
+            ELSE
+               zcpx(ji,jj) = 0._wp
+            END IF
+
+            ll_tmp1 = MIN(   ssh(ji,jj,Kmm)              ,   ssh(ji,jj+1,Kmm)                 ) >       &
+               &      MAX( -ht_0(ji,jj)                  , -ht_0(ji,jj+1)                     ) .AND.   &
+               &      MAX(   ssh(ji,jj,Kmm) + ht_0(ji,jj),   ssh(ji,jj+1,Kmm) + ht_0(ji,jj+1) ) >       &
+               &      rn_wdmin1 + rn_wdmin2
+            ll_tmp2 = ( ABS(   ssh(ji,jj,Kmm) -   ssh(ji,jj+1,Kmm) ) > 1.E-12 ) .AND.                   &
+               &      ( MAX(   ssh(ji,jj,Kmm) ,   ssh(ji,jj+1,Kmm) ) >                                  &
+               &        MAX( -ht_0(ji,jj)     , -ht_0(ji,jj+1)     ) + rn_wdmin1 + rn_wdmin2 )
+
+            IF(ll_tmp1) THEN
+               zcpy(ji,jj) = 1.0_wp
+            ELSE IF(ll_tmp2) THEN
+               ! no worries about  ssh(ji,jj+1,Kmm) -  ssh(ji,jj  ,Kmm) = 0, it won't happen ! here
+               zcpy(ji,jj) = ABS( (ssh(ji,jj+1,Kmm) + ht_0(ji,jj+1) - ssh(ji,jj,Kmm) - ht_0(ji,jj)) &
+                           &    / (ssh(ji,jj+1,Kmm) -  ssh(ji,jj  ,Kmm)) )
+               zcpy(ji,jj) = MAX(MIN( zcpy(ji,jj) , 1.0_wp),0.0_wp)
             ELSE
                zcpy(ji,jj) = 0._wp
             ENDIF
          END_2D
-         CALL lbc_lnk( 'dynhpg', zcpx, 'U', 1.0_wp, zcpy, 'V', 1.0_wp )
       ENDIF
 
       ! Clean 3-D work arrays
       zhpi(:,:,:) = 0._wp
-      zrhh(:,:,:) = rhd(:,:,:)
+      zrhh(:,:,:) = rhd(A2D(nn_hls),:)
 
       ! Preparing vertical density profile "zrhh(:,:,:)" for hybrid-sco coordinate
       DO_2D( 1, 1, 1, 1 )
-       jk = mbkt(ji,jj)
-       IF(     jk <=  1   ) THEN   ;   zrhh(ji,jj,    :   ) = 0._wp
-       ELSEIF( jk ==  2   ) THEN   ;   zrhh(ji,jj,jk+1:jpk) = rhd(ji,jj,jk)
-       ELSEIF( jk < jpkm1 ) THEN
-          DO jkk = jk+1, jpk
-             zrhh(ji,jj,jkk) = interp1(gde3w(ji,jj,jkk  ), gde3w(ji,jj,jkk-1),   &
-                &                      gde3w(ji,jj,jkk-2), zrhh (ji,jj,jkk-1), zrhh(ji,jj,jkk-2))
-          END DO
-       ENDIF
+         jk = mbkt(ji,jj)
+         IF(     jk <=  1   ) THEN   ;   zrhh(ji,jj,    :   ) = 0._wp
+         ELSEIF( jk ==  2   ) THEN   ;   zrhh(ji,jj,jk+1:jpk) = rhd(ji,jj,jk)
+         ELSEIF( jk < jpkm1 ) THEN
+            DO jkk = jk+1, jpk
+               zrhh(ji,jj,jkk) = interp1(gde3w(ji,jj,jkk  ), gde3w(ji,jj,jkk-1),   &
+                  &                      gde3w(ji,jj,jkk-2), zrhh (ji,jj,jkk-1), zrhh(ji,jj,jkk-2))
+            END DO
+         ENDIF
       END_2D
 
@@ -1082,17 +1076,17 @@
       ! Integrate the hydrostatic pressure "zhpi(:,:,:)" at "T(ji,jj,1)"
       DO_2D( 0, 1, 0, 1 )
-       zrhdt1 = zrhh(ji,jj,1) - interp3( zdept(ji,jj,1), asp(ji,jj,1), bsp(ji,jj,1),  &
-          &                                              csp(ji,jj,1), dsp(ji,jj,1) ) * 0.25_wp * e3w(ji,jj,1,Kmm)
-
-       ! assuming linear profile across the top half surface layer
-       zhpi(ji,jj,1) =  0.5_wp * e3w(ji,jj,1,Kmm) * zrhdt1
+         zrhdt1 = zrhh(ji,jj,1) - interp3( zdept(ji,jj,1), asp(ji,jj,1), bsp(ji,jj,1),  &
+            &                                              csp(ji,jj,1), dsp(ji,jj,1) ) * 0.25_wp * e3w(ji,jj,1,Kmm)
+
+         ! assuming linear profile across the top half surface layer
+         zhpi(ji,jj,1) =  0.5_wp * e3w(ji,jj,1,Kmm) * zrhdt1
       END_2D
 
       ! Calculate the pressure "zhpi(:,:,:)" at "T(ji,jj,2:jpkm1)"
       DO_3D( 0, 1, 0, 1, 2, jpkm1 )
-      zhpi(ji,jj,jk) = zhpi(ji,jj,jk-1) +                                  &
-         &             integ_spline( zdept(ji,jj,jk-1), zdept(ji,jj,jk),   &
-         &                           asp  (ji,jj,jk-1), bsp  (ji,jj,jk-1), &
-         &                           csp  (ji,jj,jk-1), dsp  (ji,jj,jk-1)  )
+         zhpi(ji,jj,jk) = zhpi(ji,jj,jk-1) +                                  &
+            &             integ_spline( zdept(ji,jj,jk-1), zdept(ji,jj,jk),   &
+            &                           asp  (ji,jj,jk-1), bsp  (ji,jj,jk-1), &
+            &                           csp  (ji,jj,jk-1), dsp  (ji,jj,jk-1)  )
       END_3D
 
@@ -1107,158 +1101,153 @@
 !                         & r1_e1e2v(ji,jj) * vmask(ji,jj,1) * 0.5_wp 
 !!gm not this:
-       zsshu_n(ji,jj) = (e1e2u(ji,jj) * ssh(ji,jj,Kmm) + e1e2u(ji+1, jj) * ssh(ji+1,jj,Kmm)) * &
-                      & r1_e1e2u(ji,jj) * umask(ji,jj,1) * 0.5_wp 
-       zsshv_n(ji,jj) = (e1e2v(ji,jj) * ssh(ji,jj,Kmm) + e1e2v(ji+1, jj) * ssh(ji,jj+1,Kmm)) * &
-                      & r1_e1e2v(ji,jj) * vmask(ji,jj,1) * 0.5_wp 
-      END_2D
-
-      CALL lbc_lnk ('dynhpg', zsshu_n, 'U', 1.0_wp, zsshv_n, 'V', 1.0_wp )
+         zsshu_n(ji,jj) = (e1e2u(ji,jj) * ssh(ji,jj,Kmm) + e1e2u(ji+1, jj) * ssh(ji+1,jj,Kmm)) * &
+                        & r1_e1e2u(ji,jj) * umask(ji,jj,1) * 0.5_wp
+         zsshv_n(ji,jj) = (e1e2v(ji,jj) * ssh(ji,jj,Kmm) + e1e2v(ji+1, jj) * ssh(ji,jj+1,Kmm)) * &
+                        & r1_e1e2v(ji,jj) * vmask(ji,jj,1) * 0.5_wp
+      END_2D
 
       DO_2D( 0, 0, 0, 0 )
-       zu(ji,jj,1) = - ( e3u(ji,jj,1,Kmm) - zsshu_n(ji,jj) ) 
-       zv(ji,jj,1) = - ( e3v(ji,jj,1,Kmm) - zsshv_n(ji,jj) )
+         zu(ji,jj,1) = - ( e3u(ji,jj,1,Kmm) - zsshu_n(ji,jj) )
+         zv(ji,jj,1) = - ( e3v(ji,jj,1,Kmm) - zsshv_n(ji,jj) )
       END_2D
 
       DO_3D( 0, 0, 0, 0, 2, jpkm1 )
-      zu(ji,jj,jk) = zu(ji,jj,jk-1) - e3u(ji,jj,jk,Kmm)
-      zv(ji,jj,jk) = zv(ji,jj,jk-1) - e3v(ji,jj,jk,Kmm)
+         zu(ji,jj,jk) = zu(ji,jj,jk-1) - e3u(ji,jj,jk,Kmm)
+         zv(ji,jj,jk) = zv(ji,jj,jk-1) - e3v(ji,jj,jk,Kmm)
       END_3D
 
       DO_3D( 0, 0, 0, 0, 1, jpkm1 )
-      zu(ji,jj,jk) = zu(ji,jj,jk) + 0.5_wp * e3u(ji,jj,jk,Kmm)
-      zv(ji,jj,jk) = zv(ji,jj,jk) + 0.5_wp * e3v(ji,jj,jk,Kmm)
+         zu(ji,jj,jk) = zu(ji,jj,jk) + 0.5_wp * e3u(ji,jj,jk,Kmm)
+         zv(ji,jj,jk) = zv(ji,jj,jk) + 0.5_wp * e3v(ji,jj,jk,Kmm)
       END_3D
 
       DO_3D( 0, 0, 0, 0, 1, jpkm1 )
-      zu(ji,jj,jk) = MIN(  zu(ji,jj,jk) , MAX( -zdept(ji,jj,jk) , -zdept(ji+1,jj,jk) )  )
-      zu(ji,jj,jk) = MAX(  zu(ji,jj,jk) , MIN( -zdept(ji,jj,jk) , -zdept(ji+1,jj,jk) )  )
-      zv(ji,jj,jk) = MIN(  zv(ji,jj,jk) , MAX( -zdept(ji,jj,jk) , -zdept(ji,jj+1,jk) )  )
-      zv(ji,jj,jk) = MAX(  zv(ji,jj,jk) , MIN( -zdept(ji,jj,jk) , -zdept(ji,jj+1,jk) )  )
+         zu(ji,jj,jk) = MIN(  zu(ji,jj,jk) , MAX( -zdept(ji,jj,jk) , -zdept(ji+1,jj,jk) )  )
+         zu(ji,jj,jk) = MAX(  zu(ji,jj,jk) , MIN( -zdept(ji,jj,jk) , -zdept(ji+1,jj,jk) )  )
+         zv(ji,jj,jk) = MIN(  zv(ji,jj,jk) , MAX( -zdept(ji,jj,jk) , -zdept(ji,jj+1,jk) )  )
+         zv(ji,jj,jk) = MAX(  zv(ji,jj,jk) , MIN( -zdept(ji,jj,jk) , -zdept(ji,jj+1,jk) )  )
       END_3D
 
 
       DO_3D( 0, 0, 0, 0, 1, jpkm1 )
-      zpwes = 0._wp; zpwed = 0._wp
-      zpnss = 0._wp; zpnsd = 0._wp
-      zuijk = zu(ji,jj,jk)
-      zvijk = zv(ji,jj,jk)
-
-      !!!!!     for u equation
-      IF( jk <= mbku(ji,jj) ) THEN
-         IF( -zdept(ji+1,jj,jk) >= -zdept(ji,jj,jk) ) THEN
-           jis = ji + 1; jid = ji
-         ELSE
-           jis = ji;     jid = ji +1
+         zpwes = 0._wp; zpwed = 0._wp
+         zpnss = 0._wp; zpnsd = 0._wp
+         zuijk = zu(ji,jj,jk)
+         zvijk = zv(ji,jj,jk)
+
+         !!!!!     for u equation
+         IF( jk <= mbku(ji,jj) ) THEN
+            IF( -zdept(ji+1,jj,jk) >= -zdept(ji,jj,jk) ) THEN
+              jis = ji + 1; jid = ji
+            ELSE
+              jis = ji;     jid = ji +1
+            ENDIF
+
+            ! integrate the pressure on the shallow side
+            jk1 = jk
+            DO WHILE ( -zdept(jis,jj,jk1) > zuijk )
+               IF( jk1 == mbku(ji,jj) ) THEN
+                  zuijk = -zdept(jis,jj,jk1)
+                  EXIT
+               ENDIF
+               zdeps = MIN(zdept(jis,jj,jk1+1), -zuijk)
+               zpwes = zpwes +                                      &
+                  integ_spline(zdept(jis,jj,jk1), zdeps,            &
+                                 asp(jis,jj,jk1), bsp(jis,jj,jk1),  &
+                                 csp(jis,jj,jk1), dsp(jis,jj,jk1))
+               jk1 = jk1 + 1
+            END DO
+
+            ! integrate the pressure on the deep side
+            jk1 = jk
+            DO WHILE ( -zdept(jid,jj,jk1) < zuijk )
+               IF( jk1 == 1 ) THEN
+                  zdeps = zdept(jid,jj,1) + MIN(zuijk, ssh(jid,jj,Kmm)*znad)
+                  zrhdt1 = zrhh(jid,jj,1) - interp3(zdept(jid,jj,1), asp(jid,jj,1), &
+                                                    bsp(jid,jj,1)  , csp(jid,jj,1), &
+                                                    dsp(jid,jj,1)) * zdeps
+                  zpwed  = zpwed + 0.5_wp * (zrhh(jid,jj,1) + zrhdt1) * zdeps
+                  EXIT
+               ENDIF
+               zdeps = MAX(zdept(jid,jj,jk1-1), -zuijk)
+               zpwed = zpwed +                                        &
+                  integ_spline(zdeps,             zdept(jid,jj,jk1),  &
+                               asp(jid,jj,jk1-1), bsp(jid,jj,jk1-1),  &
+                               csp(jid,jj,jk1-1), dsp(jid,jj,jk1-1) )
+               jk1 = jk1 - 1
+            END DO
+
+            ! update the momentum trends in u direction
+            zdpdx1 = zcoef0 * r1_e1u(ji,jj) * ( zhpi(ji+1,jj,jk) - zhpi(ji,jj,jk) )
+            IF( .NOT.ln_linssh ) THEN
+               zdpdx2 = zcoef0 * r1_e1u(ji,jj) * &
+                  &    ( REAL(jis-jid, wp) * (zpwes + zpwed) + (ssh(ji+1,jj,Kmm)-ssh(ji,jj,Kmm)) )
+            ELSE
+               zdpdx2 = zcoef0 * r1_e1u(ji,jj) * REAL(jis-jid, wp) * (zpwes + zpwed)
+            ENDIF
+            IF( ln_wd_il ) THEN
+               zdpdx1 = zdpdx1 * zcpx(ji,jj) * wdrampu(ji,jj)
+               zdpdx2 = zdpdx2 * zcpx(ji,jj) * wdrampu(ji,jj)
+            ENDIF
+            puu(ji,jj,jk,Krhs) = puu(ji,jj,jk,Krhs) + (zdpdx1 + zdpdx2 - zpgu(ji,jj)) * umask(ji,jj,jk)
          ENDIF
 
-         ! integrate the pressure on the shallow side
-         jk1 = jk
-         DO WHILE ( -zdept(jis,jj,jk1) > zuijk )
-           IF( jk1 == mbku(ji,jj) ) THEN
-             zuijk = -zdept(jis,jj,jk1)
-             EXIT
-           ENDIF
-           zdeps = MIN(zdept(jis,jj,jk1+1), -zuijk)
-           zpwes = zpwes +                                    &
-                integ_spline(zdept(jis,jj,jk1), zdeps,            &
-                       asp(jis,jj,jk1),    bsp(jis,jj,jk1), &
-                       csp(jis,jj,jk1),    dsp(jis,jj,jk1))
-           jk1 = jk1 + 1
-         END DO
-
-         ! integrate the pressure on the deep side
-         jk1 = jk
-         DO WHILE ( -zdept(jid,jj,jk1) < zuijk )
-           IF( jk1 == 1 ) THEN
-             zdeps = zdept(jid,jj,1) + MIN(zuijk, ssh(jid,jj,Kmm)*znad)
-             zrhdt1 = zrhh(jid,jj,1) - interp3(zdept(jid,jj,1), asp(jid,jj,1), &
-                                               bsp(jid,jj,1),   csp(jid,jj,1), &
-                                               dsp(jid,jj,1)) * zdeps
-             zpwed  = zpwed + 0.5_wp * (zrhh(jid,jj,1) + zrhdt1) * zdeps
-             EXIT
-           ENDIF
-           zdeps = MAX(zdept(jid,jj,jk1-1), -zuijk)
-           zpwed = zpwed +                                        &
-                  integ_spline(zdeps,              zdept(jid,jj,jk1), &
-                         asp(jid,jj,jk1-1), bsp(jid,jj,jk1-1),  &
-                         csp(jid,jj,jk1-1), dsp(jid,jj,jk1-1) )
-           jk1 = jk1 - 1
-         END DO
-
-         ! update the momentum trends in u direction
-
-         zdpdx1 = zcoef0 * r1_e1u(ji,jj) * ( zhpi(ji+1,jj,jk) - zhpi(ji,jj,jk) )
-         IF( .NOT.ln_linssh ) THEN
-           zdpdx2 = zcoef0 * r1_e1u(ji,jj) * &
-              &    ( REAL(jis-jid, wp) * (zpwes + zpwed) + (ssh(ji+1,jj,Kmm)-ssh(ji,jj,Kmm)) )
-          ELSE
-           zdpdx2 = zcoef0 * r1_e1u(ji,jj) * REAL(jis-jid, wp) * (zpwes + zpwed)
+         !!!!!     for v equation
+         IF( jk <= mbkv(ji,jj) ) THEN
+            IF( -zdept(ji,jj+1,jk) >= -zdept(ji,jj,jk) ) THEN
+               jjs = jj + 1; jjd = jj
+            ELSE
+               jjs = jj    ; jjd = jj + 1
+            ENDIF
+
+            ! integrate the pressure on the shallow side
+            jk1 = jk
+            DO WHILE ( -zdept(ji,jjs,jk1) > zvijk )
+               IF( jk1 == mbkv(ji,jj) ) THEN
+                  zvijk = -zdept(ji,jjs,jk1)
+                  EXIT
+               ENDIF
+               zdeps = MIN(zdept(ji,jjs,jk1+1), -zvijk)
+               zpnss = zpnss +                                       &
+                  integ_spline(zdept(ji,jjs,jk1), zdeps,             &
+                               asp(ji,jjs,jk1),   bsp(ji,jjs,jk1),   &
+                               csp(ji,jjs,jk1),   dsp(ji,jjs,jk1) )
+              jk1 = jk1 + 1
+            END DO
+
+            ! integrate the pressure on the deep side
+            jk1 = jk
+            DO WHILE ( -zdept(ji,jjd,jk1) < zvijk )
+               IF( jk1 == 1 ) THEN
+                  zdeps = zdept(ji,jjd,1) + MIN(zvijk, ssh(ji,jjd,Kmm)*znad)
+                  zrhdt1 = zrhh(ji,jjd,1) - interp3(zdept(ji,jjd,1), asp(ji,jjd,1), &
+                                                    bsp(ji,jjd,1)  , csp(ji,jjd,1), &
+                                                    dsp(ji,jjd,1) ) * zdeps
+                  zpnsd  = zpnsd + 0.5_wp * (zrhh(ji,jjd,1) + zrhdt1) * zdeps
+                  EXIT
+               ENDIF
+               zdeps = MAX(zdept(ji,jjd,jk1-1), -zvijk)
+               zpnsd = zpnsd +                                        &
+                  integ_spline(zdeps,             zdept(ji,jjd,jk1),  &
+                               asp(ji,jjd,jk1-1), bsp(ji,jjd,jk1-1),  &
+                               csp(ji,jjd,jk1-1), dsp(ji,jjd,jk1-1) )
+               jk1 = jk1 - 1
+            END DO
+
+            ! update the momentum trends in v direction
+            zdpdy1 = zcoef0 * r1_e2v(ji,jj) * ( zhpi(ji,jj+1,jk) - zhpi(ji,jj,jk) )
+            IF( .NOT.ln_linssh ) THEN
+               zdpdy2 = zcoef0 * r1_e2v(ji,jj) * &
+                       ( REAL(jjs-jjd, wp) * (zpnss + zpnsd) + (ssh(ji,jj+1,Kmm)-ssh(ji,jj,Kmm)) )
+            ELSE
+               zdpdy2 = zcoef0 * r1_e2v(ji,jj) * REAL(jjs-jjd, wp) * (zpnss + zpnsd )
+            ENDIF
+            IF( ln_wd_il ) THEN
+               zdpdy1 = zdpdy1 * zcpy(ji,jj) * wdrampv(ji,jj)
+               zdpdy2 = zdpdy2 * zcpy(ji,jj) * wdrampv(ji,jj)
+            ENDIF
+
+            pvv(ji,jj,jk,Krhs) = pvv(ji,jj,jk,Krhs) + (zdpdy1 + zdpdy2 - zpgv(ji,jj)) * vmask(ji,jj,jk)
          ENDIF
-         IF( ln_wd_il ) THEN
-            zdpdx1 = zdpdx1 * zcpx(ji,jj) * wdrampu(ji,jj)
-            zdpdx2 = zdpdx2 * zcpx(ji,jj) * wdrampu(ji,jj)
-         ENDIF
-         puu(ji,jj,jk,Krhs) = puu(ji,jj,jk,Krhs) + (zdpdx1 + zdpdx2 - zpgu(ji,jj)) * umask(ji,jj,jk) 
-      ENDIF
-
-      !!!!!     for v equation
-      IF( jk <= mbkv(ji,jj) ) THEN
-         IF( -zdept(ji,jj+1,jk) >= -zdept(ji,jj,jk) ) THEN
-           jjs = jj + 1; jjd = jj
-         ELSE
-           jjs = jj    ; jjd = jj + 1
-         ENDIF
-
-         ! integrate the pressure on the shallow side
-         jk1 = jk
-         DO WHILE ( -zdept(ji,jjs,jk1) > zvijk )
-           IF( jk1 == mbkv(ji,jj) ) THEN
-             zvijk = -zdept(ji,jjs,jk1)
-             EXIT
-           ENDIF
-           zdeps = MIN(zdept(ji,jjs,jk1+1), -zvijk)
-           zpnss = zpnss +                                      &
-                  integ_spline(zdept(ji,jjs,jk1), zdeps,            &
-                         asp(ji,jjs,jk1),    bsp(ji,jjs,jk1), &
-                         csp(ji,jjs,jk1),    dsp(ji,jjs,jk1) )
-           jk1 = jk1 + 1
-         END DO
-
-         ! integrate the pressure on the deep side
-         jk1 = jk
-         DO WHILE ( -zdept(ji,jjd,jk1) < zvijk )
-           IF( jk1 == 1 ) THEN
-             zdeps = zdept(ji,jjd,1) + MIN(zvijk, ssh(ji,jjd,Kmm)*znad)
-             zrhdt1 = zrhh(ji,jjd,1) - interp3(zdept(ji,jjd,1), asp(ji,jjd,1), &
-                                               bsp(ji,jjd,1),   csp(ji,jjd,1), &
-                                               dsp(ji,jjd,1) ) * zdeps
-             zpnsd  = zpnsd + 0.5_wp * (zrhh(ji,jjd,1) + zrhdt1) * zdeps
-             EXIT
-           ENDIF
-           zdeps = MAX(zdept(ji,jjd,jk1-1), -zvijk)
-           zpnsd = zpnsd +                                        &
-                  integ_spline(zdeps,              zdept(ji,jjd,jk1), &
-                         asp(ji,jjd,jk1-1), bsp(ji,jjd,jk1-1), &
-                         csp(ji,jjd,jk1-1), dsp(ji,jjd,jk1-1) )
-           jk1 = jk1 - 1
-         END DO
-
-
-         ! update the momentum trends in v direction
-
-         zdpdy1 = zcoef0 * r1_e2v(ji,jj) * ( zhpi(ji,jj+1,jk) - zhpi(ji,jj,jk) )
-         IF( .NOT.ln_linssh ) THEN
-            zdpdy2 = zcoef0 * r1_e2v(ji,jj) * &
-                    ( REAL(jjs-jjd, wp) * (zpnss + zpnsd) + (ssh(ji,jj+1,Kmm)-ssh(ji,jj,Kmm)) )
-         ELSE
-            zdpdy2 = zcoef0 * r1_e2v(ji,jj) * REAL(jjs-jjd, wp) * (zpnss + zpnsd )
-         ENDIF
-         IF( ln_wd_il ) THEN
-            zdpdy1 = zdpdy1 * zcpy(ji,jj) * wdrampv(ji,jj) 
-            zdpdy2 = zdpdy2 * zcpy(ji,jj) * wdrampv(ji,jj) 
-         ENDIF
-
-         pvv(ji,jj,jk,Krhs) = pvv(ji,jj,jk,Krhs) + (zdpdy1 + zdpdy2 - zpgv(ji,jj)) * vmask(ji,jj,jk)
-      ENDIF
          !
       END_3D
@@ -1279,91 +1268,79 @@
       !! Reference: CJC Kruger, Constrained Cubic Spline Interpoltation
       !!----------------------------------------------------------------------
-      REAL(wp), DIMENSION(:,:,:), INTENT(in   ) ::   fsp, xsp           ! value and coordinate
-      REAL(wp), DIMENSION(:,:,:), INTENT(  out) ::   asp, bsp, csp, dsp ! coefficients of the interpoated function
-      INTEGER                   , INTENT(in   ) ::   polynomial_type    ! 1: cubic spline   ;   2: Linear
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(in   ) ::   fsp, xsp           ! value and coordinate
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(  out) ::   asp, bsp, csp, dsp ! coefficients of the interpoated function
+      INTEGER                             , INTENT(in   ) ::   polynomial_type    ! 1: cubic spline   ;   2: Linear
       !
       INTEGER  ::   ji, jj, jk                 ! dummy loop indices
-      INTEGER  ::   jpi, jpj, jpkm1
       REAL(wp) ::   zdf1, zdf2, zddf1, zddf2, ztmp1, ztmp2, zdxtmp
       REAL(wp) ::   zdxtmp1, zdxtmp2, zalpha
-      REAL(wp) ::   zdf(size(fsp,3))
-      !!----------------------------------------------------------------------
-      !
-!!gm  WHAT !!!!!   THIS IS VERY DANGEROUS !!!!!  
-      jpi   = size(fsp,1)
-      jpj   = size(fsp,2)
-      jpkm1 = MAX( 1, size(fsp,3) - 1 )
+      REAL(wp) ::   zdf(jpk)
+      !!----------------------------------------------------------------------
       !
       IF (polynomial_type == 1) THEN     ! Constrained Cubic Spline
-         DO ji = 1, jpi
-            DO jj = 1, jpj
-           !!Fritsch&Butland's method, 1984 (preferred, but more computation)
-           !    DO jk = 2, jpkm1-1
-           !       zdxtmp1 = xsp(ji,jj,jk)   - xsp(ji,jj,jk-1)
-           !       zdxtmp2 = xsp(ji,jj,jk+1) - xsp(ji,jj,jk)
-           !       zdf1    = ( fsp(ji,jj,jk)   - fsp(ji,jj,jk-1) ) / zdxtmp1
-           !       zdf2    = ( fsp(ji,jj,jk+1) - fsp(ji,jj,jk)   ) / zdxtmp2
-           !
-           !       zalpha = ( zdxtmp1 + 2._wp * zdxtmp2 ) / ( zdxtmp1 + zdxtmp2 ) / 3._wp
-           !
-           !       IF(zdf1 * zdf2 <= 0._wp) THEN
-           !           zdf(jk) = 0._wp
-           !       ELSE
-           !         zdf(jk) = zdf1 * zdf2 / ( ( 1._wp - zalpha ) * zdf1 + zalpha * zdf2 )
-           !       ENDIF
-           !    END DO
-
-           !!Simply geometric average
-               DO jk = 2, jpkm1-1
-                  zdf1 = (fsp(ji,jj,jk  ) - fsp(ji,jj,jk-1)) / (xsp(ji,jj,jk  ) - xsp(ji,jj,jk-1))
-                  zdf2 = (fsp(ji,jj,jk+1) - fsp(ji,jj,jk  )) / (xsp(ji,jj,jk+1) - xsp(ji,jj,jk  ))
-
-                  IF(zdf1 * zdf2 <= 0._wp) THEN
-                     zdf(jk) = 0._wp
-                  ELSE
-                     zdf(jk) = 2._wp * zdf1 * zdf2 / (zdf1 + zdf2)
-                  ENDIF
-               END DO
-
-               zdf(1)     = 1.5_wp * ( fsp(ji,jj,2) - fsp(ji,jj,1) ) / &
-                          &          ( xsp(ji,jj,2) - xsp(ji,jj,1) )           -  0.5_wp * zdf(2)
-               zdf(jpkm1) = 1.5_wp * ( fsp(ji,jj,jpkm1) - fsp(ji,jj,jpkm1-1) ) / &
-                          &          ( xsp(ji,jj,jpkm1) - xsp(ji,jj,jpkm1-1) ) - 0.5_wp * zdf(jpkm1 - 1)
-
-               DO jk = 1, jpkm1 - 1
-                 zdxtmp = xsp(ji,jj,jk+1) - xsp(ji,jj,jk)
-                 ztmp1  = (zdf(jk+1) + 2._wp * zdf(jk)) / zdxtmp
-                 ztmp2  =  6._wp * (fsp(ji,jj,jk+1) - fsp(ji,jj,jk)) / zdxtmp / zdxtmp
-                 zddf1  = -2._wp * ztmp1 + ztmp2
-                 ztmp1  = (2._wp * zdf(jk+1) + zdf(jk)) / zdxtmp
-                 zddf2  =  2._wp * ztmp1 - ztmp2
-
-                 dsp(ji,jj,jk) = (zddf2 - zddf1) / 6._wp / zdxtmp
-                 csp(ji,jj,jk) = ( xsp(ji,jj,jk+1) * zddf1 - xsp(ji,jj,jk)*zddf2 ) / 2._wp / zdxtmp
-                 bsp(ji,jj,jk) = ( fsp(ji,jj,jk+1) - fsp(ji,jj,jk) ) / zdxtmp - &
-                               & csp(ji,jj,jk) * ( xsp(ji,jj,jk+1) + xsp(ji,jj,jk) ) - &
-                               & dsp(ji,jj,jk) * ((xsp(ji,jj,jk+1) + xsp(ji,jj,jk))**2 - &
-                               &                   xsp(ji,jj,jk+1) * xsp(ji,jj,jk))
-                 asp(ji,jj,jk) = fsp(ji,jj,jk) - xsp(ji,jj,jk) * (bsp(ji,jj,jk) + &
-                               &                (xsp(ji,jj,jk) * (csp(ji,jj,jk) + &
-                               &                 dsp(ji,jj,jk) * xsp(ji,jj,jk))))
-               END DO
+         DO_2D( 1, 1, 1, 1 )
+            !!Fritsch&Butland's method, 1984 (preferred, but more computation)
+            !    DO jk = 2, jpkm1-1
+            !       zdxtmp1 = xsp(ji,jj,jk)   - xsp(ji,jj,jk-1)
+            !       zdxtmp2 = xsp(ji,jj,jk+1) - xsp(ji,jj,jk)
+            !       zdf1    = ( fsp(ji,jj,jk)   - fsp(ji,jj,jk-1) ) / zdxtmp1
+            !       zdf2    = ( fsp(ji,jj,jk+1) - fsp(ji,jj,jk)   ) / zdxtmp2
+            !
+            !       zalpha = ( zdxtmp1 + 2._wp * zdxtmp2 ) / ( zdxtmp1 + zdxtmp2 ) / 3._wp
+            !
+            !       IF(zdf1 * zdf2 <= 0._wp) THEN
+            !           zdf(jk) = 0._wp
+            !       ELSE
+            !         zdf(jk) = zdf1 * zdf2 / ( ( 1._wp - zalpha ) * zdf1 + zalpha * zdf2 )
+            !       ENDIF
+            !    END DO
+
+            !!Simply geometric average
+            DO jk = 2, jpk-2
+               zdf1 = (fsp(ji,jj,jk  ) - fsp(ji,jj,jk-1)) / (xsp(ji,jj,jk  ) - xsp(ji,jj,jk-1))
+               zdf2 = (fsp(ji,jj,jk+1) - fsp(ji,jj,jk  )) / (xsp(ji,jj,jk+1) - xsp(ji,jj,jk  ))
+
+               IF(zdf1 * zdf2 <= 0._wp) THEN
+                  zdf(jk) = 0._wp
+               ELSE
+                  zdf(jk) = 2._wp * zdf1 * zdf2 / (zdf1 + zdf2)
+               ENDIF
             END DO
-         END DO
+
+            zdf(1)     = 1.5_wp * ( fsp(ji,jj,2) - fsp(ji,jj,1) ) / &
+                       &          ( xsp(ji,jj,2) - xsp(ji,jj,1) )           -  0.5_wp * zdf(2)
+            zdf(jpkm1) = 1.5_wp * ( fsp(ji,jj,jpkm1) - fsp(ji,jj,jpkm1-1) ) / &
+                       &          ( xsp(ji,jj,jpkm1) - xsp(ji,jj,jpkm1-1) ) - 0.5_wp * zdf(jpk - 2)
+
+            DO jk = 1, jpk-2
+               zdxtmp = xsp(ji,jj,jk+1) - xsp(ji,jj,jk)
+               ztmp1  = (zdf(jk+1) + 2._wp * zdf(jk)) / zdxtmp
+               ztmp2  =  6._wp * (fsp(ji,jj,jk+1) - fsp(ji,jj,jk)) / zdxtmp / zdxtmp
+               zddf1  = -2._wp * ztmp1 + ztmp2
+               ztmp1  = (2._wp * zdf(jk+1) + zdf(jk)) / zdxtmp
+               zddf2  =  2._wp * ztmp1 - ztmp2
+
+               dsp(ji,jj,jk) = (zddf2 - zddf1) / 6._wp / zdxtmp
+               csp(ji,jj,jk) = ( xsp(ji,jj,jk+1) * zddf1 - xsp(ji,jj,jk)*zddf2 ) / 2._wp / zdxtmp
+               bsp(ji,jj,jk) = ( fsp(ji,jj,jk+1) - fsp(ji,jj,jk) ) / zdxtmp - &
+                             & csp(ji,jj,jk) * ( xsp(ji,jj,jk+1) + xsp(ji,jj,jk) ) - &
+                             & dsp(ji,jj,jk) * ((xsp(ji,jj,jk+1) + xsp(ji,jj,jk))**2 - &
+                             &                   xsp(ji,jj,jk+1) * xsp(ji,jj,jk))
+               asp(ji,jj,jk) = fsp(ji,jj,jk) - xsp(ji,jj,jk) * (bsp(ji,jj,jk) + &
+                             &                (xsp(ji,jj,jk) * (csp(ji,jj,jk) + &
+                             &                 dsp(ji,jj,jk) * xsp(ji,jj,jk))))
+            END DO
+         END_2D
 
       ELSEIF ( polynomial_type == 2 ) THEN     ! Linear
-         DO ji = 1, jpi
-            DO jj = 1, jpj
-               DO jk = 1, jpkm1-1
-                  zdxtmp =xsp(ji,jj,jk+1) - xsp(ji,jj,jk)
-                  ztmp1 = fsp(ji,jj,jk+1) - fsp(ji,jj,jk)
-
-                  dsp(ji,jj,jk) = 0._wp
-                  csp(ji,jj,jk) = 0._wp
-                  bsp(ji,jj,jk) = ztmp1 / zdxtmp
-                  asp(ji,jj,jk) = fsp(ji,jj,jk) - bsp(ji,jj,jk) * xsp(ji,jj,jk)
-               END DO
-            END DO
-         END DO
+         DO_3D( 1, 1, 1, 1, 1, jpk-2 )
+            zdxtmp =xsp(ji,jj,jk+1) - xsp(ji,jj,jk)
+            ztmp1 = fsp(ji,jj,jk+1) - fsp(ji,jj,jk)
+
+            dsp(ji,jj,jk) = 0._wp
+            csp(ji,jj,jk) = 0._wp
+            bsp(ji,jj,jk) = ztmp1 / zdxtmp
+            asp(ji,jj,jk) = fsp(ji,jj,jk) - bsp(ji,jj,jk) * xsp(ji,jj,jk)
+         END_3D
          !
       ELSE
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynkeg.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynkeg.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynkeg.F90	(revision 14852)
@@ -78,5 +78,5 @@
       INTEGER  ::   ji, jj, jk             ! dummy loop indices
       REAL(wp) ::   zu, zv                   ! local scalars
-      REAL(wp), DIMENSION(jpi,jpj,jpk)        ::   zhke
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk)    ::   zhke
       REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) ::   ztrdu, ztrdv 
       !!----------------------------------------------------------------------
@@ -84,8 +84,10 @@
       IF( ln_timing )   CALL timing_start('dyn_keg')
       !
-      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,*) '~~~~~~~'
+      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
 
@@ -109,17 +111,21 @@
          END_3D
       CASE ( nkeg_HW )                          !--  Hollingsworth scheme  --!
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+         DO_3D( 0, nn_hls-1, 0, nn_hls-1, 1, jpkm1 )
+            ! round brackets added to fix the order of floating point operations
+            ! needed to ensure halo 1 - halo 2 compatibility
             zu = 8._wp * ( puu(ji-1,jj  ,jk,Kmm) * puu(ji-1,jj  ,jk,Kmm)    &
                &         + puu(ji  ,jj  ,jk,Kmm) * puu(ji  ,jj  ,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-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) )
+               &   +     ( ( 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 = 8._wp * ( pvv(ji  ,jj-1,jk,Kmm) * pvv(ji  ,jj-1,jk,Kmm)    &
                &         + pvv(ji  ,jj  ,jk,Kmm) * pvv(ji  ,jj  ,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-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) )
+               &  +      ( ( 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,jk) = r1_48 * ( zv + zu )
          END_3D
-         CALL lbc_lnk( 'dynkeg', zhke, 'T', 1.0_wp )
+         IF (nn_hls==1) CALL lbc_lnk( 'dynkeg', zhke, 'T', 1.0_wp )
          !
       END SELECT 
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynldf_iso.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynldf_iso.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynldf_iso.F90	(revision 14852)
@@ -28,4 +28,7 @@
    USE lbclnk          ! ocean lateral boundary conditions (or mpp link)
    USE prtctl          ! Print control
+#if defined key_loop_fusion
+   USE dynldf_iso_lf, ONLY: dyn_ldf_iso_lf   ! lateral mixing - loop fusion version (dyn_ldf_iso routine )
+#endif
 
    IMPLICIT NONE
@@ -36,7 +39,4 @@
 
    REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   akzu, akzv   !: vertical component of rotated lateral viscosity
-   
-   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) :: zfuw, zdiu, zdju, zdj1u   ! 2D workspace (dyn_ldf_iso) 
-   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) :: zfvw, zdiv, zdjv, zdj1v   !  -      -
 
    !! * Substitutions
@@ -54,8 +54,10 @@
       !!                  ***  ROUTINE dyn_ldf_iso_alloc  ***
       !!----------------------------------------------------------------------
-      ALLOCATE( akzu(jpi,jpj,jpk) , zfuw(jpi,jpk) , zdiu(jpi,jpk) , zdju(jpi,jpk) , zdj1u(jpi,jpk) ,     & 
-         &      akzv(jpi,jpj,jpk) , zfvw(jpi,jpk) , zdiv(jpi,jpk) , zdjv(jpi,jpk) , zdj1v(jpi,jpk) , STAT=dyn_ldf_iso_alloc )
-         !
-      IF( dyn_ldf_iso_alloc /= 0 )   CALL ctl_warn('dyn_ldf_iso_alloc: array allocate failed.')
+      dyn_ldf_iso_alloc = 0
+      IF( .NOT. ALLOCATED( akzu ) ) THEN
+         ALLOCATE( akzu(jpi,jpj,jpk), akzv(jpi,jpj,jpk), STAT=dyn_ldf_iso_alloc )
+            !
+         IF( dyn_ldf_iso_alloc /= 0 )   CALL ctl_warn('dyn_ldf_iso_alloc: array allocate failed.')
+      ENDIF
    END FUNCTION dyn_ldf_iso_alloc
 
@@ -112,14 +114,22 @@
       REAL(wp) ::   zabe2, zmskf, zmkf, zvav, zvwslpi, zvwslpj   !   -      -
       REAL(wp) ::   zcof0, zcof1, zcof2, zcof3, zcof4, zaht_0    !   -      -
-      REAL(wp), DIMENSION(jpi,jpj) ::   ziut, zivf, zdku, zdk1u  ! 2D workspace
-      REAL(wp), DIMENSION(jpi,jpj) ::   zjuf, zjvt, zdkv, zdk1v  !  -      -
+      REAL(wp), DIMENSION(A2D(nn_hls))      ::   ziut, zivf, zdku, zdk1u  ! 2D workspace
+      REAL(wp), DIMENSION(A2D(nn_hls))      ::   zjuf, zjvt, zdkv, zdk1v  !  -      -
+      REAL(wp), DIMENSION(A1Di(nn_hls),jpk) ::   zfuw, zdiu, zdju, zdj1u  !  -      -
+      REAL(wp), DIMENSION(A1Di(nn_hls),jpk) ::   zfvw, zdiv, zdjv, zdj1v  !  -      -
       !!----------------------------------------------------------------------
       !
-      IF( kt == nit000 ) THEN
-         IF(lwp) WRITE(numout,*)
-         IF(lwp) WRITE(numout,*) 'dyn_ldf_iso : iso-neutral laplacian diffusive operator or '
-         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~   s-coordinate horizontal diffusive operator'
-         !                                      ! allocate dyn_ldf_bilap arrays
-         IF( dyn_ldf_iso_alloc() /= 0 )   CALL ctl_stop('STOP', 'dyn_ldf_iso: failed to allocate arrays')
+#if defined key_loop_fusion
+      CALL dyn_ldf_iso_lf( kt, Kbb, Kmm, puu, pvv, Krhs    )
+#else
+
+      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_ldf_iso : iso-neutral laplacian diffusive operator or '
+            IF(lwp) WRITE(numout,*) '~~~~~~~~~~~   s-coordinate horizontal diffusive operator'
+            !                                      ! allocate dyn_ldf_iso arrays
+            IF( dyn_ldf_iso_alloc() /= 0 )   CALL ctl_stop('STOP', 'dyn_ldf_iso: failed to allocate arrays')
+         ENDIF
       ENDIF
 
@@ -128,5 +138,5 @@
       IF( ln_dynldf_hor .AND. ln_traldf_iso ) THEN
          !
-         DO_3D( 0, 0, 0, 0, 1, jpk )      ! set the slopes of iso-level
+         DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpk )      ! set the slopes of iso-level
             uslp (ji,jj,jk) = - ( gdept(ji+1,jj,jk,Kbb) - gdept(ji ,jj ,jk,Kbb) ) * r1_e1u(ji,jj) * umask(ji,jj,jk)
             vslp (ji,jj,jk) = - ( gdept(ji,jj+1,jk,Kbb) - gdept(ji ,jj ,jk,Kbb) ) * r1_e2v(ji,jj) * vmask(ji,jj,jk)
@@ -135,7 +145,7 @@
          END_3D
          ! Lateral boundary conditions on the slopes
-         CALL lbc_lnk( 'dynldf_iso', uslp , 'U', -1.0_wp, vslp , 'V', -1.0_wp, wslpi, 'W', -1.0_wp, wslpj, 'W', -1.0_wp )
+         IF (nn_hls == 1) CALL lbc_lnk( 'dynldf_iso', uslp , 'U', -1.0_wp, vslp , 'V', -1.0_wp, wslpi, 'W', -1.0_wp, wslpj, 'W', -1.0_wp )
          !
-       ENDIF
+      ENDIF
          
       zaht_0 = 0.5_wp * rn_Ud * rn_Ld                  ! aht_0 from namtra_ldf = zaht_max
@@ -150,6 +160,8 @@
          !                             zdkv(jk=1)=zdkv(jk=2)
 
-         zdk1u(:,:) = ( puu(:,:,jk,Kbb) -puu(:,:,jk+1,Kbb) ) * umask(:,:,jk+1)
-         zdk1v(:,:) = ( pvv(:,:,jk,Kbb) -pvv(:,:,jk+1,Kbb) ) * vmask(:,:,jk+1)
+         DO_2D( 1, 1, 1, 1 )
+            zdk1u(ji,jj) = ( puu(ji,jj,jk,Kbb) -puu(ji,jj,jk+1,Kbb) ) * umask(ji,jj,jk+1)
+            zdk1v(ji,jj) = ( pvv(ji,jj,jk,Kbb) -pvv(ji,jj,jk+1,Kbb) ) * vmask(ji,jj,jk+1)
+         END_2D
 
          IF( jk == 1 ) THEN
@@ -157,6 +169,8 @@
             zdkv(:,:) = zdk1v(:,:)
          ELSE
-            zdku(:,:) = ( puu(:,:,jk-1,Kbb) - puu(:,:,jk,Kbb) ) * umask(:,:,jk)
-            zdkv(:,:) = ( pvv(:,:,jk-1,Kbb) - pvv(:,:,jk,Kbb) ) * vmask(:,:,jk)
+            DO_2D( 1, 1, 1, 1 )
+               zdku(ji,jj) = ( puu(ji,jj,jk-1,Kbb) - puu(ji,jj,jk,Kbb) ) * umask(ji,jj,jk)
+               zdkv(ji,jj) = ( pvv(ji,jj,jk-1,Kbb) - pvv(ji,jj,jk,Kbb) ) * vmask(ji,jj,jk)
+            END_2D
          ENDIF
 
@@ -286,5 +300,5 @@
 
       !                                                ! ===============
-      DO jj = 2, jpjm1                                 !  Vertical slab
+      DO jj = ntsj, ntej                               !  Vertical slab
          !                                             ! ===============
 
@@ -299,5 +313,5 @@
 
          DO jk = 1, jpk
-            DO ji = 2, jpi
+            DO ji = ntsi, ntei + nn_hls
                ! i-gradient of u at jj
                zdiu (ji,jk) = tmask(ji,jj  ,jk) * ( puu(ji,jj  ,jk,Kbb) - puu(ji-1,jj  ,jk,Kbb) )
@@ -311,5 +325,5 @@
          END DO
          DO jk = 1, jpk
-            DO ji = 1, jpim1
+            DO ji = ntsi - nn_hls, ntei
                ! i-gradient of v at jj
                zdiv (ji,jk) = fmask(ji,jj  ,jk) * ( pvv(ji+1,jj,jk,Kbb) - pvv(ji  ,jj  ,jk,Kbb) )
@@ -322,5 +336,5 @@
 
          ! Surface and bottom vertical fluxes set to zero
-         DO ji = 1, jpi
+         DO ji = ntsi - nn_hls, ntei + nn_hls
             zfuw(ji, 1 ) = 0.e0
             zfvw(ji, 1 ) = 0.e0
@@ -331,5 +345,5 @@
          ! interior (2=<jk=<jpk-1) on U field
          DO jk = 2, jpkm1
-            DO ji = 2, jpim1
+            DO ji = ntsi, ntei
                zcof0 = 0.5_wp * zaht_0 * umask(ji,jj,jk)
                !
@@ -357,5 +371,5 @@
          ! interior (2=<jk=<jpk-1) on V field
          DO jk = 2, jpkm1
-            DO ji = 2, jpim1
+            DO ji = ntsi, ntei
                zcof0 = 0.5_wp * zaht_0 * vmask(ji,jj,jk)
                !
@@ -385,5 +399,5 @@
          ! -------------------------------------------------------------------
          DO jk = 1, jpkm1
-            DO ji = 2, jpim1
+            DO ji = ntsi, ntei
                puu(ji,jj,jk,Krhs) = puu(ji,jj,jk,Krhs) + ( zfuw(ji,jk) - zfuw(ji,jk+1) ) * r1_e1e2u(ji,jj)   &
                   &               / e3u(ji,jj,jk,Kmm)
@@ -395,4 +409,5 @@
       END DO                                           !   End of slab
       !                                                ! ===============
+#endif
    END SUBROUTINE dyn_ldf_iso
 
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynldf_iso_lf.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynldf_iso_lf.F90	(revision 14852)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynldf_iso_lf.F90	(revision 14852)
@@ -0,0 +1,401 @@
+MODULE dynldf_iso_lf
+   !!======================================================================
+   !!                     ***  MODULE  dynldf_iso  ***
+   !! Ocean dynamics:   lateral viscosity trend (rotated laplacian operator)
+   !!======================================================================
+   !! History :  OPA  !  97-07  (G. Madec)  Original code
+   !!  NEMO      1.0  !  2002-08  (G. Madec)  F90: Free form and module
+   !!             -   !  2004-08  (C. Talandier) New trends organization
+   !!            2.0  !  2005-11  (G. Madec)  s-coordinate: horizontal diffusion
+   !!            3.7  !  2014-01  (F. Lemarie, G. Madec)  restructuration/simplification of ahm specification,
+   !!                 !                                   add velocity dependent coefficient and optional read in file
+   !!----------------------------------------------------------------------
+
+   !!----------------------------------------------------------------------
+   !!   dyn_ldf_iso  : update the momentum trend with the horizontal part
+   !!                  of the lateral diffusion using isopycnal or horizon-
+   !!                  tal s-coordinate laplacian operator.
+   !!----------------------------------------------------------------------
+   USE oce             ! ocean dynamics and tracers
+   USE dom_oce         ! ocean space and time domain
+   USE ldfdyn          ! lateral diffusion: eddy viscosity coef.
+   USE ldftra          ! lateral physics: eddy diffusivity
+   USE zdf_oce         ! ocean vertical physics
+   USE ldfslp          ! iso-neutral slopes 
+   !
+   USE in_out_manager  ! I/O manager
+   USE lib_mpp         ! MPP library
+   USE lbclnk          ! ocean lateral boundary conditions (or mpp link)
+   USE prtctl          ! Print control
+
+   IMPLICIT NONE
+   PRIVATE
+
+   PUBLIC   dyn_ldf_iso_lf           ! called by step.F90
+   PUBLIC   dyn_ldf_iso_alloc_lf     ! called by nemogcm.F90
+
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   akzu, akzv   !: vertical component of rotated lateral viscosity
+
+   !! * Substitutions
+#  include "do_loop_substitute.h90"
+#  include "domzgr_substitute.h90"
+   !!----------------------------------------------------------------------
+   !! NEMO/OCE 4.0 , NEMO Consortium (2018)
+   !! $Id: dynldf_iso.F90 14757 2021-04-27 15:33:44Z francesca $
+   !! Software governed by the CeCILL license (see ./LICENSE)
+   !!----------------------------------------------------------------------
+CONTAINS
+
+   INTEGER FUNCTION dyn_ldf_iso_alloc_lf()
+      !!----------------------------------------------------------------------
+      !!                  ***  ROUTINE dyn_ldf_iso_alloc  ***
+      !!----------------------------------------------------------------------
+      dyn_ldf_iso_alloc_lf = 0
+      IF( .NOT. ALLOCATED( akzu ) ) THEN
+         ALLOCATE( akzu(jpi,jpj,jpk), akzv(jpi,jpj,jpk), STAT=dyn_ldf_iso_alloc_lf )
+            !
+         IF( dyn_ldf_iso_alloc_lf /= 0 )   CALL ctl_warn('dyn_ldf_iso_alloc: array allocate failed.')
+      ENDIF
+   END FUNCTION dyn_ldf_iso_alloc_lf
+
+
+   SUBROUTINE dyn_ldf_iso_lf( kt, Kbb, Kmm, puu, pvv, Krhs )
+      !!----------------------------------------------------------------------
+      !!                     ***  ROUTINE dyn_ldf_iso  ***
+      !!                       
+      !! ** Purpose :   Compute the before trend of the rotated laplacian
+      !!      operator of lateral momentum diffusion except the diagonal
+      !!      vertical term that will be computed in dynzdf module. Add it
+      !!      to the general trend of momentum equation.
+      !!
+      !! ** Method :
+      !!        The momentum lateral diffusive trend is provided by a 2nd
+      !!      order operator rotated along neutral or geopotential surfaces
+      !!      (in s-coordinates).
+      !!      It is computed using before fields (forward in time) and isopyc-
+      !!      nal or geopotential slopes computed in routine ldfslp.
+      !!      Here, u and v components are considered as 2 independent scalar
+      !!      fields. Therefore, the property of splitting divergent and rota-
+      !!      tional part of the flow of the standard, z-coordinate laplacian
+      !!      momentum diffusion is lost.
+      !!      horizontal fluxes associated with the rotated lateral mixing:
+      !!      u-component:
+      !!         ziut = ( ahmt + rn_ahm_b ) e2t * e3t / e1t  di[ uu ]
+      !!               -  ahmt              e2t * mi-1(uslp) dk[ mi(mk(uu)) ]
+      !!         zjuf = ( ahmf + rn_ahm_b ) e1f * e3f / e2f  dj[ uu ]
+      !!               -  ahmf              e1f * mi(vslp)   dk[ mj(mk(uu)) ]
+      !!      v-component:
+      !!         zivf = ( ahmf + rn_ahm_b ) e2t * e3t / e1t  di[ vv ]
+      !!               -  ahmf              e2t * mj(uslp)   dk[ mi(mk(vv)) ]
+      !!         zjvt = ( ahmt + rn_ahm_b ) e1f * e3f / e2f  dj[ vv ]
+      !!               -  ahmt              e1f * mj-1(vslp) dk[ mj(mk(vv)) ]
+      !!      take the horizontal divergence of the fluxes:
+      !!         diffu = 1/(e1u*e2u*e3u) {  di  [ ziut ] + dj-1[ zjuf ]  }
+      !!         diffv = 1/(e1v*e2v*e3v) {  di-1[ zivf ] + dj  [ zjvt ]  }
+      !!      Add this trend to the general trend (uu(rhs),vv(rhs)):
+      !!         uu(rhs) = uu(rhs) + diffu
+      !!      CAUTION: here the isopycnal part is with a coeff. of aht. This
+      !!      should be modified for applications others than orca_r2 (!!bug)
+      !!
+      !! ** Action :
+      !!       -(puu(:,:,:,Krhs),pvv(:,:,:,Krhs)) updated with the before geopotential harmonic mixing trend
+      !!       -(akzu,akzv) to accompt for the diagonal vertical component
+      !!                    of the rotated operator in dynzdf module
+      !!----------------------------------------------------------------------
+      INTEGER                             , INTENT( in )  ::  kt               ! ocean time-step index
+      INTEGER                             , INTENT( in )  ::  Kbb, 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) ::   zabe1, zmskt, zmkt, zuav, zuwslpi, zuwslpj   ! local scalars
+      REAL(wp) ::   zabe2, zmskf, zmkf, zvav, zvwslpi, zvwslpj   !   -      -
+      REAL(wp) ::   zcof0, zcof1, zcof2, zcof3, zcof4, zaht_0    !   -      -
+      REAL(wp) ::   zdiu, zdiu_km1, zdiu_ip1, zdiu_ip1_km1       !   -      -
+      REAL(wp) ::   zdju, zdju_km1, zdj1u, zdj1u_km1
+      REAL(wp) ::   zdjv, zdjv_km1, zdj1v, zdj1v_km1
+      REAL(wp) ::   zdiv_im1_km1, zdiv, zdiv_im1, zdiv_km1       !   -      -
+      REAL(wp), DIMENSION(A2D(nn_hls)) ::   ziut, zivf, zdku, zdk1u  ! 2D workspace
+      REAL(wp), DIMENSION(A2D(nn_hls)) ::   zjuf, zjvt, zdkv, zdk1v  !  -      -
+      REAL(wp), DIMENSION(A1Di(nn_hls),jpk) ::   zfuw, zfvw
+      !!----------------------------------------------------------------------
+      !
+      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_ldf_iso_lf : iso-neutral laplacian diffusive operator or '
+            IF(lwp) WRITE(numout,*) '~~~~~~~~~~~     s-coordinate horizontal diffusive operator'
+            !                                      ! allocate dyn_ldf_bilap arrays
+            IF( dyn_ldf_iso_alloc_lf() /= 0 )   CALL ctl_stop('STOP', 'dyn_ldf_iso: failed to allocate arrays')
+         ENDIF
+      ENDIF
+
+!!gm bug is dyn_ldf_iso called before tra_ldf_iso ....   <<<<<===== TO BE CHECKED
+      ! s-coordinate: Iso-level diffusion on momentum but not on tracer
+      IF( ln_dynldf_hor .AND. ln_traldf_iso ) THEN
+         !
+         DO_3D_OVR( 1, 1, 1, 1, 1, jpk )      ! set the slopes of iso-level
+            uslp (ji,jj,jk) = - ( gdept(ji+1,jj,jk,Kbb) - gdept(ji ,jj ,jk,Kbb) ) * r1_e1u(ji,jj) * umask(ji,jj,jk)
+            vslp (ji,jj,jk) = - ( gdept(ji,jj+1,jk,Kbb) - gdept(ji ,jj ,jk,Kbb) ) * r1_e2v(ji,jj) * vmask(ji,jj,jk)
+            wslpi(ji,jj,jk) = - ( gdepw(ji+1,jj,jk,Kbb) - gdepw(ji-1,jj,jk,Kbb) ) * r1_e1t(ji,jj) * tmask(ji,jj,jk) * 0.5
+            wslpj(ji,jj,jk) = - ( gdepw(ji,jj+1,jk,Kbb) - gdepw(ji,jj-1,jk,Kbb) ) * r1_e2t(ji,jj) * tmask(ji,jj,jk) * 0.5
+         END_3D
+         !
+       ENDIF
+         
+      zaht_0 = 0.5_wp * rn_Ud * rn_Ld                  ! aht_0 from namtra_ldf = zaht_max
+      
+      !                                                ! ===============
+      DO jk = 1, jpkm1                                 ! Horizontal slab
+         !                                             ! ===============
+
+         ! Vertical u- and v-shears at level jk and jk+1
+         ! ---------------------------------------------
+         ! surface boundary condition: zdku(jk=1)=zdku(jk=2)
+         !                             zdkv(jk=1)=zdkv(jk=2)
+
+         DO_2D( 1, 1, 1, 1 )
+            zdk1u(ji,jj) = ( puu(ji,jj,jk,Kbb) -puu(ji,jj,jk+1,Kbb) ) * umask(ji,jj,jk+1)
+            zdk1v(ji,jj) = ( pvv(ji,jj,jk,Kbb) -pvv(ji,jj,jk+1,Kbb) ) * vmask(ji,jj,jk+1)
+         END_2D
+
+         IF( jk == 1 ) THEN
+            zdku(:,:) = zdk1u(:,:)
+            zdkv(:,:) = zdk1v(:,:)
+         ELSE
+            DO_2D( 1, 1, 1, 1 )
+               zdku(ji,jj) = ( puu(ji,jj,jk-1,Kbb) - puu(ji,jj,jk,Kbb) ) * umask(ji,jj,jk)
+               zdkv(ji,jj) = ( pvv(ji,jj,jk-1,Kbb) - pvv(ji,jj,jk,Kbb) ) * vmask(ji,jj,jk)
+            END_2D
+         ENDIF
+
+         !                               -----f-----
+         ! Horizontal fluxes on U             |  
+         ! --------------------===        t   u   t
+         !                                    |  
+         ! i-flux at t-point             -----f-----
+
+         IF( ln_zps ) THEN      ! z-coordinate - partial steps : min(e3u)
+            DO_2D( 0, 1, 0, 0 )
+               zabe1 = ( ahmt(ji,jj,jk)+rn_ahm_b ) * e2t(ji,jj)   &
+                  &    * MIN( e3u(ji  ,jj,jk,Kmm),                &
+                  &           e3u(ji-1,jj,jk,Kmm) ) * r1_e1t(ji,jj)
+
+               zmskt = 1._wp / MAX(   umask(ji-1,jj,jk  )+umask(ji,jj,jk+1)     &
+                  &                 + umask(ji-1,jj,jk+1)+umask(ji,jj,jk  ) , 1._wp )
+
+               zcof1 = - zaht_0 * e2t(ji,jj) * zmskt * 0.5  * ( uslp(ji-1,jj,jk) + uslp(ji,jj,jk) )
+
+               ziut(ji,jj) = (  zabe1 * ( puu(ji,jj,jk,Kbb) - puu(ji-1,jj,jk,Kbb) )    &
+                  &           + zcof1 * ( zdku (ji,jj) + zdk1u(ji-1,jj)      &
+                  &                      +zdk1u(ji,jj) + zdku (ji-1,jj) )  ) * tmask(ji,jj,jk)
+            END_2D
+         ELSE                   ! other coordinate system (zco or sco) : e3t
+            DO_2D( 0, 1, 0, 0 )
+               zabe1 = ( ahmt(ji,jj,jk)+rn_ahm_b )   &
+                  &     * e2t(ji,jj) * e3t(ji,jj,jk,Kmm) * r1_e1t(ji,jj)
+
+               zmskt = 1._wp / MAX(   umask(ji-1,jj,jk  ) + umask(ji,jj,jk+1)     &
+                  &                 + umask(ji-1,jj,jk+1) + umask(ji,jj,jk  ) , 1._wp )
+
+               zcof1 = - zaht_0 * e2t(ji,jj) * zmskt * 0.5  * ( uslp(ji-1,jj,jk) + uslp(ji,jj,jk) )
+
+               ziut(ji,jj) = (  zabe1 * ( puu(ji,jj,jk,Kbb) - puu(ji-1,jj,jk,Kbb) )   &
+                  &           + zcof1 * ( zdku (ji,jj) + zdk1u(ji-1,jj)     &
+                  &                      +zdk1u(ji,jj) + zdku (ji-1,jj) )  ) * tmask(ji,jj,jk)
+            END_2D
+         ENDIF
+
+         ! j-flux at f-point
+         DO_2D( 1, 0, 1, 0 )
+            zabe2 = ( ahmf(ji,jj,jk) + rn_ahm_b )   &
+               &     * e1f(ji,jj) * e3f(ji,jj,jk) * r1_e2f(ji,jj)
+
+            zmskf = 1._wp / MAX(   umask(ji,jj+1,jk  )+umask(ji,jj,jk+1)     &
+               &                 + umask(ji,jj+1,jk+1)+umask(ji,jj,jk  ) , 1._wp )
+
+            zcof2 = - zaht_0 * e1f(ji,jj) * zmskf * 0.5  * ( vslp(ji+1,jj,jk) + vslp(ji,jj,jk) )
+
+            zjuf(ji,jj) = (  zabe2 * ( puu(ji,jj+1,jk,Kbb) - puu(ji,jj,jk,Kbb) )   &
+               &           + zcof2 * ( zdku (ji,jj+1) + zdk1u(ji,jj)     &
+               &                      +zdk1u(ji,jj+1) + zdku (ji,jj) )  ) * fmask(ji,jj,jk)
+
+            !                                |   t   |
+            ! Horizontal fluxes on V         |       |
+            ! --------------------===        f---v---f
+            !                                |       |
+            ! i-flux at f-point              |   t   |
+
+            zabe1 = ( ahmf(ji,jj,jk) + rn_ahm_b )   &
+               &     * e2f(ji,jj) * e3f(ji,jj,jk) * r1_e1f(ji,jj)
+
+            zmskf = 1._wp / MAX(  vmask(ji+1,jj,jk  )+vmask(ji,jj,jk+1)     &
+               &                + vmask(ji+1,jj,jk+1)+vmask(ji,jj,jk  ) , 1._wp )
+
+            zcof1 = - zaht_0 * e2f(ji,jj) * zmskf * 0.5 * ( uslp(ji,jj+1,jk) + uslp(ji,jj,jk) )
+
+            zivf(ji,jj) = (  zabe1 * ( pvv(ji+1,jj,jk,Kbb) - pvv(ji,jj,jk,Kbb) )    &
+               &           + zcof1 * (  zdkv (ji,jj) + zdk1v(ji+1,jj)      &
+               &                      + zdk1v(ji,jj) + zdkv (ji+1,jj) )  ) * fmask(ji,jj,jk)
+         END_2D
+
+         ! j-flux at t-point
+         IF( ln_zps ) THEN      ! z-coordinate - partial steps : min(e3u)
+            DO_2D( 1, 0, 0, 1 )
+               zabe2 = ( ahmt(ji,jj,jk)+rn_ahm_b ) * e1t(ji,jj)   &
+                  &     * MIN( e3v(ji,jj  ,jk,Kmm),                 &
+                  &            e3v(ji,jj-1,jk,Kmm) ) * r1_e2t(ji,jj)
+
+               zmskt = 1._wp / MAX(  vmask(ji,jj-1,jk  )+vmask(ji,jj,jk+1)     &
+                  &                + vmask(ji,jj-1,jk+1)+vmask(ji,jj,jk  ) , 1._wp )
+
+               zcof2 = - zaht_0 * e1t(ji,jj) * zmskt * 0.5 * ( vslp(ji,jj-1,jk) + vslp(ji,jj,jk) )
+
+               zjvt(ji,jj) = (  zabe2 * ( pvv(ji,jj,jk,Kbb) - pvv(ji,jj-1,jk,Kbb) )    &
+                  &           + zcof2 * ( zdkv (ji,jj-1) + zdk1v(ji,jj)      &
+                  &                      +zdk1v(ji,jj-1) + zdkv (ji,jj) )  ) * tmask(ji,jj,jk)
+            END_2D
+         ELSE                   ! other coordinate system (zco or sco) : e3t
+            DO_2D( 1, 0, 0, 1 )
+               zabe2 = ( ahmt(ji,jj,jk)+rn_ahm_b )   &
+                  &     * e1t(ji,jj) * e3t(ji,jj,jk,Kmm) * r1_e2t(ji,jj)
+
+               zmskt = 1./MAX(  vmask(ji,jj-1,jk  )+vmask(ji,jj,jk+1)   &
+                  &           + vmask(ji,jj-1,jk+1)+vmask(ji,jj,jk  ), 1. )
+
+               zcof2 = - zaht_0 * e1t(ji,jj) * zmskt * 0.5 * ( vslp(ji,jj-1,jk) + vslp(ji,jj,jk) )
+
+               zjvt(ji,jj) = (  zabe2 * ( pvv(ji,jj,jk,Kbb) - pvv(ji,jj-1,jk,Kbb) )   &
+                  &           + zcof2 * ( zdkv (ji,jj-1) + zdk1v(ji,jj)     &
+                  &                      +zdk1v(ji,jj-1) + zdkv (ji,jj) )  ) * tmask(ji,jj,jk)
+            END_2D
+         ENDIF
+
+
+         ! Second derivative (divergence) and add to the general trend
+         ! -----------------------------------------------------------
+         DO_2D( 0, 0, 0, 0 )      !!gm Question vectop possible??? !!bug
+            puu(ji,jj,jk,Krhs) = puu(ji,jj,jk,Krhs) + (  ziut(ji+1,jj) - ziut(ji,jj  )    &
+               &                           + zjuf(ji  ,jj) - zjuf(ji,jj-1)  ) * r1_e1e2u(ji,jj)   &
+               &                           / e3u(ji,jj,jk,Kmm)
+            pvv(ji,jj,jk,Krhs) = pvv(ji,jj,jk,Krhs) + (  zivf(ji,jj  ) - zivf(ji-1,jj)    &
+               &                           + zjvt(ji,jj+1) - zjvt(ji,jj  )  ) * r1_e1e2v(ji,jj)   &
+               &                           / e3v(ji,jj,jk,Kmm)
+         END_2D
+         !                                             ! ===============
+      END DO                                           !   End of slab
+      !                                                ! ===============
+
+      ! print sum trends (used for debugging)
+      IF(sn_cfctl%l_prtctl)   CALL prt_ctl( tab3d_1=puu(:,:,:,Krhs), clinfo1=' ldfh - Ua: ', mask1=umask, &
+         &                                  tab3d_2=pvv(:,:,:,Krhs), clinfo2=       ' Va: ', mask2=vmask, clinfo3='dyn' )
+
+
+      !                                                ! ===============
+      DO jj = ntsj, ntej                               !  Vertical slab
+         !                                             ! ===============
+
+ 
+         ! I. vertical trends associated with the lateral mixing
+         ! =====================================================
+         !  (excluding the vertical flux proportional to dk[t]
+
+         ! I.2 Vertical fluxes
+         ! -------------------
+
+         ! Surface and bottom vertical fluxes set to zero
+         DO ji = ntsi - nn_hls, ntei + nn_hls
+            zfuw(ji, 1 ) = 0.e0
+            zfvw(ji, 1 ) = 0.e0
+            zfuw(ji,jpk) = 0.e0
+            zfvw(ji,jpk) = 0.e0
+         END DO
+
+         ! interior (2=<jk=<jpk-1) on U and V fields
+         DO jk = 2, jpkm1
+            DO ji = ntsi, ntei
+               ! I.1 horizontal momentum gradient
+               ! --------------------------------
+               ! i-gradient of u at jj
+               zdiu = tmask(ji,jj,jk) * ( puu(ji,jj  ,jk,Kbb) - puu(ji-1,jj ,jk,Kbb) )
+               zdiu_km1 = tmask(ji,jj,jk-1) * ( puu(ji,jj,jk-1,Kbb) - puu(ji-1,jj,jk-1,Kbb) )
+               zdiu_ip1 = tmask(ji+1,jj,jk) * ( puu(ji+1,jj,jk,Kbb) - puu(ji,jj,jk,Kbb) )
+               zdiu_ip1_km1 = tmask(ji+1,jj,jk-1) * ( puu(ji+1,jj,jk-1,Kbb) - puu(ji,jj,jk-1,Kbb) )
+               ! j-gradient of u and v at jj
+               zdju = fmask(ji,jj,jk) * ( puu(ji,jj+1,jk,Kbb) - puu(ji,jj,jk,Kbb) )
+               zdju_km1 = fmask(ji,jj,jk-1) * ( puu(ji,jj+1,jk-1,Kbb) - puu(ji,jj,jk-1,Kbb) )
+               ! j-gradient of u and v at jj+1
+               zdj1u = fmask(ji,jj-1,jk) * ( puu(ji,jj,jk,Kbb) - puu(ji,jj-1,jk,Kbb) )
+               zdj1u_km1 = fmask(ji,jj-1,jk-1) * ( puu(ji,jj,jk-1,Kbb) - puu(ji,jj-1,jk-1,Kbb) )
+               !
+               zcof0 = 0.5_wp * zaht_0 * umask(ji,jj,jk)
+               !
+               zuwslpi = zcof0 * ( wslpi(ji+1,jj,jk) + wslpi(ji,jj,jk) )
+               zuwslpj = zcof0 * ( wslpj(ji+1,jj,jk) + wslpj(ji,jj,jk) )
+               !
+               zmkt = 1./MAX(  tmask(ji,jj,jk-1)+tmask(ji+1,jj,jk-1)      &
+                             + tmask(ji,jj,jk  )+tmask(ji+1,jj,jk  ) , 1. )
+               zmkf = 1./MAX(  fmask(ji,jj-1,jk-1) + fmask(ji,jj,jk-1)      &
+                             + fmask(ji,jj-1,jk  ) + fmask(ji,jj,jk  ) , 1. )
+
+               zcof3 = - e2u(ji,jj) * zmkt * zuwslpi
+               zcof4 = - e1u(ji,jj) * zmkf * zuwslpj
+               ! vertical flux on u field
+               zfuw(ji,jk) = zcof3 * (  zdiu_km1 + zdiu_ip1_km1 + zdiu + zdiu_ip1 )   &
+                  &        + zcof4 * (  zdj1u_km1 + zdju_km1 + zdj1u + zdju )
+               ! vertical mixing coefficient (akzu)
+               ! Note: zcof0 include zaht_0, so divided by zaht_0 to obtain slp^2 * zaht_0
+               akzu(ji,jj,jk) = ( zuwslpi * zuwslpi + zuwslpj * zuwslpj ) / zaht_0
+
+               ! I.1 horizontal momentum gradient
+               ! --------------------------------
+               ! j-gradient of u and v at jj
+               zdjv     = tmask(ji,jj  ,jk) * ( pvv(ji,jj  ,jk,Kbb) - pvv(ji ,jj-1,jk,Kbb) )
+               zdjv_km1 = tmask(ji,jj,jk-1) * ( pvv(ji,jj,jk-1,Kbb) - pvv(ji,jj-1,jk-1,Kbb) )
+               ! i-gradient of v at jj
+               zdiv = fmask(ji,jj,jk) * ( pvv(ji+1,jj,jk,Kbb) - pvv(ji,jj,jk,Kbb) )
+               zdiv_im1 = fmask(ji-1,jj,jk) * ( pvv(ji,jj,jk,Kbb) - pvv(ji-1,jj,jk,Kbb) )
+               zdiv_km1 = fmask(ji,jj,jk-1) * ( pvv(ji+1,jj,jk-1,Kbb) - pvv(ji,jj,jk-1,Kbb) )
+               zdiv_im1_km1 = fmask(ji-1,jj,jk-1) * ( pvv(ji,jj,jk-1,Kbb) - pvv(ji-1,jj,jk-1,Kbb) )
+               ! j-gradient of u and v at jj+1
+               zdj1v = tmask(ji,jj+1,jk) * ( pvv(ji,jj+1,jk,Kbb) - pvv(ji,jj,jk,Kbb) )
+               zdj1v_km1 = tmask(ji,jj+1,jk-1) * ( pvv(ji,jj+1,jk-1,Kbb) - pvv(ji,jj,jk-1,Kbb) )
+               !
+               zcof0 = 0.5_wp * zaht_0 * vmask(ji,jj,jk)
+               !
+               zvwslpi = zcof0 * ( wslpi(ji,jj+1,jk) + wslpi(ji,jj,jk) )
+               zvwslpj = zcof0 * ( wslpj(ji,jj+1,jk) + wslpj(ji,jj,jk) )
+               !
+               zmkf = 1./MAX(  fmask(ji-1,jj,jk-1)+fmask(ji,jj,jk-1)      &
+                  &          + fmask(ji-1,jj,jk  )+fmask(ji,jj,jk  ) , 1. )
+               zmkt = 1./MAX(  tmask(ji,jj,jk-1)+tmask(ji,jj+1,jk-1)      &
+                  &          + tmask(ji,jj,jk  )+tmask(ji,jj+1,jk  ) , 1. )
+
+               zcof3 = - e2v(ji,jj) * zmkf * zvwslpi
+               zcof4 = - e1v(ji,jj) * zmkt * zvwslpj
+               ! vertical flux on v field
+               zfvw(ji,jk) = zcof3 * (  zdiv_km1 + zdiv_im1_km1 + zdiv + zdiv_im1 )   &
+                  &        + zcof4 * (  zdjv_km1 + zdj1v_km1 + zdjv + zdj1v )
+               ! vertical mixing coefficient (akzv)
+               ! Note: zcof0 include zaht_0, so divided by zaht_0 to obtain slp^2 * zaht_0
+               akzv(ji,jj,jk) = ( zvwslpi * zvwslpi + zvwslpj * zvwslpj ) / zaht_0
+            END DO
+         END DO
+
+
+         ! I.3 Divergence of vertical fluxes added to the general tracer trend
+         ! -------------------------------------------------------------------
+         DO jk = 1, jpkm1
+            DO ji = ntsi, ntei
+               puu(ji,jj,jk,Krhs) = puu(ji,jj,jk,Krhs) + ( zfuw(ji,jk) - zfuw(ji,jk+1) ) * r1_e1e2u(ji,jj)   &
+                  &               / e3u(ji,jj,jk,Kmm)
+               pvv(ji,jj,jk,Krhs) = pvv(ji,jj,jk,Krhs) + ( zfvw(ji,jk) - zfvw(ji,jk+1) ) * r1_e1e2v(ji,jj)   &
+                  &               / e3v(ji,jj,jk,Kmm)
+            END DO
+         END DO
+         !                                             ! ===============
+      END DO                                           !   End of slab
+      !                                                ! ===============
+   END SUBROUTINE dyn_ldf_iso_lf
+
+   !!======================================================================
+END MODULE dynldf_iso_lf
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynldf_lap_blp.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynldf_lap_blp.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynldf_lap_blp.F90	(revision 14852)
@@ -14,4 +14,5 @@
    USE oce            ! ocean dynamics and tracers
    USE dom_oce        ! ocean space and time domain
+   USE domutl, ONLY : is_tile
    USE ldfdyn         ! lateral diffusion: eddy viscosity coef.
    USE ldfslp         ! iso-neutral slopes 
@@ -21,5 +22,8 @@
    USE lbclnk         ! ocean lateral boundary conditions (or mpp link)
    USE lib_mpp
-   
+#if defined key_loop_fusion
+   USE dynldf_lap_blp_lf
+#endif
+
    IMPLICIT NONE
    PRIVATE
@@ -39,4 +43,21 @@
 
    SUBROUTINE dyn_ldf_lap( kt, Kbb, Kmm, pu, pv, pu_rhs, pv_rhs, kpass )
+      !!
+      INTEGER                   , INTENT(in   ) ::   kt               ! ocean time-step index
+      INTEGER                   , INTENT(in   ) ::   Kbb, Kmm         ! ocean time level indices
+      INTEGER                   , INTENT(in   ) ::   kpass            ! =1/2 first or second passage
+      REAL(wp), DIMENSION(:,:,:), INTENT(in   ) ::   pu, pv           ! before velocity  [m/s]
+      REAL(wp), DIMENSION(:,:,:), INTENT(inout) ::   pu_rhs, pv_rhs   ! velocity trend   [m/s2]
+      !!
+#if defined key_loop_fusion
+      CALL dyn_ldf_lap_lf( kt, Kbb, Kmm, pu, pv, pu_rhs, pv_rhs, kpass )
+#else
+      CALL dyn_ldf_lap_t( kt, Kbb, Kmm, pu, pv, is_tile(pu), pu_rhs, pv_rhs, is_tile(pu_rhs), kpass )
+#endif
+
+   END SUBROUTINE dyn_ldf_lap
+
+
+   SUBROUTINE dyn_ldf_lap_t( kt, Kbb, Kmm, pu, pv, ktuv, pu_rhs, pv_rhs, ktuv_rhs, kpass )
       !!----------------------------------------------------------------------
       !!                     ***  ROUTINE dyn_ldf_lap  ***
@@ -52,11 +73,13 @@
       !! Reference : S.Griffies, R.Hallberg 2000 Mon.Wea.Rev., DOI:/ 
       !!----------------------------------------------------------------------
-      INTEGER                         , INTENT(in   ) ::   kt         ! ocean time-step index
-      INTEGER                         , INTENT(in   ) ::   Kbb, Kmm   ! ocean time level indices
-      INTEGER                         , INTENT(in   ) ::   kpass      ! =1/2 first or second passage
-      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(in   ) ::   pu, pv     ! before velocity  [m/s]
-      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   pu_rhs, pv_rhs   ! velocity trend   [m/s2]
+      INTEGER                                 , INTENT(in   ) ::   kt               ! ocean time-step index
+      INTEGER                                 , INTENT(in   ) ::   Kbb, Kmm         ! ocean time level indices
+      INTEGER                                 , INTENT(in   ) ::   kpass            ! =1/2 first or second passage
+      INTEGER                                 , INTENT(in   ) ::   ktuv, ktuv_rhs
+      REAL(wp), DIMENSION(A2D_T(ktuv)    ,JPK), INTENT(in   ) ::   pu, pv           ! before velocity  [m/s]
+      REAL(wp), DIMENSION(A2D_T(ktuv_rhs),JPK), INTENT(inout) ::   pu_rhs, pv_rhs   ! velocity trend   [m/s2]
       !
       INTEGER  ::   ji, jj, jk   ! dummy loop indices
+      INTEGER  ::   iij
       REAL(wp) ::   zsign        ! local scalars
       REAL(wp) ::   zua, zva     ! local scalars
@@ -65,8 +88,15 @@
       !!----------------------------------------------------------------------
       !
-      IF( kt == nit000 .AND. lwp ) THEN
-         WRITE(numout,*)
-         WRITE(numout,*) 'dyn_ldf : iso-level harmonic (laplacian) operator, pass=', kpass
-         WRITE(numout,*) '~~~~~~~ '
+      IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+         IF( kt == nit000 .AND. lwp ) THEN
+            WRITE(numout,*)
+            WRITE(numout,*) 'dyn_ldf : iso-level harmonic (laplacian) operator, pass=', kpass
+            WRITE(numout,*) '~~~~~~~ '
+         ENDIF
+      ENDIF
+      !
+      ! Define pu_rhs/pv_rhs halo points for multi-point haloes in bilaplacian case
+      IF( nldf_dyn == np_blp .AND. kpass == 1 ) THEN ; iij = nn_hls
+      ELSE                                           ; iij = 1
       ENDIF
       !
@@ -79,9 +109,9 @@
       CASE ( np_typ_rot )       !==  Vorticity-Divergence operator  ==!
          !
-         ALLOCATE( zcur(jpi,jpj) , zdiv(jpi,jpj) )
+         ALLOCATE( zcur(A2D(nn_hls)) , zdiv(A2D(nn_hls)) )
          !
          DO jk = 1, jpkm1                                 ! Horizontal slab
             !
-            DO_2D( 0, 1, 0, 1 )
+            DO_2D( iij-1, iij, iij-1, iij )
                !                                      ! ahm * e3 * curl  (computed from 1 to jpim1/jpjm1)
                zcur(ji-1,jj-1) = ahmf(ji-1,jj-1,jk) * e3f(ji-1,jj-1,jk) * r1_e1e2f(ji-1,jj-1)       &   ! ahmf already * by fmask
@@ -94,5 +124,5 @@
             END_2D
             !
-            DO_2D( 0, 0, 0, 0 )                       ! - curl( curl) + grad( div )
+            DO_2D( iij-1, iij-1, iij-1, iij-1 )   ! - curl( curl) + grad( div )
                pu_rhs(ji,jj,jk) = pu_rhs(ji,jj,jk) + zsign * umask(ji,jj,jk) * (    &    ! * by umask is mandatory for dyn_ldf_blp use
                   &              - ( zcur(ji  ,jj) - zcur(ji,jj-1) ) * r1_e2u(ji,jj) / e3u(ji,jj,jk,Kmm)   &
@@ -110,9 +140,9 @@
       CASE ( np_typ_sym )       !==  Symmetric operator  ==!
          !
-         ALLOCATE( zten(jpi,jpj) , zshe(jpi,jpj) )
+         ALLOCATE( zten(A2D(nn_hls)) , zshe(A2D(nn_hls)) )
          !
          DO jk = 1, jpkm1                                 ! Horizontal slab
             !
-            DO_2D( 0, 1, 0, 1 )
+            DO_2D( iij-1, iij, iij-1, iij )
                !                                      ! shearing stress component (F-point)   NB : ahmf has already been multiplied by fmask
                zshe(ji-1,jj-1) = ahmf(ji-1,jj-1,jk)                                                              &
@@ -129,5 +159,5 @@
             END_2D
             !
-            DO_2D( 0, 0, 0, 0 )
+            DO_2D( iij-1, iij-1, iij-1, iij-1 )
                pu_rhs(ji,jj,jk) = pu_rhs(ji,jj,jk) + zsign * r1_e1e2u(ji,jj) / e3u(ji,jj,jk,Kmm)                               &
                   &    * (   (   zten(ji+1,jj  ) * e2t(ji+1,jj  )*e2t(ji+1,jj  ) * e3t(ji+1,jj  ,jk,Kmm)                       &
@@ -150,5 +180,5 @@
       END SELECT
       !
-   END SUBROUTINE dyn_ldf_lap
+   END SUBROUTINE dyn_ldf_lap_t
 
 
@@ -171,11 +201,16 @@
       REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   pu_rhs, pv_rhs   ! momentum trend
       !
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zulap, zvlap   ! laplacian at u- and v-point
-      !!----------------------------------------------------------------------
-      !
-      IF( kt == nit000 )  THEN
-         IF(lwp) WRITE(numout,*)
-         IF(lwp) WRITE(numout,*) 'dyn_ldf_blp : bilaplacian operator momentum '
-         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~'
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zulap, zvlap   ! laplacian at u- and v-point
+      !!----------------------------------------------------------------------
+      !
+#if defined key_loop_fusion
+      CALL dyn_ldf_blp_lf( kt, Kbb, Kmm, pu, pv, pu_rhs, pv_rhs )
+#else
+      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_ldf_blp : bilaplacian operator momentum '
+            IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~'
+         ENDIF
       ENDIF
       !
@@ -185,8 +220,9 @@
       CALL dyn_ldf_lap( kt, Kbb, Kmm, pu, pv, zulap, zvlap, 1 )   ! rotated laplacian applied to pt (output in zlap,Kbb)
       !
-      CALL lbc_lnk( 'dynldf_lap_blp', zulap, 'U', -1.0_wp, zvlap, 'V', -1.0_wp )             ! Lateral boundary conditions
+      IF (nn_hls==1) CALL lbc_lnk( 'dynldf_lap_blp', zulap, 'U', -1.0_wp, zvlap, 'V', -1.0_wp )             ! Lateral boundary conditions
       !
       CALL dyn_ldf_lap( kt, Kbb, Kmm, zulap, zvlap, pu_rhs, pv_rhs, 2 )   ! rotated laplacian applied to zlap (output in pt(:,:,:,:,Krhs))
       !
+#endif
    END SUBROUTINE dyn_ldf_blp
 
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynldf_lap_blp_lf.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynldf_lap_blp_lf.F90	(revision 14852)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynldf_lap_blp_lf.F90	(revision 14852)
@@ -0,0 +1,225 @@
+MODULE dynldf_lap_blp_lf
+   !!======================================================================
+   !!                   ***  MODULE  dynldf_lap_blp  ***
+   !! Ocean dynamics:  lateral viscosity trend (laplacian and bilaplacian)
+   !!======================================================================
+   !! History : 3.7  ! 2014-01  (G. Madec, S. Masson)  Original code, re-entrant laplacian
+   !!           4.0  ! 2020-04  (A. Nasser, G. Madec)  Add symmetric mixing tensor 
+   !!----------------------------------------------------------------------
+
+   !!----------------------------------------------------------------------
+   !!   dyn_ldf_lap   : update the momentum trend with the lateral viscosity using an iso-level   laplacian operator
+   !!   dyn_ldf_blp   : update the momentum trend with the lateral viscosity using an iso-level bilaplacian operator
+   !!----------------------------------------------------------------------
+   USE oce            ! ocean dynamics and tracers
+   USE dom_oce        ! ocean space and time domain
+   USE domutl, ONLY : is_tile
+   USE ldfdyn         ! lateral diffusion: eddy viscosity coef.
+   USE ldfslp         ! iso-neutral slopes 
+   USE zdf_oce        ! ocean vertical physics
+   !
+   USE in_out_manager ! I/O manager
+   USE lib_mpp
+   
+   IMPLICIT NONE
+   PRIVATE
+
+   PUBLIC dyn_ldf_lap_lf  ! called by dynldf.F90
+   PUBLIC dyn_ldf_blp_lf  ! called by dynldf.F90
+
+   !! * Substitutions
+#  include "do_loop_substitute.h90"
+#  include "domzgr_substitute.h90"
+   !!----------------------------------------------------------------------
+   !! NEMO/OCE 4.0 , NEMO Consortium (2018)
+   !! $Id: dynldf_lap_blp.F90 14757 2021-04-27 15:33:44Z francesca $ 
+   !! Software governed by the CeCILL license (see ./LICENSE)
+   !!----------------------------------------------------------------------
+CONTAINS
+
+   SUBROUTINE dyn_ldf_lap_lf( kt, Kbb, Kmm, pu, pv, pu_rhs, pv_rhs, kpass )
+      !!
+      INTEGER                   , INTENT(in   ) ::   kt               ! ocean time-step index
+      INTEGER                   , INTENT(in   ) ::   Kbb, Kmm         ! ocean time level indices
+      INTEGER                   , INTENT(in   ) ::   kpass            ! =1/2 first or second passage
+      REAL(wp), DIMENSION(:,:,:), INTENT(in   ) ::   pu, pv           ! before velocity  [m/s]
+      REAL(wp), DIMENSION(:,:,:), INTENT(inout) ::   pu_rhs, pv_rhs   ! velocity trend   [m/s2]
+      !!
+      CALL dyn_ldf_lap_lf_t( kt, Kbb, Kmm, pu, pv, is_tile(pu), pu_rhs, pv_rhs, is_tile(pu_rhs), kpass )
+
+   END SUBROUTINE dyn_ldf_lap_lf
+  
+   SUBROUTINE dyn_ldf_lap_lf_t( kt, Kbb, Kmm, pu, pv, ktuv, pu_rhs, pv_rhs, ktuv_rhs, kpass )
+      !!----------------------------------------------------------------------
+      !!                     ***  ROUTINE dyn_ldf_lap  ***
+      !!                       
+      !! ** Purpose :   Compute the before horizontal momentum diffusive 
+      !!      trend and add it to the general trend of momentum equation.
+      !!
+      !! ** Method  :   The Laplacian operator apply on horizontal velocity is 
+      !!      writen as :   grad_h( ahmt div_h(U )) - curl_h( ahmf curl_z(U) ) 
+      !!
+      !! ** Action : - pu_rhs, pv_rhs increased by the harmonic operator applied on pu, pv.
+      !!
+      !! Reference : S.Griffies, R.Hallberg 2000 Mon.Wea.Rev., DOI:/ 
+      !!----------------------------------------------------------------------
+      INTEGER                                 , INTENT(in   ) ::   kt         ! ocean time-step index
+      INTEGER                                 , INTENT(in   ) ::   Kbb, Kmm   ! ocean time level indices
+      INTEGER                                 , INTENT(in   ) ::   kpass      ! =1/2 first or second passage
+      INTEGER                                 , INTENT(in   ) ::   ktuv, ktuv_rhs
+      REAL(wp), DIMENSION(A2D_T(ktuv)    ,JPK), INTENT(in   ) ::   pu, pv ! before velocity  [m/s]
+      REAL(wp), DIMENSION(A2D_T(ktuv_rhs),JPK), INTENT(inout) ::   pu_rhs, pv_rhs   ! velocity trend   [m/s2]
+      !
+      INTEGER  ::   ji, jj, jk   ! dummy loop indices
+      INTEGER  ::   iij
+      REAL(wp) ::   zsign        ! local scalars
+      REAL(wp) ::   zcur, zcur_im1, zcur_jm1     ! local scalars
+      REAL(wp) ::   zdiv, zdiv_ip1, zdiv_jp1     ! local scalars
+      REAL(wp) ::   zten, zten_ip1, zten_jp1, zshe, zshe_im1, zshe_jm1  ! tension (diagonal) and shearing (anti-diagonal) terms
+      !!----------------------------------------------------------------------
+      !
+      IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+         IF( kt == nit000 .AND. lwp ) THEN
+            WRITE(numout,*)
+            WRITE(numout,*) 'dyn_ldf_lf : iso-level harmonic (laplacian) operator, pass=', kpass
+            WRITE(numout,*) '~~~~~~~ '
+         ENDIF
+      ENDIF
+      !
+      ! Define pu_rhs/pv_rhs halo points for multi-point haloes in bilaplacian case
+      IF( nldf_dyn == np_blp .AND. kpass == 1 ) THEN ; iij = nn_hls
+      ELSE                                           ; iij = 1
+      ENDIF
+      !
+      IF( kpass == 1 ) THEN   ;   zsign =  1._wp      ! bilaplacian operator require a minus sign
+      ELSE                    ;   zsign = -1._wp      !  (eddy viscosity coef. >0)
+      ENDIF
+      !
+      SELECT CASE( nn_dynldf_typ )  
+      !              
+      CASE ( np_typ_rot )       !==  Vorticity-Divergence operator  ==!
+         !
+         DO_3D( iij-1, iij-1, iij-1, iij-1, 1, jpkm1 )                           ! Horizontal slab
+            !                                      ! ahm * e3 * curl  (computed from 1 to jpim1/jpjm1)
+            zcur     = ahmf(ji,jj,jk) * e3f(ji,jj,jk) * r1_e1e2f(ji,jj)               &   ! ahmf already * by fmask   
+               &       * ( 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) )
+            zcur_jm1 = ahmf(ji  ,jj-1,jk) * e3f(ji,jj-1,jk) * r1_e1e2f(ji,jj-1)               &   ! ahmf already * by fmask
+               &       * ( e2v(ji+1,jj-1) * pv(ji+1,jj-1,jk) - e2v(ji,jj-1) * pv(ji,jj-1,jk)  &
+               &       - e1u(ji,jj) * pu(ji,jj,jk) + e1u(ji,jj-1) * pu(ji,jj-1,jk) )
+            zcur_im1 = ahmf(ji-1,jj,jk) * e3f(ji-1,jj,jk) * r1_e1e2f(ji-1,jj)         &   ! ahmf already * by fmask
+               &       * ( e2v(ji,jj) * pv(ji,jj,jk) - e2v(ji-1,jj) * pv(ji-1,jj,jk)  &
+               &       - e1u(ji-1,jj+1) * pu(ji-1,jj+1,jk) + e1u(ji-1,jj) * pu(ji-1,jj,jk) )
+            !                                      ! ahm * div        (computed from 2 to jpi/jpj)
+            zdiv     = ahmt(ji,jj,jk) * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kbb)               &   ! ahmt already * by tmask
+               &     * ( e2u(ji,jj)*e3u(ji,jj,jk,Kbb) * pu(ji,jj,jk) - e2u(ji-1,jj)*e3u(ji-1,jj,jk,Kbb) * pu(ji-1,jj,jk)  &
+               &       + e1v(ji,jj)*e3v(ji,jj,jk,Kbb) * pv(ji,jj,jk) - e1v(ji,jj-1)*e3v(ji,jj-1,jk,Kbb) * pv(ji,jj-1,jk)  )
+            zdiv_ip1 = ahmt(ji+1,jj,jk) * r1_e1e2t(ji+1,jj) / e3t(ji+1,jj,jk,Kbb)         &   ! ahmt already * by tmask
+               &     * ( e2u(ji+1,jj)*e3u(ji+1,jj,jk,Kbb) * pu(ji+1,jj,jk) - e2u(ji,jj)*e3u(ji,jj,jk,Kbb) * pu(ji,jj,jk)  &
+               &       + e1v(ji+1,jj)*e3v(ji+1,jj,jk,Kbb) * pv(ji+1,jj,jk) - e1v(ji+1,jj-1)*e3v(ji+1,jj-1,jk,Kbb) * pv(ji+1,jj-1,jk) )
+            zdiv_jp1 = ahmt(ji,jj+1,jk) * r1_e1e2t(ji,jj+1) / e3t(ji,jj+1,jk,Kbb)         &   ! ahmt already * by tmask
+               &     * ( e2u(ji,jj+1)*e3u(ji,jj+1,jk,Kbb) * pu(ji,jj+1,jk) - e2u(ji-1,jj+1)*e3u(ji-1,jj+1,jk,Kbb) * pu(ji-1,jj+1,jk)  &
+               &       + e1v(ji,jj+1)*e3v(ji,jj+1,jk,Kbb) * pv(ji,jj+1,jk) - e1v(ji,jj)*e3v(ji,jj,jk,Kbb) * pv(ji,jj,jk) )
+            !                                      ! - curl( curl) + grad( div )
+            pu_rhs(ji,jj,jk) = pu_rhs(ji,jj,jk) + zsign * umask(ji,jj,jk) * (    &    ! * by umask is mandatory for dyn_ldf_blp use
+               &              - ( zcur - zcur_jm1 ) * r1_e2u(ji,jj) / e3u(ji,jj,jk,Kmm)   &
+               &              + ( zdiv_ip1 - zdiv ) * r1_e1u(ji,jj)                      )
+            !
+            pv_rhs(ji,jj,jk) = pv_rhs(ji,jj,jk) + zsign * vmask(ji,jj,jk) * (    &    ! * by vmask is mandatory for dyn_ldf_blp use
+               &                ( zcur - zcur_im1 ) * r1_e1v(ji,jj) / e3v(ji,jj,jk,Kmm)   &
+               &              + ( zdiv_jp1 - zdiv ) * r1_e2v(ji,jj)                      )
+         END_3D                                                  !   End of slab
+         !
+      CASE ( np_typ_sym )       !==  Symmetric operator  ==!
+         !
+         DO_3D( iij-1, iij-1, iij-1, iij-1, 1, jpkm1 )                           ! Horizontal slab
+            !                                      ! shearing stress component (F-point)   NB : ahmf has already been multiplied by fmask
+            zshe = ahmf(ji,jj,jk)                                                            &
+               &    * (    e1f(ji,jj)    * r1_e2f(ji,jj)                                     &
+               &    * ( pu(ji,jj+1,jk) * r1_e1u(ji,jj+1)  - pu(ji,jj,jk) * r1_e1u(ji,jj) )   &
+               &    +  e2f(ji,jj)    * r1_e1f(ji,jj)                                         &
+               &    * ( pv(ji+1,jj,jk) * r1_e2v(ji+1,jj)  - pv(ji,jj,jk) * r1_e2v(ji,jj) )   ) 
+            zshe_im1 = ahmf(ji-1,jj,jk)                                                                  &
+               &        * (    e1f(ji-1,jj)    * r1_e2f(ji-1,jj)                                         &
+               &        * ( pu(ji-1,jj+1,jk) * r1_e1u(ji-1,jj+1)  - pu(ji-1,jj,jk) * r1_e1u(ji-1,jj) )   &
+               &        +  e2f(ji-1,jj)    * r1_e1f(ji-1,jj)                                             &
+               &        * ( pv(ji  ,jj,jk) * r1_e2v(ji  ,jj)  - pv(ji-1,jj,jk) * r1_e2v(ji-1,jj) )   ) 
+            zshe_jm1 = ahmf(ji,jj-1,jk)                                                                &
+               &        * (    e1f(ji,jj-1)    * r1_e2f(ji,jj-1)                                       &
+               &        * ( pu(ji,jj,jk) * r1_e1u(ji,jj)  - pu(ji,jj-1,jk) * r1_e1u(ji,jj-1) )         &
+               &        +  e2f(ji,jj-1)    * r1_e1f(ji,jj-1)                                           &
+               &        * ( pv(ji+1,jj-1,jk) * r1_e2v(ji+1,jj-1)  - pv(ji,jj-1,jk) * r1_e2v(ji,jj-1) )   ) 
+            !                                      ! tension stress component (T-point)   NB : ahmt has already been multiplied by tmask
+            zten        = ahmt(ji,jj,jk)                                                          &
+               &     * (    e2t(ji,jj)    * r1_e1t(ji,jj)                                         &
+               &         * ( pu(ji,jj,jk) * r1_e2u(ji,jj)  - pu(ji-1,jj,jk) * r1_e2u(ji-1,jj) )   &
+               &         -  e1t(ji,jj)    * r1_e2t(ji,jj)                                         &
+               &         * ( pv(ji,jj,jk) * r1_e1v(ji,jj)  - pv(ji,jj-1,jk) * r1_e1v(ji,jj-1) )   )   
+            zten_ip1    = ahmt(ji+1,jj,jk)                                                              &
+               &     * (    e2t(ji+1,jj)    * r1_e1t(ji+1,jj)                                           &
+               &         * ( pu(ji+1,jj,jk) * r1_e2u(ji+1,jj)  - pu(ji,jj,jk) * r1_e2u(ji,jj) )         &
+               &         -  e1t(ji+1,jj)    * r1_e2t(ji+1,jj)                                           &
+               &         * ( pv(ji+1,jj,jk) * r1_e1v(ji+1,jj)  - pv(ji+1,jj-1,jk) * r1_e1v(ji+1,jj-1) ) )   
+            zten_jp1    = ahmt(ji,jj+1,jk)                                                              &
+               &     * (    e2t(ji,jj+1)    * r1_e1t(ji,jj+1)                                           &
+               &         * ( pu(ji,jj+1,jk) * r1_e2u(ji,jj+1)  - pu(ji-1,jj+1,jk) * r1_e2u(ji-1,jj+1) ) &
+               &         -  e1t(ji,jj+1)    * r1_e2t(ji,jj+1)                                           &
+               &         * ( pv(ji,jj+1,jk) * r1_e1v(ji,jj+1)  - pv(ji,jj,jk) * r1_e1v(ji,jj) )   )   
+            ! 
+            pu_rhs(ji,jj,jk) = pu_rhs(ji,jj,jk) + zsign * r1_e1e2u(ji,jj) / e3u(ji,jj,jk,Kmm)                    &
+               &    * (   (   zten_ip1 * e2t(ji+1,jj  )*e2t(ji+1,jj  ) * e3t(ji+1,jj  ,jk,Kmm)                   &
+               &            - zten * e2t(ji  ,jj  )*e2t(ji  ,jj  ) * e3t(ji  ,jj  ,jk,Kmm) ) * r1_e2u(ji,jj)     & 
+               &        + (   zshe * e1f(ji  ,jj  )*e1f(ji  ,jj  ) * e3f(ji  ,jj  ,jk)                           &
+               &            - zshe_jm1 * e1f(ji  ,jj-1)*e1f(ji  ,jj-1) * e3f(ji  ,jj-1,jk)     ) * r1_e1u(ji,jj) )   
+            !
+            pv_rhs(ji,jj,jk) = pv_rhs(ji,jj,jk) + zsign * r1_e1e2v(ji,jj) / e3v(ji,jj,jk,Kmm)                    &
+               &    * (   (   zshe * e2f(ji  ,jj  )*e2f(ji  ,jj  ) * e3f(ji  ,jj  ,jk)                           &
+               &            - zshe_im1 * e2f(ji-1,jj  )*e2f(ji-1,jj  ) * e3f(ji-1,jj  ,jk)     ) * r1_e2v(ji,jj) &
+               &        - (   zten_jp1 * e1t(ji  ,jj+1)*e1t(ji  ,jj+1) * e3t(ji  ,jj+1,jk,Kmm)                   &
+               &            - zten * e1t(ji  ,jj  )*e1t(ji  ,jj  ) * e3t(ji  ,jj  ,jk,Kmm) ) * r1_e1v(ji,jj) )
+            !
+         END_3D
+         !
+      END SELECT
+      !
+   END SUBROUTINE dyn_ldf_lap_lf_t
+
+
+   SUBROUTINE dyn_ldf_blp_lf( kt, Kbb, Kmm, pu, pv, pu_rhs, pv_rhs )
+      !!----------------------------------------------------------------------
+      !!                 ***  ROUTINE dyn_ldf_blp  ***
+      !!                    
+      !! ** Purpose :   Compute the before lateral momentum viscous trend 
+      !!              and add it to the general trend of momentum equation.
+      !!
+      !! ** Method  :   The lateral viscous trends is provided by a bilaplacian
+      !!      operator applied to before field (forward in time).
+      !!      It is computed by two successive calls to dyn_ldf_lap routine
+      !!
+      !! ** Action :   pt(:,:,:,:,Krhs)   updated with the before rotated bilaplacian diffusion
+      !!----------------------------------------------------------------------
+      INTEGER                         , INTENT(in   ) ::   kt         ! ocean time-step index
+      INTEGER                         , INTENT(in   ) ::   Kbb, Kmm   ! ocean time level indices
+      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(in   ) ::   pu, pv     ! before velocity fields
+      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   pu_rhs, pv_rhs   ! momentum trend
+      !
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zulap, zvlap   ! laplacian at u- and v-point
+      !!----------------------------------------------------------------------
+      !
+      IF( kt == nit000 )  THEN
+         IF(lwp) WRITE(numout,*)
+         IF(lwp) WRITE(numout,*) 'dyn_ldf_blp_lf : bilaplacian operator momentum '
+         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~'
+      ENDIF
+      !
+      zulap(:,:,:) = 0._wp
+      zvlap(:,:,:) = 0._wp
+      !
+      CALL dyn_ldf_lap_lf( kt, Kbb, Kmm, pu, pv, zulap, zvlap, 1 )   ! rotated laplacian applied to pt (output in zlap,Kbb)
+      !
+      CALL dyn_ldf_lap_lf( kt, Kbb, Kmm, zulap, zvlap, pu_rhs, pv_rhs, 2 )   ! rotated laplacian applied to zlap (output in pt(:,:,:,:,Krhs))
+      !
+   END SUBROUTINE dyn_ldf_blp_lf
+
+   !!======================================================================
+END MODULE dynldf_lap_blp_lf
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynspg_ts.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynspg_ts.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynspg_ts.F90	(revision 14852)
@@ -730,5 +730,5 @@
       IF (ln_bt_fw) THEN
          IF( .NOT.( kt == nit000 .AND. l_1st_euler ) ) THEN
-            DO_2D( 1, 1, 1, 1 )
+            DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
                zun_save = un_adv(ji,jj)
                zvn_save = vn_adv(ji,jj)
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynvor.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynvor.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynvor.F90	(revision 14852)
@@ -240,12 +240,14 @@
       INTEGER  ::   ji, jj, jk           ! dummy loop indices
       REAL(wp) ::   zx1, zy1, zx2, zy2   ! local scalars
-      REAL(wp), DIMENSION(jpi,jpj)     ::   zwx, zwy, zwt   ! 2D workspace
-      REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) ::   zwz      ! 3D workspace, jpkm1 -> avoid lbc_lnk on jpk that is not defined
-      !!----------------------------------------------------------------------
-      !
-      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,*) '~~~~~~~~~~~'
+      REAL(wp), DIMENSION(A2D(nn_hls))        ::   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
       !
@@ -254,17 +256,17 @@
       !
       CASE ( np_RVO , np_CRV )                  !* relative vorticity at f-point is used
-         ALLOCATE( zwz(jpi,jpj,jpk) )
+         ALLOCATE( zwz(A2D(nn_hls),jpk) )
          DO jk = 1, jpkm1                                ! Horizontal slab
-            DO_2D( 1, 0, 1, 0 )
+            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)  &
                   &             - 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, 0, 1, 0 )
+               DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
                   zwz(ji,jj,jk) = zwz(ji,jj,jk) * fmask(ji,jj,jk)
                END_2D
             ENDIF
          END DO
-         CALL lbc_lnk( 'dynvor', zwz, 'F', 1.0_wp )
+         IF (nn_hls==1) CALL lbc_lnk( 'dynvor', zwz, 'F', 1.0_wp )
          !
       END SELECT
@@ -277,5 +279,7 @@
          !
          CASE ( np_COR )                           !* Coriolis (planetary vorticity)
-            zwt(:,:) = ff_t(:,:) * e1e2t(:,:)*e3t(:,:,jk,Kmm)
+            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 )
@@ -356,11 +360,13 @@
       INTEGER  ::   ji, jj, jk           ! dummy loop indices
       REAL(wp) ::   zx1, zy1, zx2, zy2, ze3f, zmsk   ! local scalars
-      REAL(wp), DIMENSION(jpi,jpj) ::   zwx, zwy, zwz   ! 2D workspace
-      !!----------------------------------------------------------------------
-      !
-      IF( kt == nit000 ) THEN
-         IF(lwp) WRITE(numout,*)
-         IF(lwp) WRITE(numout,*) 'dyn:vor_ene : vorticity term: energy conserving scheme'
-         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~'
+      REAL(wp), DIMENSION(A2D(nn_hls)) ::   zwx, zwy, zwz   ! 2D workspace
+      !!----------------------------------------------------------------------
+      !
+      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_ene : vorticity term: energy conserving scheme'
+            IF(lwp) WRITE(numout,*) '~~~~~~~~~~~'
+         ENDIF
       ENDIF
       !
@@ -371,5 +377,7 @@
          SELECT CASE( kvor )                 !==  vorticity considered  ==!
          CASE ( np_COR )                           !* Coriolis (planetary vorticity)
-            zwz(:,:) = ff_f(:,:)
+            DO_2D( 1, 0, 1, 0 )
+               zwz(ji,jj) = ff_f(ji,jj)
+            END_2D
          CASE ( np_RVO )                           !* relative vorticity
             DO_2D( 1, 0, 1, 0 )
@@ -437,6 +445,8 @@
 #endif
          !                                   !==  horizontal fluxes  ==!
-         zwx(:,:) = e2u(:,:) * e3u(:,:,jk,Kmm) * pu(:,:,jk)
-         zwy(:,:) = e1v(:,:) * e3v(:,:,jk,Kmm) * pv(:,:,jk)
+         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  =!
@@ -483,11 +493,13 @@
       INTEGER  ::   ji, jj, jk   ! dummy loop indices
       REAL(wp) ::   zuav, zvau, ze3f, zmsk   ! local scalars
-      REAL(wp), DIMENSION(jpi,jpj) ::   zwx, zwy, zwz, zww   ! 2D workspace
-      !!----------------------------------------------------------------------
-      !
-      IF( kt == nit000 ) THEN
-         IF(lwp) WRITE(numout,*)
-         IF(lwp) WRITE(numout,*) 'dyn:vor_ens : vorticity term: enstrophy conserving scheme'
-         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~'
+      REAL(wp), DIMENSION(A2D(nn_hls)) ::   zwx, zwy, zwz   ! 2D workspace
+      !!----------------------------------------------------------------------
+      !
+      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_ens : vorticity term: enstrophy conserving scheme'
+            IF(lwp) WRITE(numout,*) '~~~~~~~~~~~'
+         ENDIF
       ENDIF
       !                                                ! ===============
@@ -497,5 +509,7 @@
          SELECT CASE( kvor )                 !==  vorticity considered  ==!
          CASE ( np_COR )                           !* Coriolis (planetary vorticity)
-            zwz(:,:) = ff_f(:,:)
+            DO_2D( 1, 0, 1, 0 )
+               zwz(ji,jj) = ff_f(ji,jj)
+            END_2D
          CASE ( np_RVO )                           !* relative vorticity
             DO_2D( 1, 0, 1, 0 )
@@ -564,6 +578,8 @@
 #endif
          !                                   !==  horizontal fluxes  ==!
-         zwx(:,:) = e2u(:,:) * e3u(:,:,jk,Kmm) * pu(:,:,jk)
-         zwy(:,:) = e1v(:,:) * e3v(:,:,jk,Kmm) * pv(:,:,jk)
+         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  =!
@@ -609,13 +625,22 @@
       REAL(wp) ::   zua, zva     ! local scalars
       REAL(wp) ::   zmsk, ze3f   ! local scalars
-      REAL(wp), DIMENSION(jpi,jpj)       ::   zwx , zwy , z1_e3f
-      REAL(wp), DIMENSION(jpi,jpj)       ::   ztnw, ztne, ztsw, ztse
-      REAL(wp), DIMENSION(jpi,jpj,jpkm1) ::   zwz   ! 3D workspace, jpkm1 -> jpkm1 -> avoid lbc_lnk on jpk that is not defined
-      !!----------------------------------------------------------------------
-      !
-      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,*) '~~~~~~~~~~~'
+      REAL(wp), DIMENSION(A2D(nn_hls))       ::   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
+#endif
+      REAL(wp), DIMENSION(A2D(nn_hls),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
+         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
       !
@@ -625,5 +650,5 @@
          !
 #if defined key_qco   ||   defined key_linssh
-         DO_2D( 1, 0, 1, 0 )                 ! == reciprocal of e3 at F-point (key_qco)
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )                 ! == reciprocal of e3 at F-point (key_qco)
             z1_e3f(ji,jj) = 1._wp / e3f_vor(ji,jj,jk)
          END_2D
@@ -631,9 +656,11 @@
          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, 0, 1, 0 )
-               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)  )
+            DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-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
@@ -641,9 +668,11 @@
             END_2D
          CASE ( 1 )                                   ! new formulation  (masked averaging of e3t divided by the sum of mask)
-            DO_2D( 1, 0, 1, 0 )
-               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)  )
+            DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-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)  )
@@ -658,35 +687,39 @@
          !
          CASE ( np_COR )                           !* Coriolis (planetary vorticity)
-            DO_2D( 1, 0, 1, 0 )
+            DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
                zwz(ji,jj,jk) = ff_f(ji,jj) * z1_e3f(ji,jj)
             END_2D
          CASE ( np_RVO )                           !* relative vorticity
-            DO_2D( 1, 0, 1, 0 )
+            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)  &
                   &            - 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, 0, 1, 0 )
+               DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
                   zwz(ji,jj,jk) = zwz(ji,jj,jk) * fmask(ji,jj,jk)
                END_2D
             ENDIF
          CASE ( np_MET )                           !* metric term
-            DO_2D( 1, 0, 1, 0 )
+            DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
                zwz(ji,jj,jk) = (   ( 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, 0, 1, 0 )
-               zwz(ji,jj,jk) = (  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)   ) * z1_e3f(ji,jj)
+            DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
+            ! round brackets added to fix the order of floating point operations
+            ! needed to ensure halo 1 - halo 2 compatibility
+               zwz(ji,jj,jk) = (  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, 0, 1, 0 )
+               DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
                   zwz(ji,jj,jk) = ( zwz(ji,jj,jk) - ff_f(ji,jj) ) * fmask(ji,jj,jk) + ff_f(ji,jj)
                END_2D
             ENDIF
          CASE ( np_CME )                           !* Coriolis + metric
-            DO_2D( 1, 0, 1, 0 )
+            DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
                zwz(ji,jj,jk) = (   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)
@@ -699,13 +732,44 @@
       !                                                ! ===============
       !
-      CALL lbc_lnk( 'dynvor', zwz, 'F', 1.0_wp )
-      !
-      !                                                ! ===============
-      DO jk = 1, jpkm1                                 ! Horizontal slab
-         !                                             ! ===============
-         !
+      IF (nn_hls==1) CALL lbc_lnk( 'dynvor', zwz, 'F', 1.0_wp )
+      !
+      !                                                ! ===============
+      !                                                ! Horizontal slab
+      !                                                ! ===============
+#if defined key_loop_fusion
+      DO_3D( 0, 0, 0, 0, 1, jpkm1 )
          !                                   !==  horizontal fluxes  ==!
-         zwx(:,:) = e2u(:,:) * e3u(:,:,jk,Kmm) * pu(:,:,jk)
-         zwy(:,:) = e1v(:,:) * e3v(:,:,jk,Kmm) * pv(:,:,jk)
+         zwx         = e2u(ji  ,jj  ) * e3u(ji  ,jj  ,jk,Kmm) * pu(ji  ,jj  ,jk)
+         zwx_im1     = e2u(ji-1,jj  ) * e3u(ji-1,jj  ,jk,Kmm) * pu(ji-1,jj  ,jk)
+         zwx_jp1     = e2u(ji  ,jj+1) * e3u(ji  ,jj+1,jk,Kmm) * pu(ji  ,jj+1,jk)
+         zwx_im1_jp1 = e2u(ji-1,jj+1) * e3u(ji-1,jj+1,jk,Kmm) * pu(ji-1,jj+1,jk)
+         zwy         = e1v(ji  ,jj  ) * e3v(ji  ,jj  ,jk,Kmm) * pv(ji  ,jj  ,jk)
+         zwy_ip1     = e1v(ji+1,jj  ) * e3v(ji+1,jj  ,jk,Kmm) * pv(ji+1,jj  ,jk)
+         zwy_jm1     = e1v(ji  ,jj-1) * e3v(ji  ,jj-1,jk,Kmm) * pv(ji  ,jj-1,jk)
+         zwy_ip1_jm1 = e1v(ji+1,jj-1) * e3v(ji+1,jj-1,jk,Kmm) * pv(ji+1,jj-1,jk)
+         !                                   !==  compute and add the vorticity term trend  =!
+         ztne     = zwz(ji-1,jj  ,jk) + zwz(ji  ,jj  ,jk) + zwz(ji  ,jj-1,jk)
+         ztnw     = zwz(ji-1,jj-1,jk) + zwz(ji-1,jj  ,jk) + zwz(ji  ,jj  ,jk)
+         ztnw_ip1 = zwz(ji  ,jj-1,jk) + zwz(ji  ,jj  ,jk) + zwz(ji+1,jj  ,jk)
+         ztse     = zwz(ji  ,jj  ,jk) + zwz(ji  ,jj-1,jk) + zwz(ji-1,jj-1,jk)
+         ztse_jp1 = zwz(ji  ,jj+1,jk) + zwz(ji  ,jj  ,jk) + zwz(ji-1,jj  ,jk)
+         ztsw_jp1 = zwz(ji  ,jj  ,jk) + zwz(ji-1,jj  ,jk) + zwz(ji-1,jj+1,jk)
+         ztsw_ip1 = zwz(ji+1,jj-1,jk) + zwz(ji  ,jj-1,jk) + zwz(ji  ,jj  ,jk)
+         !
+         zua = + r1_12 * r1_e1u(ji,jj) * (  ztne * zwy + ztnw_ip1 * zwy_ip1   &
+            &                             + ztse * zwy_jm1 + ztsw_ip1 * zwy_ip1_jm1 )
+         zva = - r1_12 * r1_e2v(ji,jj) * (  ztsw_jp1 * zwx_im1_jp1 + ztse_jp1 * zwx_jp1   &
+            &                             + ztnw * zwx_im1 + ztne * zwx )
+         pu_rhs(ji,jj,jk) = pu_rhs(ji,jj,jk) + zua
+         pv_rhs(ji,jj,jk) = pv_rhs(ji,jj,jk) + zva
+      END_3D
+#else
+      DO jk = 1, jpkm1
+         !
+         !                                   !==  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  =!
@@ -725,6 +789,8 @@
             pv_rhs(ji,jj,jk) = pv_rhs(ji,jj,jk) + zva
          END_2D
-         !                                             ! ===============
-      END DO                                           !   End of slab
+      END DO
+#endif
+         !                                             ! ===============
+         !                                             !   End of slab
       !                                                ! ===============
    END SUBROUTINE vor_een
@@ -758,13 +824,15 @@
       REAL(wp) ::   zua, zva       ! local scalars
       REAL(wp) ::   zmsk, z1_e3t   ! local scalars
-      REAL(wp), DIMENSION(jpi,jpj)       ::   zwx , zwy
-      REAL(wp), DIMENSION(jpi,jpj)       ::   ztnw, ztne, ztsw, ztse
-      REAL(wp), DIMENSION(jpi,jpj,jpkm1) ::   zwz   ! 3D workspace, avoid lbc_lnk on jpk that is not defined
-      !!----------------------------------------------------------------------
-      !
-      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,*) '~~~~~~~~~~~'
+      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
+      !!----------------------------------------------------------------------
+      !
+      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
       !
@@ -776,36 +844,40 @@
          SELECT CASE( kvor )                 !==  vorticity considered  ==!
          CASE ( np_COR )                           !* Coriolis (planetary vorticity)
-            DO_2D( 1, 0, 1, 0 )
+            DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
                zwz(ji,jj,jk) = ff_f(ji,jj)
             END_2D
          CASE ( np_RVO )                           !* relative vorticity
-            DO_2D( 1, 0, 1, 0 )
-               zwz(ji,jj,jk) = (  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)  ) &
+            DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
+               ! round brackets added to fix the order of floating point operations
+               ! needed to ensure halo 1 - halo 2 compatibility
+               zwz(ji,jj,jk) = (  (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, 0, 1, 0 )
+               DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
                   zwz(ji,jj,jk) = zwz(ji,jj,jk) * fmask(ji,jj,jk)
                END_2D
             ENDIF
          CASE ( np_MET )                           !* metric term
-            DO_2D( 1, 0, 1, 0 )
+            DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
                zwz(ji,jj,jk) = ( 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, 0, 1, 0 )
-               zwz(ji,jj,jk) = (  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)    )
+            DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
+               ! round brackets added to fix the order of floating point operations
+               ! needed to ensure halo 1 - halo 2 compatibility
+               zwz(ji,jj,jk) = (  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, 0, 1, 0 )
+               DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
                   zwz(ji,jj,jk) = ( zwz(ji,jj,jk) - ff_f(ji,jj) ) * fmask(ji,jj,jk) + ff_f(ji,jj)
                END_2D
             ENDIF
          CASE ( np_CME )                           !* Coriolis + metric
-            DO_2D( 1, 0, 1, 0 )
+            DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
                zwz(ji,jj,jk) = 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)
@@ -819,5 +891,5 @@
       !                                                ! ===============
       !
-      CALL lbc_lnk( 'dynvor', zwz, 'F', 1.0_wp )
+      IF (nn_hls==1) CALL lbc_lnk( 'dynvor', zwz, 'F', 1.0_wp )
       !
       !                                                ! ===============
@@ -826,6 +898,8 @@
          !
          !                                   !==  horizontal fluxes  ==!
-         zwx(:,:) = e2u(:,:) * e3u(:,:,jk,Kmm) * pu(:,:,jk)
-         zwy(:,:) = e1v(:,:) * e3v(:,:,jk,Kmm) * pv(:,:,jk)
+         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  =!
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynzad.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynzad.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynzad.F90	(revision 14852)
@@ -60,6 +60,6 @@
       INTEGER  ::   ji, jj, jk   ! dummy loop indices
       REAL(wp) ::   zua, zva     ! local scalars
-      REAL(wp), DIMENSION(jpi,jpj)     ::   zww
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zwuw, zwvw
+      REAL(wp), DIMENSION(A2D(nn_hls))     ::   zww
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zwuw, zwvw
       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::   ztrdu, ztrdv
       !!----------------------------------------------------------------------
@@ -67,7 +67,9 @@
       IF( ln_timing )   CALL timing_start('dyn_zad')
       !
-      IF( kt == nit000 ) THEN
-         IF(lwp) WRITE(numout,*)
-         IF(lwp) WRITE(numout,*) 'dyn_zad : 2nd order vertical advection scheme'
+      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_zad : 2nd order vertical advection scheme'
+         ENDIF
       ENDIF
 
@@ -79,11 +81,13 @@
 
       DO jk = 2, jpkm1                ! Vertical momentum advection at level w and u- and v- vertical
-         DO_2D( 0, 1, 0, 1 )              ! vertical fluxes
-          IF( ln_vortex_force ) THEN
-            zww(ji,jj) = 0.25_wp * e1e2t(ji,jj) * ( ww(ji,jj,jk) + wsd(ji,jj,jk) )
-          ELSE
-            zww(ji,jj) = 0.25_wp * e1e2t(ji,jj) * ww(ji,jj,jk)
-          ENDIF
-         END_2D
+         IF( ln_vortex_force ) THEN       ! vertical fluxes
+            DO_2D( 0, 1, 0, 1 )
+               zww(ji,jj) = 0.25_wp * e1e2t(ji,jj) * ( ww(ji,jj,jk) + wsd(ji,jj,jk) )
+            END_2D
+         ELSE
+            DO_2D( 0, 1, 0, 1 )
+               zww(ji,jj) = 0.25_wp * e1e2t(ji,jj) * ww(ji,jj,jk)
+            END_2D
+         ENDIF
          DO_2D( 0, 0, 0, 0 )              ! vertical momentum advection at w-point
             zwuw(ji,jj,jk) = ( zww(ji+1,jj  ) + zww(ji,jj) ) * ( puu(ji,jj,jk-1,Kmm) - puu(ji,jj,jk,Kmm) )
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynzdf.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynzdf.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/dynzdf.F90	(revision 14852)
@@ -19,5 +19,9 @@
    USE zdfdrg         ! vertical physics: top/bottom drag coef.
    USE dynadv    ,ONLY: ln_dynadv_vec    ! dynamics: advection form
+#if defined key_loop_fusion
+   USE dynldf_iso_lf,ONLY: akzu, akzv       ! dynamics: vertical component of rotated lateral mixing 
+#else
    USE dynldf_iso,ONLY: akzu, akzv       ! dynamics: vertical component of rotated lateral mixing 
+#endif
    USE ldfdyn         ! lateral diffusion: eddy viscosity coef. and type of operator
    USE trd_oce        ! trends: ocean variables
@@ -78,5 +82,5 @@
       REAL(wp) ::   zWui, zWvi         !   -      -
       REAL(wp) ::   zWus, zWvs         !   -      -
-      REAL(wp), DIMENSION(jpi,jpj,jpk)        ::  zwi, zwd, zws   ! 3D workspace 
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk)        ::  zwi, zwd, zws   ! 3D workspace
       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::   ztrdu, ztrdv   !  -      -
       !!---------------------------------------------------------------------
@@ -84,11 +88,13 @@
       IF( ln_timing )   CALL timing_start('dyn_zdf')
       !
-      IF( kt == nit000 ) THEN       !* initialization
-         IF(lwp) WRITE(numout,*)
-         IF(lwp) WRITE(numout,*) 'dyn_zdf_imp : vertical momentum diffusion implicit operator'
-         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~ '
-         !
-         If( ln_linssh ) THEN   ;    r_vvl = 0._wp    ! non-linear free surface indicator
-         ELSE                   ;    r_vvl = 1._wp
+      IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+         IF( kt == nit000 ) THEN       !* initialization
+            IF(lwp) WRITE(numout,*)
+            IF(lwp) WRITE(numout,*) 'dyn_zdf_imp : vertical momentum diffusion implicit operator'
+            IF(lwp) WRITE(numout,*) '~~~~~~~~~~~ '
+            !
+            If( ln_linssh ) THEN   ;    r_vvl = 0._wp    ! non-linear free surface indicator
+            ELSE                   ;    r_vvl = 1._wp
+            ENDIF
          ENDIF
       ENDIF
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/sshwzv.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/sshwzv.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/sshwzv.F90	(revision 14852)
@@ -78,5 +78,5 @@
       REAL(wp), DIMENSION(jpi,jpj,jpt), INTENT(inout) ::   pssh           ! sea-surface height
       ! 
-      INTEGER  ::   jk      ! dummy loop index
+      INTEGER  ::   ji, jj, jk      ! dummy loop index
       REAL(wp) ::   zcoef   ! local scalar
       REAL(wp), DIMENSION(jpi,jpj) ::   zhdiv   ! 2D workspace
@@ -103,12 +103,16 @@
       !
       zhdiv(:,:) = 0._wp
-      DO jk = 1, jpkm1                                 ! Horizontal divergence of barotropic transports
-        zhdiv(:,:) = zhdiv(:,:) + e3t(:,:,jk,Kmm) * hdiv(:,:,jk)
-      END DO
+      DO_3D( 1, nn_hls, 1, nn_hls, 1, jpkm1 )                                 ! Horizontal divergence of barotropic transports
+        zhdiv(ji,jj) = zhdiv(ji,jj) + e3t(ji,jj,jk,Kmm) * hdiv(ji,jj,jk)
+      END_3D
       !                                                ! Sea surface elevation time stepping
       ! In time-split case we need a first guess of the ssh after (using the baroclinic timestep) in order to
       ! compute the vertical velocity which can be used to compute the non-linear terms of the momentum equations.
       ! 
-      pssh(:,:,Kaa) = (  pssh(:,:,Kbb) - rDt * ( zcoef * ( emp_b(:,:) + emp(:,:) ) + zhdiv(:,:) )  ) * ssmask(:,:)
+      DO_2D_OVR( 1, nn_hls, 1, nn_hls )                ! Loop bounds limited by hdiv definition in div_hor
+         pssh(ji,jj,Kaa) = (  pssh(ji,jj,Kbb) - rDt * ( zcoef * ( emp_b(ji,jj) + emp(ji,jj) ) + zhdiv(ji,jj) )  ) * ssmask(ji,jj)
+      END_2D
+      ! pssh must be defined everywhere (true for dyn_spg_ts, not for dyn_spg_exp)
+      IF ( .NOT. ln_dynspg_ts .AND. nn_hls == 2 ) CALL lbc_lnk( 'sshwzv', pssh(:,:,Kaa), 'T', 1.0_wp )
       !
 #if defined key_agrif
@@ -119,5 +123,5 @@
       IF ( .NOT.ln_dynspg_ts ) THEN
          IF( ln_bdy ) THEN
-            CALL lbc_lnk( 'sshwzv', pssh(:,:,Kaa), 'T', 1.0_wp )    ! Not sure that's necessary
+            IF (nn_hls==1) CALL lbc_lnk( 'sshwzv', pssh(:,:,Kaa), 'T', 1.0_wp )    ! Not sure that's necessary
             CALL bdy_ssh( pssh(:,:,Kaa) )             ! Duplicate sea level across open boundaries
          ENDIF
@@ -178,18 +182,18 @@
             ! horizontal divergence of thickness diffusion transport ( velocity multiplied by e3t)
             ! - ML - note: computation already done in dom_vvl_sf_nxt. Could be optimized (not critical and clearer this way)
-            DO_2D( 0, 0, 0, 0 )
+            DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
                zhdiv(ji,jj,jk) = r1_e1e2t(ji,jj) * ( un_td(ji,jj,jk) - un_td(ji-1,jj,jk) + vn_td(ji,jj,jk) - vn_td(ji,jj-1,jk) )
             END_2D
          END DO
-         CALL lbc_lnk('sshwzv', zhdiv, 'T', 1.0_wp)  ! - ML - Perhaps not necessary: not used for horizontal "connexions"
+         IF (nn_hls==1) CALL lbc_lnk('sshwzv', zhdiv, 'T', 1.0_wp)  ! - ML - Perhaps not necessary: not used for horizontal "connexions"
          !                             ! Is it problematic to have a wrong vertical velocity in boundary cells?
          !                             ! Same question holds for hdiv. Perhaps just for security
-         DO jk = jpkm1, 1, -1                       ! integrate from the bottom the hor. divergence
+         DO_3DS( 1, 1, 1, 1, jpkm1, 1, -1 )         ! integrate from the bottom the hor. divergence
             ! computation of w
-            pww(:,:,jk) = pww(:,:,jk+1) - (   e3t(:,:,jk,Kmm) * hdiv(:,:,jk)   &
-               &                            +                  zhdiv(:,:,jk)   &
-               &                            + r1_Dt * (  e3t(:,:,jk,Kaa)       &
-               &                                       - e3t(:,:,jk,Kbb) )   ) * tmask(:,:,jk)
-         END DO
+            pww(ji,jj,jk) = pww(ji,jj,jk+1) - (   e3t(ji,jj,jk,Kmm) * hdiv(ji,jj,jk)   &
+               &                                  +                  zhdiv(ji,jj,jk)   &
+               &                                  + r1_Dt * (  e3t(ji,jj,jk,Kaa)       &
+               &                                             - e3t(ji,jj,jk,Kbb) )   ) * tmask(ji,jj,jk)
+         END_3D
          !          IF( ln_vvl_layer ) pww(:,:,:) = 0.e0
          DEALLOCATE( zhdiv ) 
@@ -197,15 +201,15 @@
       ELSEIF( ln_linssh )   THEN                      !==  linear free surface cases  ==!
          !                                            !=================================!
-         DO jk = jpkm1, 1, -1                               ! integrate from the bottom the hor. divergence
-            pww(:,:,jk) = pww(:,:,jk+1) - (  e3t(:,:,jk,Kmm) * hdiv(:,:,jk)  ) * tmask(:,:,jk)
-         END DO
+         DO_3DS( 1, 1, 1, 1, jpkm1, 1, -1 )                 ! integrate from the bottom the hor. divergence
+            pww(ji,jj,jk) = pww(ji,jj,jk+1) - (  e3t(ji,jj,jk,Kmm) * hdiv(ji,jj,jk)  ) * tmask(ji,jj,jk)
+         END_3D
          !                                            !==========================================!
       ELSE                                            !==  Quasi-Eulerian vertical coordinate  ==!   ('key_qco')
          !                                            !==========================================!
-         DO jk = jpkm1, 1, -1                               ! integrate from the bottom the hor. divergence
-            pww(:,:,jk) = pww(:,:,jk+1) - (  e3t(:,:,jk,Kmm) * hdiv(:,:,jk)                 &
-               &                            + r1_Dt * (  e3t(:,:,jk,Kaa)        &
-               &                                       - e3t(:,:,jk,Kbb)  )   ) * tmask(:,:,jk)
-         END DO
+         DO_3DS( 1, 1, 1, 1, jpkm1, 1, -1 )                 ! integrate from the bottom the hor. divergence
+            pww(ji,jj,jk) = pww(ji,jj,jk+1) - (  e3t(ji,jj,jk,Kmm) * hdiv(ji,jj,jk)    &
+               &                                 + r1_Dt * (  e3t(ji,jj,jk,Kaa)        &
+               &                                            - e3t(ji,jj,jk,Kbb)  )   ) * tmask(ji,jj,jk)
+         END_3D
       ENDIF
 
@@ -357,5 +361,5 @@
       zdt = 2._wp * rn_Dt                            ! 2*rn_Dt and not rDt (for restartability)
       IF( ln_vvl_ztilde .OR. ln_vvl_layer ) THEN
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpkm1 )
             z1_e3t = 1._wp / e3t(ji,jj,jk,Kmm)
             Cu_adv(ji,jj,jk) =   zdt *                                                         &
@@ -374,5 +378,5 @@
          END_3D
       ELSE
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpkm1 )
             z1_e3t = 1._wp / e3t(ji,jj,jk,Kmm)
             Cu_adv(ji,jj,jk) =   zdt *                                                      &
@@ -387,10 +391,10 @@
          END_3D
       ENDIF
-      CALL lbc_lnk( 'sshwzv', Cu_adv, 'T', 1.0_wp )
+      IF (nn_hls==1) CALL lbc_lnk( 'sshwzv', Cu_adv, 'T', 1.0_wp )
       !
       CALL iom_put("Courant",Cu_adv)
       !
       IF( MAXVAL( Cu_adv(:,:,:) ) > Cu_min ) THEN       ! Quick check if any breaches anywhere
-         DO_3DS( 1, 1, 1, 1, jpkm1, 2, -1 )             ! or scan Courant criterion and partition ! w where necessary
+         DO_3DS( nn_hls, nn_hls, nn_hls, nn_hls, jpkm1, 2, -1 )             ! or scan Courant criterion and partition ! w where necessary
             !
             zCu = MAX( Cu_adv(ji,jj,jk) , Cu_adv(ji,jj,jk-1) )
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/wet_dry.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/wet_dry.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/DYN/wet_dry.F90	(revision 14852)
@@ -117,4 +117,6 @@
          IF( ierr /= 0 ) CALL ctl_stop('STOP', 'wad_init : Array allocation error')
       ENDIF
+
+      IF( ln_tile .AND. ln_wd_il ) CALL ctl_warn('Tiling has not been tested with ln_wd_il = T')
       !
    END SUBROUTINE wad_init
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ICB/icbdia.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ICB/icbdia.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ICB/icbdia.F90	(revision 14852)
@@ -491,10 +491,10 @@
    SUBROUTINE icb_dia_melt(ki, kj, pmnew, pheat_hcflux, pheat_latent, pmass_scale,     &
       &                    pdM, pdMbitsE, pdMbitsM, pdMb, pdMe,   &
-      &                    pdMv, pz1_dt_e1e2 )
+      &                    pdMv, pz1_dt_e1e2, pz1_e1e2 )
       !!----------------------------------------------------------------------
       !!----------------------------------------------------------------------
       INTEGER , INTENT(in) ::   ki, kj
       REAL(wp), INTENT(in) ::   pmnew, pheat_hcflux, pheat_latent, pmass_scale
-      REAL(wp), INTENT(in) ::   pdM, pdMbitsE, pdMbitsM, pdMb, pdMe, pdMv, pz1_dt_e1e2
+      REAL(wp), INTENT(in) ::   pdM, pdMbitsE, pdMbitsM, pdMb, pdMe, pdMv, pz1_dt_e1e2, pz1_e1e2
       !!----------------------------------------------------------------------
       !
@@ -502,6 +502,6 @@
       !
       berg_melt (ki,kj) = berg_melt (ki,kj) + pdM      * pz1_dt_e1e2   ! kg/m2/s
-      berg_melt_hcflx (ki,kj) = berg_melt_hcflx (ki,kj) + pheat_hcflux * pz1_dt_e1e2   ! J/m2/s
-      berg_melt_qlat (ki,kj) = berg_melt_qlat (ki,kj) + pheat_latent * pz1_dt_e1e2   ! J/m2/s
+      berg_melt_hcflx (ki,kj) = berg_melt_hcflx (ki,kj) + pheat_hcflux * pz1_e1e2   ! W/m2
+      berg_melt_qlat (ki,kj) = berg_melt_qlat (ki,kj) + pheat_latent * pz1_e1e2   ! W/m2
       bits_src  (ki,kj) = bits_src  (ki,kj) + pdMbitsE * pz1_dt_e1e2   ! mass flux into bergy bitskg/m2/s
       bits_melt (ki,kj) = bits_melt (ki,kj) + pdMbitsM * pz1_dt_e1e2   ! melt rate of bergy bits kg/m2/s
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ICB/icbthm.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ICB/icbthm.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ICB/icbthm.F90	(revision 14852)
@@ -241,5 +241,5 @@
             CALL icb_dia_melt( ii, ij, zMnew, zheat_hcflux, zheat_latent, this%mass_scaling,       &
                &                       zdM, zdMbitsE, zdMbitsM, zdMb, zdMe,   &
-               &                       zdMv, z1_dt_e1e2 )
+               &                       zdMv, z1_dt_e1e2, z1_e1e2 )
          ELSE
             WRITE(numout,*) 'icb_thm: berg ',this%number(:),' appears to have grounded  at ',narea,ii,ij
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/IOM/iom.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/IOM/iom.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/IOM/iom.F90	(revision 14852)
@@ -2026,5 +2026,9 @@
       IF( iom_use(cdname) ) THEN
 #if defined key_xios
-         CALL xios_send_field( cdname, pfield2d )
+         IF( is_tile(pfield2d) == 1 ) THEN
+            CALL xios_send_field( cdname, pfield2d, ntile - 1 )
+         ELSE IF( .NOT. l_istiled .OR. ntile == nijtile ) THEN
+            CALL xios_send_field( cdname, pfield2d )
+         ENDIF
 #else
          WRITE(numout,*) pfield2d   ! iom_use(cdname) = .F. -> useless test to avoid compilation warnings
@@ -2038,5 +2042,9 @@
       IF( iom_use(cdname) ) THEN
 #if defined key_xios
-         CALL xios_send_field( cdname, pfield2d )
+         IF( is_tile(pfield2d) == 1 ) THEN
+            CALL xios_send_field( cdname, pfield2d, ntile - 1 )
+         ELSE IF( .NOT. l_istiled .OR. ntile == nijtile ) THEN
+            CALL xios_send_field( cdname, pfield2d )
+         ENDIF
 #else
          WRITE(numout,*) pfield2d   ! iom_use(cdname) = .F. -> useless test to avoid compilation warnings
@@ -2050,5 +2058,9 @@
       IF( iom_use(cdname) ) THEN
 #if defined key_xios
-         CALL xios_send_field( cdname, pfield3d )
+         IF( is_tile(pfield3d) == 1 ) THEN
+            CALL xios_send_field( cdname, pfield3d, ntile - 1 )
+         ELSE IF( .NOT. l_istiled .OR. ntile == nijtile ) THEN
+            CALL xios_send_field( cdname, pfield3d )
+         ENDIF
 #else
          WRITE(numout,*) pfield3d   ! iom_use(cdname) = .F. -> useless test to avoid compilation warnings
@@ -2062,5 +2074,9 @@
       IF( iom_use(cdname) ) THEN
 #if defined key_xios
-         CALL xios_send_field( cdname, pfield3d )
+         IF( is_tile(pfield3d) == 1 ) THEN
+            CALL xios_send_field( cdname, pfield3d, ntile - 1 )
+         ELSE IF( .NOT. l_istiled .OR. ntile == nijtile ) THEN
+            CALL xios_send_field( cdname, pfield3d )
+         ENDIF
 #else
          WRITE(numout,*) pfield3d   ! iom_use(cdname) = .F. -> useless test to avoid compilation warnings
@@ -2074,5 +2090,9 @@
       IF( iom_use(cdname) ) THEN
 #if defined key_xios
-         CALL xios_send_field (cdname, pfield4d )
+         IF( is_tile(pfield4d) == 1 ) THEN
+            CALL xios_send_field( cdname, pfield4d, ntile - 1 )
+         ELSE IF( .NOT. l_istiled .OR. ntile == nijtile ) THEN
+            CALL xios_send_field( cdname, pfield4d )
+         ENDIF
 #else
          WRITE(numout,*) pfield4d   ! iom_use(cdname) = .F. -> useless test to avoid compilation warnings
@@ -2086,5 +2106,9 @@
       IF( iom_use(cdname) ) THEN
 #if defined key_xios
-         CALL xios_send_field (cdname, pfield4d )
+         IF( is_tile(pfield4d) == 1 ) THEN
+            CALL xios_send_field( cdname, pfield4d, ntile - 1 )
+         ELSE IF( .NOT. l_istiled .OR. ntile == nijtile ) THEN
+            CALL xios_send_field( cdname, pfield4d )
+         ENDIF
 #else
          WRITE(numout,*) pfield4d   ! iom_use(cdname) = .F. -> useless test to avoid compilation warnings
@@ -2100,4 +2124,6 @@
    SUBROUTINE iom_set_domain_attr( cdid, ni_glo, nj_glo, ibegin, jbegin, ni, nj,                                               &
       &                                    data_dim, data_ibegin, data_ni, data_jbegin, data_nj, lonvalue, latvalue, mask,     &
+      &                                  ntiles, tile_ibegin, tile_jbegin, tile_ni, tile_nj,                                   &
+      &                                  tile_data_ibegin, tile_data_jbegin, tile_data_ni, tile_data_nj,                       &
       &                                    nvertex, bounds_lon, bounds_lat, area )
       !!----------------------------------------------------------------------
@@ -2105,6 +2131,8 @@
       CHARACTER(LEN=*)                  , INTENT(in) ::   cdid
       INTEGER                 , OPTIONAL, INTENT(in) ::   ni_glo, nj_glo, ibegin, jbegin, ni, nj
+      INTEGER,  DIMENSION(:)  , OPTIONAL, INTENT(in) ::   tile_ibegin, tile_jbegin, tile_ni, tile_nj
+      INTEGER,  DIMENSION(:)  , OPTIONAL, INTENT(in) ::   tile_data_ibegin, tile_data_jbegin, tile_data_ni, tile_data_nj
       INTEGER                 , OPTIONAL, INTENT(in) ::   data_dim, data_ibegin, data_ni, data_jbegin, data_nj
-      INTEGER                 , OPTIONAL, INTENT(in) ::   nvertex
+      INTEGER                 , OPTIONAL, INTENT(in) ::   nvertex, ntiles
       REAL(dp), DIMENSION(:)  , OPTIONAL, INTENT(in) ::   lonvalue, latvalue
       REAL(dp), DIMENSION(:,:), OPTIONAL, INTENT(in) ::   bounds_lon, bounds_lat, area
@@ -2115,4 +2143,7 @@
          CALL xios_set_domain_attr     ( cdid, ni_glo=ni_glo, nj_glo=nj_glo, ibegin=ibegin, jbegin=jbegin, ni=ni, nj=nj,   &
             &    data_dim=data_dim, data_ibegin=data_ibegin, data_ni=data_ni, data_jbegin=data_jbegin, data_nj=data_nj ,   &
+            &    ntiles=ntiles, tile_ibegin=tile_ibegin, tile_jbegin=tile_jbegin, tile_ni=tile_ni, tile_nj=tile_nj,        &
+            &    tile_data_ibegin=tile_data_ibegin, tile_data_jbegin=tile_data_jbegin,                                     &
+            &    tile_data_ni=tile_data_ni, tile_data_nj=tile_data_nj,                                                     &
             &    lonvalue_1D=lonvalue, latvalue_1D=latvalue, mask_1D=mask, nvertex=nvertex, bounds_lon_1D=bounds_lon,      &
             &    bounds_lat_1D=bounds_lat, area=area, type='curvilinear')
@@ -2121,4 +2152,7 @@
          CALL xios_set_domaingroup_attr( cdid, ni_glo=ni_glo, nj_glo=nj_glo, ibegin=ibegin, jbegin=jbegin, ni=ni, nj=nj,   &
             &    data_dim=data_dim, data_ibegin=data_ibegin, data_ni=data_ni, data_jbegin=data_jbegin, data_nj=data_nj ,   &
+            &    ntiles=ntiles, tile_ibegin=tile_ibegin, tile_jbegin=tile_jbegin, tile_ni=tile_ni, tile_nj=tile_nj,        &
+            &    tile_data_ibegin=tile_data_ibegin, tile_data_jbegin=tile_data_jbegin,                                     &
+            &    tile_data_ni=tile_data_ni, tile_data_nj=tile_data_nj,                                                     &
             &    lonvalue_1D=lonvalue, latvalue_1D=latvalue, mask_1D=mask, nvertex=nvertex, bounds_lon_1D=bounds_lon,      &
             &    bounds_lat_1D=bounds_lat, area=area, type='curvilinear' )
@@ -2288,4 +2322,6 @@
       !
       REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zmask
+      INTEGER :: jn
+      INTEGER, DIMENSION(nijtile) :: ini, inj, idb
       LOGICAL, INTENT(IN) :: ldxios, ldrxios
       !!----------------------------------------------------------------------
@@ -2293,4 +2329,20 @@
       CALL iom_set_domain_attr("grid_"//cdgrd, ni_glo=Ni0glo,nj_glo=Nj0glo,ibegin=mig0(Nis0)-1,jbegin=mjg0(Njs0)-1,ni=Ni_0,nj=Nj_0)
       CALL iom_set_domain_attr("grid_"//cdgrd, data_dim=2, data_ibegin = -nn_hls, data_ni=jpi, data_jbegin = -nn_hls, data_nj=jpj)
+
+      IF( ln_tile ) THEN
+         DO jn = 1, nijtile
+            ini(jn) = ntei_a(jn) - ntsi_a(jn) + 1     ! Tile size in i and j
+            inj(jn) = ntej_a(jn) - ntsj_a(jn) + 1
+            idb(jn) = -nn_hls                         ! Tile data offset (halo size)
+         END DO
+
+         ! Tile_[ij]begin are defined with respect to the processor data domain, so data_[ij]begin is added
+         CALL iom_set_domain_attr("grid_"//cdgrd, ntiles=nijtile,                                     &
+            & tile_ibegin=ntsi_a(1:nijtile) + idb(:) - 1, tile_jbegin=ntsj_a(1:nijtile) + idb(:) - 1, &
+            & tile_ni=ini(:), tile_nj=inj(:),                                                         &
+            & tile_data_ibegin=idb(:), tile_data_jbegin=idb(:),                                       &
+            & tile_data_ni=ini(:) - 2 * idb(:), tile_data_nj=inj(:) - 2 * idb(:))
+      ENDIF
+
 !don't define lon and lat for restart reading context.
       IF ( .NOT.ldrxios ) &
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/IOM/restart.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/IOM/restart.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/IOM/restart.F90	(revision 14852)
@@ -410,5 +410,5 @@
                ssh(:,:,Kbb) = -ssh_ref
                !
-               DO_2D( 1, 1, 1, 1 )
+               DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
                   IF( ht_0(ji,jj)-ssh_ref <  rn_wdmin1 ) THEN   ! if total depth is less than min depth
                      ssh(ji,jj,Kbb) = rn_wdmin1 - ht_0(ji,jj)
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ISF/isfhdiv.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ISF/isfhdiv.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ISF/isfhdiv.F90	(revision 14852)
@@ -52,5 +52,5 @@
          IF ( ln_isfpar_mlt ) CALL isf_hdiv_mlt(misfkt_par, misfkb_par, rhisf_tbl_par, rfrac_tbl_par, fwfisf_par, fwfisf_par_b, phdiv)
          !
-         ! ice sheet coupling contribution 
+         ! ice sheet coupling contribution
          IF ( ln_isfcpl .AND. kt /= 0 ) THEN
             !
@@ -91,5 +91,5 @@
       INTEGER  ::   ji, jj, jk   ! dummy loop indices
       INTEGER  ::   ikt, ikb 
-      REAL(wp), DIMENSION(jpi,jpj) :: zhdiv
+      REAL(wp), DIMENSION(A2D(nn_hls)) :: zhdiv
       !!----------------------------------------------------------------------
       !
@@ -97,8 +97,10 @@
       !
       ! compute integrated divergence correction
-      zhdiv(:,:) = 0.5_wp * ( pfwf(:,:) + pfwf_b(:,:) ) * r1_rho0 / phtbl(:,:)
+      DO_2D( nn_hls-1, nn_hls, nn_hls-1, nn_hls )
+         zhdiv(ji,jj) = 0.5_wp * ( pfwf(ji,jj) + pfwf_b(ji,jj) ) * r1_rho0 / phtbl(ji,jj)
+      END_2D
       !
       ! update divergence at each level affected by ice shelf top boundary layer
-      DO_2D( 1, 1, 1, 1 )
+      DO_2D_OVR( nn_hls-1, nn_hls, nn_hls-1, nn_hls )
          ikt = ktop(ji,jj)
          ikb = kbot(ji,jj)
@@ -131,11 +133,11 @@
       REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(in   ) :: pqvol
       !!----------------------------------------------------------------------
-      INTEGER :: jk
+      INTEGER :: ji, jj, jk
       !!----------------------------------------------------------------------
       !
-      DO jk=1,jpk 
-         phdiv(:,:,jk) =  phdiv(:,:,jk) + pqvol(:,:,jk) * r1_e1e2t(:,:)   &
-            &                             / e3t(:,:,jk,Kmm)
-      END DO
+      DO_3D_OVR( nn_hls-1, nn_hls, nn_hls-1, nn_hls, 1, jpk )
+         phdiv(ji,jj,jk) =  phdiv(ji,jj,jk) + pqvol(ji,jj,jk) * r1_e1e2t(ji,jj)   &
+            &                             / e3t(ji,jj,jk,Kmm)
+      END_3D
       !
    END SUBROUTINE isf_hdiv_cpl
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ISF/isftbl.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ISF/isftbl.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ISF/isftbl.F90	(revision 14852)
@@ -176,5 +176,5 @@
       !
       ! get htbl
-      DO_2D( 1, 1, 1, 1 )
+      DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
          !
          ! tbl top/bottom indices initialisation
@@ -193,5 +193,5 @@
       !
       ! get pfrac
-      DO_2D( 1, 1, 1, 1 )
+      DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
          !
          ! tbl top/bottom indices initialisation
@@ -227,5 +227,5 @@
       !
       ! get ktbl
-      DO_2D( 1, 1, 1, 1 )
+      DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
          !
          ! determine the deepest level influenced by the boundary layer
@@ -261,5 +261,5 @@
       ! test: this routine run with pdep = 0 should return 1
       !
-      DO_2D( 1, 1, 1, 1 )
+      DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
          ! comput ktop
          ikt = 2
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/LBC/lbc_lnk_neicoll_generic.h90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/LBC/lbc_lnk_neicoll_generic.h90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/LBC/lbc_lnk_neicoll_generic.h90	(revision 14852)
@@ -26,4 +26,5 @@
       INTEGER, DIMENSION(8)  ::   isizej, ishtSj, ishtRj, ishtPj
       INTEGER, DIMENSION(8)  ::   ifill, iszall
+      INTEGER, DIMENSION(8)  ::   jnf
       INTEGER, DIMENSION(:), ALLOCATABLE  ::   iScnt, iRcnt    ! number of elements to be sent/received
       INTEGER, DIMENSION(:), ALLOCATABLE  ::   iSdpl, iRdpl    ! displacement in halos arrays
@@ -192,28 +193,43 @@
       !
       idx = 1
+      ! MPI3 bug fix when domain decomposition has 2 columns/rows
+      IF (jpni .eq. 2) THEN
+         IF (jpnj .eq. 2) THEN
+            jnf(1:8) = (/ 2, 1, 4, 3, 8, 7, 6, 5 /)
+         ELSE
+            jnf(1:8) = (/ 2, 1, 3, 4, 6, 5, 8, 7 /)
+         ENDIF
+      ELSE
+         IF (jpnj .eq. 2) THEN
+            jnf(1:8) = (/ 1, 2, 4, 3, 7, 8, 5, 6 /)
+         ELSE
+            jnf(1:8) = (/ 1, 2, 3, 4, 5, 6, 7, 8 /)
+         ENDIF
+      ENDIF
+
       DO jn = 1, 8
-         ishti = ishtRi(jn)
-         ishtj = ishtRj(jn)
-         SELECT CASE ( ifill(jn) )
+         ishti = ishtRi(jnf(jn))
+         ishtj = ishtRj(jnf(jn))
+         SELECT CASE ( ifill(jnf(jn)) )
          CASE ( jpfillnothing )               ! no filling 
          CASE ( jpfillmpi   )                 ! fill with data received by MPI
-            DO jf = 1, ipf  ;  DO jl = 1, ipl  ;  DO jk = 1, ipk  ;  DO jj = 1,isizej(jn)  ;  DO ji = 1,isizei(jn)
+            DO jf = 1, ipf  ;  DO jl = 1, ipl  ;  DO jk = 1, ipk  ;  DO jj = 1,isizej(jnf(jn))  ;  DO ji = 1,isizei(jnf(jn))
                ptab(jf)%pt4d(ishti+ji,ishtj+jj,jk,jl) = BUFFRCV(idx)
                idx = idx + 1
             END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
          CASE ( jpfillperio )                 ! use periodicity
-            ishti2 = ishtPi(jn)
-            ishtj2 = ishtPj(jn)
-            DO jf = 1, ipf  ;  DO jl = 1, ipl  ;  DO jk = 1, ipk  ;  DO jj = 1,isizej(jn)  ;  DO ji = 1,isizei(jn)
+            ishti2 = ishtPi(jnf(jn))
+            ishtj2 = ishtPj(jnf(jn))
+            DO jf = 1, ipf  ;  DO jl = 1, ipl  ;  DO jk = 1, ipk  ;  DO jj = 1,isizej(jnf(jn))  ;  DO ji = 1,isizei(jnf(jn))
                ptab(jf)%pt4d(ishti+ji,ishtj+jj,jk,jl) = ptab(jf)%pt4d(ishti2+ji,ishtj2+jj,jk,jl)
             END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
          CASE ( jpfillcopy  )                 ! filling with inner domain values
-            ishti2 = ishtSi(jn)
-            ishtj2 = ishtSj(jn)
-            DO jf = 1, ipf  ;  DO jl = 1, ipl  ;  DO jk = 1, ipk  ;  DO jj = 1,isizej(jn)  ;  DO ji = 1,isizei(jn)
+            ishti2 = ishtSi(jnf(jn))
+            ishtj2 = ishtSj(jnf(jn))
+            DO jf = 1, ipf  ;  DO jl = 1, ipl  ;  DO jk = 1, ipk  ;  DO jj = 1,isizej(jnf(jn))  ;  DO ji = 1,isizei(jnf(jn))
                ptab(jf)%pt4d(ishti+ji,ishtj+jj,jk,jl) = ptab(jf)%pt4d(ishti2+ji,ishtj2+jj,jk,jl)
             END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
          CASE ( jpfillcst   )                 ! filling with constant value
-            DO jf = 1, ipf  ;  DO jl = 1, ipl  ;  DO jk = 1, ipk  ;  DO jj = 1,isizej(jn)  ;  DO ji = 1,isizei(jn)
+            DO jf = 1, ipf  ;  DO jl = 1, ipl  ;  DO jk = 1, ipk  ;  DO jj = 1,isizej(jnf(jn))  ;  DO ji = 1,isizei(jnf(jn))
                ptab(jf)%pt4d(ishti+ji,ishtj+jj,jk,jl) = zland
             END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/LBC/mppini.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/LBC/mppini.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/LBC/mppini.F90	(revision 14852)
@@ -632,8 +632,8 @@
       klci(1:iresti      ,:) = kimax
       klci(iresti+1:knbi ,:) = kimax-1
-      IF( MINVAL(klci) < 2*i2hls ) THEN
-         WRITE(ctmp1,*) '   mpp_basesplit: minimum value of jpi must be >= ', 2*i2hls
+      IF( MINVAL(klci) < 3*khls ) THEN
+         WRITE(ctmp1,*) '   mpp_basesplit: minimum value of jpi must be >= ', 3*khls
          WRITE(ctmp2,*) '   We have ', MINVAL(klci)
-        CALL ctl_stop( 'STOP', ctmp1, ctmp2 )
+         CALL ctl_stop( 'STOP', ctmp1, ctmp2 )
       ENDIF
       IF( l_NFold ) THEN
@@ -650,6 +650,6 @@
       ENDIF
       klcj(:,1:irestj) = kjmax
-      IF( MINVAL(klcj) < 2*i2hls ) THEN
-         WRITE(ctmp1,*) '   mpp_basesplit: minimum value of jpj must be >= ', 2*i2hls
+      IF( MINVAL(klcj) < 3*khls ) THEN
+         WRITE(ctmp1,*) '   mpp_basesplit: minimum value of jpj must be >= ', 3*khls
          WRITE(ctmp2,*) '   We have ', MINVAL(klcj)
          CALL ctl_stop( 'STOP', ctmp1, ctmp2 )
@@ -729,6 +729,6 @@
       iszjref = jpiglo*jpjglo+1
       !
-      iszimin = 4*nn_hls          ! minimum size of the MPI subdomain so halos are always adressing neighbor inner domain
-      iszjmin = 4*nn_hls
+      iszimin = 3*nn_hls          ! minimum size of the MPI subdomain so halos are always adressing neighbor inner domain
+      iszjmin = 3*nn_hls
       IF( c_NFtype == 'T' )   iszjmin = MAX(iszjmin, 2+3*nn_hls)   ! V and F folding must be outside of southern halos
       IF( c_NFtype == 'F' )   iszjmin = MAX(iszjmin, 1+3*nn_hls)   ! V and F folding must be outside of southern halos
@@ -760,4 +760,12 @@
          ENDIF
       END DO
+      IF( inbimax == 0 ) THEN
+         WRITE(ctmp1,'(a,i2,a,i2)') '   mpp_ini bestpartition: Ni0glo (', Ni0glo, ') is too small to be used with nn_hls = ', nn_hls
+         CALL ctl_stop( 'STOP', ctmp1 )
+      ENDIF
+      IF( inbjmax == 0 ) THEN
+         WRITE(ctmp1,'(a,i2,a,i2)') '   mpp_ini bestpartition: Nj0glo (', Nj0glo, ') is too small to be used with nn_hls = ', nn_hls
+         CALL ctl_stop( 'STOP', ctmp1 )
+      ENDIF
 
       ! combine these 2 lists to get all possible knbi*knbj <  inbijmax
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/LDF/ldfc1d_c2d.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/LDF/ldfc1d_c2d.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/LDF/ldfc1d_c2d.F90	(revision 14852)
@@ -135,5 +135,5 @@
       !
       CASE( 'DYN' )                       ! T- and F-points
-         DO_2D( 1, 1, 1, 1 )
+         DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
             pah1(ji,jj,1) = pUfac * MAX( e1t(ji,jj) , e2t(ji,jj) )**knn
             pah2(ji,jj,1) = pUfac * MAX( e1f(ji,jj) , e2f(ji,jj) )**knn
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/LDF/ldfslp.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/LDF/ldfslp.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/LDF/ldfslp.F90	(revision 14852)
@@ -371,5 +371,5 @@
          !
          ip = jl   ;   jp = jl                ! guaranteed nonzero gradients ( absolute value larger than repsln)
-         DO_3D( 1, 0, 1, 0, 1, jpkm1 )        ! done each pair of triad ! NB: not masked ==>  a minimum value is set
+         DO_3D( nn_hls, nn_hls-1, nn_hls, nn_hls-1, 1, jpkm1 )        ! done each pair of triad ! NB: not masked ==>  a minimum value is set
             zdit = ( ts(ji+1,jj,jk,jp_tem,Kbb) - ts(ji,jj,jk,jp_tem,Kbb) )    ! i-gradient of T & S at u-point
             zdis = ( ts(ji+1,jj,jk,jp_sal,Kbb) - ts(ji,jj,jk,jp_sal,Kbb) )
@@ -383,5 +383,5 @@
          !
          IF( ln_zps .AND. l_grad_zps ) THEN     ! partial steps: correction of i- & j-grad on bottom
-            DO_2D( 1, 0, 1, 0 )
+            DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )
                iku  = mbku(ji,jj)          ;   ikv  = mbkv(ji,jj)             ! last ocean level (u- & v-points)
                zdit = gtsu(ji,jj,jp_tem)   ;   zdjt = gtsv(ji,jj,jp_tem)      ! i- & j-gradient of Temperature
@@ -397,5 +397,5 @@
 
       DO kp = 0, 1                            !==  unmasked before density i- j-, k-gradients  ==!
-         DO_3D( 1, 1, 1, 1, 1, jpkm1 )        ! done each pair of triad ! NB: not masked ==>  a minimum value is set
+         DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpkm1 )      ! done each pair of triad ! NB: not masked ==>  a minimum value is set
             IF( jk+kp > 1 ) THEN              ! k-gradient of T & S a jk+kp
                zdkt = ( ts(ji,jj,jk+kp-1,jp_tem,Kbb) - ts(ji,jj,jk+kp,jp_tem,Kbb) )
@@ -412,5 +412,5 @@
       END DO
       !
-      DO_2D( 1, 1, 1, 1 )                     !==  Reciprocal depth of the w-point below ML base  ==!
+      DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )                   !== Reciprocal depth of the w-point below ML base  ==!
          jk = MIN( nmln(ji,jj), mbkt(ji,jj) ) + 1     ! MIN in case ML depth is the ocean depth
          z1_mlbw(ji,jj) = 1._wp / gdepw(ji,jj,jk,Kmm)
@@ -432,5 +432,5 @@
       DO jl = 0, 1                            ! calculate slope of the 4 triads immediately ONE level below mixed-layer base
          DO kp = 0, 1                         ! with only the slope-max limit   and   MASKED
-            DO_2D( 1, 0, 1, 0 )
+            DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )
                ip = jl   ;   jp = jl
                !
@@ -469,5 +469,5 @@
                ! Must mask contribution to slope from dz/dx at constant s for triads jk=1,kp=0 that poke up though ocean surface
                znot_thru_surface = REAL( 1-1/(jk+kp), wp )  !jk+kp=1,=0.; otherwise=1.0
-               DO_2D( 1, 0, 1, 0 )
+               DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )
                   !
                   ! Calculate slope relative to geopotentials used for GM skew fluxes
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/LDF/ldftra.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/LDF/ldftra.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/LDF/ldftra.F90	(revision 14852)
@@ -633,9 +633,9 @@
       INTEGER                         , INTENT(in   ) ::   kt             ! ocean time-step index
       INTEGER                         , INTENT(in   ) ::   Kmm            ! ocean time level indices
-      REAL(wp)                        , INTENT(inout) ::   paei0          ! max value            [m2/s]
+      REAL(wp)                        , INTENT(in   ) ::   paei0          ! max value            [m2/s]
       REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   paeiu, paeiv   ! eiv coefficient      [m2/s]
       !
       INTEGER  ::   ji, jj, jk    ! dummy loop indices
-      REAL(wp) ::   zfw, ze3w, zn2, z1_f20, zaht, zaht_min, zzaei    ! local scalars
+      REAL(wp) ::   zfw, ze3w, zn2, z1_f20, zzaei    ! local scalars
       REAL(wp), DIMENSION(jpi,jpj) ::   zn, zah, zhw, zRo, zaeiw   ! 2D workspace
       !!----------------------------------------------------------------------
@@ -647,5 +647,5 @@
       !                       ! Compute lateral diffusive coefficient at T-point
       IF( ln_traldf_triad ) THEN
-         DO_3D( 0, 0, 0, 0, 1, jpk )
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpk )
             ! Take the max of N^2 and zero then take the vertical sum
             ! of the square root of the resulting N^2 ( required to compute
@@ -661,5 +661,5 @@
          END_3D
       ELSE
-         DO_3D( 0, 0, 0, 0, 1, jpk )
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpk )
             ! Take the max of N^2 and zero then take the vertical sum
             ! of the square root of the resulting N^2 ( required to compute
@@ -677,5 +677,5 @@
       ENDIF
 
-      DO_2D( 0, 0, 0, 0 )
+      DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
          zfw = MAX( ABS( 2. * omega * SIN( rad * gphit(ji,jj) ) ) , 1.e-10 )
          ! Rossby radius at w-point taken betwenn 2 km and  40km
@@ -687,5 +687,5 @@
       !                                         !==  Bound on eiv coeff.  ==!
       z1_f20 = 1._wp / (  2._wp * omega * sin( rad * 20._wp )  )
-      DO_2D( 0, 0, 0, 0 )
+      DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
          zzaei = MIN( 1._wp, ABS( ff_t(ji,jj) * z1_f20 ) ) * zaeiw(ji,jj)     ! tropical decrease
          zaeiw(ji,jj) = MIN( zzaei , paei0 )                                  ! Max value = paei0
@@ -693,5 +693,5 @@
       CALL lbc_lnk( 'ldftra', zaeiw(:,:), 'W', 1.0_wp )       ! lateral boundary condition
       !
-      DO_2D( 0, 0, 0, 0 )                       !== aei at u- and v-points  ==!
+      DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
          paeiu(ji,jj,1) = 0.5_wp * ( zaeiw(ji,jj) + zaeiw(ji+1,jj  ) ) * umask(ji,jj,1)
          paeiv(ji,jj,1) = 0.5_wp * ( zaeiw(ji,jj) + zaeiw(ji  ,jj+1) ) * vmask(ji,jj,1)
@@ -729,7 +729,8 @@
       INTEGER                     , INTENT(in   ) ::   Kmm, Krhs ! ocean time level indices
       CHARACTER(len=3)            , INTENT(in   ) ::   cdtype    ! =TRA or TRC (tracer indicator)
-      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(inout) ::   pu        ! in : 3 ocean transport components   [m3/s]
-      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(inout) ::   pv        ! out: 3 ocean transport components   [m3/s]
-      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(inout) ::   pw        ! increased by the eiv                [m3/s]
+      ! TEMP: [tiling] 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(inout) ::   pu        ! in : 3 ocean transport components   [m3/s]
+      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   pv        ! out: 3 ocean transport components   [m3/s]
+      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   pw        ! increased by the eiv                [m3/s]
       !!
       INTEGER  ::   ji, jj, jk                 ! dummy loop indices
@@ -739,5 +740,5 @@
       !!----------------------------------------------------------------------
       !
-      IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+      IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
          IF( kt == kit000 )  THEN
             IF(lwp) WRITE(numout,*)
@@ -751,5 +752,5 @@
       zpsi_uw(:,:,jpk) = 0._wp   ;   zpsi_vw(:,:,jpk) = 0._wp
       !
-      DO_3D( 1, 0, 1, 0, 2, jpkm1 )
+      DO_3D( nn_hls, nn_hls-1, nn_hls, nn_hls-1, 2, jpkm1 )
          zpsi_uw(ji,jj,jk) = - r1_4 * e2u(ji,jj) * ( wslpi(ji,jj,jk  ) + wslpi(ji+1,jj,jk) )   &
             &                                    * ( aeiu (ji,jj,jk-1) + aeiu (ji  ,jj,jk) ) * wumask(ji,jj,jk)
@@ -758,11 +759,11 @@
       END_3D
       !
-      DO_3D( 1, 0, 1, 0, 1, jpkm1 )
+      DO_3D_OVR( nn_hls, nn_hls-1, nn_hls, nn_hls-1, 1, jpkm1 )
          pu(ji,jj,jk) = pu(ji,jj,jk) - ( zpsi_uw(ji,jj,jk) - zpsi_uw(ji,jj,jk+1) )
          pv(ji,jj,jk) = pv(ji,jj,jk) - ( zpsi_vw(ji,jj,jk) - zpsi_vw(ji,jj,jk+1) )
       END_3D
-      DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+      DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpkm1 )
          pw(ji,jj,jk) = pw(ji,jj,jk) + (  zpsi_uw(ji,jj,jk) - zpsi_uw(ji-1,jj  ,jk)   &
-            &                             + zpsi_vw(ji,jj,jk) - zpsi_vw(ji  ,jj-1,jk) )
+            &                           + zpsi_vw(ji,jj,jk) - zpsi_vw(ji  ,jj-1,jk) )
       END_3D
       !
@@ -783,6 +784,6 @@
       !!
       !!----------------------------------------------------------------------
-      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(inout) ::   psi_uw, psi_vw   ! streamfunction   [m3/s]
-      INTEGER                     , INTENT(in   ) ::   Kmm   ! ocean time level indices
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(in) ::   psi_uw, psi_vw   ! streamfunction   [m3/s]
+      INTEGER                             , INTENT(in) ::   Kmm              ! ocean time level indices
       !
       INTEGER  ::   ji, jj, jk    ! dummy loop indices
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/OBS/diaobs.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/OBS/diaobs.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/OBS/diaobs.F90	(revision 14852)
@@ -687,5 +687,5 @@
                   &               nit000, idaystp, jvar,                   &
                   &               zprofvar(:,:,:,jvar),                    &
-                  &               gdept(:,:,:,Kmm), gdepw(:,:,:,Kmm),      & 
+                  &               gdept(:,:,:,Kmm), gdepw(:,:,:,Kmm),      &
                   &               zprofmask(:,:,:,jvar),                   &
                   &               zglam(:,:,jvar), zgphi(:,:,jvar),        &
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/SBC/sbccpl.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/SBC/sbccpl.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/SBC/sbccpl.F90	(revision 14852)
@@ -1301,5 +1301,5 @@
          IF( llnewtau ) THEN
             zcoef = 1. / ( zrhoa * zcdrag )
-            DO_2D( 1, 1, 1, 1 )
+            DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
                frcv(jpr_w10m)%z3(ji,jj,1) = SQRT( frcv(jpr_taum)%z3(ji,jj,1) * zcoef )
             END_2D
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/SBC/sbcmod.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/SBC/sbcmod.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/SBC/sbcmod.F90	(revision 14852)
@@ -475,11 +475,13 @@
       END SELECT
 
-      IF( ln_icebergs    )   THEN
-                                     CALL icb_stp( kt, Kmm )           ! compute icebergs
-         ! Icebergs do not melt over the haloes.
-         ! So emp values over the haloes are no more consistent with the inner domain values.
-         ! A lbc_lnk is therefore needed to ensure reproducibility and restartability.
-         ! see ticket #2113 for discussion about this lbc_lnk.
-         IF( .NOT. ln_passive_mode ) CALL lbc_lnk( 'sbcmod', emp, 'T', 1.0_wp ) ! ensure restartability with icebergs
+      IF( ln_icebergs    )   CALL icb_stp( kt, Kmm )              ! compute icebergs
+
+      ! Icebergs do not melt over the haloes.
+      ! So emp values over the haloes are no more consistent with the inner domain values.
+      ! A lbc_lnk is therefore needed to ensure reproducibility and restartability.
+      ! see ticket #2113 for discussion about this lbc_lnk.
+      ! The lbc_lnk is also needed for SI3 with nn_hls > 1 as emp is not yet defined for these points in iceupdate.F90
+      IF( (ln_icebergs .AND. .NOT. ln_passive_mode) .OR. (nn_ice == 2 .AND. nn_hls == 2) ) THEN
+         CALL lbc_lnk( 'sbcmod', emp, 'T', 1.0_wp )
       ENDIF
 
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/SBC/sbcrnf.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/SBC/sbcrnf.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/SBC/sbcrnf.F90	(revision 14852)
@@ -211,5 +211,5 @@
       IF( ln_rnf_depth .OR. ln_rnf_depth_ini ) THEN      !==   runoff distributed over several levels   ==!
          IF( ln_linssh ) THEN    !* constant volume case : just apply the runoff input flow
-            DO_2D( 1, 1, 1, 1 )
+            DO_2D_OVR( nn_hls-1, nn_hls, nn_hls-1, nn_hls )
                DO jk = 1, nk_rnf(ji,jj)
                   phdivn(ji,jj,jk) = phdivn(ji,jj,jk) - ( rnf(ji,jj) + rnf_b(ji,jj) ) * zfact * r1_rho0 / h_rnf(ji,jj)
@@ -217,5 +217,5 @@
             END_2D
          ELSE                    !* variable volume case
-            DO_2D( 1, 1, 1, 1 )              ! update the depth over which runoffs are distributed
+            DO_2D_OVR( nn_hls, nn_hls, nn_hls, nn_hls )         ! update the depth over which runoffs are distributed
                h_rnf(ji,jj) = 0._wp
                DO jk = 1, nk_rnf(ji,jj)                             ! recalculates h_rnf to be the depth in metres
@@ -229,6 +229,8 @@
          ENDIF
       ELSE                       !==   runoff put only at the surface   ==!
-         h_rnf (:,:)   = e3t (:,:,1,Kmm)        ! update h_rnf to be depth of top box
-         phdivn(:,:,1) = phdivn(:,:,1) - ( rnf(:,:) + rnf_b(:,:) ) * zfact * r1_rho0 / e3t(:,:,1,Kmm)
+         DO_2D_OVR( nn_hls, nn_hls, nn_hls, nn_hls )
+            h_rnf (ji,jj)   = e3t (ji,jj,1,Kmm)        ! update h_rnf to be depth of top box
+            phdivn(ji,jj,1) = phdivn(ji,jj,1) - ( rnf(ji,jj) + rnf_b(ji,jj) ) * zfact * r1_rho0 / e3t(ji,jj,1,Kmm)
+         END_2D
       ENDIF
       !
@@ -363,5 +365,5 @@
          !
          nk_rnf(:,:) = 0                               ! set the number of level over which river runoffs are applied
-         DO_2D( 1, 1, 1, 1 )
+         DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
             IF( h_rnf(ji,jj) > 0._wp ) THEN
                jk = 2
@@ -376,5 +378,5 @@
             ENDIF
          END_2D
-         DO_2D( 1, 1, 1, 1 )                           ! set the associated depth
+         DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )                           ! set the associated depth
             h_rnf(ji,jj) = 0._wp
             DO jk = 1, nk_rnf(ji,jj)
@@ -406,5 +408,5 @@
          WHERE( zrnfcl(:,:,1) > 0._wp )  h_rnf(:,:) = zacoef * zrnfcl(:,:,1)   ! compute depth for all runoffs
          !
-         DO_2D( 1, 1, 1, 1 )                ! take in account min depth of ocean rn_hmin
+         DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )                ! take in account min depth of ocean rn_hmin
             IF( zrnfcl(ji,jj,1) > 0._wp ) THEN
                jk = mbkt(ji,jj)
@@ -414,5 +416,5 @@
          !
          nk_rnf(:,:) = 0                       ! number of levels on which runoffs are distributed
-         DO_2D( 1, 1, 1, 1 )
+         DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
             IF( zrnfcl(ji,jj,1) > 0._wp ) THEN
                jk = 2
@@ -425,5 +427,5 @@
          END_2D
          !
-         DO_2D( 1, 1, 1, 1 )                          ! set the associated depth
+         DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )                          ! set the associated depth
             h_rnf(ji,jj) = 0._wp
             DO jk = 1, nk_rnf(ji,jj)
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/SBC/sbcssr.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/SBC/sbcssr.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/SBC/sbcssr.F90	(revision 14852)
@@ -98,5 +98,5 @@
             !
             IF( nn_sstr == 1 ) THEN                                   !* Temperature restoring term
-               DO_2D( 1, 1, 1, 1 )
+               DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
                   zqrp = rn_dqdt * ( sst_m(ji,jj) - sf_sst(1)%fnow(ji,jj,1) ) * tmask(ji,jj,1)
                   qns(ji,jj) = qns(ji,jj) + zqrp
@@ -108,5 +108,5 @@
               ! use fraction of ice ( fr_i ) to adjust relaxation under ice if nn_sssr_ice .ne. 1
               ! n.b. coefice is initialised and fixed to 1._wp if nn_sssr_ice = 1
-               DO_2D( 1, 1, 1, 1 )
+               DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
                   SELECT CASE ( nn_sssr_ice )
                     CASE ( 0 )    ;  coefice(ji,jj) = 1._wp - fr_i(ji,jj)              ! no/reduced damping under ice
@@ -118,5 +118,5 @@
             IF( nn_sssr == 1 ) THEN                                   !* Salinity damping term (salt flux only (sfx))
                zsrp = rn_deds / rday                                  ! from [mm/day] to [kg/m2/s]
-               DO_2D( 1, 1, 1, 1 )
+               DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
                   zerp = zsrp * ( 1. - 2.*rnfmsk(ji,jj) )   &      ! No damping in vicinity of river mouths
                      &        *   coefice(ji,jj)            &      ! Optional control of damping under sea-ice
@@ -129,5 +129,5 @@
                zsrp = rn_deds / rday                                  ! from [mm/day] to [kg/m2/s]
                zerp_bnd = rn_sssr_bnd / rday                          !       -              -    
-               DO_2D( 1, 1, 1, 1 )
+               DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
                   zerp = zsrp * ( 1. - 2.*rnfmsk(ji,jj) )   &      ! No damping in vicinity of river mouths
                      &        *   coefice(ji,jj)            &      ! Optional control of damping under sea-ice
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/eosbn2.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/eosbn2.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/eosbn2.F90	(revision 14852)
@@ -577,4 +577,14 @@
 
    SUBROUTINE eos_insitu_pot_2d( pts, prhop )
+      !!
+      REAL(wp), DIMENSION(:,:,:), INTENT(in   ) ::   pts    ! 1 : potential temperature  [Celsius]
+      !                                                     ! 2 : salinity               [psu]
+      REAL(wp), DIMENSION(:,:)  , INTENT(  out) ::   prhop  ! potential density (surface referenced)
+      !!
+      CALL eos_insitu_pot_2d_t( pts, is_tile(pts), prhop, is_tile(prhop) )
+   END SUBROUTINE eos_insitu_pot_2d
+
+
+   SUBROUTINE eos_insitu_pot_2d_t( pts, ktts, prhop, ktrhop )
       !!----------------------------------------------------------------------
       !!                  ***  ROUTINE eos_insitu_pot  ***
@@ -589,7 +599,8 @@
       !!
       !!----------------------------------------------------------------------
-      REAL(wp), DIMENSION(jpi,jpj,jpts), INTENT(in   ) ::   pts    ! 1 : potential temperature  [Celsius]
+      INTEGER                              , INTENT(in   ) ::   ktts, ktrhop
+      REAL(wp), DIMENSION(A2D_T(ktts),JPTS), INTENT(in   ) ::   pts    ! 1 : potential temperature  [Celsius]
       !                                                                ! 2 : salinity               [psu]
-      REAL(wp), DIMENSION(jpi,jpj     ), INTENT(  out) ::   prhop  ! potential density (surface referenced)
+      REAL(wp), DIMENSION(A2D_T(ktrhop)   ), INTENT(  out) ::   prhop  ! potential density (surface referenced)
       !
       INTEGER  ::   ji, jj, jk, jsmp             ! dummy loop indices
@@ -606,26 +617,26 @@
       CASE( np_teos10, np_eos80 )                !==  polynomial TEOS-10 / EOS-80 ==!
          !
-            DO_2D( 1, 1, 1, 1 )
-               !
-               zt  = pts (ji,jj,jp_tem) * r1_T0                           ! temperature
-               zs  = SQRT( ABS( pts(ji,jj,jp_sal) + rdeltaS ) * r1_S0 )   ! square root salinity
-               ztm = tmask(ji,jj,1)                                         ! tmask
-               !
-               zn0 = (((((EOS060*zt   &
-                  &   + EOS150*zs+EOS050)*zt   &
-                  &   + (EOS240*zs+EOS140)*zs+EOS040)*zt   &
-                  &   + ((EOS330*zs+EOS230)*zs+EOS130)*zs+EOS030)*zt   &
-                  &   + (((EOS420*zs+EOS320)*zs+EOS220)*zs+EOS120)*zs+EOS020)*zt   &
-                  &   + ((((EOS510*zs+EOS410)*zs+EOS310)*zs+EOS210)*zs+EOS110)*zs+EOS010)*zt   &
-                  &   + (((((EOS600*zs+EOS500)*zs+EOS400)*zs+EOS300)*zs+EOS200)*zs+EOS100)*zs+EOS000
-                  !
-               !
-               prhop(ji,jj) = zn0 * ztm                           ! potential density referenced at the surface
-               !
-            END_2D
+         DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
+            !
+            zt  = pts (ji,jj,jp_tem) * r1_T0                           ! temperature
+            zs  = SQRT( ABS( pts(ji,jj,jp_sal) + rdeltaS ) * r1_S0 )   ! square root salinity
+            ztm = tmask(ji,jj,1)                                         ! tmask
+            !
+            zn0 = (((((EOS060*zt   &
+               &   + EOS150*zs+EOS050)*zt   &
+               &   + (EOS240*zs+EOS140)*zs+EOS040)*zt   &
+               &   + ((EOS330*zs+EOS230)*zs+EOS130)*zs+EOS030)*zt   &
+               &   + (((EOS420*zs+EOS320)*zs+EOS220)*zs+EOS120)*zs+EOS020)*zt   &
+               &   + ((((EOS510*zs+EOS410)*zs+EOS310)*zs+EOS210)*zs+EOS110)*zs+EOS010)*zt   &
+               &   + (((((EOS600*zs+EOS500)*zs+EOS400)*zs+EOS300)*zs+EOS200)*zs+EOS100)*zs+EOS000
+               !
+            !
+            prhop(ji,jj) = zn0 * ztm                           ! potential density referenced at the surface
+            !
+         END_2D
 
       CASE( np_seos )                !==  simplified EOS  ==!
          !
-         DO_2D( 1, 1, 1, 1 )
+         DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
             zt  = pts  (ji,jj,jp_tem) - 10._wp
             zs  = pts  (ji,jj,jp_sal) - 35._wp
@@ -646,5 +657,5 @@
       IF( ln_timing )   CALL timing_stop('eos-pot')
       !
-   END SUBROUTINE eos_insitu_pot_2d
+   END SUBROUTINE eos_insitu_pot_2d_t
 
 
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv.F90	(revision 14852)
@@ -18,5 +18,5 @@
    USE oce            ! ocean dynamics and active tracers
    USE dom_oce        ! ocean space and time domain
-   ! TEMP: [tiling] This change not necessary after extended haloes development
+   ! TEMP: [tiling] This change not necessary after all lbc_lnks removed in the nn_hls = 2 case in tra_adv_fct
    USE domtile
    USE domvvl         ! variable vertical scale factors
@@ -25,7 +25,5 @@
    USE traadv_cen     ! centered scheme            (tra_adv_cen  routine)
    USE traadv_fct     ! FCT      scheme            (tra_adv_fct  routine)
-   USE traadv_fct_lf  ! FCT      scheme            (tra_adv_fct  routine - loop fusion version)
    USE traadv_mus     ! MUSCL    scheme            (tra_adv_mus  routine)
-   USE traadv_mus_lf  ! MUSCL    scheme            (tra_adv_mus  routine - loop fusion version)
    USE traadv_ubs     ! UBS      scheme            (tra_adv_ubs  routine)
    USE traadv_qck     ! QUICKEST scheme            (tra_adv_qck  routine)
@@ -61,12 +59,12 @@
    LOGICAL ::   ln_traadv_qck    ! QUICKEST scheme flag
 
-   INTEGER ::   nadv             ! choice of the type of advection scheme
+   INTEGER, PUBLIC ::   nadv             ! choice of the type of advection scheme
    !                             ! associated indices:
-   INTEGER, PARAMETER ::   np_NO_adv  = 0   ! no T-S advection
-   INTEGER, PARAMETER ::   np_CEN     = 1   ! 2nd/4th order centered scheme
-   INTEGER, PARAMETER ::   np_FCT     = 2   ! 2nd/4th order Flux Corrected Transport scheme
-   INTEGER, PARAMETER ::   np_MUS     = 3   ! MUSCL scheme
-   INTEGER, PARAMETER ::   np_UBS     = 4   ! 3rd order Upstream Biased Scheme
-   INTEGER, PARAMETER ::   np_QCK     = 5   ! QUICK scheme
+   INTEGER, PARAMETER, PUBLIC ::   np_NO_adv  = 0   ! no T-S advection
+   INTEGER, PARAMETER, PUBLIC ::   np_CEN     = 1   ! 2nd/4th order centered scheme
+   INTEGER, PARAMETER, PUBLIC ::   np_FCT     = 2   ! 2nd/4th order Flux Corrected Transport scheme
+   INTEGER, PARAMETER, PUBLIC ::   np_MUS     = 3   ! MUSCL scheme
+   INTEGER, PARAMETER, PUBLIC ::   np_UBS     = 4   ! 3rd order Upstream Biased Scheme
+   INTEGER, PARAMETER, PUBLIC ::   np_QCK     = 5   ! QUICK scheme
 
    !! * Substitutions
@@ -93,8 +91,8 @@
       !
       INTEGER ::   ji, jj, jk   ! dummy loop index
-      ! TEMP: [tiling] This change not necessary and can be A2D(nn_hls) if using XIOS (subdomain support)
+      ! TEMP: [tiling] This change not necessary and can be A2D(nn_hls) after all lbc_lnks removed in the nn_hls = 2 case in tra_adv_fct
       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE, SAVE :: zuu, zvv, zww   ! 3D workspace
       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: ztrdt, ztrds
-      ! TEMP: [tiling] This change not necessary after extra haloes development
+      ! TEMP: [tiling] This change not necessary after all lbc_lnks removed in the nn_hls = 2 case in tra_adv_fct
       LOGICAL :: lskip
       !!----------------------------------------------------------------------
@@ -104,17 +102,15 @@
       lskip = .FALSE.
 
-      ! TEMP: [tiling] These changes not necessary if using XIOS (subdomain support)
-      IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+      ! TEMP: [tiling] These changes not necessary after all lbc_lnks removed in the nn_hls = 2 case in tra_adv_fct
+      IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
          ALLOCATE( zuu(jpi,jpj,jpk), zvv(jpi,jpj,jpk), zww(jpi,jpj,jpk) )
       ENDIF
 
-      ! TEMP: [tiling] These changes not necessary after extra haloes development (lbc_lnk removed from tra_adv_*) and if XIOS has subdomain support (ldf_eiv_dia)
-      IF( nadv /= np_CEN .OR. (nadv == np_CEN .AND. nn_cen_h == 4) .OR. ln_ldfeiv_dia )  THEN
-         IF( ln_tile ) THEN
-            IF( ntile == 1 ) THEN
-               CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = 0 )
-            ELSE
-               lskip = .TRUE.
-            ENDIF
+      ! TEMP: [tiling] These changes not necessary after all lbc_lnks removed in the nn_hls = 2 case in tra_adv_fct
+      IF( ln_tile .AND. nadv == np_FCT )  THEN
+         IF( ntile == 1 ) THEN
+            CALL dom_tile_stop( ldhold=.TRUE. )
+         ELSE
+            lskip = .TRUE.
          ENDIF
       ENDIF
@@ -122,5 +118,5 @@
          !                                         !==  effective transport  ==!
          IF( ln_wave .AND. ln_sdw )  THEN
-            DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpkm1 )
+            DO_3D_OVR( nn_hls, nn_hls-1, nn_hls, nn_hls-1, 1, jpkm1 )
                zuu(ji,jj,jk) = e2u  (ji,jj) * e3u(ji,jj,jk,Kmm) * ( uu(ji,jj,jk,Kmm) + usd(ji,jj,jk) )
                zvv(ji,jj,jk) = e1v  (ji,jj) * e3v(ji,jj,jk,Kmm) * ( vv(ji,jj,jk,Kmm) + vsd(ji,jj,jk) )
@@ -128,5 +124,5 @@
             END_3D
          ELSE
-            DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpkm1 )
+            DO_3D_OVR( nn_hls, nn_hls-1, nn_hls, nn_hls-1, 1, jpkm1 )
                zuu(ji,jj,jk) = e2u  (ji,jj) * e3u(ji,jj,jk,Kmm) * uu(ji,jj,jk,Kmm)               ! eulerian transport only
                zvv(ji,jj,jk) = e1v  (ji,jj) * e3v(ji,jj,jk,Kmm) * vv(ji,jj,jk,Kmm)
@@ -136,5 +132,5 @@
          !
          IF( ln_vvl_ztilde .OR. ln_vvl_layer ) THEN                                ! add z-tilde and/or vvl corrections
-            DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpkm1 )
+            DO_3D_OVR( nn_hls, nn_hls-1, nn_hls, nn_hls-1, 1, jpkm1 )
                zuu(ji,jj,jk) = zuu(ji,jj,jk) + un_td(ji,jj,jk)
                zvv(ji,jj,jk) = zvv(ji,jj,jk) + vn_td(ji,jj,jk)
@@ -142,5 +138,5 @@
          ENDIF
          !
-         DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
+         DO_2D_OVR( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )
             zuu(ji,jj,jpk) = 0._wp                                                      ! no transport trough the bottom
             zvv(ji,jj,jpk) = 0._wp
@@ -148,14 +144,11 @@
          END_2D
          !
-         ! TEMP: [tiling] These changes not necessary if using XIOS (subdomain support)
          IF( ln_ldfeiv .AND. .NOT. ln_traldf_triad )   &
-            &              CALL ldf_eiv_trp( kt, nit000, zuu(A2D(nn_hls),:), zvv(A2D(nn_hls),:), zww(A2D(nn_hls),:), &
-            &                                'TRA', Kmm, Krhs )   ! add the eiv transport (if necessary)
-         !
-         IF( ln_mle    )   CALL tra_mle_trp( kt, nit000, zuu(A2D(nn_hls),:), zvv(A2D(nn_hls),:), zww(A2D(nn_hls),:), &
-            &                                'TRA', Kmm       )   ! add the mle transport (if necessary)
-         !
-         ! TEMP: [tiling] This change not necessary if using XIOS (subdomain support)
-         IF( ntile == 0 .OR. ntile == nijtile )  THEN                ! Do only on the last tile
+            &              CALL ldf_eiv_trp( kt, nit000, zuu, zvv, zww, 'TRA', Kmm, Krhs )   ! add the eiv transport (if necessary)
+         !
+         IF( ln_mle    )   CALL tra_mle_trp( kt, nit000, zuu, zvv, zww, 'TRA', Kmm       )   ! add the mle transport (if necessary)
+         !
+         ! TEMP: [tiling] This change not necessary after all lbc_lnks removed in the nn_hls = 2 case in tra_adv_fct
+         IF( .NOT. l_istiled .OR. ntile == nijtile )  THEN                ! Do only on the last tile
             CALL iom_put( "uocetr_eff", zuu )                                        ! output effective transport
             CALL iom_put( "vocetr_eff", zvv )
@@ -163,8 +156,8 @@
          ENDIF
          !
-   !!gm ???
-         ! TEMP: [tiling] This change not necessary if using XIOS (subdomain support)
+!!gm ???
+         ! TEMP: [tiling] This copy-in not necessary after all lbc_lnks removed in the nn_hls = 2 case in tra_adv_fct
          CALL dia_ptr( kt, Kmm, zvv(A2D(nn_hls),:) )                                    ! diagnose the effective MSF
-   !!gm ???
+!!gm ???
          !
 
@@ -178,37 +171,12 @@
          !
          CASE ( np_CEN )                                 ! Centered scheme : 2nd / 4th order
-            IF (nn_hls.EQ.2) CALL lbc_lnk( 'traadv', pts(:,:,:,:,Kmm), 'T', 1. )
             CALL tra_adv_cen    ( kt, nit000, 'TRA',         zuu, zvv, zww, Kmm, pts, jpts, Krhs, nn_cen_h, nn_cen_v )
          CASE ( np_FCT )                                 ! FCT scheme      : 2nd / 4th order
-            IF (nn_hls.EQ.2) THEN
-               CALL lbc_lnk( 'traadv', pts(:,:,:,:,Kbb), 'T', 1., pts(:,:,:,:,Kmm), 'T', 1.)
-               CALL lbc_lnk( 'traadv', zuu(:,:,:), 'U', -1., zvv(:,:,:), 'V', -1., zww(:,:,:), 'W', 1.)
-#if defined key_loop_fusion
-               CALL tra_adv_fct_lf ( kt, nit000, 'TRA', rDt, zuu, zvv, zww, Kbb, Kmm, pts, jpts, Krhs, nn_fct_h, nn_fct_v )
-#else
                CALL tra_adv_fct    ( kt, nit000, 'TRA', rDt, zuu, zvv, zww, Kbb, Kmm, pts, jpts, Krhs, nn_fct_h, nn_fct_v )
-#endif
-            ELSE
-               CALL tra_adv_fct    ( kt, nit000, 'TRA', rDt, zuu, zvv, zww, Kbb, Kmm, pts, jpts, Krhs, nn_fct_h, nn_fct_v )
-            END IF
          CASE ( np_MUS )                                 ! MUSCL
-            IF (nn_hls.EQ.2) THEN
-                CALL lbc_lnk( 'traadv', pts(:,:,:,:,Kbb), 'T', 1.)
-#if defined key_loop_fusion
-                CALL tra_adv_mus_lf ( 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 )
-#endif
-            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
-            IF (nn_hls.EQ.2) CALL lbc_lnk( 'traadv', pts(:,:,:,:,Kbb), 'T', 1.)
             CALL tra_adv_ubs    ( kt, nit000, 'TRA', rDt, zuu, zvv, zww, Kbb, Kmm, pts, jpts, Krhs, nn_ubs_v   )
          CASE ( np_QCK )                                 ! QUICKEST
-            IF (nn_hls.EQ.2) THEN
-               CALL lbc_lnk( 'traadv', zuu(:,:,:), 'U', -1., zvv(:,:,:), 'V', -1.)
-               CALL lbc_lnk( 'traadv', pts(:,:,:,:,Kbb), 'T', 1.)
-            END IF
             CALL tra_adv_qck    ( kt, nit000, 'TRA', rDt, zuu, zvv, zww, Kbb, Kmm, pts, jpts, Krhs )
          !
@@ -225,7 +193,6 @@
          ENDIF
 
-         ! TEMP: [tiling] This change not necessary after extra haloes development (lbc_lnk removed from tra_adv_*) and if XIOS has subdomain support (ldf_eiv_dia)
-         IF( ln_tile .AND. ntile == 0 ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = 1 )
-
+         ! TEMP: [tiling] This change not necessary after all lbc_lnks removed in the nn_hls = 2 case in tra_adv_fct
+         IF( ln_tile .AND. .NOT. l_istiled ) CALL dom_tile_start( ldhold=.TRUE. )
       ENDIF
       !                                              ! print mean trends (used for debugging)
@@ -233,6 +200,6 @@
          &                                  tab3d_2=pts(:,:,:,jp_sal,Krhs), clinfo2=       ' Sa: ', mask2=tmask, clinfo3='tra' )
 
-      ! TEMP: [tiling] This change not necessary if using XIOS (subdomain support)
-      IF( ntile == 0 .OR. ntile == nijtile )  THEN                ! Do only for the full domain
+      ! TEMP: [tiling] This change not necessary after all lbc_lnks removed in the nn_hls = 2 case in tra_adv_fct
+      IF( .NOT. l_istiled .OR. ntile == nijtile )  THEN                ! Do only for the full domain
          DEALLOCATE( zuu, zvv, zww )
       ENDIF
@@ -306,4 +273,8 @@
         CALL ctl_stop( 'tra_adv_init: FCT scheme, choose 2nd or 4th order' )
       ENDIF
+      ! TEMP: [tiling] This change not necessary after all lbc_lnks removed in the nn_hls = 2 case in tra_adv_fct
+      IF( ln_traadv_fct .AND. ln_tile ) THEN
+         CALL ctl_warn( 'tra_adv_init: FCT scheme does not yet work with tiling' )
+      ENDIF
       IF( ln_traadv_ubs .AND. ( nn_ubs_v /= 2 .AND. nn_ubs_v /= 4 )   ) THEN     ! UBS
         CALL ctl_stop( 'tra_adv_init: UBS scheme, choose 2nd or 4th order' )
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv_cen.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv_cen.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv_cen.F90	(revision 14852)
@@ -23,4 +23,7 @@
    USE trc_oce        ! share passive tracers/Ocean variables
    USE lib_mpp        ! MPP library
+#if defined key_loop_fusion
+   USE traadv_cen_lf  ! centered scheme            (tra_adv_cen  routine - loop fusion version)
+#endif
 
    IMPLICIT NONE
@@ -71,5 +74,5 @@
       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) if using XIOS (subdomain support)
+      ! 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
@@ -82,5 +85,8 @@
       !!----------------------------------------------------------------------
       !
-      IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+#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,*)
@@ -119,5 +125,5 @@
                ztv(ji,jj,jk) = ( pt(ji  ,jj+1,jk,jn,Kmm) - pt(ji,jj,jk,jn,Kmm) ) * vmask(ji,jj,jk)
             END_3D
-            IF (nn_hls.EQ.1) CALL lbc_lnk( 'traadv_cen', ztu, 'U', -1.0_wp , ztv, 'V', -1.0_wp )   ! Lateral boundary cond.
+            IF (nn_hls==1) CALL lbc_lnk( 'traadv_cen', ztu, 'U', -1.0_wp , ztv, 'V', -1.0_wp, ld4only= .TRUE. )   ! Lateral boundary cond.
             !
             DO_3D( nn_hls-1, 0, nn_hls-1, 0, 1, jpkm1 )           ! Horizontal advective fluxes
@@ -131,5 +137,5 @@
                zwy(ji,jj,jk) =  0.5_wp * pV(ji,jj,jk) * zC4t_v
             END_3D
-            IF (nn_hls.EQ.1) CALL lbc_lnk( 'traadv_cen', zwx, 'U', -1. , zwy, 'V', -1. )
+            IF (nn_hls==1) CALL lbc_lnk( 'traadv_cen', zwx, 'U', -1. , zwy, 'V', -1. )
             !
          CASE DEFAULT
@@ -184,4 +190,5 @@
       END DO
       !
+#endif
    END SUBROUTINE tra_adv_cen
 
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv_cen_lf.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv_cen_lf.F90	(revision 14852)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv_cen_lf.F90	(revision 14852)
@@ -0,0 +1,187 @@
+MODULE traadv_cen_lf
+   !!======================================================================
+   !!                     ***  MODULE  traadv_cen  ***
+   !! Ocean  tracers:   advective trend (2nd/4th order centered)
+   !!======================================================================
+   !! History :  3.7  ! 2014-05  (G. Madec)  original code
+   !!----------------------------------------------------------------------
+
+   !!----------------------------------------------------------------------
+   !!   tra_adv_cen   : update the tracer trend with the advection trends using a centered or scheme (2nd or 4th order)
+   !!                   NB: on the vertical it is actually a 4th order COMPACT scheme which is used
+   !!----------------------------------------------------------------------
+   USE dom_oce        ! ocean space and time domain
+   USE eosbn2         ! equation of state
+   USE traadv_fct     ! acces to routine interp_4th_cpt
+   USE trd_oce        ! trends: ocean variables
+   USE trdtra         ! trends manager: tracers
+   USE diaptr         ! poleward transport diagnostics
+   USE diaar5         ! AR5 diagnostics
+   !
+   USE in_out_manager ! I/O manager
+   USE iom            ! IOM library
+   USE trc_oce        ! share passive tracers/Ocean variables
+   USE lib_mpp        ! MPP library
+
+   IMPLICIT NONE
+   PRIVATE
+
+   PUBLIC   tra_adv_cen_lf   ! called by traadv.F90
+
+   REAL(wp) ::   r1_6 = 1._wp / 6._wp   ! =1/6
+
+   LOGICAL ::   l_trd   ! flag to compute trends
+   LOGICAL ::   l_ptr   ! flag to compute poleward transport
+   LOGICAL ::   l_hst   ! flag to compute heat/salt transport
+
+   !! * Substitutions
+#  include "do_loop_substitute.h90"
+#  include "domzgr_substitute.h90"
+   !!----------------------------------------------------------------------
+   !! NEMO/OCE 4.0 , NEMO Consortium (2018)
+   !! $Id: traadv_cen.F90 14776 2021-04-30 12:33:41Z mocavero $
+   !! Software governed by the CeCILL license (see ./LICENSE)
+   !!----------------------------------------------------------------------
+CONTAINS
+
+   SUBROUTINE tra_adv_cen_lf( 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) if using XIOS (subdomain support)
+      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) ::   ztu_im1, ztu_ip1 !   -      -
+      REAL(wp) ::   ztv_jm1, ztv_jp1 !   -      -
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zwx, zwy, zwz, ztw
+      !!----------------------------------------------------------------------
+      !
+      IF( ntile == 0 .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
+      !
+      !
+      zwz(:,:, 1 ) = 0._wp       ! surface & bottom vertical flux set to zero for all tracers
+      zwz(:,:,jpk) = 0._wp
+      !
+      DO jn = 1, kjpt            !==  loop over the tracers  ==!
+         !
+         SELECT CASE( kn_cen_h )       !--  Horizontal fluxes  --!
+         !
+         CASE(  2  )                         !* 2nd order centered
+            DO_3D( 1, 0, 1, 0, 1, jpkm1 )
+               zwx(ji,jj,jk) = 0.5_wp * pU(ji,jj,jk) * ( pt(ji,jj,jk,jn,Kmm) + pt(ji+1,jj  ,jk,jn,Kmm) )
+               zwy(ji,jj,jk) = 0.5_wp * pV(ji,jj,jk) * ( pt(ji,jj,jk,jn,Kmm) + pt(ji  ,jj+1,jk,jn,Kmm) )
+            END_3D
+            !
+         CASE(  4  )                         !* 4th order centered
+            DO_3D( 1, 0, 1, 0, 1, jpkm1 )           ! Horizontal advective fluxes
+               ztu_im1 = ( pt(ji,jj  ,jk,jn,Kmm) - pt(ji-1,jj,jk,jn,Kmm) ) * umask(ji-1,jj,jk)
+               ztu_ip1 = ( pt(ji+2,jj  ,jk,jn,Kmm) - pt(ji+1,jj,jk,jn,Kmm) ) * umask(ji+1,jj,jk)
+               ztv_jm1 = ( pt(ji,jj,jk,jn,Kmm) - pt(ji,jj-1,jk,jn,Kmm) ) * vmask(ji,jj-1,jk)
+               ztv_jp1 = ( pt(ji,jj+2,jk,jn,Kmm) - pt(ji,jj+1,jk,jn,Kmm) ) * vmask(ji,jj+1,jk)
+               !
+               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 * ( ztu_im1 - ztu_ip1 )
+               zC4t_v =  zC2t_v + r1_6 * ( ztv_jm1 - ztv_jp1 )
+               !                                                  ! C4 fluxes
+               zwx(ji,jj,jk) =  0.5_wp * pU(ji,jj,jk) * zC4t_u
+               zwy(ji,jj,jk) =  0.5_wp * pV(ji,jj,jk) * zC4t_v
+            END_3D
+            !
+         CASE DEFAULT
+            CALL ctl_stop( 'traadv_cen: wrong value for nn_cen' )
+         END SELECT
+         !
+         SELECT CASE( kn_cen_v )       !--  Vertical fluxes  --!   (interior)
+         !
+         CASE(  2  )                         !* 2nd order centered
+            DO_3D( 0, 0, 0, 0, 2, jpk )
+               zwz(ji,jj,jk) = 0.5 * pW(ji,jj,jk) * ( pt(ji,jj,jk,jn,Kmm) + pt(ji,jj,jk-1,jn,Kmm) ) * wmask(ji,jj,jk)
+            END_3D
+            !
+         CASE(  4  )                         !* 4th order compact
+            CALL interp_4th_cpt( pt(:,:,:,jn,Kmm) , ztw )      ! ztw = interpolated value of T at w-point
+            DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+               zwz(ji,jj,jk) = pW(ji,jj,jk) * ztw(ji,jj,jk) * wmask(ji,jj,jk)
+            END_3D
+            !
+         END SELECT
+         !
+         IF( ln_linssh ) THEN                !* top value   (linear free surf. only as zwz is multiplied by wmask)
+            IF( ln_isfcav ) THEN                  ! ice-shelf cavities (top of the ocean)
+               DO_2D( 1, 1, 1, 1 )
+                  zwz(ji,jj, mikt(ji,jj) ) = pW(ji,jj,mikt(ji,jj)) * pt(ji,jj,mikt(ji,jj),jn,Kmm)
+               END_2D
+            ELSE                                   ! no ice-shelf cavities (only ocean surface)
+               DO_2D( 1, 1, 1, 1 )
+                  zwz(ji,jj,1) = pW(ji,jj,1) * pt(ji,jj,1,jn,Kmm)
+               END_2D
+            ENDIF
+         ENDIF
+         !
+         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)  ) &
+               &                * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
+         END_3D
+         !                               ! trend diagnostics
+         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
+      !
+   END SUBROUTINE tra_adv_cen_lf
+
+   !!======================================================================
+END MODULE traadv_cen_lf
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv_fct.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv_fct.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv_fct.F90	(revision 14852)
@@ -34,6 +34,4 @@
    PUBLIC   tra_adv_fct        ! called by traadv.F90
    PUBLIC   interp_4th_cpt     ! called by traadv_cen.F90
-   PUBLIC   tridia_solver      ! called by traadv_fct_lf.F90
-   PUBLIC   nonosc             ! called by traadv_fct_lf.F90 - key_agrif
 
    LOGICAL  ::   l_trd   ! flag to compute trends
@@ -81,5 +79,5 @@
       INTEGER                                  , INTENT(in   ) ::   kn_fct_v        ! order of the FCT scheme (=2 or 4)
       REAL(wp)                                 , INTENT(in   ) ::   p2dt            ! tracer time-step
-      ! TEMP: [tiling] This can be A2D(nn_hls) if using XIOS (subdomain support)
+      ! TEMP: [tiling] This can be A2D(nn_hls) after all lbc_lnks removed in the nn_hls = 2 case
       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
@@ -95,5 +93,8 @@
       !!----------------------------------------------------------------------
       !
-      IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+#if defined key_loop_fusion
+      CALL tra_adv_fct_lf ( kt, nit000, cdtype, p2dt, pU, pV, pW, Kbb, Kmm, pt, kjpt, Krhs, kn_fct_h, kn_fct_v )
+#else
+      IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
          IF( kt == kit000 )  THEN
             IF(lwp) WRITE(numout,*)
@@ -136,5 +137,5 @@
       ! If adaptive vertical advection, check if it is needed on this PE at this time
       IF( ln_zad_Aimp ) THEN
-         IF( MAXVAL( ABS( wi(A2D(nn_hls),:) ) ) > 0._wp ) ll_zAimp = .TRUE.
+         IF( MAXVAL( ABS( wi(A2D(1),:) ) ) > 0._wp ) ll_zAimp = .TRUE.
       END IF
       ! If active adaptive vertical advection, build tridiagonal matrix
@@ -238,23 +239,29 @@
                END_2D
             END DO
-            CALL lbc_lnk( 'traadv_fct', zltu, 'T', 1.0_wp , zltv, 'T', 1.0_wp )   ! Lateral boundary cond. (unchanged sgn)
-            !
-            DO_3D( 1, 0, 1, 0, 1, jpkm1 )
+            ! NOTE [ comm_cleanup ] : need to change sign to ensure halo 1 - halo 2 compatibility
+            CALL lbc_lnk( 'traadv_fct', zltu, 'T', -1.0_wp , zltv, 'T', -1.0_wp, ld4only= .TRUE. )   ! Lateral boundary cond. (unchanged sgn)
+            !
+            DO_3D( nn_hls, nn_hls-1, nn_hls, nn_hls-1, 1, jpkm1 )
                zC2t_u = pt(ji,jj,jk,jn,Kmm) + pt(ji+1,jj  ,jk,jn,Kmm)   ! 2 x C2 interpolation of T at u- & v-points
                zC2t_v = pt(ji,jj,jk,jn,Kmm) + pt(ji  ,jj+1,jk,jn,Kmm)
                !                                                        ! C4 minus upstream advective fluxes
-               zwx(ji,jj,jk) =  0.5_wp * pU(ji,jj,jk) * ( zC2t_u + zltu(ji,jj,jk) - zltu(ji+1,jj,jk) ) - zwx(ji,jj,jk)
-               zwy(ji,jj,jk) =  0.5_wp * pV(ji,jj,jk) * ( zC2t_v + zltv(ji,jj,jk) - zltv(ji,jj+1,jk) ) - zwy(ji,jj,jk)
-            END_3D
-            IF (nn_hls.EQ.2) CALL lbc_lnk( 'traadv_fct', zwx, 'U', -1.0_wp, zwy, 'V', -1.0_wp )   ! Lateral boundary cond. (unchanged sgn)
+               ! round brackets added to fix the order of floating point operations
+               ! needed to ensure halo 1 - halo 2 compatibility
+               zwx(ji,jj,jk) =  0.5_wp * pU(ji,jj,jk) * ( zC2t_u + ( zltu(ji,jj,jk) - zltu(ji+1,jj,jk)   &
+                             &                                     )                                     & ! bracket for halo 1 - halo 2 compatibility
+                             &                          ) - zwx(ji,jj,jk)
+               zwy(ji,jj,jk) =  0.5_wp * pV(ji,jj,jk) * ( zC2t_v + ( zltv(ji,jj,jk) - zltv(ji,jj+1,jk)   &
+                             &                                     )                                     & ! bracket for halo 1 - halo 2 compatibility
+                             &                          ) - zwy(ji,jj,jk)
+            END_3D
             !
          CASE(  41 )                   !- 4th order centered       ==>>   !!gm coding attempt   need to be tested
             ztu(:,:,jpk) = 0._wp             ! Bottom value : flux set to zero
             ztv(:,:,jpk) = 0._wp
-            DO_3D( nn_hls, nn_hls-1, nn_hls, nn_hls-1, 1, jpkm1 )    ! 1st derivative (gradient)
+            DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpkm1 )    ! 1st derivative (gradient)
                ztu(ji,jj,jk) = ( pt(ji+1,jj  ,jk,jn,Kmm) - pt(ji,jj,jk,jn,Kmm) ) * umask(ji,jj,jk)
                ztv(ji,jj,jk) = ( pt(ji  ,jj+1,jk,jn,Kmm) - pt(ji,jj,jk,jn,Kmm) ) * vmask(ji,jj,jk)
             END_3D
-            IF (nn_hls.EQ.1) CALL lbc_lnk( 'traadv_fct', ztu, 'U', -1.0_wp , ztv, 'V', -1.0_wp )   ! Lateral boundary cond. (unchanged sgn)
+            IF (nn_hls==1) CALL lbc_lnk( 'traadv_fct', ztu, 'U', -1.0_wp , ztv, 'V', -1.0_wp, ld4only= .TRUE. )   ! Lateral boundary cond. (unchanged sgn)
             !
             DO_3D( 0, 0, 0, 0, 1, jpkm1 )    ! Horizontal advective fluxes
@@ -268,5 +275,5 @@
                zwy(ji,jj,jk) =  0.5_wp * pV(ji,jj,jk) * zC4t_v - zwy(ji,jj,jk)
             END_3D
-            IF (nn_hls.EQ.2) CALL lbc_lnk( 'traadv_fct', zwx, 'U', -1.0_wp , zwy, 'V', -1.0_wp )   ! Lateral boundary cond. (unchanged sgn)
+            IF (nn_hls==2) CALL lbc_lnk( 'traadv_fct', zwx, 'U', -1.0_wp , zwy, 'V', -1.0_wp )   ! Lateral boundary cond. (unchanged sgn)
             !
          END SELECT
@@ -291,5 +298,5 @@
          ENDIF
          !
-         IF (nn_hls.EQ.1) THEN
+         IF (nn_hls==1) THEN
             CALL lbc_lnk( 'traadv_fct', zwi, 'T', 1.0_wp, zwx, 'U', -1.0_wp , zwy, 'V', -1.0_wp, zwz, 'T', 1.0_wp )
          ELSE
@@ -374,4 +381,5 @@
       ENDIF
       !
+#endif
    END SUBROUTINE tra_adv_fct
 
@@ -449,5 +457,5 @@
          END_2D
       END DO
-      IF (nn_hls.EQ.1) CALL lbc_lnk( 'traadv_fct', zbetup, 'T', 1.0_wp , zbetdo, 'T', 1.0_wp )   ! lateral boundary cond. (unchanged sign)
+      IF (nn_hls==1) CALL lbc_lnk( 'traadv_fct', zbetup, 'T', 1.0_wp , zbetdo, 'T', 1.0_wp, ld4only= .TRUE. )   ! lateral boundary cond. (unchanged sign)
 
       ! 3. monotonic flux in the i & j direction (paa & pbb)
@@ -670,4 +678,331 @@
    END SUBROUTINE tridia_solver
 
+#if defined key_loop_fusion
+#define tracer_flux_i(out,zfp,zfm,ji,jj,jk) \
+        zfp = pU(ji,jj,jk) + ABS( pU(ji,jj,jk) ) ; \
+        zfm = pU(ji,jj,jk) - ABS( pU(ji,jj,jk) ) ; \
+        out = 0.5 * ( zfp * pt(ji,jj,jk,jn,Kbb) + zfm * pt(ji+1,jj,jk,jn,Kbb) )
+
+#define tracer_flux_j(out,zfp,zfm,ji,jj,jk) \
+        zfp = pV(ji,jj,jk) + ABS( pV(ji,jj,jk) ) ; \
+        zfm = pV(ji,jj,jk) - ABS( pV(ji,jj,jk) ) ; \
+        out = 0.5 * ( zfp * pt(ji,jj,jk,jn,Kbb) + zfm * pt(ji,jj+1,jk,jn,Kbb) )
+
+   SUBROUTINE tra_adv_fct_lf( kt, kit000, cdtype, p2dt, pU, pV, pW,       &
+      &                    Kbb, Kmm, pt, kjpt, Krhs, kn_fct_h, kn_fct_v )
+      !!----------------------------------------------------------------------
+      !!                  ***  ROUTINE tra_adv_fct  ***
+      !!
+      !! **  Purpose :   Compute the now trend due to total advection of tracers
+      !!               and add it to the general trend of tracer equations
+      !!
+      !! **  Method  : - 2nd or 4th FCT scheme on the horizontal direction
+      !!               (choice through the value of kn_fct)
+      !!               - on the vertical the 4th order is a compact scheme
+      !!               - corrected flux (monotonic correction)
+      !!
+      !! ** Action : - update pt(:,:,:,:,Krhs)  with the now advective tracer trends
+      !!             - send trends to trdtra module for further diagnostics (l_trdtra=T)
+      !!             - poleward advective heat and salt transport (ln_diaptr=T)
+      !!----------------------------------------------------------------------
+      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
+      INTEGER                                  , INTENT(in   ) ::   kn_fct_h        ! order of the FCT scheme (=2 or 4)
+      INTEGER                                  , INTENT(in   ) ::   kn_fct_v        ! order of the FCT scheme (=2 or 4)
+      REAL(wp)                                 , INTENT(in   ) ::   p2dt            ! tracer time-step
+      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
+      REAL(wp) ::   ztra                                     ! local scalar
+      REAL(wp) ::   zwx_im1, zfp_ui, zfp_ui_m1, zfp_vj, zfp_vj_m1, zfp_wk, zC2t_u, zC4t_u   !   -      -
+      REAL(wp) ::   zwy_jm1, zfm_ui, zfm_ui_m1, zfm_vj, zfm_vj_m1, zfm_wk, zC2t_v, zC4t_v   !   -      -
+      REAL(wp) ::   ztu, ztv, ztu_im1, ztu_ip1, ztv_jm1, ztv_jp1
+      REAL(wp), DIMENSION(jpi,jpj,jpk)        ::   zwi, zwx_3d, zwy_3d, zwz, ztw, zltu_3d, zltv_3d
+      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::   ztrdx, ztrdy, ztrdz, zptry
+      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::   zwinf, zwdia, zwsup
+      LOGICAL  ::   ll_zAimp                                 ! flag to apply adaptive implicit vertical advection
+      !!----------------------------------------------------------------------
+      !
+      IF( kt == kit000 )  THEN
+         IF(lwp) WRITE(numout,*)
+         IF(lwp) WRITE(numout,*) 'tra_adv_fct_lf : FCT advection scheme on ', cdtype
+         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~'
+      ENDIF
+      !! -- init to 0
+      zwx_3d(:,:,:) = 0._wp
+      zwy_3d(:,:,:) = 0._wp
+      zwz(:,:,:) = 0._wp
+      zwi(:,:,:) = 0._wp
+      !
+      l_trd = .FALSE.            ! set local switches
+      l_hst = .FALSE.
+      l_ptr = .FALSE.
+      ll_zAimp = .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.
+      !
+      IF( l_trd .OR. l_hst )  THEN
+         ALLOCATE( ztrdx(jpi,jpj,jpk), ztrdy(jpi,jpj,jpk), ztrdz(jpi,jpj,jpk) )
+         ztrdx(:,:,:) = 0._wp   ;    ztrdy(:,:,:) = 0._wp   ;   ztrdz(:,:,:) = 0._wp
+      ENDIF
+      !
+      IF( l_ptr ) THEN
+         ALLOCATE( zptry(jpi,jpj,jpk) )
+         zptry(:,:,:) = 0._wp
+      ENDIF
+      !
+      ! If adaptive vertical advection, check if it is needed on this PE at this time
+      IF( ln_zad_Aimp ) THEN
+         IF( MAXVAL( ABS( wi(:,:,:) ) ) > 0._wp ) ll_zAimp = .TRUE.
+      END IF
+      ! If active adaptive vertical advection, build tridiagonal matrix
+      IF( ll_zAimp ) THEN
+         ALLOCATE(zwdia(jpi,jpj,jpk), zwinf(jpi,jpj,jpk),zwsup(jpi,jpj,jpk))
+         DO_3D( 1, 1, 1, 1, 1, jpkm1 )
+            zwdia(ji,jj,jk) =  1._wp + p2dt * ( MAX( wi(ji,jj,jk) , 0._wp ) - MIN( wi(ji,jj,jk+1) , 0._wp ) )   &
+            &                               / e3t(ji,jj,jk,Krhs)
+            zwinf(ji,jj,jk) =  p2dt * MIN( wi(ji,jj,jk  ) , 0._wp ) / e3t(ji,jj,jk,Krhs)
+            zwsup(ji,jj,jk) = -p2dt * MAX( wi(ji,jj,jk+1) , 0._wp ) / e3t(ji,jj,jk,Krhs)
+         END_3D
+      END IF
+      !
+      DO jn = 1, kjpt            !==  loop over the tracers  ==!
+         !
+         !        !==  upstream advection with initial mass fluxes & intermediate update  ==!
+         !                               !* upstream tracer flux in the k direction *!
+         DO_3D( 1, 1, 1, 1, 2, jpkm1 )      ! Interior value ( multiplied by wmask)
+            zfp_wk = pW(ji,jj,jk) + ABS( pW(ji,jj,jk) )
+            zfm_wk = pW(ji,jj,jk) - ABS( pW(ji,jj,jk) )
+            zwz(ji,jj,jk) = 0.5 * ( zfp_wk * pt(ji,jj,jk,jn,Kbb) + zfm_wk * pt(ji,jj,jk-1,jn,Kbb) ) * wmask(ji,jj,jk)
+         END_3D
+         IF( ln_linssh ) THEN               ! top ocean value (only in linear free surface as zwz has been w-masked)
+            IF( ln_isfcav ) THEN                        ! top of the ice-shelf cavities and at the ocean surface
+               DO_2D( 1, 1, 1, 1 )
+                  zwz(ji,jj, mikt(ji,jj) ) = pW(ji,jj,mikt(ji,jj)) * pt(ji,jj,mikt(ji,jj),jn,Kbb)   ! linear free surface
+               END_2D
+            ELSE                                        ! no cavities: only at the ocean surface
+               DO_2D( 1, 1, 1, 1 )
+                  zwz(ji,jj,1) = pW(ji,jj,1) * pt(ji,jj,1,jn,Kbb)
+               END_2D
+            ENDIF
+         ENDIF
+         !
+         !                    !* upstream tracer flux in the i and j direction
+         DO jk = 1, jpkm1
+            DO jj = 1, jpj-1
+               tracer_flux_i(zwx_3d(1,jj,jk),zfp_ui,zfm_ui,1,jj,jk)
+               tracer_flux_j(zwy_3d(1,jj,jk),zfp_vj,zfm_vj,1,jj,jk)
+            END DO
+            DO ji = 1, jpi-1
+               tracer_flux_i(zwx_3d(ji,1,jk),zfp_ui,zfm_ui,ji,1,jk)
+               tracer_flux_j(zwy_3d(ji,1,jk),zfp_vj,zfm_vj,ji,1,jk)
+            END DO
+            DO_2D( 1, 1, 1, 1 )
+               tracer_flux_i(zwx_3d(ji,jj,jk),zfp_ui,zfm_ui,ji,jj,jk)
+               tracer_flux_i(zwx_im1,zfp_ui_m1,zfm_ui_m1,ji-1,jj,jk)
+               tracer_flux_j(zwy_3d(ji,jj,jk),zfp_vj,zfm_vj,ji,jj,jk)
+               tracer_flux_j(zwy_jm1,zfp_vj_m1,zfm_vj_m1,ji,jj-1,jk)
+               ztra = - ( zwx_3d(ji,jj,jk) - zwx_im1 + zwy_3d(ji,jj,jk) - zwy_jm1 + zwz(ji,jj,jk) - zwz(ji,jj,jk+1) ) * r1_e1e2t(ji,jj)
+               !                               ! update and guess with monotonic sheme
+               pt(ji,jj,jk,jn,Krhs) =                   pt(ji,jj,jk,jn,Krhs) +       ztra   &
+                  &                                  / e3t(ji,jj,jk,Kmm ) * tmask(ji,jj,jk)
+               zwi(ji,jj,jk)    = ( e3t(ji,jj,jk,Kbb) * pt(ji,jj,jk,jn,Kbb) + p2dt * ztra ) &
+                  &                                  / e3t(ji,jj,jk,Krhs) * tmask(ji,jj,jk)
+            END_2D
+         END DO
+
+         IF ( ll_zAimp ) THEN
+            CALL tridia_solver( zwdia, zwsup, zwinf, zwi, zwi , 0 )
+            !
+            ztw(:,:,1) = 0._wp ; ztw(:,:,jpk) = 0._wp ;
+            DO_3D( 1, 1, 1, 1, 2, jpkm1 )       ! Interior value ( multiplied by wmask)
+               zfp_wk = wi(ji,jj,jk) + ABS( wi(ji,jj,jk) )
+               zfm_wk = wi(ji,jj,jk) - ABS( wi(ji,jj,jk) )
+               ztw(ji,jj,jk) =  0.5 * e1e2t(ji,jj) * ( zfp_wk * zwi(ji,jj,jk) + zfm_wk * zwi(ji,jj,jk-1) ) * wmask(ji,jj,jk)
+               zwz(ji,jj,jk) = zwz(ji,jj,jk) + ztw(ji,jj,jk) ! update vertical fluxes
+            END_3D
+            DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+               pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) - ( ztw(ji,jj,jk) - ztw(ji  ,jj  ,jk+1) ) &
+                  &                                        * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
+            END_3D
+            !
+         END IF
+         !
+         IF( l_trd .OR. l_hst )  THEN             ! trend diagnostics (contribution of upstream fluxes)
+            ztrdx(:,:,:) = zwx_3d(:,:,:)   ;   ztrdy(:,:,:) = zwy_3d(:,:,:)   ;   ztrdz(:,:,:) = zwz(:,:,:)
+         END IF
+         !                             ! "Poleward" heat and salt transports (contribution of upstream fluxes)
+         IF( l_ptr )   zptry(:,:,:) = zwy_3d(:,:,:)
+         !
+         !        !==  anti-diffusive flux : high order minus low order  ==!
+         !
+         SELECT CASE( kn_fct_h )    !* horizontal anti-diffusive fluxes
+         !
+         CASE(  2  )                   !- 2nd order centered
+            DO_3D( 2, 1, 2, 1, 1, jpkm1 )
+               zwx_3d(ji,jj,jk) = 0.5_wp * pU(ji,jj,jk) * ( pt(ji,jj,jk,jn,Kmm) + pt(ji+1,jj,jk,jn,Kmm) ) - zwx_3d(ji,jj,jk)
+               zwy_3d(ji,jj,jk) = 0.5_wp * pV(ji,jj,jk) * ( pt(ji,jj,jk,jn,Kmm) + pt(ji,jj+1,jk,jn,Kmm) ) - zwy_3d(ji,jj,jk)
+            END_3D
+            !
+         CASE(  4  )                   !- 4th order centered
+            zltu_3d(:,:,jpk) = 0._wp            ! Bottom value : flux set to zero
+            zltv_3d(:,:,jpk) = 0._wp
+            !                          ! Laplacian
+            DO_3D( 0, 0, 0, 0, 1, jpkm1 )                 ! 2nd derivative * 1/ 6
+                  !             ! 1st derivative (gradient)
+                  ztu = ( pt(ji+1,jj,jk,jn,Kmm) - pt(ji,jj,jk,jn,Kmm) ) * umask(ji,jj,jk)
+                  ztu_im1 = ( pt(ji,jj,jk,jn,Kmm) - pt(ji-1,jj,jk,jn,Kmm) ) * umask(ji-1,jj,jk)
+                  ztv = ( pt(ji,jj+1,jk,jn,Kmm) - pt(ji,jj,jk,jn,Kmm) ) * vmask(ji,jj,jk)
+                  ztv_jm1 = ( pt(ji,jj,jk,jn,Kmm) - pt(ji,jj-1,jk,jn,Kmm) ) * vmask(ji,jj-1,jk)
+                  !             ! 2nd derivative * 1/ 6
+                  zltu_3d(ji,jj,jk) = (  ztu + ztu_im1  ) * r1_6
+                  zltv_3d(ji,jj,jk) = (  ztv + ztv_jm1  ) * r1_6
+               END_2D
+            END DO
+            ! NOTE [ comm_cleanup ] : need to change sign to ensure halo 1 - halo 2 compatibility
+            CALL lbc_lnk( 'traadv_fct', zltu_3d, 'T', -1.0_wp , zltv_3d, 'T', -1.0_wp )   ! Lateral boundary cond. (unchanged sgn)
+            !
+            DO_3D( 2, 1, 2, 1, 1, jpkm1 )
+               zC2t_u = pt(ji,jj,jk,jn,Kmm) + pt(ji+1,jj  ,jk,jn,Kmm)   ! 2 x C2 interpolation of T at u- & v-points
+               zC2t_v = pt(ji,jj,jk,jn,Kmm) + pt(ji  ,jj+1,jk,jn,Kmm)
+               !                                                        ! C4 minus upstream advective fluxes
+               ! round brackets added to fix the order of floating point operations
+               ! needed to ensure halo 1 - halo 2 compatibility
+               zwx_3d(ji,jj,jk) =  0.5_wp * pU(ji,jj,jk) * ( zC2t_u + ( zltu_3d(ji,jj,jk) - zltu_3d(ji+1,jj,jk)   &
+                             &                                        )                                           & ! bracket for halo 1 - halo 2 compatibility
+                             &                             ) - zwx_3d(ji,jj,jk)
+               zwy_3d(ji,jj,jk) =  0.5_wp * pV(ji,jj,jk) * ( zC2t_v + ( zltv_3d(ji,jj,jk) - zltv_3d(ji,jj+1,jk)   &
+                             &                                        )                                           & ! bracket for halo 1 - halo 2 compatibility
+                             &                             ) - zwy_3d(ji,jj,jk)
+            END_3D
+            !
+         CASE(  41 )                   !- 4th order centered       ==>>   !!gm coding attempt   need to be tested
+            DO_3D( 0, 0, 0, 0, 1, jpkm1 )    ! Horizontal advective fluxes
+               ztu_im1 = ( pt(ji  ,jj  ,jk,jn,Kmm) - pt(ji-1,jj,jk,jn,Kmm) ) * umask(ji-1,jj,jk)
+               ztu_ip1 = ( pt(ji+2,jj  ,jk,jn,Kmm) - pt(ji+1,jj,jk,jn,Kmm) ) * umask(ji+1,jj,jk)
+
+               ztv_jm1 = ( pt(ji,jj  ,jk,jn,Kmm) - pt(ji,jj-1,jk,jn,Kmm) ) * vmask(ji,jj-1,jk)
+               ztv_jp1 = ( pt(ji,jj+2,jk,jn,Kmm) - pt(ji,jj+1,jk,jn,Kmm) ) * vmask(ji,jj+1,jk)
+               zC2t_u = pt(ji,jj,jk,jn,Kmm) + pt(ji+1,jj  ,jk,jn,Kmm)   ! 2 x 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 * ( ztu_im1 - ztu_ip1 )
+               zC4t_v =  zC2t_v + r1_6 * ( ztv_jm1 - ztv_jp1 )
+               !                                                  ! C4 minus upstream advective fluxes
+               zwx_3d(ji,jj,jk) =  0.5_wp * pU(ji,jj,jk) * zC4t_u - zwx_3d(ji,jj,jk)
+               zwy_3d(ji,jj,jk) =  0.5_wp * pV(ji,jj,jk) * zC4t_v - zwy_3d(ji,jj,jk)
+            END_3D
+            CALL lbc_lnk( 'traadv_fct', zwx_3d, 'U', -1.0_wp , zwy_3d, 'V', -1.0_wp )   ! Lateral boundary cond. (unchanged sgn)
+            !
+         END SELECT
+         !
+         SELECT CASE( kn_fct_v )    !* vertical anti-diffusive fluxes (w-masked interior values)
+         !
+         CASE(  2  )                   !- 2nd order centered
+            DO_3D( 1, 1, 1, 1, 2, jpkm1 )
+               zwz(ji,jj,jk) =  (  pW(ji,jj,jk) * 0.5_wp * ( pt(ji,jj,jk,jn,Kmm) + pt(ji,jj,jk-1,jn,Kmm) )   &
+                  &              - zwz(ji,jj,jk)  ) * wmask(ji,jj,jk)
+            END_3D
+            !
+         CASE(  4  )                   !- 4th order COMPACT
+            CALL interp_4th_cpt( pt(:,:,:,jn,Kmm) , ztw )   ! zwt = COMPACT interpolation of T at w-point
+            DO_3D( 1, 1, 1, 1, 2, jpkm1 )
+               zwz(ji,jj,jk) = ( pW(ji,jj,jk) * ztw(ji,jj,jk) - zwz(ji,jj,jk) ) * wmask(ji,jj,jk)
+            END_3D
+            !
+         END SELECT
+         IF( ln_linssh ) THEN    ! top ocean value: high order = upstream  ==>>  zwz=0
+            zwz(:,:,1) = 0._wp   ! only ocean surface as interior zwz values have been w-masked
+         ENDIF
+         !
+         CALL lbc_lnk( 'traadv_fct', zwi, 'T', 1.0_wp)
+         !
+         IF ( ll_zAimp ) THEN
+            DO_3D( 1, 1, 1, 1, 1, jpkm1 )    !* trend and after field with monotonic scheme
+               !                                                ! total intermediate advective trends
+               ztra = - (  zwx_3d(ji,jj,jk) - zwx_3d(ji-1,jj  ,jk  )   &
+                  &      + zwy_3d(ji,jj,jk) - zwy_3d(ji  ,jj-1,jk  )   &
+                  &      + zwz(ji,jj,jk) - zwz(ji  ,jj  ,jk+1) ) * r1_e1e2t(ji,jj)
+               ztw(ji,jj,jk) = zwi(ji,jj,jk) + p2dt * ztra / e3t(ji,jj,jk,Krhs) * tmask(ji,jj,jk)
+            END_3D
+            !
+            CALL tridia_solver( zwdia, zwsup, zwinf, ztw, ztw , 0 )
+            !
+            DO_3D( 1, 1, 1, 1, 2, jpkm1 )       ! Interior value ( multiplied by wmask)
+               zfp_wk = wi(ji,jj,jk) + ABS( wi(ji,jj,jk) )
+               zfm_wk = wi(ji,jj,jk) - ABS( wi(ji,jj,jk) )
+               zwz(ji,jj,jk) = zwz(ji,jj,jk) + 0.5 * e1e2t(ji,jj) * ( zfp_wk * ztw(ji,jj,jk) + zfm_wk * ztw(ji,jj,jk-1) ) * wmask(ji,jj,jk)
+            END_3D
+         END IF
+         !
+         !        !==  monotonicity algorithm  ==!
+         !
+         CALL nonosc( Kmm, pt(:,:,:,jn,Kbb), zwx_3d, zwy_3d, zwz, zwi, p2dt )
+         !
+         !        !==  final trend with corrected fluxes  ==!
+         !
+         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+            ztra = - (  zwx_3d(ji,jj,jk) - zwx_3d(ji-1,jj  ,jk  )   &
+               &      + zwy_3d(ji,jj,jk) - zwy_3d(ji  ,jj-1,jk  )   &
+               &      + zwz(ji,jj,jk) - zwz(ji  ,jj  ,jk+1) ) * r1_e1e2t(ji,jj)
+            pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) + ztra / e3t(ji,jj,jk,Kmm)
+            zwi(ji,jj,jk) = zwi(ji,jj,jk) + p2dt * ztra / e3t(ji,jj,jk,Krhs) * tmask(ji,jj,jk)
+         END_3D
+         !
+         IF ( ll_zAimp ) THEN
+            !
+            ztw(:,:,1) = 0._wp ; ztw(:,:,jpk) = 0._wp
+            DO_3D( 0, 0, 0, 0, 2, jpkm1 )      ! Interior value ( multiplied by wmask)
+               zfp_wk = wi(ji,jj,jk) + ABS( wi(ji,jj,jk) )
+               zfm_wk = wi(ji,jj,jk) - ABS( wi(ji,jj,jk) )
+               ztw(ji,jj,jk) = - 0.5 * e1e2t(ji,jj) * ( zfp_wk * zwi(ji,jj,jk) + zfm_wk * zwi(ji,jj,jk-1) ) * wmask(ji,jj,jk)
+               zwz(ji,jj,jk) = zwz(ji,jj,jk) + ztw(ji,jj,jk) ! Update vertical fluxes for trend diagnostic
+            END_3D
+            DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+               pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) - ( ztw(ji,jj,jk) - ztw(ji  ,jj  ,jk+1) ) &
+                  &                                        * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
+            END_3D
+         END IF
+         ! NOT TESTED - NEED l_trd OR l_hst TRUE
+         IF( l_trd .OR. l_hst ) THEN   ! trend diagnostics // heat/salt transport
+            ztrdx(:,:,:) = ztrdx(:,:,:) + zwx_3d(:,:,:)  ! <<< add anti-diffusive fluxes
+            ztrdy(:,:,:) = ztrdy(:,:,:) + zwy_3d(:,:,:)  !     to upstream fluxes
+            ztrdz(:,:,:) = ztrdz(:,:,:) + zwz(:,:,:)  !
+            !
+            IF( l_trd ) THEN              ! trend diagnostics
+               CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_xad, ztrdx, pU, pt(:,:,:,jn,Kmm) )
+               CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_yad, ztrdy, pV, pt(:,:,:,jn,Kmm) )
+               CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_zad, ztrdz, pW, pt(:,:,:,jn,Kmm) )
+            ENDIF
+            !                             ! heat/salt transport
+            IF( l_hst )   CALL dia_ar5_hst( jn, 'adv', ztrdx(:,:,:), ztrdy(:,:,:) )
+            !
+         ENDIF
+         ! NOT TESTED - NEED l_ptr TRUE
+         IF( l_ptr ) THEN              ! "Poleward" transports
+            zptry(:,:,:) = zptry(:,:,:) + zwy_3d(:,:,:)  ! <<< add anti-diffusive fluxes
+            CALL dia_ptr_hst( jn, 'adv', zptry(:,:,:) )
+         ENDIF
+         !
+      END DO                     ! end of tracer loop
+      !
+      IF ( ll_zAimp ) THEN
+         DEALLOCATE( zwdia, zwinf, zwsup )
+      ENDIF
+      IF( l_trd .OR. l_hst ) THEN
+         DEALLOCATE( ztrdx, ztrdy, ztrdz )
+      ENDIF
+      IF( l_ptr ) THEN
+         DEALLOCATE( zptry )
+      ENDIF
+      !
+   END SUBROUTINE tra_adv_fct_lf
+#endif
    !!======================================================================
 END MODULE traadv_fct
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv_fct_lf.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv_fct_lf.F90	(revision 14851)
+++ 	(revision )
@@ -1,553 +1,0 @@
-MODULE traadv_fct_lf
-   !!==============================================================================
-   !!                       ***  MODULE  traadv_fct  ***
-   !! Ocean  tracers:  horizontal & vertical advective trend (2nd/4th order Flux Corrected Transport method)
-   !!==============================================================================
-   !! History :  3.7  !  2015-09  (L. Debreu, G. Madec)  original code (inspired from traadv_tvd.F90)
-   !!----------------------------------------------------------------------
-
-   !!----------------------------------------------------------------------
-   !!  tra_adv_fct-lf : update the tracer trend with a 3D advective trends using a 2nd or 4th order FCT scheme
-   !!                   with sub-time-stepping in the vertical direction - loop fusion version
-   !!  nonosc_lf      : compute monotonic tracer fluxes by a non-oscillatory algorithm - loop fusion version 
-   !!----------------------------------------------------------------------
-   USE oce            ! ocean dynamics and active tracers
-   USE dom_oce        ! ocean space and time domain
-   USE trc_oce        ! share passive tracers/Ocean variables
-   USE trd_oce        ! trends: ocean variables
-   USE trdtra         ! tracers trends
-   USE diaptr         ! poleward transport diagnostics
-   USE diaar5         ! AR5 diagnostics
-   USE phycst  , ONLY : rho0_rcp
-   USE zdf_oce , ONLY : ln_zad_Aimp
-   !
-   USE in_out_manager ! I/O manager
-   USE iom            ! 
-   USE lib_mpp        ! MPP library
-   USE lbclnk         ! ocean lateral boundary condition (or mpp link) 
-   USE lib_fortran    ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined)  
-   USE traadv_fct
-
-   IMPLICIT NONE
-   PRIVATE
-
-   PUBLIC   tra_adv_fct_lf     ! called by traadv.F90
-
-   LOGICAL  ::   l_trd   ! flag to compute trends
-   LOGICAL  ::   l_ptr   ! flag to compute poleward transport
-   LOGICAL  ::   l_hst   ! flag to compute heat/salt transport
-   REAL(wp) ::   r1_6 = 1._wp / 6._wp   ! =1/6
-
-   !                                        ! tridiag solver associated indices:
-   INTEGER, PARAMETER ::   np_NH   = 0   ! Neumann homogeneous boundary condition
-   INTEGER, PARAMETER ::   np_CEN2 = 1   ! 2nd order centered  boundary condition
-
-   !! * Substitutions
-#  include "do_loop_substitute.h90"
-#  include "domzgr_substitute.h90"
-
-#define tracer_flux_i(out,zfp,zfm,ji,jj,jk) \
-        zfp = pU(ji,jj,jk) + ABS( pU(ji,jj,jk) ) ; \
-        zfm = pU(ji,jj,jk) - ABS( pU(ji,jj,jk) ) ; \
-        out = 0.5 * ( zfp * pt(ji,jj,jk,jn,Kbb) + zfm * pt(ji+1,jj,jk,jn,Kbb) )
-
-#define tracer_flux_j(out,zfp,zfm,ji,jj,jk) \
-        zfp = pV(ji,jj,jk) + ABS( pV(ji,jj,jk) ) ; \
-        zfm = pV(ji,jj,jk) - ABS( pV(ji,jj,jk) ) ; \
-        out = 0.5 * ( zfp * pt(ji,jj,jk,jn,Kbb) + zfm * pt(ji,jj+1,jk,jn,Kbb) )
-
-#define search_in_neighbour(out,OP,vec,ji,jj,jk) \
-        out = OP(vec(ji,jj,jk),vec(ji-1,jj,jk),vec(ji+1,jj,jk), \
-        vec(ji,jj-1,jk),vec(ji,jj+1,jk),vec(ji,jj,MAX(jk-1,1)),vec(ji,jj,jk+1))
-
-#define pos_part_of_flux(ji,jj,jk,out) \
-        out = MAX(0.,paa_in(ji-1,jj,jk)) - MIN(0.,paa_in(ji,jj,jk)) \
-        + MAX(0.,pbb_in(ji,jj-1,jk)) - MIN(0.,pbb_in(ji,jj,jk)) \
-        + MAX(0.,pcc_in(ji,jj,jk+1)) - MIN(0.,pcc_in(ji,jj,jk)) 
-
-#define neg_part_of_flux(ji,jj,jk,out) \
-        out = MAX( 0.,paa_in(ji,jj,jk) ) - MIN( 0., paa_in(ji-1,jj,jk)) \
-        + MAX( 0.,pbb_in(ji,jj,jk) ) - MIN( 0., pbb_in(ji,jj-1,jk)) \
-        + MAX( 0.,pcc_in(ji,jj,jk) ) - MIN( 0., pcc_in(ji,jj,jk+1))
-
-#define beta_terms(bt,betup,betdo,up,pos,do,neg,ji,jj,jk) \
-        bt = e1e2t(ji,jj) * e3t(ji,jj,jk,Kmm) / p2dt ; \
-        betup = ( up            - paft(ji,jj,jk) ) / ( pos + zrtrn ) * bt ; \
-        betdo = ( paft(ji,jj,jk) - do            ) / ( neg + zrtrn ) * bt
-
-#define monotonic_flux(a,b,c,betup_p1,betdo_p1,vec,vec_in,jk) \
-        a = MIN( 1._wp, zbetdo(ji,jj), betup_p1 ) ; \
-        b = MIN( 1._wp, zbetup(ji,jj), betdo_p1 ) ; \
-        c = ( 0.5_wp  + SIGN( 0.5_wp , vec_in(ji,jj,jk) ) ) ; \
-        vec(ji,jj,jk) = vec_in(ji,jj,jk) * ( c * a + ( 1._wp - c) * b )
-
-#define monotonic_flux_k(a,b,c,betup,betdo,vec,vec_in,jk) \
-        a = MIN( 1._wp, betdo, zbetup_ptr(ji,jj) ) ; \
-        b = MIN( 1._wp, betup, zbetdo_ptr(ji,jj) ) ; \
-        c = ( 0.5 + SIGN( 0.5_wp , vec_in(ji,jj,jk) ) ) ; \
-        vec(ji,jj,jk) = vec_in(ji,jj,jk) * ( c * a + ( 1._wp - c) * b )
-
-   !!----------------------------------------------------------------------
-   !! NEMO/OCE 4.0 , NEMO Consortium (2018)
-   !! $Id: traadv_fct.F90 13660 2020-10-22 10:47:32Z francesca $
-   !! Software governed by the CeCILL license (see ./LICENSE)
-   !!----------------------------------------------------------------------
-CONTAINS
-
-   SUBROUTINE tra_adv_fct_lf( kt, kit000, cdtype, p2dt, pU, pV, pW,       &
-      &                    Kbb, Kmm, pt, kjpt, Krhs, kn_fct_h, kn_fct_v )
-      !!----------------------------------------------------------------------
-      !!                  ***  ROUTINE tra_adv_fct  ***
-      !! 
-      !! **  Purpose :   Compute the now trend due to total advection of tracers
-      !!               and add it to the general trend of tracer equations
-      !!
-      !! **  Method  : - 2nd or 4th FCT scheme on the horizontal direction
-      !!               (choice through the value of kn_fct)
-      !!               - on the vertical the 4th order is a compact scheme 
-      !!               - corrected flux (monotonic correction) 
-      !!
-      !! ** Action : - update pt(:,:,:,:,Krhs)  with the now advective tracer trends
-      !!             - send trends to trdtra module for further diagnostics (l_trdtra=T)
-      !!             - poleward advective heat and salt transport (ln_diaptr=T)
-      !!----------------------------------------------------------------------
-      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
-      INTEGER                                  , INTENT(in   ) ::   kn_fct_h        ! order of the FCT scheme (=2 or 4)
-      INTEGER                                  , INTENT(in   ) ::   kn_fct_v        ! order of the FCT scheme (=2 or 4)
-      REAL(wp)                                 , INTENT(in   ) ::   p2dt            ! tracer time-step
-      REAL(wp), DIMENSION(jpi,jpj,jpk         ), INTENT(inout) ::   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  
-      REAL(wp) ::   ztra                                     ! local scalar
-      REAL(wp) ::   zwx_im1, zfp_ui, zfp_ui_m1, zfp_vj, zfp_vj_m1, zfp_wk, zC2t_u, zC4t_u   !   -      -
-      REAL(wp) ::   zwy_jm1, zfm_ui, zfm_ui_m1, zfm_vj, zfm_vj_m1, zfm_wk, zC2t_v, zC4t_v   !   -      -
-      REAL(wp) ::   ztu_im1, ztu_ip1, ztv_jm1, ztv_jp1  
-      REAL(wp), DIMENSION(jpi,jpj,jpk)        ::   zwi, zwx_3d, zwy_3d, zwz, ztw, zltu_3d, zltv_3d, ztu, ztv
-      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::   ztrdx, ztrdy, ztrdz, zptry
-      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::   zwinf, zwdia, zwsup
-      LOGICAL  ::   ll_zAimp                                 ! flag to apply adaptive implicit vertical advection
-      !!----------------------------------------------------------------------
-      !
-      IF( kt == kit000 )  THEN
-         IF(lwp) WRITE(numout,*)
-         IF(lwp) WRITE(numout,*) 'tra_adv_fct_lf : FCT advection scheme on ', cdtype
-         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~'
-      ENDIF
-      !! -- init to 0
-      zwx_3d(:,:,:) = 0._wp
-      zwy_3d(:,:,:) = 0._wp
-      zwz(:,:,:) = 0._wp
-      zwi(:,:,:) = 0._wp
-      !
-      l_trd = .FALSE.            ! set local switches
-      l_hst = .FALSE.
-      l_ptr = .FALSE.
-      ll_zAimp = .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.
-      !
-      IF( l_trd .OR. l_hst )  THEN
-         ALLOCATE( ztrdx(jpi,jpj,jpk), ztrdy(jpi,jpj,jpk), ztrdz(jpi,jpj,jpk) )
-         ztrdx(:,:,:) = 0._wp   ;    ztrdy(:,:,:) = 0._wp   ;   ztrdz(:,:,:) = 0._wp
-      ENDIF
-      !
-      IF( l_ptr ) THEN  
-         ALLOCATE( zptry(jpi,jpj,jpk) )
-         zptry(:,:,:) = 0._wp
-      ENDIF
-      !
-      ! If adaptive vertical advection, check if it is needed on this PE at this time
-      IF( ln_zad_Aimp ) THEN
-         IF( MAXVAL( ABS( wi(:,:,:) ) ) > 0._wp ) ll_zAimp = .TRUE.
-      END IF
-      ! If active adaptive vertical advection, build tridiagonal matrix
-      IF( ll_zAimp ) THEN
-         ALLOCATE(zwdia(jpi,jpj,jpk), zwinf(jpi,jpj,jpk),zwsup(jpi,jpj,jpk))
-         DO_3D( 1, 1, 1, 1, 1, jpkm1 )
-            zwdia(ji,jj,jk) =  1._wp + p2dt * ( MAX( wi(ji,jj,jk) , 0._wp ) - MIN( wi(ji,jj,jk+1) , 0._wp ) )   &
-            &                               / e3t(ji,jj,jk,Krhs)
-            zwinf(ji,jj,jk) =  p2dt * MIN( wi(ji,jj,jk  ) , 0._wp ) / e3t(ji,jj,jk,Krhs)
-            zwsup(ji,jj,jk) = -p2dt * MAX( wi(ji,jj,jk+1) , 0._wp ) / e3t(ji,jj,jk,Krhs)
-         END_3D
-      END IF
-      !
-      DO jn = 1, kjpt            !==  loop over the tracers  ==!
-         !
-         !        !==  upstream advection with initial mass fluxes & intermediate update  ==!
-         !                               !* upstream tracer flux in the k direction *!
-         DO_3D( 1, 1, 1, 1, 2, jpkm1 )      ! Interior value ( multiplied by wmask)
-            zfp_wk = pW(ji,jj,jk) + ABS( pW(ji,jj,jk) )
-            zfm_wk = pW(ji,jj,jk) - ABS( pW(ji,jj,jk) )
-            zwz(ji,jj,jk) = 0.5 * ( zfp_wk * pt(ji,jj,jk,jn,Kbb) + zfm_wk * pt(ji,jj,jk-1,jn,Kbb) ) * wmask(ji,jj,jk)
-         END_3D
-         IF( ln_linssh ) THEN               ! top ocean value (only in linear free surface as zwz has been w-masked)
-            IF( ln_isfcav ) THEN                        ! top of the ice-shelf cavities and at the ocean surface
-               DO_2D( 1, 1, 1, 1 )
-                  zwz(ji,jj, mikt(ji,jj) ) = pW(ji,jj,mikt(ji,jj)) * pt(ji,jj,mikt(ji,jj),jn,Kbb)   ! linear free surface 
-               END_2D
-            ELSE                                        ! no cavities: only at the ocean surface
-               DO_2D( 1, 1, 1, 1 )
-                  zwz(ji,jj,1) = pW(ji,jj,1) * pt(ji,jj,1,jn,Kbb)
-               END_2D
-            ENDIF
-         ENDIF
-         !               
-         !                    !* upstream tracer flux in the i and j direction 
-         DO jk = 1, jpkm1
-            DO jj = 1, jpj-1
-               tracer_flux_i(zwx_3d(1,jj,jk),zfp_ui,zfm_ui,1,jj,jk)
-               tracer_flux_j(zwy_3d(1,jj,jk),zfp_vj,zfm_vj,1,jj,jk)
-            END DO
-            DO ji = 1, jpi-1
-               tracer_flux_i(zwx_3d(ji,1,jk),zfp_ui,zfm_ui,ji,1,jk)
-               tracer_flux_j(zwy_3d(ji,1,jk),zfp_vj,zfm_vj,ji,1,jk)
-            END DO
-            DO_2D( 1, 1, 1, 1 )
-               tracer_flux_i(zwx_3d(ji,jj,jk),zfp_ui,zfm_ui,ji,jj,jk)
-               tracer_flux_i(zwx_im1,zfp_ui_m1,zfm_ui_m1,ji-1,jj,jk)
-               tracer_flux_j(zwy_3d(ji,jj,jk),zfp_vj,zfm_vj,ji,jj,jk)
-               tracer_flux_j(zwy_jm1,zfp_vj_m1,zfm_vj_m1,ji,jj-1,jk)
-               ztra = - ( zwx_3d(ji,jj,jk) - zwx_im1 + zwy_3d(ji,jj,jk) - zwy_jm1 + zwz(ji,jj,jk) - zwz(ji,jj,jk+1) ) * r1_e1e2t(ji,jj)
-               !                               ! update and guess with monotonic sheme
-               pt(ji,jj,jk,jn,Krhs) =                   pt(ji,jj,jk,jn,Krhs) +       ztra   &
-                  &                                  / e3t(ji,jj,jk,Kmm ) * tmask(ji,jj,jk)
-               zwi(ji,jj,jk)    = ( e3t(ji,jj,jk,Kbb) * pt(ji,jj,jk,jn,Kbb) + p2dt * ztra ) &
-                  &                                  / e3t(ji,jj,jk,Krhs) * tmask(ji,jj,jk)
-            END_2D
-         END DO
-         
-         IF ( ll_zAimp ) THEN
-            CALL tridia_solver( zwdia, zwsup, zwinf, zwi, zwi , 0 )
-            !
-            ztw(:,:,1) = 0._wp ; ztw(:,:,jpk) = 0._wp ;
-            DO_3D( 1, 1, 1, 1, 2, jpkm1 )       ! Interior value ( multiplied by wmask)
-               zfp_wk = wi(ji,jj,jk) + ABS( wi(ji,jj,jk) )
-               zfm_wk = wi(ji,jj,jk) - ABS( wi(ji,jj,jk) )
-               ztw(ji,jj,jk) =  0.5 * e1e2t(ji,jj) * ( zfp_wk * zwi(ji,jj,jk) + zfm_wk * zwi(ji,jj,jk-1) ) * wmask(ji,jj,jk)
-               zwz(ji,jj,jk) = zwz(ji,jj,jk) + ztw(ji,jj,jk) ! update vertical fluxes
-            END_3D
-            DO_3D( 0, 0, 0, 0, 1, jpkm1 )
-               pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) - ( ztw(ji,jj,jk) - ztw(ji  ,jj  ,jk+1) ) &
-                  &                                        * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
-            END_3D
-            !
-         END IF
-         !                
-         IF( l_trd .OR. l_hst )  THEN             ! trend diagnostics (contribution of upstream fluxes)
-            ztrdx(:,:,:) = zwx_3d(:,:,:)   ;   ztrdy(:,:,:) = zwy_3d(:,:,:)   ;   ztrdz(:,:,:) = zwz(:,:,:)
-         END IF
-         !                             ! "Poleward" heat and salt transports (contribution of upstream fluxes)
-         IF( l_ptr )   zptry(:,:,:) = zwy_3d(:,:,:) 
-         !
-         !        !==  anti-diffusive flux : high order minus low order  ==!
-         !
-         SELECT CASE( kn_fct_h )    !* horizontal anti-diffusive fluxes
-         !
-         CASE(  2  )                   !- 2nd order centered
-            DO_3D( 2, 1, 2, 1, 1, jpkm1 )
-               zwx_3d(ji,jj,jk) = 0.5_wp * pU(ji,jj,jk) * ( pt(ji,jj,jk,jn,Kmm) + pt(ji+1,jj,jk,jn,Kmm) ) - zwx_3d(ji,jj,jk)
-               zwy_3d(ji,jj,jk) = 0.5_wp * pV(ji,jj,jk) * ( pt(ji,jj,jk,jn,Kmm) + pt(ji,jj+1,jk,jn,Kmm) ) - zwy_3d(ji,jj,jk)
-            END_3D
-            !
-         CASE(  4  )                   !- 4th order centered
-            zltu_3d(:,:,jpk) = 0._wp            ! Bottom value : flux set to zero
-            zltv_3d(:,:,jpk) = 0._wp
-            DO jk = 1, jpkm1                 ! Laplacian
-               DO_2D( 1, 0, 1, 0 )                 ! 1st derivative (gradient)
-                  ztu(ji,jj,jk) = ( pt(ji+1,jj  ,jk,jn,Kmm) - pt(ji,jj,jk,jn,Kmm) ) * umask(ji,jj,jk)
-                  ztv(ji,jj,jk) = ( pt(ji  ,jj+1,jk,jn,Kmm) - pt(ji,jj,jk,jn,Kmm) ) * vmask(ji,jj,jk)
-               END_2D
-               DO_2D( 0, 0, 0, 0 )                 ! 2nd derivative * 1/ 6
-                  zltu_3d(ji,jj,jk) = (  ztu(ji,jj,jk) + ztu(ji-1,jj,jk)  ) * r1_6
-                  zltv_3d(ji,jj,jk) = (  ztv(ji,jj,jk) + ztv(ji,jj-1,jk)  ) * r1_6
-               END_2D
-            END DO
-            CALL lbc_lnk( 'traadv_fct', zltu_3d, 'T', 1.0_wp , zltv_3d, 'T', 1.0_wp )   ! Lateral boundary cond. (unchanged sgn)
-!            !
-            DO_3D( nn_hls, nn_hls-1, nn_hls, nn_hls-1, 1, jpkm1 )
-               zC2t_u = pt(ji,jj,jk,jn,Kmm) + pt(ji+1,jj  ,jk,jn,Kmm)   ! 2 x C2 interpolation of T at u- & v-points
-               zC2t_v = pt(ji,jj,jk,jn,Kmm) + pt(ji  ,jj+1,jk,jn,Kmm)
-               !                                                        ! C4 minus upstream advective fluxes 
-               zwx_3d(ji,jj,jk) =  0.5_wp * pU(ji,jj,jk) * ( zC2t_u + zltu_3d(ji,jj,jk) - zltu_3d(ji+1,jj,jk) ) - zwx_3d(ji,jj,jk)
-               zwy_3d(ji,jj,jk) =  0.5_wp * pV(ji,jj,jk) * ( zC2t_v + zltv_3d(ji,jj,jk) - zltv_3d(ji,jj+1,jk) ) - zwy_3d(ji,jj,jk)
-            END_3D
-            !
-            CALL lbc_lnk( 'traadv_fct', zwx_3d, 'U', -1.0_wp , zwy_3d, 'V', -1.0_wp )   ! Lateral boundary cond. (unchanged sgn)
-         CASE(  41 )                   !- 4th order centered       ==>>   !!gm coding attempt   need to be tested
-            DO_3D( 0, 0, 0, 0, 1, jpkm1 )    ! Horizontal advective fluxes
-               ztu_im1 = ( pt(ji  ,jj  ,jk,jn,Kmm) - pt(ji-1,jj,jk,jn,Kmm) ) * umask(ji-1,jj,jk)
-               ztu_ip1 = ( pt(ji+2,jj  ,jk,jn,Kmm) - pt(ji+1,jj,jk,jn,Kmm) ) * umask(ji+1,jj,jk)
-
-               ztv_jm1 = ( pt(ji,jj  ,jk,jn,Kmm) - pt(ji,jj-1,jk,jn,Kmm) ) * vmask(ji,jj-1,jk)
-               ztv_jp1 = ( pt(ji,jj+2,jk,jn,Kmm) - pt(ji,jj+1,jk,jn,Kmm) ) * vmask(ji,jj+1,jk)
-
-               zC2t_u = pt(ji,jj,jk,jn,Kmm) + pt(ji+1,jj  ,jk,jn,Kmm)   ! 2 x 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 * ( ztu_im1 - ztu_ip1 )
-               zC4t_v =  zC2t_v + r1_6 * ( ztv_jm1 - ztv_jp1 )
-               !                                                  ! C4 minus upstream advective fluxes 
-               zwx_3d(ji,jj,jk) =  0.5_wp * pU(ji,jj,jk) * zC4t_u - zwx_3d(ji,jj,jk)
-               zwy_3d(ji,jj,jk) =  0.5_wp * pV(ji,jj,jk) * zC4t_v - zwy_3d(ji,jj,jk)
-            END_3D
-            CALL lbc_lnk( 'traadv_fct', zwx_3d, 'U', -1.0_wp , zwy_3d, 'V', -1.0_wp )   ! Lateral boundary cond. (unchanged sgn)
-            !
-         END SELECT
-         !                      
-         SELECT CASE( kn_fct_v )    !* vertical anti-diffusive fluxes (w-masked interior values)
-         !
-         CASE(  2  )                   !- 2nd order centered
-            DO_3D( 1, 1, 1, 1, 2, jpkm1 )
-               zwz(ji,jj,jk) =  (  pW(ji,jj,jk) * 0.5_wp * ( pt(ji,jj,jk,jn,Kmm) + pt(ji,jj,jk-1,jn,Kmm) )   &
-                  &              - zwz(ji,jj,jk)  ) * wmask(ji,jj,jk)
-            END_3D
-            !
-         CASE(  4  )                   !- 4th order COMPACT
-            CALL interp_4th_cpt( pt(:,:,:,jn,Kmm) , ztw )   ! zwt = COMPACT interpolation of T at w-point
-            DO_3D( 1, 1, 1, 1, 2, jpkm1 )
-               zwz(ji,jj,jk) = ( pW(ji,jj,jk) * ztw(ji,jj,jk) - zwz(ji,jj,jk) ) * wmask(ji,jj,jk)
-            END_3D
-            !
-         END SELECT
-         IF( ln_linssh ) THEN    ! top ocean value: high order = upstream  ==>>  zwz=0
-            zwz(:,:,1) = 0._wp   ! only ocean surface as interior zwz values have been w-masked
-         ENDIF
-         !         
-         CALL lbc_lnk( 'traadv_fct', zwi, 'T', 1.0_wp)
-         !
-         IF ( ll_zAimp ) THEN
-            DO_3D( 1, 1, 1, 1, 1, jpkm1 )    !* trend and after field with monotonic scheme
-               !                                                ! total intermediate advective trends
-               ztra = - (  zwx_3d(ji,jj,jk) - zwx_3d(ji-1,jj  ,jk  )   &
-                  &      + zwy_3d(ji,jj,jk) - zwy_3d(ji  ,jj-1,jk  )   &
-                  &      + zwz(ji,jj,jk) - zwz(ji  ,jj  ,jk+1) ) * r1_e1e2t(ji,jj)
-               ztw(ji,jj,jk) = zwi(ji,jj,jk) + p2dt * ztra / e3t(ji,jj,jk,Krhs) * tmask(ji,jj,jk)
-            END_3D
-            !
-            CALL tridia_solver( zwdia, zwsup, zwinf, ztw, ztw , 0 )
-            !
-            DO_3D( 1, 1, 1, 1, 2, jpkm1 )       ! Interior value ( multiplied by wmask)
-               zfp_wk = wi(ji,jj,jk) + ABS( wi(ji,jj,jk) )
-               zfm_wk = wi(ji,jj,jk) - ABS( wi(ji,jj,jk) )
-               zwz(ji,jj,jk) = zwz(ji,jj,jk) + 0.5 * e1e2t(ji,jj) * ( zfp_wk * ztw(ji,jj,jk) + zfm_wk * ztw(ji,jj,jk-1) ) * wmask(ji,jj,jk)
-            END_3D
-         END IF
-         !
-         !        !==  monotonicity algorithm  ==!
-         !
-#if defined key_agrif
-         CALL nonosc( Kmm, pt(:,:,:,jn,Kbb), zwx_3d, zwy_3d, zwz, zwi, p2dt )
-#else
-         CALL nonosc_lf( Kmm, pt(:,:,:,jn,Kbb), zwx_3d, zwy_3d, zwz, zwi, p2dt )
-#endif
-         !
-         !        !==  final trend with corrected fluxes  ==!
-         !
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
-            ztra = - (  zwx_3d(ji,jj,jk) - zwx_3d(ji-1,jj  ,jk  )   &
-               &      + zwy_3d(ji,jj,jk) - zwy_3d(ji  ,jj-1,jk  )   &
-               &      + zwz(ji,jj,jk) - zwz(ji  ,jj  ,jk+1) ) * r1_e1e2t(ji,jj)
-            pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) + ztra / e3t(ji,jj,jk,Kmm)
-            zwi(ji,jj,jk) = zwi(ji,jj,jk) + p2dt * ztra / e3t(ji,jj,jk,Krhs) * tmask(ji,jj,jk)
-         END_3D
-         !
-         IF ( ll_zAimp ) THEN
-            !
-            ztw(:,:,1) = 0._wp ; ztw(:,:,jpk) = 0._wp
-            DO_3D( 0, 0, 0, 0, 2, jpkm1 )      ! Interior value ( multiplied by wmask)
-               zfp_wk = wi(ji,jj,jk) + ABS( wi(ji,jj,jk) )
-               zfm_wk = wi(ji,jj,jk) - ABS( wi(ji,jj,jk) )
-               ztw(ji,jj,jk) = - 0.5 * e1e2t(ji,jj) * ( zfp_wk * zwi(ji,jj,jk) + zfm_wk * zwi(ji,jj,jk-1) ) * wmask(ji,jj,jk)
-               zwz(ji,jj,jk) = zwz(ji,jj,jk) + ztw(ji,jj,jk) ! Update vertical fluxes for trend diagnostic
-            END_3D
-            DO_3D( 0, 0, 0, 0, 1, jpkm1 )
-               pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) - ( ztw(ji,jj,jk) - ztw(ji  ,jj  ,jk+1) ) &
-                  &                                        * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
-            END_3D
-         END IF         
-         ! NOT TESTED - NEED l_trd OR l_hst TRUE 
-         IF( l_trd .OR. l_hst ) THEN   ! trend diagnostics // heat/salt transport
-            ztrdx(:,:,:) = ztrdx(:,:,:) + zwx_3d(:,:,:)  ! <<< add anti-diffusive fluxes 
-            ztrdy(:,:,:) = ztrdy(:,:,:) + zwy_3d(:,:,:)  !     to upstream fluxes
-            ztrdz(:,:,:) = ztrdz(:,:,:) + zwz(:,:,:)  !
-            !
-            IF( l_trd ) THEN              ! trend diagnostics
-               CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_xad, ztrdx, pU, pt(:,:,:,jn,Kmm) )
-               CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_yad, ztrdy, pV, pt(:,:,:,jn,Kmm) )
-               CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_zad, ztrdz, pW, pt(:,:,:,jn,Kmm) )
-            ENDIF
-            !                             ! heat/salt transport
-            IF( l_hst )   CALL dia_ar5_hst( jn, 'adv', ztrdx(:,:,:), ztrdy(:,:,:) )
-            !
-         ENDIF
-         ! NOT TESTED - NEED l_ptr TRUE 
-         IF( l_ptr ) THEN              ! "Poleward" transports
-            zptry(:,:,:) = zptry(:,:,:) + zwy_3d(:,:,:)  ! <<< add anti-diffusive fluxes
-            CALL dia_ptr_hst( jn, 'adv', zptry(:,:,:) )
-         ENDIF
-         !
-      END DO                     ! end of tracer loop
-      !
-      IF ( ll_zAimp ) THEN
-         DEALLOCATE( zwdia, zwinf, zwsup )
-      ENDIF
-      IF( l_trd .OR. l_hst ) THEN 
-         DEALLOCATE( ztrdx, ztrdy, ztrdz )
-      ENDIF
-      IF( l_ptr ) THEN 
-         DEALLOCATE( zptry )
-      ENDIF
-      !
-   END SUBROUTINE tra_adv_fct_lf
-
-   SUBROUTINE nonosc_lf( Kmm, pbef, paa, pbb, pcc, paft, p2dt )
-      !!---------------------------------------------------------------------
-      !!                    ***  ROUTINE nonosc  ***
-      !!     
-      !! **  Purpose :   compute monotonic tracer fluxes from the upstream 
-      !!       scheme and the before field by a nonoscillatory algorithm 
-      !!
-      !! **  Method  :   ... ???
-      !!       warning : pbef and paft must be masked, but the boundaries
-      !!       conditions on the fluxes are not necessary zalezak (1979)
-      !!       drange (1995) multi-dimensional forward-in-time and upstream-
-      !!       in-space based differencing for fluid
-      !!----------------------------------------------------------------------
-      INTEGER                          , INTENT(in   ) ::   Kmm             ! time level index 
-      REAL(wp)                         , INTENT(in   ) ::   p2dt            ! tracer time-step
-      REAL(wp), DIMENSION (jpi,jpj,jpk), INTENT(in   ) ::   pbef, paft      ! before & after field
-      REAL(wp), DIMENSION (jpi,jpj,jpk), INTENT(inout) ::   paa, pbb, pcc   ! monotonic fluxes in the 3 directions
-      REAL(wp), DIMENSION (jpi,jpj,jpk) ::   paa_in, pbb_in, pcc_in   ! monotonic fluxes in the 3 directions
-      !
-      REAL(dp), DIMENSION (jpi,jpj,jpk) :: zbup, zbdo
-      !
-      INTEGER  ::   ji, jj, jk   ! dummy loop indices
-      REAL(dp) ::   zpos, zneg, zbt, za, zb, zc, zbig, zrtrn    ! local scalars
-      REAL(dp) ::   zau, zbu, zcu, zav, zbv, zcv, zup, zdo            !   -      -
-      REAL(dp) ::   zbt_ip1, zpos_ip1, zneg_ip1, zup_ip1, zdo_ip1, zbetup_ip1, zbetdo_ip1 
-      REAL(dp) ::   zbt_jp1, zpos_jp1, zneg_jp1, zup_jp1, zdo_jp1, zbetup_jp1, zbetdo_jp1
-      REAL(dp), TARGET, DIMENSION(jpi,jpj) :: zbetup_buf, zbetdo_buf, zbetup_ptr_buf, zbetdo_ptr_buf
-      REAL(dp), POINTER, DIMENSION(:,:) :: tmp, zbetup, zbetdo, zbetup_ptr, zbetdo_ptr
-      !!----------------------------------------------------------------------
-      !
-      zbig  = 1.e+40_dp
-      zrtrn = 1.e-15_dp
-
-      paa_in(:,:,:) = paa(:,:,:)
-      pbb_in(:,:,:) = pbb(:,:,:)
-      pcc_in(:,:,:) = pcc(:,:,:)
-      ! Search local extrema
-      ! --------------------
-      ! max/min of pbef & paft with large negative/positive value (-/+zbig) inside land
-      zbup = MAX( pbef * tmask - zbig * ( 1._wp - tmask ),   &
-         &        paft * tmask - zbig * ( 1._wp - tmask )  )
-      zbdo = MIN( pbef * tmask + zbig * ( 1._wp - tmask ),   &
-         &        paft * tmask + zbig * ( 1._wp - tmask )  )
-
-      zbetup => zbetup_buf
-      zbetdo => zbetdo_buf
-      zbetup_ptr => zbetup_ptr_buf
-      zbetdo_ptr => zbetdo_ptr_buf
-
-      DO_2D( 1, 0, 1, 0 )
-
-        ! search maximum in neighbourhood
-        search_in_neighbour(zup,MAX,zbup,ji,jj,1)
-        search_in_neighbour(zup_ip1,MAX,zbup,ji+1,jj,1)
-        search_in_neighbour(zup_jp1,MAX,zbup,ji,jj+1,1)
-
-        ! search minimum in neighbourhood
-        search_in_neighbour(zdo,MIN,zbdo,ji,jj,1)
-        search_in_neighbour(zdo_ip1,MIN,zbdo,ji+1,jj,1)
-        search_in_neighbour(zdo_jp1,MIN,zbdo,ji,jj+1,1)
-
-        ! positive part of the flux
-        pos_part_of_flux(ji,jj,1,zpos)
-        pos_part_of_flux(ji+1,jj,1,zpos_ip1)
-        pos_part_of_flux(ji,jj+1,1,zpos_jp1)
-
-        ! negative part of the flux
-        neg_part_of_flux(ji,jj,1,zneg)
-        neg_part_of_flux(ji+1,jj,1,zneg_ip1)
-        neg_part_of_flux(ji,jj+1,1,zneg_jp1)
-
-        ! up & down beta terms
-        beta_terms(zbt,zbetup(ji,jj),zbetdo(ji,jj),zup,zpos,zdo,zneg,ji,jj,1)
-        beta_terms(zbt_ip1,zbetup_ip1,zbetdo_ip1,zup_ip1,zpos_ip1,zdo_ip1,zneg_ip1,ji+1,jj,1)
-        beta_terms(zbt_jp1,zbetup_jp1,zbetdo_jp1,zup_jp1,zpos_jp1,zdo_jp1,zneg_jp1,ji,jj+1,1)
-
-        ! 3. monotonic flux in the i & j (paa & pbb)
-        ! ----------------------------------------
-        monotonic_flux(zau,zbu,zcu,zbetup_ip1,zbetdo_ip1,paa,paa_in,1)
-        monotonic_flux(zav,zbv,zcv,zbetup_jp1,zbetdo_jp1,pbb,pbb_in,1)
-
-      END_2D
-      tmp => zbetup_ptr
-      zbetup_ptr => zbetup
-      zbetup => tmp
-
-      tmp => zbetdo_ptr
-      zbetdo_ptr => zbetdo
-      zbetdo => tmp
-
-      DO jk = 2, jpk-1
-         DO_2D( 1, 0, 1, 0 )
-
-            ! search maximum in neighbourhood
-            search_in_neighbour(zup,MAX,zbup,ji,jj,jk)
-            search_in_neighbour(zup_ip1,MAX,zbup,ji+1,jj,jk)
-            search_in_neighbour(zup_jp1,MAX,zbup,ji,jj+1,jk)
-
-            ! search minimum in neighbourhood
-            search_in_neighbour(zdo,MIN,zbdo,ji,jj,jk)
-            search_in_neighbour(zdo_ip1,MIN,zbdo,ji+1,jj,jk)
-            search_in_neighbour(zdo_jp1,MIN,zbdo,ji,jj+1,jk)
-
-            ! positive part of the flux
-            pos_part_of_flux(ji,jj,jk,zpos)
-            pos_part_of_flux(ji+1,jj,jk,zpos_ip1)
-            pos_part_of_flux(ji,jj+1,jk,zpos_jp1)
-
-            ! negative part of the flux
-            neg_part_of_flux(ji,jj,jk,zneg)
-            neg_part_of_flux(ji+1,jj,jk,zneg_ip1)
-            neg_part_of_flux(ji,jj+1,jk,zneg_jp1)
-
-            ! up & down beta terms
-            beta_terms(zbt,zbetup(ji,jj),zbetdo(ji,jj),zup,zpos,zdo,zneg,ji,jj,jk)
-            beta_terms(zbt_ip1,zbetup_ip1,zbetdo_ip1,zup_ip1,zpos_ip1,zdo_ip1,zneg_ip1,ji+1,jj,jk)
-            beta_terms(zbt_jp1,zbetup_jp1,zbetdo_jp1,zup_jp1,zpos_jp1,zdo_jp1,zneg_jp1,ji,jj+1,jk)
-
-            ! 3. monotonic flux in the i & j (paa & pbb)
-            ! ----------------------------------------
-            monotonic_flux(zau,zbu,zcu,zbetup_ip1,zbetdo_ip1,paa,paa_in,jk)
-            monotonic_flux(zav,zbv,zcv,zbetup_jp1,zbetdo_jp1,pbb,pbb_in,jk)
-
-            ! monotonic flux in the k direction, i.e. pcc
-            ! -------------------------------------------
-            monotonic_flux_k(za,zb,zc,zbetup(ji,jj),zbetdo(ji,jj),pcc,pcc_in,jk)
-         END_2D
-         tmp => zbetup_ptr
-         zbetup_ptr => zbetup
-         zbetup => tmp
-
-         tmp => zbetdo_ptr
-         zbetdo_ptr => zbetdo
-         zbetdo => tmp
-      END DO
-      !
-      DO_2D( 1, 0, 1, 0 )
-        ! monotonic flux in the k direction, i.e. pcc
-        ! -------------------------------------------
-        monotonic_flux_k(za,zb,zc,0._dp,0._dp,pcc,pcc_in,jpk)
-      END_2D
-   END SUBROUTINE nonosc_lf
-
-END MODULE traadv_fct_lf
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv_mus.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv_mus.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv_mus.F90	(revision 14852)
@@ -81,5 +81,5 @@
       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) if using XIOS (subdomain support)
+      ! 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
@@ -93,5 +93,5 @@
       !!----------------------------------------------------------------------
       !
-      IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+      IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
          IF( kt == kit000 )  THEN
             IF(lwp) WRITE(numout,*)
@@ -139,10 +139,8 @@
             zwy(ji,jj,jk) = vmask(ji,jj,jk) * ( pt(ji,jj+1,jk,jn,Kbb) - pt(ji,jj,jk,jn,Kbb) )
          END_3D
-         ! lateral boundary conditions   (changed sign)
-         IF ( nn_hls.EQ.1 ) CALL lbc_lnk( 'traadv_mus', zwx, 'U', -1.0_wp , zwy, 'V', -1.0_wp )
          !                                !-- Slopes of tracer
          zslpx(:,:,jpk) = 0._wp                 ! bottom values
          zslpy(:,:,jpk) = 0._wp
-         DO_3D( nn_hls-1, 1, nn_hls-1, 1, 1, jpkm1 )
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpkm1 )
             zslpx(ji,jj,jk) =                       ( zwx(ji,jj,jk) + zwx(ji-1,jj  ,jk) )   &
                &            * ( 0.25 + SIGN( 0.25_wp, zwx(ji,jj,jk) * zwx(ji-1,jj  ,jk) ) )
@@ -151,5 +149,5 @@
          END_3D
          !
-         DO_3D( nn_hls-1, 1, nn_hls-1, 1, 1, jpkm1 )    !-- Slopes limitation
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpkm1 )    !-- Slopes limitation
             zslpx(ji,jj,jk) = SIGN( 1.0_wp, zslpx(ji,jj,jk) ) * MIN(    ABS( zslpx(ji  ,jj,jk) ),   &
                &                                                     2.*ABS( zwx  (ji-1,jj,jk) ),   &
@@ -159,6 +157,8 @@
                &                                                     2.*ABS( zwy  (ji,jj  ,jk) ) )
          END_3D
-         !
-         DO_3D( nn_hls-1, 0, nn_hls-1, 0, 1, jpkm1 )    !-- MUSCL horizontal advective fluxes
+         ! NOTE [ comm_cleanup ] : need to change sign to ensure halo 1 - halo 2 compatibility
+         IF ( nn_hls==1 ) CALL lbc_lnk( 'traadv_mus', zslpx, 'T', -1.0_wp , zslpy, 'T', -1.0_wp )   ! lateral boundary conditions   (changed sign)
+         !
+         DO_3D( 1, 0, 1, 0, 1, jpkm1 )    !-- MUSCL horizontal advective fluxes
             ! MUSCL fluxes
             z0u = SIGN( 0.5_wp, pU(ji,jj,jk) )
@@ -176,5 +176,4 @@
             zwy(ji,jj,jk) = pV(ji,jj,jk) * ( zalpha * zzwx + (1.-zalpha) * zzwy )
          END_3D
-         IF ( nn_hls.EQ.1 ) CALL lbc_lnk( 'traadv_mus', zwx, 'U', -1.0_wp , zwy, 'V', -1.0_wp )   ! lateral boundary conditions   (changed sign)
          !
          DO_3D( 0, 0, 0, 0, 1, jpkm1 )    !-- Tracer advective trend
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv_mus_lf.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv_mus_lf.F90	(revision 14851)
+++ 	(revision )
@@ -1,289 +1,0 @@
-MODULE traadv_mus_lf
-   !!======================================================================
-   !!                       ***  MODULE  traadv_mus  ***
-   !! Ocean  tracers:  horizontal & vertical advective trend
-   !!======================================================================
-   !! History :       !  2000-06  (A.Estublier)  for passive tracers
-   !!                 !  2001-08  (E.Durand, G.Madec)  adapted for T & S
-   !!   NEMO     1.0  !  2002-06  (G. Madec)  F90: Free form and module
-   !!            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
-   !!----------------------------------------------------------------------
-
-   !!----------------------------------------------------------------------
-   !!   tra_adv_mus   : update the tracer trend with the horizontal
-   !!                   and vertical advection trends using MUSCL scheme
-   !!----------------------------------------------------------------------
-   USE oce            ! ocean dynamics and active tracers
-   USE trc_oce        ! share passive tracers/Ocean variables
-   USE dom_oce        ! ocean space and time domain
-   USE trd_oce        ! trends: ocean variables
-   USE trdtra         ! tracers trends manager
-   USE sbcrnf         ! river runoffs
-   USE diaptr         ! poleward transport diagnostics
-   USE diaar5         ! AR5 diagnostics
-
-   !
-   USE iom            ! XIOS library
-   USE in_out_manager ! I/O manager
-   USE lib_mpp        ! distribued memory computing
-   USE lib_fortran    ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined)  
-
-   IMPLICIT NONE
-   PRIVATE
-
-   PUBLIC   tra_adv_mus_lf   ! 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)
-   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   xind     !: mixed upstream/centered index
-   
-   LOGICAL  ::   l_trd   ! flag to compute trends
-   LOGICAL  ::   l_ptr   ! flag to compute poleward transport
-   LOGICAL  ::   l_hst   ! flag to compute heat/salt transport
-
-   !! * Substitutions
-#  include "do_loop_substitute.h90"
-#  include "domzgr_substitute.h90"
-
-#define initial_slop_i(out, ji) \
-        out = umask(ji,jj,jk) * ( pt(ji+1,jj,jk,jn,Kbb) - pt(ji,jj,jk,jn,Kbb) )
-
-#define initial_slop_j(out, jj) \
-        out = vmask(ji,jj,jk) * ( pt(ji,jj+1,jk,jn,Kbb) - pt(ji,jj,jk,jn,Kbb) )
-
-#define initial_slop_k(out, jk) \
-        out = tmask(ji,jj,jk) * ( pt(ji,jj,jk-1,jn,Kbb) - pt(ji,jj,jk,jn,Kbb) )
-
-#define tracer_slop(out, zzw, zzwm1) \
-        out = ( zzw + zzwm1 ) * ( 0.25 + SIGN( 0.25_wp, zzw * zzwm1 ) )
-
-#define limitation_slop(out, zzslp, zzwm1, zzw) \
-        out = SIGN( 1.0_wp, zzslp ) * MIN( ABS( zzslp ), 2.*ABS( zzwm1 ), 2.*ABS( zzw ) )
-
-#define vertical_adv_flux_i(out, jk, slp, slp1) \
-        z0u = SIGN( 0.5_wp, pU(ji,jj,jk) ) ; \
-        zalpha = 0.5 - z0u ; \
-        zu  = z0u - 0.5 * 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 * slp1 ; \
-        zzwy = pt(ji  ,jj,jk,jn,Kbb) + xind(ji,jj,jk) * zu * slp ; \
-        out = pU(ji,jj,jk) * ( zalpha * zzwx + (1.-zalpha) * zzwy )
-
-#define vertical_adv_flux_j(out, jk, slp, slp1) \
-        z0v = SIGN( 0.5_wp, pV(ji,jj,jk) ) ; \
-        zalpha = 0.5 - z0v ; \
-        zv  = z0v - 0.5 * 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 * slp1 ; \
-        zzwy = pt(ji,jj  ,jk,jn,Kbb) + xind(ji,jj,jk) * zv * slp ; \
-        out = pV(ji,jj,jk) * ( zalpha * zzwx + (1.-zalpha) * zzwy )
-
-#define vertical_adv_flux(out, jk, slp, slp1) \
-        z0w = SIGN( 0.5_wp, pW(ji,jj,jk+1) ) ; \
-        zalpha = 0.5 + z0w ; \
-        zw  = z0w - 0.5 * 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 * slp1 ; \
-        zzwy = pt(ji,jj,jk  ,jn,Kbb) + xind(ji,jj,jk) * zw * slp ; \
-        out = pW(ji,jj,jk+1) * ( zalpha * zzwx + (1.-zalpha) * zzwy ) * wmask(ji,jj,jk) 
-
-   !!----------------------------------------------------------------------
-   !!----------------------------------------------------------------------
-   !! NEMO/OCE 4.0 , NEMO Consortium (2018)
-   !! $Id: traadv_mus.F90 13619 2020-10-16 08:41:21Z francesca $ 
-   !! Software governed by the CeCILL license (see ./LICENSE)
-   !!----------------------------------------------------------------------
-CONTAINS
-
-   SUBROUTINE tra_adv_mus_lf( 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
-      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) ::   zu, z0u, zw , zalpha   ! local scalars
-      REAL(wp) ::   zv, z0v, z0w           !   -      -
-      REAL(wp) ::   zzwx, zzwxm1, zzwxp1, zzwy, zzwym1, zzwyp1
-      REAL(wp) ::   zzslpx, zzslpxp1, zzslpy, zzslpyp1
-      REAL(wp), TARGET, DIMENSION(jpi,jpj) :: zzwz_buf, zzwzp1_buf, zzwzp2_buf
-      REAL(wp), TARGET, DIMENSION(jpi,jpj) :: zzslpz_buf, zzslpzp1_buf
-      REAL(wp), POINTER, DIMENSION(:,:)    :: tmp, zzwz_ptr, zzwzp1_ptr, zzwzp2_ptr
-      REAL(wp), POINTER, DIMENSION(:,:)    :: zzslpz_ptr, zzslpzp1_ptr 
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zwz, zwx, zwy   ! 3D workspace
-      !!----------------------------------------------------------------------
-      !
-      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)
-            ALLOCATE( upsmsk(jpi,jpj), STAT=ierr )
-            upsmsk(:,:) = 0._wp                             ! not upstream by default
-            !
-            DO jk = 1, jpkm1
-               xind(:,:,jk) = 1._wp                              &                 ! =>1 where up-stream is not needed
-                  &         - MAX ( rnfmsk(:,:) * rnfmsk_z(jk),  &                 ! =>0 near runoff mouths (& closed sea outflows)
-                  &                 upsmsk(:,:)                ) * tmask(:,:,jk)   ! =>0 in some user defined area
-            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(   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.
-      !
-         zzwz_ptr => zzwz_buf
-         zzwzp1_ptr => zzwzp1_buf
-         zzwzp2_ptr => zzwzp2_buf
-         zzslpz_ptr => zzslpz_buf
-         zzslpzp1_ptr => zzslpzp1_buf
-         !
-      DO jn = 1, kjpt            !==  loop over the tracers  ==!
-         !
-         zwx(:,:,jpk) = 0._wp                   ! bottom values
-         zwy(:,:,jpk) = 0._wp
-         zwz(:,:, 1 ) = 0._wp                   ! surface & bottom boundary conditions
-         zwz(:,:,jpk) = 0._wp
-         !                          !* Horizontal advective fluxes
-         !
-         !!----------------------------------------------------------------------
-         DO_3D( 1, 0, 1, 0, 1, jpkm1 )
-            !-- first guess of the slopes
-            initial_slop_i(zzwxm1, ji-1)
-            initial_slop_i(zzwx, ji)
-            initial_slop_i(zzwxp1, ji+1)
-
-            initial_slop_j(zzwym1, jj-1)
-            initial_slop_j(zzwy, jj)
-            initial_slop_j(zzwyp1, jj+1)
-            !-- Slopes of tracer
-            tracer_slop(zzslpx, zzwx, zzwxm1) 
-            tracer_slop(zzslpxp1, zzwxp1, zzwx) 
-            tracer_slop(zzslpy, zzwy, zzwym1) 
-            tracer_slop(zzslpyp1, zzwyp1, zzwy) 
-            !-- Slopes limitation
-            limitation_slop(zzslpx, zzslpx, zzwxm1, zzwx)
-            limitation_slop(zzslpxp1, zzslpxp1, zzwx, zzwxp1)
-            limitation_slop(zzslpy, zzslpy, zzwym1, zzwy)
-            limitation_slop(zzslpyp1, zzslpyp1, zzwy, zzwyp1)
-            !-- MUSCL horizontal advective fluxes
-            vertical_adv_flux_i(zwx(ji,jj,jk), jk, zzslpx, zzslpxp1) 
-            vertical_adv_flux_j(zwy(ji,jj,jk), jk, zzslpy, zzslpyp1) 
-         END_3D
-         !
-         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  ) )     &
-            &                                     * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
-         END_3D
-         !                          !* Vertical advective fluxes
-         DO_2D( 0, 0, 0, 0 ) 
-            !-- first guess of the slopes
-            initial_slop_k(zzwz_ptr(ji,jj), 2)
-            initial_slop_k(zzwzp1_ptr(ji,jj), 3)
-            !-- Slopes of tracer
-            tracer_slop(zzslpz_ptr(ji,jj), zzwz_ptr(ji,jj), zzwzp1_ptr(ji,jj))
-            !-- Slopes limitation
-            limitation_slop(zzslpz_ptr(ji,jj), zzslpz_ptr(ji,jj), zzwzp1_ptr(ji,jj), zzwz_ptr(ji,jj))
-            !-- vertical advective flux
-            vertical_adv_flux(zwz(ji,jj,2), 1, 0, zzslpz_ptr(ji,jj))
-         END_2D
-         
-         DO jk = 2, jpk-3    
-            DO_2D( 0, 0, 0, 0 )
-               !-- first guess of the slopes
-               initial_slop_k(zzwzp2_ptr(ji,jj), jk+2)
-               !-- Slopes of tracer
-               tracer_slop(zzslpzp1_ptr(ji,jj), zzwzp1_ptr(ji,jj), zzwzp2_ptr(ji,jj))
-               !-- Slopes limitation
-               limitation_slop(zzslpzp1_ptr(ji,jj), zzslpzp1_ptr(ji,jj), zzwzp2_ptr(ji,jj), zzwzp1_ptr(ji,jj))
-               !-- vertical advective flux
-               vertical_adv_flux(zwz(ji,jj,jk+1), jk, zzslpz_ptr(ji,jj), zzslpzp1_ptr(ji,jj))
-            END_2D
-            tmp => zzwzp1_ptr
-            zzwzp1_ptr => zzwzp2_ptr
-            zzwzp2_ptr => tmp
-
-            tmp => zzslpz_ptr
-            zzslpz_ptr => zzslpzp1_ptr
-            zzslpzp1_ptr => tmp 
-         END DO
-         DO_2D( 0, 0, 0, 0 ) 
-            !-- Slopes of tracer
-            tracer_slop(zzslpzp1_ptr(ji,jj), zzwzp1_ptr(ji,jj), 0)
-            !-- Slopes limitation
-            limitation_slop(zzslpzp1_ptr(ji,jj), zzslpzp1_ptr(ji,jj), 0, zzwzp1_ptr(ji,jj))
-            !-- vertical advective flux
-            vertical_adv_flux(zwz(ji,jj,jpk-1), jpk-2, zzslpz_ptr(ji,jj), zzslpzp1_ptr(ji,jj))
-         END_2D
-
-         IF( ln_linssh ) THEN                   ! top values, linear free surface only
-            IF( ln_isfcav ) THEN                      ! ice-shelf cavities (top of the ocean)
-               DO_2D( 1, 1, 1, 1 )
-                  zwz(ji,jj, mikt(ji,jj) ) = pW(ji,jj,mikt(ji,jj)) * pt(ji,jj,mikt(ji,jj),jn,Kbb)
-               END_2D
-            ELSE                                      ! no cavities: only at the ocean surface
-               zwz(:,:,1) = pW(:,:,1) * pt(:,:,1,jn,Kbb)
-            ENDIF
-         ENDIF
-         !
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )     !-- vertical advective trend
-            pt(ji,jj,jk,jn,Krhs) =  pt(ji,jj,jk,jn,Krhs) - ( zwz(ji,jj,jk) - zwz(ji,jj,jk+1) )   &
-               &                                      * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
-         END_3D
-         !                                ! trend horizontal diagnostics
-         IF( l_trd )  THEN
-            CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_xad, zwx, pU, pt(:,:,:,jn,Kbb) )
-            CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_yad, zwy, pV, pt(:,:,:,jn,Kbb) )
-         END IF
-         !                                 ! "Poleward" heat and salt transports 
-         IF( l_ptr )  CALL dia_ptr_hst( jn, 'adv', zwy(:,:,:) )
-         !                                 !  heat transport
-         IF( l_hst )  CALL dia_ar5_hst( jn, 'adv', zwx(:,:,:), zwy(:,:,:) )
-         !
-         !                                ! send vertical trends for diagnostic
-         IF( l_trd )  CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_zad, zwz, pW, pt(:,:,:,jn,Kbb) )
-         !
-      END DO                     ! end of tracer loop
-      !
-   END SUBROUTINE tra_adv_mus_lf
-
-   !!======================================================================
-END MODULE traadv_mus_lf
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv_qck.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv_qck.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv_qck.F90	(revision 14852)
@@ -27,4 +27,7 @@
    USE lbclnk          ! ocean lateral boundary condition (or mpp link)
    USE lib_fortran     ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined)
+#if defined key_loop_fusion
+   USE traadv_qck_lf   ! QCK    scheme            (tra_adv_qck  routine - loop fusion version)
+#endif
 
    IMPLICIT NONE
@@ -91,10 +94,13 @@
       INTEGER                                  , INTENT(in   ) ::   kjpt            ! number of tracers
       REAL(wp)                                 , INTENT(in   ) ::   p2dt            ! tracer time-step
-      ! TEMP: [tiling] This can be A2D(nn_hls) if using XIOS (subdomain support)
+      ! 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 transport components
       REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt,jpt), INTENT(inout) ::   pt              ! tracers and RHS of tracer equation
       !!----------------------------------------------------------------------
       !
-      IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+#if defined key_loop_fusion
+      CALL tra_adv_qck_lf ( kt, kit000, cdtype, p2dt, pU, pV, pW, Kbb, Kmm, pt, kjpt, Krhs )
+#else
+      IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
          IF( kt == kit000 )  THEN
             IF(lwp) WRITE(numout,*)
@@ -117,4 +123,5 @@
       CALL tra_adv_cen2_k( kt, cdtype, pW, Kmm, pt, kjpt, Krhs )
       !
+#endif
    END SUBROUTINE tra_adv_qck
 
@@ -129,5 +136,5 @@
       INTEGER                                  , INTENT(in   ) ::   kjpt       ! number of tracers
       REAL(wp)                                 , INTENT(in   ) ::   p2dt       ! tracer time-step
-      ! TEMP: [tiling] This can be A2D(nn_hls) if using XIOS (subdomain support)
+      ! 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        ! i-velocity components
       REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt,jpt), INTENT(inout) ::   pt              ! active tracers and RHS of tracer equation
@@ -149,5 +156,5 @@
             zfd(ji,jj,jk) = pt(ji+1,jj,jk,jn,Kbb)        ! Downstream in the x-direction for the tracer
          END_3D
-         IF (nn_hls.EQ.1) CALL lbc_lnk( 'traadv_qck', zfc(:,:,:), 'T', 1.0_wp , zfd(:,:,:), 'T', 1.0_wp )   ! Lateral boundary conditions
+         IF (nn_hls==1) CALL lbc_lnk( 'traadv_qck', zfc(:,:,:), 'T', 1.0_wp , zfd(:,:,:), 'T', 1.0_wp, ld4only= .TRUE. )   ! Lateral boundary conditions
 
          !
@@ -167,5 +174,5 @@
          END_3D
          !--- Lateral boundary conditions
-         IF (nn_hls.EQ.1) CALL lbc_lnk( 'traadv_qck', zfu(:,:,:), 'T', 1.0_wp , zfd(:,:,:), 'T', 1.0_wp, zfc(:,:,:), 'T', 1.0_wp,  zwx(:,:,:), 'T', 1.0_wp )
+         IF (nn_hls==1) CALL lbc_lnk( 'traadv_qck', zfu(:,:,:), 'T', 1.0_wp , zfd(:,:,:), 'T', 1.0_wp, zfc(:,:,:), 'T', 1.0_wp,  zwx(:,:,:), 'T', 1.0_wp )
 
          !--- QUICKEST scheme
@@ -176,5 +183,5 @@
             zfu(ji,jj,jk) = tmask(ji-1,jj,jk) + tmask(ji,jj,jk) + tmask(ji+1,jj,jk) - 2.
          END_3D
-         IF (nn_hls.EQ.1) CALL lbc_lnk( 'traadv_qck', zfu(:,:,:), 'T', 1.0_wp )      ! Lateral boundary conditions
+         IF (nn_hls==1) CALL lbc_lnk( 'traadv_qck', zfu(:,:,:), 'T', 1.0_wp, ld4only= .TRUE. )      ! Lateral boundary conditions
 
          !
@@ -214,5 +221,5 @@
       INTEGER                                  , INTENT(in   ) ::   kjpt       ! number of tracers
       REAL(wp)                                 , INTENT(in   ) ::   p2dt       ! tracer time-step
-      ! TEMP: [tiling] This can be A2D(nn_hls) if using XIOS (subdomain support)
+      ! 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   ) ::   pV        ! j-velocity components
       REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt,jpt), INTENT(inout) ::   pt              ! active tracers and RHS of tracer equation
@@ -229,15 +236,13 @@
          zfd(:,:,:) = 0.0     ;   zwy(:,:,:) = 0.0
          !
-         DO jk = 1, jpkm1
-            !
-            !--- Computation of the ustream and downstream value of the tracer and the mask
-            DO_2D( 0, 0, nn_hls-1, nn_hls-1 )
-               ! Upstream in the x-direction for the tracer
-               zfc(ji,jj,jk) = pt(ji,jj-1,jk,jn,Kbb)
-               ! Downstream in the x-direction for the tracer
-               zfd(ji,jj,jk) = pt(ji,jj+1,jk,jn,Kbb)
-            END_2D
-         END DO
-         IF (nn_hls.EQ.1) CALL lbc_lnk( 'traadv_qck', zfc(:,:,:), 'T', 1.0_wp , zfd(:,:,:), 'T', 1.0_wp )   ! Lateral boundary conditions
+         !--- Computation of the ustream and downstream value of the tracer and the mask
+         DO_3D( 0, 0, nn_hls-1, nn_hls-1, 1, jpkm1 )
+            ! Upstream in the x-direction for the tracer
+            zfc(ji,jj,jk) = pt(ji,jj-1,jk,jn,Kbb)
+            ! Downstream in the x-direction for the tracer
+            zfd(ji,jj,jk) = pt(ji,jj+1,jk,jn,Kbb)
+         END_3D
+
+         IF (nn_hls==1) CALL lbc_lnk( 'traadv_qck', zfc(:,:,:), 'T', 1.0_wp , zfd(:,:,:), 'T', 1.0_wp, ld4only= .TRUE. )   ! Lateral boundary conditions
 
          !
@@ -259,5 +264,5 @@
 
          !--- Lateral boundary conditions
-         IF (nn_hls.EQ.1) CALL lbc_lnk( 'traadv_qck', zfu(:,:,:), 'T', 1.0_wp , zfd(:,:,:), 'T', 1.0_wp, zfc(:,:,:), 'T', 1.0_wp, zwy(:,:,:), 'T', 1.0_wp )
+         IF (nn_hls==1) CALL lbc_lnk( 'traadv_qck', zfu(:,:,:), 'T', 1.0_wp , zfd(:,:,:), 'T', 1.0_wp, zfc(:,:,:), 'T', 1.0_wp, zwy(:,:,:), 'T', 1.0_wp )
 
          !--- QUICKEST scheme
@@ -268,5 +273,5 @@
             zfu(ji,jj,jk) = tmask(ji,jj-1,jk) + tmask(ji,jj,jk) + tmask(ji,jj+1,jk) - 2.
          END_3D
-         IF (nn_hls.EQ.1) CALL lbc_lnk( 'traadv_qck', zfu(:,:,:), 'T', 1.0_wp )    !--- Lateral boundary conditions
+         IF (nn_hls==1) CALL lbc_lnk( 'traadv_qck', zfu(:,:,:), 'T', 1.0_wp, ld4only= .TRUE. )    !--- Lateral boundary conditions
          !
          ! Tracer flux on the x-direction
@@ -306,5 +311,5 @@
       CHARACTER(len=3)                         , INTENT(in   ) ::   cdtype   ! =TRA or TRC (tracer indicator)
       INTEGER                                  , INTENT(in   ) ::   kjpt     ! number of tracers
-      ! TEMP: [tiling] This can be A2D(nn_hls) if using XIOS (subdomain support)
+      ! 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   ) ::   pW      ! vertical velocity
       REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt,jpt), INTENT(inout) ::   pt              ! active tracers and RHS of tracer equation
@@ -365,5 +370,5 @@
       !----------------------------------------------------------------------
       !
-      DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpkm1 )
+      DO_3D( 1, 0, 1, 0, 1, jpkm1 )
          zc     = puc(ji,jj,jk)                         ! Courant number
          zcurv  = pfd(ji,jj,jk) + pfu(ji,jj,jk) - 2. * pfc(ji,jj,jk)
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv_qck_lf.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv_qck_lf.F90	(revision 14852)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv_qck_lf.F90	(revision 14852)
@@ -0,0 +1,374 @@
+MODULE traadv_qck_lf
+   !!==============================================================================
+   !!                       ***  MODULE  traadv_qck  ***
+   !! Ocean tracers:  horizontal & vertical advective trend
+   !!==============================================================================
+   !! History :  3.0  !  2008-07  (G. Reffray)  Original code
+   !!            3.3  !  2010-05  (C.Ethe, G. Madec)  merge TRC-TRA + switch from velocity to transport
+   !!----------------------------------------------------------------------
+
+   !!----------------------------------------------------------------------
+   !!   tra_adv_qck    : update the tracer trend with the horizontal advection
+   !!                    trends using a 3rd order finite difference scheme
+   !!   tra_adv_qck_i  : apply QUICK scheme in i-direction
+   !!   tra_adv_qck_j  : apply QUICK scheme in j-direction
+   !!   tra_adv_cen2_k : 2nd centered scheme for the vertical advection
+   !!----------------------------------------------------------------------
+   USE oce             ! ocean dynamics and active tracers
+   USE dom_oce         ! ocean space and time domain
+   USE trc_oce         ! share passive tracers/Ocean variables
+   USE trd_oce         ! trends: ocean variables
+   USE trdtra          ! trends manager: tracers
+   USE diaptr          ! poleward transport diagnostics
+   USE iom
+   !
+   USE in_out_manager  ! I/O manager
+   USE lib_mpp         ! distribued memory computing
+   USE lbclnk          ! ocean lateral boundary condition (or mpp link)
+   USE lib_fortran     ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined)
+
+   IMPLICIT NONE
+   PRIVATE
+
+   PUBLIC   tra_adv_qck_lf   ! routine called by step.F90
+
+   REAL(wp) :: r1_6 = 1./ 6.   ! 1/6 ratio
+
+   LOGICAL  ::   l_trd   ! flag to compute trends
+   LOGICAL  ::   l_ptr   ! flag to compute poleward transport
+
+
+   !! * Substitutions
+#  include "do_loop_substitute.h90"
+#  include "domzgr_substitute.h90"
+   !!----------------------------------------------------------------------
+   !! NEMO/OCE 4.0 , NEMO Consortium (2018)
+   !! $Id: traadv_qck.F90 14776 2021-04-30 12:33:41Z mocavero $
+   !! Software governed by the CeCILL license (see ./LICENSE)
+   !!----------------------------------------------------------------------
+CONTAINS
+
+   SUBROUTINE tra_adv_qck_lf ( kt, kit000, cdtype, p2dt, pU, pV, pW, Kbb, Kmm, pt, kjpt, Krhs )
+      !!----------------------------------------------------------------------
+      !!                  ***  ROUTINE tra_adv_qck  ***
+      !!
+      !! ** 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 third order scheme
+      !!             For a positive velocity u :              u(i)>0
+      !!                                          |--FU--|--FC--|--FD--|------|
+      !!                                             i-1    i      i+1   i+2
+      !!
+      !!             For a negative velocity u :              u(i)<0
+      !!                                          |------|--FD--|--FC--|--FU--|
+      !!                                             i-1    i      i+1   i+2
+      !!             where  FU is the second upwind point
+      !!                    FD is the first douwning point
+      !!                    FC is the central point (or the first upwind point)
+      !!
+      !!      Flux(i) = u(i) * { 0.5(FC+FD)  -0.5C(i)(FD-FC)  -((1-C(i))/6)(FU+FD-2FC) }
+      !!                with C(i)=|u(i)|dx(i)/dt (=Courant number)
+      !!
+      !!         dt = 2*rdtra and the scalar values are tb and sb
+      !!
+      !!       On the vertical, the simple centered scheme used pt(:,:,:,:,Kmm)
+      !!
+      !!               The fluxes are bounded by the ULTIMATE limiter to
+      !!             guarantee the monotonicity of the solution and to
+      !!            prevent the appearance of spurious numerical oscillations
+      !!
+      !! ** 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)
+      !!
+      !! ** Reference : Leonard (1979, 1991)
+      !!----------------------------------------------------------------------
+      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
+      REAL(wp)                                 , INTENT(in   ) ::   p2dt            ! tracer time-step
+      ! TEMP: [tiling] This can be A2D(nn_hls) if using XIOS (subdomain support)
+      REAL(wp), DIMENSION(jpi,jpj,jpk         ), INTENT(in   ) ::   pU, pV, pW      ! 3 ocean volume transport components
+      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt,jpt), INTENT(inout) ::   pt              ! tracers and RHS of tracer equation
+      !!----------------------------------------------------------------------
+      !
+      IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+         IF( kt == kit000 )  THEN
+            IF(lwp) WRITE(numout,*)
+            IF(lwp) WRITE(numout,*) 'tra_adv_qck : 3rd order quickest advection scheme on ', cdtype
+            IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~'
+            IF(lwp) WRITE(numout,*)
+         ENDIF
+         !
+         l_trd = .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.
+      ENDIF
+      !
+      !        ! horizontal fluxes are computed with the QUICKEST + ULTIMATE scheme
+      CALL tra_adv_qck_i( kt, cdtype, p2dt, pU, Kbb, Kmm, pt, kjpt, Krhs )
+      CALL tra_adv_qck_j( kt, cdtype, p2dt, pV, Kbb, Kmm, pt, kjpt, Krhs )
+
+      !        ! vertical fluxes are computed with the 2nd order centered scheme
+      CALL tra_adv_cen2_k( kt, cdtype, pW, Kmm, pt, kjpt, Krhs )
+      !
+   END SUBROUTINE tra_adv_qck_lf
+
+
+   SUBROUTINE tra_adv_qck_i( kt, cdtype, p2dt, pU, Kbb, Kmm, pt, kjpt, Krhs )
+      !!----------------------------------------------------------------------
+      !!
+      !!----------------------------------------------------------------------
+      INTEGER                                  , INTENT(in   ) ::   kt         ! ocean time-step index
+      INTEGER                                  , INTENT(in   ) ::   Kbb, Kmm, Krhs  ! ocean time level indices
+      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
+      ! TEMP: [tiling] This can be A2D(nn_hls) if using XIOS (subdomain support)
+      REAL(wp), DIMENSION(jpi,jpj,jpk         ), INTENT(in   ) ::   pU        ! i-velocity components
+      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt,jpt), INTENT(inout) ::   pt              ! active tracers and RHS of tracer equation
+      !!
+      INTEGER  ::   ji, jj, jk, jn   ! dummy loop indices
+      REAL(wp) ::   ztra, zbtr, zdir, zdx, zmsk  ! local scalars
+      REAL(wp) ::   zzfc, zzfd, zzfu, zzfu_ip1   !   -     -
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zwx, zfu, zfc, zfd
+      !----------------------------------------------------------------------
+      !
+      !                                                          ! ===========
+      DO jn = 1, kjpt                                            ! tracer loop
+         !                                                       ! ===========
+         zfu(:,:,:) = 0._wp     ;   zfc(:,:,:) = 0._wp
+         zfd(:,:,:) = 0._wp     ;   zwx(:,:,:) = 0._wp
+         !
+!!gm why not using a SHIFT instruction...
+         DO_3D( 1, 0, 0, 0, 1, jpkm1 )     !--- Computation of the ustream and downstream value of the tracer and the mask
+            zzfc = pt(ji-1,jj,jk,jn,Kbb)        ! Upstream   in the x-direction for the tracer
+            zzfd = pt(ji+2,jj,jk,jn,Kbb)        ! Downstream in the x-direction for the tracer
+            !
+            ! Horizontal advective fluxes
+            ! ---------------------------
+            zdir = 0.5 + SIGN( 0.5_wp, pU(ji,jj,jk) )   ! if pU > 0 : zdir = 1 otherwise zdir = 0
+            zfu(ji,jj,jk) = zdir * zzfc + ( 1. - zdir ) * zzfd  ! FU in the x-direction for T
+            !
+            zdir = 0.5 + SIGN( 0.5_wp, pU(ji,jj,jk) )   ! if pU > 0 : zdir = 1 otherwise zdir = 0
+            zdx = ( zdir * e1t(ji,jj) + ( 1. - zdir ) * e1t(ji+1,jj) ) * e2u(ji,jj) * e3u(ji,jj,jk,Kmm)
+            zwx(ji,jj,jk)  = ABS( pU(ji,jj,jk) ) * p2dt / zdx    ! (0<zc_cfl<1 : Courant number on x-direction)
+            zfc(ji,jj,jk)  = zdir * pt(ji  ,jj,jk,jn,Kbb) + ( 1. - zdir ) * pt(ji+1,jj,jk,jn,Kbb)  ! FC in the x-direction for T
+            zfd(ji,jj,jk)  = zdir * pt(ji+1,jj,jk,jn,Kbb) + ( 1. - zdir ) * pt(ji  ,jj,jk,jn,Kbb)  ! FD in the x-direction for T
+         END_3D
+         !--- Lateral boundary conditions
+
+         !--- QUICKEST scheme
+         CALL quickest( zfu, zfd, zfc, zwx )
+         !
+         ! Mask at the T-points in the x-direction (mask=0 or mask=1)
+         DO_3D( 1, 0, 0, 0, 1, jpkm1 )
+            zzfu = tmask(ji-1,jj,jk) + tmask(ji,jj,jk) + tmask(ji+1,jj,jk) - 2.
+            zzfu_ip1 = tmask(ji,jj,jk) + tmask(ji+1,jj,jk) + tmask(ji+2,jj,jk) - 2.
+            !
+            ! Tracer flux on the x-direction
+            zdir = 0.5 + SIGN( 0.5_wp, pU(ji,jj,jk) )   ! if pU > 0 : zdir = 1 otherwise zdir = 0
+            !--- If the second ustream point is a land point
+            !--- the flux is computed by the 1st order UPWIND scheme
+            zmsk = zdir * zzfu + ( 1. - zdir ) * zzfu_ip1
+            zwx(ji,jj,jk) = zmsk * zwx(ji,jj,jk) + ( 1. - zmsk ) * zfc(ji,jj,jk)
+            zwx(ji,jj,jk) = zwx(ji,jj,jk) * pU(ji,jj,jk)
+         END_3D
+         !
+         ! Computation of the trend
+         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+            zbtr = r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
+            ! horizontal advective trends
+            ztra = - zbtr * ( zwx(ji,jj,jk) - zwx(ji-1,jj,jk) )
+            !--- add it to the general tracer trends
+            pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) + ztra
+         END_3D
+         !                                 ! trend diagnostics
+         IF( l_trd )   CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_xad, zwx, pU, pt(:,:,:,jn,Kmm) )
+         !
+      END DO
+      !
+   END SUBROUTINE tra_adv_qck_i
+
+
+   SUBROUTINE tra_adv_qck_j( kt, cdtype, p2dt, pV, Kbb, Kmm, pt, kjpt, Krhs )
+      !!----------------------------------------------------------------------
+      !!
+      !!----------------------------------------------------------------------
+      INTEGER                                  , INTENT(in   ) ::   kt         ! ocean time-step index
+      INTEGER                                  , INTENT(in   ) ::   Kbb, Kmm, Krhs  ! ocean time level indices
+      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
+      ! TEMP: [tiling] This can be A2D(nn_hls) if using XIOS (subdomain support)
+      REAL(wp), DIMENSION(jpi,jpj,jpk         ), INTENT(in   ) ::   pV        ! j-velocity components
+      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt,jpt), INTENT(inout) ::   pt              ! active tracers and RHS of tracer equation
+      !!
+      INTEGER  :: ji, jj, jk, jn                ! dummy loop indices
+      REAL(wp) :: ztra, zbtr, zdir, zdx, zmsk   ! local scalars
+      REAL(wp) :: zzfc, zzfd, zzfu, zzfu_jp1    !   -     -
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zwy, zfu, zfc, zfd   ! 3D workspace
+      !----------------------------------------------------------------------
+      !
+      !                                                          ! ===========
+      DO jn = 1, kjpt                                            ! tracer loop
+         !                                                       ! ===========
+         zfu(:,:,:) = 0.0     ;   zfc(:,:,:) = 0.0
+         zfd(:,:,:) = 0.0     ;   zwy(:,:,:) = 0.0
+         !
+         !--- Computation of the ustream and downstream value of the tracer and the mask
+         DO_3D( 0, 0, 1, 0, 1, jpkm1 )
+            ! Upstream in the x-direction for the tracer
+            zzfc = pt(ji,jj-1,jk,jn,Kbb)
+            ! Downstream in the x-direction for the tracer
+            zzfd = pt(ji,jj+2,jk,jn,Kbb)
+            !
+            ! Horizontal advective fluxes
+            ! ---------------------------
+            !
+            zdir = 0.5 + SIGN( 0.5_wp, pV(ji,jj,jk) )   ! if pU > 0 : zdir = 1 otherwise zdir = 0
+            zfu(ji,jj,jk) = zdir * zzfc + ( 1. - zdir ) * zzfd  ! FU in the x-direction for T
+            !
+            zdir = 0.5 + SIGN( 0.5_wp, pV(ji,jj,jk) )   ! if pU > 0 : zdir = 1 otherwise zdir = 0
+            zdx = ( zdir * e2t(ji,jj) + ( 1. - zdir ) * e2t(ji,jj+1) ) * e1v(ji,jj) * e3v(ji,jj,jk,Kmm)
+            zwy(ji,jj,jk)  = ABS( pV(ji,jj,jk) ) * p2dt / zdx    ! (0<zc_cfl<1 : Courant number on x-direction)
+            zfc(ji,jj,jk)  = zdir * pt(ji,jj  ,jk,jn,Kbb) + ( 1. - zdir ) * pt(ji,jj+1,jk,jn,Kbb)  ! FC in the x-direction for T
+            zfd(ji,jj,jk)  = zdir * pt(ji,jj+1,jk,jn,Kbb) + ( 1. - zdir ) * pt(ji,jj  ,jk,jn,Kbb)  ! FD in the x-direction for T
+         END_3D
+
+         !--- QUICKEST scheme
+         CALL quickest( zfu, zfd, zfc, zwy )
+         !
+         ! Mask at the T-points in the x-direction (mask=0 or mask=1)
+         DO_3D( 0, 0, 1, 0, 1, jpkm1 )
+            zzfu = tmask(ji,jj-1,jk) + tmask(ji,jj,jk) + tmask(ji,jj+1,jk) - 2.
+            zzfu_jp1 = tmask(ji,jj,jk) + tmask(ji,jj+1,jk) + tmask(ji,jj+2,jk) - 2.
+            !
+            ! Tracer flux on the x-direction
+            zdir = 0.5 + SIGN( 0.5_wp, pV(ji,jj,jk) )   ! if pU > 0 : zdir = 1 otherwise zdir = 0
+            !--- If the second ustream point is a land point
+            !--- the flux is computed by the 1st order UPWIND scheme
+            zmsk = zdir * zzfu + ( 1. - zdir ) * zzfu_jp1
+            zwy(ji,jj,jk) = zmsk * zwy(ji,jj,jk) + ( 1. - zmsk ) * zfc(ji,jj,jk)
+            zwy(ji,jj,jk) = zwy(ji,jj,jk) * pV(ji,jj,jk)
+         END_3D
+         !
+         ! Computation of the trend
+         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+            zbtr = r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
+            ! horizontal advective trends
+            ztra = - zbtr * ( zwy(ji,jj,jk) - zwy(ji,jj-1,jk) )
+            !--- add it to the general tracer trends
+            pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) + ztra
+         END_3D
+         !                                 ! trend diagnostics
+         IF( l_trd )   CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_yad, zwy, pV, pt(:,:,:,jn,Kmm) )
+         !                                 ! "Poleward" heat and salt transports (contribution of upstream fluxes)
+         IF( l_ptr )   CALL dia_ptr_hst( jn, 'adv', zwy(:,:,:) )
+         !
+      END DO
+      !
+   END SUBROUTINE tra_adv_qck_j
+
+
+   SUBROUTINE tra_adv_cen2_k( kt, cdtype, pW, Kmm, pt, kjpt, Krhs )
+      !!----------------------------------------------------------------------
+      !!
+      !!----------------------------------------------------------------------
+      INTEGER                                  , INTENT(in   ) ::   kt       ! ocean time-step index
+      INTEGER                                  , INTENT(in   ) ::   Kmm, Krhs  ! ocean time level indices
+      CHARACTER(len=3)                         , INTENT(in   ) ::   cdtype   ! =TRA or TRC (tracer indicator)
+      INTEGER                                  , INTENT(in   ) ::   kjpt     ! number of tracers
+      ! TEMP: [tiling] This can be A2D(nn_hls) if using XIOS (subdomain support)
+      REAL(wp), DIMENSION(jpi,jpj,jpk         ), INTENT(in   ) ::   pW      ! vertical velocity
+      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt,jpt), INTENT(inout) ::   pt              ! active tracers and RHS of tracer equation
+      !
+      INTEGER  ::   ji, jj, jk, jn   ! dummy loop indices
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zwz   ! 3D workspace
+      !!----------------------------------------------------------------------
+      !
+      zwz(:,:, 1 ) = 0._wp       ! surface & bottom values set to zero for all tracers
+      zwz(:,:,jpk) = 0._wp
+      !
+      !                                                          ! ===========
+      DO jn = 1, kjpt                                            ! tracer loop
+         !                                                       ! ===========
+         !
+         DO_3D( 0, 0, 0, 0, 2, jpkm1 )       !* Interior point   (w-masked 2nd order centered flux)
+            zwz(ji,jj,jk) = 0.5 * pW(ji,jj,jk) * ( pt(ji,jj,jk-1,jn,Kmm) + pt(ji,jj,jk,jn,Kmm) ) * wmask(ji,jj,jk)
+         END_3D
+         IF( ln_linssh ) THEN                !* top value   (only in linear free surf. as zwz is multiplied by wmask)
+            IF( ln_isfcav ) THEN                  ! ice-shelf cavities (top of the ocean)
+               DO_2D( 0, 0, 0, 0 )
+                  zwz(ji,jj, mikt(ji,jj) ) = pW(ji,jj,mikt(ji,jj)) * pt(ji,jj,mikt(ji,jj),jn,Kmm)   ! linear free surface
+               END_2D
+            ELSE                                   ! no ocean cavities (only ocean surface)
+               DO_2D( 0, 0, 0, 0 )
+                  zwz(ji,jj,1) = pW(ji,jj,1) * pt(ji,jj,1,jn,Kmm)
+               END_2D
+            ENDIF
+         ENDIF
+         !
+         DO_3D( 0, 0, 0, 0, 1, jpkm1 )   !==  Tracer flux divergence added to the general trend  ==!
+            pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) - ( zwz(ji,jj,jk) - zwz(ji,jj,jk+1) )   &
+               &                                * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
+         END_3D
+         !                                 ! Send trends for diagnostic
+         IF( l_trd )  CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_zad, zwz, pW, pt(:,:,:,jn,Kmm) )
+         !
+      END DO
+      !
+   END SUBROUTINE tra_adv_cen2_k
+
+
+   SUBROUTINE quickest( pfu, pfd, pfc, puc )
+      !!----------------------------------------------------------------------
+      !!
+      !! ** Purpose :  Computation of advective flux with Quickest scheme
+      !!
+      !! ** Method :
+      !!----------------------------------------------------------------------
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(in   ) ::   pfu   ! second upwind point
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(in   ) ::   pfd   ! first douwning point
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(in   ) ::   pfc   ! the central point (or the first upwind point)
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(inout) ::   puc   ! input as Courant number ; output as flux
+      !!
+      INTEGER  ::  ji, jj, jk               ! dummy loop indices
+      REAL(wp) ::  zcoef1, zcoef2, zcoef3   ! local scalars
+      REAL(wp) ::  zc, zcurv, zfho          !   -      -
+      !----------------------------------------------------------------------
+      !
+      DO_3D( 2, 2, 2, 2, 1, jpkm1 )
+         zc     = puc(ji,jj,jk)                         ! Courant number
+         zcurv  = pfd(ji,jj,jk) + pfu(ji,jj,jk) - 2. * pfc(ji,jj,jk)
+         zcoef1 = 0.5 *      ( pfc(ji,jj,jk) + pfd(ji,jj,jk) )
+         zcoef2 = 0.5 * zc * ( pfd(ji,jj,jk) - pfc(ji,jj,jk) )
+         zcoef3 = ( 1. - ( zc * zc ) ) * r1_6 * zcurv
+         zfho   = zcoef1 - zcoef2 - zcoef3              !  phi_f QUICKEST
+         !
+         zcoef1 = pfd(ji,jj,jk) - pfu(ji,jj,jk)
+         zcoef2 = ABS( zcoef1 )
+         zcoef3 = ABS( zcurv )
+         IF( zcoef3 >= zcoef2 ) THEN
+            zfho = pfc(ji,jj,jk)
+         ELSE
+            zcoef3 = pfu(ji,jj,jk) + ( ( pfc(ji,jj,jk) - pfu(ji,jj,jk) ) / MAX( zc, 1.e-9 ) )    ! phi_REF
+            IF( zcoef1 >= 0. ) THEN
+               zfho = MAX( pfc(ji,jj,jk), zfho )
+               zfho = MIN( zfho, MIN( zcoef3, pfd(ji,jj,jk) ) )
+            ELSE
+               zfho = MIN( pfc(ji,jj,jk), zfho )
+               zfho = MAX( zfho, MAX( zcoef3, pfd(ji,jj,jk) ) )
+            ENDIF
+         ENDIF
+         puc(ji,jj,jk) = zfho
+      END_3D
+      !
+   END SUBROUTINE quickest
+
+   !!======================================================================
+END MODULE traadv_qck_lf
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv_ubs.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv_ubs.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv_ubs.F90	(revision 14852)
@@ -26,4 +26,7 @@
    USE lbclnk         ! ocean lateral boundary condition (or mpp link)
    USE lib_fortran    ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined)
+#if defined key_loop_fusion
+   USE traadv_ubs_lf  ! UBS      scheme            (tra_adv_ubs  routine - loop fusion version)
+#endif
 
    IMPLICIT NONE
@@ -92,5 +95,5 @@
       INTEGER                                  , INTENT(in   ) ::   kn_ubs_v        ! number of tracers
       REAL(wp)                                 , INTENT(in   ) ::   p2dt            ! tracer time-step
-      ! TEMP: [tiling] This can be A2D(nn_hls) if using XIOS (subdomain support)
+      ! 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 transport components
       REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt,jpt), INTENT(inout) ::   pt              ! tracers and RHS of tracer equation
@@ -103,5 +106,8 @@
       !!----------------------------------------------------------------------
       !
-      IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+#if defined key_loop_fusion
+      CALL tra_adv_ubs_lf    ( kt, kit000, cdtype, p2dt, pU, pV, pW, Kbb, Kmm, pt, kjpt, Krhs, kn_ubs_v )
+#else
+      IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
          IF( kt == kit000 )  THEN
             IF(lwp) WRITE(numout,*)
@@ -140,5 +146,5 @@
             !
          END DO
-         IF (nn_hls.EQ.1) CALL lbc_lnk( 'traadv_ubs', zltu, 'T', 1.0_wp, zltv, 'T', 1.0_wp )   ! Lateral boundary cond. (unchanged sgn)
+         IF (nn_hls==1) CALL lbc_lnk( 'traadv_ubs', zltu, 'T', 1.0_wp, zltv, 'T', 1.0_wp, ld4only= .TRUE. )   ! Lateral boundary cond. (unchanged sgn)
          !
          DO_3D( 1, 0, 1, 0, 1, jpkm1 )   !==  Horizontal advective fluxes  ==!     (UBS)
@@ -260,4 +266,5 @@
       END DO
       !
+#endif
    END SUBROUTINE tra_adv_ubs
 
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv_ubs_lf.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv_ubs_lf.F90	(revision 14852)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traadv_ubs_lf.F90	(revision 14852)
@@ -0,0 +1,366 @@
+MODULE traadv_ubs_lf
+   !!==============================================================================
+   !!                       ***  MODULE  traadv_ubs  ***
+   !! Ocean active tracers:  horizontal & vertical advective trend
+   !!==============================================================================
+   !! History :  1.0  !  2006-08  (L. Debreu, R. Benshila)  Original code
+   !!            3.3  !  2010-05  (C. Ethe, G. Madec)  merge TRC-TRA + switch from velocity to transport
+   !!----------------------------------------------------------------------
+
+   !!----------------------------------------------------------------------
+   !!   tra_adv_ubs : update the tracer trend with the horizontal
+   !!                 advection trends using a third order biaised scheme
+   !!----------------------------------------------------------------------
+   USE oce            ! ocean dynamics and active tracers
+   USE dom_oce        ! ocean space and time domain
+   USE trc_oce        ! share passive tracers/Ocean variables
+   USE trd_oce        ! trends: ocean variables
+   USE traadv_fct      ! acces to routine interp_4th_cpt
+   USE trdtra         ! trends manager: tracers
+   USE diaptr         ! poleward transport diagnostics
+   USE diaar5         ! AR5 diagnostics
+   !
+   USE iom            ! I/O library
+   USE in_out_manager ! I/O manager
+   USE lib_mpp        ! massively parallel library
+   USE lbclnk         ! ocean lateral boundary condition (or mpp link)
+   USE lib_fortran    ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined)
+
+   IMPLICIT NONE
+   PRIVATE
+
+   PUBLIC   tra_adv_ubs_lf   ! routine called by traadv module
+
+   LOGICAL :: l_trd   ! flag to compute trends
+   LOGICAL :: l_ptr   ! flag to compute poleward transport
+   LOGICAL :: l_hst   ! flag to compute heat transport
+
+
+   !! * Substitutions
+#  include "do_loop_substitute.h90"
+#  include "domzgr_substitute.h90"
+   !!----------------------------------------------------------------------
+   !! NEMO/OCE 4.0 , NEMO Consortium (2018)
+   !! $Id: traadv_ubs.F90 14776 2021-04-30 12:33:41Z mocavero $
+   !! Software governed by the CeCILL license (see ./LICENSE)
+   !!----------------------------------------------------------------------
+CONTAINS
+
+   SUBROUTINE tra_adv_ubs_lf( kt, kit000, cdtype, p2dt, pU, pV, pW,          &
+      &                    Kbb, Kmm, pt, kjpt, Krhs, kn_ubs_v )
+      !!----------------------------------------------------------------------
+      !!                  ***  ROUTINE tra_adv_ubs  ***
+      !!
+      !! ** Purpose :   Compute the now trend due to the advection of tracers
+      !!      and add it to the general trend of passive tracer equations.
+      !!
+      !! ** Method  :   The 3rd order Upstream Biased Scheme (UBS) is based on an
+      !!      upstream-biased parabolic interpolation (Shchepetkin and McWilliams 2005)
+      !!      It is only used in the horizontal direction.
+      !!      For example the i-component of the advective fluxes are given by :
+      !!                !  e2u e3u un ( mi(Tn) - zltu(i  ) )   if un(i) >= 0
+      !!          ztu = !  or
+      !!                !  e2u e3u un ( mi(Tn) - zltu(i+1) )   if un(i) < 0
+      !!      where zltu is the second derivative of the before temperature field:
+      !!          zltu = 1/e3t di[ e2u e3u / e1u di[Tb] ]
+      !!        This results in a dissipatively dominant (i.e. hyper-diffusive)
+      !!      truncation error. The overall performance of the advection scheme
+      !!      is similar to that reported in (Farrow and Stevens, 1995).
+      !!        For stability reasons, the first term of the fluxes which corresponds
+      !!      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).
+      !!      Note that UBS is not positive. Do not use it on passive tracers.
+      !!                On the vertical, the advection is evaluated using a FCT scheme,
+      !!      as the UBS have been found to be too diffusive.
+      !!                kn_ubs_v argument controles whether the FCT is based on
+      !!      a 2nd order centrered scheme (kn_ubs_v=2) or on a 4th order compact
+      !!      scheme (kn_ubs_v=4).
+      !!
+      !! ** 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)
+      !!
+      !! Reference : Shchepetkin, A. F., J. C. McWilliams, 2005, Ocean Modelling, 9, 347-404.
+      !!             Farrow, D.E., Stevens, D.P., 1995, J. Phys. Ocean. 25, 1731�1741.
+      !!----------------------------------------------------------------------
+      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
+      INTEGER                                  , INTENT(in   ) ::   kn_ubs_v        ! number of tracers
+      REAL(wp)                                 , INTENT(in   ) ::   p2dt            ! tracer time-step
+      ! TEMP: [tiling] This can be A2D(nn_hls) if using XIOS (subdomain support)
+      REAL(wp), DIMENSION(jpi,jpj,jpk         ), INTENT(in   ) ::   pU, pV, pW      ! 3 ocean volume transport 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
+      REAL(wp) ::   ztra, zbtr, zcoef, zcoef_ip1, zcoef_jp1        ! local scalars
+      REAL(wp) ::   zfp_ui, zfm_ui, zcenut, ztak, zfp_wk, zfm_wk   !   -      -
+      REAL(wp) ::   zfp_vj, zfm_vj, zcenvt, zeeu, zeev, z_hdivn    !   -      -
+      REAL(wp) ::   zeeu_im1, zeeu_ip1, zeev_jm1, zeev_jp1
+      REAL(wp) ::   zztu, zztu_im1, zztu_ip1
+      REAL(wp) ::   zztv, zztv_jm1, zztv_jp1
+      REAL(wp) ::   zzltu, zzltu_ip1, zzltv, zzltv_jp1
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   ztu, ztv, zltu, zltv, zti, ztw     ! 3D workspace
+      !!----------------------------------------------------------------------
+      !
+      IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+         IF( kt == kit000 )  THEN
+            IF(lwp) WRITE(numout,*)
+            IF(lwp) WRITE(numout,*) 'tra_adv_ubs :  horizontal UBS advection scheme on ', cdtype
+            IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~'
+         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(   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
+      !
+      ztw (:,:, 1 ) = 0._wp      ! surface & bottom value : set to zero for all tracers
+      zltu(:,:,jpk) = 0._wp   ;   zltv(:,:,jpk) = 0._wp
+      ztw (:,:,jpk) = 0._wp   ;   zti (:,:,jpk) = 0._wp
+      !                                                          ! ===========
+      DO jn = 1, kjpt                                            ! tracer loop
+         !                                                       ! ===========
+         !                        !==  horizontal laplacian of before tracer ==!
+         DO_3D( 1, 1, 1, 1, 1, jpkm1 )                   ! Second derivative (divergence)
+            ! First derivative (masked gradient)
+            zeeu_im1 = e2_e1u(ji-1,jj) * e3u(ji-1,jj,jk,Kmm) * umask(ji-1,jj,jk)
+            zeeu = e2_e1u(ji,jj) * e3u(ji,jj,jk,Kmm) * umask(ji,jj,jk)
+            zeeu_ip1 = e2_e1u(ji+1,jj) * e3u(ji+1,jj,jk,Kmm) * umask(ji+1,jj,jk)
+            zeev_jm1 = e1_e2v(ji,jj-1) * e3v(ji,jj-1,jk,Kmm) * vmask(ji,jj-1,jk)
+            zeev = e1_e2v(ji,jj) * e3v(ji,jj,jk,Kmm) * vmask(ji,jj,jk)
+            zeev_jp1 = e1_e2v(ji,jj+1) * e3v(ji,jj+1,jk,Kmm) * vmask(ji,jj+1,jk)
+            !
+            zztu_im1 = zeeu_im1 * ( pt(ji,jj,jk,jn,Kbb) - pt(ji-1,jj,jk,jn,Kbb) )
+            zztu = zeeu * ( pt(ji+1,jj,jk,jn,Kbb) - pt(ji,jj,jk,jn,Kbb) )
+            zztu_ip1 = zeeu_ip1 * ( pt(ji+2,jj,jk,jn,Kbb) - pt(ji+1,jj,jk,jn,Kbb) )
+            !
+            zztv_jm1 = zeev_jm1 * ( pt(ji,jj,jk,jn,Kbb) - pt(ji,jj-1,jk,jn,Kbb) )
+            zztv = zeev * ( pt(ji  ,jj+1,jk,jn,Kbb) - pt(ji,jj,jk,jn,Kbb) )
+            zztv_jp1 = zeev_jp1 * ( pt(ji,jj+2,jk,jn,Kbb) - pt(ji,jj+1,jk,jn,Kbb) )
+            ! Second derivative (divergence)
+            zcoef = 1._wp / ( 6._wp * e3t(ji,jj,jk,Kmm) )
+            zcoef_ip1 = 1._wp / ( 6._wp * e3t(ji+1,jj,jk,Kmm) )
+            zcoef_jp1 = 1._wp / ( 6._wp * e3t(ji,jj+1,jk,Kmm) )
+            !
+            zzltu = (  zztu - zztu_im1  ) * zcoef
+            zzltu_ip1 = (  zztu_ip1 - zztu  ) * zcoef_ip1
+            zzltv = (  zztv - zztv_jm1  ) * zcoef
+            zzltv_jp1 = (  zztv_jp1 - zztv  ) * zcoef_jp1
+            !
+            !                     !==  Horizontal advective fluxes  ==!     (UBS)
+            zfp_ui = pU(ji,jj,jk) + ABS( pU(ji,jj,jk) )        ! upstream transport (x2)
+            zfm_ui = pU(ji,jj,jk) - ABS( pU(ji,jj,jk) )
+            zfp_vj = pV(ji,jj,jk) + ABS( pV(ji,jj,jk) )
+            zfm_vj = pV(ji,jj,jk) - ABS( pV(ji,jj,jk) )
+            !                                                  ! 2nd order centered advective fluxes (x2)
+            zcenut = pU(ji,jj,jk) * ( pt(ji,jj,jk,jn,Kmm) + pt(ji+1,jj  ,jk,jn,Kmm) )
+            zcenvt = pV(ji,jj,jk) * ( pt(ji,jj,jk,jn,Kmm) + pt(ji  ,jj+1,jk,jn,Kmm) )
+            !                                                  ! UBS advective fluxes
+            ztu(ji,jj,jk) = 0.5 * ( zcenut - zfp_ui * zzltu - zfm_ui * zzltu_ip1 )
+            ztv(ji,jj,jk) = 0.5 * ( zcenvt - zfp_vj * zzltv - zfm_vj * zzltv_jp1 )
+         END_3D
+         !
+         DO_3D( 0, 0, 0, 0, 1, jpk )
+            zltu(ji,jj,jk) = pt(ji,jj,jk,jn,Krhs)      ! store the initial trends before its update
+         END_3D
+         !
+         !                           !==  add the horizontal advective trend  ==!
+         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+            pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs)                &
+               &             - (  ztu(ji,jj,jk) - ztu(ji-1,jj  ,jk)    &
+               &                + ztv(ji,jj,jk) - ztv(ji  ,jj-1,jk)  ) &
+               &                * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
+         END_3D
+         !
+         DO_3D( 0, 0, 0, 0, 1, jpk )
+            zltu(ji,jj,jk) = pt(ji,jj,jk,jn,Krhs) - zltu(ji,jj,jk)  ! Horizontal advective trend used in vertical 2nd order FCT case
+         END_3D                                                     ! and/or in trend diagnostic (l_trd=T)
+         !
+         IF( l_trd ) THEN                  ! trend diagnostics
+             CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_xad, ztu, pU, pt(:,:,:,jn,Kmm) )
+             CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_yad, ztv, pV, pt(:,:,:,jn,Kmm) )
+         END IF
+         !
+         !                                ! "Poleward" heat and salt transports (contribution of upstream fluxes)
+         IF( l_ptr )  CALL dia_ptr_hst( jn, 'adv', ztv(:,:,:) )
+         !                                !  heati/salt transport
+         IF( l_hst )  CALL dia_ar5_hst( jn, 'adv', ztu(:,:,:), ztv(:,:,:) )
+         !
+         !
+         !                       !== vertical advective trend  ==!
+         !
+         SELECT CASE( kn_ubs_v )       ! select the vertical advection scheme
+         !
+         CASE(  2  )                   ! 2nd order FCT
+            !
+            IF( l_trd ) THEN
+               DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+                  zltv(ji,jj,jk) = pt(ji,jj,jk,jn,Krhs)          ! store pt(:,:,:,:,Krhs) if trend diag.
+               END_3D
+            ENDIF
+            !
+            !                               !*  upstream advection with initial mass fluxes & intermediate update  ==!
+            DO_3D( 1, 1, 1, 1, 2, jpkm1 )
+               zfp_wk = pW(ji,jj,jk) + ABS( pW(ji,jj,jk) )
+               zfm_wk = pW(ji,jj,jk) - ABS( pW(ji,jj,jk) )
+               ztw(ji,jj,jk) = 0.5_wp * (  zfp_wk * pt(ji,jj,jk,jn,Kbb) + zfm_wk * pt(ji,jj,jk-1,jn,Kbb)  ) * wmask(ji,jj,jk)
+            END_3D
+            IF( ln_linssh ) THEN                ! top ocean value (only in linear free surface as ztw has been w-masked)
+               IF( ln_isfcav ) THEN                   ! top of the ice-shelf cavities and at the ocean surface
+                  DO_2D( 1, 1, 1, 1 )
+                     ztw(ji,jj, mikt(ji,jj) ) = pW(ji,jj,mikt(ji,jj)) * pt(ji,jj,mikt(ji,jj),jn,Kbb)   ! linear free surface
+                  END_2D
+               ELSE                                   ! no cavities: only at the ocean surface
+                  DO_2D( 1, 1, 1, 1 )
+                     ztw(ji,jj,1) = pW(ji,jj,1) * pt(ji,jj,1,jn,Kbb)
+                  END_2D
+               ENDIF
+            ENDIF
+            !
+            DO_3D( 0, 0, 0, 0, 1, jpkm1 )   !* trend and after field with monotonic scheme
+               ztak = - ( ztw(ji,jj,jk) - ztw(ji,jj,jk+1) )    &
+                  &     * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
+               pt(ji,jj,jk,jn,Krhs) =   pt(ji,jj,jk,jn,Krhs) +  ztak
+               zti(ji,jj,jk)    = ( pt(ji,jj,jk,jn,Kbb) + p2dt * ( ztak + zltu(ji,jj,jk) ) ) * tmask(ji,jj,jk)
+            END_3D
+            !
+            !                          !*  anti-diffusive flux : high order minus low order
+            DO_3D( 1, 1, 1, 1, 2, jpkm1 )
+               ztw(ji,jj,jk) = (   0.5_wp * pW(ji,jj,jk) * ( pt(ji,jj,jk,jn,Kmm) + pt(ji,jj,jk-1,jn,Kmm) )   &
+                  &              - ztw(ji,jj,jk)   ) * wmask(ji,jj,jk)
+            END_3D
+            !                                            ! top ocean value: high order == upstream  ==>>  zwz=0
+            IF( ln_linssh )   ztw(:,:, 1 ) = 0._wp       ! only ocean surface as interior zwz values have been w-masked
+            !
+            CALL nonosc_z( Kmm, pt(:,:,:,jn,Kbb), ztw, zti, p2dt )      !  monotonicity algorithm
+            !
+         CASE(  4  )                               ! 4th order COMPACT
+            CALL interp_4th_cpt( pt(:,:,:,jn,Kmm) , ztw )         ! 4th order compact interpolation of T at w-point
+            DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+               ztw(ji,jj,jk) = pW(ji,jj,jk) * ztw(ji,jj,jk) * wmask(ji,jj,jk)
+            END_3D
+            IF( ln_linssh ) THEN
+               DO_2D( 1, 1, 1, 1 )
+                  ztw(ji,jj,1) = pW(ji,jj,1) * pt(ji,jj,1,jn,Kmm)     !!gm ISF & 4th COMPACT doesn't work
+               END_2D
+            ENDIF
+            !
+         END SELECT
+         !
+         DO_3D( 0, 0, 0, 0, 1, jpkm1 )   !  final trend with corrected fluxes
+            pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) - ( ztw(ji,jj,jk) - ztw(ji,jj,jk+1) )    &
+               &                                        * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
+         END_3D
+         !
+         IF( l_trd )  THEN               ! vertical advective trend diagnostics
+            DO_3D( 0, 0, 0, 0, 1, jpkm1 )                 ! (compute -w.dk[ptn]= -dk[w.ptn] + ptn.dk[w])
+               zltv(ji,jj,jk) = pt(ji,jj,jk,jn,Krhs) - zltv(ji,jj,jk)                          &
+                  &           + pt(ji,jj,jk,jn,Kmm) * (  pW(ji,jj,jk) - pW(ji,jj,jk+1)  )   &
+                  &                              * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
+            END_3D
+            CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_zad, zltv )
+         ENDIF
+         !
+      END DO
+      !
+   END SUBROUTINE tra_adv_ubs_lf
+
+
+   SUBROUTINE nonosc_z( Kmm, pbef, pcc, paft, p2dt )
+      !!---------------------------------------------------------------------
+      !!                    ***  ROUTINE nonosc_z  ***
+      !!
+      !! **  Purpose :   compute monotonic tracer fluxes from the upstream
+      !!       scheme and the before field by a nonoscillatory algorithm
+      !!
+      !! **  Method  :   ... ???
+      !!       warning : pbef and paft must be masked, but the boundaries
+      !!       conditions on the fluxes are not necessary zalezak (1979)
+      !!       drange (1995) multi-dimensional forward-in-time and upstream-
+      !!       in-space based differencing for fluid
+      !!----------------------------------------------------------------------
+      INTEGER , INTENT(in   )                         ::   Kmm    ! time level index
+      REAL(wp), INTENT(in   )                         ::   p2dt   ! tracer time-step
+      REAL(wp),                DIMENSION(jpi,jpj,jpk) ::   pbef   ! before field
+      REAL(wp), INTENT(inout), DIMENSION(A2D(nn_hls)    ,jpk) ::   paft   ! after field
+      REAL(wp), INTENT(inout), DIMENSION(A2D(nn_hls)    ,jpk) ::   pcc    ! monotonic flux in the k direction
+      !
+      INTEGER  ::   ji, jj, jk   ! dummy loop indices
+      INTEGER  ::   ikm1         ! local integer
+      REAL(wp) ::   zpos, zneg, zbt, za, zb, zc, zbig, zrtrn   ! local scalars
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zbetup, zbetdo         ! 3D workspace
+      !!----------------------------------------------------------------------
+      !
+      zbig  = 1.e+38_wp
+      zrtrn = 1.e-15_wp
+      zbetup(:,:,:) = 0._wp   ;   zbetdo(:,:,:) = 0._wp
+      !
+      ! Search local extrema
+      ! --------------------
+      !                    ! large negative value (-zbig) inside land
+      DO_3D( 0, 0, 0, 0, 1, jpk )
+         pbef(ji,jj,jk) = pbef(ji,jj,jk) * tmask(ji,jj,jk) - zbig * ( 1.e0 - tmask(ji,jj,jk) )
+         paft(ji,jj,jk) = paft(ji,jj,jk) * tmask(ji,jj,jk) - zbig * ( 1.e0 - tmask(ji,jj,jk) )
+      END_3D
+      !
+      DO jk = 1, jpkm1     ! search maximum in neighbourhood
+         ikm1 = MAX(jk-1,1)
+         DO_2D( 0, 0, 0, 0 )
+            zbetup(ji,jj,jk) = MAX(  pbef(ji  ,jj  ,jk  ), paft(ji  ,jj  ,jk  ),   &
+               &                     pbef(ji  ,jj  ,ikm1), pbef(ji  ,jj  ,jk+1),   &
+               &                     paft(ji  ,jj  ,ikm1), paft(ji  ,jj  ,jk+1)  )
+         END_2D
+      END DO
+      !                    ! large positive value (+zbig) inside land
+      DO_3D( 0, 0, 0, 0, 1, jpk )
+         pbef(ji,jj,jk) = pbef(ji,jj,jk) * tmask(ji,jj,jk) + zbig * ( 1.e0 - tmask(ji,jj,jk) )
+         paft(ji,jj,jk) = paft(ji,jj,jk) * tmask(ji,jj,jk) + zbig * ( 1.e0 - tmask(ji,jj,jk) )
+      END_3D
+      !
+      DO jk = 1, jpkm1     ! search minimum in neighbourhood
+         ikm1 = MAX(jk-1,1)
+         DO_2D( 0, 0, 0, 0 )
+            zbetdo(ji,jj,jk) = MIN(  pbef(ji  ,jj  ,jk  ), paft(ji  ,jj  ,jk  ),   &
+               &                     pbef(ji  ,jj  ,ikm1), pbef(ji  ,jj  ,jk+1),   &
+               &                     paft(ji  ,jj  ,ikm1), paft(ji  ,jj  ,jk+1)  )
+         END_2D
+      END DO
+      !                    ! restore masked values to zero
+      DO_3D( 0, 0, 0, 0, 1, jpk )
+         pbef(ji,jj,jk) = pbef(ji,jj,jk) * tmask(ji,jj,jk)
+         paft(ji,jj,jk) = paft(ji,jj,jk) * tmask(ji,jj,jk)
+      END_3D
+      !
+      ! Positive and negative part of fluxes and beta terms
+      ! ---------------------------------------------------
+      DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+         ! positive & negative part of the flux
+         zpos = MAX( 0., pcc(ji  ,jj  ,jk+1) ) - MIN( 0., pcc(ji  ,jj  ,jk  ) )
+         zneg = MAX( 0., pcc(ji  ,jj  ,jk  ) ) - MIN( 0., pcc(ji  ,jj  ,jk+1) )
+         ! up & down beta terms
+         zbt = e1e2t(ji,jj) * e3t(ji,jj,jk,Kmm) / p2dt
+         zbetup(ji,jj,jk) = ( zbetup(ji,jj,jk) - paft(ji,jj,jk) ) / (zpos+zrtrn) * zbt
+         zbetdo(ji,jj,jk) = ( paft(ji,jj,jk) - zbetdo(ji,jj,jk) ) / (zneg+zrtrn) * zbt
+      END_3D
+      !
+      ! monotonic flux in the k direction, i.e. pcc
+      ! -------------------------------------------
+      DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+         za = MIN( 1., zbetdo(ji,jj,jk), zbetup(ji,jj,jk-1) )
+         zb = MIN( 1., zbetup(ji,jj,jk), zbetdo(ji,jj,jk-1) )
+         zc = 0.5 * ( 1.e0 + SIGN( 1.0_wp, pcc(ji,jj,jk) ) )
+         pcc(ji,jj,jk) = pcc(ji,jj,jk) * ( zc * za + ( 1.e0 - zc) * zb )
+      END_3D
+      !
+   END SUBROUTINE nonosc_z
+
+   !!======================================================================
+END MODULE traadv_ubs_lf
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/trabbc.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/trabbc.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/trabbc.F90	(revision 14852)
@@ -102,7 +102,6 @@
       ENDIF
       !
-      IF( ntile == 0 .OR. ntile == nijtile )  THEN                ! Do only for the full domain
-         CALL iom_put ( "hfgeou" , rho0_rcp * qgh_trd0(:,:) )
-      ENDIF
+      CALL iom_put ( "hfgeou" , rho0_rcp * qgh_trd0(:,:) )
+
       IF(sn_cfctl%l_prtctl)   CALL prt_ctl( tab3d_1=pts(:,:,:,jp_tem,Krhs), clinfo1=' bbc  - Ta: ', mask1=tmask, clinfo3='tra-ta' )
       !
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/trabbl.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/trabbl.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/trabbl.F90	(revision 14852)
@@ -126,8 +126,6 @@
          CALL prt_ctl( tab3d_1=pts(:,:,:,jp_tem,Krhs), clinfo1=' bbl_ldf  - Ta: ', mask1=tmask, &
             &          tab3d_2=pts(:,:,:,jp_sal,Krhs), clinfo2=           ' Sa: ', mask2=tmask, clinfo3='tra' )
-         IF( ntile == 0 .OR. ntile == nijtile ) THEN                       ! Do only on the last tile
-            CALL iom_put( "ahu_bbl", ahu_bbl )   ! bbl diffusive flux i-coef
-            CALL iom_put( "ahv_bbl", ahv_bbl )   ! bbl diffusive flux j-coef
-         ENDIF
+         CALL iom_put( "ahu_bbl", ahu_bbl )   ! bbl diffusive flux i-coef
+         CALL iom_put( "ahv_bbl", ahv_bbl )   ! bbl diffusive flux j-coef
          !
       ENDIF
@@ -139,10 +137,6 @@
          CALL prt_ctl( tab3d_1=pts(:,:,:,jp_tem,Krhs), clinfo1=' bbl_adv  - Ta: ', mask1=tmask, &
             &          tab3d_2=pts(:,:,:,jp_sal,Krhs), clinfo2=           ' Sa: ', mask2=tmask, clinfo3='tra' )
-         IF( ntile == 0 .OR. ntile == nijtile ) THEN                       ! Do only on the last tile
-            ! lateral boundary conditions ; just need for outputs
-            CALL lbc_lnk( 'trabbl', utr_bbl, 'U', 1.0_wp , vtr_bbl, 'V', 1.0_wp )
-            CALL iom_put( "uoce_bbl", utr_bbl )  ! bbl i-transport
-            CALL iom_put( "voce_bbl", vtr_bbl )  ! bbl j-transport
-         ENDIF
+         CALL iom_put( "uoce_bbl", utr_bbl )  ! bbl i-transport
+         CALL iom_put( "voce_bbl", vtr_bbl )  ! bbl j-transport
          !
       ENDIF
@@ -215,4 +209,5 @@
 
 
+   ! NOTE: [tiling] tiling changes the results, but only the order of floating point operations is different
    SUBROUTINE tra_bbl_adv( pt, pt_rhs, kjpt, Kmm )
       !!----------------------------------------------------------------------
@@ -238,15 +233,11 @@
       INTEGER  ::   iis , iid , ijs , ijd    ! local integers
       INTEGER  ::   ikus, ikud, ikvs, ikvd   !   -       -
-      INTEGER  ::   isi, isj                 !   -       -
       REAL(wp) ::   zbtr, ztra               ! local scalars
       REAL(wp) ::   zu_bbl, zv_bbl           !   -      -
       !!----------------------------------------------------------------------
-      !
-      IF( ntsi == Nis0 ) THEN ; isi = 1 ; ELSE ; isi = 0 ; ENDIF    ! Avoid double-counting when using tiling
-      IF( ntsj == Njs0 ) THEN ; isj = 1 ; ELSE ; isj = 0 ; ENDIF
       !                                                          ! ===========
       DO jn = 1, kjpt                                            ! tracer loop
          !                                                       ! ===========
-         DO_2D( isi, 0, isj, 0 )            ! CAUTION start from i=1 to update i=2 when cyclic east-west
+         DO_2D_OVR( 1, 0, 1, 0 )            ! CAUTION start from i=1 to update i=2 when cyclic east-west
             IF( utr_bbl(ji,jj) /= 0.e0 ) THEN            ! non-zero i-direction bbl advection
                ! down-slope i/k-indices (deep)      &   up-slope i/k indices (shelf)
@@ -340,5 +331,5 @@
       !!----------------------------------------------------------------------
       !
-      IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+      IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
          IF( kt == kit000 )  THEN
             IF(lwp)  WRITE(numout,*)
@@ -363,5 +354,5 @@
       IF( nn_bbl_ldf == 1 ) THEN          !   diffusive bbl   !
          !                                !-------------------!
-         DO_2D( 1, 0, 1, 0 )                   ! (criteria for non zero flux: grad(rho).grad(h) < 0 )
+         DO_2D_OVR( 1, 0, 1, 0 )                   ! (criteria for non zero flux: grad(rho).grad(h) < 0 )
             !                                                   ! i-direction
             za = zab(ji+1,jj,jp_tem) + zab(ji,jj,jp_tem)              ! 2*(alpha,beta) at u-point
@@ -393,5 +384,5 @@
          !
          CASE( 1 )                                   != use of upper velocity
-            DO_2D( 1, 0, 1, 0 )                              ! criteria: grad(rho).grad(h)<0  and grad(rho).grad(h)<0
+            DO_2D_OVR( 1, 0, 1, 0 )                              ! criteria: grad(rho).grad(h)<0  and grad(rho).grad(h)<0
                !                                                  ! i-direction
                za = zab(ji+1,jj,jp_tem) + zab(ji,jj,jp_tem)               ! 2*(alpha,beta) at u-point
@@ -422,5 +413,5 @@
          CASE( 2 )                                 != bbl velocity = F( delta rho )
             zgbbl = grav * rn_gambbl
-            DO_2D( 1, 0, 1, 0 )                         ! criteria: rho_up > rho_down
+            DO_2D_OVR( 1, 0, 1, 0 )                         ! criteria: rho_up > rho_down
                !                                                  ! i-direction
                ! down-slope T-point i/k-index (deep)  &   up-slope T-point i/k-index (shelf)
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traisf.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traisf.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traisf.F90	(revision 14852)
@@ -47,5 +47,5 @@
       IF( ln_timing )   CALL timing_start('tra_isf')
       !
-      IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+      IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
          IF( kt == nit000 ) THEN
             IF(lwp) WRITE(numout,*)
@@ -79,5 +79,5 @@
       !
       IF ( ln_isfdebug ) THEN
-         IF( ntile == 0 .OR. ntile == nijtile ) THEN                       ! Do only for the full domain
+         IF( .NOT. l_istiled .OR. ntile == nijtile ) THEN                       ! Do only for the full domain
             CALL debug('tra_isf: pts(:,:,:,:,Krhs) T', pts(:,:,:,1,Krhs))
             CALL debug('tra_isf: pts(:,:,:,:,Krhs) S', pts(:,:,:,2,Krhs))
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traldf.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traldf.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traldf.F90	(revision 14852)
@@ -17,6 +17,4 @@
    USE oce            ! ocean dynamics and tracers
    USE dom_oce        ! ocean space and time domain
-   ! TEMP: [tiling] This change not necessary after extra haloes development (lbc_lnk removed from tra_ldf_blp, zps_hde*)
-   USE domtile
    USE phycst         ! physical constants
    USE ldftra         ! lateral diffusion: eddy diffusivity & EIV coeff.
@@ -58,12 +56,8 @@
       !!
       REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) ::   ztrdt, ztrds
-      ! TEMP: [tiling] This change not necessary after extra haloes development (lbc_lnk removed from tra_ldf_blp, zps_hde*)
-      LOGICAL :: lskip
       !!----------------------------------------------------------------------
       !
       IF( ln_timing )   CALL timing_start('tra_ldf')
       !
-      lskip = .FALSE.
-
       IF( l_trdtra )   THEN                    !* Save ta and sa trends
          ALLOCATE( ztrdt(jpi,jpj,jpk) , ztrds(jpi,jpj,jpk) )
@@ -71,39 +65,22 @@
          ztrds(:,:,:) = pts(:,:,:,jp_sal,Krhs)
       ENDIF
-
-      ! TEMP: [tiling] These changes not necessary after extra haloes development (lbc_lnk removed from tra_ldf_blp, zps_hde*)
-      IF( nldf_tra == np_blp .OR. nldf_tra == np_blp_i .OR. nldf_tra == np_blp_it )  THEN
-         IF( ln_tile ) THEN
-            IF( ntile == 1 ) THEN
-               CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = 0 )
-            ELSE
-               lskip = .TRUE.
-            ENDIF
-         ENDIF
-      ENDIF
-      IF( .NOT. lskip ) THEN
-         !
-         SELECT CASE ( nldf_tra )                 !* compute lateral mixing trend and add it to the general trend
-         CASE ( np_lap   )                                  ! laplacian: iso-level operator
-            CALL tra_ldf_lap  ( kt, Kmm, nit000,'TRA', ahtu, ahtv, gtsu, gtsv, gtui, gtvi, pts(:,:,:,:,Kbb), pts(:,:,:,:,Krhs),                   jpts,  1 )
-         CASE ( np_lap_i )                                  ! laplacian: standard iso-neutral operator (Madec)
-            CALL tra_ldf_iso  ( kt, Kmm, nit000,'TRA', ahtu, ahtv, gtsu, gtsv, gtui, gtvi, pts(:,:,:,:,Kbb), pts(:,:,:,:,Kbb), pts(:,:,:,:,Krhs), jpts,  1 )
-         CASE ( np_lap_it )                                 ! laplacian: triad iso-neutral operator (griffies)
-            CALL tra_ldf_triad( kt, Kmm, nit000,'TRA', ahtu, ahtv, gtsu, gtsv, gtui, gtvi, pts(:,:,:,:,Kbb), pts(:,:,:,:,Kbb), pts(:,:,:,:,Krhs), jpts,  1 )
-         CASE ( np_blp , np_blp_i , np_blp_it )             ! bilaplacian: iso-level & iso-neutral operators
-            IF(nn_hls.EQ.2) CALL lbc_lnk( 'tra_ldf', pts(:,:,:,:,Kbb), 'T',1.)
-            CALL tra_ldf_blp  ( kt, Kmm, nit000,'TRA', ahtu, ahtv, gtsu, gtsv, gtui, gtvi, pts(:,:,:,:,Kbb), pts(:,:,:,:,Krhs),             jpts, nldf_tra )
-         END SELECT
-         !
-         IF( l_trdtra )   THEN                    !* save the horizontal diffusive trends for further diagnostics
-            ztrdt(:,:,:) = pts(:,:,:,jp_tem,Krhs) - ztrdt(:,:,:)
-            ztrds(:,:,:) = pts(:,:,:,jp_sal,Krhs) - ztrds(:,:,:)
-            CALL trd_tra( kt, Kmm, Krhs, 'TRA', jp_tem, jptra_ldf, ztrdt )
-            CALL trd_tra( kt, Kmm, Krhs, 'TRA', jp_sal, jptra_ldf, ztrds )
-            DEALLOCATE( ztrdt, ztrds )
-         ENDIF
-
-         ! TEMP: [tiling] This change not necessary after extra haloes development (lbc_lnk removed from tra_ldf_blp, zps_hde*)
-         IF( ln_tile .AND. ntile == 0 ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = 1 )
+      !
+      SELECT CASE ( nldf_tra )                 !* compute lateral mixing trend and add it to the general trend
+      CASE ( np_lap   )                                  ! laplacian: iso-level operator
+         CALL tra_ldf_lap  ( kt, Kmm, nit000,'TRA', ahtu, ahtv, gtsu, gtsv, gtui, gtvi, pts(:,:,:,:,Kbb), pts(:,:,:,:,Krhs),                   jpts,  1 )
+      CASE ( np_lap_i )                                  ! laplacian: standard iso-neutral operator (Madec)
+         CALL tra_ldf_iso  ( kt, Kmm, nit000,'TRA', ahtu, ahtv, gtsu, gtsv, gtui, gtvi, pts(:,:,:,:,Kbb), pts(:,:,:,:,Kbb), pts(:,:,:,:,Krhs), jpts,  1 )
+      CASE ( np_lap_it )                                 ! laplacian: triad iso-neutral operator (griffies)
+         CALL tra_ldf_triad( kt, Kmm, nit000,'TRA', ahtu, ahtv, gtsu, gtsv, gtui, gtvi, pts(:,:,:,:,Kbb), pts(:,:,:,:,Kbb), pts(:,:,:,:,Krhs), jpts,  1 )
+      CASE ( np_blp , np_blp_i , np_blp_it )             ! bilaplacian: iso-level & iso-neutral operators
+         CALL tra_ldf_blp  ( kt, Kmm, nit000,'TRA', ahtu, ahtv, gtsu, gtsv, gtui, gtvi, pts(:,:,:,:,Kbb), pts(:,:,:,:,Krhs),             jpts, nldf_tra )
+      END SELECT
+      !
+      IF( l_trdtra )   THEN                    !* save the horizontal diffusive trends for further diagnostics
+         ztrdt(:,:,:) = pts(:,:,:,jp_tem,Krhs) - ztrdt(:,:,:)
+         ztrds(:,:,:) = pts(:,:,:,jp_sal,Krhs) - ztrds(:,:,:)
+         CALL trd_tra( kt, Kmm, Krhs, 'TRA', jp_tem, jptra_ldf, ztrdt )
+         CALL trd_tra( kt, Kmm, Krhs, 'TRA', jp_sal, jptra_ldf, ztrds )
+         DEALLOCATE( ztrdt, ztrds )
       ENDIF
       !                                        !* print mean trends (used for debugging)
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traldf_iso.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traldf_iso.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traldf_iso.F90	(revision 14852)
@@ -132,5 +132,5 @@
       INTEGER  ::  ji, jj, jk, jn   ! dummy loop indices
       INTEGER  ::  ikt
-      INTEGER  ::  ierr             ! local integer
+      INTEGER  ::  ierr, iij        ! local integer
       REAL(wp) ::  zmsku, zahu_w, zabe1, zcof1, zcoef3   ! local scalars
       REAL(wp) ::  zmskv, zahv_w, zabe2, zcof2, zcoef4   !   -      -
@@ -141,5 +141,5 @@
       !
       IF( kpass == 1 .AND. kt == kit000 )  THEN
-         IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+         IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
             IF(lwp) WRITE(numout,*)
             IF(lwp) WRITE(numout,*) 'tra_ldf_iso : rotated laplacian diffusion operator on ', cdtype
@@ -147,5 +147,5 @@
          ENDIF
          !
-         DO_3D( 0, 0, 0, 0, 1, jpk )
+         DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpk )
             akz     (ji,jj,jk) = 0._wp
             ah_wslp2(ji,jj,jk) = 0._wp
@@ -153,5 +153,5 @@
       ENDIF
       !
-      IF( ntile == 0 .OR. ntile == 1 )  THEN                           ! Do only on the first tile
+      IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                           ! Do only on the first tile
          l_hst = .FALSE.
          l_ptr = .FALSE.
@@ -161,4 +161,9 @@
       ENDIF
       !
+      ! Define pt_rhs halo points for multi-point haloes in bilaplacian case
+      IF( nldf_tra == np_blp_i .AND. kpass == 1 ) THEN ; iij = nn_hls
+      ELSE                                             ; iij = 1
+      ENDIF
+
       !
       IF( kpass == 1 ) THEN   ;   zsign =  1._wp      ! bilaplacian operator require a minus sign (eddy diffusivity >0)
@@ -172,5 +177,5 @@
       IF( kpass == 1 ) THEN                  !==  first pass only  ==!
          !
-         DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+         DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
             !
             zmsku = wmask(ji,jj,jk) / MAX(   umask(ji  ,jj,jk-1) + umask(ji-1,jj,jk)          &
@@ -179,8 +184,16 @@
                &                           + vmask(ji,jj-1,jk-1) + vmask(ji,jj  ,jk) , 1._wp  )
                !
-            zahu_w = (   pahu(ji  ,jj,jk-1) + pahu(ji-1,jj,jk)    &
-               &       + pahu(ji-1,jj,jk-1) + pahu(ji  ,jj,jk)  ) * zmsku
-            zahv_w = (   pahv(ji,jj  ,jk-1) + pahv(ji,jj-1,jk)    &
-               &       + pahv(ji,jj-1,jk-1) + pahv(ji,jj  ,jk)  ) * zmskv
+            ! round brackets added to fix the order of floating point operations
+            ! needed to ensure halo 1 - halo 2 compatibility
+            zahu_w = ( (  pahu(ji  ,jj,jk-1) + pahu(ji-1,jj,jk)                    &
+               &       )                                                           & ! bracket for halo 1 - halo 2 compatibility
+               &       + ( pahu(ji-1,jj,jk-1) + pahu(ji  ,jj,jk)                   &
+               &         )                                                         & ! bracket for halo 1 - halo 2 compatibility
+               &     ) * zmsku
+            zahv_w = ( (  pahv(ji,jj  ,jk-1) + pahv(ji,jj-1,jk)                    &
+               &       )                                                           & ! bracket for halo 1 - halo 2 compatibility
+               &       + ( pahv(ji,jj-1,jk-1) + pahv(ji,jj  ,jk)                   &
+               &         )                                                         & ! bracket for halo 1 - halo 2 compatibility
+               &     ) * zmskv
                !
             ah_wslp2(ji,jj,jk) = zahu_w * wslpi(ji,jj,jk) * wslpi(ji,jj,jk)   &
@@ -189,14 +202,19 @@
          !
          IF( ln_traldf_msc ) THEN                ! stabilizing vertical diffusivity coefficient
-            DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+            DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
+               ! round brackets added to fix the order of floating point operations
+               ! needed to ensure halo 1 - halo 2 compatibility
                akz(ji,jj,jk) = 0.25_wp * (                                                                     &
-                  &              ( pahu(ji  ,jj,jk) + pahu(ji  ,jj,jk-1) ) / ( e1u(ji  ,jj) * e1u(ji  ,jj) )   &
+                  &            ( ( pahu(ji  ,jj,jk) + pahu(ji  ,jj,jk-1) ) / ( e1u(ji  ,jj) * e1u(ji  ,jj) )   &
                   &            + ( pahu(ji-1,jj,jk) + pahu(ji-1,jj,jk-1) ) / ( e1u(ji-1,jj) * e1u(ji-1,jj) )   &
-                  &            + ( pahv(ji,jj  ,jk) + pahv(ji,jj  ,jk-1) ) / ( e2v(ji,jj  ) * e2v(ji,jj  ) )   &
-                  &            + ( pahv(ji,jj-1,jk) + pahv(ji,jj-1,jk-1) ) / ( e2v(ji,jj-1) * e2v(ji,jj-1) )   )
+                  &            )                                                                               & ! bracket for halo 1 - halo 2 compatibility
+                  &            + ( ( pahv(ji,jj  ,jk) + pahv(ji,jj  ,jk-1) ) / ( e2v(ji,jj  ) * e2v(ji,jj  ) ) &
+                  &              + ( pahv(ji,jj-1,jk) + pahv(ji,jj-1,jk-1) ) / ( e2v(ji,jj-1) * e2v(ji,jj-1) ) &
+                  &              )                                                                             & ! bracket for halo 1 - halo 2 compatibility
+                  &                      )
             END_3D
             !
             IF( ln_traldf_blp ) THEN                ! bilaplacian operator
-               DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+               DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
                   akz(ji,jj,jk) = 16._wp   &
                      &   * ah_wslp2   (ji,jj,jk)   &
@@ -206,5 +224,5 @@
                END_3D
             ELSEIF( ln_traldf_lap ) THEN              ! laplacian operator
-               DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+               DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
                   ze3w_2 = e3w(ji,jj,jk,Kmm) * e3w(ji,jj,jk,Kmm)
                   zcoef0 = rDt * (  akz(ji,jj,jk) + ah_wslp2(ji,jj,jk) / ze3w_2  )
@@ -214,5 +232,5 @@
            !
          ELSE                                    ! 33 flux set to zero with akz=ah_wslp2 ==>> computed in full implicit
-            DO_3D( 0, 0, 0, 0, 1, jpk )
+            DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpk )
                akz(ji,jj,jk) = ah_wslp2(ji,jj,jk)
             END_3D
@@ -227,21 +245,19 @@
          !!   I - masked horizontal derivative
          !!----------------------------------------------------------------------
-!!gm : bug.... why (x,:,:)?   (1,jpj,:) and (jpi,1,:) should be sufficient....
-         zdit (ntsi-nn_hls,:,:) = 0._wp     ;     zdit (ntei+nn_hls,:,:) = 0._wp
-         zdjt (ntsi-nn_hls,:,:) = 0._wp     ;     zdjt (ntei+nn_hls,:,:) = 0._wp
-         !!end
+         zdit(:,:,:) = 0._wp
+         zdjt(:,:,:) = 0._wp
 
          ! Horizontal tracer gradient
-         DO_3D( 1, 0, 1, 0, 1, jpkm1 )
+         DO_3D( iij, iij-1, iij, iij-1, 1, jpkm1 )
             zdit(ji,jj,jk) = ( pt(ji+1,jj  ,jk,jn) - pt(ji,jj,jk,jn) ) * umask(ji,jj,jk)
             zdjt(ji,jj,jk) = ( pt(ji  ,jj+1,jk,jn) - pt(ji,jj,jk,jn) ) * vmask(ji,jj,jk)
          END_3D
          IF( ln_zps ) THEN      ! botton and surface ocean correction of the horizontal gradient
-            DO_2D( 1, 0, 1, 0 )           ! bottom correction (partial bottom cell)
+            DO_2D( iij, iij-1, iij, iij-1 )            ! bottom correction (partial bottom cell)
                zdit(ji,jj,mbku(ji,jj)) = pgu(ji,jj,jn)
                zdjt(ji,jj,mbkv(ji,jj)) = pgv(ji,jj,jn)
             END_2D
             IF( ln_isfcav ) THEN      ! first wet level beneath a cavity
-               DO_2D( 1, 0, 1, 0 )
+               DO_2D( iij, iij-1, iij, iij-1 )
                   IF( miku(ji,jj) > 1 )   zdit(ji,jj,miku(ji,jj)) = pgui(ji,jj,jn)
                   IF( mikv(ji,jj) > 1 )   zdjt(ji,jj,mikv(ji,jj)) = pgvi(ji,jj,jn)
@@ -256,5 +272,5 @@
          DO jk = 1, jpkm1                                 ! Horizontal slab
             !
-            DO_2D( 1, 1, 1, 1 )
+            DO_2D( iij, iij, iij, iij )
                !                             !== Vertical tracer gradient
                zdk1t(ji,jj) = ( pt(ji,jj,jk,jn) - pt(ji,jj,jk+1,jn) ) * wmask(ji,jj,jk+1)     ! level jk+1
@@ -265,5 +281,5 @@
             END_2D
             !
-            DO_2D( 1, 0, 1, 0 )           !==  Horizontal fluxes
+            DO_2D( iij, iij-1, iij, iij-1 )           !==  Horizontal fluxes
                zabe1 = pahu(ji,jj,jk) * e2_e1u(ji,jj) * e3u(ji,jj,jk,Kmm)
                zabe2 = pahv(ji,jj,jk) * e1_e2v(ji,jj) * e3v(ji,jj,jk,Kmm)
@@ -278,16 +294,29 @@
                zcof2 = - pahv(ji,jj,jk) * e1v(ji,jj) * vslp(ji,jj,jk) * zmskv
                !
-               zftu(ji,jj,jk ) = (  zabe1 * zdit(ji,jj,jk)   &
-                  &               + zcof1 * (  zdkt (ji+1,jj) + zdk1t(ji,jj)      &
-                  &                          + zdk1t(ji+1,jj) + zdkt (ji,jj)  )  ) * umask(ji,jj,jk)
-               zftv(ji,jj,jk) = (  zabe2 * zdjt(ji,jj,jk)   &
-                  &               + zcof2 * (  zdkt (ji,jj+1) + zdk1t(ji,jj)      &
-                  &                          + zdk1t(ji,jj+1) + zdkt (ji,jj)  )  ) * vmask(ji,jj,jk)
+               ! round brackets added to fix the order of floating point operations
+               ! needed to ensure halo 1 - halo 2 compatibility
+               zftu(ji,jj,jk ) = (  zabe1 * zdit(ji,jj,jk)                       &
+                  &               + zcof1 * ( ( zdkt (ji+1,jj) + zdk1t(ji,jj)    &
+                  &                           )                                  & ! bracket for halo 1 - halo 2 compatibility
+                  &                         + ( zdk1t(ji+1,jj) + zdkt (ji,jj)    &
+                  &                           )                                  & ! bracket for halo 1 - halo 2 compatibility
+                  &                         ) ) * umask(ji,jj,jk)
+               zftv(ji,jj,jk) = (  zabe2 * zdjt(ji,jj,jk)                        &
+                  &              + zcof2 * ( ( zdkt (ji,jj+1) + zdk1t(ji,jj)     &
+                  &                           )                                  & ! bracket for halo 1 - halo 2 compatibility
+                  &                         + ( zdk1t(ji,jj+1) + zdkt (ji,jj)    &
+                  &                           )                                  & ! bracket for halo 1 - halo 2 compatibility
+                  &                         ) ) * vmask(ji,jj,jk)
             END_2D
             !
-            DO_2D( 0, 0, 0, 0 )           !== horizontal divergence and add to pta
-               pt_rhs(ji,jj,jk,jn) = pt_rhs(ji,jj,jk,jn)    &
-                  &       + zsign * (  zftu(ji,jj,jk) - zftu(ji-1,jj,jk) + zftv(ji,jj,jk) - zftv(ji,jj-1,jk)  )   &
-                  &                                              * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
+            DO_2D( iij-1, iij-1, iij-1, iij-1 )           !== horizontal divergence and add to pta
+               ! round brackets added to fix the order of floating point operations
+               ! needed to ensure halo 1 - halo 2 compatibility
+               pt_rhs(ji,jj,jk,jn) = pt_rhs(ji,jj,jk,jn)                         &
+                  &       + zsign * ( ( zftu(ji,jj,jk) - zftu(ji-1,jj,jk)        &
+                  &                   )                                          & ! bracket for halo 1 - halo 2 compatibility
+                  &                 + ( zftv(ji,jj,jk) - zftv(ji,jj-1,jk)        &
+                  &                   )                                          & ! bracket for halo 1 - halo 2 compatibility
+                  &                 ) * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
             END_2D
          END DO                                        !   End of slab
@@ -302,5 +331,5 @@
          ztfw(:,:, 1 ) = 0._wp      ;      ztfw(:,:,jpk) = 0._wp
 
-         DO_3D( 0, 0, 0, 0, 2, jpkm1 )    ! interior (2=<jk=<jpk-1)
+         DO_3D( iij-1, iij-1, iij-1, iij-1, 2, jpkm1 )    ! interior (2=<jk=<jpk-1)
             !
             zmsku = wmask(ji,jj,jk) / MAX(   umask(ji  ,jj,jk-1) + umask(ji-1,jj,jk)          &
@@ -317,12 +346,20 @@
             zcoef4 = - zahv_w * e1t(ji,jj) * zmskv * wslpj (ji,jj,jk)
             !
-            ztfw(ji,jj,jk) = zcoef3 * (   zdit(ji  ,jj  ,jk-1) + zdit(ji-1,jj  ,jk)      &
-               &                        + zdit(ji-1,jj  ,jk-1) + zdit(ji  ,jj  ,jk)  )   &
-               &           + zcoef4 * (   zdjt(ji  ,jj  ,jk-1) + zdjt(ji  ,jj-1,jk)      &
-               &                        + zdjt(ji  ,jj-1,jk-1) + zdjt(ji  ,jj  ,jk)  )
+            ! round brackets added to fix the order of floating point operations
+            ! needed to ensure halo 1 - halo 2 compatibility
+            ztfw(ji,jj,jk) = zcoef3 * ( ( zdit(ji  ,jj  ,jk-1) + zdit(ji-1,jj  ,jk)    &
+                  &                     )                                              & ! bracket for halo 1 - halo 2 compatibility
+                  &                   + ( zdit(ji-1,jj  ,jk-1) + zdit(ji  ,jj  ,jk)    &
+                  &                     )                                              & ! bracket for halo 1 - halo 2 compatibility
+                  &                   )                                                &
+                  &        + zcoef4 * ( ( zdjt(ji  ,jj  ,jk-1) + zdjt(ji  ,jj-1,jk)    &
+                  &                     )                                              & ! bracket for halo 1 - halo 2 compatibility
+                  &                   + ( zdjt(ji  ,jj-1,jk-1) + zdjt(ji  ,jj  ,jk)    &
+                  &                     )                                              & ! bracket for halo 1 - halo 2 compatibility
+                  &                   )
          END_3D
          !                                !==  add the vertical 33 flux  ==!
          IF( ln_traldf_lap ) THEN               ! laplacian case: eddy coef = ah_wslp2 - akz
-            DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+            DO_3D( iij-1, iij-1, iij-1, iij-1, 2, jpkm1 )
                ztfw(ji,jj,jk) = ztfw(ji,jj,jk) + e1e2t(ji,jj) / e3w(ji,jj,jk,Kmm) * wmask(ji,jj,jk)   &
                   &                            * ( ah_wslp2(ji,jj,jk) - akz(ji,jj,jk) )               &
@@ -333,5 +370,5 @@
             SELECT CASE( kpass )
             CASE(  1  )                            ! 1st pass : eddy coef = ah_wslp2
-               DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+               DO_3D( iij-1, iij-1, iij-1, iij-1, 2, jpkm1 )
                   ztfw(ji,jj,jk) =   &
                      &  ztfw(ji,jj,jk) + ah_wslp2(ji,jj,jk) * e1e2t(ji,jj)   &
@@ -347,5 +384,5 @@
          ENDIF
          !
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )    !==  Divergence of vertical fluxes added to pta  ==!
+         DO_3D( iij-1, iij-1, iij-1, iij-1, 1, jpkm1 )    !==  Divergence of vertical fluxes added to pta  ==!
             pt_rhs(ji,jj,jk,jn) = pt_rhs(ji,jj,jk,jn) + zsign * (  ztfw (ji,jj,jk) - ztfw(ji,jj,jk+1)  ) * r1_e1e2t(ji,jj)   &
                &                                             / e3t(ji,jj,jk,Kmm)
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traldf_lap_blp.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traldf_lap_blp.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traldf_lap_blp.F90	(revision 14852)
@@ -103,10 +103,10 @@
       !
       INTEGER  ::   ji, jj, jk, jn      ! dummy loop indices
-      INTEGER  ::   isi, iei, isj, iej  ! local integers
+      INTEGER  ::   iij
       REAL(wp) ::   zsign               ! local scalars
       REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   ztu, ztv, zaheeu, zaheev
       !!----------------------------------------------------------------------
       !
-      IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+      IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
          IF( kt == nit000 .AND. lwp )  THEN
             WRITE(numout,*)
@@ -122,4 +122,9 @@
       ENDIF
       !
+      ! Define pt_rhs halo points for multi-point haloes in bilaplacian case
+      IF( nldf_tra == np_blp .AND. kpass == 1 ) THEN ; iij = nn_hls
+      ELSE                                           ; iij = 1
+      ENDIF
+
       !                                !==  Initialization of metric arrays used for all tracers  ==!
       IF( kpass == 1 ) THEN   ;   zsign =  1._wp      ! bilaplacian operator require a minus sign (eddy diffusivity >0)
@@ -127,10 +132,5 @@
       ENDIF
 
-      IF( ntsi == Nis0 ) THEN ; isi = nn_hls - 1 ; ELSE ; isi = 0 ; ENDIF    ! Avoid double-counting when using tiling
-      IF( ntsj == Njs0 ) THEN ; isj = nn_hls - 1 ; ELSE ; isj = 0 ; ENDIF
-      IF( ntei == Nie0 ) THEN ; iei = nn_hls - 1 ; ELSE ; iei = 0 ; ENDIF
-      IF( ntej == Nje0 ) THEN ; iej = nn_hls - 1 ; ELSE ; iej = 0 ; ENDIF
-
-      DO_3D( nn_hls, nn_hls-1, nn_hls, nn_hls-1, 1, jpkm1 )            !== First derivative (gradient)  ==!
+      DO_3D( iij, iij-1, iij, iij-1, 1, jpkm1 )            !== First derivative (gradient)  ==!
          zaheeu(ji,jj,jk) = zsign * pahu(ji,jj,jk) * e2_e1u(ji,jj) * e3u(ji,jj,jk,Kmm)   !!gm   * umask(ji,jj,jk) pah masked!
          zaheev(ji,jj,jk) = zsign * pahv(ji,jj,jk) * e1_e2v(ji,jj) * e3v(ji,jj,jk,Kmm)   !!gm   * vmask(ji,jj,jk)
@@ -141,15 +141,15 @@
          !                          ! =========== !
          !
-         DO_3D( nn_hls, nn_hls-1, nn_hls, nn_hls-1, 1, jpkm1 )            !== First derivative (gradient)  ==!
+         DO_3D( iij, iij-1, iij, iij-1, 1, jpkm1 )            !== First derivative (gradient)  ==!
             ztu(ji,jj,jk) = zaheeu(ji,jj,jk) * ( pt(ji+1,jj  ,jk,jn) - pt(ji,jj,jk,jn) )
             ztv(ji,jj,jk) = zaheev(ji,jj,jk) * ( pt(ji  ,jj+1,jk,jn) - pt(ji,jj,jk,jn) )
          END_3D
          IF( ln_zps ) THEN                             ! set gradient at bottom/top ocean level
-            DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )                              ! bottom
+            DO_2D( iij, iij-1, iij, iij-1 )                              ! bottom
                ztu(ji,jj,mbku(ji,jj)) = zaheeu(ji,jj,mbku(ji,jj)) * pgu(ji,jj,jn)
                ztv(ji,jj,mbkv(ji,jj)) = zaheev(ji,jj,mbkv(ji,jj)) * pgv(ji,jj,jn)
             END_2D
             IF( ln_isfcav ) THEN                             ! top in ocean cavities only
-               DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )
+               DO_2D( iij, iij-1, iij, iij-1 )
                   IF( miku(ji,jj) > 1 )   ztu(ji,jj,miku(ji,jj)) = zaheeu(ji,jj,miku(ji,jj)) * pgui(ji,jj,jn)
                   IF( mikv(ji,jj) > 1 )   ztv(ji,jj,mikv(ji,jj)) = zaheev(ji,jj,mikv(ji,jj)) * pgvi(ji,jj,jn)
@@ -158,8 +158,12 @@
          ENDIF
          !
-         DO_3D( isi, iei, isj, iej, 1, jpkm1 )            !== Second derivative (divergence) added to the general tracer trends  ==!
-            pt_rhs(ji,jj,jk,jn) = pt_rhs(ji,jj,jk,jn) + (  ztu(ji,jj,jk) - ztu(ji-1,jj,jk)     &
-               &                                      +    ztv(ji,jj,jk) - ztv(ji,jj-1,jk) )   &
-               &                                      / ( e1e2t(ji,jj) * e3t(ji,jj,jk,Kmm) )
+         DO_3D( iij-1, iij-1, iij-1, iij-1, 1, jpkm1 )            !== Second derivative (divergence) added to the general tracer trends  ==!
+            ! round brackets added to fix the order of floating point operations
+            ! needed to ensure halo 1 - halo 2 compatibility
+            pt_rhs(ji,jj,jk,jn) = pt_rhs(ji,jj,jk,jn) + ( ( ztu(ji,jj,jk) - ztu(ji-1,jj,jk)    &
+               &                                          )                                    & ! bracket for halo 1 - halo 2 compatibility
+               &                                      +   ( ztv(ji,jj,jk) - ztv(ji,jj-1,jk)    &
+               &                                          )                                    & ! bracket for halo 1 - halo 2 compatibility
+               &                                        ) / ( e1e2t(ji,jj) * e3t(ji,jj,jk,Kmm) )
          END_3D
          !
@@ -211,5 +215,5 @@
       !!---------------------------------------------------------------------
       !
-      IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+      IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
          IF( kt == kit000 .AND. lwp )  THEN
             WRITE(numout,*)
@@ -235,5 +239,5 @@
       END SELECT
       !
-      CALL lbc_lnk( 'traldf_lap_blp', zlap(:,:,:,:) , 'T', 1.0_wp )     ! Lateral boundary conditions (unchanged sign)
+      IF (nn_hls==1) CALL lbc_lnk( 'traldf_lap_blp', zlap(:,:,:,:) , 'T', 1.0_wp )     ! Lateral boundary conditions (unchanged sign)
       !                                               ! Partial top/bottom cell: GRADh( zlap )
       IF( ln_isfcav .AND. ln_zps ) THEN   ;   CALL zps_hde_isf( kt, Kmm, kjpt, zlap, zglu, zglv, zgui, zgvi )  ! both top & bottom
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traldf_triad.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traldf_triad.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traldf_triad.F90	(revision 14852)
@@ -13,6 +13,4 @@
    USE oce            ! ocean dynamics and active tracers
    USE dom_oce        ! ocean space and time domain
-   ! TEMP: [tiling] This change not necessary if XIOS has subdomain support
-   USE domtile
    USE domutl, ONLY : is_tile
    USE phycst         ! physical constants
@@ -109,22 +107,16 @@
       REAL(wp), DIMENSION(A2D_T(ktt_rhs),JPK,KJPT), INTENT(inout) ::   pt_rhs     ! tracer trend
       !
-      INTEGER  ::  ji, jj, jk, jn   ! dummy loop indices
-      INTEGER  ::  ip,jp,kp         ! dummy loop indices
-      INTEGER  ::  ierr            ! local integer
-      REAL(wp) ::  zmsku, zabe1, zcof1, zcoef3    ! local scalars
-      REAL(wp) ::  zmskv, zabe2, zcof2, zcoef4    !   -      -
+      INTEGER  ::  ji, jj, jk, jn, kp, iij   ! dummy loop indices
       REAL(wp) ::  zcoef0, ze3w_2, zsign          !   -      -
       !
-      REAL(wp) ::   zslope_skew, zslope_iso, zslope2, zbu, zbv
-      REAL(wp) ::   ze1ur, ze2vr, ze3wr, zdxt, zdyt, zdzt
-      REAL(wp) ::   zah, zah_slp, zaei_slp
-      REAL(wp), DIMENSION(A2D(nn_hls),0:1)     ::   zdkt3d                         ! vertical tracer gradient at 2 levels
-      REAL(wp), DIMENSION(A2D(nn_hls)        ) ::   z2d                            ! 2D workspace
-      REAL(wp), DIMENSION(A2D(nn_hls)    ,jpk) ::   zdit, zdjt, zftu, zftv, ztfw   ! 3D     -
-      ! TEMP: [tiling] This can be A2D(nn_hls) if XIOS has subdomain support
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zpsi_uw, zpsi_vw
+      REAL(wp) ::   zslope2, zbu, zbv, zbu1, zbv1, zslope21, zah, zah1, zah_ip1, zah_jp1, zbu_ip1, zbv_jp1
+      REAL(wp) ::   ze1ur, ze2vr, ze3wr, zdxt, zdyt, zdzt, zdyt_jp1, ze3wr_jp1, zdzt_jp1, zah_slp1, zah_slp_jp1, zaei_slp_jp1
+      REAL(wp) ::   zah_slp, zaei_slp, zdxt_ip1, ze3wr_ip1, zdzt_ip1, zah_slp_ip1, zaei_slp_ip1, zaei_slp1
+      REAL(wp), DIMENSION(A2D(nn_hls),0:1) ::   zdkt3d                                           ! vertical tracer gradient at 2 levels
+      REAL(wp), DIMENSION(A2D(nn_hls)    ) ::   z2d                                              ! 2D workspace
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zdit, zdjt, zftu, zftv, ztfw, zpsi_uw, zpsi_vw   ! 3D     -
       !!----------------------------------------------------------------------
       !
-      IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+      IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
          IF( kpass == 1 .AND. kt == kit000 )  THEN
             IF(lwp) WRITE(numout,*)
@@ -142,4 +134,10 @@
       ENDIF
       !
+      ! Define pt_rhs halo points for multi-point haloes in bilaplacian case
+      IF( nldf_tra == np_blp_it .AND. kpass == 1 ) THEN ; iij = nn_hls
+      ELSE                                              ; iij = 1
+      ENDIF
+
+      !
       IF( kpass == 1 ) THEN   ;   zsign =  1._wp      ! bilaplacian operator require a minus sign (eddy diffusivity >0)
       ELSE                    ;   zsign = -1._wp
@@ -152,44 +150,54 @@
       IF( kpass == 1 ) THEN         !==  first pass only  and whatever the tracer is  ==!
          !
-         DO_3D( 0, 0, 0, 0, 1, jpk )
+         DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpk )
             akz     (ji,jj,jk) = 0._wp
             ah_wslp2(ji,jj,jk) = 0._wp
          END_3D
          !
-         DO ip = 0, 1                            ! i-k triads
-            DO kp = 0, 1
-               DO_3D( 0, 0, 0, 0, 1, jpkm1 )
-                  ze3wr = 1._wp / e3w(ji,jj,jk+kp,Kmm)
-                  zbu   = e1e2u(ji-ip,jj) * e3u(ji-ip,jj,jk,Kmm)
-                  zah   = 0.25_wp * pahu(ji-ip,jj,jk)
-                  zslope_skew = triadi_g(ji,jj,jk,1-ip,kp)
-                  ! Subtract s-coordinate slope at t-points to give slope rel to s-surfaces (do this by *adding* gradient of depth)
-                  zslope2 = zslope_skew + ( gdept(ji-ip+1,jj,jk,Kmm) - gdept(ji-ip,jj,jk,Kmm) ) * r1_e1u(ji-ip,jj) * umask(ji-ip,jj,jk+kp)
-                  zslope2 = zslope2 *zslope2
-                  ah_wslp2(ji,jj,jk+kp) = ah_wslp2(ji,jj,jk+kp) + zah * zbu * ze3wr * r1_e1e2t(ji,jj) * zslope2
-                  akz     (ji,jj,jk+kp) = akz     (ji,jj,jk+kp) + zah * r1_e1u(ji-ip,jj)       &
-                     &                                                      * r1_e1u(ji-ip,jj) * umask(ji-ip,jj,jk+kp)
-                     !
-               END_3D
-            END DO
+         DO kp = 0, 1                            ! i-k triads
+            DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpkm1 )
+               ze3wr = 1._wp / e3w(ji,jj,jk+kp,Kmm)
+               zbu   = e1e2u(ji,jj) * e3u(ji,jj,jk,Kmm)
+               zbu1  = e1e2u(ji-1,jj) * e3u(ji-1,jj,jk,Kmm)
+               zah   = 0.25_wp * pahu(ji,jj,jk)
+               zah1  = 0.25_wp * pahu(ji-1,jj,jk)
+               ! Subtract s-coordinate slope at t-points to give slope rel to s-surfaces (do this by *adding* gradient of depth)
+               zslope2 = triadi_g(ji,jj,jk,1,kp) + ( gdept(ji+1,jj,jk,Kmm) - gdept(ji,jj,jk,Kmm) ) * r1_e1u(ji,jj) * umask(ji,jj,jk+kp)
+               zslope2 = zslope2 *zslope2
+               zslope21 = triadi_g(ji,jj,jk,0,kp) + ( gdept(ji,jj,jk,Kmm) - gdept(ji-1,jj,jk,Kmm) ) * r1_e1u(ji-1,jj) * umask(ji-1,jj,jk+kp)
+               zslope21 = zslope21 *zslope21
+               ! round brackets added to fix the order of floating point operations
+               ! needed to ensure halo 1 - halo 2 compatibility
+               ah_wslp2(ji,jj,jk+kp) =  ah_wslp2(ji,jj,jk+kp) + ( zah * zbu * ze3wr * r1_e1e2t(ji,jj) * zslope2                    &
+                        &                                       + zah1 * zbu1 * ze3wr * r1_e1e2t(ji,jj) * zslope21                 &
+                        &                                       )                                                                  ! bracket for halo 1 - halo 2 compatibility
+               akz     (ji,jj,jk+kp) =  akz     (ji,jj,jk+kp) + ( zah * r1_e1u(ji,jj) * r1_e1u(ji,jj) * umask(ji,jj,jk+kp)         &
+                                                                + zah1 * r1_e1u(ji-1,jj) * r1_e1u(ji-1,jj) * umask(ji-1,jj,jk+kp)  &
+                        &                                       )                                                                  ! bracket for halo 1 - halo 2 compatibility
+            END_3D
          END DO
          !
-         DO jp = 0, 1                            ! j-k triads
-            DO kp = 0, 1
-               DO_3D( 0, 0, 0, 0, 1, jpkm1 )
-                  ze3wr = 1.0_wp / e3w(ji,jj,jk+kp,Kmm)
-                  zbv   = e1e2v(ji,jj-jp) * e3v(ji,jj-jp,jk,Kmm)
-                  zah   = 0.25_wp * pahv(ji,jj-jp,jk)
-                  zslope_skew = triadj_g(ji,jj,jk,1-jp,kp)
-                  ! Subtract s-coordinate slope at t-points to give slope rel to s surfaces
-                  !    (do this by *adding* gradient of depth)
-                  zslope2 = zslope_skew + ( gdept(ji,jj-jp+1,jk,Kmm) - gdept(ji,jj-jp,jk,Kmm) ) * r1_e2v(ji,jj-jp) * vmask(ji,jj-jp,jk+kp)
-                  zslope2 = zslope2 * zslope2
-                  ah_wslp2(ji,jj,jk+kp) = ah_wslp2(ji,jj,jk+kp) + zah * zbv * ze3wr * r1_e1e2t(ji,jj) * zslope2
-                  akz     (ji,jj,jk+kp) = akz     (ji,jj,jk+kp) + zah * r1_e2v(ji,jj-jp)     &
-                     &                                                      * r1_e2v(ji,jj-jp) * vmask(ji,jj-jp,jk+kp)
-                  !
-               END_3D
-            END DO
+         DO kp = 0, 1                            ! j-k triads
+            DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpkm1 )
+               ze3wr = 1.0_wp / e3w(ji,jj,jk+kp,Kmm)
+               zbv   = e1e2v(ji,jj) * e3v(ji,jj,jk,Kmm)
+               zbv1   = e1e2v(ji,jj-1) * e3v(ji,jj-1,jk,Kmm)
+               zah   = 0.25_wp * pahv(ji,jj,jk)
+               zah1   = 0.25_wp * pahv(ji,jj-1,jk)
+               ! Subtract s-coordinate slope at t-points to give slope rel to s surfaces
+               !    (do this by *adding* gradient of depth)
+               zslope2 = triadj_g(ji,jj,jk,1,kp) + ( gdept(ji,jj+1,jk,Kmm) - gdept(ji,jj,jk,Kmm) ) * r1_e2v(ji,jj) * vmask(ji,jj,jk+kp)
+               zslope2 = zslope2 * zslope2
+               zslope21 = triadj_g(ji,jj,jk,0,kp) + ( gdept(ji,jj,jk,Kmm) - gdept(ji,jj-1,jk,Kmm) ) * r1_e2v(ji,jj-1) * vmask(ji,jj-1,jk+kp)
+               zslope21 = zslope21 * zslope21
+               ! round brackets added to fix the order of floating point operations
+               ! needed to ensure halo 1 - halo 2 compatibility
+               ah_wslp2(ji,jj,jk+kp) = ah_wslp2(ji,jj,jk+kp) + ( zah * zbv * ze3wr * r1_e1e2t(ji,jj) * zslope2                     &
+                        &                                      + zah1 * zbv1 * ze3wr * r1_e1e2t(ji,jj) * zslope21                  &
+                        &                                      )                                                                   ! bracket for halo 1 - halo 2 compatibility
+               akz     (ji,jj,jk+kp) = akz     (ji,jj,jk+kp) + ( zah * r1_e2v(ji,jj) * r1_e2v(ji,jj) * vmask(ji,jj,jk+kp)          &
+                        &                                      + zah1 * r1_e2v(ji,jj-1) * r1_e2v(ji,jj-1) * vmask(ji,jj-1,jk+kp)   &
+                        &                                      )                                                                   ! bracket for halo 1 - halo 2 compatibility
+            END_3D
          END DO
          !
@@ -197,5 +205,5 @@
             !
             IF( ln_traldf_blp ) THEN                ! bilaplacian operator
-               DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+               DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
                   akz(ji,jj,jk) = 16._wp           &
                      &   * ah_wslp2   (ji,jj,jk)   &
@@ -205,5 +213,5 @@
                END_3D
             ELSEIF( ln_traldf_lap ) THEN              ! laplacian operator
-               DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+               DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
                   ze3w_2 = e3w(ji,jj,jk,Kmm) * e3w(ji,jj,jk,Kmm)
                   zcoef0 = rDt * (  akz(ji,jj,jk) + ah_wslp2(ji,jj,jk) / ze3w_2  )
@@ -213,31 +221,28 @@
            !
          ELSE                                    ! 33 flux set to zero with akz=ah_wslp2 ==>> computed in full implicit
-            DO_3D( 0, 0, 0, 0, 1, jpk )
+            DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpk )
                akz(ji,jj,jk) = ah_wslp2(ji,jj,jk)
             END_3D
          ENDIF
          !
-         ! TEMP: [tiling] These changes not necessary if XIOS has subdomain support
-         IF( ntile == 0 .OR. ntile == nijtile )  THEN                ! Do only for the full domain
-            IF( ln_ldfeiv_dia .AND. cdtype == 'TRA' ) THEN
-               IF( ln_tile ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = 0 )
-
-               zpsi_uw(:,:,:) = 0._wp
-               zpsi_vw(:,:,:) = 0._wp
-
-               DO jp = 0, 1
-                  DO kp = 0, 1
-                     DO_3D( 1, 0, 1, 0, 1, jpkm1 )
-                        zpsi_uw(ji,jj,jk+kp) = zpsi_uw(ji,jj,jk+kp) &
-                           & + 0.25_wp * aeiu(ji,jj,jk) * e2u(ji,jj) * triadi_g(ji+jp,jj,jk,1-jp,kp)
-                        zpsi_vw(ji,jj,jk+kp) = zpsi_vw(ji,jj,jk+kp) &
-                           & + 0.25_wp * aeiv(ji,jj,jk) * e1v(ji,jj) * triadj_g(ji,jj+jp,jk,1-jp,kp)
-                     END_3D
-                  END DO
-               END DO
-               CALL ldf_eiv_dia( zpsi_uw, zpsi_vw, Kmm )
-
-               IF( ln_tile ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = nijtile )
-            ENDIF
+         IF( ln_ldfeiv_dia .AND. cdtype == 'TRA' ) THEN
+            zpsi_uw(:,:,:) = 0._wp
+            zpsi_vw(:,:,:) = 0._wp
+
+            DO kp = 0, 1
+               DO_3D( 1, 0, 1, 0, 1, jpkm1 )
+                  ! round brackets added to fix the order of floating point operations
+                  ! needed to ensure halo 1 - halo 2 compatibility
+                  zpsi_uw(ji,jj,jk+kp) = zpsi_uw(ji,jj,jk+kp)                                     &
+                     & + ( 0.25_wp * aeiu(ji,jj,jk) * e2u(ji,jj) * triadi_g(ji,jj,jk,1,kp)        &
+                     &   + 0.25_wp * aeiu(ji,jj,jk) * e2u(ji,jj) * triadi_g(ji+1,jj,jk,0,kp)      &
+                     &   )                                                                        ! bracket for halo 1 - halo 2 compatibility
+                  zpsi_vw(ji,jj,jk+kp) = zpsi_vw(ji,jj,jk+kp)                                     &
+                     & + ( 0.25_wp * aeiv(ji,jj,jk) * e1v(ji,jj) * triadj_g(ji,jj,jk,1,kp)        &
+                     &   + 0.25_wp * aeiv(ji,jj,jk) * e1v(ji,jj) * triadj_g(ji,jj+1,jk,0,kp)      &
+                     &   )                                                                        ! bracket for halo 1 - halo 2 compatibility
+               END_3D
+            END DO
+            CALL ldf_eiv_dia( zpsi_uw, zpsi_vw, Kmm )
          ENDIF
          !
@@ -252,16 +257,18 @@
          zftu(:,:,:) = 0._wp
          zftv(:,:,:) = 0._wp
-         !
-         DO_3D( 1, 0, 1, 0, 1, jpkm1 )    !==  before lateral T & S gradients at T-level jk  ==!
+         zdit(:,:,:) = 0._wp
+         zdjt(:,:,:) = 0._wp
+         !
+         DO_3D( iij, iij-1, iij, iij-1, 1, jpkm1 )    !==  before lateral T & S gradients at T-level jk  ==!
             zdit(ji,jj,jk) = ( pt(ji+1,jj  ,jk,jn) - pt(ji,jj,jk,jn) ) * umask(ji,jj,jk)
             zdjt(ji,jj,jk) = ( pt(ji  ,jj+1,jk,jn) - pt(ji,jj,jk,jn) ) * vmask(ji,jj,jk)
          END_3D
          IF( ln_zps .AND. l_grad_zps ) THEN    ! partial steps: correction at top/bottom ocean level
-            DO_2D( 1, 0, 1, 0 )                    ! bottom level
+            DO_2D( iij, iij-1, iij, iij-1 )                    ! bottom level
                zdit(ji,jj,mbku(ji,jj)) = pgu(ji,jj,jn)
                zdjt(ji,jj,mbkv(ji,jj)) = pgv(ji,jj,jn)
             END_2D
             IF( ln_isfcav ) THEN                   ! top level (ocean cavities only)
-               DO_2D( 1, 0, 1, 0 )
+               DO_2D( iij, iij-1, iij, iij-1 )
                   IF( miku(ji,jj)  > 1 )   zdit(ji,jj,miku(ji,jj) ) = pgui(ji,jj,jn)
                   IF( mikv(ji,jj)  > 1 )   zdjt(ji,jj,mikv(ji,jj) ) = pgvi(ji,jj,jn)
@@ -276,5 +283,5 @@
          DO jk = 1, jpkm1
             !                    !==  Vertical tracer gradient at level jk and jk+1
-            DO_2D( 1, 1, 1, 1 )
+            DO_2D( iij, iij, iij, iij )
                zdkt3d(ji,jj,1) = ( pt(ji,jj,jk,jn) - pt(ji,jj,jk+1,jn) ) * tmask(ji,jj,jk+1)
             END_2D
@@ -283,5 +290,5 @@
             IF( jk == 1 ) THEN   ;   zdkt3d(:,:,0) = zdkt3d(:,:,1)
             ELSE
-               DO_2D( 1, 1, 1, 1 )
+               DO_2D( iij, iij, iij, iij )
                   zdkt3d(ji,jj,0) = ( pt(ji,jj,jk-1,jn) - pt(ji,jj,jk,jn) ) * tmask(ji,jj,jk)
                END_2D
@@ -289,96 +296,163 @@
             !
             zaei_slp = 0._wp
+            zaei_slp_ip1 = 0._wp
+            zaei_slp_jp1 = 0._wp
+            zaei_slp1 = 0._wp
             !
             IF( ln_botmix_triad ) THEN
-               DO ip = 0, 1              !==  Horizontal & vertical fluxes
-                  DO kp = 0, 1
-                     DO_2D( 1, 0, 1, 0 )
-                        ze1ur = r1_e1u(ji,jj)
-                        zdxt  = zdit(ji,jj,jk) * ze1ur
-                        ze3wr = 1._wp / e3w(ji+ip,jj,jk+kp,Kmm)
-                        zdzt  = zdkt3d(ji+ip,jj,kp) * ze3wr
-                        zslope_skew = triadi_g(ji+ip,jj,jk,1-ip,kp)
-                        zslope_iso  = triadi  (ji+ip,jj,jk,1-ip,kp)
-                        !
-                        zbu = 0.25_wp * e1e2u(ji,jj) * e3u(ji,jj,jk,Kmm)
-                        ! ln_botmix_triad is .T. don't mask zah for bottom half cells    !!gm ?????   ahu is masked....
-                        zah = pahu(ji,jj,jk)
-                        zah_slp  = zah * zslope_iso
-                        IF( ln_ldfeiv )   zaei_slp = aeiu(ji,jj,jk) * zslope_skew
-                        zftu(ji   ,jj,jk   ) = zftu(ji   ,jj,jk   ) - ( zah * zdxt + (zah_slp - zaei_slp) * zdzt ) * zbu * ze1ur
-                        ztfw(ji+ip,jj,jk+kp) = ztfw(ji+ip,jj,jk+kp) - ( zah_slp + zaei_slp) * zdxt                 * zbu * ze3wr
-                     END_2D
-                  END DO
+               DO kp = 0, 1              !==  Horizontal & vertical fluxes
+                  DO_2D( iij, iij-1, iij, iij-1 )
+                     ze1ur = r1_e1u(ji,jj)
+                     zdxt  = zdit(ji,jj,jk) * ze1ur
+                     zdxt_ip1  = zdit(ji+1,jj,jk) * r1_e1u(ji+1,jj)
+                     ze3wr = 1._wp / e3w(ji,jj,jk+kp,Kmm)
+                     ze3wr_ip1 = 1._wp / e3w(ji+1,jj,jk+kp,Kmm)
+                     zdzt  = zdkt3d(ji,jj,kp) * ze3wr
+                     zdzt_ip1  = zdkt3d(ji+1,jj,kp) * ze3wr_ip1
+                     !
+                     zbu = 0.25_wp * e1e2u(ji,jj) * e3u(ji,jj,jk,Kmm)
+                     zbu_ip1 = 0.25_wp * e1e2u(ji+1,jj) * e3u(ji+1,jj,jk,Kmm)
+                     ! ln_botmix_triad is .T. don't mask zah for bottom half cells    !!gm ?????   ahu is masked....
+                     zah = pahu(ji,jj,jk)
+                     zah_ip1 = pahu(ji+1,jj,jk)
+                     zah_slp  = zah * triadi(ji,jj,jk,1,kp)
+                     zah_slp_ip1  = zah_ip1 * triadi(ji+1,jj,jk,1,kp)
+                     zah_slp1  = zah * triadi(ji+1,jj,jk,0,kp)
+                     IF( ln_ldfeiv )   THEN
+                        zaei_slp = aeiu(ji,jj,jk) * triadi_g(ji,jj,jk,1,kp)
+                        zaei_slp_ip1 = aeiu(ji+1,jj,jk) * triadi_g(ji+1,jj,jk,1,kp)
+                        zaei_slp1 = aeiu(ji,jj,jk) * triadi_g(ji+1,jj,jk,0,kp)
+                     ENDIF
+                     ! round brackets added to fix the order of floating point operations
+                     ! needed to ensure halo 1 - halo 2 compatibility
+                     zftu(ji   ,jj,jk  ) =  zftu(ji   ,jj,jk )                                                               &
+                                         &    - ( ( zah * zdxt + ( zah_slp - zaei_slp ) * zdzt ) * zbu * ze1ur               &
+                                         &      + ( zah * zdxt + zah_slp1 * zdzt_ip1 - zaei_slp1 * zdzt_ip1 ) * zbu * ze1ur  &
+                                         &      )                                                                            ! bracket for halo 1 - halo 2 compatibility
+                     ztfw(ji+1,jj,jk+kp) =  ztfw(ji+1,jj,jk+kp)                                                              &
+                                         &    - ( (zah_slp_ip1 + zaei_slp_ip1) * zdxt_ip1 * zbu_ip1 * ze3wr_ip1              &
+                                         &      + ( zah_slp1 + zaei_slp1) * zdxt * zbu * ze3wr_ip1                           &
+                                         &      )                                                                            ! bracket for halo 1 - halo 2 compatibility
+                  END_2D
                END DO
                !
-               DO jp = 0, 1
-                  DO kp = 0, 1
-                     DO_2D( 1, 0, 1, 0 )
-                        ze2vr = r1_e2v(ji,jj)
-                        zdyt  = zdjt(ji,jj,jk) * ze2vr
-                        ze3wr = 1._wp / e3w(ji,jj+jp,jk+kp,Kmm)
-                        zdzt  = zdkt3d(ji,jj+jp,kp) * ze3wr
-                        zslope_skew = triadj_g(ji,jj+jp,jk,1-jp,kp)
-                        zslope_iso  = triadj(ji,jj+jp,jk,1-jp,kp)
-                        zbv = 0.25_wp * e1e2v(ji,jj) * e3v(ji,jj,jk,Kmm)
-                        ! ln_botmix_triad is .T. don't mask zah for bottom half cells    !!gm ?????  ahv is masked...
-                        zah = pahv(ji,jj,jk)
-                        zah_slp = zah * zslope_iso
-                        IF( ln_ldfeiv )   zaei_slp = aeiv(ji,jj,jk) * zslope_skew
-                        zftv(ji,jj   ,jk   ) = zftv(ji,jj   ,jk   ) - ( zah * zdyt + (zah_slp - zaei_slp) * zdzt ) * zbv * ze2vr
-                        ztfw(ji,jj+jp,jk+kp) = ztfw(ji,jj+jp,jk+kp) - ( zah_slp + zaei_slp ) * zdyt                * zbv * ze3wr
-                     END_2D
-                  END DO
+               DO kp = 0, 1
+                  DO_2D( iij, iij-1, iij, iij-1 )
+                     ze2vr = r1_e2v(ji,jj)
+                     zdyt  = zdjt(ji,jj,jk) * ze2vr
+                     zdyt_jp1  = zdjt(ji,jj+1,jk) * r1_e2v(ji,jj+1)
+                     ze3wr = 1._wp / e3w(ji,jj,jk+kp,Kmm)
+                     ze3wr_jp1 = 1._wp / e3w(ji,jj+1,jk+kp,Kmm)
+                     zdzt  = zdkt3d(ji,jj,kp) * ze3wr
+                     zdzt_jp1  = zdkt3d(ji,jj+1,kp) * ze3wr_jp1
+                     zbv = 0.25_wp * e1e2v(ji,jj) * e3v(ji,jj,jk,Kmm)
+                     zbv_jp1 = 0.25_wp * e1e2v(ji,jj+1) * e3v(ji,jj+1,jk,Kmm)
+                     ! ln_botmix_triad is .T. don't mask zah for bottom half cells    !!gm ?????   ahu is masked....
+                     zah = pahv(ji,jj,jk)          ! pahv(ji,jj+jp,jk)  ????
+                     zah_jp1 = pahv(ji,jj+1,jk)
+                     zah_slp = zah * triadj(ji,jj,jk,1,kp)
+                     zah_slp1 = zah * triadj(ji,jj+1,jk,0,kp)
+                     zah_slp_jp1 = zah_jp1 * triadj(ji,jj+1,jk,1,kp)
+                     IF( ln_ldfeiv )   THEN
+                        zaei_slp = aeiv(ji,jj,jk) * triadj_g(ji,jj,jk,1,kp)
+                        zaei_slp_jp1 = aeiv(ji,jj+1,jk) * triadj_g(ji,jj+1,jk,1,kp)
+                        zaei_slp1 = aeiv(ji,jj,jk) * triadj_g(ji,jj+1,jk,0,kp)
+                     ENDIF
+                     ! round brackets added to fix the order of floating point operations
+                     ! needed to ensure halo 1 - halo 2 compatibility
+                     zftv(ji,jj  ,jk   ) =  zftv(ji,jj  ,jk   )                                                              &
+                                         &    - ( ( zah * zdyt + ( zah_slp - zaei_slp ) * zdzt ) * zbv * ze2vr               &
+                                         &      + ( zah * zdyt + zah_slp1 * zdzt_jp1 - zaei_slp1 * zdzt_jp1 ) * zbv * ze2vr  &
+                                         &      )                                                                            ! bracket for halo 1 - halo 2 compatibility
+                     ztfw(ji,jj+1,jk+kp) =  ztfw(ji,jj+1,jk+kp)                                                              &
+                                         &    - ( ( zah_slp_jp1 + zaei_slp_jp1) * zdyt_jp1 * zbv_jp1 * ze3wr_jp1             &
+                                         &      + ( zah_slp1 + zaei_slp1) * zdyt * zbv * ze3wr_jp1                           &
+                                         &      )                                                                            ! bracket for halo 1 - halo 2 compatibility
+                  END_2D
                END DO
                !
             ELSE
                !
-               DO ip = 0, 1               !==  Horizontal & vertical fluxes
-                  DO kp = 0, 1
-                     DO_2D( 1, 0, 1, 0 )
-                        ze1ur = r1_e1u(ji,jj)
-                        zdxt  = zdit(ji,jj,jk) * ze1ur
-                        ze3wr = 1._wp / e3w(ji+ip,jj,jk+kp,Kmm)
-                        zdzt  = zdkt3d(ji+ip,jj,kp) * ze3wr
-                        zslope_skew = triadi_g(ji+ip,jj,jk,1-ip,kp)
-                        zslope_iso  = triadi(ji+ip,jj,jk,1-ip,kp)
-                        !
-                        zbu = 0.25_wp * e1e2u(ji,jj) * e3u(ji,jj,jk,Kmm)
-                        ! ln_botmix_triad is .F. mask zah for bottom half cells
-                        zah = pahu(ji,jj,jk) * umask(ji,jj,jk+kp)         ! pahu(ji+ip,jj,jk)   ===>>  ????
-                        zah_slp  = zah * zslope_iso
-                        IF( ln_ldfeiv )   zaei_slp = aeiu(ji,jj,jk) * zslope_skew        ! aeit(ji+ip,jj,jk)*zslope_skew
-                        zftu(ji   ,jj,jk   ) = zftu(ji   ,jj,jk   ) - ( zah * zdxt + (zah_slp - zaei_slp) * zdzt ) * zbu * ze1ur
-                        ztfw(ji+ip,jj,jk+kp) = ztfw(ji+ip,jj,jk+kp) - (zah_slp + zaei_slp) * zdxt * zbu * ze3wr
-                     END_2D
-                  END DO
+               DO kp = 0, 1               !==  Horizontal & vertical fluxes
+                  DO_2D( iij, iij-1, iij, iij-1 )
+                     ze1ur = r1_e1u(ji,jj)
+                     zdxt  = zdit(ji,jj,jk) * ze1ur
+                     zdxt_ip1  = zdit(ji+1,jj,jk) * r1_e1u(ji+1,jj)
+                     ze3wr = 1._wp / e3w(ji,jj,jk+kp,Kmm)
+                     ze3wr_ip1 = 1._wp / e3w(ji+1,jj,jk+kp,Kmm)
+                     zdzt  = zdkt3d(ji,jj,kp) * ze3wr
+                     zdzt_ip1  = zdkt3d(ji+1,jj,kp) * ze3wr_ip1
+                     !
+                     zbu = 0.25_wp * e1e2u(ji,jj) * e3u(ji,jj,jk,Kmm)
+                     zbu_ip1 = 0.25_wp * e1e2u(ji+1,jj) * e3u(ji+1,jj,jk,Kmm)
+                     ! ln_botmix_triad is .F. mask zah for bottom half cells
+                     zah = pahu(ji,jj,jk) * umask(ji,jj,jk+kp)         ! pahu(ji+ip,jj,jk)   ===>>  ????
+                     zah_ip1 = pahu(ji+1,jj,jk) * umask(ji+1,jj,jk+kp)
+                     zah_slp  = zah * triadi(ji,jj,jk,1,kp)
+                     zah_slp_ip1  = zah_ip1 * triadi(ji+1,jj,jk,1,kp)
+                     zah_slp1  = zah * triadi(ji+1,jj,jk,0,kp)
+                     IF( ln_ldfeiv )   THEN
+                        zaei_slp = aeiu(ji,jj,jk) * triadi_g(ji,jj,jk,1,kp)
+                        zaei_slp_ip1 = aeiu(ji+1,jj,jk) * triadi_g(ji+1,jj,jk,1,kp)
+                        zaei_slp1 = aeiu(ji,jj,jk) * triadi_g(ji+1,jj,jk,0,kp)
+                     ENDIF
+                     ! round brackets added to fix the order of floating point operations
+                     ! needed to ensure halo 1 - halo 2 compatibility
+                     zftu(ji   ,jj,jk  ) =  zftu(ji   ,jj,jk )                                                               &
+                                         &    - ( ( zah * zdxt + ( zah_slp - zaei_slp ) * zdzt ) * zbu * ze1ur               &
+                                         &      + ( zah * zdxt + zah_slp1 * zdzt_ip1 - zaei_slp1 * zdzt_ip1 ) * zbu * ze1ur  &
+                                         &      )                                                                            ! bracket for halo 1 - halo 2 compatibility
+                     ztfw(ji+1,jj,jk+kp) =  ztfw(ji+1,jj,jk+kp)                                                              &
+                                         &    - ( (zah_slp_ip1 + zaei_slp_ip1) * zdxt_ip1 * zbu_ip1 * ze3wr_ip1              &
+                                         &      + ( zah_slp1 + zaei_slp1) * zdxt * zbu * ze3wr_ip1                           &
+                                         &      )                                                                            ! bracket for halo 1 - halo 2 compatibility
+                  END_2D
                END DO
                !
-               DO jp = 0, 1
-                  DO kp = 0, 1
-                     DO_2D( 1, 0, 1, 0 )
-                        ze2vr = r1_e2v(ji,jj)
-                        zdyt  = zdjt(ji,jj,jk) * ze2vr
-                        ze3wr = 1._wp / e3w(ji,jj+jp,jk+kp,Kmm)
-                        zdzt  = zdkt3d(ji,jj+jp,kp) * ze3wr
-                        zslope_skew = triadj_g(ji,jj+jp,jk,1-jp,kp)
-                        zslope_iso  = triadj(ji,jj+jp,jk,1-jp,kp)
-                        zbv = 0.25_wp * e1e2v(ji,jj) * e3v(ji,jj,jk,Kmm)
-                        ! ln_botmix_triad is .F. mask zah for bottom half cells
-                        zah = pahv(ji,jj,jk) * vmask(ji,jj,jk+kp)         ! pahv(ji,jj+jp,jk)  ????
-                        zah_slp = zah * zslope_iso
-                        IF( ln_ldfeiv )   zaei_slp = aeiv(ji,jj,jk) * zslope_skew        ! aeit(ji,jj+jp,jk)*zslope_skew
-                        zftv(ji,jj,jk) = zftv(ji,jj,jk) - ( zah * zdyt + (zah_slp - zaei_slp) * zdzt ) * zbv * ze2vr
-                        ztfw(ji,jj+jp,jk+kp) = ztfw(ji,jj+jp,jk+kp) - (zah_slp + zaei_slp) * zdyt * zbv * ze3wr
-                     END_2D
-                  END DO
+               DO kp = 0, 1
+                  DO_2D( iij, iij-1, iij, iij-1 )
+                     ze2vr = r1_e2v(ji,jj)
+                     zdyt  = zdjt(ji,jj,jk) * ze2vr
+                     zdyt_jp1  = zdjt(ji,jj+1,jk) * r1_e2v(ji,jj+1)
+                     ze3wr = 1._wp / e3w(ji,jj,jk+kp,Kmm)
+                     ze3wr_jp1 = 1._wp / e3w(ji,jj+1,jk+kp,Kmm)
+                     zdzt  = zdkt3d(ji,jj,kp) * ze3wr
+                     zdzt_jp1  = zdkt3d(ji,jj+1,kp) * ze3wr_jp1
+                     zbv = 0.25_wp * e1e2v(ji,jj) * e3v(ji,jj,jk,Kmm)
+                     zbv_jp1 = 0.25_wp * e1e2v(ji,jj+1) * e3v(ji,jj+1,jk,Kmm)
+                     ! ln_botmix_triad is .F. mask zah for bottom half cells
+                     zah = pahv(ji,jj,jk) * vmask(ji,jj,jk+kp)         ! pahv(ji,jj+jp,jk)  ????
+                     zah_jp1 = pahv(ji,jj+1,jk) * vmask(ji,jj+1,jk+kp)
+                     zah_slp = zah * triadj(ji,jj,jk,1,kp)
+                     zah_slp1 = zah * triadj(ji,jj+1,jk,0,kp)
+                     zah_slp_jp1 = zah_jp1 * triadj(ji,jj+1,jk,1,kp)
+                     IF( ln_ldfeiv )   THEN
+                        zaei_slp = aeiv(ji,jj,jk) * triadj_g(ji,jj,jk,1,kp)
+                        zaei_slp_jp1 = aeiv(ji,jj+1,jk) * triadj_g(ji,jj+1,jk,1,kp)
+                        zaei_slp1 = aeiv(ji,jj,jk) * triadj_g(ji,jj+1,jk,0,kp)
+                     ENDIF
+                     ! round brackets added to fix the order of floating point operations
+                     ! needed to ensure halo 1 - halo 2 compatibility
+                     zftv(ji,jj  ,jk   ) =  zftv(ji,jj  ,jk   )                                                              &
+                                         &    - ( ( zah * zdyt + ( zah_slp - zaei_slp ) * zdzt ) * zbv * ze2vr               &
+                                         &      + ( zah * zdyt + zah_slp1 * zdzt_jp1 - zaei_slp1 * zdzt_jp1 ) * zbv * ze2vr  &
+                                         &      )                                                                            ! bracket for halo 1 - halo 2 compatibility
+                     ztfw(ji,jj+1,jk+kp) =  ztfw(ji,jj+1,jk+kp)                                                              &
+                                         &    - ( ( zah_slp_jp1 + zaei_slp_jp1) * zdyt_jp1 * zbv_jp1 * ze3wr_jp1             &
+                                         &      + ( zah_slp1 + zaei_slp1) * zdyt * zbv * ze3wr_jp1                           &
+                                         &      )                                                                            ! bracket for halo 1 - halo 2 compatibility
+                  END_2D
                END DO
             ENDIF
             !                             !==  horizontal divergence and add to the general trend  ==!
-            DO_2D( 0, 0, 0, 0 )
-               pt_rhs(ji,jj,jk,jn) = pt_rhs(ji,jj,jk,jn)    &
-                  &                       + zsign * (  zftu(ji-1,jj  ,jk) - zftu(ji,jj,jk)       &
-                  &                                           + zftv(ji,jj-1,jk) - zftv(ji,jj,jk)   )   &
-                  &                                        / (  e1e2t(ji,jj) * e3t(ji,jj,jk,Kmm)  )
+            DO_2D( iij-1, iij-1, iij-1, iij-1 )
+               ! round brackets added to fix the order of floating point operations
+               ! needed to ensure halo 1 - halo 2 compatibility
+               pt_rhs(ji,jj,jk,jn) = pt_rhs(ji,jj,jk,jn)                                                &
+                  &                       + zsign * ( ( zftu(ji-1,jj  ,jk) - zftu(ji,jj,jk)             &
+                  &                                   )                                                 & ! bracket for halo 1 - halo 2 compatibility
+                  &                                 + ( zftv(ji,jj-1,jk) - zftv(ji,jj,jk)               &
+                  &                                   )                                                 & ! bracket for halo 1 - halo 2 compatibility
+                  &                                 ) / (  e1e2t(ji,jj) * e3t(ji,jj,jk,Kmm)  )
             END_2D
             !
@@ -387,5 +461,5 @@
          !                                !==  add the vertical 33 flux  ==!
          IF( ln_traldf_lap ) THEN               ! laplacian case: eddy coef = ah_wslp2 - akz
-            DO_3D( 0, 0, 1, 0, 2, jpkm1 )
+            DO_3D( iij-1, iij-1, iij-1, iij-1, 2, jpkm1 )
                ztfw(ji,jj,jk) = ztfw(ji,jj,jk) - e1e2t(ji,jj) / e3w(ji,jj,jk,Kmm) * tmask(ji,jj,jk)   &
                   &                            * ( ah_wslp2(ji,jj,jk) - akz(ji,jj,jk) )             &
@@ -395,10 +469,10 @@
             SELECT CASE( kpass )
             CASE(  1  )                            ! 1st pass : eddy coef = ah_wslp2
-               DO_3D( 0, 0, 1, 0, 2, jpkm1 )
+               DO_3D( iij-1, iij-1, iij-1, iij-1, 2, jpkm1 )
                   ztfw(ji,jj,jk) = ztfw(ji,jj,jk) - e1e2t(ji,jj) / e3w(ji,jj,jk,Kmm) * tmask(ji,jj,jk)             &
                      &                            * ah_wslp2(ji,jj,jk) * ( pt(ji,jj,jk-1,jn) - pt(ji,jj,jk,jn) )
                END_3D
             CASE(  2  )                            ! 2nd pass : eddy flux = ah_wslp2 and akz applied on pt  and pt2 gradients, resp.
-               DO_3D( 0, 0, 1, 0, 2, jpkm1 )
+               DO_3D( 0, 0, 0, 0, 2, jpkm1 )
                   ztfw(ji,jj,jk) = ztfw(ji,jj,jk) - e1e2t(ji,jj) / e3w(ji,jj,jk,Kmm) * tmask(ji,jj,jk)                      &
                      &                            * (  ah_wslp2(ji,jj,jk) * ( pt (ji,jj,jk-1,jn) - pt (ji,jj,jk,jn) )   &
@@ -408,5 +482,5 @@
          ENDIF
          !
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )      !==  Divergence of vertical fluxes added to pta  ==!
+         DO_3D( iij-1, iij-1, iij-1, iij-1, 1, jpkm1 )      !==  Divergence of vertical fluxes added to pta  ==!
             pt_rhs(ji,jj,jk,jn) = pt_rhs(ji,jj,jk,jn)    &
             &                                  + zsign * (  ztfw(ji,jj,jk+1) - ztfw(ji,jj,jk)  )   &
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/tramle.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/tramle.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/tramle.F90	(revision 14852)
@@ -87,7 +87,8 @@
       INTEGER                     , INTENT(in   ) ::   Kmm        ! ocean time level index
       CHARACTER(len=3)            , INTENT(in   ) ::   cdtype     ! =TRA or TRC (tracer indicator)
-      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(inout) ::   pu         ! in : 3 ocean transport components
-      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(inout) ::   pv         ! out: same 3  transport components
-      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(inout) ::   pw         !   increased by the MLE induced transport
+      ! TEMP: [tiling] 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(inout) ::   pu         ! in : 3 ocean transport components
+      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   pv         ! out: same 3  transport components
+      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   pw         !   increased by the MLE induced transport
       !
       INTEGER  ::   ji, jj, jk          ! dummy loop indices
@@ -96,9 +97,6 @@
       REAL(wp) ::   zcvw, zmvw          !   -      -
       INTEGER , DIMENSION(A2D(nn_hls))     :: inml_mle
-      REAL(wp), DIMENSION(A2D(nn_hls))     :: zpsim_u, zpsim_v, zmld, zbm, zhu, zhv, zn2, zLf_MH
+      REAL(wp), DIMENSION(A2D(nn_hls))     :: zpsim_u, zpsim_v, zmld, zbm, zhu, zhv, zn2, zLf_NH, zLf_MH
       REAL(wp), DIMENSION(A2D(nn_hls),jpk) :: zpsi_uw, zpsi_vw
-      ! TEMP: [tiling] These changes not necessary if using XIOS (subdomain support)
-      REAL(wp), DIMENSION(:,:),   ALLOCATABLE, SAVE :: zLf_NH
-      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE, SAVE :: zpsiu_mle, zpsiv_mle
       !!----------------------------------------------------------------------
       !
@@ -110,15 +108,15 @@
          SELECT CASE( nn_mld_uv )                         ! MLD at u- & v-pts
          CASE ( 0 )                                               != min of the 2 neighbour MLDs
-            DO_2D( 1, 0, 1, 0 )
+            DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )
                zhu(ji,jj) = MIN( hmle(ji+1,jj), hmle(ji,jj) )
                zhv(ji,jj) = MIN( hmle(ji,jj+1), hmle(ji,jj) )
             END_2D
          CASE ( 1 )                                               != average of the 2 neighbour MLDs
-            DO_2D( 1, 0, 1, 0 )
+            DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )
                zhu(ji,jj) = MAX( hmle(ji+1,jj), hmle(ji,jj) )
                zhv(ji,jj) = MAX( hmle(ji,jj+1), hmle(ji,jj) )
             END_2D
          CASE ( 2 )                                               != max of the 2 neighbour MLDs
-            DO_2D( 1, 0, 1, 0 )
+            DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )
                zhu(ji,jj) = MAX( hmle(ji+1,jj), hmle(ji,jj) )
                zhv(ji,jj) = MAX( hmle(ji,jj+1), hmle(ji,jj) )
@@ -126,5 +124,5 @@
          END SELECT
          IF( nn_mle == 0 ) THEN           ! Fox-Kemper et al. 2010 formulation
-            DO_2D( 1, 0, 1, 0 )
+            DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )
                zpsim_u(ji,jj) = rn_ce * zhu(ji,jj) * zhu(ji,jj)  * e2u(ji,jj)                                            &
                     &           * dbdx_mle(ji,jj) * MIN( 111.e3_wp , e1u(ji,jj) )   &
@@ -137,5 +135,5 @@
             !
          ELSEIF( nn_mle == 1 ) THEN       ! New formulation (Lf = 5km fo/ff with fo=Coriolis parameter at latitude rn_lat)
-            DO_2D( 1, 0, 1, 0 )
+            DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )
                zpsim_u(ji,jj) = rc_f *   zhu(ji,jj)   * zhu(ji,jj)   * e2u(ji,jj)               &
                     &                  * dbdx_mle(ji,jj) * MIN( 111.e3_wp , e1u(ji,jj) )
@@ -149,9 +147,9 @@
          !                                      !==  MLD used for MLE  ==!
          !                                                ! compute from the 10m density to deal with the diurnal cycle
-         DO_2D( 1, 1, 1, 1 )
+         DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
             inml_mle(ji,jj) = mbkt(ji,jj) + 1                    ! init. to number of ocean w-level (T-level + 1)
          END_2D
          IF ( nla10 > 0 ) THEN                            ! avoid case where first level is thicker than 10m
-           DO_3DS( 1, 1, 1, 1, jpkm1, nlb10, -1 )        ! from the bottom to nlb10 (10m)
+           DO_3DS( nn_hls, nn_hls, nn_hls, nn_hls, jpkm1, nlb10, -1 )        ! from the bottom to nlb10 (10m)
               IF( rhop(ji,jj,jk) > rhop(ji,jj,nla10) + rn_rho_c_mle )   inml_mle(ji,jj) = jk      ! Mixed layer
            END_3D
@@ -163,5 +161,5 @@
          zbm (:,:) = 0._wp
          zn2 (:,:) = 0._wp
-         DO_3D( 1, 1, 1, 1, 1, ikmax )                    ! MLD and mean buoyancy and N2 over the mixed layer
+         DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, ikmax )                    ! MLD and mean buoyancy and N2 over the mixed layer
             zc = e3t(ji,jj,jk,Kmm) * REAL( MIN( MAX( 0, inml_mle(ji,jj)-jk ) , 1  )  )    ! zc being 0 outside the ML t-points
             zmld(ji,jj) = zmld(ji,jj) + zc
@@ -172,15 +170,15 @@
          SELECT CASE( nn_mld_uv )                         ! MLD at u- & v-pts
          CASE ( 0 )                                               != min of the 2 neighbour MLDs
-            DO_2D( 1, 0, 1, 0 )
+            DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )
                zhu(ji,jj) = MIN( zmld(ji+1,jj), zmld(ji,jj) )
                zhv(ji,jj) = MIN( zmld(ji,jj+1), zmld(ji,jj) )
             END_2D
          CASE ( 1 )                                               != average of the 2 neighbour MLDs
-            DO_2D( 1, 0, 1, 0 )
+            DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )
                zhu(ji,jj) = ( zmld(ji+1,jj) + zmld(ji,jj) ) * 0.5_wp
                zhv(ji,jj) = ( zmld(ji,jj+1) + zmld(ji,jj) ) * 0.5_wp
             END_2D
          CASE ( 2 )                                               != max of the 2 neighbour MLDs
-            DO_2D( 1, 0, 1, 0 )
+            DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )
                zhu(ji,jj) = MAX( zmld(ji+1,jj), zmld(ji,jj) )
                zhv(ji,jj) = MAX( zmld(ji,jj+1), zmld(ji,jj) )
@@ -188,5 +186,5 @@
          END SELECT
          !                                                ! convert density into buoyancy
-         DO_2D( 1, 1, 1, 1 )
+         DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
             zbm(ji,jj) = + grav * zbm(ji,jj) / MAX( e3t(ji,jj,1,Kmm), zmld(ji,jj) )
          END_2D
@@ -201,5 +199,5 @@
          !
          IF( nn_mle == 0 ) THEN           ! Fox-Kemper et al. 2010 formulation
-            DO_2D( 1, 0, 1, 0 )
+            DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )
                zpsim_u(ji,jj) = rn_ce * zhu(ji,jj) * zhu(ji,jj)  * e2_e1u(ji,jj)                                            &
                     &           * ( zbm(ji+1,jj) - zbm(ji,jj) ) * MIN( 111.e3_wp , e1u(ji,jj) )   &
@@ -212,5 +210,5 @@
             !
          ELSEIF( nn_mle == 1 ) THEN       ! New formulation (Lf = 5km fo/ff with fo=Coriolis parameter at latitude rn_lat)
-            DO_2D( 1, 0, 1, 0 )
+            DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )
                zpsim_u(ji,jj) = rc_f *   zhu(ji,jj)   * zhu(ji,jj)   * e2_e1u(ji,jj)               &
                     &                  * ( zbm(ji+1,jj) - zbm(ji,jj) ) * MIN( 111.e3_wp , e1u(ji,jj) )
@@ -222,5 +220,5 @@
          !
          IF( nn_conv == 1 ) THEN              ! No MLE in case of convection
-            DO_2D( 1, 0, 1, 0 )
+            DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )
                IF( MIN( zn2(ji,jj) , zn2(ji+1,jj) ) < 0._wp )   zpsim_u(ji,jj) = 0._wp
                IF( MIN( zn2(ji,jj) , zn2(ji,jj+1) ) < 0._wp )   zpsim_v(ji,jj) = 0._wp
@@ -230,5 +228,5 @@
       ENDIF  ! end of ln_osm_mle conditional
     !                                      !==  structure function value at uw- and vw-points  ==!
-    DO_2D( 1, 0, 1, 0 )
+    DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )
        zhu(ji,jj) = 1._wp / MAX(zhu(ji,jj), rsmall)                   ! hu --> 1/hu
        zhv(ji,jj) = 1._wp / MAX(zhv(ji,jj), rsmall) 
@@ -238,5 +236,6 @@
     zpsi_vw(:,:,:) = 0._wp
     !
-      DO_3D( 1, 0, 1, 0, 2, ikmax )                ! start from 2 : surface value = 0
+      DO_3D( nn_hls, nn_hls-1, nn_hls, nn_hls-1, 2, ikmax )                ! start from 2 : surface value = 0
+      
          zcuw = 1._wp - ( gdepw(ji+1,jj,jk,Kmm) + gdepw(ji,jj,jk,Kmm) ) * zhu(ji,jj)
          zcvw = 1._wp - ( gdepw(ji,jj+1,jk,Kmm) + gdepw(ji,jj,jk,Kmm) ) * zhv(ji,jj)
@@ -252,9 +251,9 @@
       !                                      !==  transport increased by the MLE induced transport ==!
       DO jk = 1, ikmax
-         DO_2D( 1, 0, 1, 0 )                      ! CAUTION pu,pv must be defined at row/column i=1 / j=1
+         DO_2D_OVR( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )
             pu(ji,jj,jk) = pu(ji,jj,jk) + ( zpsi_uw(ji,jj,jk) - zpsi_uw(ji,jj,jk+1) )
             pv(ji,jj,jk) = pv(ji,jj,jk) + ( zpsi_vw(ji,jj,jk) - zpsi_vw(ji,jj,jk+1) )
          END_2D
-         DO_2D( 0, 0, 0, 0 )
+         DO_2D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
             pw(ji,jj,jk) = pw(ji,jj,jk) - ( zpsi_uw(ji,jj,jk) - zpsi_uw(ji-1,jj,jk)   &
                &                          + zpsi_vw(ji,jj,jk) - zpsi_vw(ji,jj-1,jk) ) * wmask(ji,jj,1)
@@ -262,10 +261,5 @@
       END DO
 
-      ! TEMP: [tiling] These changes not necessary if using XIOS (subdomain support)
       IF( cdtype == 'TRA') THEN              !==  outputs  ==!
-         IF( ntile == 0 .OR. ntile == 1 ) THEN                             ! Do only on the first tile
-            ALLOCATE( zLf_NH(jpi,jpj), zpsiu_mle(jpi,jpj,jpk), zpsiv_mle(jpi,jpj,jpk) )
-            zpsiu_mle(:,:,:) = 0._wp ; zpsiv_mle(:,:,:) = 0._wp
-         ENDIF
          !
          IF (ln_osm_mle.and.ln_zdfosm) THEN
@@ -279,16 +273,13 @@
          ENDIF
          !
+         CALL iom_put( "Lf_NHpf" , zLf_NH  )    ! Lf = N H / f
+         !
          ! divide by cross distance to give streamfunction with dimensions m^2/s
          DO_3D( 0, 0, 0, 0, 1, ikmax+1 )
-            zpsiu_mle(ji,jj,jk) = zpsi_uw(ji,jj,jk) * r1_e2u(ji,jj)
-            zpsiv_mle(ji,jj,jk) = zpsi_vw(ji,jj,jk) * r1_e1v(ji,jj)
+            zpsi_uw(ji,jj,jk) = zpsi_uw(ji,jj,jk) * r1_e2u(ji,jj)
+            zpsi_vw(ji,jj,jk) = zpsi_vw(ji,jj,jk) * r1_e1v(ji,jj)
          END_3D
-
-         IF( ntile == 0 .OR. ntile == nijtile ) THEN                       ! Do only on the last tile
-            CALL iom_put( "Lf_NHpf" , zLf_NH  )    ! Lf = N H / f
-            CALL iom_put( "psiu_mle", zpsiu_mle )    ! i-mle streamfunction
-            CALL iom_put( "psiv_mle", zpsiv_mle )    ! j-mle streamfunction
-            DEALLOCATE( zLf_NH, zpsiu_mle, zpsiv_mle )
-         ENDIF
+         CALL iom_put( "psiu_mle", zpsi_uw )    ! i-mle streamfunction
+         CALL iom_put( "psiv_mle", zpsi_vw )    ! j-mle streamfunction
       ENDIF
       !
@@ -375,4 +366,8 @@
          r1_ft(:,:) = 1._wp / SQRT(  ff_t(:,:) * ff_t(:,:) + z1_t2  )
          !
+         ! Specifically, dbdx_mle, dbdy_mle and mld_prof need to be defined for nn_hls = 2
+         IF( nn_hls == 2 .AND. ln_osm_mle .AND. ln_zdfosm ) THEN
+            CALL ctl_stop('nn_hls = 2 cannot be used with ln_mle = ln_osm_mle = ln_zdfosm = T (zdfosm not updated for nn_hls = 2)')
+         ENDIF
       ENDIF
       !
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/tranpc.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/tranpc.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/tranpc.F90	(revision 14852)
@@ -17,6 +17,4 @@
    USE oce            ! ocean dynamics and active tracers
    USE dom_oce        ! ocean space and time domain
-   ! TEMP: [tiling] This change not necessary after extra haloes development (lbc_lnk removed)
-   USE domtile
    USE phycst         ! physical constants
    USE zdf_oce        ! ocean vertical physics
@@ -81,5 +79,4 @@
       LOGICAL, PARAMETER :: l_LB_debug = .FALSE. ! set to true if you want to follow what is
       INTEGER :: ilc1, jlc1, klc1, nncpu         ! actually happening in a water column at point "ilc1, jlc1"
-      INTEGER :: isi, isj, iei, iej
       LOGICAL :: lp_monitor_point = .FALSE.      ! in CPU domain "nncpu"
       !!----------------------------------------------------------------------
@@ -105,12 +102,7 @@
          CALL bn2    ( pts(:,:,:,:,Kaa), zab, zn2, Kmm )    ! after Brunt-Vaisala  (given on W-points)
          !
-         IF( ntile == 0 .OR. ntile == 1 ) nnpcc = 0         ! Do only on the first tile
-         !
-         IF( ntsi == Nis0 ) THEN ; isi = nn_hls ; ELSE ; isi = 0 ; ENDIF    ! Avoid double-counting when using tiling
-         IF( ntsj == Njs0 ) THEN ; isj = nn_hls ; ELSE ; isj = 0 ; ENDIF
-         IF( ntei == Nie0 ) THEN ; iei = nn_hls ; ELSE ; iei = 0 ; ENDIF
-         IF( ntej == Nje0 ) THEN ; iej = nn_hls ; ELSE ; iej = 0 ; ENDIF
-         !
-         DO_2D( isi, iei, isj, iej )                        ! interior column only
+         IF( .NOT. l_istiled .OR. ntile == 1 ) nnpcc = 0         ! Do only on the first tile
+         !
+         DO_2D_OVR( 0, 0, 0, 0 )                        ! interior column only
             !
             IF( tmask(ji,jj,2) == 1 ) THEN      ! At least 2 ocean points
@@ -319,5 +311,5 @@
          ENDIF
          !
-         IF( ntile == 0 .OR. ntile == nijtile )  THEN                ! Do only for the full domain
+         IF( .NOT. l_istiled .OR. ntile == nijtile )  THEN                ! Do only for the full domain
             IF( lwp .AND. l_LB_debug ) THEN
                WRITE(numout,*) 'Exiting tra_npc , kt = ',kt,', => numb. of statically instable water-columns: ', nnpcc
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traqsr.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traqsr.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/traqsr.F90	(revision 14852)
@@ -108,5 +108,5 @@
       !
       INTEGER  ::   ji, jj, jk               ! dummy loop indices
-      INTEGER  ::   irgb, isi, iei, isj, iej ! local integers
+      INTEGER  ::   irgb                     ! local integers
       REAL(wp) ::   zchl, zcoef, z1_2        ! local scalars
       REAL(wp) ::   zc0 , zc1 , zc2 , zc3    !    -         -
@@ -121,5 +121,5 @@
       IF( ln_timing )   CALL timing_start('tra_qsr')
       !
-      IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+      IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
          IF( kt == nit000 ) THEN
             IF(lwp) WRITE(numout,*)
@@ -137,13 +137,8 @@
       !                         !  before qsr induced heat content  !
       !                         !-----------------------------------!
-      IF( ntsi == Nis0 ) THEN ; isi = nn_hls ; ELSE ; isi = 0 ; ENDIF    ! Avoid double-counting when using tiling
-      IF( ntsj == Njs0 ) THEN ; isj = nn_hls ; ELSE ; isj = 0 ; ENDIF
-      IF( ntei == Nie0 ) THEN ; iei = nn_hls ; ELSE ; iei = 0 ; ENDIF
-      IF( ntej == Nje0 ) THEN ; iej = nn_hls ; ELSE ; iej = 0 ; ENDIF
-
       IF( kt == nit000 ) THEN          !==  1st time step  ==!
          IF( ln_rstart .AND. .NOT.l_1st_euler ) THEN    ! read in restart
             z1_2 = 0.5_wp
-            IF( ntile == 0 .OR. ntile == 1 )  THEN                        ! Do only on the first tile
+            IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                        ! Do only on the first tile
                IF(lwp) WRITE(numout,*) '          nit000-1 qsr tracer content forcing field read in the restart file'
                CALL iom_get( numror, jpdom_auto, 'qsr_hc_b', qsr_hc_b )   ! before heat content trend due to Qsr flux
@@ -151,5 +146,5 @@
          ELSE                                           ! No restart or Euler forward at 1st time step
             z1_2 = 1._wp
-            DO_3D( isi, iei, isj, iej, 1, jpk )
+            DO_3D_OVR( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpk )
                qsr_hc_b(ji,jj,jk) = 0._wp
             END_3D
@@ -157,5 +152,5 @@
       ELSE                             !==  Swap of qsr heat content  ==!
          z1_2 = 0.5_wp
-         DO_3D( isi, iei, isj, iej, 1, jpk )
+         DO_3D_OVR( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpk )
             qsr_hc_b(ji,jj,jk) = qsr_hc(ji,jj,jk)
          END_3D
@@ -168,5 +163,5 @@
       CASE( np_BIO )                   !==  bio-model fluxes  ==!
          !
-         DO_3D( isi, iei, isj, iej, 1, nksr )
+         DO_3D_OVR( nn_hls, nn_hls, nn_hls, nn_hls, 1, nksr )
             qsr_hc(ji,jj,jk) = r1_rho0_rcp * ( etot3(ji,jj,jk) - etot3(ji,jj,jk+1) )
          END_3D
@@ -179,8 +174,8 @@
          !
          IF( nqsr == np_RGBc ) THEN          !*  Variable Chlorophyll
-            IF( ntile == 0 .OR. ntile == 1 )  THEN                                         ! Do only for the full domain
-               IF( ln_tile ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = 0 )            ! Use full domain
+            IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                                         ! Do only for the full domain
+               IF( ln_tile ) CALL dom_tile_stop( ldhold=.TRUE. )             ! Use full domain
                CALL fld_read( kt, 1, sf_chl )         ! Read Chl data and provides it at the current time step
-               IF( ln_tile ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = 1 )            ! Revert to tile domain
+               IF( ln_tile ) CALL dom_tile_start( ldhold=.TRUE. )            ! Revert to tile domain
             ENDIF
             !
@@ -190,5 +185,5 @@
             ! most expensive calculations)
             !
-            DO_2D( isi, iei, isj, iej )
+            DO_2D_OVR( nn_hls, nn_hls, nn_hls, nn_hls )
                        ! zlogc = log(zchl)
                zlogc = LOG ( MIN( 10. , MAX( 0.03, sf_chl(1)%fnow(ji,jj,1) ) ) )
@@ -209,5 +204,5 @@
 
 !
-            DO_3D( isi, iei, isj, iej, 1, nksr + 1 )
+            DO_3D_OVR( nn_hls, nn_hls, nn_hls, nn_hls, 1, nksr + 1 )
                ! zchl    = ALOG( ze0(ji,jj) )
                zlogc = ze0(ji,jj)
@@ -239,5 +234,5 @@
          !
          zcoef  = ( 1. - rn_abs ) / 3._wp    !* surface equi-partition in R-G-B
-         DO_2D( isi, iei, isj, iej )
+         DO_2D_OVR( nn_hls, nn_hls, nn_hls, nn_hls )
             ze0(ji,jj) = rn_abs * qsr(ji,jj)
             ze1(ji,jj) = zcoef  * qsr(ji,jj)
@@ -250,5 +245,5 @@
          !
          !                                    !* interior equi-partition in R-G-B depending on vertical profile of Chl
-         DO_3D( isi, iei, isj, iej, 2, nksr + 1 )
+         DO_3D_OVR( nn_hls, nn_hls, nn_hls, nn_hls, 2, nksr + 1 )
             ze3t = e3t(ji,jj,jk-1,Kmm)
             irgb = NINT( ztmp3d(ji,jj,jk) )
@@ -264,5 +259,5 @@
          END_3D
          !
-         DO_3D( isi, iei, isj, iej, 1, nksr )          !* now qsr induced heat content
+         DO_3D_OVR( nn_hls, nn_hls, nn_hls, nn_hls, 1, nksr )          !* now qsr induced heat content
             qsr_hc(ji,jj,jk) = r1_rho0_rcp * ( ztmp3d(ji,jj,jk) - ztmp3d(ji,jj,jk+1) )
          END_3D
@@ -274,5 +269,5 @@
          zz0 =        rn_abs   * r1_rho0_rcp      ! surface equi-partition in 2-bands
          zz1 = ( 1. - rn_abs ) * r1_rho0_rcp
-         DO_3D( isi, iei, isj, iej, 1, nksr )          !* now qsr induced heat content
+         DO_3D_OVR( nn_hls, nn_hls, nn_hls, nn_hls, 1, nksr )          !* now qsr induced heat content
             zc0 = zz0 * EXP( -gdepw(ji,jj,jk  ,Kmm)*xsi0r ) + zz1 * EXP( -gdepw(ji,jj,jk  ,Kmm)*xsi1r )
             zc1 = zz0 * EXP( -gdepw(ji,jj,jk+1,Kmm)*xsi0r ) + zz1 * EXP( -gdepw(ji,jj,jk+1,Kmm)*xsi1r )
@@ -292,5 +287,5 @@
       !
       ! sea-ice: store the 1st ocean level attenuation coefficient
-      DO_2D( isi, iei, isj, iej )
+      DO_2D_OVR( nn_hls, nn_hls, nn_hls, nn_hls )
          IF( qsr(ji,jj) /= 0._wp ) THEN   ;   fraqsr_1lev(ji,jj) = qsr_hc(ji,jj,1) / ( r1_rho0_rcp * qsr(ji,jj) )
          ELSE                             ;   fraqsr_1lev(ji,jj) = 1._wp
@@ -298,18 +293,15 @@
       END_2D
       !
-      ! TEMP: [tiling] This change not necessary and working array can use A2D(nn_hls) if using XIOS (subdomain support)
-      IF( ntile == 0 .OR. ntile == nijtile )  THEN                ! Do only for the full domain
-         IF( iom_use('qsr3d') ) THEN      ! output the shortwave Radiation distribution
-            ALLOCATE( zetot(jpi,jpj,jpk) )
-            zetot(:,:,nksr+1:jpk) = 0._wp     ! below ~400m set to zero
-            DO jk = nksr, 1, -1
-               zetot(:,:,jk) = zetot(:,:,jk+1) + qsr_hc(:,:,jk) * rho0_rcp
-            END DO
-            CALL iom_put( 'qsr3d', zetot )   ! 3D distribution of shortwave Radiation
-            DEALLOCATE( zetot )
-         ENDIF
-      ENDIF
-      !
-      IF( ntile == 0 .OR. ntile == nijtile )  THEN                ! Do only on the last tile
+      IF( iom_use('qsr3d') ) THEN      ! output the shortwave Radiation distribution
+         ALLOCATE( zetot(A2D(nn_hls),jpk) )
+         zetot(:,:,nksr+1:jpk) = 0._wp     ! below ~400m set to zero
+         DO_3DS(0, 0, 0, 0, nksr, 1, -1)
+            zetot(ji,jj,jk) = zetot(ji,jj,jk+1) + qsr_hc(ji,jj,jk) * rho0_rcp
+         END_3D
+         CALL iom_put( 'qsr3d', zetot )   ! 3D distribution of shortwave Radiation
+         DEALLOCATE( zetot )
+      ENDIF
+      !
+      IF( .NOT. l_istiled .OR. ntile == nijtile )  THEN                ! Do only on the last tile
          IF( lrst_oce ) THEN     ! write in the ocean restart file
             CALL iom_rstput( kt, nitrst, numrow, 'qsr_hc_b'   , qsr_hc      )
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/trasbc.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/trasbc.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/trasbc.F90	(revision 14852)
@@ -77,5 +77,5 @@
       !
       INTEGER  ::   ji, jj, jk, jn               ! dummy loop indices
-      INTEGER  ::   ikt, ikb, isi, iei, isj, iej ! local integers
+      INTEGER  ::   ikt, ikb                     ! local integers
       REAL(wp) ::   zfact, z1_e3t, zdep, ztim    ! local scalar
       REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) ::  ztrdt, ztrds
@@ -84,5 +84,5 @@
       IF( ln_timing )   CALL timing_start('tra_sbc')
       !
-      IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+      IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
          IF( kt == nit000 ) THEN
             IF(lwp) WRITE(numout,*)
@@ -98,12 +98,7 @@
       ENDIF
       !
-      IF( ntsi == Nis0 ) THEN ; isi = nn_hls ; ELSE ; isi = 0 ; ENDIF    ! Avoid double-counting when using tiling
-      IF( ntsj == Njs0 ) THEN ; isj = nn_hls ; ELSE ; isj = 0 ; ENDIF
-      IF( ntei == Nie0 ) THEN ; iei = nn_hls ; ELSE ; iei = 0 ; ENDIF
-      IF( ntej == Nje0 ) THEN ; iej = nn_hls ; ELSE ; iej = 0 ; ENDIF
-
 !!gm  This should be moved into sbcmod.F90 module ? (especially now that ln_traqsr is read in namsbc namelist)
       IF( .NOT.ln_traqsr ) THEN     ! no solar radiation penetration
-         DO_2D( isi, iei, isj, iej )
+         DO_2D_OVR( nn_hls, nn_hls, nn_hls, nn_hls )
             qns(ji,jj) = qns(ji,jj) + qsr(ji,jj)      ! total heat flux in qns
             qsr(ji,jj) = 0._wp                        ! qsr set to zero
@@ -118,5 +113,5 @@
          IF( ln_rstart .AND. .NOT.l_1st_euler ) THEN      ! Restart: read in restart file
             zfact = 0.5_wp
-            IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+            IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
                IF(lwp) WRITE(numout,*) '          nit000-1 sbc tracer content field read in the restart file'
                sbc_tsc(:,:,:) = 0._wp
@@ -126,5 +121,5 @@
          ELSE                                             ! No restart or restart not found: Euler forward time stepping
             zfact = 1._wp
-            DO_2D( isi, iei, isj, iej )
+            DO_2D_OVR( nn_hls, nn_hls, nn_hls, nn_hls )
                sbc_tsc(ji,jj,:) = 0._wp
                sbc_tsc_b(ji,jj,:) = 0._wp
@@ -133,22 +128,20 @@
       ELSE                                !* other time-steps: swap of forcing fields
          zfact = 0.5_wp
-         DO_2D( isi, iei, isj, iej )
+         DO_2D_OVR( nn_hls, nn_hls, nn_hls, nn_hls )
             sbc_tsc_b(ji,jj,:) = sbc_tsc(ji,jj,:)
          END_2D
       ENDIF
       !                             !==  Now sbc tracer content fields  ==!
-      DO_2D( isi, iei, isj, iej )
+      DO_2D_OVR( nn_hls, nn_hls, nn_hls, nn_hls )
          sbc_tsc(ji,jj,jp_tem) = r1_rho0_rcp * qns(ji,jj)   ! non solar heat flux
          sbc_tsc(ji,jj,jp_sal) = r1_rho0     * sfx(ji,jj)   ! salt flux due to freezing/melting
       END_2D
       IF( ln_linssh ) THEN                !* linear free surface
-         DO_2D( isi, iei, isj, iej )                    !==>> add concentration/dilution effect due to constant volume cell
+         DO_2D_OVR( nn_hls, nn_hls, nn_hls, nn_hls )                    !==>> add concentration/dilution effect due to constant volume cell
             sbc_tsc(ji,jj,jp_tem) = sbc_tsc(ji,jj,jp_tem) + r1_rho0 * emp(ji,jj) * pts(ji,jj,1,jp_tem,Kmm)
             sbc_tsc(ji,jj,jp_sal) = sbc_tsc(ji,jj,jp_sal) + r1_rho0 * emp(ji,jj) * pts(ji,jj,1,jp_sal,Kmm)
          END_2D                                 !==>> output c./d. term
-         IF( ntile == 0 .OR. ntile == nijtile )  THEN             ! Do only on the last tile
-            IF( iom_use('emp_x_sst') )   CALL iom_put( "emp_x_sst", emp (:,:) * pts(:,:,1,jp_tem,Kmm) )
-            IF( iom_use('emp_x_sss') )   CALL iom_put( "emp_x_sss", emp (:,:) * pts(:,:,1,jp_sal,Kmm) )
-         ENDIF
+         IF( iom_use('emp_x_sst') )   CALL iom_put( "emp_x_sst", emp (:,:) * pts(:,:,1,jp_tem,Kmm) )
+         IF( iom_use('emp_x_sss') )   CALL iom_put( "emp_x_sss", emp (:,:) * pts(:,:,1,jp_sal,Kmm) )
       ENDIF
       !
@@ -160,5 +153,5 @@
       END DO
       !
-      IF( ntile == 0 .OR. ntile == nijtile )  THEN                ! Do only on the last tile
+      IF( .NOT. l_istiled .OR. ntile == nijtile )  THEN                ! Do only on the last tile
          IF( lrst_oce ) THEN           !==  write sbc_tsc in the ocean restart file  ==!
             CALL iom_rstput( kt, nitrst, numrow, 'sbc_hc_b', sbc_tsc(:,:,jp_tem) )
@@ -186,8 +179,6 @@
       ENDIF
 
-      IF( ntile == 0 .OR. ntile == nijtile )  THEN                ! Do only on the last tile
-         IF( iom_use('rnf_x_sst') )   CALL iom_put( "rnf_x_sst", rnf*pts(:,:,1,jp_tem,Kmm) )   ! runoff term on sst
-         IF( iom_use('rnf_x_sss') )   CALL iom_put( "rnf_x_sss", rnf*pts(:,:,1,jp_sal,Kmm) )   ! runoff term on sss
-      ENDIF
+      IF( iom_use('rnf_x_sst') )   CALL iom_put( "rnf_x_sst", rnf*pts(:,:,1,jp_tem,Kmm) )   ! runoff term on sst
+      IF( iom_use('rnf_x_sss') )   CALL iom_put( "rnf_x_sss", rnf*pts(:,:,1,jp_sal,Kmm) )   ! runoff term on sss
 
 #if defined key_asminc
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/trazdf.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/trazdf.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/trazdf.F90	(revision 14852)
@@ -64,5 +64,5 @@
       !
       IF( kt == nit000 )  THEN
-         IF( ntile == 0 .OR. ntile == 1 )  THEN                   ! Do only on the first tile
+         IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                   ! Do only on the first tile
             IF(lwp)WRITE(numout,*)
             IF(lwp)WRITE(numout,*) 'tra_zdf : implicit vertical mixing on T & S'
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/zpshde.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/zpshde.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRA/zpshde.F90	(revision 14852)
@@ -47,7 +47,7 @@
       INTEGER                     , INTENT(in   )           ::  Kmm         ! ocean time level index
       INTEGER                     , INTENT(in   )           ::  kjpt        ! number of tracers
-      REAL(wp), DIMENSION(:,:,:,:), INTENT(inout)           ::  pta         ! 4D tracers fields
+      REAL(wp), DIMENSION(:,:,:,:), INTENT(in   )           ::  pta         ! 4D tracers fields
       REAL(wp), DIMENSION(:,:,:)  , INTENT(  out)           ::  pgtu, pgtv  ! hor. grad. of ptra at u- & v-pts
-      REAL(wp), DIMENSION(:,:,:)  , INTENT(inout), OPTIONAL ::  prd         ! 3D density anomaly fields
+      REAL(wp), DIMENSION(:,:,:)  , INTENT(in   ), OPTIONAL ::  prd         ! 3D density anomaly fields
       REAL(wp), DIMENSION(:,:)    , INTENT(  out), OPTIONAL ::  pgru, pgrv  ! hor. grad of prd at u- & v-pts (bottom)
       !
@@ -111,7 +111,7 @@
       INTEGER                                , INTENT(in   )           ::  kjpt        ! number of tracers
       INTEGER                                , INTENT(in   )           ::  ktta, ktgt, ktrd, ktgr
-      REAL(wp), DIMENSION(A2D_T(ktta),JPK,KJPT), INTENT(inout)           ::  pta         ! 4D tracers fields
+      REAL(wp), DIMENSION(A2D_T(ktta),JPK,KJPT), INTENT(in   )           ::  pta         ! 4D tracers fields
       REAL(wp), DIMENSION(A2D_T(ktgt)    ,KJPT), INTENT(  out)           ::  pgtu, pgtv  ! hor. grad. of ptra at u- & v-pts
-      REAL(wp), DIMENSION(A2D_T(ktrd),JPK     ), INTENT(inout), OPTIONAL ::  prd         ! 3D density anomaly fields
+      REAL(wp), DIMENSION(A2D_T(ktrd),JPK     ), INTENT(in   ), OPTIONAL ::  prd         ! 3D density anomaly fields
       REAL(wp), DIMENSION(A2D_T(ktgr)         ), INTENT(  out), OPTIONAL ::  pgru, pgrv  ! hor. grad of prd at u- & v-pts (bottom)
       !
@@ -124,8 +124,4 @@
       !
       IF( ln_timing )   CALL timing_start( 'zps_hde')
-      IF (nn_hls.EQ.2) THEN
-         CALL lbc_lnk( 'zpshde', pta, 'T', 1.0_wp)
-         IF(PRESENT(prd)) CALL lbc_lnk( 'zpshde', prd, 'T', 1.0_wp)
-      END IF
       !
       pgtu(:,:,:) = 0._wp   ;   zti (:,:,:) = 0._wp   ;   zhi (:,:) = 0._wp
@@ -134,5 +130,5 @@
       DO jn = 1, kjpt      !==   Interpolation of tracers at the last ocean level   ==!
          !
-         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )              ! Gradient of density at the last level
+         DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )              ! Gradient of density at the last level
             iku = mbku(ji,jj)   ;   ikum1 = MAX( iku - 1 , 1 )    ! last and before last ocean level at u- & v-points
             ikv = mbkv(ji,jj)   ;   ikvm1 = MAX( ikv - 1 , 1 )    ! if level first is a p-step, ik.m1=1
@@ -173,5 +169,5 @@
       END DO
       !
-      IF (nn_hls.EQ.1) CALL lbc_lnk( 'zpshde', pgtu(:,:,:), 'U', -1.0_wp , pgtv(:,:,:), 'V', -1.0_wp )   ! Lateral boundary cond.
+      IF (nn_hls==1) CALL lbc_lnk( 'zpshde', pgtu(:,:,:), 'U', -1.0_wp , pgtv(:,:,:), 'V', -1.0_wp )   ! Lateral boundary cond.
       !
       IF( PRESENT( prd ) ) THEN    !==  horizontal derivative of density anomalies (rd)  ==!    (optional part)
@@ -206,5 +202,5 @@
             ENDIF
          END_2D
-         IF (nn_hls.EQ.1) CALL lbc_lnk( 'zpshde', pgru , 'U', -1.0_wp , pgrv , 'V', -1.0_wp )   ! Lateral boundary conditions
+         IF (nn_hls==1) CALL lbc_lnk( 'zpshde', pgru , 'U', -1.0_wp , pgrv , 'V', -1.0_wp )   ! Lateral boundary conditions
          !
       END IF
@@ -221,8 +217,8 @@
       INTEGER                     , INTENT(in   )           ::  Kmm          ! ocean time level index
       INTEGER                     , INTENT(in   )           ::  kjpt         ! number of tracers
-      REAL(wp), DIMENSION(:,:,:,:), INTENT(inout)           ::  pta          ! 4D tracers fields
+      REAL(wp), DIMENSION(:,:,:,:), INTENT(in   )           ::  pta          ! 4D tracers fields
       REAL(wp), DIMENSION(:,:,:)  , INTENT(  out)           ::  pgtu, pgtv   ! hor. grad. of ptra at u- & v-pts
       REAL(wp), DIMENSION(:,:,:)  , INTENT(  out)           ::  pgtui, pgtvi ! hor. grad. of stra at u- & v-pts (ISF)
-      REAL(wp), DIMENSION(:,:,:)  , INTENT(inout), OPTIONAL ::  prd          ! 3D density anomaly fields
+      REAL(wp), DIMENSION(:,:,:)  , INTENT(in   ), OPTIONAL ::  prd          ! 3D density anomaly fields
       REAL(wp), DIMENSION(:,:)    , INTENT(  out), OPTIONAL ::  pgru, pgrv   ! hor. grad of prd at u- & v-pts (bottom)
       REAL(wp), DIMENSION(:,:)    , INTENT(  out), OPTIONAL ::  pgrui, pgrvi ! hor. grad of prd at u- & v-pts (top)
@@ -291,8 +287,8 @@
       INTEGER                                , INTENT(in   )           ::  kjpt         ! number of tracers
       INTEGER                                , INTENT(in   )           ::  ktta, ktgt, ktgti, ktrd, ktgr, ktgri
-      REAL(wp), DIMENSION(A2D_T(ktta),JPK,KJPT), INTENT(inout)           ::  pta          ! 4D tracers fields
+      REAL(wp), DIMENSION(A2D_T(ktta),JPK,KJPT), INTENT(in   )           ::  pta          ! 4D tracers fields
       REAL(wp), DIMENSION(A2D_T(ktgt)    ,KJPT), INTENT(  out)           ::  pgtu, pgtv   ! hor. grad. of ptra at u- & v-pts
       REAL(wp), DIMENSION(A2D_T(ktgti)   ,KJPT), INTENT(  out)           ::  pgtui, pgtvi ! hor. grad. of stra at u- & v-pts (ISF)
-      REAL(wp), DIMENSION(A2D_T(ktrd),JPK     ), INTENT(inout), OPTIONAL ::  prd          ! 3D density anomaly fields
+      REAL(wp), DIMENSION(A2D_T(ktrd),JPK     ), INTENT(in   ), OPTIONAL ::  prd          ! 3D density anomaly fields
       REAL(wp), DIMENSION(A2D_T(ktgr)         ), INTENT(  out), OPTIONAL ::  pgru, pgrv   ! hor. grad of prd at u- & v-pts (bottom)
       REAL(wp), DIMENSION(A2D_T(ktgri)        ), INTENT(  out), OPTIONAL ::  pgrui, pgrvi ! hor. grad of prd at u- & v-pts (top)
@@ -307,9 +303,4 @@
       IF( ln_timing )   CALL timing_start( 'zps_hde_isf')
       !
-      IF (nn_hls.EQ.2) THEN
-         CALL lbc_lnk( 'zpshde', pta, 'T', 1.0_wp)
-         IF (PRESENT(prd)) CALL lbc_lnk( 'zpshde', prd, 'T', 1.0_wp)
-      END IF
-
       pgtu (:,:,:) = 0._wp   ;   pgtv (:,:,:) =0._wp
       pgtui(:,:,:) = 0._wp   ;   pgtvi(:,:,:) =0._wp
@@ -319,5 +310,5 @@
       DO jn = 1, kjpt      !==   Interpolation of tracers at the last ocean level   ==!
          !
-         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
+         DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )
 
             iku = mbku(ji,jj); ikum1 = MAX( iku - 1 , 1 )    ! last and before last ocean level at u- & v-points
@@ -359,5 +350,5 @@
       END DO
       !
-      IF (nn_hls.EQ.1) CALL lbc_lnk( 'zpshde', pgtu(:,:,:), 'U', -1.0_wp , pgtv(:,:,:), 'V', -1.0_wp )   ! Lateral boundary cond.
+      IF (nn_hls==1) CALL lbc_lnk( 'zpshde', pgtu(:,:,:), 'U', -1.0_wp , pgtv(:,:,:), 'V', -1.0_wp )   ! Lateral boundary cond.
 
       ! horizontal derivative of density anomalies (rd)
@@ -401,5 +392,5 @@
          END_2D
 
-         IF (nn_hls.EQ.1) CALL lbc_lnk( 'zpshde', pgru , 'U', -1.0_wp , pgrv , 'V', -1.0_wp )   ! Lateral boundary conditions
+         IF (nn_hls==1) CALL lbc_lnk( 'zpshde', pgru , 'U', -1.0_wp , pgrv , 'V', -1.0_wp )   ! Lateral boundary conditions
          !
       END IF
@@ -408,5 +399,5 @@
       !
       DO jn = 1, kjpt      !==   Interpolation of tracers at the last ocean level   ==!            !
-         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
+         DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )
             iku = miku(ji,jj); ikup1 = miku(ji,jj) + 1
             ikv = mikv(ji,jj); ikvp1 = mikv(ji,jj) + 1
@@ -452,5 +443,5 @@
          !
       END DO
-      IF (nn_hls.EQ.1) CALL lbc_lnk( 'zpshde', pgtui(:,:,:), 'U', -1.0_wp , pgtvi(:,:,:), 'V', -1.0_wp )   ! Lateral boundary cond.
+      IF (nn_hls==1) CALL lbc_lnk( 'zpshde', pgtui(:,:,:), 'U', -1.0_wp , pgtvi(:,:,:), 'V', -1.0_wp )   ! Lateral boundary cond.
 
       IF( PRESENT( prd ) ) THEN    !==  horizontal derivative of density anomalies (rd)  ==!    (optional part)
@@ -491,5 +482,5 @@
 
          END_2D
-         IF (nn_hls.EQ.1) CALL lbc_lnk( 'zpshde', pgrui, 'U', -1.0_wp , pgrvi, 'V', -1.0_wp )   ! Lateral boundary conditions
+         IF (nn_hls==1) CALL lbc_lnk( 'zpshde', pgrui, 'U', -1.0_wp , pgrvi, 'V', -1.0_wp )   ! Lateral boundary conditions
          !
       END IF
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRD/trdini.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRD/trdini.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/TRD/trdini.F90	(revision 14852)
@@ -93,5 +93,5 @@
          CALL ctl_warn('Tiling is not yet implemented for the trends diagnostics; ln_tile is forced to FALSE')
          ln_tile = .FALSE.
-         CALL dom_tile( ntsi, ntsj, ntei, ntej )
+         CALL dom_tile_init
       ENDIF
 
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/USR/usrdef_istate.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/USR/usrdef_istate.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/USR/usrdef_istate.F90	(revision 14852)
@@ -61,5 +61,5 @@
       pv  (:,:,:) = 0._wp
       !
-      DO_3D( 1, 1, 1, 1, 1, jpk )   ! horizontally uniform T & S profiles
+      DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpk )   ! horizontally uniform T & S profiles
          pts(ji,jj,jk,jp_tem) =  (  (  16. - 12. * TANH( (pdept(ji,jj,jk) - 400) / 700 ) )   &
               &           * (-TANH( (500. - pdept(ji,jj,jk)) / 150. ) + 1.) / 2.             &
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfddm.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfddm.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfddm.F90	(revision 14852)
@@ -83,5 +83,5 @@
       REAL(dp) ::          zavfs    !   -      -
       REAL(wp) ::   zavdt, zavds    !   -      -
-      REAL(wp), DIMENSION(jpi,jpj) ::   zrau, zmsks, zmskf, zmskd1, zmskd2, zmskd3
+      REAL(wp), DIMENSION(A2D(nn_hls)) ::   zrau, zmsks, zmskf, zmskd1, zmskd2, zmskd3
       !!----------------------------------------------------------------------
       !
@@ -95,5 +95,5 @@
 !!gm                            and many acces in memory
          
-         DO_2D( 1, 1, 1, 1 )           !==  R=zrau = (alpha / beta) (dk[t] / dk[s])  ==!
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )           !==  R=zrau = (alpha / beta) (dk[t] / dk[s])  ==!
             zrw =   ( gdepw(ji,jj,jk  ,Kmm) - gdept(ji,jj,jk,Kmm) )   &
 !!gm please, use e3w at Kmm below 
@@ -111,5 +111,5 @@
          END_2D
 
-         DO_2D( 1, 1, 1, 1 )           !==  indicators  ==!
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )           !==  indicators  ==!
             ! stability indicator: msks=1 if rn2>0; 0 elsewhere
             IF( rn2(ji,jj,jk) + 1.e-12  <= 0. ) THEN   ;   zmsks(ji,jj) = 0._wp
@@ -135,5 +135,5 @@
          END_2D
          ! mask zmsk in order to have avt and avs masked
-         zmsks(:,:) = zmsks(:,:) * wmask(:,:,jk)
+         zmsks(:,:) = zmsks(:,:) * wmask(A2D(nn_hls),jk)
 
 
@@ -141,5 +141,5 @@
          ! ------------------
          ! Constant eddy coefficient: reset to the background value
-         DO_2D( 1, 1, 1, 1 )
+         DO_2D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
             zinr = 1._wp / zrau(ji,jj)
             ! salt fingering
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfdrg.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfdrg.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfdrg.F90	(revision 14852)
@@ -117,5 +117,5 @@
       !
       IF( l_log_not_linssh ) THEN     !==  "log layer"  ==!   compute Cd and -Cd*|U|
-         DO_2D( 0, 0, 0, 0 )
+         DO_2D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
             imk = k_mk(ji,jj)          ! ocean bottom level at t-points
             zut = uu(ji,jj,imk,Kmm) + uu(ji-1,jj,imk,Kmm)     ! 2 x velocity at t-point
@@ -129,5 +129,5 @@
          END_2D
       ELSE                                            !==  standard Cd  ==!
-         DO_2D( 0, 0, 0, 0 )
+         DO_2D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
             imk = k_mk(ji,jj)    ! ocean bottom level at t-points
             zut = uu(ji,jj,imk,Kmm) + uu(ji-1,jj,imk,Kmm)     ! 2 x velocity at t-point
@@ -432,5 +432,5 @@
             l_log_not_linssh = .FALSE.    !- don't update Cd at each time step
             !
-            DO_2D( 1, 1, 1, 1 )              ! pCd0 = mask (and boosted) logarithmic drag coef.
+            DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )              ! pCd0 = mask (and boosted) logarithmic drag coef.
                zzz =  0.5_wp * e3t_0(ji,jj,k_mk(ji,jj))
                zcd = (  vkarmn / LOG( zzz / rn_z0 )  )**2
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfevd.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfevd.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfevd.F90	(revision 14852)
@@ -62,16 +62,24 @@
       !
       INTEGER ::   ji, jj, jk   ! dummy loop indices
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zavt_evd, zavm_evd
+      ! NOTE: [tiling] use a SAVE array to store diagnostics, then send after all tiles are finished. This is necessary because p_avt/p_avm are modified on adjacent tiles when using nn_hls > 1. zavt_evd/zavm_evd are then zero on some points when subsequently calculated for these tiles.
+      REAL(wp), SAVE, ALLOCATABLE, DIMENSION(:,:,:) ::   zavt_evd, zavm_evd
       !!----------------------------------------------------------------------
       !
-      IF( kt == nit000 ) THEN
-         IF(lwp) WRITE(numout,*)
-         IF(lwp) WRITE(numout,*) 'zdf_evd : Enhanced Vertical Diffusion (evd)'
-         IF(lwp) WRITE(numout,*) '~~~~~~~ '
-         IF(lwp) WRITE(numout,*)
+      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,*) 'zdf_evd : Enhanced Vertical Diffusion (evd)'
+            IF(lwp) WRITE(numout,*) '~~~~~~~ '
+            IF(lwp) WRITE(numout,*)
+         ENDIF
+
+         ALLOCATE( zavt_evd(jpi,jpj,jpk) )
+         IF( nn_evdm == 1 ) ALLOCATE( zavm_evd(jpi,jpj,jpk) )
       ENDIF
       !
       !
-      zavt_evd(:,:,:) = p_avt(:,:,:)         ! set avt prior to evd application
+      DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpk )
+         zavt_evd(ji,jj,jk) = p_avt(ji,jj,jk)         ! set avt prior to evd application
+      END_3D
       !
       SELECT CASE ( nn_evdm )
@@ -79,5 +87,7 @@
       CASE ( 1 )           !==  enhance tracer & momentum Kz  ==!   (if rn2<-1.e-12)
          !
-         zavm_evd(:,:,:) = p_avm(:,:,:)      ! set avm prior to evd application
+         DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpk )
+            zavm_evd(ji,jj,jk) = p_avm(ji,jj,jk)      ! set avm prior to evd application
+         END_3D
          !
 !! change last digits results
@@ -87,5 +97,5 @@
 !         END WHERE
          !
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+         DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpkm1 )
             IF(  MIN( rn2(ji,jj,jk), rn2b(ji,jj,jk) ) <= -1.e-12 ) THEN
                p_avt(ji,jj,jk) = rn_evd * wmask(ji,jj,jk)
@@ -94,6 +104,11 @@
          END_3D
          !
-         zavm_evd(:,:,:) = p_avm(:,:,:) - zavm_evd(:,:,:)   ! change in avm due to evd
-         CALL iom_put( "avm_evd", zavm_evd )                ! output this change
+         DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpk )
+            zavm_evd(ji,jj,jk) = p_avm(ji,jj,jk) - zavm_evd(ji,jj,jk)   ! change in avm due to evd
+         END_3D
+         IF( .NOT. l_istiled .OR. ntile == nijtile ) THEN                       ! Do only on the last tile
+            CALL iom_put( "avm_evd", zavm_evd )                ! output this change
+            DEALLOCATE( zavm_evd )
+         ENDIF
          !
       CASE DEFAULT         !==  enhance tracer Kz  ==!   (if rn2<-1.e-12) 
@@ -103,5 +118,5 @@
 !         END WHERE
 
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+         DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpkm1 )
             IF(  MIN( rn2(ji,jj,jk), rn2b(ji,jj,jk) ) <= -1.e-12 )   &
                p_avt(ji,jj,jk) = rn_evd * wmask(ji,jj,jk)
@@ -110,6 +125,11 @@
       END SELECT 
       !
-      zavt_evd(:,:,:) = p_avt(:,:,:) - zavt_evd(:,:,:)   ! change in avt due to evd
-      CALL iom_put( "avt_evd", zavt_evd )              ! output this change
+      DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpk )
+         zavt_evd(ji,jj,jk) = p_avt(ji,jj,jk) - zavt_evd(ji,jj,jk)   ! change in avt due to evd
+      END_3D
+      IF( .NOT. l_istiled .OR. ntile == nijtile ) THEN                       ! Do only on the last tile
+         CALL iom_put( "avt_evd", zavt_evd )              ! output this change
+         DEALLOCATE( zavt_evd )
+      ENDIF
       IF( l_trdtra ) CALL trd_tra( kt, Kmm, Krhs, 'TRA', jp_tem, jptra_evd, zavt_evd )
       !
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfgls.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfgls.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfgls.F90	(revision 14852)
@@ -137,8 +137,8 @@
       USE zdf_oce , ONLY : en, avtb, avmb   ! ocean vertical physics
       !!
-      INTEGER                   , INTENT(in   ) ::   kt             ! ocean time step
-      INTEGER                   , INTENT(in   ) ::   Kbb, Kmm       ! ocean time level indices
-      REAL(wp), DIMENSION(:,:,:), INTENT(in   ) ::   p_sh2          ! shear production term
-      REAL(wp), DIMENSION(:,:,:), INTENT(inout) ::   p_avm, p_avt   !  momentum and tracer Kz (w-points)
+      INTEGER                             , INTENT(in   ) ::   kt             ! ocean time step
+      INTEGER                             , INTENT(in   ) ::   Kbb, Kmm       ! ocean time level indices
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(in   ) ::   p_sh2          ! shear production term
+      REAL(wp), DIMENSION(:,:,:)          , INTENT(inout) ::   p_avm, p_avt   !  momentum and tracer Kz (w-points)
       !
       INTEGER  ::   ji, jj, jk    ! dummy loop arguments
@@ -151,33 +151,35 @@
       REAL(wp) ::   gh, gm, shr, dif, zsqen, zavt, zavm !   -      -
       REAL(wp) ::   zmsku, zmskv                        !   -      -
-      REAL(wp), DIMENSION(jpi,jpj)     ::   zdep
-      REAL(wp), DIMENSION(jpi,jpj)     ::   zkar
-      REAL(wp), DIMENSION(jpi,jpj)     ::   zflxs       ! Turbulence fluxed induced by internal waves
-      REAL(wp), DIMENSION(jpi,jpj)     ::   zhsro       ! Surface roughness (surface waves)
-      REAL(wp), DIMENSION(jpi,jpj)     ::   zice_fra    ! Tapering of wave breaking under sea ice
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   eb          ! tke at time before
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   hmxl_b      ! mixing length at time before
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   eps         ! dissipation rate
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zwall_psi   ! Wall function use in the wb case (ln_sigpsi)
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   psi         ! psi at time now
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zd_lw, zd_up, zdiag   ! lower, upper  and diagonal of the matrix
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zstt, zstm  ! stability function on tracer and momentum
+      REAL(wp), DIMENSION(A2D(nn_hls))     ::   zdep
+      REAL(wp), DIMENSION(A2D(nn_hls))     ::   zkar
+      REAL(wp), DIMENSION(A2D(nn_hls))     ::   zflxs                 ! Turbulence fluxed induced by internal waves
+      REAL(wp), DIMENSION(A2D(nn_hls))     ::   zhsro                 ! Surface roughness (surface waves)
+      REAL(wp), DIMENSION(A2D(nn_hls))     ::   zice_fra              ! Tapering of wave breaking under sea ice
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   eb                    ! tke at time before
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   hmxl_b                ! mixing length at time before
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   eps                   ! dissipation rate
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zwall_psi             ! Wall function use in the wb case (ln_sigpsi)
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   psi                   ! psi at time now
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zd_lw, zd_up, zdiag   ! lower, upper  and diagonal of the matrix
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zstt, zstm            ! stability function on tracer and momentum
       !!--------------------------------------------------------------------
       !
       ! Preliminary computing
-
-      ustar2_surf(:,:) = 0._wp   ;         psi(:,:,:) = 0._wp
-      ustar2_top (:,:) = 0._wp   ;   zwall_psi(:,:,:) = 0._wp
-      ustar2_bot (:,:) = 0._wp
+      DO_2D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
+         ustar2_surf(ji,jj) = 0._wp   ;   ustar2_top(ji,jj) = 0._wp   ;   ustar2_bot(ji,jj) = 0._wp
+      END_2D
+      DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpk )
+         psi(ji,jj,jk) = 0._wp   ;   zwall_psi(ji,jj,jk) = 0._wp
+      END_3D
 
       SELECT CASE ( nn_z0_ice )
       CASE( 0 )   ;   zice_fra(:,:) = 0._wp
-      CASE( 1 )   ;   zice_fra(:,:) =        TANH( fr_i(:,:) * 10._wp )
-      CASE( 2 )   ;   zice_fra(:,:) =              fr_i(:,:)
-      CASE( 3 )   ;   zice_fra(:,:) = MIN( 4._wp * fr_i(:,:) , 1._wp )
+      CASE( 1 )   ;   zice_fra(:,:) =        TANH( fr_i(A2D(nn_hls)) * 10._wp )
+      CASE( 2 )   ;   zice_fra(:,:) =              fr_i(A2D(nn_hls))
+      CASE( 3 )   ;   zice_fra(:,:) = MIN( 4._wp * fr_i(A2D(nn_hls)) , 1._wp )
       END SELECT
 
       ! Compute surface, top and bottom friction at T-points
-      DO_2D( 0, 0, 0, 0 )          !==  surface ocean friction
+      DO_2D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )          !==  surface ocean friction
          ustar2_surf(ji,jj) = r1_rho0 * taum(ji,jj) * tmask(ji,jj,1)   ! surface friction
       END_2D
@@ -186,5 +188,5 @@
       !
       IF( .NOT.ln_drg_OFF ) THEN     !== top/bottom friction   (explicit before friction)
-         DO_2D( 0, 0, 0, 0 )         ! bottom friction (explicit before friction)
+         DO_2D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )          ! bottom friction (explicit before friction)
             zmsku = 0.5_wp * ( 2._wp - umask(ji-1,jj,mbkt(ji,jj)) * umask(ji,jj,mbkt(ji,jj)) )
             zmskv = 0.5_wp * ( 2._wp - vmask(ji,jj-1,mbkt(ji,jj)) * vmask(ji,jj,mbkt(ji,jj)) )     ! (CAUTION: CdU<0)
@@ -193,5 +195,5 @@
          END_2D
          IF( ln_isfcav ) THEN
-            DO_2D( 0, 0, 0, 0 )      ! top friction
+            DO_2D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )      ! top friction
                zmsku = 0.5_wp * ( 2. - umask(ji-1,jj,mikt(ji,jj)) * umask(ji,jj,mikt(ji,jj)) )
                zmskv = 0.5_wp * ( 2. - vmask(ji,jj-1,mikt(ji,jj)) * vmask(ji,jj,mikt(ji,jj)) )     ! (CAUTION: CdU<0)
@@ -206,28 +208,35 @@
          zhsro(:,:) = rn_hsro
       CASE ( 1 )             ! Standard Charnock formula
-         zhsro(:,:) = MAX( rsbc_zs1 * ustar2_surf(:,:) , rn_hsro )
+         zhsro(:,:) = MAX( rsbc_zs1 * ustar2_surf(A2D(nn_hls)) , rn_hsro )
       CASE ( 2 )             ! Roughness formulae according to Rascle et al., Ocean Modelling (2008)
 !!gm faster coding : the 2 comment lines should be used
 !!gm         zcof = 2._wp * 0.6_wp / 28._wp
 !!gm         zdep(:,:)  = 30._wp * TANH(  zcof/ SQRT( MAX(ustar2_surf(:,:),rsmall) )  )       ! Wave age (eq. 10)
-         zdep (:,:) = 30.*TANH( 2.*0.3/(28.*SQRT(MAX(ustar2_surf(:,:),rsmall))) )         ! Wave age (eq. 10)
-         zhsro(:,:) = MAX(rsbc_zs2 * ustar2_surf(:,:) * zdep(:,:)**1.5, rn_hsro)          ! zhsro = rn_frac_hs * Hsw (eq. 11)
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
+            zcof = 30.*TANH( 2.*0.3/(28.*SQRT(MAX(ustar2_surf(ji,jj),rsmall))) )          ! Wave age (eq. 10)
+            zhsro(ji,jj) = MAX(rsbc_zs2 * ustar2_surf(ji,jj) * zcof**1.5, rn_hsro)        ! zhsro = rn_frac_hs * Hsw (eq. 11)
+         END_2D
       CASE ( 3 )             ! Roughness given by the wave model (coupled or read in file)
-         zhsro(:,:) = MAX(rn_frac_hs * hsw(:,:), rn_hsro)   ! (rn_frac_hs=1.6 see Eq. (5) of Rascle et al. 2008 )
+         zhsro(:,:) = MAX(rn_frac_hs * hsw(A2D(nn_hls)), rn_hsro)   ! (rn_frac_hs=1.6 see Eq. (5) of Rascle et al. 2008 )
       END SELECT
       !
       ! adapt roughness where there is sea ice
-      zhsro(:,:) = ( (1._wp-zice_fra(:,:)) * zhsro(:,:) + zice_fra(:,:) * rn_hsri )*tmask(:,:,1)  + (1._wp - tmask(:,:,1))*rn_hsro
-      !
-      DO_3D( 0, 0, 0, 0, 2, jpkm1 )  !==  Compute dissipation rate  ==!
+      DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
+         zhsro(ji,jj) = ( (1._wp-zice_fra(ji,jj)) * zhsro(ji,jj) + zice_fra(ji,jj) * rn_hsri )*tmask(ji,jj,1)  + &
+            &           (1._wp - tmask(ji,jj,1))*rn_hsro
+      END_2D
+      !
+      DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )  !==  Compute dissipation rate  ==!
          eps(ji,jj,jk)  = rc03 * en(ji,jj,jk) * SQRT( en(ji,jj,jk) ) / hmxl_n(ji,jj,jk)
       END_3D
 
       ! Save tke at before time step
-      eb    (:,:,:) = en    (:,:,:)
-      hmxl_b(:,:,:) = hmxl_n(:,:,:)
+      DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpk )
+         eb    (ji,jj,jk) = en    (ji,jj,jk)
+         hmxl_b(ji,jj,jk) = hmxl_n(ji,jj,jk)
+      END_3D
 
       IF( nn_clos == 0 ) THEN    ! Mellor-Yamada
-         DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+         DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
             zup   = hmxl_n(ji,jj,jk) * gdepw(ji,jj,mbkt(ji,jj)+1,Kmm)
             zdown = vkarmn * gdepw(ji,jj,jk,Kmm) * ( -gdepw(ji,jj,jk,Kmm) + gdepw(ji,jj,mbkt(ji,jj)+1,Kmm) )
@@ -250,5 +259,5 @@
       ! Warning : after this step, en : right hand side of the matrix
 
-      DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+      DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
          !
          buoy = - p_avt(ji,jj,jk) * rn2(ji,jj,jk)     ! stratif. destruction
@@ -303,39 +312,43 @@
       !
       CASE ( 0 )             ! Dirichlet boundary condition (set e at k=1 & 2)
-      ! First level
-      en   (:,:,1) = MAX(  rn_emin , rc02r * ustar2_surf(:,:) * (1._wp + (1._wp-zice_fra(:,:))*rsbc_tke1)**r2_3  )
-      zd_lw(:,:,1) = en(:,:,1)
-      zd_up(:,:,1) = 0._wp
-      zdiag(:,:,1) = 1._wp
-      !
-      ! One level below
-      en   (:,:,2) =  MAX(  rc02r * ustar2_surf(:,:) * (  1._wp + (1._wp-zice_fra(:,:))*rsbc_tke1 * ((zhsro(:,:)+gdepw(:,:,2,Kmm)) &
-         &                 / zhsro(:,:) )**(1.5_wp*ra_sf)  )**(2._wp/3._wp) , rn_emin   )
-      zd_lw(:,:,2) = 0._wp
-      zd_up(:,:,2) = 0._wp
-      zdiag(:,:,2) = 1._wp
-      !
-      !
+         DO_2D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
+            ! First level
+            en   (ji,jj,1) = MAX(  rn_emin , rc02r * ustar2_surf(ji,jj) * (1._wp + (1._wp-zice_fra(ji,jj))*rsbc_tke1)**r2_3  )
+            zd_lw(ji,jj,1) = en(ji,jj,1)
+            zd_up(ji,jj,1) = 0._wp
+            zdiag(ji,jj,1) = 1._wp
+            !
+            ! One level below
+            en   (ji,jj,2) =  MAX( rn_emin , rc02r * ustar2_surf(ji,jj) * (1._wp + (1._wp-zice_fra(ji,jj))*rsbc_tke1          &
+               &                             * ((zhsro(ji,jj)+gdepw(ji,jj,2,Kmm)) / zhsro(ji,jj) )**(1.5_wp*ra_sf)  )**r2_3 )
+            zd_lw(ji,jj,2) = 0._wp
+            zd_up(ji,jj,2) = 0._wp
+            zdiag(ji,jj,2) = 1._wp
+         END_2D
+         !
+         !
       CASE ( 1 )             ! Neumann boundary condition (set d(e)/dz)
-      !
-      ! Dirichlet conditions at k=1
-      en   (:,:,1) = MAX(  rc02r * ustar2_surf(:,:) * (1._wp + (1._wp-zice_fra(:,:))*rsbc_tke1)**r2_3 , rn_emin  )
-      zd_lw(:,:,1) = en(:,:,1)
-      zd_up(:,:,1) = 0._wp
-      zdiag(:,:,1) = 1._wp
-      !
-      ! at k=2, set de/dz=Fw
-      !cbr
-      DO_2D( 0, 0, 0, 0 )   ! zdiag zd_lw not defined/used on the halo
-         zdiag(ji,jj,2) = zdiag(ji,jj,2) +  zd_lw(ji,jj,2) ! Remove zd_lw from zdiag
-         zd_lw(ji,jj,2) = 0._wp
-      END_2D
-      zkar (:,:)   = (rl_sf + (vkarmn-rl_sf)*(1.-EXP(-rtrans*gdept(:,:,1,Kmm)/zhsro(:,:)) ))
-      zflxs(:,:)   = rsbc_tke2 * (1._wp-zice_fra(:,:)) * ustar2_surf(:,:)**1.5_wp * zkar(:,:) &
-          &                    * (  ( zhsro(:,:)+gdept(:,:,1,Kmm) ) / zhsro(:,:)  )**(1.5_wp*ra_sf)
+         !
+         DO_2D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
+            ! Dirichlet conditions at k=1
+            en   (ji,jj,1) = MAX(  rn_emin , rc02r * ustar2_surf(ji,jj) * (1._wp + (1._wp-zice_fra(ji,jj))*rsbc_tke1)**r2_3  )
+            zd_lw(ji,jj,1) = en(ji,jj,1)
+            zd_up(ji,jj,1) = 0._wp
+            zdiag(ji,jj,1) = 1._wp
+            !
+            ! at k=2, set de/dz=Fw
+            !cbr
+            ! zdiag zd_lw not defined/used on the halo
+            zdiag(ji,jj,2) = zdiag(ji,jj,2) +  zd_lw(ji,jj,2) ! Remove zd_lw from zdiag
+            zd_lw(ji,jj,2) = 0._wp
+            !
+            zkar (ji,jj)   = (rl_sf + (vkarmn-rl_sf)*(1.-EXP(-rtrans*gdept(ji,jj,1,Kmm)/zhsro(ji,jj)) ))
+            zflxs(ji,jj)   = rsbc_tke2 * (1._wp-zice_fra(ji,jj)) * ustar2_surf(ji,jj)**1.5_wp * zkar(ji,jj) &
+                &                    * (  ( zhsro(ji,jj)+gdept(ji,jj,1,Kmm) ) / zhsro(ji,jj)  )**(1.5_wp*ra_sf)
 !!gm why not   :                        * ( 1._wp + gdept(:,:,1,Kmm) / zhsro(:,:) )**(1.5_wp*ra_sf)
-      en(:,:,2) = en(:,:,2) + zflxs(:,:) / e3w(:,:,2,Kmm)
-      !
-      !
+            en(ji,jj,2) = en(ji,jj,2) + zflxs(ji,jj) / e3w(ji,jj,2,Kmm)
+         END_2D
+         !
+         !
       END SELECT
 
@@ -348,5 +361,5 @@
          !                      ! en(ibot) = u*^2 / Co2 and hmxl_n(ibot) = rn_lmin
          !                      ! Balance between the production and the dissipation terms
-         DO_2D( 0, 0, 0, 0 )
+         DO_2D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
 !!gm This means that bottom and ocean w-level above have a specified "en" value.   Sure ????
 !!   With thick deep ocean level thickness, this may be quite large, no ???
@@ -365,6 +378,7 @@
          END_2D
          !
+         ! NOTE: ctl_stop with ln_isfcav when using GLS
          IF( ln_isfcav) THEN     ! top boundary   (ocean cavity)
-            DO_2D( 0, 0, 0, 0 )
+            DO_2D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
                itop   = mikt(ji,jj)       ! k   top w-point
                itopp1 = mikt(ji,jj) + 1   ! k+1 1st w-point below the top one
@@ -384,5 +398,5 @@
       CASE ( 1 )             ! Neumman boundary condition
          !
-         DO_2D( 0, 0, 0, 0 )
+         DO_2D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
             ibot   = mbkt(ji,jj) + 1      ! k   bottom level of w-point
             ibotm1 = mbkt(ji,jj)          ! k-1 bottom level of w-point but >=1
@@ -398,6 +412,7 @@
             en   (ji,jj,ibot) = z_en
          END_2D
+         ! NOTE: ctl_stop with ln_isfcav when using GLS
          IF( ln_isfcav) THEN     ! top boundary   (ocean cavity)
-            DO_2D( 0, 0, 0, 0 )
+            DO_2D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
                itop   = mikt(ji,jj)       ! k   top w-point
                itopp1 = mikt(ji,jj) + 1   ! k+1 1st w-point below the top one
@@ -420,15 +435,17 @@
       ! ----------------------------------------------------------
       !
-      DO_3D( 0, 0, 0, 0, 2, jpkm1 )                ! First recurrence : Dk = Dk - Lk * Uk-1 / Dk-1
+      DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )                ! First recurrence : Dk = Dk - Lk * Uk-1 / Dk-1
          zdiag(ji,jj,jk) = zdiag(ji,jj,jk) - zd_lw(ji,jj,jk) * zd_up(ji,jj,jk-1) / zdiag(ji,jj,jk-1)
       END_3D
-      DO_3D( 0, 0, 0, 0, 2, jpkm1 )                ! Second recurrence : Lk = RHSk - Lk / Dk-1 * Lk-1
+      DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )                ! Second recurrence : Lk = RHSk - Lk / Dk-1 * Lk-1
          zd_lw(ji,jj,jk) = en(ji,jj,jk) - zd_lw(ji,jj,jk) / zdiag(ji,jj,jk-1) * zd_lw(ji,jj,jk-1)
       END_3D
-      DO_3DS( 0, 0, 0, 0, jpkm1, 2, -1 )           ! thrid recurrence : Ek = ( Lk - Uk * Ek+1 ) / Dk
+      DO_3DS_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, jpkm1, 2, -1 )           ! Third recurrence : Ek = ( Lk - Uk * Ek+1 ) / Dk
          en(ji,jj,jk) = ( zd_lw(ji,jj,jk) - zd_up(ji,jj,jk) * en(ji,jj,jk+1) ) / zdiag(ji,jj,jk)
       END_3D
       !                                            ! set the minimum value of tke
-      en(:,:,:) = MAX( en(:,:,:), rn_emin )
+      DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpk )
+         en(ji,jj,jk) = MAX( en(ji,jj,jk), rn_emin )
+      END_3D
 
       !!----------------------------------------!!
@@ -441,20 +458,20 @@
       !
       CASE( 0 )               ! k-kl  (Mellor-Yamada)
-         DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
             psi(ji,jj,jk)  = eb(ji,jj,jk) * hmxl_b(ji,jj,jk)
          END_3D
          !
       CASE( 1 )               ! k-eps
-         DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
             psi(ji,jj,jk)  = eps(ji,jj,jk)
          END_3D
          !
       CASE( 2 )               ! k-w
-         DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
             psi(ji,jj,jk)  = SQRT( eb(ji,jj,jk) ) / ( rc0 * hmxl_b(ji,jj,jk) )
          END_3D
          !
       CASE( 3 )               ! generic
-         DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
             psi(ji,jj,jk)  = rc02 * eb(ji,jj,jk) * hmxl_b(ji,jj,jk)**rnn
          END_3D
@@ -469,5 +486,5 @@
       ! Warning : after this step, en : right hand side of the matrix
 
-      DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+      DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
          !
          ! psi / k
@@ -516,43 +533,45 @@
       CASE ( 0 )             ! Dirichlet boundary conditions
          !
-         ! Surface value
-         zdep    (:,:)   = zhsro(:,:) * rl_sf ! Cosmetic
-         psi     (:,:,1) = rc0**rpp * en(:,:,1)**rmm * zdep(:,:)**rnn * tmask(:,:,1)
-         zd_lw(:,:,1) = psi(:,:,1)
-         zd_up(:,:,1) = 0._wp
-         zdiag(:,:,1) = 1._wp
-         !
-         ! One level below
-         zkar    (:,:)   = (rl_sf + (vkarmn-rl_sf)*(1._wp-EXP(-rtrans*gdepw(:,:,2,Kmm)/zhsro(:,:) )))
-         zdep    (:,:)   = (zhsro(:,:) + gdepw(:,:,2,Kmm)) * zkar(:,:)
-         psi     (:,:,2) = rc0**rpp * en(:,:,2)**rmm * zdep(:,:)**rnn * tmask(:,:,1)
-         zd_lw(:,:,2) = 0._wp
-         zd_up(:,:,2) = 0._wp
-         zdiag(:,:,2) = 1._wp
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
+            ! Surface value
+            zdep    (ji,jj)   = zhsro(ji,jj) * rl_sf ! Cosmetic
+            psi     (ji,jj,1) = rc0**rpp * en(ji,jj,1)**rmm * zdep(ji,jj)**rnn * tmask(ji,jj,1)
+            zd_lw(ji,jj,1) = psi(ji,jj,1)
+            zd_up(ji,jj,1) = 0._wp
+            zdiag(ji,jj,1) = 1._wp
+            !
+            ! One level below
+            zkar    (ji,jj)   = (rl_sf + (vkarmn-rl_sf)*(1._wp-EXP(-rtrans*gdepw(ji,jj,2,Kmm)/zhsro(ji,jj) )))
+            zdep    (ji,jj)   = (zhsro(ji,jj) + gdepw(ji,jj,2,Kmm)) * zkar(ji,jj)
+            psi     (ji,jj,2) = rc0**rpp * en(ji,jj,2)**rmm * zdep(ji,jj)**rnn * tmask(ji,jj,1)
+            zd_lw(ji,jj,2) = 0._wp
+            zd_up(ji,jj,2) = 0._wp
+            zdiag(ji,jj,2) = 1._wp
+         END_2D
          !
       CASE ( 1 )             ! Neumann boundary condition on d(psi)/dz
          !
-         ! Surface value: Dirichlet
-         zdep    (:,:)   = zhsro(:,:) * rl_sf
-         psi     (:,:,1) = rc0**rpp * en(:,:,1)**rmm * zdep(:,:)**rnn * tmask(:,:,1)
-         zd_lw(:,:,1) = psi(:,:,1)
-         zd_up(:,:,1) = 0._wp
-         zdiag(:,:,1) = 1._wp
-         !
-         ! Neumann condition at k=2
-         DO_2D( 0, 0, 0, 0 )   ! zdiag zd_lw not defined/used on the halo
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
+            ! Surface value: Dirichlet
+            zdep    (ji,jj)   = zhsro(ji,jj) * rl_sf
+            psi     (ji,jj,1) = rc0**rpp * en(ji,jj,1)**rmm * zdep(ji,jj)**rnn * tmask(ji,jj,1)
+            zd_lw(ji,jj,1) = psi(ji,jj,1)
+            zd_up(ji,jj,1) = 0._wp
+            zdiag(ji,jj,1) = 1._wp
+            !
+            ! Neumann condition at k=2, zdiag zd_lw not defined/used on the halo
             zdiag(ji,jj,2) = zdiag(ji,jj,2) +  zd_lw(ji,jj,2) ! Remove zd_lw from zdiag
             zd_lw(ji,jj,2) = 0._wp
+            !
+            ! Set psi vertical flux at the surface:
+            zkar (ji,jj)   = rl_sf + (vkarmn-rl_sf)*(1._wp-EXP(-rtrans*gdept(ji,jj,1,Kmm)/zhsro(ji,jj) )) ! Lengh scale slope
+            zdep (ji,jj)   = ((zhsro(ji,jj) + gdept(ji,jj,1,Kmm)) / zhsro(ji,jj))**(rmm*ra_sf)
+            zflxs(ji,jj)   = (rnn + (1._wp-zice_fra(ji,jj))*rsbc_tke1 * (rnn + rmm*ra_sf) * zdep(ji,jj)) &
+               &           *(1._wp + (1._wp-zice_fra(ji,jj))*rsbc_tke1*zdep(ji,jj))**(2._wp*rmm/3._wp-1_wp)
+            zdep (ji,jj)   = rsbc_psi1 * (zwall_psi(ji,jj,1)*p_avm(ji,jj,1)+zwall_psi(ji,jj,2)*p_avm(ji,jj,2)) * &
+               &           ustar2_surf(ji,jj)**rmm * zkar(ji,jj)**rnn * (zhsro(ji,jj) + gdept(ji,jj,1,Kmm))**(rnn-1.)
+            zflxs(ji,jj)   = zdep(ji,jj) * zflxs(ji,jj)
+            psi  (ji,jj,2) = psi(ji,jj,2) + zflxs(ji,jj) / e3w(ji,jj,2,Kmm)
          END_2D
-         !
-         ! Set psi vertical flux at the surface:
-         zkar (:,:)   = rl_sf + (vkarmn-rl_sf)*(1._wp-EXP(-rtrans*gdept(:,:,1,Kmm)/zhsro(:,:) )) ! Lengh scale slope
-         zdep (:,:)   = ((zhsro(:,:) + gdept(:,:,1,Kmm)) / zhsro(:,:))**(rmm*ra_sf)
-         zflxs(:,:)   = (rnn + (1._wp-zice_fra(:,:))*rsbc_tke1 * (rnn + rmm*ra_sf) * zdep(:,:)) &
-            &           *(1._wp + (1._wp-zice_fra(:,:))*rsbc_tke1*zdep(:,:))**(2._wp*rmm/3._wp-1_wp)
-         zdep (:,:)   = rsbc_psi1 * (zwall_psi(:,:,1)*p_avm(:,:,1)+zwall_psi(:,:,2)*p_avm(:,:,2)) * &
-            &           ustar2_surf(:,:)**rmm * zkar(:,:)**rnn * (zhsro(:,:) + gdept(:,:,1,Kmm))**(rnn-1.)
-         zflxs(:,:)   = zdep(:,:) * zflxs(:,:)
-         psi  (:,:,2) = psi(:,:,2) + zflxs(:,:) / e3w(:,:,2,Kmm)
          !
       END SELECT
@@ -569,5 +588,5 @@
          !                      ! en(ibot) = u*^2 / Co2 and hmxl_n(ibot) = vkarmn * r_z0_bot
          !                      ! Balance between the production and the dissipation terms
-         DO_2D( 0, 0, 0, 0 )
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
             ibot   = mbkt(ji,jj) + 1      ! k   bottom level of w-point
             ibotm1 = mbkt(ji,jj)          ! k-1 bottom level of w-point but >=1
@@ -588,5 +607,5 @@
       CASE ( 1 )             ! Neumman boundary condition
          !
-         DO_2D( 0, 0, 0, 0 )
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
             ibot   = mbkt(ji,jj) + 1      ! k   bottom level of w-point
             ibotm1 = mbkt(ji,jj)          ! k-1 bottom level of w-point but >=1
@@ -616,11 +635,11 @@
       ! ----------------
       !
-      DO_3D( 0, 0, 0, 0, 2, jpkm1 )                ! First recurrence : Dk = Dk - Lk * Uk-1 / Dk-1
+      DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )                ! First recurrence : Dk = Dk - Lk * Uk-1 / Dk-1
          zdiag(ji,jj,jk) = zdiag(ji,jj,jk) - zd_lw(ji,jj,jk) * zd_up(ji,jj,jk-1) / zdiag(ji,jj,jk-1)
       END_3D
-      DO_3D( 0, 0, 0, 0, 2, jpkm1 )                ! Second recurrence : Lk = RHSk - Lk / Dk-1 * Lk-1
+      DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )                ! Second recurrence : Lk = RHSk - Lk / Dk-1 * Lk-1
          zd_lw(ji,jj,jk) = psi(ji,jj,jk) - zd_lw(ji,jj,jk) / zdiag(ji,jj,jk-1) * zd_lw(ji,jj,jk-1)
       END_3D
-      DO_3DS( 0, 0, 0, 0, jpkm1, 2, -1 )           ! Third recurrence : Ek = ( Lk - Uk * Ek+1 ) / Dk
+      DO_3DS( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, jpkm1, 2, -1 )           ! Third recurrence : Ek = ( Lk - Uk * Ek+1 ) / Dk
          psi(ji,jj,jk) = ( zd_lw(ji,jj,jk) - zd_up(ji,jj,jk) * psi(ji,jj,jk+1) ) / zdiag(ji,jj,jk)
       END_3D
@@ -632,15 +651,15 @@
       !
       CASE( 0 )               ! k-kl  (Mellor-Yamada)
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpkm1 )
             eps(ji,jj,jk) = rc03 * en(ji,jj,jk) * en(ji,jj,jk) * SQRT( en(ji,jj,jk) ) / MAX( psi(ji,jj,jk), rn_epsmin)
          END_3D
          !
       CASE( 1 )               ! k-eps
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpkm1 )
             eps(ji,jj,jk) = psi(ji,jj,jk)
          END_3D
          !
       CASE( 2 )               ! k-w
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpkm1 )
             eps(ji,jj,jk) = rc04 * en(ji,jj,jk) * psi(ji,jj,jk)
          END_3D
@@ -650,5 +669,5 @@
          zex1  =      ( 1.5_wp + rmm/rnn )
          zex2  = -1._wp / rnn
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpkm1 )
             eps(ji,jj,jk) = zcoef * en(ji,jj,jk)**zex1 * psi(ji,jj,jk)**zex2
          END_3D
@@ -658,12 +677,15 @@
       ! Limit dissipation rate under stable stratification
       ! --------------------------------------------------
-      DO_3D( 0, 0, 0, 0, 1, jpkm1 )   ! Note that this set boundary conditions on hmxl_n at the same time
+      DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpkm1 )   ! Note that this set boundary conditions on hmxl_n at the same time
          ! limitation
          eps   (ji,jj,jk)  = MAX( eps(ji,jj,jk), rn_epsmin )
          hmxl_n(ji,jj,jk)  = rc03 * en(ji,jj,jk) * SQRT( en(ji,jj,jk) ) / eps(ji,jj,jk)
-         ! Galperin criterium (NOTE : Not required if the proper value of C3 in stable cases is calculated)
-         zrn2 = MAX( rn2(ji,jj,jk), rsmall )
-         IF( ln_length_lim )   hmxl_n(ji,jj,jk) = MIN(  rn_clim_galp * SQRT( 2._wp * en(ji,jj,jk) / zrn2 ), hmxl_n(ji,jj,jk) )
-      END_3D
+      END_3D
+      IF( ln_length_lim ) THEN        ! Galperin criterium (NOTE : Not required if the proper value of C3 in stable cases is calculated)
+         DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpkm1 )
+            zrn2 = MAX( rn2(ji,jj,jk), rsmall )
+            hmxl_n(ji,jj,jk) = MIN(  rn_clim_galp * SQRT( 2._wp * en(ji,jj,jk) / zrn2 ), hmxl_n(ji,jj,jk) )
+         END_3D
+      ENDIF
 
       !
@@ -674,5 +696,5 @@
       !
       CASE ( 0 , 1 )             ! Galperin or Kantha-Clayson stability functions
-         DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
             ! zcof =  l²/q²
             zcof = hmxl_b(ji,jj,jk) * hmxl_b(ji,jj,jk) / ( 2._wp*eb(ji,jj,jk) )
@@ -691,5 +713,5 @@
          !
       CASE ( 2, 3 )               ! Canuto stability functions
-         DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
             ! zcof =  l²/q²
             zcof = hmxl_b(ji,jj,jk)*hmxl_b(ji,jj,jk) / ( 2._wp * eb(ji,jj,jk) )
@@ -723,10 +745,10 @@
       ! default value, in case jpk > mbkt(ji,jj)+1. Not needed but avoid a bug when looking for undefined values (-fpe0)
       zstm(:,:,jpk) = 0.
-      DO_2D( 0, 0, 0, 0 )             ! update bottom with good values
+      DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )             ! update bottom with good values
          zstm(ji,jj,mbkt(ji,jj)+1) = zstm(ji,jj,mbkt(ji,jj))
       END_2D
 
-      zstt(:,:,  1) = wmask(:,:,  1)  ! default value not needed but avoid a bug when looking for undefined values (-fpe0)
-      zstt(:,:,jpk) = wmask(:,:,jpk)  ! default value not needed but avoid a bug when looking for undefined values (-fpe0)
+      zstt(:,:,  1) = wmask(A2D(nn_hls),  1)  ! default value not needed but avoid a bug when looking for undefined values (-fpe0)
+      zstt(:,:,jpk) = wmask(A2D(nn_hls),jpk)  ! default value not needed but avoid a bug when looking for undefined values (-fpe0)
 
 !!gm should be done for ISF (top boundary cond.)
@@ -738,5 +760,5 @@
       !     later overwritten by surface/bottom boundaries conditions, so we don't really care of p_avm(:,:1) and p_avm(:,:jpk)
       !     for zd_lw and zd_up but they have to be defined to avoid a bug when looking for undefined values (-fpe0)
-      DO_3D( 0, 0, 0, 0, 1, jpk )
+      DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpk )
          zsqen = SQRT( 2._wp * en(ji,jj,jk) ) * hmxl_n(ji,jj,jk)
          zavt  = zsqen * zstt(ji,jj,jk)
@@ -745,5 +767,5 @@
          p_avm(ji,jj,jk) = MAX( zavm, avmb(jk) )                   ! Note that avm is not masked at the surface and the bottom
       END_3D
-      p_avt(:,:,1) = 0._wp
+      p_avt(A2D(nn_hls),1) = 0._wp
       !
       IF(sn_cfctl%l_prtctl) THEN
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfiwm.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfiwm.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfiwm.F90	(revision 14852)
@@ -125,15 +125,16 @@
       !
       INTEGER  ::   ji, jj, jk   ! dummy loop indices
-      REAL(wp) ::   zztmp, ztmp1, ztmp2        ! scalar workspace
-      REAL(wp), DIMENSION(jpi,jpj)     ::   zfact       ! Used for vertical structure
-      REAL(wp), DIMENSION(jpi,jpj)     ::   zhdep       ! Ocean depth
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zwkb        ! WKB-stretched height above bottom
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zweight     ! Weight for high mode vertical distribution
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   znu_t       ! Molecular kinematic viscosity (T grid)
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   znu_w       ! Molecular kinematic viscosity (W grid)
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zReb        ! Turbulence intensity parameter
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zemx_iwm    ! local energy density available for mixing (W/kg)
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zav_ratio   ! S/T diffusivity ratio (only for ln_tsdiff=T)
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zav_wave    ! Internal wave-induced diffusivity
+      REAL(wp), SAVE :: zztmp
+      REAL(wp)       :: ztmp1, ztmp2        ! scalar workspace
+      REAL(wp), DIMENSION(A2D(nn_hls))     ::   zfact       ! Used for vertical structure
+      REAL(wp), DIMENSION(A2D(nn_hls))     ::   zhdep       ! Ocean depth
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zwkb        ! WKB-stretched height above bottom
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zweight     ! Weight for high mode vertical distribution
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   znu_t       ! Molecular kinematic viscosity (T grid)
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   znu_w       ! Molecular kinematic viscosity (W grid)
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zReb        ! Turbulence intensity parameter
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zemx_iwm    ! local energy density available for mixing (W/kg)
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zav_ratio   ! S/T diffusivity ratio (only for ln_tsdiff=T)
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zav_wave    ! Internal wave-induced diffusivity
       REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) ::   z3d  ! 3D workspace used for iom_put 
       REAL(wp), ALLOCATABLE, DIMENSION(:,:)   ::   z2d  ! 2D     -      -    -     -
@@ -143,15 +144,15 @@
       ! Set to zero the 1st and last vertical levels of appropriate variables
       IF( iom_use("emix_iwm") ) THEN
-         DO_2D( 0, 0, 0, 0 )
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
             zemx_iwm (ji,jj,1) = 0._wp   ;   zemx_iwm (ji,jj,jpk) = 0._wp
          END_2D
       ENDIF
       IF( iom_use("av_ratio") ) THEN
-         DO_2D( 0, 0, 0, 0 )
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
             zav_ratio(ji,jj,1) = 0._wp   ;   zav_ratio(ji,jj,jpk) = 0._wp
          END_2D
       ENDIF
       IF( iom_use("av_wave") .OR. sn_cfctl%l_prtctl ) THEN
-         DO_2D( 0, 0, 0, 0 )
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
             zav_wave (ji,jj,1) = 0._wp   ;   zav_wave (ji,jj,jpk) = 0._wp
          END_2D
@@ -164,5 +165,5 @@
       !                       !* Critical slope mixing: distribute energy over the time-varying ocean depth,
       !                                                 using an exponential decay from the seafloor.
-      DO_2D( 0, 0, 0, 0 )             ! part independent of the level
+      DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )             ! part independent of the level
          zhdep(ji,jj) = gdepw_0(ji,jj,mbkt(ji,jj)+1)       ! depth of the ocean
          zfact(ji,jj) = rho0 * (  1._wp - EXP( -zhdep(ji,jj) / hcri_iwm(ji,jj) )  )
@@ -170,5 +171,5 @@
       END_2D
 !!gm gde3w ==>>>  check for ssh taken into account.... seem OK gde3w_n=gdept(:,:,:,Kmm) - ssh(:,:,Kmm)
-      DO_3D( 0, 0, 0, 0, 2, jpkm1 )   ! complete with the level-dependent part
+      DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )   ! complete with the level-dependent part
          IF ( zfact(ji,jj) == 0._wp .OR. wmask(ji,jj,jk) == 0._wp ) THEN   ! optimization
             zemx_iwm(ji,jj,jk) = 0._wp
@@ -190,16 +191,16 @@
       CASE ( 1 )               ! Dissipation scales as N (recommended)
          !
-         DO_2D( 0, 0, 0, 0 )
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
             zfact(ji,jj) = 0._wp
          END_2D
-         DO_3D( 0, 0, 0, 0, 2, jpkm1 )       ! part independent of the level
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )       ! part independent of the level
             zfact(ji,jj) = zfact(ji,jj) + e3w(ji,jj,jk,Kmm) * SQRT(  MAX( 0._wp, rn2(ji,jj,jk) )  ) * wmask(ji,jj,jk)
          END_3D
          !
-         DO_2D( 0, 0, 0, 0 )
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
             IF( zfact(ji,jj) /= 0 )   zfact(ji,jj) = epyc_iwm(ji,jj) / ( rho0 * zfact(ji,jj) )
          END_2D
          !
-         DO_3D( 0, 0, 0, 0, 2, jpkm1 )       ! complete with the level-dependent part
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )       ! complete with the level-dependent part
             zemx_iwm(ji,jj,jk) = zemx_iwm(ji,jj,jk) + zfact(ji,jj) * SQRT(  MAX( 0._wp, rn2(ji,jj,jk) )  ) * wmask(ji,jj,jk)
          END_3D
@@ -207,16 +208,16 @@
       CASE ( 2 )               ! Dissipation scales as N^2
          !
-         DO_2D( 0, 0, 0, 0 )
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
             zfact(ji,jj) = 0._wp
          END_2D
-         DO_3D( 0, 0, 0, 0, 2, jpkm1 )       ! part independent of the level
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )       ! part independent of the level
             zfact(ji,jj) = zfact(ji,jj) + e3w(ji,jj,jk,Kmm) * MAX( 0._wp, rn2(ji,jj,jk) ) * wmask(ji,jj,jk)
          END_3D
          !
-         DO_2D( 0, 0, 0, 0 )
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
             IF( zfact(ji,jj) /= 0 )   zfact(ji,jj) = epyc_iwm(ji,jj) / ( rho0 * zfact(ji,jj) )
          END_2D
          !
-         DO_3D( 0, 0, 0, 0, 2, jpkm1 )       ! complete with the level-dependent part
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
             zemx_iwm(ji,jj,jk) = zemx_iwm(ji,jj,jk) + zfact(ji,jj) * MAX( 0._wp, rn2(ji,jj,jk) ) * wmask(ji,jj,jk)
          END_3D
@@ -227,23 +228,23 @@
       !                        !* ocean depth as proportional to rn2 * exp(-z_wkb/rn_hbot)
       !
-      DO_2D( 0, 0, 0, 0 )
+      DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
          zwkb(ji,jj,1) = 0._wp
       END_2D
-      DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+      DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
          zwkb(ji,jj,jk) = zwkb(ji,jj,jk-1) + e3w(ji,jj,jk,Kmm) * SQRT(  MAX( 0._wp, rn2(ji,jj,jk) )  ) * wmask(ji,jj,jk)
       END_3D
-      DO_2D( 0, 0, 0, 0 )
+      DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
          zfact(ji,jj) = zwkb(ji,jj,jpkm1)
       END_2D
       !
-      DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+      DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
          IF( zfact(ji,jj) /= 0 )   zwkb(ji,jj,jk) = zhdep(ji,jj) * ( zfact(ji,jj) - zwkb(ji,jj,jk) )   &
             &                                     * wmask(ji,jj,jk) / zfact(ji,jj)
       END_3D
-      DO_2D( 0, 0, 0, 0 )
+      DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
          zwkb (ji,jj,1) = zhdep(ji,jj) * wmask(ji,jj,1)
       END_2D
       !
-      DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+      DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
          IF ( rn2(ji,jj,jk) <= 0._wp .OR. wmask(ji,jj,jk) == 0._wp ) THEN   ! optimization: EXP coast a lot
             zweight(ji,jj,jk) = 0._wp
@@ -254,16 +255,16 @@
       END_3D
       !
-      DO_2D( 0, 0, 0, 0 )
+      DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
          zfact(ji,jj) = 0._wp
       END_2D
-      DO_3D( 0, 0, 0, 0, 2, jpkm1 )       ! part independent of the level
+      DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )       ! part independent of the level
          zfact(ji,jj) = zfact(ji,jj) + zweight(ji,jj,jk)
       END_3D
       !
-      DO_2D( 0, 0, 0, 0 )
+      DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
          IF( zfact(ji,jj) /= 0 )   zfact(ji,jj) = ebot_iwm(ji,jj) / ( rho0 * zfact(ji,jj) )
       END_2D
       !
-      DO_3D( 0, 0, 0, 0, 2, jpkm1 )       ! complete with the level-dependent part
+      DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )       ! complete with the level-dependent part
          zemx_iwm(ji,jj,jk) = zemx_iwm(ji,jj,jk) + zweight(ji,jj,jk) * zfact(ji,jj) * wmask(ji,jj,jk)   &
             &                                                        / ( gde3w(ji,jj,jk) - gde3w(ji,jj,jk-1) )
@@ -273,10 +274,10 @@
 !!gm  this is to be replaced by just a constant value znu=1.e-6 m2/s
       ! Calculate molecular kinematic viscosity
-      DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+      DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpkm1 )
          znu_t(ji,jj,jk) = 1.e-4_wp * (  17.91_wp - 0.53810_wp * ts(ji,jj,jk,jp_tem,Kmm)   &
             &                                     + 0.00694_wp * ts(ji,jj,jk,jp_tem,Kmm) * ts(ji,jj,jk,jp_tem,Kmm)  &
             &                                     + 0.02305_wp * ts(ji,jj,jk,jp_sal,Kmm)  ) * tmask(ji,jj,jk) * r1_rho0
       END_3D
-      DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+      DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
          znu_w(ji,jj,jk) = 0.5_wp * ( znu_t(ji,jj,jk-1) + znu_t(ji,jj,jk) ) * wmask(ji,jj,jk)
       END_3D
@@ -284,15 +285,15 @@
       !
       ! Calculate turbulence intensity parameter Reb
-      DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+      DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
          zReb(ji,jj,jk) = zemx_iwm(ji,jj,jk) / MAX( 1.e-20_wp, znu_w(ji,jj,jk) * rn2(ji,jj,jk) )
       END_3D
       !
       ! Define internal wave-induced diffusivity
-      DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+      DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
          zav_wave(ji,jj,jk) = znu_w(ji,jj,jk) * zReb(ji,jj,jk) * r1_6   ! This corresponds to a constant mixing efficiency of 1/6
       END_3D
       !
       IF( ln_mevar ) THEN                ! Variable mixing efficiency case : modify zav_wave in the
-         DO_3D( 0, 0, 0, 0, 2, jpkm1 )   ! energetic (Reb > 480) and buoyancy-controlled (Reb <10.224 ) regimes
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )   ! energetic (Reb > 480) and buoyancy-controlled (Reb <10.224 ) regimes
             IF( zReb(ji,jj,jk) > 480.00_wp ) THEN
                zav_wave(ji,jj,jk) = 3.6515_wp * znu_w(ji,jj,jk) * SQRT( zReb(ji,jj,jk) )
@@ -303,10 +304,10 @@
       ENDIF
       !
-      DO_3D( 0, 0, 0, 0, 2, jpkm1 )      ! Bound diffusivity by molecular value and 100 cm2/s
+      DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )      ! Bound diffusivity by molecular value and 100 cm2/s
          zav_wave(ji,jj,jk) = MIN(  MAX( 1.4e-7_wp, zav_wave(ji,jj,jk) ), 1.e-2_wp  ) * wmask(ji,jj,jk)
       END_3D
       !
       IF( kt == nit000 ) THEN        !* Control print at first time-step: diagnose the energy consumed by zav_wave
-         zztmp = 0._wp
+         IF( .NOT. l_istiled .OR. ntile == 1 ) zztmp = 0._wp                    ! Do only on the first tile
 !!gm used of glosum 3D....
          DO_3D( 0, 0, 0, 0, 2, jpkm1 )
@@ -314,13 +315,16 @@
                &          * MAX( 0._wp, rn2(ji,jj,jk) ) * zav_wave(ji,jj,jk) * wmask(ji,jj,jk) * tmask_i(ji,jj)
          END_3D
-         CALL mpp_sum( 'zdfiwm', zztmp )
-         zztmp = rho0 * zztmp ! Global integral of rauo * Kz * N^2 = power contributing to mixing 
-         !
-         IF(lwp) THEN
-            WRITE(numout,*)
-            WRITE(numout,*) 'zdf_iwm : Internal wave-driven mixing (iwm)'
-            WRITE(numout,*) '~~~~~~~ '
-            WRITE(numout,*)
-            WRITE(numout,*) '      Total power consumption by av_wave =  ', zztmp * 1.e-12_wp, 'TW'
+
+         IF( .NOT. l_istiled .OR. ntile == nijtile ) THEN                       ! Do only on the last tile
+            CALL mpp_sum( 'zdfiwm', zztmp )
+            zztmp = rho0 * zztmp ! Global integral of rauo * Kz * N^2 = power contributing to mixing
+            !
+            IF(lwp) THEN
+               WRITE(numout,*)
+               WRITE(numout,*) 'zdf_iwm : Internal wave-driven mixing (iwm)'
+               WRITE(numout,*) '~~~~~~~ '
+               WRITE(numout,*)
+               WRITE(numout,*) '      Total power consumption by av_wave =  ', zztmp * 1.e-12_wp, 'TW'
+            ENDIF
          ENDIF
       ENDIF
@@ -332,5 +336,5 @@
       IF( ln_tsdiff ) THEN                !* Option for differential mixing of salinity and temperature
          ztmp1 = 0.505_wp + 0.495_wp * TANH( 0.92_wp * ( LOG10( 1.e-20_wp ) - 0.60_wp ) )
-         DO_3D( 0, 0, 0, 0, 2, jpkm1 )       ! Calculate S/T diffusivity ratio as a function of Reb
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )       ! Calculate S/T diffusivity ratio as a function of Reb
             ztmp2 = zReb(ji,jj,jk) * 5._wp * r1_6
             IF ( ztmp2 > 1.e-20_wp .AND. wmask(ji,jj,jk) == 1._wp ) THEN
@@ -341,5 +345,5 @@
          END_3D
          CALL iom_put( "av_ratio", zav_ratio )
-         DO_3D( 0, 0, 0, 0, 2, jpkm1 )    !* update momentum & tracer diffusivity with wave-driven mixing
+         DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )    !* update momentum & tracer diffusivity with wave-driven mixing
             p_avs(ji,jj,jk) = p_avs(ji,jj,jk) + zav_wave(ji,jj,jk) * zav_ratio(ji,jj,jk)
             p_avt(ji,jj,jk) = p_avt(ji,jj,jk) + zav_wave(ji,jj,jk)
@@ -348,5 +352,5 @@
          !
       ELSE                                !* update momentum & tracer diffusivity with wave-driven mixing
-         DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+         DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
             p_avs(ji,jj,jk) = p_avs(ji,jj,jk) + zav_wave(ji,jj,jk)
             p_avt(ji,jj,jk) = p_avt(ji,jj,jk) + zav_wave(ji,jj,jk)
@@ -361,13 +365,11 @@
                                           !  vertical integral of rho0 * Kz * N^2 , energy density (zemx_iwm)
       IF( iom_use("bflx_iwm") .OR. iom_use("pcmap_iwm") ) THEN
-         ALLOCATE( z2d(jpi,jpj) , z3d(jpi,jpj,jpk) )
+         ALLOCATE( z2d(A2D(nn_hls)) , z3d(A2D(nn_hls),jpk) )
+         z2d(:,:) = 0._wp ; z3d(:,:,:) = 0._wp
+
          ! Initialisation for iom_put
          DO_2D( 0, 0, 0, 0 )
             z3d(ji,jj,1) = 0._wp   ;   z3d(ji,jj,jpk) = 0._wp
          END_2D
-         z3d(           1:nn_hls,:,:) = 0._wp   ;   z3d(:,           1:nn_hls,:) = 0._wp
-         z3d(jpi-nn_hls+1:jpi   ,:,:) = 0._wp   ;   z3d(:,jpj-nn_hls+1:   jpj,:) = 0._wp
-         z2d(           1:nn_hls,:  ) = 0._wp   ;   z2d(:,           1:nn_hls  ) = 0._wp
-         z2d(jpi-nn_hls+1:jpi   ,:  ) = 0._wp   ;   z2d(:,jpj-nn_hls+1:   jpj  ) = 0._wp
 
          DO_3D( 0, 0, 0, 0, 2, jpkm1 )
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfmfc.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfmfc.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfmfc.F90	(revision 14852)
@@ -96,24 +96,24 @@
       INTEGER                                  , INTENT(in)    :: Kmm, Krhs ! time level indices
       REAL(wp), DIMENSION(jpi,jpj,jpk,jpts,jpt), INTENT(inout) :: pts       ! active tracers and RHS of tracer equation
-      REAL(wp), DIMENSION(jpi,jpj,jpk,2) ::   ztsp         ! T/S of the plume
-      REAL(wp), DIMENSION(jpi,jpj,jpk,2) ::   ztse         ! T/S at W point
-      REAL(wp), DIMENSION(jpi,jpj,jpk) :: zrwp          !
-      REAL(wp), DIMENSION(jpi,jpj,jpk) :: zrwp2         !
-      REAL(wp), DIMENSION(jpi,jpj,jpk) :: zapp          !
-      REAL(wp), DIMENSION(jpi,jpj,jpk) :: zedmf         !
-      REAL(wp), DIMENSION(jpi,jpj,jpk) :: zepsT, zepsW  !
-      !
-      REAL(wp), DIMENSION(jpi,jpj) :: zustar, zustar2   !
-      REAL(wp), DIMENSION(jpi,jpj) :: zuws, zvws, zsws, zfnet          !
-      REAL(wp), DIMENSION(jpi,jpj) :: zfbuo, zrautbm1, zrautb, zraupl
-      REAL(wp), DIMENSION(jpi,jpj) :: zwpsurf            !
-      REAL(wp), DIMENSION(jpi,jpj) :: zop0 , zsp0 !
-      REAL(wp), DIMENSION(jpi,jpj) :: zrwp_0, zrwp2_0  !
-      REAL(wp), DIMENSION(jpi,jpj) :: zapp0           !
-      REAL(wp), DIMENSION(jpi,jpj) :: zphp, zph, zphpm1, zphm1, zNHydro
-      REAL(wp), DIMENSION(jpi,jpj) :: zhcmo          !
-      !
-      REAL(wp), DIMENSION(jpi,jpj,jpk)   ::   zn2    ! N^2
-      REAL(wp), DIMENSION(jpi,jpj,2  ) ::   zab, zabm1, zabp ! alpha and beta
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk,2) ::   ztsp         ! T/S of the plume
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk,2) ::   ztse         ! T/S at W point
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) :: zrwp          !
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) :: zrwp2         !
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) :: zapp          !
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) :: zedmf         !
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) :: zepsT, zepsW  !
+      !
+      REAL(wp), DIMENSION(A2D(nn_hls)) :: zustar, zustar2   !
+      REAL(wp), DIMENSION(A2D(nn_hls)) :: zuws, zvws, zsws, zfnet          !
+      REAL(wp), DIMENSION(A2D(nn_hls)) :: zfbuo, zrautbm1, zrautb, zraupl
+      REAL(wp), DIMENSION(A2D(nn_hls)) :: zwpsurf            !
+      REAL(wp), DIMENSION(A2D(nn_hls)) :: zop0 , zsp0 !
+      REAL(wp), DIMENSION(A2D(nn_hls)) :: zrwp_0, zrwp2_0  !
+      REAL(wp), DIMENSION(A2D(nn_hls)) :: zapp0           !
+      REAL(wp), DIMENSION(A2D(nn_hls)) :: zphp, zph, zphpm1, zphm1, zNHydro
+      REAL(wp), DIMENSION(A2D(nn_hls)) :: zhcmo          !
+      !
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk)   ::   zn2    ! N^2
+      REAL(wp), DIMENSION(A2D(nn_hls),2  ) ::   zab, zabm1, zabp ! alpha and beta
      
       REAL(wp), PARAMETER :: zepsilon = 1.e-30                 ! local small value
@@ -136,35 +136,37 @@
       zcd          = 1._wp
 
-      !------------------------------------------------------------------
-      ! Surface boundary condition
-      !------------------------------------------------------------------
-      ! surface Stress
-      !--------------------
-      zuws(:,:) = utau(:,:) * r1_rho0 
-      zvws(:,:) = vtau(:,:) * r1_rho0 
-      zustar2(:,:) = SQRT(zuws(:,:)*zuws(:,:)+zvws(:,:)*zvws(:,:))
-      zustar(:,:)  = SQRT(zustar2(:,:))
-
-      ! Heat Flux
-      !--------------------
-      zfnet(:,:) = qns(:,:) + qsr(:,:)
-      zfnet(:,:) = zfnet(:,:) / (rho0 * rcp)
-
-      ! Water Flux
-      !---------------------
-      zsws(:,:) = emp(:,:)
-
-      !-------------------------------------------
-      ! Initialisation of prognostic variables
-      !-------------------------------------------
-      zrwp (:,:,:) =  0._wp ; zrwp2(:,:,:) =  0._wp ; zedmf(:,:,:) =  0._wp
-      zph  (:,:)   =  0._wp ; zphm1(:,:)   =  0._wp ; zphpm1(:,:)  =  0._wp
-      ztsp(:,:,:,:)=  0._wp
-
-      ! Tracers inside plume (ztsp) and environment (ztse)
-      ztsp(:,:,1,jp_tem) = pts(:,:,1,jp_tem,Kmm) * tmask(:,:,1)
-      ztsp(:,:,1,jp_sal) = pts(:,:,1,jp_sal,Kmm) * tmask(:,:,1)
-      ztse(:,:,1,jp_tem) = pts(:,:,1,jp_tem,Kmm) * tmask(:,:,1)
-      ztse(:,:,1,jp_sal) = pts(:,:,1,jp_sal,Kmm) * tmask(:,:,1)
+      DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
+         !------------------------------------------------------------------
+         ! Surface boundary condition
+         !------------------------------------------------------------------
+         ! surface Stress
+         !--------------------
+         zuws(ji,jj) = utau(ji,jj) * r1_rho0
+         zvws(ji,jj) = vtau(ji,jj) * r1_rho0
+         zustar2(ji,jj) = SQRT(zuws(ji,jj)*zuws(ji,jj)+zvws(ji,jj)*zvws(ji,jj))
+         zustar(ji,jj)  = SQRT(zustar2(ji,jj))
+
+         ! Heat Flux
+         !--------------------
+         zfnet(ji,jj) = qns(ji,jj) + qsr(ji,jj)
+         zfnet(ji,jj) = zfnet(ji,jj) / (rho0 * rcp)
+
+         ! Water Flux
+         !---------------------
+         zsws(ji,jj) = emp(ji,jj)
+
+         !-------------------------------------------
+         ! Initialisation of prognostic variables
+         !-------------------------------------------
+         zrwp (ji,jj,:) =  0._wp ; zrwp2(ji,jj,:) =  0._wp ; zedmf(ji,jj,:) =  0._wp
+         zph  (ji,jj)   =  0._wp ; zphm1(ji,jj)   =  0._wp ; zphpm1(ji,jj)  =  0._wp
+         ztsp(ji,jj,:,:)=  0._wp
+
+         ! Tracers inside plume (ztsp) and environment (ztse)
+         ztsp(ji,jj,1,jp_tem) = pts(ji,jj,1,jp_tem,Kmm) * tmask(ji,jj,1)
+         ztsp(ji,jj,1,jp_sal) = pts(ji,jj,1,jp_sal,Kmm) * tmask(ji,jj,1)
+         ztse(ji,jj,1,jp_tem) = pts(ji,jj,1,jp_tem,Kmm) * tmask(ji,jj,1)
+         ztse(ji,jj,1,jp_sal) = pts(ji,jj,1,jp_sal,Kmm) * tmask(ji,jj,1)
+      END_2D
 
       CALL eos( ztse(:,:,1,:) ,  zrautb(:,:) )
@@ -174,8 +176,10 @@
       ! Boundary Condition of Mass Flux (plume velo.; convective area, entrain/detrain)
       !-------------------------------------------
-      zhcmo(:,:) = e3t(:,:,1,Kmm)
+      zhcmo(:,:) = e3t(A1Di(nn_hls),A1Dj(nn_hls),1,Kmm)
       zfbuo(:,:)   = 0._wp
       WHERE ( ABS(zrautb(:,:)) > 1.e-20 ) zfbuo(:,:)   =   &
-         &      grav * ( 2.e-4_wp *zfnet(:,:) - 7.6E-4_wp*pts(:,:,1,jp_sal,Kmm)*zsws(:,:)/zrautb(:,:)) * zhcmo(:,:)
+         &      grav * ( 2.e-4_wp *zfnet(:,:)              &
+         &      - 7.6E-4_wp*pts(A2D(nn_hls),1,jp_sal,Kmm)  &
+         &      * zsws(:,:)/zrautb(:,:)) * zhcmo(:,:)
 
       zedmf(:,:,1) = -0.065_wp*(ABS(zfbuo(:,:)))**(1._wp/3._wp)*SIGN(1.,zfbuo(:,:))
@@ -211,8 +215,10 @@
          CALL eos( ztsp(:,:,jk-1,:    ) ,  zraupl(:,:)   )
 
-         zphm1(:,:)  = zphm1(:,:)  + grav * zrautbm1(:,:) * e3t(:,:,jk-1, Kmm)
-         zphpm1(:,:) = zphpm1(:,:) + grav * zraupl(:,:)   * e3t(:,:,jk-1, Kmm)
-         zph(:,:)    = zphm1(:,:)  + grav * zrautb(:,:)   * e3t(:,:,jk  , Kmm)
-         zph(:,:)    = MAX( zph(:,:), zepsilon)
+         DO_2D( 0, 0, 0, 0 )
+            zphm1(ji,jj)  = zphm1(ji,jj)  + grav * zrautbm1(ji,jj) * e3t(ji,jj,jk-1, Kmm)
+            zphpm1(ji,jj) = zphpm1(ji,jj) + grav * zraupl(ji,jj)   * e3t(ji,jj,jk-1, Kmm)
+            zph(ji,jj)    = zphm1(ji,jj)  + grav * zrautb(ji,jj)   * e3t(ji,jj,jk  , Kmm)
+            zph(ji,jj)    = MAX( zph(ji,jj), zepsilon)
+         END_2D
 
          WHERE(zrautbm1 .NE. 0.) zfbuo(:,:)  =  grav * (zraupl(:,:) - zrautbm1(:,:)) / zrautbm1(:,:)
@@ -322,8 +328,10 @@
 
       ! Compute Mass Flux on T-point
-      DO jk=1,jpk-1
-         edmfm(:,:,jk) = (zedmf(:,:,jk+1)  + zedmf(:,:,jk) )*0.5_wp
-      END DO
-      edmfm(:,:,jpk) = zedmf(:,:,jpk) 
+      DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+         edmfm(ji,jj,jk) = (zedmf(ji,jj,jk+1)  + zedmf(ji,jj,jk) )*0.5_wp
+      END_3D
+      DO_2D( 0, 0, 0, 0 )
+         edmfm(ji,jj,jpk) = zedmf(ji,jj,jpk)
+      END_2D
 
       ! Save variable (on T point)
@@ -338,43 +346,48 @@
       !  Computation of a tridiagonal matrix and right hand side terms of the linear system
       !=================================================================================
-      edmfa(:,:,:)     = 0._wp
-      edmfb(:,:,:)     = 0._wp
-      edmfc(:,:,:)     = 0._wp
-      edmftra(:,:,:,:) = 0._wp
+      DO_3D( 0, 0, 0, 0, 1, jpk )
+         edmfa(ji,jj,jk)     = 0._wp
+         edmfb(ji,jj,jk)     = 0._wp
+         edmfc(ji,jj,jk)     = 0._wp
+         edmftra(ji,jj,jk,:) = 0._wp
+      END_3D
 
       !---------------------------------------------------------------
       ! Diagonal terms 
       !---------------------------------------------------------------
-      DO jk=1,jpk-1
-         edmfa(:,:,jk) =  0._wp
-         edmfb(:,:,jk) = -edmfm(:,:,jk  ) / e3w(:,:,jk+1,Kmm)
-         edmfc(:,:,jk) =  edmfm(:,:,jk+1) / e3w(:,:,jk+1,Kmm)
-      END DO
-      edmfa(:,:,jpk)   = -edmfm(:,:,jpk-1) / e3w(:,:,jpk,Kmm)
-      edmfb(:,:,jpk)   =  edmfm(:,:,jpk  ) / e3w(:,:,jpk,Kmm)
-      edmfc(:,:,jpk)   =  0._wp
+      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
+      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
 
       !---------------------------------------------------------------
       ! right hand side term for Temperature
       !---------------------------------------------------------------
-      DO jk=1,jpk-1
-        edmftra(:,:,jk,1) = - edmfm(:,:,jk  ) * ztsp(:,:,jk  ,jp_tem) / e3w(:,:,jk+1,Kmm) &
-                          & + edmfm(:,:,jk+1) * ztsp(:,:,jk+1,jp_tem) / e3w(:,:,jk+1,Kmm)
-      END DO
-      edmftra(:,:,jpk,1) = - edmfm(:,:,jpk-1) * ztsp(:,:,jpk-1,jp_tem) / e3w(:,:,jpk,Kmm) &
-                         & + edmfm(:,:,jpk  ) * ztsp(:,:,jpk  ,jp_tem) / e3w(:,:,jpk,Kmm)
-                        
+      DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+        edmftra(ji,jj,jk,1) = - edmfm(ji,jj,jk  ) * ztsp(ji,jj,jk  ,jp_tem) / e3w(ji,jj,jk+1,Kmm) &
+                            & + edmfm(ji,jj,jk+1) * ztsp(ji,jj,jk+1,jp_tem) / e3w(ji,jj,jk+1,Kmm)
+      END_3D
+      DO_2D( 0, 0, 0, 0 )
+         edmftra(ji,jj,jpk,1) = - edmfm(ji,jj,jpk-1) * ztsp(ji,jj,jpk-1,jp_tem) / e3w(ji,jj,jpk,Kmm) &
+                              & + edmfm(ji,jj,jpk  ) * ztsp(ji,jj,jpk  ,jp_tem) / e3w(ji,jj,jpk,Kmm)
+      END_2D
+
       !---------------------------------------------------------------
       ! Right hand side term for Salinity
       !---------------------------------------------------------------
-      DO jk=1,jpk-1
-         edmftra(:,:,jk,2) =  - edmfm(:,:,jk  ) * ztsp(:,:,jk  ,jp_sal) / e3w(:,:,jk+1,Kmm) &
-                           &  + edmfm(:,:,jk+1) * ztsp(:,:,jk+1,jp_sal) / e3w(:,:,jk+1,Kmm)
-      END DO
-      edmftra(:,:,jpk,2) = - edmfm(:,:,jpk-1) * ztsp(:,:,jpk-1,jp_sal) / e3w(:,:,jpk,Kmm) &
-                         & + edmfm(:,:,jpk  ) * ztsp(:,:,jpk  ,jp_sal) / e3w(:,:,jpk,Kmm)
-      !
-      !
-      CALL lbc_lnk( 'zdfmfc', edmfm,'T',1., edmfa,'T',1., edmfb,'T',1., edmfc,'T',1., edmftra(:,:,:,jp_tem),'T',1., edmftra(:,:,:,jp_sal),'T',1.)
+      DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+         edmftra(ji,jj,jk,2) =  - edmfm(ji,jj,jk  ) * ztsp(ji,jj,jk  ,jp_sal) / e3w(ji,jj,jk+1,Kmm) &
+                             &  + edmfm(ji,jj,jk+1) * ztsp(ji,jj,jk+1,jp_sal) / e3w(ji,jj,jk+1,Kmm)
+      END_3D
+      DO_2D( 0, 0, 0, 0 )
+         edmftra(ji,jj,jpk,2) = - edmfm(ji,jj,jpk-1) * ztsp(ji,jj,jpk-1,jp_sal) / e3w(ji,jj,jpk,Kmm) &
+                              & + edmfm(ji,jj,jpk  ) * ztsp(ji,jj,jpk  ,jp_sal) / e3w(ji,jj,jpk,Kmm)
+      END_2D
       !
    END SUBROUTINE tra_mfc
@@ -383,7 +396,7 @@
    SUBROUTINE diag_mfc( zdiagi, zdiagd, zdiags, p2dt, Kaa )
 
-      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::  zdiagi, zdiagd, zdiags  ! inout: tridaig. terms 
-      REAL(wp)                        , INTENT(in   ) ::   p2dt                   ! tracer time-step
-      INTEGER                         , INTENT(in   ) ::   Kaa                    ! ocean time level indices
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(inout) ::  zdiagi, zdiagd, zdiags  ! inout: tridaig. terms
+      REAL(wp)                            , INTENT(in   ) ::   p2dt                   ! tracer time-step
+      INTEGER                             , INTENT(in   ) ::   Kaa                    ! ocean time level indices
 
       INTEGER  ::   ji, jj, jk  ! dummy  loop arguments   
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfmxl.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfmxl.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfmxl.F90	(revision 14852)
@@ -26,5 +26,5 @@
    PRIVATE
 
-   PUBLIC   zdf_mxl   ! called by zdfphy.F90
+   PUBLIC   zdf_mxl, zdf_mxl_turb   ! called by zdfphy.F90
 
    INTEGER , PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   nmln    !: number of level in the mixed layer (used by LDF, ZDF, TRD, TOP)
@@ -41,5 +41,5 @@
    !!----------------------------------------------------------------------
    !! NEMO/OCE 4.0 , NEMO Consortium (2018)
-   !! $Id$ 
+   !! $Id$
    !! Software governed by the CeCILL license (see ./LICENSE)
    !!----------------------------------------------------------------------
@@ -65,16 +65,11 @@
       !!                  ***  ROUTINE zdfmxl  ***
       !!                   
-      !! ** Purpose :   Compute the turbocline depth and the mixed layer depth
-      !!              with density criteria.
+      !! ** Purpose :   Compute the mixed layer depth with density criteria.
       !!
       !! ** Method  :   The mixed layer depth is the shallowest W depth with 
       !!      the density of the corresponding T point (just bellow) bellow a
       !!      given value defined locally as rho(10m) + rho_c
-      !!               The turbocline depth is the depth at which the vertical
-      !!      eddy diffusivity coefficient (resulting from the vertical physics
-      !!      alone, not the isopycnal part, see trazdf.F) fall below a given
-      !!      value defined locally (avt_c here taken equal to 5 cm/s2 by default)
       !!
-      !! ** Action  :   nmln, hmld, hmlp, hmlpt
+      !! ** Action  :   nmln, hmlp, hmlpt
       !!----------------------------------------------------------------------
       INTEGER, INTENT(in) ::   kt   ! ocean time-step index
@@ -82,22 +77,25 @@
       !
       INTEGER  ::   ji, jj, jk      ! dummy loop indices
-      INTEGER  ::   iikn, iiki, ikt ! local integer
+      INTEGER  ::   iik, ikt        ! local integer
       REAL(wp) ::   zN2_c           ! local scalar
-      INTEGER, DIMENSION(jpi,jpj) ::   imld   ! 2D workspace
       !!----------------------------------------------------------------------
       !
-      IF( kt == nit000 ) THEN
-         IF(lwp) WRITE(numout,*)
-         IF(lwp) WRITE(numout,*) 'zdf_mxl : mixed layer depth'
-         IF(lwp) WRITE(numout,*) '~~~~~~~ '
-         !                             ! allocate zdfmxl arrays
-         IF( zdf_mxl_alloc() /= 0 )   CALL ctl_stop( 'STOP', 'zdf_mxl : unable to allocate arrays' )
+      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,*) 'zdf_mxl : mixed layer depth'
+            IF(lwp) WRITE(numout,*) '~~~~~~~ '
+            !                             ! allocate zdfmxl arrays
+            IF( zdf_mxl_alloc() /= 0 )   CALL ctl_stop( 'STOP', 'zdf_mxl : unable to allocate arrays' )
+         ENDIF
       ENDIF
       !
       ! w-level of the mixing and mixed layers
-      nmln(:,:)  = nlb10                  ! Initialization to the number of w ocean point
-      hmlp(:,:)  = 0._wp                  ! here hmlp used as a dummy variable, integrating vertically N^2
+      DO_2D_OVR( nn_hls, nn_hls, nn_hls, nn_hls )
+         nmln(ji,jj)  = nlb10                  ! Initialization to the number of w ocean point
+         hmlp(ji,jj)  = 0._wp                  ! here hmlp used as a dummy variable, integrating vertically N^2
+      END_2D
       zN2_c = grav * rho_c * r1_rho0      ! convert density criteria into N^2 criteria
-      DO_3D( 1, 1, 1, 1, nlb10, jpkm1 )   ! Mixed layer level: w-level
+      DO_3D_OVR( nn_hls, nn_hls, nn_hls, nn_hls, nlb10, jpkm1 )   ! Mixed layer level: w-level
          ikt = mbkt(ji,jj)
          hmlp(ji,jj) =   &
@@ -105,30 +103,15 @@
          IF( hmlp(ji,jj) < zN2_c )   nmln(ji,jj) = MIN( jk , ikt ) + 1   ! Mixed layer level
       END_3D
-      !
-      ! w-level of the turbocline and mixing layer (iom_use)
-      imld(:,:) = mbkt(:,:) + 1                ! Initialization to the number of w ocean point
-      DO_3DS( 1, 1, 1, 1, jpkm1, nlb10, -1 )   ! from the bottom to nlb10
-         IF( avt (ji,jj,jk) < avt_c * wmask(ji,jj,jk) )   imld(ji,jj) = jk      ! Turbocline 
-      END_3D
-      ! depth of the mixing and mixed layers
-      DO_2D( 1, 1, 1, 1 )
-         iiki = imld(ji,jj)
-         iikn = nmln(ji,jj)
-         hmld (ji,jj) = gdepw(ji,jj,iiki  ,Kmm) * ssmask(ji,jj)    ! Turbocline depth 
-         hmlp (ji,jj) = gdepw(ji,jj,iikn  ,Kmm) * ssmask(ji,jj)    ! Mixed layer depth
-         hmlpt(ji,jj) = gdept(ji,jj,iikn-1,Kmm) * ssmask(ji,jj)    ! depth of the last T-point inside the mixed layer
+      ! depth of the mixed layer
+      DO_2D_OVR( nn_hls, nn_hls, nn_hls, nn_hls )
+         iik = nmln(ji,jj)
+         hmlp (ji,jj) = gdepw(ji,jj,iik  ,Kmm) * ssmask(ji,jj)    ! Mixed layer depth
+         hmlpt(ji,jj) = gdept(ji,jj,iik-1,Kmm) * ssmask(ji,jj)    ! depth of the last T-point inside the mixed layer
       END_2D
       !
-      IF( .NOT.l_offline ) THEN
-         IF( iom_use("mldr10_1") ) THEN
-            IF( ln_isfcav ) THEN  ;  CALL iom_put( "mldr10_1", hmlp - risfdep)   ! mixed layer thickness
-            ELSE                  ;  CALL iom_put( "mldr10_1", hmlp )            ! mixed layer depth
-            END IF
+      IF( .NOT.l_offline .AND. iom_use("mldr10_1") ) THEN
+         IF( ln_isfcav ) THEN  ;  CALL iom_put( "mldr10_1", hmlp - risfdep)   ! mixed layer thickness
+         ELSE                  ;  CALL iom_put( "mldr10_1", hmlp )            ! mixed layer depth
          END IF
-         IF( iom_use("mldkz5") ) THEN
-            IF( ln_isfcav ) THEN  ;  CALL iom_put( "mldkz5"  , hmld - risfdep )   ! turbocline thickness
-            ELSE                  ;  CALL iom_put( "mldkz5"  , hmld )             ! turbocline depth
-            END IF
-         ENDIF
       ENDIF
       !
@@ -137,4 +120,44 @@
    END SUBROUTINE zdf_mxl
 
+
+   SUBROUTINE zdf_mxl_turb( kt, Kmm )
+      !!----------------------------------------------------------------------
+      !!                  ***  ROUTINE zdf_mxl_turb  ***
+      !!
+      !! ** Purpose :   Compute the turbocline depth.
+      !!
+      !! ** Method  :   The turbocline depth is the depth at which the vertical
+      !!      eddy diffusivity coefficient (resulting from the vertical physics
+      !!      alone, not the isopycnal part, see trazdf.F) fall below a given
+      !!      value defined locally (avt_c here taken equal to 5 cm/s2 by default)
+      !!
+      !! ** Action  :   hmld
+      !!----------------------------------------------------------------------
+      INTEGER, INTENT(in) ::   kt   ! ocean time-step index
+      INTEGER, INTENT(in) ::   Kmm  ! ocean time level index
+      !
+      INTEGER  ::   ji, jj, jk      ! dummy loop indices
+      INTEGER  ::   iik             ! local integer
+      INTEGER, DIMENSION(A2D(nn_hls)) ::   imld   ! 2D workspace
+      !!----------------------------------------------------------------------
+      !
+      ! w-level of the turbocline and mixing layer (iom_use)
+      imld(:,:) = mbkt(A2D(nn_hls)) + 1                ! Initialization to the number of w ocean point
+      DO_3DS( 1, 1, 1, 1, jpkm1, nlb10, -1 )   ! from the bottom to nlb10
+         IF( avt (ji,jj,jk) < avt_c * wmask(ji,jj,jk) )   imld(ji,jj) = jk      ! Turbocline
+      END_3D
+      ! depth of the mixing layer
+      DO_2D_OVR( 1, 1, 1, 1 )
+         iik = imld(ji,jj)
+         hmld (ji,jj) = gdepw(ji,jj,iik  ,Kmm) * ssmask(ji,jj)    ! Turbocline depth
+      END_2D
+      !
+      IF( .NOT.l_offline .AND. iom_use("mldkz5") ) THEN
+         IF( ln_isfcav ) THEN  ;  CALL iom_put( "mldkz5"  , hmld - risfdep )   ! turbocline thickness
+         ELSE                  ;  CALL iom_put( "mldkz5"  , hmld )             ! turbocline depth
+         END IF
+      ENDIF
+      !
+   END SUBROUTINE zdf_mxl_turb
    !!======================================================================
 END MODULE zdfmxl
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfphy.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfphy.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfphy.F90	(revision 14852)
@@ -12,4 +12,6 @@
    !!----------------------------------------------------------------------
    USE oce            ! ocean dynamics and tracers variables
+   ! TEMP: [tiling] This change not necessary after finalisation of zdf_osm (not yet tiled)
+   USE domtile
    USE zdf_oce        ! vertical physics: shared variables
    USE zdfdrg         ! vertical physics: top/bottom drag coef.
@@ -54,6 +56,10 @@
    INTEGER, PARAMETER ::   np_OSM = 5   ! OSMOSIS-OBL closure scheme for Kz
 
-   LOGICAL ::   l_zdfsh2   ! shear production term flag (=F for CST, =T otherwise (i.e. TKE, GLS, RIC))
-
+   LOGICAL, PUBLIC ::   l_zdfsh2   ! shear production term flag (=F for CST, =T otherwise (i.e. TKE, GLS, RIC))
+
+   REAL(wp), SAVE, ALLOCATABLE, DIMENSION(:,:,:) ::   avm_k_n !: "Now" avm_k used for calculation of zsh2 with tiling
+
+   !! * Substitutions
+#  include "do_loop_substitute.h90"
    !!----------------------------------------------------------------------
    !! NEMO/OCE 4.0 , NEMO Consortium (2018)
@@ -180,4 +186,6 @@
       IF( lk_top    .AND. ln_zdfnpc )   CALL ctl_stop( 'zdf_phy_init: npc scheme is not working with key_top' )
       IF( lk_top    .AND. ln_zdfosm )   CALL ctl_warn( 'zdf_phy_init: osmosis gives no non-local fluxes for TOP tracers yet' )
+      ! TEMP: [tiling] This change not necessary after finalisation of zdf_osm (not yet tiled)
+      IF( ln_tile   .AND. ln_zdfosm )   CALL ctl_warn( 'zdf_phy_init: osmosis does not yet work with tiling' )
       IF( lk_top    .AND. ln_zdfmfc )   CALL ctl_stop( 'zdf_phy_init: Mass Flux scheme is not working with key_top' )
       IF(lwp) THEN
@@ -210,7 +218,8 @@
       ENDIF
       !                                ! shear production term flag
-      IF( ln_zdfcst ) THEN   ;   l_zdfsh2 = .FALSE.
-      ELSE                   ;   l_zdfsh2 = .TRUE.
-      ENDIF
+      IF( ln_zdfcst .OR. ln_zdfosm ) THEN   ;   l_zdfsh2 = .FALSE.
+      ELSE                                  ;   l_zdfsh2 = .TRUE.
+      ENDIF
+      IF( ln_tile .AND. l_zdfsh2 ) ALLOCATE( avm_k_n(jpi,jpj,jpk) )
       !                          !== Mass Flux Convectiive algorithm  ==!
       IF( ln_zdfmfc )   CALL zdf_mfc_init       ! Convection computed with eddy diffusivity mass flux
@@ -246,8 +255,21 @@
       !
       INTEGER ::   ji, jj, jk   ! dummy loop indice
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zsh2   ! shear production
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zsh2   ! shear production
+      ! TEMP: [tiling] This change not necessary after finalisation of zdf_osm (not yet tiled)
+      LOGICAL :: lskip
       !! ---------------------------------------------------------------------
       !
       IF( ln_timing )   CALL timing_start('zdf_phy')
+
+      ! TEMP: [tiling] These changes not necessary after finalisation of zdf_osm (not yet tiled)
+      lskip = .FALSE.
+
+      IF( ln_tile .AND. nzdf_phy == np_OSM )  THEN
+         IF( ntile == 1 ) THEN
+            CALL dom_tile_stop( ldhold=.TRUE. )
+         ELSE
+            lskip = .TRUE.
+         ENDIF
+      ENDIF
       !
       IF( l_zdfdrg ) THEN     !==  update top/bottom drag  ==!   (non-linear cases)
@@ -267,38 +289,59 @@
       IF ( ln_drgice_imp) THEN
          IF ( ln_isfcav ) THEN
-            rCdU_top(:,:) = rCdU_top(:,:) + ssmask(:,:) * tmask(:,:,1) * rCdU_ice(:,:)
+            DO_2D_OVR( 1, 1, 1, 1 )
+               rCdU_top(ji,jj) = rCdU_top(ji,jj) + ssmask(ji,jj) * tmask(ji,jj,1) * rCdU_ice(ji,jj)
+            END_2D
          ELSE
-            rCdU_top(:,:) = rCdU_ice(:,:)
+            DO_2D_OVR( 1, 1, 1, 1 )
+               rCdU_top(ji,jj) = rCdU_ice(ji,jj)
+            END_2D
          ENDIF
       ENDIF
 #endif
       !
-      !                       !==  Kz from chosen turbulent closure  ==!   (avm_k, avt_k)
-      !
-      IF( l_zdfsh2 )   &         !* shear production at w-points (energy conserving form)
-         CALL zdf_sh2( Kbb, Kmm, avm_k,   &     ! <<== in
-            &                     zsh2    )     ! ==>> out : shear production
-      !
-      SELECT CASE ( nzdf_phy )                  !* Vertical eddy viscosity and diffusivity coefficients at w-points
-      CASE( np_RIC )   ;   CALL zdf_ric( kt,      Kmm, zsh2, avm_k, avt_k )    ! Richardson number dependent Kz
-      CASE( np_TKE )   ;   CALL zdf_tke( kt, Kbb, Kmm, zsh2, avm_k, avt_k )    ! TKE closure scheme for Kz
-      CASE( np_GLS )   ;   CALL zdf_gls( kt, Kbb, Kmm, zsh2, avm_k, avt_k )    ! GLS closure scheme for Kz
-      CASE( np_OSM )   ;   CALL zdf_osm( kt, Kbb, Kmm, Krhs, avm_k, avt_k )    ! OSMOSIS closure scheme for Kz
-!     CASE( np_CST )                                  ! Constant Kz (reset avt, avm to the background value)
-!         ! avt_k and avm_k set one for all at initialisation phase
+      CALL zdf_mxl( kt, Kmm )                        !* mixed layer depth, and level
+
+      ! TEMP: [tiling] These changes not necessary after finalisation of zdf_osm (not yet tiled)
+      IF( .NOT. lskip ) THEN
+         !                       !==  Kz from chosen turbulent closure  ==!   (avm_k, avt_k)
+         !
+         ! NOTE: [tiling] the closure schemes (zdf_tke etc) will update avm_k. With tiling, the calculation of zsh2 on adjacent tiles then uses both updated (next timestep) and non-updated (current timestep) values of avm_k. To preserve results, we save a read-only copy of the "now" avm_k to use in the calculation of zsh2.
+         IF( l_zdfsh2 ) THEN        !* shear production at w-points (energy conserving form)
+            IF( ln_tile ) THEN
+               IF( ntile == 1 ) avm_k_n(:,:,:) = avm_k(:,:,:)     ! Preserve "now" avm_k for calculation of zsh2
+               CALL zdf_sh2( Kbb, Kmm, avm_k_n, &     ! <<== in
+                  &                     zsh2    )     ! ==>> out : shear production
+            ELSE
+               CALL zdf_sh2( Kbb, Kmm, avm_k,   &     ! <<== in
+                  &                     zsh2    )     ! ==>> out : shear production
+            ENDIF
+         ENDIF
+         !
+         SELECT CASE ( nzdf_phy )                  !* Vertical eddy viscosity and diffusivity coefficients at w-points
+         CASE( np_RIC )   ;   CALL zdf_ric( kt,      Kmm, zsh2, avm_k, avt_k )    ! Richardson number dependent Kz
+         CASE( np_TKE )   ;   CALL zdf_tke( kt, Kbb, Kmm, zsh2, avm_k, avt_k )    ! TKE closure scheme for Kz
+         CASE( np_GLS )   ;   CALL zdf_gls( kt, Kbb, Kmm, zsh2, avm_k, avt_k )    ! GLS closure scheme for Kz
+         CASE( np_OSM )   ;   CALL zdf_osm( kt, Kbb, Kmm, Krhs, avm_k, avt_k )    ! OSMOSIS closure scheme for Kz
+   !     CASE( np_CST )                                  ! Constant Kz (reset avt, avm to the background value)
+   !         ! avt_k and avm_k set one for all at initialisation phase
 !!gm         avt(2:jpim1,2:jpjm1,1:jpkm1) = rn_avt0 * wmask(2:jpim1,2:jpjm1,1:jpkm1)
 !!gm         avm(2:jpim1,2:jpjm1,1:jpkm1) = rn_avm0 * wmask(2:jpim1,2:jpjm1,1:jpkm1)
-      END SELECT
+         END SELECT
+
+         IF( ln_tile .AND. .NOT. l_istiled ) CALL dom_tile_start( ldhold=.TRUE. )
+      ENDIF
       !
       !                          !==  ocean Kz  ==!   (avt, avs, avm)
       !
       !                                         !* start from turbulent closure values
-      avt(:,:,2:jpkm1) = avt_k(:,:,2:jpkm1)
-      avm(:,:,2:jpkm1) = avm_k(:,:,2:jpkm1)
+      DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
+         avt(ji,jj,jk) = avt_k(ji,jj,jk)
+         avm(ji,jj,jk) = avm_k(ji,jj,jk)
+      END_3D
       !
       IF( ln_rnf_mouth ) THEN                   !* increase diffusivity at rivers mouths
-         DO jk = 2, nkrnf
-            avt(:,:,jk) = avt(:,:,jk) + 2._wp * rn_avt_rnf * rnfmsk(:,:) * wmask(:,:,jk)
-         END DO
+         DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, nkrnf )
+            avt(ji,jj,jk) = avt(ji,jj,jk) + 2._wp * rn_avt_rnf * rnfmsk(ji,jj) * wmask(ji,jj,jk)
+         END_3D
       ENDIF
       !
@@ -309,5 +352,7 @@
                         CALL zdf_ddm( kt, Kmm,  avm, avt, avs )
       ELSE                                            ! same mixing on all tracers
-         avs(2:jpim1,2:jpjm1,1:jpkm1) = avt(2:jpim1,2:jpjm1,1:jpkm1)
+         DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpkm1 )
+            avs(ji,jj,jk) = avt(ji,jj,jk)
+         END_3D
       ENDIF
       !
@@ -318,28 +363,34 @@
 #if defined key_agrif
       ! interpolation parent grid => child grid for avm_k ( ex : at west border: update column 1 and 2)
-      IF( l_zdfsh2 )   CALL Agrif_avm
+      IF( .NOT. l_istiled .OR. ntile == nijtile ) THEN                       ! Do only on the last tile
+         IF( l_zdfsh2 )   CALL Agrif_avm
+      ENDIF
 #endif
 
       !                                         !* Lateral boundary conditions (sign unchanged)
-      IF( l_zdfsh2 ) THEN
-         CALL lbc_lnk( 'zdfphy', avm_k, 'W', 1.0_wp , avt_k, 'W', 1.0_wp,   &
-            &                    avm  , 'W', 1.0_wp , avt  , 'W', 1.0_wp , avs , 'W', 1.0_wp )
-      ELSE
-         CALL lbc_lnk( 'zdfphy', avm  , 'W', 1.0_wp , avt  , 'W', 1.0_wp , avs , 'W', 1.0_wp )
-      ENDIF
-      !
-      IF( l_zdfdrg ) THEN     ! drag  have been updated (non-linear cases)
-         IF( ln_isfcav ) THEN   ;  CALL lbc_lnk( 'zdfphy', rCdU_top, 'T', 1.0_wp , rCdU_bot, 'T', 1.0_wp )   ! top & bot drag
-         ELSE                   ;  CALL lbc_lnk( 'zdfphy', rCdU_bot, 'T', 1.0_wp )                       ! bottom drag only
-         ENDIF
-      ENDIF
-      !
-      CALL zdf_mxl( kt, Kmm )                        !* mixed layer depth, and level
-      !
-      IF( lrst_oce ) THEN                       !* write TKE, GLS or RIC fields in the restart file
-         IF( ln_zdftke )   CALL tke_rst( kt, 'WRITE' )
-         IF( ln_zdfgls )   CALL gls_rst( kt, 'WRITE' )
-         IF( ln_zdfric )   CALL ric_rst( kt, 'WRITE' )
-         ! NB. OSMOSIS restart (osm_rst) will be called in step.F90 after ww has been updated
+      IF(nn_hls==1) THEN
+         IF( l_zdfsh2 ) THEN
+            CALL lbc_lnk( 'zdfphy', avm_k, 'W', 1.0_wp , avt_k, 'W', 1.0_wp,   &
+                  &                 avm  , 'W', 1.0_wp , avt  , 'W', 1.0_wp , avs , 'W', 1.0_wp )
+         ELSE
+            CALL lbc_lnk( 'zdfphy', avm  , 'W', 1.0_wp , avt  , 'W', 1.0_wp , avs , 'W', 1.0_wp )
+         ENDIF
+         !
+         IF( l_zdfdrg ) THEN     ! drag  have been updated (non-linear cases)
+            IF( ln_isfcav ) THEN   ;  CALL lbc_lnk( 'zdfphy', rCdU_top, 'T', 1.0_wp , rCdU_bot, 'T', 1.0_wp )   ! top & bot drag
+            ELSE                   ;  CALL lbc_lnk( 'zdfphy', rCdU_bot, 'T', 1.0_wp )                           ! bottom drag only
+            ENDIF
+         ENDIF
+      ENDIF
+      !
+      CALL zdf_mxl_turb( kt, Kmm )                   !* turbocline depth
+      !
+      IF( .NOT. l_istiled .OR. ntile == nijtile ) THEN                       ! Do only on the last tile
+         IF( lrst_oce ) THEN                       !* write TKE, GLS or RIC fields in the restart file
+            IF( ln_zdftke )   CALL tke_rst( kt, 'WRITE' )
+            IF( ln_zdfgls )   CALL gls_rst( kt, 'WRITE' )
+            IF( ln_zdfric )   CALL ric_rst( kt, 'WRITE' )
+            ! NB. OSMOSIS restart (osm_rst) will be called in step.F90 after ww has been updated
+         ENDIF
       ENDIF
       !
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfric.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfric.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfric.F90	(revision 14852)
@@ -145,16 +145,16 @@
       !!              PFJ Lermusiaux 2001.
       !!----------------------------------------------------------------------
-      INTEGER                   , INTENT(in   ) ::   kt             ! ocean time-step
-      INTEGER                   , INTENT(in   ) ::   Kmm            ! ocean time level index
-      REAL(wp), DIMENSION(:,:,:), INTENT(in   ) ::   p_sh2          ! shear production term
-      REAL(wp), DIMENSION(:,:,:), INTENT(inout) ::   p_avm, p_avt   ! momentum and tracer Kz (w-points)
+      INTEGER                             , INTENT(in   ) ::   kt             ! ocean time-step
+      INTEGER                             , INTENT(in   ) ::   Kmm            ! ocean time level index
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(in   ) ::   p_sh2          ! shear production term
+      REAL(wp), DIMENSION(:,:,:)          , INTENT(inout) ::   p_avm, p_avt   ! momentum and tracer Kz (w-points)
       !!
       INTEGER  ::   ji, jj, jk                  ! dummy loop indices
       REAL(wp) ::   zcfRi, zav, zustar, zhek    ! local scalars
-      REAL(wp), DIMENSION(jpi,jpj) ::   zh_ekm  ! 2D workspace
+      REAL(wp), DIMENSION(A2D(nn_hls)) ::   zh_ekm  ! 2D workspace
       !!----------------------------------------------------------------------
       !
       !                       !==  avm and avt = F(Richardson number)  ==!
-      DO_3D( 1, 0, 1, 0, 2, jpkm1 )       ! coefficient = F(richardson number) (avm-weighted Ri)
+      DO_3D_OVR( nn_hls, nn_hls-1, nn_hls, nn_hls-1, 2, jpkm1 )       ! coefficient = F(richardson number) (avm-weighted Ri)
          zcfRi = 1._wp / (  1._wp + rn_alp * MAX(  0._wp , avm(ji,jj,jk) * rn2(ji,jj,jk) / ( p_sh2(ji,jj,jk) + 1.e-20 ) )  )
          zav   = rn_avmri * zcfRi**nn_ric
@@ -169,10 +169,10 @@
       IF( ln_mldw ) THEN      !==  set a minimum value in the Ekman layer  ==!
          !
-         DO_2D( 0, 0, 0, 0 )             !* Ekman depth
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 ) 
             zustar = SQRT( taum(ji,jj) * r1_rho0 )
             zhek   = rn_ekmfc * zustar / ( ABS( ff_t(ji,jj) ) + rsmall )   ! Ekman depth
             zh_ekm(ji,jj) = MAX(  rn_mldmin , MIN( zhek , rn_mldmax )  )   ! set allowed range
          END_2D
-         DO_3D( 0, 0, 0, 0, 2, jpkm1 )   !* minimum mixing coeff. within the Ekman layer
+         DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )   !* minimum mixing coeff. within the Ekman layer
             IF( gdept(ji,jj,jk,Kmm) < zh_ekm(ji,jj) ) THEN
                p_avm(ji,jj,jk) = MAX(  p_avm(ji,jj,jk), rn_wvmix  ) * wmask(ji,jj,jk)
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfsh2.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfsh2.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfsh2.F90	(revision 14852)
@@ -55,15 +55,15 @@
       !! References :   Bruchard, OM 2002
       !! ---------------------------------------------------------------------
-      INTEGER                    , INTENT(in   ) ::   Kbb, Kmm             ! ocean time level indices
-      REAL(wp), DIMENSION(:,:,:) , INTENT(in   ) ::   p_avm                ! vertical eddy viscosity (w-points)
-      REAL(wp), DIMENSION(:,:,:) , INTENT(  out) ::   p_sh2                ! shear production of TKE (w-points)
+      INTEGER                              , INTENT(in   ) ::   Kbb, Kmm             ! ocean time level indices
+      REAL(wp), DIMENSION(:,:,:)           , INTENT(in   ) ::   p_avm                ! vertical eddy viscosity (w-points)
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) , INTENT(  out) ::   p_sh2                ! shear production of TKE (w-points)
       !
       INTEGER  ::   ji, jj, jk   ! dummy loop arguments
-      REAL(wp), DIMENSION(jpi,jpj) ::   zsh2u, zsh2v   ! 2D workspace
+      REAL(wp), DIMENSION(A2D(nn_hls)) ::   zsh2u, zsh2v   ! 2D workspace
       !!--------------------------------------------------------------------
       !
       DO jk = 2, jpkm1                 !* Shear production at uw- and vw-points (energy conserving form)
          IF ( cpl_sdrftx .AND. ln_stshear )  THEN       ! Surface Stokes Drift available  ===>>>  shear + stokes drift contibution
-            DO_2D( 1, 0, 1, 0 )
+            DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )
                zsh2u(ji,jj) = ( p_avm(ji+1,jj,jk) + p_avm(ji,jj,jk) )        &
                   &         * ( uu (ji,jj,jk-1,Kmm) -   uu (ji,jj,jk,Kmm)    &
@@ -78,5 +78,5 @@
             END_2D
          ELSE
-            DO_2D( 1, 0, 1, 0 )     !* 2 x shear production at uw- and vw-points (energy conserving form)
+            DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )     !* 2 x shear production at uw- and vw-points (energy conserving form)
                zsh2u(ji,jj) = ( p_avm(ji+1,jj,jk) + p_avm(ji,jj,jk) ) &
                   &         * (   uu(ji,jj,jk-1,Kmm) -   uu(ji,jj,jk,Kmm) ) &
@@ -91,5 +91,5 @@
             END_2D
          ENDIF
-         DO_2D( 0, 0, 0, 0 )     !* shear production at w-point ! coast mask: =2 at the coast ; =1 otherwise (NB: wmask useless as zsh2 are masked)
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )     !* shear production at w-point ! coast mask: =2 at the coast ; =1 otherwise (NB: wmask useless as zsh2 are masked)
             p_sh2(ji,jj,jk) = 0.25 * (   ( zsh2u(ji-1,jj) + zsh2u(ji,jj) ) * ( 2. - umask(ji-1,jj,jk) * umask(ji,jj,jk) )   &
                &                       + ( zsh2v(ji,jj-1) + zsh2v(ji,jj) ) * ( 2. - vmask(ji,jj-1,jk) * vmask(ji,jj,jk) )   )
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfswm.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfswm.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdfswm.F90	(revision 14852)
@@ -63,5 +63,5 @@
       !
       zcoef = 1._wp * 0.353553_wp
-      DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+      DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
          zqb = zcoef * hsw(ji,jj) * tsd2d(ji,jj) * EXP( -3. * wnum(ji,jj) * gdepw(ji,jj,jk,Kmm) ) * wmask(ji,jj,jk)
          !
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdftke.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdftke.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/ZDF/zdftke.F90	(revision 14852)
@@ -168,8 +168,8 @@
       !!              Bruchard OM 2002
       !!----------------------------------------------------------------------
-      INTEGER                   , INTENT(in   ) ::   kt             ! ocean time step
-      INTEGER                   , INTENT(in   ) ::   Kbb, Kmm       ! ocean time level indices
-      REAL(wp), DIMENSION(:,:,:), INTENT(in   ) ::   p_sh2          ! shear production term
-      REAL(wp), DIMENSION(:,:,:), INTENT(inout) ::   p_avm, p_avt   !  momentum and tracer Kz (w-points)
+      INTEGER                             , INTENT(in   ) ::   kt             ! ocean time step
+      INTEGER                             , INTENT(in   ) ::   Kbb, Kmm       ! ocean time level indices
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(in   ) ::   p_sh2          ! shear production term
+      REAL(wp), DIMENSION(:,:,:)          , INTENT(inout) ::   p_avm, p_avt   !  momentum and tracer Kz (w-points)
       !!----------------------------------------------------------------------
       !
@@ -201,7 +201,7 @@
       USE zdf_oce , ONLY : en   ! ocean vertical physics
       !!
-      INTEGER                    , INTENT(in   ) ::   Kbb, Kmm       ! ocean time level indices
-      REAL(wp), DIMENSION(:,:,:) , INTENT(in   ) ::   p_sh2          ! shear production term
-      REAL(wp), DIMENSION(:,:,:) , INTENT(in   ) ::   p_avm, p_avt   ! vertical eddy viscosity & diffusivity (w-points)
+      INTEGER                              , INTENT(in   ) ::   Kbb, Kmm       ! ocean time level indices
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) , INTENT(in   ) ::   p_sh2          ! shear production term
+      REAL(wp), DIMENSION(:,:,:)           , INTENT(in   ) ::   p_avm, p_avt   ! vertical eddy viscosity & diffusivity (w-points)
       !
       INTEGER ::   ji, jj, jk                  ! dummy loop arguments
@@ -216,7 +216,7 @@
       REAL(wp) ::   zzd_up, zzd_lw             !   -      -
       REAL(wp) ::   ztaui, ztauj, z1_norm
-      INTEGER , DIMENSION(jpi,jpj)     ::   imlc
-      REAL(wp), DIMENSION(jpi,jpj)     ::   zice_fra, zhlc, zus3, zWlc2
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zpelc, zdiag, zd_up, zd_lw
+      INTEGER , DIMENSION(A2D(nn_hls))     ::   imlc
+      REAL(wp), DIMENSION(A2D(nn_hls))     ::   zice_fra, zhlc, zus3, zWlc2
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zpelc, zdiag, zd_up, zd_lw
       !!--------------------------------------------------------------------
       !
@@ -232,7 +232,7 @@
       SELECT CASE ( nn_eice )
       CASE( 0 )   ;   zice_fra(:,:) = 0._wp
-      CASE( 1 )   ;   zice_fra(:,:) =        TANH( fr_i(:,:) * 10._wp )
-      CASE( 2 )   ;   zice_fra(:,:) =              fr_i(:,:)
-      CASE( 3 )   ;   zice_fra(:,:) = MIN( 4._wp * fr_i(:,:) , 1._wp )
+      CASE( 1 )   ;   zice_fra(:,:) =        TANH( fr_i(A2D(nn_hls)) * 10._wp )
+      CASE( 2 )   ;   zice_fra(:,:) =              fr_i(A2D(nn_hls))
+      CASE( 3 )   ;   zice_fra(:,:) = MIN( 4._wp * fr_i(A2D(nn_hls)) , 1._wp )
       END SELECT
       !
@@ -241,5 +241,5 @@
       !                     !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
       !
-      DO_2D( 0, 0, 0, 0 )
+      DO_2D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
          en(ji,jj,1) = MAX( rn_emin0, zbbrau * taum(ji,jj) )
          zdiag(ji,jj,1) = 1._wp/en(ji,jj,1)
@@ -258,5 +258,5 @@
       IF( .NOT.ln_drg_OFF ) THEN    !== friction used as top/bottom boundary condition on TKE
          !
-         DO_2D( 0, 0, 0, 0 )        ! bottom friction
+         DO_2D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )        ! bottom friction
             zmsku = ( 2. - umask(ji-1,jj,mbkt(ji,jj)) * umask(ji,jj,mbkt(ji,jj)) )
             zmskv = ( 2. - vmask(ji,jj-1,mbkt(ji,jj)) * vmask(ji,jj,mbkt(ji,jj)) )
@@ -267,5 +267,5 @@
          END_2D
          IF( ln_isfcav ) THEN
-            DO_2D( 0, 0, 0, 0 )     ! top friction
+            DO_2D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )     ! top friction
                zmsku = ( 2. - umask(ji-1,jj,mikt(ji,jj)) * umask(ji,jj,mikt(ji,jj)) )
                zmskv = ( 2. - vmask(ji,jj-1,mikt(ji,jj)) * vmask(ji,jj,mikt(ji,jj)) )
@@ -294,5 +294,5 @@
 !!gm  ! PS: currently we don't have neither the 2 stress components at t-point !nor the angle between u* and u_s
 !!gm  ! so we will overestimate the LC velocity....   !!gm I will do the work if !LC have an effect !
-            DO_2D( 0, 0, 0, 0 )
+            DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
 !!XC                  zWlc2(ji,jj) = 0.5_wp * SQRT( taum(ji,jj) * r1_rho0 * ( ut0sd(ji,jj)**2 +vt0sd(ji,jj)**2 )  )
                   zWlc2(ji,jj) = 0.5_wp *  ( ut0sd(ji,jj)**2 +vt0sd(ji,jj)**2 )
@@ -301,5 +301,5 @@
 !  Projection of Stokes drift in the wind stress direction
 !
-            DO_2D( 0, 0, 0, 0 )
+            DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
                   ztaui   = 0.5_wp * ( utau(ji,jj) + utau(ji-1,jj) )
                   ztauj   = 0.5_wp * ( vtau(ji,jj) + vtau(ji,jj-1) )
@@ -307,6 +307,4 @@
                   zWlc2(ji,jj) = 0.5_wp * z1_norm * ( MAX( ut0sd(ji,jj)*ztaui + vt0sd(ji,jj)*ztauj, 0._wp ) )**2
             END_2D
-         CALL lbc_lnk      ( 'zdftke', zWlc2, 'T', 1. )
-!
          ELSE                          ! Surface Stokes drift deduced from surface stress
             !                                ! Wlc = u_s   with u_s = 0.016*U_10m, the surface stokes drift  (Axell 2002, Eq.44)
@@ -315,5 +313,5 @@
             !                                ! 1/2 Wlc^2 = 0.5 * 0.016 * 0.016 |tau| /( rho_air Cdrag )
             zcof = 0.5 * 0.016 * 0.016 / ( zrhoa * zcdrag )      ! to convert stress in 10m wind using a constant drag
-            DO_2D( 1, 1, 1, 1 )
+            DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
                zWlc2(ji,jj) = zcof * taum(ji,jj)
             END_2D
@@ -323,26 +321,28 @@
          !                       !* Depth of the LC circulation  (Axell 2002, Eq.47)
          !                             !- LHS of Eq.47
-         zpelc(:,:,1) =  MAX( rn2b(:,:,1), 0._wp ) * gdepw(:,:,1,Kmm) * e3w(:,:,1,Kmm)
-         DO jk = 2, jpk
-            zpelc(:,:,jk)  = zpelc(:,:,jk-1) +   &
-               &        MAX( rn2b(:,:,jk), 0._wp ) * gdepw(:,:,jk,Kmm) * e3w(:,:,jk,Kmm)
-         END DO
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
+            zpelc(ji,jj,1) =  MAX( rn2b(ji,jj,1), 0._wp ) * gdepw(ji,jj,1,Kmm) * e3w(ji,jj,1,Kmm)
+         END_2D
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpk )
+            zpelc(ji,jj,jk)  = zpelc(ji,jj,jk-1) +   &
+               &          MAX( rn2b(ji,jj,jk), 0._wp ) * gdepw(ji,jj,jk,Kmm) * e3w(ji,jj,jk,Kmm)
+         END_3D
          !
          !                             !- compare LHS to RHS of Eq.47
-         imlc(:,:) = mbkt(:,:) + 1       ! Initialization to the number of w ocean point (=2 over land)
-         DO_3DS( 1, 1, 1, 1, jpkm1, 2, -1 )
+         imlc(:,:) = mbkt(A2D(nn_hls)) + 1       ! Initialization to the number of w ocean point (=2 over land)
+         DO_3DS( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, jpkm1, 2, -1 )
             IF( zpelc(ji,jj,jk) > zWlc2(ji,jj) )   imlc(ji,jj) = jk
          END_3D
          !                               ! finite LC depth
-         DO_2D( 1, 1, 1, 1 )
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
             zhlc(ji,jj) = gdepw(ji,jj,imlc(ji,jj),Kmm)
          END_2D
          !
          zcof = 0.016 / SQRT( zrhoa * zcdrag )
-         DO_2D( 0, 0, 0, 0 )
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
             zus = SQRT( 2. * zWlc2(ji,jj) )             ! Stokes drift
             zus3(ji,jj) = MAX( 0._wp, 1._wp - zice_fra(ji,jj) ) * zus * zus * zus * tmask(ji,jj,1) ! zus > 0. ok
          END_2D
-         DO_3D( 0, 0, 0, 0, 2, jpkm1 )                  !* TKE Langmuir circulation source term added to en
+         DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )                  !* TKE Langmuir circulation source term added to en
             IF ( zus3(ji,jj) /= 0._wp ) THEN
                IF ( gdepw(ji,jj,jk,Kmm) - zhlc(ji,jj) < 0 .AND. wmask(ji,jj,jk) /= 0. ) THEN
@@ -365,5 +365,5 @@
       !
       IF( nn_pdl == 1 ) THEN          !* Prandtl number = F( Ri )
-         DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+         DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
             !                             ! local Richardson number
             IF (rn2b(ji,jj,jk) <= 0.0_wp) then
@@ -377,5 +377,5 @@
       ENDIF
       !
-      DO_3D( 0, 0, 0, 0, 2, jpkm1 )   !* Matrix and right hand side in en
+      DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )   !* Matrix and right hand side in en
          zcof   = zfact1 * tmask(ji,jj,jk)
          !                                   ! A minimum of 2.e-5 m2/s is imposed on TKE vertical
@@ -406,5 +406,5 @@
 
          CASE ( 0 ) ! Dirichlet BC
-            DO_2D( 0, 0, 0, 0 )    ! en(1)   = rn_ebb taum / rho0  (min value rn_emin0)
+            DO_2D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )    ! en(1)   = rn_ebb taum / rho0  (min value rn_emin0)
                IF ( phioc(ji,jj) < 0 )  phioc(ji,jj) = 0._wp
                en(ji,jj,1) = MAX( rn_emin0, .5 * ( 15.8 * phioc(ji,jj) / rho0 )**(2./3.) )  * tmask(ji,jj,1)
@@ -413,5 +413,5 @@
 
          CASE ( 1 ) ! Neumann BC
-            DO_2D( 0, 0, 0, 0 )
+            DO_2D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
                IF ( phioc(ji,jj) < 0 )  phioc(ji,jj) = 0._wp
                en(ji,jj,2)    = en(ji,jj,2) + ( rn_Dt * phioc(ji,jj) / rho0 ) /e3w(ji,jj,2,Kmm)
@@ -427,5 +427,5 @@
       !
       !                          !* Matrix inversion from level 2 (tke prescribed at level 1)
-      DO_3D( 0, 0, 0, 0, 2, jpkm1 )                ! First recurrence : Dk = Dk - Lk * Uk-1 / Dk-1
+      DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )                ! First recurrence : Dk = Dk - Lk * Uk-1 / Dk-1
          zdiag(ji,jj,jk) = zdiag(ji,jj,jk) - zd_lw(ji,jj,jk) * zd_up(ji,jj,jk-1) / zdiag(ji,jj,jk-1)
       END_3D
@@ -434,14 +434,14 @@
 !         zd_lw(ji,jj,2) = en(ji,jj,2) - zd_lw(ji,jj,2) * en(ji,jj,1)    ! Surface boudary conditions on tke
 !      END_2D
-      DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+      DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
          zd_lw(ji,jj,jk) = en(ji,jj,jk) - zd_lw(ji,jj,jk) / zdiag(ji,jj,jk-1) *zd_lw(ji,jj,jk-1)
       END_3D
-      DO_2D( 0, 0, 0, 0 )                          ! thrid recurrence : Ek = ( Lk - Uk * Ek+1 ) / Dk
+      DO_2D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )                          ! thrid recurrence : Ek = ( Lk - Uk * Ek+1 ) / Dk
          en(ji,jj,jpkm1) = zd_lw(ji,jj,jpkm1) / zdiag(ji,jj,jpkm1)
       END_2D
-      DO_3DS( 0, 0, 0, 0, jpk-2, 2, -1 )
+      DO_3DS_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, jpk-2, 2, -1 )
          en(ji,jj,jk) = ( zd_lw(ji,jj,jk) - zd_up(ji,jj,jk) * en(ji,jj,jk+1) ) / zdiag(ji,jj,jk)
       END_3D
-      DO_3D( 0, 0, 0, 0, 2, jpkm1 )                ! set the minimum value of tke
+      DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )                ! set the minimum value of tke
          en(ji,jj,jk) = MAX( en(ji,jj,jk), rn_emin ) * wmask(ji,jj,jk)
       END_3D
@@ -456,10 +456,10 @@
       !
       IF( nn_etau == 1 ) THEN           !* penetration below the mixed layer (rn_efr fraction)
-         DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+         DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
             en(ji,jj,jk) = en(ji,jj,jk) + rn_efr * en(ji,jj,1) * EXP( -gdepw(ji,jj,jk,Kmm) / htau(ji,jj) )   &
                &                                 * MAX( 0._wp, 1._wp - zice_fra(ji,jj) ) * wmask(ji,jj,jk) * tmask(ji,jj,1)
          END_3D
       ELSEIF( nn_etau == 2 ) THEN       !* act only at the base of the mixed layer (jk=nmln)  (rn_efr fraction)
-         DO_2D( 0, 0, 0, 0 )
+         DO_2D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
             jk = nmln(ji,jj)
             en(ji,jj,jk) = en(ji,jj,jk) + rn_efr * en(ji,jj,1) * EXP( -gdepw(ji,jj,jk,Kmm) / htau(ji,jj) )   &
@@ -467,5 +467,5 @@
          END_2D
       ELSEIF( nn_etau == 3 ) THEN       !* penetration belox the mixed layer (HF variability)
-         DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+         DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
             ztx2 = utau(ji-1,jj  ) + utau(ji,jj)
             zty2 = vtau(ji  ,jj-1) + vtau(ji,jj)
@@ -524,5 +524,5 @@
       REAL(wp) ::   zdku,   zdkv, zsqen       !   -      -
       REAL(wp) ::   zemxl, zemlm, zemlp, zmaxice       !   -      -
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zmxlm, zmxld   ! 3D workspace
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zmxlm, zmxld   ! 3D workspace
       !!--------------------------------------------------------------------
       !
@@ -548,5 +548,5 @@
             zraug = vkarmn * 2.e5_wp / ( rho0 * grav )
 #if ! defined key_si3 && ! defined key_cice
-            DO_2D( 0, 0, 0, 0 )                  ! No sea-ice
+            DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )                  ! No sea-ice
                zmxlm(ji,jj,1) =  zraug * taum(ji,jj) * tmask(ji,jj,1)
             END_2D
@@ -555,10 +555,10 @@
             !
             CASE( 0 )                      ! No scaling under sea-ice
-               DO_2D( 0, 0, 0, 0 )
+               DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
                   zmxlm(ji,jj,1) = zraug * taum(ji,jj) * tmask(ji,jj,1)
                END_2D
                !
             CASE( 1 )                      ! scaling with constant sea-ice thickness
-               DO_2D( 0, 0, 0, 0 )
+               DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
                   zmxlm(ji,jj,1) =  ( ( 1._wp - fr_i(ji,jj) ) * zraug * taum(ji,jj) + &
                      &                          fr_i(ji,jj)   * rn_mxlice           ) * tmask(ji,jj,1)
@@ -566,5 +566,5 @@
                !
             CASE( 2 )                      ! scaling with mean sea-ice thickness
-               DO_2D( 0, 0, 0, 0 )
+               DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
 #if defined key_si3
                   zmxlm(ji,jj,1) = ( ( 1._wp - fr_i(ji,jj) ) * zraug * taum(ji,jj) + &
@@ -578,5 +578,5 @@
                !
             CASE( 3 )                      ! scaling with max sea-ice thickness
-               DO_2D( 0, 0, 0, 0 )
+               DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
                   zmaxice = MAXVAL( h_i(ji,jj,:) )
                   zmxlm(ji,jj,1) = ( ( 1._wp - fr_i(ji,jj) ) * zraug * taum(ji,jj) + &
@@ -587,5 +587,5 @@
 #endif
             !
-            DO_2D( 0, 0, 0, 0 )
+            DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
                zmxlm(ji,jj,1) = MAX( rn_mxl0, zmxlm(ji,jj,1) )
             END_2D
@@ -596,5 +596,5 @@
       ENDIF
       !
-      DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+      DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
          zrn2 = MAX( rn2(ji,jj,jk), rsmall )
          zmxlm(ji,jj,jk) = MAX(  rmxl_min,  SQRT( 2._wp * en(ji,jj,jk) / zrn2 )  )
@@ -611,5 +611,5 @@
       ! where wmask = 0 set zmxlm == e3w(:,:,:,Kmm)
       CASE ( 0 )           ! bounded by the distance to surface and bottom
-         DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
             zemxl = MIN( gdepw(ji,jj,jk,Kmm) - gdepw(ji,jj,mikt(ji,jj),Kmm), zmxlm(ji,jj,jk),   &
             &            gdepw(ji,jj,mbkt(ji,jj)+1,Kmm) - gdepw(ji,jj,jk,Kmm) )
@@ -622,5 +622,5 @@
          !
       CASE ( 1 )           ! bounded by the vertical scale factor
-         DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
             zemxl = MIN( e3w(ji,jj,jk,Kmm), zmxlm(ji,jj,jk) )
             zmxlm(ji,jj,jk) = zemxl
@@ -629,9 +629,9 @@
          !
       CASE ( 2 )           ! |dk[xml]| bounded by e3t :
-         DO_3D( 0, 0, 0, 0, 2, jpkm1 )        ! from the surface to the bottom :
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )       ! from the surface to the bottom :
             zmxlm(ji,jj,jk) =   &
                &    MIN( zmxlm(ji,jj,jk-1) + e3t(ji,jj,jk-1,Kmm), zmxlm(ji,jj,jk) )
          END_3D
-         DO_3DS( 0, 0, 0, 0, jpkm1, 2, -1 )   ! from the bottom to the surface :
+         DO_3DS( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, jpkm1, 2, -1 )   ! from the bottom to the surface :
             zemxl = MIN( zmxlm(ji,jj,jk+1) + e3t(ji,jj,jk+1,Kmm), zmxlm(ji,jj,jk) )
             zmxlm(ji,jj,jk) = zemxl
@@ -640,13 +640,13 @@
          !
       CASE ( 3 )           ! lup and ldown, |dk[xml]| bounded by e3t :
-         DO_3D( 0, 0, 0, 0, 2, jpkm1 )        ! from the surface to the bottom : lup
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )        ! from the surface to the bottom : lup
             zmxld(ji,jj,jk) =    &
                &    MIN( zmxld(ji,jj,jk-1) + e3t(ji,jj,jk-1,Kmm), zmxlm(ji,jj,jk) )
          END_3D
-         DO_3DS( 0, 0, 0, 0, jpkm1, 2, -1 )   ! from the bottom to the surface : ldown
+         DO_3DS( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, jpkm1, 2, -1 )   ! from the bottom to the surface : ldown
             zmxlm(ji,jj,jk) =   &
                &    MIN( zmxlm(ji,jj,jk+1) + e3t(ji,jj,jk+1,Kmm), zmxlm(ji,jj,jk) )
          END_3D
-         DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
             zemlm = MIN ( zmxld(ji,jj,jk),  zmxlm(ji,jj,jk) )
             zemlp = SQRT( zmxld(ji,jj,jk) * zmxlm(ji,jj,jk) )
@@ -660,5 +660,5 @@
       !                     !  Vertical eddy viscosity and diffusivity  (avm and avt)
       !                     !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
-      DO_3D( 0, 0, 0, 0, 1, jpkm1 )   !* vertical eddy viscosity & diffivity at w-points
+      DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpkm1 )   !* vertical eddy viscosity & diffivity at w-points
          zsqen = SQRT( en(ji,jj,jk) )
          zav   = rn_ediff * zmxlm(ji,jj,jk) * zsqen
@@ -670,5 +670,5 @@
       !
       IF( nn_pdl == 1 ) THEN          !* Prandtl number case: update avt
-         DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+         DO_3D_OVR( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 2, jpkm1 )
             p_avt(ji,jj,jk)   = MAX( apdlr(ji,jj,jk) * p_avt(ji,jj,jk), avtb_2d(ji,jj) * avtb(jk) ) * wmask(ji,jj,jk)
          END_3D
@@ -786,7 +786,7 @@
       !
       !                               !* Check of some namelist values
-      IF( nn_mxl  < 0   .OR.  nn_mxl  > 3 )   CALL ctl_stop( 'bad flag: nn_mxl is  0, 1 or 2 ' )
-      IF( nn_pdl  < 0   .OR.  nn_pdl  > 1 )   CALL ctl_stop( 'bad flag: nn_pdl is  0 or 1    ' )
-      IF( nn_htau < 0   .OR.  nn_htau > 1 )   CALL ctl_stop( 'bad flag: nn_htau is 0, 1 or 2 ' )
+      IF( nn_mxl  < 0   .OR.  nn_mxl  > 3 )   CALL ctl_stop( 'bad flag: nn_mxl is  0, 1, 2 or 3' )
+      IF( nn_pdl  < 0   .OR.  nn_pdl  > 1 )   CALL ctl_stop( 'bad flag: nn_pdl is  0 or 1' )
+      IF( nn_htau < 0   .OR.  nn_htau > 1 )   CALL ctl_stop( 'bad flag: nn_htau is 0 or 1' )
       IF( nn_etau == 3 .AND. .NOT. ln_cpl )   CALL ctl_stop( 'nn_etau == 3 : HF taum only known in coupled mode' )
       !
@@ -796,7 +796,4 @@
          rn_mxl0 = rmxl_min
       ENDIF
-
-      IF( nn_etau == 2  )   CALL zdf_mxl( nit000, Kmm )      ! Initialization of nmln
-
       !                               !* depth of penetration of surface tke
       IF( nn_etau /= 0 ) THEN
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/do_loop_substitute.h90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/do_loop_substitute.h90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/do_loop_substitute.h90	(revision 14852)
@@ -59,5 +59,6 @@
 #endif
 
-#define DO_2D(L, R, B, T) DO jj = ntsj-(B), ntej+(T)   ;   DO ji = ntsi-(L), ntei+(R)
+#define DO_2D(L, R, B, T) DO jj = ntsj-(B), ntej+(T) ; DO ji = ntsi-(L), ntei+(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
@@ -70,7 +71,9 @@
 #define KJPT  :
 
-#define DO_3D(L, R, B, T, ks, ke) DO jk = ks, ke   ;   DO_2D(L, R, B, T)
+#define DO_3D(L, R, B, T, ks, ke) DO jk = ks, ke ; DO_2D(L, R, B, T)
+#define DO_3D_OVR(L, R, B, T, ks, ke) DO jk = ks, ke ; DO_2D_OVR(L, R, B, T)
 
-#define DO_3DS(L, R, B, T, ks, ke, ki) DO jk = ks, ke, ki   ;   DO_2D(L, R, B, T)
+#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_2D   END DO   ;   END DO
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/module_example.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/module_example.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/module_example.F90	(revision 14852)
@@ -102,5 +102,5 @@
       !!--------------------------------------------------------------------
       !
-      IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+      IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
          IF( kt == nit000  )   CALL exa_mpl_init    ! Initialization (first time-step only)
 
@@ -175,5 +175,5 @@
       IF( exa_mpl_alloc() /= 0 )   CALL ctl_stop( 'STOP', 'exa_mpl_init : unable to allocate arrays' )
       !                              ! Parameter control
-      IF( ln_tile .AND. ntile > 0 ) CALL ctl_stop( 'exa_mpl_init: tiling is not supported in this module by default, see manual for how to adapt your code' )
+      IF( ln_tile ) CALL ctl_stop( 'exa_mpl_init: tiling is not supported in this module by default, see manual for how to adapt your code' )
       IF( ln_opt      )   CALL ctl_stop( 'exa_mpl_init: this work and option xxx are incompatible'   )
       IF( nn_opt == 2 )   CALL ctl_stop( 'STOP',  'exa_mpl_init: this work and option yyy may cause problems'  )
@@ -187,5 +187,6 @@
 CONTAINS
    SUBROUTINE exa_mpl( kt, pvar1, pvar2, ptab )              ! Empty routine
-      REAL::   ptab(:,:)
+      INTEGER :: kt
+      REAL::   pvar1, pvar2, ptab(:,:)
       WRITE(*,*) 'exa_mpl: You should not have seen this print! error?', kt, pvar1, pvar2, ptab(1,1)
    END SUBROUTINE exa_mpl
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/nemogcm.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/nemogcm.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/nemogcm.F90	(revision 14852)
@@ -390,4 +390,10 @@
       CALL mpp_init
 
+#if defined key_loop_fusion
+      IF( nn_hls == 1 ) THEN
+         CALL ctl_stop( 'STOP', 'nemogcm : Loop fusion can be used only with extra-halo' )
+      ENDIF
+#endif
+
       CALL halo_mng_init()
       ! Now we know the dimensions of the grid and numout has been set: we can allocate arrays
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/par_oce.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/par_oce.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/par_oce.F90	(revision 14852)
@@ -72,4 +72,6 @@
    INTEGER, PUBLIC ::   ntei       !: end of internal part of tile domain
    INTEGER, PUBLIC ::   ntej       !
+   INTEGER, PUBLIC ::   nthl, nthr !: Modifier on DO loop macro bound offset (left, right)
+   INTEGER, PUBLIC ::   nthb, ntht !:              "         "               (bottom, top)
 
    !!---------------------------------------------------------------------
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/step.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/step.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/step.F90	(revision 14852)
@@ -174,5 +174,14 @@
 
       !  VERTICAL PHYSICS
+      ! lbc_lnk needed for zdf_sh2 when using nn_hls = 2, moved here to allow tiling in zdf_phy
+      IF( nn_hls == 2 .AND. l_zdfsh2 ) CALL lbc_lnk( 'stp', avm_k, 'W', 1.0_wp )
+
+      IF( ln_tile ) CALL dom_tile_start         ! [tiling] ZDF tiling loop
+      DO jtile = 1, nijtile
+         IF( ln_tile ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = jtile )
+
                          CALL zdf_phy( kstp, Nbb, Nnn, Nrhs )   ! vertical physics update (top/bot drag, avt, avs, avm + MLD)
+      END DO
+      IF( ln_tile ) CALL dom_tile_stop
 
       !  LATERAL  PHYSICS
@@ -181,9 +190,9 @@
                          CALL eos( ts(:,:,:,:,Nbb), rhd, gdept_0(:,:,:) )               ! before in situ density
 
-         IF( ln_zps .AND. .NOT. ln_isfcav)                                    &
+      IF( ln_zps .AND. .NOT. ln_isfcav)                                    &
             &            CALL zps_hde    ( kstp, Nnn, jpts, ts(:,:,:,:,Nbb), gtsu, gtsv,  &  ! Partial steps: before horizontal gradient
             &                                          rhd, gru , grv    )       ! of t, s, rd at the last ocean level
 
-         IF( ln_zps .AND.       ln_isfcav)                                                &
+      IF( ln_zps .AND.       ln_isfcav)                                                &
             &            CALL zps_hde_isf( kstp, Nnn, jpts, ts(:,:,:,:,Nbb), gtsu, gtsv, gtui, gtvi,  &  ! Partial steps for top cell (ISF)
             &                                          rhd, gru , grv , grui, grvi   )       ! of t, s, rd at the first ocean level
@@ -213,24 +222,53 @@
                          vv(:,:,:,Nrhs) = 0._wp
 
-      IF(  lk_asminc .AND. ln_asmiau .AND. ln_dyninc )   &
-               &         CALL dyn_asm_inc   ( kstp, Nbb, Nnn, uu, vv, Nrhs )  ! apply dynamics assimilation increment
-      IF( ln_bdy     )   CALL bdy_dyn3d_dmp ( kstp, Nbb,      uu, vv, Nrhs )  ! bdy damping trends
-#if defined key_agrif
+      IF( ln_tile ) CALL dom_tile_start         ! [tiling] DYN tiling loop (1)
+      DO jtile = 1, nijtile
+         IF( ln_tile ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = jtile )
+
+         IF(  lk_asminc .AND. ln_asmiau .AND. ln_dyninc )   &
+                  &         CALL dyn_asm_inc   ( kstp, Nbb, Nnn, uu, vv, Nrhs )  ! apply dynamics assimilation increment
+         IF( ln_bdy     )   CALL bdy_dyn3d_dmp ( kstp, Nbb,      uu, vv, Nrhs )  ! bdy damping trends
+#if defined key_agrif
+      END DO
+      IF( ln_tile ) CALL dom_tile_stop
+
       IF(.NOT. Agrif_Root())  &
                &         CALL Agrif_Sponge_dyn        ! momentum sponge
-#endif
-                         CALL dyn_adv( kstp, Nbb, Nnn      , uu, vv, Nrhs )  ! advection (VF or FF)	==> RHS
-                         CALL dyn_vor( kstp,      Nnn      , uu, vv, Nrhs )  ! vorticity           	==> RHS
-                         CALL dyn_ldf( kstp, Nbb, Nnn      , uu, vv, Nrhs )  ! lateral mixing
-      IF( ln_zdfosm  )   CALL dyn_osm( kstp,      Nnn      , uu, vv, Nrhs )  ! OSMOSIS non-local velocity fluxes ==> RHS
-                         CALL dyn_hpg( kstp,      Nnn      , uu, vv, Nrhs )  ! horizontal gradient of Hydrostatic pressure
-                         CALL dyn_spg( kstp, Nbb, Nnn, Nrhs, uu, vv, ssh, uu_b, vv_b, Naa )  ! surface pressure gradient
+
+      IF( ln_tile ) CALL dom_tile_start         ! [tiling] DYN tiling loop (1, continued)
+      DO jtile = 1, nijtile
+         IF( ln_tile ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = jtile )
+#endif
+                            CALL dyn_adv( kstp, Nbb, Nnn      , uu, vv, Nrhs )  ! advection (VF or FF)	==> RHS
+                            CALL dyn_vor( kstp,      Nnn      , uu, vv, Nrhs )  ! vorticity           	==> RHS
+                            CALL dyn_ldf( kstp, Nbb, Nnn      , uu, vv, Nrhs )  ! lateral mixing
+         IF( ln_zdfosm  )   CALL dyn_osm( kstp,      Nnn      , uu, vv, Nrhs )  ! OSMOSIS non-local velocity fluxes ==> RHS
+                            CALL dyn_hpg( kstp,      Nnn      , uu, vv, Nrhs )  ! horizontal gradient of Hydrostatic pressure
+      END DO
+      IF( ln_tile ) CALL dom_tile_stop
+
+                            CALL dyn_spg( kstp, Nbb, Nnn, Nrhs, uu, vv, ssh, uu_b, vv_b, Naa )  ! surface pressure gradient
 
                                                       ! With split-explicit free surface, since now transports have been updated and ssh(:,:,Nrhs) as well
       IF( ln_dynspg_ts ) THEN                         ! vertical scale factors and vertical velocity need to be updated
-                            CALL div_hor       ( kstp, Nbb, Nnn )                ! Horizontal divergence  (2nd call in time-split case)
-         IF(.NOT.ln_linssh) CALL dom_vvl_sf_nxt( kstp, Nbb, Nnn, Naa, kcall=2 )  ! after vertical scale factors (update depth average component)
-      ENDIF
-                            CALL dyn_zdf    ( kstp, Nbb, Nnn, Nrhs, uu, vv, Naa  )  ! vertical diffusion
+         IF( ln_tile ) CALL dom_tile_start      ! [tiling] DYN tiling loop (2- div_hor only)
+         DO jtile = 1, nijtile
+            IF( ln_tile ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = jtile )
+
+                             CALL div_hor       ( kstp, Nbb, Nnn )               ! Horizontal divergence  (2nd call in time-split case)
+         END DO
+         IF( ln_tile ) CALL dom_tile_stop
+
+         IF(.NOT. ln_linssh) CALL dom_vvl_sf_nxt( kstp, Nbb, Nnn, Naa, kcall=2 )  ! after vertical scale factors (update depth average component)
+      ENDIF
+
+      IF( ln_tile ) CALL dom_tile_start         ! [tiling] DYN tiling loop (3- dyn_zdf only)
+      DO jtile = 1, nijtile
+         IF( ln_tile ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = jtile )
+
+                               CALL dyn_zdf    ( kstp, Nbb, Nnn, Nrhs, uu, vv, Naa  )  ! vertical diffusion
+      END DO
+      IF( ln_tile ) CALL dom_tile_stop
+
       IF( ln_dynspg_ts ) THEN                                                       ! vertical scale factors and vertical velocity need to be updated
                             CALL wzv        ( kstp, Nbb, Nnn, Naa, ww )             ! Nnn cross-level velocity
@@ -268,11 +306,9 @@
       ! Active tracers
       !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
-      ! Loop over tile domains
-      DO jtile = 1, nijtile
-         IF( ln_tile    )   CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = jtile )
-
-         DO_3D( 0, 0, 0, 0, 1, jpk )
-            ts(ji,jj,jk,:,Nrhs) = 0._wp                                   ! set tracer trends to zero
-         END_3D
+                         ts(:,:,:,:,Nrhs) = 0._wp         ! set tracer trends to zero
+
+      IF( ln_tile ) CALL dom_tile_start         ! [tiling] TRA tiling loop (1)
+      DO jtile = 1, nijtile
+         IF( ln_tile ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = jtile )
 
          IF(  lk_asminc .AND. ln_asmiau .AND. &
@@ -286,8 +322,8 @@
          IF( ln_bdy     )   CALL bdy_tra_dmp( kstp, Nbb,      ts, Nrhs )  ! bdy damping trends
       END DO
+      IF( ln_tile ) CALL dom_tile_stop
 
 #if defined key_agrif
       IF(.NOT. Agrif_Root() )   THEN
-         IF( ln_tile    )   CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = 0 )
                             CALL Agrif_Sponge_tra        ! tracers sponge
       ENDIF
@@ -295,6 +331,7 @@
 
       ! TEMP: [tiling] Separate loop over tile domains (due to tra_adv workarounds for tiling)
-      DO jtile = 1, nijtile
-         IF( ln_tile    )   CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = jtile )
+      IF( ln_tile ) CALL dom_tile_start         ! [tiling] TRA tiling loop (2)
+      DO jtile = 1, nijtile
+         IF( ln_tile ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = jtile )
 
                             CALL tra_adv    ( kstp, Nbb, Nnn, ts, Nrhs )  ! hor. + vert. advection	==> RHS
@@ -309,6 +346,6 @@
          IF( ln_zdfnpc  )   CALL tra_npc    ( kstp,      Nnn, Nrhs, ts, Naa  )  ! update after fields by non-penetrative convection
       END DO
-
-      IF( ln_tile ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = 0 ) ! Revert to tile over full domain
+      IF( ln_tile ) CALL dom_tile_stop
+
       !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
       ! Set boundary conditions, time filter and swap time levels
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/stpmlf.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/stpmlf.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/stpmlf.F90	(revision 14852)
@@ -62,5 +62,4 @@
 #  include "do_loop_substitute.h90"
 #  include "domzgr_substitute.h90"
-#  include "do_loop_substitute.h90"
    !!----------------------------------------------------------------------
    !! NEMO/OCE 4.0 , NEMO Consortium (2018)
@@ -182,5 +181,10 @@
 
       !  VERTICAL PHYSICS
+      IF( ln_tile ) CALL dom_tile_start         ! [tiling] ZDF tiling loop
+      DO jtile = 1, nijtile
+         IF( ln_tile ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = jtile )
                          CALL zdf_phy( kstp, Nbb, Nnn, Nrhs )   ! vertical physics update (top/bot drag, avt, avs, avm + MLD)
+      END DO
+      IF( ln_tile ) CALL dom_tile_stop
 
       !  LATERAL  PHYSICS
@@ -189,9 +193,9 @@
                          CALL eos( ts(:,:,:,:,Nbb), rhd, gdept_0(:,:,:) )               ! before in situ density
 
-         IF( ln_zps .AND. .NOT. ln_isfcav)                                    &
+      IF( ln_zps .AND. .NOT. ln_isfcav)                                    &
             &            CALL zps_hde    ( kstp, Nnn, jpts, ts(:,:,:,:,Nbb), gtsu, gtsv,  &  ! Partial steps: before horizontal gradient
             &                                          rhd, gru , grv    )       ! of t, s, rd at the last ocean level
 
-         IF( ln_zps .AND.       ln_isfcav)                                                &
+      IF( ln_zps .AND.       ln_isfcav)                                                &
             &            CALL zps_hde_isf( kstp, Nnn, jpts, ts(:,:,:,:,Nbb), gtsu, gtsv, gtui, gtvi,  &  ! Partial steps for top cell (ISF)
             &                                          rhd, gru , grv , grui, grvi   )       ! of t, s, rd at the first ocean level
@@ -228,24 +232,45 @@
                          vv(:,:,:,Nrhs) = 0._wp
 
-      IF(  lk_asminc .AND. ln_asmiau .AND. ln_dyninc )   &
-               &         CALL dyn_asm_inc   ( kstp, Nbb, Nnn, uu, vv, Nrhs )  ! apply dynamics assimilation increment
-      IF( ln_bdy     )   CALL bdy_dyn3d_dmp ( kstp, Nbb,      uu, vv, Nrhs )  ! bdy damping trends
-#if defined key_agrif
+      IF( ln_tile ) CALL dom_tile_start         ! [tiling] DYN tiling loop (1)
+      DO jtile = 1, nijtile
+         IF( ln_tile ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = jtile )
+
+         IF(  lk_asminc .AND. ln_asmiau .AND. ln_dyninc )   &
+                  &         CALL dyn_asm_inc   ( kstp, Nbb, Nnn, uu, vv, Nrhs )  ! apply dynamics assimilation increment
+         IF( ln_bdy     )   CALL bdy_dyn3d_dmp ( kstp, Nbb,      uu, vv, Nrhs )  ! bdy damping trends
+#if defined key_agrif
+      END DO
+      IF( ln_tile ) CALL dom_tile_stop
+
       IF(.NOT. Agrif_Root())  &
                &         CALL Agrif_Sponge_dyn        ! momentum sponge
-#endif
-                         CALL dyn_adv( kstp, Nbb, Nnn      , uu, vv, Nrhs )  ! advection (VF or FF)	==> RHS
-                         CALL dyn_vor( kstp,      Nnn      , uu, vv, Nrhs )  ! vorticity           	==> RHS
-                         CALL dyn_ldf( kstp, Nbb, Nnn      , uu, vv, Nrhs )  ! lateral mixing
-      IF( ln_zdfosm  )   CALL dyn_osm( kstp,      Nnn      , uu, vv, Nrhs )  ! OSMOSIS non-local velocity fluxes ==> RHS
-                         CALL dyn_hpg( kstp,      Nnn      , uu, vv, Nrhs )  ! horizontal gradient of Hydrostatic pressure
-                         CALL dyn_spg( kstp, Nbb, Nnn, Nrhs, uu, vv, ssh, uu_b, vv_b, Naa )  ! surface pressure gradient
-                         
-      IF( ln_dynspg_ts ) THEN      ! With split-explicit free surface, since now transports have been updated and ssh(:,:,Nrhs)
-                                   ! as well as vertical scale factors and vertical velocity need to be updated
-                            CALL div_hor    ( kstp, Nbb, Nnn )                ! Horizontal divergence  (2nd call in time-split case)
-         IF(.NOT.lk_linssh) CALL dom_qco_r3c( ssh(:,:,Naa), r3t(:,:,Naa), r3u(:,:,Naa), r3v(:,:,Naa), r3f(:,:) )   ! update ssh/h_0 ratio at t,u,v,f pts 
-      ENDIF
+
+      IF( ln_tile ) CALL dom_tile_start         ! [tiling] DYN tiling loop (1, continued)
+      DO jtile = 1, nijtile
+         IF( ln_tile ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = jtile )
+#endif
+                            CALL dyn_adv( kstp, Nbb, Nnn      , uu, vv, Nrhs )  ! advection (VF or FF)	==> RHS
+                            CALL dyn_vor( kstp,      Nnn      , uu, vv, Nrhs )  ! vorticity           	==> RHS
+                            CALL dyn_ldf( kstp, Nbb, Nnn      , uu, vv, Nrhs )  ! lateral mixing
+         IF( ln_zdfosm  )   CALL dyn_osm( kstp,      Nnn      , uu, vv, Nrhs )  ! OSMOSIS non-local velocity fluxes ==> RHS
+                            CALL dyn_hpg( kstp,      Nnn      , uu, vv, Nrhs )  ! horizontal gradient of Hydrostatic pressure
+      END DO
+      IF( ln_tile ) CALL dom_tile_stop
+
+                            CALL dyn_spg( kstp, Nbb, Nnn, Nrhs, uu, vv, ssh, uu_b, vv_b, Naa )  ! surface pressure gradient
+
+      IF( ln_tile ) CALL dom_tile_start         ! [tiling] DYN tiling loop (2)
+      DO jtile = 1, nijtile
+         IF( ln_tile ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = jtile )
+
+         IF( ln_dynspg_ts ) THEN      ! With split-explicit free surface, since now transports have been updated and ssh(:,:,Nrhs)
+                                      ! as well as vertical scale factors and vertical velocity need to be updated
+                            CALL div_hor    ( kstp, Nbb, Nnn )                  ! Horizontal divergence  (2nd call in time-split case)
+            IF(.NOT.lk_linssh) CALL dom_qco_r3c( ssh(:,:,Naa), r3t(:,:,Naa), r3u(:,:,Naa), r3v(:,:,Naa), r3f(:,:) )   ! update ssh/h_0 ratio at t,u,v,f pts
+         ENDIF
                             CALL dyn_zdf    ( kstp, Nbb, Nnn, Nrhs, uu, vv, Naa  )  ! vertical diffusion
+      END DO
+      IF( ln_tile ) CALL dom_tile_stop
+
       IF( ln_dynspg_ts ) THEN                                                       ! vertical scale factors and vertical velocity need to be updated
                             CALL wzv        ( kstp, Nbb, Nnn, Naa, ww )             ! Nnn cross-level velocity
@@ -288,11 +313,9 @@
       ! Active tracers
       !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
-      ! Loop over tile domains
+                         ts(:,:,:,:,Nrhs) = 0._wp         ! set tracer trends to zero
+
+      IF( ln_tile ) CALL dom_tile_start         ! [tiling] TRA tiling loop (1)
       DO jtile = 1, nijtile
-         IF( ln_tile    )   CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = jtile )
-
-         DO_3D( 0, 0, 0, 0, 1, jpk )
-            ts(ji,jj,jk,:,Nrhs) = 0._wp                                   ! set tracer trends to zero
-         END_3D
+         IF( ln_tile ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = jtile )
 
          IF(  lk_asminc .AND. ln_asmiau .AND. &
@@ -306,8 +329,8 @@
          IF( ln_bdy     )   CALL bdy_tra_dmp( kstp, Nbb,      ts, Nrhs )  ! bdy damping trends
       END DO
+      IF( ln_tile ) CALL dom_tile_stop
 
 #if defined key_agrif
       IF(.NOT. Agrif_Root() ) THEN
-         IF( ln_tile    )   CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = 0 )
                             CALL Agrif_Sponge_tra        ! tracers sponge
       ENDIF
@@ -315,6 +338,7 @@
 
       ! TEMP: [tiling] Separate loop over tile domains (due to tra_adv workarounds for tiling)
+      IF( ln_tile ) CALL dom_tile_start         ! [tiling] TRA tiling loop (2)
       DO jtile = 1, nijtile
-         IF( ln_tile    )   CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = jtile )
+         IF( ln_tile ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = jtile )
 
                             CALL tra_adv    ( kstp, Nbb, Nnn, ts, Nrhs )  ! hor. + vert. advection	==> RHS
@@ -329,6 +353,6 @@
          IF( ln_zdfnpc  )   CALL tra_npc    ( kstp,      Nnn, Nrhs, ts, Naa  )  ! update after fields by non-penetrative convection
       END DO
-
-      IF( ln_tile ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = 0 ) ! Revert to tile over full domain
+      IF( ln_tile ) CALL dom_tile_stop
+
       !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
       ! Set boundary conditions, time filter and swap time levels
@@ -516,4 +540,12 @@
                        &          , pts(:,:,:,jp_tem,Kaa), 'T',  1., pts(:,:,:,jp_sal,Kaa), 'T',  1. )
       !
+      ! lbc_lnk needed for zdf_sh2 when using nn_hls = 2, moved here to allow tiling in zdf_phy
+      IF( nn_hls == 2 .AND. l_zdfsh2 ) CALL lbc_lnk( 'stp', avm_k, 'W', 1.0_wp )
+
+      ! dom_qco_r3c defines over [nn_hls, nn_hls-1, nn_hls, nn_hls-1]
+      IF( nn_hls == 2 .AND. .NOT. lk_linssh ) THEN
+         CALL lbc_lnk( 'finalize_lbc', r3u(:,:,Kaa), 'U', 1._wp, r3v(:,:,Kaa), 'V', 1._wp, &
+            &                          r3u_f(:,:),   'U', 1._wp, r3v_f(:,:),   'V', 1._wp )
+      ENDIF
       !                                        !* BDY open boundaries
       IF( ln_bdy )   THEN
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/timing.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/timing.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OCE/timing.F90	(revision 14852)
@@ -109,5 +109,5 @@
 
       s_timer%l_tdone = .FALSE.
-      IF( ntile == 0 .OR. ntile == 1 ) s_timer%niter = s_timer%niter + 1      ! All tiles count as one iteration
+      IF( .NOT. l_istiled .OR. ntile == 1 ) s_timer%niter = s_timer%niter + 1      ! All tiles count as one iteration
       s_timer%t_cpu = 0.
       s_timer%t_clock = 0.
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OFF/nemogcm.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OFF/nemogcm.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/OFF/nemogcm.F90	(revision 14852)
@@ -323,4 +323,10 @@
       CALL mpp_init
 
+#if defined key_loop_fusion
+      IF( nn_hls == 1 ) THEN
+         CALL ctl_stop( 'STOP', 'nemogcm : Loop fusion can be used only with extra-halo' )
+      ENDIF
+#endif
+
       CALL halo_mng_init()
       ! Now we know the dimensions of the grid and numout has been set: we can allocate arrays
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/SAS/nemogcm.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/SAS/nemogcm.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/SAS/nemogcm.F90	(revision 14852)
@@ -352,4 +352,10 @@
       CALL mpp_init
 
+#if defined key_loop_fusion
+      IF( nn_hls == 1 ) THEN
+         CALL ctl_stop( 'STOP', 'nemogcm : Loop fusion can be used only with extra-halo' )
+      ENDIF
+#endif
+
       CALL halo_mng_init()
       ! Now we know the dimensions of the grid and numout has been set: we can allocate arrays
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/SWE/nemogcm.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/SWE/nemogcm.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/SWE/nemogcm.F90	(revision 14852)
@@ -273,4 +273,10 @@
       CALL mpp_init
 
+#if defined key_loop_fusion
+      IF( nn_hls == 1 ) THEN
+         CALL ctl_stop( 'STOP', 'nemogcm : Loop fusion can be used only with extra-halo' )
+      ENDIF
+#endif
+
       CALL halo_mng_init()
       ! Now we know the dimensions of the grid and numout has been set: we can allocate arrays
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/SWE/stprk3.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/SWE/stprk3.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/SWE/stprk3.F90	(revision 14852)
@@ -172,4 +172,5 @@
       !
       CALL lbc_lnk( 'stp_RK3', uu(:,:,:,Naa), 'U', -1., vv(:,:,:,Naa), 'V', -1. )
+      IF (nn_hls==2) CALL lbc_lnk( 'stp_MLF', r3u(:,:,Naa), 'U', 1., r3v(:,:,Naa), 'U', 1.)
       !
       !                                 !==  Swap time levels  ==!
@@ -237,4 +238,5 @@
       !
       CALL lbc_lnk( 'stp_RK3', uu(:,:,:,Naa), 'U', -1., vv(:,:,:,Naa), 'V', -1. )
+      IF (nn_hls==2) CALL lbc_lnk( 'stp_MLF', r3u(:,:,Naa), 'U', 1., r3v(:,:,Naa), 'U', 1.)
       !
       !                                 !==  Swap time levels  ==!
@@ -300,4 +302,5 @@
       !
       CALL lbc_lnk( 'stp_RK3', uu(:,:,:,Naa), 'U', -1., vv(:,:,:,Naa), 'V', -1. )
+      IF (nn_hls==2) CALL lbc_lnk( 'stp_MLF', r3u(:,:,Naa), 'U', 1., r3v(:,:,Naa), 'U', 1.)
       !
       !                                 !==  Swap time levels  ==!
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/TOP/AGE/trcnam_age.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/TOP/AGE/trcnam_age.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/TOP/AGE/trcnam_age.F90	(revision 14852)
@@ -53,4 +53,5 @@
       ln_trc_cbc(jp_age) = .false.
       ln_trc_obc(jp_age) = .false.
+      ln_trc_ais(jp_age) = .false.
       !
       READ  ( numnat_ref, namage, IOSTAT = ios, ERR = 901)
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/TOP/TRP/trcadv.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/TOP/TRP/trcadv.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/TOP/TRP/trcadv.F90	(revision 14852)
@@ -23,7 +23,5 @@
    USE traadv_cen     ! centered scheme           (tra_adv_cen  routine)
    USE traadv_fct     ! FCT      scheme           (tra_adv_fct  routine)
-   USE traadv_fct_lf  ! FCT      scheme           (tra_adv_fct  routine - loop fusion version)
    USE traadv_mus     ! MUSCL    scheme           (tra_adv_mus  routine)
-   USE traadv_mus_lf  ! MUSCL    scheme           (tra_adv_mus  routine - loop fusion version)
    USE traadv_ubs     ! UBS      scheme           (tra_adv_ubs  routine)
    USE traadv_qck     ! QUICKEST scheme           (tra_adv_qck  routine)
@@ -127,37 +125,12 @@
       !
       CASE ( np_CEN )                                 ! Centered : 2nd / 4th order
-         IF (nn_hls.EQ.2) CALL lbc_lnk( 'trcadv', ptr(:,:,:,:,Kmm), 'T', 1.)
          CALL tra_adv_cen( kt, nittrc000,'TRC',          zuu, zvv, zww,      Kmm, ptr, jptra, Krhs, nn_cen_h, nn_cen_v )
       CASE ( np_FCT )                                 ! FCT      : 2nd / 4th order
-         IF (nn_hls.EQ.2) THEN
-            CALL lbc_lnk( 'trcadv', ptr(:,:,:,:,Kbb), 'T', 1., ptr(:,:,:,:,Kmm), 'T', 1.)
-            CALL lbc_lnk( 'traadv', zuu(:,:,:), 'U', -1., zvv(:,:,:), 'V', -1., zww(:,:,:), 'W', 1.)
-#if defined key_loop_fusion
-            CALL tra_adv_fct_lf( kt, nittrc000,'TRC', rDt_trc, zuu, zvv, zww, Kbb, Kmm, ptr, jptra, Krhs, nn_fct_h, nn_fct_v )
-#else
             CALL tra_adv_fct( kt, nittrc000,'TRC', rDt_trc, zuu, zvv, zww, Kbb, Kmm, ptr, jptra, Krhs, nn_fct_h, nn_fct_v )
-#endif
-         ELSE
-            CALL tra_adv_fct( kt, nittrc000,'TRC', rDt_trc, zuu, zvv, zww, Kbb, Kmm, ptr, jptra, Krhs, nn_fct_h, nn_fct_v )
-         END IF
       CASE ( np_MUS )                                 ! MUSCL
-         IF (nn_hls.EQ.2) THEN
-            CALL lbc_lnk( 'trcadv', ptr(:,:,:,:,Kbb), 'T', 1.)
-#if defined key_loop_fusion
-            CALL tra_adv_mus_lf( 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
-         ELSE
-            CALL tra_adv_mus( kt, nittrc000,'TRC', rDt_trc, zuu, zvv, zww, Kbb, Kmm, ptr, jptra, Krhs, ln_mus_ups ) 
-         END IF
+            CALL tra_adv_mus( kt, nittrc000,'TRC', rDt_trc, zuu, zvv, zww, Kbb, Kmm, ptr, jptra, Krhs, ln_mus_ups )
       CASE ( np_UBS )                                 ! UBS
-         IF (nn_hls.EQ.2) CALL lbc_lnk( 'trcadv', ptr(:,:,:,:,Kbb), 'T', 1.)
          CALL tra_adv_ubs( kt, nittrc000,'TRC', rDt_trc, zuu, zvv, zww, Kbb, Kmm, ptr, jptra, Krhs, nn_ubs_v           )
       CASE ( np_QCK )                                 ! QUICKEST
-         IF (nn_hls.EQ.2) THEN
-            CALL lbc_lnk( 'trcadv', zuu(:,:,:), 'U', -1., zvv(:,:,:), 'V', -1.)
-            CALL lbc_lnk( 'traadv', ptr(:,:,:,:,Kbb), 'T', 1.)
-         END IF
          CALL tra_adv_qck( kt, nittrc000,'TRC', rDt_trc, zuu, zvv, zww, Kbb, Kmm, ptr, jptra, Krhs                     )
       !
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/TOP/TRP/trcldf.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/TOP/TRP/trcldf.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/TOP/TRP/trcldf.F90	(revision 14852)
@@ -83,5 +83,5 @@
       zahv(:,:,:) = rldf * ahtv(:,:,:)
       !                                  !* Enhanced zonal diffusivity coefficent in the equatorial domain
-      DO_3D( 1, 1, 1, 1, 1, jpk )
+      DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpk )
          IF( gdept(ji,jj,jk,Kmm) > 200. .AND. gphit(ji,jj) < 5. .AND. gphit(ji,jj) > -5. ) THEN
             zdep = MAX( gdept(ji,jj,jk,Kmm) - 1000., 0. ) / 1000.
@@ -102,5 +102,4 @@
            &                     ptr(:,:,:,:,Kbb), ptr(:,:,:,:,Kbb), ptr(:,:,:,:,Krhs), jptra, 1 )
       CASE ( np_blp , np_blp_i , np_blp_it )                                                               ! bilaplacian: all operator (iso-level, -neutral)
-         IF(nn_hls.EQ.2) CALL lbc_lnk( 'trc_ldf', ptr(:,:,:,:,Kbb), 'T',1.)
          CALL tra_ldf_blp  ( kt, Kmm, nittrc000,'TRC', zahu, zahv, gtru, gtrv, gtrui, gtrvi,            &
            &                     ptr(:,:,:,:,Kbb) , ptr(:,:,:,:,Krhs),                 jptra, nldf_trc )
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/TOP/trcdta.F90
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/TOP/trcdta.F90	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/src/TOP/trcdta.F90	(revision 14852)
@@ -195,5 +195,5 @@
                WRITE(numout,*) 'trc_dta: interpolates passive tracer data onto the s- or mixed s-z-coordinate mesh'
             ENDIF
-            DO_2D( 1, 1, 1, 1 )                 ! vertical interpolation of T & S
+            DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )                 ! vertical interpolation of T & S
                DO jk = 1, jpk                        ! determines the intepolated T-S profiles at each (i,j) points
                   zl = gdept_0(ji,jj,jk)
@@ -220,5 +220,5 @@
             ! zps-coordinate (partial steps) interpolation at the last ocean level
             IF( ln_zps ) THEN
-                DO_2D( 1, 1, 1, 1 )
+                DO_2D( nn_hls, nn_hls, nn_hls, nn_hls ) 
                    ik = mbkt(ji,jj)
                    IF( ik > 1 ) THEN
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/CANAL/EXPREF/namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/CANAL/EXPREF/namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/CANAL/EXPREF/namelist_cfg	(revision 14852)
@@ -76,4 +76,8 @@
       cn_domcfg_out = "domain_cfg" ! newly created domain configuration filename
 /
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
+/
 !!======================================================================
 !!            ***  Surface Boundary Condition namelists  ***          !!
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/CPL_OASIS/EXPREF/namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/CPL_OASIS/EXPREF/namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/CPL_OASIS/EXPREF/namelist_cfg	(revision 14852)
@@ -38,4 +38,8 @@
       ln_closea    = .false.    !  F => suppress closed seas (defined by closea_mask field) 
       !                         !       from the bathymetry at runtime.
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
 /
 !-----------------------------------------------------------------------
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/DOME/EXPREF/1_namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/DOME/EXPREF/1_namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/DOME/EXPREF/1_namelist_cfg	(revision 14852)
@@ -42,4 +42,8 @@
       cn_domcfg = "DOME_domcfg"  ! domain configuration filename
       !
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
 /
 !-----------------------------------------------------------------------
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/DOME/EXPREF/namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/DOME/EXPREF/namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/DOME/EXPREF/namelist_cfg	(revision 14852)
@@ -30,4 +30,8 @@
       cn_domcfg = "DOME_domcfg"  ! domain configuration filename
       !
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
 /
 !-----------------------------------------------------------------------
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/DONUT/EXPREF/namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/DONUT/EXPREF/namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/DONUT/EXPREF/namelist_cfg	(revision 14852)
@@ -27,4 +27,8 @@
       !                    !  (=F) user defined configuration           (F => create/check namusr_def)
       cn_domcfg = "donut_cfg"  ! domain configuration filename
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
 /
 !-----------------------------------------------------------------------
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/ICB/EXPREF/namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/ICB/EXPREF/namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/ICB/EXPREF/namelist_cfg	(revision 14852)
@@ -48,4 +48,8 @@
 !-----------------------------------------------------------------------
 &namcfg        !   parameters of the configuration                      (default: use namusr_def in namelist_cfg)
+!-----------------------------------------------------------------------
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
 !-----------------------------------------------------------------------
 /
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/ICE_ADV1D/EXPREF/namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/ICE_ADV1D/EXPREF/namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/ICE_ADV1D/EXPREF/namelist_cfg	(revision 14852)
@@ -49,4 +49,8 @@
       !                     !  (=F) user defined configuration  ==>>>  see usrdef(_...) modules
       cn_domcfg = "ICE_ADV1D_domcfg"    ! domain configuration filename
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
 /
 !!======================================================================
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/ICE_ADV2D/EXPREF/namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/ICE_ADV2D/EXPREF/namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/ICE_ADV2D/EXPREF/namelist_cfg	(revision 14852)
@@ -49,4 +49,8 @@
       !                     !  (=F) user defined configuration  ==>>>  see usrdef(_...) modules
       cn_domcfg = "ICE_ADV2D_domcfg"    ! domain configuration filename
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
 /
 !!======================================================================
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/ICE_AGRIF/EXPREF/1_namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/ICE_AGRIF/EXPREF/1_namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/ICE_AGRIF/EXPREF/1_namelist_cfg	(revision 14852)
@@ -49,4 +49,8 @@
       !                     !  (=F) user defined configuration  ==>>>  see usrdef(_...) modules
       cn_domcfg = "ICE_AGRIF_domcfg"    ! domain configuration filename
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
 /
 !!======================================================================
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/ICE_AGRIF/EXPREF/namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/ICE_AGRIF/EXPREF/namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/ICE_AGRIF/EXPREF/namelist_cfg	(revision 14852)
@@ -49,4 +49,8 @@
       !                     !  (=F) user defined configuration  ==>>>  see usrdef(_...) modules
       cn_domcfg = "ICE_AGRIF_domcfg"    ! domain configuration filename
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
 /
 !!======================================================================
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/ICE_RHEO/EXPREF/namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/ICE_RHEO/EXPREF/namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/ICE_RHEO/EXPREF/namelist_cfg	(revision 14852)
@@ -48,4 +48,8 @@
    ln_read_cfg = .false.    !  (=T) read the domain configuration file
       !                     !  (=F) user defined configuration  ==>>>  see usrdef(_...) modules
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
 /
 !!======================================================================
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/ISOMIP+/EXPREF/namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/ISOMIP+/EXPREF/namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/ISOMIP+/EXPREF/namelist_cfg	(revision 14852)
@@ -50,4 +50,8 @@
 !-----------------------------------------------------------------------
    ln_read_cfg = .true.   !  (=T) read the domain configuration file
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
 /
 !-----------------------------------------------------------------------
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/ISOMIP/EXPREF/namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/ISOMIP/EXPREF/namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/ISOMIP/EXPREF/namelist_cfg	(revision 14852)
@@ -48,4 +48,8 @@
 !-----------------------------------------------------------------------
 &namcfg        !   parameters of the configuration                      (default: use namusr_def in namelist_cfg)
+!-----------------------------------------------------------------------
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
 !-----------------------------------------------------------------------
 /
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/LOCK_EXCHANGE/EXPREF/namelist_FCT2_flux_ubs_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/LOCK_EXCHANGE/EXPREF/namelist_FCT2_flux_ubs_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/LOCK_EXCHANGE/EXPREF/namelist_FCT2_flux_ubs_cfg	(revision 14852)
@@ -41,4 +41,8 @@
       !                    !  (=F) user defined configuration  ==>>>  see usrdef(_...) modules
    ln_write_cfg = .false.   !  (=T) create the domain configuration file
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
 /
 !-----------------------------------------------------------------------
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/OVERFLOW/EXPREF/AGRIF/1_namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/OVERFLOW/EXPREF/AGRIF/1_namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/OVERFLOW/EXPREF/AGRIF/1_namelist_cfg	(revision 14852)
@@ -38,4 +38,8 @@
       cn_domcfg = "OVF_domcfg"  ! domain configuration filename
       !
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
 /
 !-----------------------------------------------------------------------
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/OVERFLOW/EXPREF/AGRIF/namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/OVERFLOW/EXPREF/AGRIF/namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/OVERFLOW/EXPREF/AGRIF/namelist_cfg	(revision 14852)
@@ -32,4 +32,8 @@
       cn_domcfg = "OVF_domcfg"  ! domain configuration filename
       !
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
 /
 !-----------------------------------------------------------------------
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/OVERFLOW/EXPREF/namelist_zps_FCT4_flux_ubs_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/OVERFLOW/EXPREF/namelist_zps_FCT4_flux_ubs_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/OVERFLOW/EXPREF/namelist_zps_FCT4_flux_ubs_cfg	(revision 14852)
@@ -41,4 +41,8 @@
 !-----------------------------------------------------------------------
 &namcfg        !   parameters of the configuration
+!-----------------------------------------------------------------------
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
 !-----------------------------------------------------------------------
 /
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/SWG/EXPREF/namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/SWG/EXPREF/namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/SWG/EXPREF/namelist_cfg	(revision 14852)
@@ -32,4 +32,8 @@
 !-----------------------------------------------------------------------
    ln_read_cfg = .false.   !  (=F) user defined configuration           (F => create/check namusr_def)
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
 /
 !-----------------------------------------------------------------------
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/TSUNAMI/EXPREF/namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/TSUNAMI/EXPREF/namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/TSUNAMI/EXPREF/namelist_cfg	(revision 14852)
@@ -31,4 +31,8 @@
    ln_Iperio  =   .true.   ! i-periodicity
    ln_Jperio  =   .true.   ! j-periodicity
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
 /
 !-----------------------------------------------------------------------
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/VORTEX/EXPREF/1_namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/VORTEX/EXPREF/1_namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/VORTEX/EXPREF/1_namelist_cfg	(revision 14852)
@@ -45,4 +45,8 @@
 !-----------------------------------------------------------------------
 &namcfg        !   parameters of the configuration                      (default: user defined GYRE)
+!-----------------------------------------------------------------------
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
 !-----------------------------------------------------------------------
 /
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/VORTEX/EXPREF/namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/VORTEX/EXPREF/namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/VORTEX/EXPREF/namelist_cfg	(revision 14852)
@@ -45,4 +45,8 @@
 !-----------------------------------------------------------------------
 &namcfg        !   parameters of the configuration                      (default: use namusr_def in namelist_cfg)
+!-----------------------------------------------------------------------
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
 !-----------------------------------------------------------------------
 /
Index: NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/WAD/EXPREF/namelist_cfg
===================================================================
--- NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/WAD/EXPREF/namelist_cfg	(revision 14851)
+++ NEMO/branches/2021/dev_r13747_HPC-11_mcastril_HPDAonline_DiagGPU/tests/WAD/EXPREF/namelist_cfg	(revision 14852)
@@ -51,4 +51,8 @@
       !                    !  (=F) user defined configuration  ==>>>  see usrdef(_...) modules
    ln_write_cfg = .true.    !  (=T) create the domain configuration file
+/
+!-----------------------------------------------------------------------
+&namtile        !   parameters of the tiling
+!-----------------------------------------------------------------------
 /
 !-----------------------------------------------------------------------
