Index: /NEMO/trunk/cfgs/SHARED/namelist_ref
===================================================================
--- /NEMO/trunk/cfgs/SHARED/namelist_ref	(revision 13981)
+++ /NEMO/trunk/cfgs/SHARED/namelist_ref	(revision 13982)
@@ -94,4 +94,11 @@
    ln_use_jattr = .false.    !  use (T) the file attribute: open_ocean_jstart, if present
    !                         !  in netcdf input files, as the start j-row for reading
+/
+!-----------------------------------------------------------------------
+&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/trunk/src/ICE/icedyn_rhg_evp.F90
===================================================================
--- /NEMO/trunk/src/ICE/icedyn_rhg_evp.F90	(revision 13981)
+++ /NEMO/trunk/src/ICE/icedyn_rhg_evp.F90	(revision 13982)
@@ -199,5 +199,5 @@
          zfmask(ji,jj) = tmask(ji,jj,1) * tmask(ji+1,jj,1) * tmask(ji,jj+1,1) * tmask(ji+1,jj+1,1)
       END_2D
-      CALL lbc_lnk( 'icedyn_rhg_evp', zfmask, 'F', 1._wp )
+      CALL lbc_lnk( 'icedyn_rhg_evp', zfmask, 'F', 1._wp)
 
       ! Lateral boundary conditions on velocity (modify zfmask)
Index: /NEMO/trunk/src/OCE/ASM/asminc.F90
===================================================================
--- /NEMO/trunk/src/OCE/ASM/asminc.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/ASM/asminc.F90	(revision 13982)
@@ -26,4 +26,5 @@
    USE par_oce         ! Ocean space and time domain variables
    USE dom_oce         ! Ocean space and time domain
+   USE domain, ONLY : dom_tile
    USE domvvl          ! domain: variable volume level
    USE ldfdyn          ! lateral diffusion: eddy viscosity coefficients
@@ -518,14 +519,16 @@
       !
       INTEGER  :: ji, jj, jk
-      INTEGER  :: it
+      INTEGER  :: it, itile
       REAL(wp) :: zincwgt  ! IAU weight for current time step
-      REAL (wp), DIMENSION(jpi,jpj,jpk) :: fzptnz ! 3d freezing point values
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) :: fzptnz ! 3d freezing point values
       !!----------------------------------------------------------------------
       !
       ! freezing point calculation taken from oc_fz_pt (but calculated for all depths) 
       ! used to prevent the applied increments taking the temperature below the local freezing point 
-      DO jk = 1, jpkm1
-        CALL eos_fzp( pts(:,:,jk,jp_sal,Kmm), fzptnz(:,:,jk), gdept(:,:,jk,Kmm) )
-      END DO
+      IF( ln_temnofreeze ) THEN
+         DO jk = 1, jpkm1
+           CALL eos_fzp( pts(:,:,jk,jp_sal,Kmm), fzptnz(:,:,jk), gdept(:,:,jk,Kmm) )
+         END DO
+      ENDIF
          !
          !                             !--------------------------------------
@@ -538,8 +541,10 @@
             zincwgt = wgtiau(it) / rn_Dt   ! IAU weight for the current time step
             !
-            IF(lwp) THEN
-               WRITE(numout,*) 
-               WRITE(numout,*) 'tra_asm_inc : Tracer IAU at time step = ', kt,' with IAU weight = ', wgtiau(it)
-               WRITE(numout,*) '~~~~~~~~~~~~'
+            IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+               IF(lwp) THEN
+                  WRITE(numout,*)
+                  WRITE(numout,*) 'tra_asm_inc : Tracer IAU at time step = ', kt,' with IAU weight = ', wgtiau(it)
+                  WRITE(numout,*) '~~~~~~~~~~~~'
+               ENDIF
             ENDIF
             !
@@ -548,20 +553,24 @@
                IF (ln_temnofreeze) THEN
                   ! Do not apply negative increments if the temperature will fall below freezing
-                  WHERE(t_bkginc(:,:,jk) > 0.0_wp .OR. &
-                     &   pts(:,:,jk,jp_tem,Kmm) + pts(:,:,jk,jp_tem,Krhs) + t_bkginc(:,:,jk) * wgtiau(it) > fzptnz(:,:,jk) ) 
-                     pts(:,:,jk,jp_tem,Krhs) = pts(:,:,jk,jp_tem,Krhs) + t_bkginc(:,:,jk) * zincwgt  
+                  WHERE(t_bkginc(A2D(0),jk) > 0.0_wp .OR. &
+                     &   pts(A2D(0),jk,jp_tem,Kmm) + pts(A2D(0),jk,jp_tem,Krhs) + t_bkginc(A2D(0),jk) * wgtiau(it) > fzptnz(:,:,jk) )
+                     pts(A2D(0),jk,jp_tem,Krhs) = pts(A2D(0),jk,jp_tem,Krhs) + t_bkginc(A2D(0),jk) * zincwgt
                   END WHERE
                ELSE
-                  pts(:,:,jk,jp_tem,Krhs) = pts(:,:,jk,jp_tem,Krhs) + t_bkginc(:,:,jk) * zincwgt  
+                  DO_2D( 0, 0, 0, 0 )
+                     pts(ji,jj,jk,jp_tem,Krhs) = pts(ji,jj,jk,jp_tem,Krhs) + t_bkginc(ji,jj,jk) * zincwgt
+                  END_2D
                ENDIF
                IF (ln_salfix) THEN
                   ! Do not apply negative increments if the salinity will fall below a specified
                   ! minimum value salfixmin
-                  WHERE(s_bkginc(:,:,jk) > 0.0_wp .OR. &
-                     &   pts(:,:,jk,jp_sal,Kmm) + pts(:,:,jk,jp_sal,Krhs) + s_bkginc(:,:,jk) * wgtiau(it) > salfixmin ) 
-                     pts(:,:,jk,jp_sal,Krhs) = pts(:,:,jk,jp_sal,Krhs) + s_bkginc(:,:,jk) * zincwgt
+                  WHERE(s_bkginc(A2D(0),jk) > 0.0_wp .OR. &
+                     &   pts(A2D(0),jk,jp_sal,Kmm) + pts(A2D(0),jk,jp_sal,Krhs) + s_bkginc(A2D(0),jk) * wgtiau(it) > salfixmin )
+                     pts(A2D(0),jk,jp_sal,Krhs) = pts(A2D(0),jk,jp_sal,Krhs) + s_bkginc(A2D(0),jk) * zincwgt
                   END WHERE
                ELSE
-                  pts(:,:,jk,jp_sal,Krhs) = pts(:,:,jk,jp_sal,Krhs) + s_bkginc(:,:,jk) * zincwgt
+                  DO_2D( 0, 0, 0, 0 )
+                     pts(ji,jj,jk,jp_sal,Krhs) = pts(ji,jj,jk,jp_sal,Krhs) + s_bkginc(ji,jj,jk) * zincwgt
+                  END_2D
                ENDIF
             END DO
@@ -569,7 +578,9 @@
          ENDIF
          !
-         IF ( kt == nitiaufin_r + 1  ) THEN   ! For bias crcn to work
-            DEALLOCATE( t_bkginc )
-            DEALLOCATE( s_bkginc )
+         IF( ntile == 0 .OR. ntile == nijtile )  THEN                ! Do only on the last tile
+            IF ( kt == nitiaufin_r + 1  ) THEN   ! For bias crcn to work
+               DEALLOCATE( t_bkginc )
+               DEALLOCATE( s_bkginc )
+            ENDIF
          ENDIF
          !                             !--------------------------------------
@@ -584,21 +595,27 @@
             IF (ln_temnofreeze) THEN
                ! Do not apply negative increments if the temperature will fall below freezing
-               WHERE( t_bkginc(:,:,:) > 0.0_wp .OR. pts(:,:,:,jp_tem,Kmm) + t_bkginc(:,:,:) > fzptnz(:,:,:) ) 
-                  pts(:,:,:,jp_tem,Kmm) = t_bkg(:,:,:) + t_bkginc(:,:,:)   
+               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),:)
                END WHERE
             ELSE
-               pts(:,:,:,jp_tem,Kmm) = t_bkg(:,:,:) + t_bkginc(:,:,:)   
+               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
             ENDIF
             IF (ln_salfix) THEN
                ! Do not apply negative increments if the salinity will fall below a specified
                ! minimum value salfixmin
-               WHERE( s_bkginc(:,:,:) > 0.0_wp .OR. pts(:,:,:,jp_sal,Kmm) + s_bkginc(:,:,:) > salfixmin ) 
-                  pts(:,:,:,jp_sal,Kmm) = s_bkg(:,:,:) + s_bkginc(:,:,:)   
+               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),:)
                END WHERE
             ELSE
-               pts(:,:,:,jp_sal,Kmm) = s_bkg(:,:,:) + s_bkginc(:,:,:)   
-            ENDIF
-
-            pts(:,:,:,:,Kbb) = pts(:,:,:,:,Kmm)                 ! Update before fields
+               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
 
             CALL eos( pts(:,:,:,:,Kbb), rhd, rhop, gdept_0(:,:,:) )  ! Before potential and in situ densities
@@ -607,15 +624,26 @@
 !!gm
 
-            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    )
+            ! 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
+         !
          ENDIF
          !  
@@ -829,8 +857,9 @@
       INTEGER, INTENT(in), OPTIONAL ::   kindic   ! flag for disabling the deallocation
       !
+      INTEGER  ::   ji, jj
       INTEGER  ::   it
       REAL(wp) ::   zincwgt   ! IAU weight for current time step
 #if defined key_si3
-      REAL(wp), DIMENSION(jpi,jpj) ::   zofrld, zohicif, zseaicendg, zhicifinc
+      REAL(wp), DIMENSION(A2D(nn_hls)) ::   zofrld, zohicif, zseaicendg, zhicifinc
       REAL(wp) ::   zhicifmin = 0.5_wp      ! ice minimum depth in metres
 #endif
@@ -847,8 +876,10 @@
             ! note this is not a tendency so should not be divided by rn_Dt (as with the tracer and other increments)
             !
-            IF(lwp) THEN
-               WRITE(numout,*) 
-               WRITE(numout,*) 'seaice_asm_inc : sea ice conc IAU at time step = ', kt,' with IAU weight = ', wgtiau(it)
-               WRITE(numout,*) '~~~~~~~~~~~~'
+            IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+               IF(lwp) THEN
+                  WRITE(numout,*)
+                  WRITE(numout,*) 'seaice_asm_inc : sea ice conc IAU at time step = ', kt,' with IAU weight = ', wgtiau(it)
+                  WRITE(numout,*) '~~~~~~~~~~~~'
+               ENDIF
             ENDIF
             !
@@ -856,16 +887,18 @@
             !
 #if defined key_si3
-            zofrld (:,:) = 1._wp - at_i(:,:)
-            zohicif(:,:) = hm_i(:,:)
-            !
-            at_i  (:,:) = 1. - MIN( MAX( 1.-at_i  (:,:) - seaice_bkginc(:,:) * zincwgt, 0.0_wp), 1.0_wp)
-            at_i_b(:,:) = 1. - MIN( MAX( 1.-at_i_b(:,:) - seaice_bkginc(:,:) * zincwgt, 0.0_wp), 1.0_wp)
-            fr_i(:,:) = at_i(:,:)        ! adjust ice fraction
-            !
-            zseaicendg(:,:) = zofrld(:,:) - (1. - at_i(:,:))   ! find out actual sea ice nudge applied
+            DO_2D( 0, 0, 0, 0 )
+               zofrld (ji,jj) = 1._wp - at_i(ji,jj)
+               zohicif(ji,jj) = hm_i(ji,jj)
+               !
+               at_i  (ji,jj) = 1. - MIN( MAX( 1.-at_i  (ji,jj) - seaice_bkginc(ji,jj) * zincwgt, 0.0_wp), 1.0_wp)
+               at_i_b(ji,jj) = 1. - MIN( MAX( 1.-at_i_b(ji,jj) - seaice_bkginc(ji,jj) * zincwgt, 0.0_wp), 1.0_wp)
+               fr_i(ji,jj) = at_i(ji,jj)        ! adjust ice fraction
+               !
+               zseaicendg(ji,jj) = zofrld(ji,jj) - (1. - at_i(ji,jj))   ! find out actual sea ice nudge applied
+            END_2D
             !
             ! Nudge sea ice depth to bring it up to a required minimum depth
-            WHERE( zseaicendg(:,:) > 0.0_wp .AND. hm_i(:,:) < zhicifmin ) 
-               zhicifinc(:,:) = (zhicifmin - hm_i(:,:)) * zincwgt    
+            WHERE( zseaicendg(:,:) > 0.0_wp .AND. hm_i(A2D(0)) < zhicifmin )
+               zhicifinc(:,:) = (zhicifmin - hm_i(A2D(0))) * zincwgt
             ELSEWHERE
                zhicifinc(:,:) = 0.0_wp
@@ -873,5 +906,7 @@
             !
             ! nudge ice depth
-            hm_i (:,:) = hm_i (:,:) + zhicifinc(:,:)
+            DO_2D( 0, 0, 0, 0 )
+               hm_i (ji,jj) = hm_i (ji,jj) + zhicifinc(ji,jj)
+            END_2D
             !
             ! seaice salinity balancing (to add)
@@ -880,9 +915,13 @@
 #if defined key_cice && defined key_asminc
             ! Sea-ice : CICE case. Pass ice increment tendency into CICE
-            ndaice_da(:,:) = seaice_bkginc(:,:) * zincwgt / rn_Dt
-#endif
-            !
-            IF ( kt == nitiaufin_r ) THEN
-               DEALLOCATE( seaice_bkginc )
+            DO_2D( 0, 0, 0, 0 )
+               ndaice_da(ji,jj) = seaice_bkginc(ji,jj) * zincwgt / rn_Dt
+            END_2D
+#endif
+            !
+            IF( ntile == 0 .OR. ntile == nijtile )  THEN                ! Do only on the last tile
+               IF ( kt == nitiaufin_r ) THEN
+                  DEALLOCATE( seaice_bkginc )
+               ENDIF
             ENDIF
             !
@@ -890,5 +929,7 @@
             !
 #if defined key_cice && defined key_asminc
-            ndaice_da(:,:) = 0._wp        ! Sea-ice : CICE case. Zero ice increment tendency into CICE
+            DO_2D( 0, 0, 0, 0 )
+               ndaice_da(ji,jj) = 0._wp        ! Sea-ice : CICE case. Zero ice increment tendency into CICE
+            END_2D
 #endif
             !
@@ -905,17 +946,19 @@
             !
 #if defined key_si3
-            zofrld (:,:) = 1._wp - at_i(:,:)
-            zohicif(:,:) = hm_i(:,:)
-            ! 
-            ! Initialize the now fields the background + increment
-            at_i(:,:) = 1. - MIN( MAX( 1.-at_i(:,:) - seaice_bkginc(:,:), 0.0_wp), 1.0_wp)
-            at_i_b(:,:) = at_i(:,:) 
-            fr_i(:,:) = at_i(:,:)        ! adjust ice fraction
-            !
-            zseaicendg(:,:) = zofrld(:,:) - (1. - at_i(:,:))   ! find out actual sea ice nudge applied
+            DO_2D( 0, 0, 0, 0 )
+               zofrld (ji,jj) = 1._wp - at_i(ji,jj)
+               zohicif(ji,jj) = hm_i(ji,jj)
+               !
+               ! Initialize the now fields the background + increment
+               at_i(ji,jj) = 1. - MIN( MAX( 1.-at_i(ji,jj) - seaice_bkginc(ji,jj), 0.0_wp), 1.0_wp)
+               at_i_b(ji,jj) = at_i(ji,jj)
+               fr_i(ji,jj) = at_i(ji,jj)        ! adjust ice fraction
+               !
+               zseaicendg(ji,jj) = zofrld(ji,jj) - (1. - at_i(ji,jj))   ! find out actual sea ice nudge applied
+            END_2D
             !
             ! Nudge sea ice depth to bring it up to a required minimum depth
-            WHERE( zseaicendg(:,:) > 0.0_wp .AND. hm_i(:,:) < zhicifmin ) 
-               zhicifinc(:,:) = zhicifmin - hm_i(:,:)
+            WHERE( zseaicendg(:,:) > 0.0_wp .AND. hm_i(A2D(0)) < zhicifmin )
+               zhicifinc(:,:) = zhicifmin - hm_i(A2D(0))
             ELSEWHERE
                zhicifinc(:,:) = 0.0_wp
@@ -923,5 +966,7 @@
             !
             ! nudge ice depth
-            hm_i (:,:) = hm_i (:,:) + zhicifinc(:,:)
+            DO_2D( 0, 0, 0, 0 )
+               hm_i(ji,jj) = hm_i (ji,jj) + zhicifinc(ji,jj)
+            END_2D
             !
             ! seaice salinity balancing (to add)
@@ -930,14 +975,20 @@
 #if defined key_cice && defined key_asminc
             ! Sea-ice : CICE case. Pass ice increment tendency into CICE
-           ndaice_da(:,:) = seaice_bkginc(:,:) / rn_Dt
-#endif
-            IF ( .NOT. PRESENT(kindic) ) THEN
-               DEALLOCATE( seaice_bkginc )
-            END IF
+            DO_2D( 0, 0, 0, 0 )
+               ndaice_da(ji,jj) = seaice_bkginc(ji,jj) / rn_Dt
+            END_2D
+#endif
+            IF( ntile == 0 .OR. ntile == nijtile )  THEN                ! Do only on the last tile
+               IF ( .NOT. PRESENT(kindic) ) THEN
+                  DEALLOCATE( seaice_bkginc )
+               END IF
+            ENDIF
             !
          ELSE
             !
 #if defined key_cice && defined key_asminc
-            ndaice_da(:,:) = 0._wp     ! Sea-ice : CICE case. Zero ice increment tendency into CICE
+            DO_2D( 0, 0, 0, 0 )
+               ndaice_da(ji,jj) = 0._wp     ! Sea-ice : CICE case. Zero ice increment tendency into CICE
+            END_2D
 #endif
             !
Index: /NEMO/trunk/src/OCE/BDY/bdytra.F90
===================================================================
--- /NEMO/trunk/src/OCE/BDY/bdytra.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/BDY/bdytra.F90	(revision 13982)
@@ -13,5 +13,5 @@
    !!----------------------------------------------------------------------
    USE oce            ! ocean dynamics and tracers variables
-   USE dom_oce        ! ocean space and time domain variables 
+   USE dom_oce        ! ocean space and time domain variables
    USE bdy_oce        ! ocean open boundary conditions
    USE bdylib         ! for orlanski library routines
@@ -157,4 +157,5 @@
       INTEGER  ::   ib_bdy         ! Loop index
       !!----------------------------------------------------------------------
+      IF( ntile /= 0 .AND. ntile /= 1 ) RETURN                        ! Do only for the full domain
       !
       IF( ln_timing )   CALL timing_start('bdy_tra_dmp')
Index: /NEMO/trunk/src/OCE/DIA/diaar5.F90
===================================================================
--- /NEMO/trunk/src/OCE/DIA/diaar5.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/DIA/diaar5.F90	(revision 13982)
@@ -34,4 +34,5 @@
    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
@@ -54,5 +55,6 @@
       !!----------------------------------------------------------------------
       !
-      ALLOCATE( thick0(jpi,jpj) , sn0(jpi,jpj,jpk) , STAT=dia_ar5_alloc )
+      ALLOCATE( thick0(jpi,jpj) , sn0(jpi,jpj,jpk) , &
+         &      hstr_adv(jpi,jpj,jpts,2), hstr_ldf(jpi,jpj,jpts,2), STAT=dia_ar5_alloc )
       !
       CALL mpp_sum ( 'diaar5', dia_ar5_alloc )
@@ -304,6 +306,6 @@
    END SUBROUTINE dia_ar5
 
-
-   SUBROUTINE dia_ar5_hst( ktra, cptr, puflx, pvflx ) 
+   ! TEMP: [tiling] These changes not necessary if using XIOS (subdomain support, will not output haloes)
+   SUBROUTINE dia_ar5_hst( ktra, cptr, puflx, pvflx )
       !!----------------------------------------------------------------------
       !!                    ***  ROUTINE dia_ar5_htr ***
@@ -314,39 +316,47 @@
       INTEGER                         , INTENT(in )  :: ktra  ! tracer index
       CHARACTER(len=3)                , INTENT(in)   :: cptr  ! transport type  'adv'/'ldf'
-      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(in)   :: puflx  ! u-flux of advection/diffusion
-      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(in)   :: pvflx  ! v-flux of advection/diffusion
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk)    , INTENT(in)   :: puflx  ! u-flux of advection/diffusion
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk)    , INTENT(in)   :: pvflx  ! v-flux of advection/diffusion
       !
       INTEGER    ::  ji, jj, jk
-      REAL(wp), DIMENSION(jpi,jpj)  :: z2d
-
+
+      IF( cptr /= 'adv' .AND. cptr /= 'ldf' ) RETURN
+      IF( ktra /= jp_tem .AND. ktra /= jp_sal ) RETURN
+
+      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
+      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
+      ENDIF
     
-      z2d(:,:) = puflx(:,:,1) 
-      DO_3D( 0, 0, 0, 0, 1, jpkm1 )
-         z2d(ji,jj) = z2d(ji,jj) + puflx(ji,jj,jk) 
-      END_3D
-       CALL lbc_lnk( 'diaar5', z2d, 'U', -1.0_wp )
-       IF( cptr == 'adv' ) THEN
-          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
-       ENDIF
-       IF( cptr == 'ldf' ) THEN
-          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
-       CALL lbc_lnk( 'diaar5', z2d, 'V', -1.0_wp )
-       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
-       ENDIF
-       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
-          
    END SUBROUTINE dia_ar5_hst
 
@@ -371,4 +381,8 @@
          &  iom_use( 'masstot' ) .OR. iom_use( 'temptot'   )  .OR. iom_use( 'saltot' ) .OR.  &    
          &  iom_use( 'botpres' ) .OR. iom_use( 'sshthster' )  .OR. iom_use( 'sshsteric' ) .OR. &
+         &  iom_use( 'uadv_heattr' ) .OR. iom_use( 'udiff_heattr' ) .OR. &
+         &  iom_use( 'uadv_salttr' ) .OR. iom_use( 'udiff_salttr' ) .OR. &
+         &  iom_use( 'vadv_heattr' ) .OR. iom_use( 'vdiff_heattr' ) .OR. &
+         &  iom_use( 'vadv_salttr' ) .OR. iom_use( 'vdiff_salttr' ) .OR. &
          &  iom_use( 'rhop' )  ) L_ar5 = .TRUE.
   
Index: /NEMO/trunk/src/OCE/DIA/diaptr.F90
===================================================================
--- /NEMO/trunk/src/OCE/DIA/diaptr.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/DIA/diaptr.F90	(revision 13982)
@@ -22,4 +22,5 @@
    USE oce              ! ocean dynamics and active tracers
    USE dom_oce          ! ocean space and time domain
+   USE domain, ONLY : dom_tile
    USE phycst           ! physical constants
    !
@@ -32,4 +33,8 @@
    PRIVATE
 
+   INTERFACE ptr_sum
+      MODULE PROCEDURE ptr_sum_3d, ptr_sum_2d
+   END INTERFACE
+
    INTERFACE ptr_sj
       MODULE PROCEDURE ptr_sj_3d, ptr_sj_2d
@@ -39,8 +44,11 @@
    PUBLIC   dia_ptr_hst    ! called from tra_ldf/tra_adv routines
 
-   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   hstr_adv, hstr_ldf, hstr_eiv   !: Heat/Salt TRansports(adv, diff, Bolus.)
-   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   hstr_ove, hstr_btr, hstr_vtr   !: heat Salt TRansports(overturn, baro, merional)
-
-   LOGICAL, PUBLIC ::   l_diaptr       !: tracers  trend flag
+   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:)   ::   hstr_adv, hstr_ldf, hstr_eiv   !: Heat/Salt TRansports(adv, diff, Bolus.)
+   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:)   ::   hstr_ove, hstr_btr, hstr_vtr   !: heat Salt TRansports(overturn, baro, merional)
+   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:,:) ::   pvtr_int, pzon_int             !: Other zonal integrals
+
+   LOGICAL, PUBLIC    ::   l_diaptr       !: tracers  trend flag
+   INTEGER, PARAMETER ::   jp_msk = 3
+   INTEGER, PARAMETER ::   jp_vtr = 4
 
    REAL(wp) ::   rc_sv    = 1.e-6_wp   ! conversion from m3/s to Sverdrup
@@ -51,9 +59,6 @@
    REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: btmsk34 ! mask out Southern Ocean (=0 south of 34°S)
 
-   REAL(wp), TARGET, ALLOCATABLE, SAVE, DIMENSION(:)   :: p_fval1d
-   REAL(wp), TARGET, ALLOCATABLE, SAVE, DIMENSION(:,:) :: p_fval2d
-
    LOGICAL ::   ll_init = .TRUE.        !: tracers  trend flag
-   
+
    !! * Substitutions
 #  include "do_loop_substitute.h90"
@@ -72,12 +77,40 @@
       INTEGER                         , INTENT(in)           ::   kt     ! ocean time-step index     
       INTEGER                         , INTENT(in)           ::   Kmm    ! time level index
-      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(in), OPTIONAL ::   pvtr   ! j-effective transport
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk)    , INTENT(in), OPTIONAL ::   pvtr   ! j-effective transport
+      !!----------------------------------------------------------------------
+      !
+      IF( ln_timing )   CALL timing_start('dia_ptr')
+
+      IF( kt == nit000 .AND. ll_init )   CALL dia_ptr_init    ! -> will define l_diaptr and nbasin
+      !
+      IF( l_diaptr ) THEN
+         ! Calculate zonal integrals
+         IF( PRESENT( pvtr ) ) THEN
+            CALL dia_ptr_zint( Kmm, pvtr )
+         ELSE
+            CALL dia_ptr_zint( Kmm )
+         ENDIF
+
+         ! Calculate diagnostics only when zonal integrals have finished
+         IF( ntile == 0 .OR. ntile == nijtile ) CALL dia_ptr_iom(kt, Kmm, pvtr)
+      ENDIF
+
+      IF( ln_timing )   CALL timing_stop('dia_ptr')
+      !
+   END SUBROUTINE dia_ptr
+
+
+   SUBROUTINE dia_ptr_iom( kt, Kmm, pvtr )
+      !!----------------------------------------------------------------------
+      !!                  ***  ROUTINE dia_ptr_iom  ***
+      !!----------------------------------------------------------------------
+      !! ** Purpose : Calculate diagnostics and send to XIOS
+      !!----------------------------------------------------------------------
+      INTEGER                         , INTENT(in)           ::   kt     ! ocean time-step index
+      INTEGER                         , INTENT(in)           ::   Kmm    ! time level index
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk)    , INTENT(in), OPTIONAL ::   pvtr   ! j-effective transport
       !
       INTEGER  ::   ji, jj, jk, jn   ! dummy loop indices
-      REAL(wp) ::   zsfc,zvfc               ! local scalar
       REAL(wp), DIMENSION(jpi,jpj)     ::  z2d   ! 2D workspace
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::  zmask   ! 3D workspace
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::  z3d    ! 3D workspace
-      REAL(wp), DIMENSION(jpi,jpj,jpk,jpts) ::  zts   ! 3D workspace
       REAL(wp), DIMENSION(jpj)      ::  zvsum, ztsum, zssum   ! 1D workspace
       !
@@ -90,112 +123,292 @@
       !!----------------------------------------------------------------------
       !
-      IF( ln_timing )   CALL timing_start('dia_ptr')
-
-      IF( kt == nit000 .AND. ll_init )   CALL dia_ptr_init   ! -> will define l_diaptr and nbasin
-      !
-      IF( .NOT. l_diaptr ) THEN
-         IF( ln_timing ) CALL timing_stop('dia_ptr')
-         RETURN
-      ENDIF
-      !
       ALLOCATE( z3dtr(jpi,jpj,nbasin) )
-      !
+
       IF( PRESENT( pvtr ) ) THEN
          IF( iom_use( 'zomsf' ) ) THEN    ! effective MSF
             ALLOCATE( z4d1(jpi,jpj,jpk,nbasin) )
+            !
             DO jn = 1, nbasin                                    ! by sub-basins
-               z4d1(1,:,:,jn) =  ptr_sjk( pvtr(:,:,:), btmsk34(:,:,jn) )  ! zonal cumulative effective transport excluding closed seas
-               DO jk = jpkm1, 1, -1 
+               z4d1(1,:,:,jn) =  pvtr_int(:,:,jp_vtr,jn)                  ! zonal cumulative effective transport excluding closed seas
+               DO jk = jpkm1, 1, -1
                   z4d1(1,:,jk,jn) = z4d1(1,:,jk+1,jn) - z4d1(1,:,jk,jn)    ! effective j-Stream-Function (MSF)
                END DO
-               DO ji = 1, jpi
+               DO ji = 2, jpi
                   z4d1(ji,:,:,jn) = z4d1(1,:,:,jn)
                ENDDO
             END DO
             CALL iom_put( 'zomsf', z4d1 * rc_sv )
+            !
             DEALLOCATE( z4d1 )
          ENDIF
+         IF( iom_use( 'sopstove' ) .OR. iom_use( 'sophtove' ) ) THEN
+            ALLOCATE( sjk(jpj,jpk,nbasin), r1_sjk(jpj,jpk,nbasin), v_msf(jpj,jpk,nbasin),   &
+               &      zt_jk(jpj,jpk,nbasin), zs_jk(jpj,jpk,nbasin) )
+            !
+            DO jn = 1, nbasin
+               sjk(:,:,jn) = pvtr_int(:,:,jp_msk,jn)
+               r1_sjk(:,:,jn) = 0._wp
+               WHERE( sjk(:,:,jn) /= 0._wp )   r1_sjk(:,:,jn) = 1._wp / sjk(:,:,jn)
+               ! i-mean T and S, j-Stream-Function, basin
+               zt_jk(:,:,jn) = pvtr_int(:,:,jp_tem,jn) * r1_sjk(:,:,jn)
+               zs_jk(:,:,jn) = pvtr_int(:,:,jp_sal,jn) * r1_sjk(:,:,jn)
+               v_msf(:,:,jn) = pvtr_int(:,:,jp_vtr,jn)
+               hstr_ove(:,jp_tem,jn) = SUM( v_msf(:,:,jn)*zt_jk(:,:,jn), 2 )
+               hstr_ove(:,jp_sal,jn) = SUM( v_msf(:,:,jn)*zs_jk(:,:,jn), 2 )
+               !
+            ENDDO
+            DO jn = 1, nbasin
+               z3dtr(1,:,jn) = hstr_ove(:,jp_tem,jn) * rc_pwatt  !  (conversion in PW)
+               DO ji = 2, jpi
+                  z3dtr(ji,:,jn) = z3dtr(1,:,jn)
+               ENDDO
+            ENDDO
+            CALL iom_put( 'sophtove', z3dtr )
+            DO jn = 1, nbasin
+               z3dtr(1,:,jn) = hstr_ove(:,jp_sal,jn) * rc_ggram !  (conversion in Gg)
+               DO ji = 2, jpi
+                  z3dtr(ji,:,jn) = z3dtr(1,:,jn)
+               ENDDO
+            ENDDO
+            CALL iom_put( 'sopstove', z3dtr )
+            !
+            DEALLOCATE( sjk, r1_sjk, v_msf, zt_jk, zs_jk )
+         ENDIF
+
+         IF( iom_use( 'sopstbtr' ) .OR. iom_use( 'sophtbtr' ) ) THEN
+            ! Calculate barotropic heat and salt transport here 
+            ALLOCATE( sjk(jpj,1,nbasin), r1_sjk(jpj,1,nbasin) )
+            !
+            DO jn = 1, nbasin
+               sjk(:,1,jn) = SUM( pvtr_int(:,:,jp_msk,jn), 2 )
+               r1_sjk(:,1,jn) = 0._wp
+               WHERE( sjk(:,1,jn) /= 0._wp )   r1_sjk(:,1,jn) = 1._wp / sjk(:,1,jn)
+               !
+               zvsum(:) =    SUM( pvtr_int(:,:,jp_vtr,jn), 2 )
+               ztsum(:) =    SUM( pvtr_int(:,:,jp_tem,jn), 2 )
+               zssum(:) =    SUM( pvtr_int(:,:,jp_sal,jn), 2 )
+               hstr_btr(:,jp_tem,jn) = zvsum(:) * ztsum(:) * r1_sjk(:,1,jn)
+               hstr_btr(:,jp_sal,jn) = zvsum(:) * zssum(:) * r1_sjk(:,1,jn)
+               !
+            ENDDO
+            DO jn = 1, nbasin
+               z3dtr(1,:,jn) = hstr_btr(:,jp_tem,jn) * rc_pwatt  !  (conversion in PW)
+               DO ji = 2, jpi
+                  z3dtr(ji,:,jn) = z3dtr(1,:,jn)
+               ENDDO
+            ENDDO
+            CALL iom_put( 'sophtbtr', z3dtr )
+            DO jn = 1, nbasin
+               z3dtr(1,:,jn) = hstr_btr(:,jp_sal,jn) * rc_ggram !  (conversion in Gg)
+               DO ji = 2, jpi
+                  z3dtr(ji,:,jn) = z3dtr(1,:,jn)
+               ENDDO
+            ENDDO
+            CALL iom_put( 'sopstbtr', z3dtr )
+            !
+            DEALLOCATE( sjk, r1_sjk )
+         ENDIF
+         !
+         hstr_ove(:,:,:) = 0._wp       ! Zero before next timestep
+         hstr_btr(:,:,:) = 0._wp
+         pvtr_int(:,:,:,:) = 0._wp
+      ELSE
+         IF( iom_use( 'zotem' ) .OR. iom_use( 'zosal' ) .OR. iom_use( 'zosrf' )  ) THEN    ! i-mean i-k-surface
+            ALLOCATE( z4d1(jpi,jpj,jpk,nbasin), z4d2(jpi,jpj,jpk,nbasin) )
+            !
+            DO jn = 1, nbasin
+               z4d1(1,:,:,jn) = pzon_int(:,:,jp_msk,jn)
+               DO ji = 2, jpi
+                  z4d1(ji,:,:,jn) = z4d1(1,:,:,jn)
+               ENDDO
+            ENDDO
+            CALL iom_put( 'zosrf', z4d1 )
+            !
+            DO jn = 1, nbasin
+               z4d2(1,:,:,jn) = pzon_int(:,:,jp_tem,jn) / MAX( z4d1(1,:,:,jn), 10.e-15 )
+               DO ji = 2, jpi
+                  z4d2(ji,:,:,jn) = z4d2(1,:,:,jn)
+               ENDDO
+            ENDDO
+            CALL iom_put( 'zotem', z4d2 )
+            !
+            DO jn = 1, nbasin
+               z4d2(1,:,:,jn) = pzon_int(:,:,jp_sal,jn) / MAX( z4d1(1,:,:,jn), 10.e-15 )
+               DO ji = 2, jpi
+                  z4d2(ji,:,:,jn) = z4d2(1,:,:,jn)
+               ENDDO
+            ENDDO
+            CALL iom_put( 'zosal', z4d2 )
+            !
+            DEALLOCATE( z4d1, z4d2 )
+         ENDIF
+         !
+         !                                ! Advective and diffusive heat and salt transport
+         IF( iom_use( 'sophtadv' ) .OR. iom_use( 'sopstadv' ) ) THEN  
+            ! 
+            DO jn = 1, nbasin
+               z3dtr(1,:,jn) = hstr_adv(:,jp_tem,jn) * rc_pwatt  !  (conversion in PW)
+               DO ji = 2, jpi
+                  z3dtr(ji,:,jn) = z3dtr(1,:,jn)
+               ENDDO
+            ENDDO
+            CALL iom_put( 'sophtadv', z3dtr )
+            DO jn = 1, nbasin
+               z3dtr(1,:,jn) = hstr_adv(:,jp_sal,jn) * rc_ggram !  (conversion in Gg)
+               DO ji = 2, jpi
+                  z3dtr(ji,:,jn) = z3dtr(1,:,jn)
+               ENDDO
+            ENDDO
+            CALL iom_put( 'sopstadv', z3dtr )
+         ENDIF
+         !
+         IF( iom_use( 'sophtldf' ) .OR. iom_use( 'sopstldf' ) ) THEN  
+            ! 
+            DO jn = 1, nbasin
+               z3dtr(1,:,jn) = hstr_ldf(:,jp_tem,jn) * rc_pwatt  !  (conversion in PW)
+               DO ji = 2, jpi
+                  z3dtr(ji,:,jn) = z3dtr(1,:,jn)
+               ENDDO
+            ENDDO
+            CALL iom_put( 'sophtldf', z3dtr )
+            DO jn = 1, nbasin
+               z3dtr(1,:,jn) = hstr_ldf(:,jp_sal,jn) * rc_ggram !  (conversion in Gg)
+               DO ji = 2, jpi
+                  z3dtr(ji,:,jn) = z3dtr(1,:,jn)
+               ENDDO
+            ENDDO
+            CALL iom_put( 'sopstldf', z3dtr )
+         ENDIF
+         !
+         IF( iom_use( 'sophteiv' ) .OR. iom_use( 'sopsteiv' ) ) THEN  
+            ! 
+            DO jn = 1, nbasin
+               z3dtr(1,:,jn) = hstr_eiv(:,jp_tem,jn) * rc_pwatt  !  (conversion in PW)
+               DO ji = 2, jpi
+                  z3dtr(ji,:,jn) = z3dtr(1,:,jn)
+               ENDDO
+            ENDDO
+            CALL iom_put( 'sophteiv', z3dtr )
+            DO jn = 1, nbasin
+               z3dtr(1,:,jn) = hstr_eiv(:,jp_sal,jn) * rc_ggram !  (conversion in Gg)
+               DO ji = 2, jpi
+                  z3dtr(ji,:,jn) = z3dtr(1,:,jn)
+               ENDDO
+            ENDDO
+            CALL iom_put( 'sopsteiv', z3dtr )
+         ENDIF
+         !
+         IF( iom_use( 'sopstvtr' ) .OR. iom_use( 'sophtvtr' ) ) THEN
+             DO jn = 1, nbasin
+                z3dtr(1,:,jn) = hstr_vtr(:,jp_tem,jn) * rc_pwatt  !  (conversion in PW)
+                DO ji = 2, jpi
+                   z3dtr(ji,:,jn) = z3dtr(1,:,jn)
+                ENDDO
+             ENDDO
+             CALL iom_put( 'sophtvtr', z3dtr )
+             DO jn = 1, nbasin
+               z3dtr(1,:,jn) = hstr_vtr(:,jp_sal,jn) * rc_ggram !  (conversion in Gg)
+               DO ji = 2, jpi
+                  z3dtr(ji,:,jn) = z3dtr(1,:,jn)
+               ENDDO
+            ENDDO
+            CALL iom_put( 'sopstvtr', z3dtr )
+         ENDIF
+         !
+         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
+         !
+         hstr_adv(:,:,:) = 0._wp       ! Zero before next timestep
+         hstr_ldf(:,:,:) = 0._wp
+         hstr_eiv(:,:,:) = 0._wp
+         hstr_vtr(:,:,:) = 0._wp
+         pzon_int(:,:,:,:) = 0._wp
+      ENDIF
+      !
+      DEALLOCATE( z3dtr )
+      !
+   END SUBROUTINE dia_ptr_iom
+
+
+   SUBROUTINE dia_ptr_zint( Kmm, pvtr )
+      !!----------------------------------------------------------------------
+      !!                    ***  ROUTINE dia_ptr_zint ***
+      !!----------------------------------------------------------------------
+      !! ** Purpose : i and i-k sum operations on arrays
+      !!
+      !! ** Method  : - Call ptr_sjk (i sum) or ptr_sj (i-k sum) to perform the sum operation
+      !!              - Call ptr_sum to add this result to the sum over tiles
+      !!
+      !! ** Action  : pvtr_int - terms for volume streamfunction, heat/salt transport barotropic/overturning terms
+      !!              pzon_int - terms for i mean temperature/salinity
+      !!----------------------------------------------------------------------
+      INTEGER                     , INTENT(in)           :: Kmm          ! time level index
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(in), OPTIONAL :: pvtr         ! j-effective transport
+      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE            :: zmask        ! 3D workspace
+      REAL(wp), DIMENSION(:,:,:,:), ALLOCATABLE          :: zts          ! 4D workspace
+      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE            :: sjk, v_msf   ! Zonal sum: i-k surface area, j-effective transport
+      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE            :: zt_jk, zs_jk ! Zonal sum: i-k surface area * (T, S)
+      REAL(wp)                                           :: zsfc, zvfc   ! i-k surface area
+      INTEGER  ::   ji, jj, jk, jn                                       ! dummy loop indices
+      !!----------------------------------------------------------------------
+
+      IF( PRESENT( pvtr ) ) THEN
+         ! i sum of effective j transport excluding closed seas
+         IF( iom_use( 'zomsf' ) .OR. iom_use( 'sopstove' ) .OR. iom_use( 'sophtove' ) ) THEN
+            ALLOCATE( v_msf(A1Dj(nn_hls),jpk,nbasin) )
+
+            DO jn = 1, nbasin
+               v_msf(:,:,jn) = ptr_sjk( pvtr(:,:,:), btmsk34(:,:,jn) )
+            ENDDO
+
+            CALL ptr_sum( pvtr_int(:,:,jp_vtr,:), v_msf(:,:,:) )
+
+            DEALLOCATE( v_msf )
+         ENDIF
+
+         ! i sum of j surface area, j surface area - temperature/salinity product on V grid
          IF(  iom_use( 'sopstove' ) .OR. iom_use( 'sophtove' ) .OR.   &
             & iom_use( 'sopstbtr' ) .OR. iom_use( 'sophtbtr' ) ) THEN
-            ! define fields multiplied by scalar
+            ALLOCATE( zmask(A2D(nn_hls),jpk), zts(A2D(nn_hls),jpk,jpts), &
+               &      sjk(A1Dj(nn_hls),jpk,nbasin), &
+               &      zt_jk(A1Dj(nn_hls),jpk,nbasin), zs_jk(A1Dj(nn_hls),jpk,nbasin) )
+
             zmask(:,:,:) = 0._wp
             zts(:,:,:,:) = 0._wp
+
             DO_3D( 1, 0, 1, 1, 1, jpkm1 )
                zvfc = e1v(ji,jj) * e3v(ji,jj,jk,Kmm)
                zmask(ji,jj,jk)      = vmask(ji,jj,jk)      * zvfc
-               zts(ji,jj,jk,jp_tem) = (ts(ji,jj,jk,jp_tem,Kmm)+ts(ji,jj+1,jk,jp_tem,Kmm)) * 0.5 * zvfc  !Tracers averaged onto V grid
+               zts(ji,jj,jk,jp_tem) = (ts(ji,jj,jk,jp_tem,Kmm)+ts(ji,jj+1,jk,jp_tem,Kmm)) * 0.5 * zvfc !Tracers averaged onto V grid
                zts(ji,jj,jk,jp_sal) = (ts(ji,jj,jk,jp_sal,Kmm)+ts(ji,jj+1,jk,jp_sal,Kmm)) * 0.5 * zvfc
             END_3D
-         ENDIF
-         IF( iom_use( 'sopstove' ) .OR. iom_use( 'sophtove' ) ) THEN
-            DO jn = 1, nbasin
-               ALLOCATE( sjk(jpj,jpk,nbasin), r1_sjk(jpj,jpk,nbasin), v_msf(jpj,jpk,nbasin),   &
-                  &                          zt_jk(jpj,jpk,nbasin), zs_jk(jpj,jpk,nbasin) )
-               sjk(:,:,jn) = ptr_sjk( zmask(:,:,:), btmsk(:,:,jn) )
-               r1_sjk(:,:,jn) = 0._wp
-               WHERE( sjk(:,:,jn) /= 0._wp )   r1_sjk(:,:,jn) = 1._wp / sjk(:,:,jn)
-               ! i-mean T and S, j-Stream-Function, basin
-               zt_jk(:,:,jn) = ptr_sjk( zts(:,:,:,jp_tem), btmsk(:,:,jn) ) * r1_sjk(:,:,jn)
-               zs_jk(:,:,jn) = ptr_sjk( zts(:,:,:,jp_sal), btmsk(:,:,jn) ) * r1_sjk(:,:,jn)
-               v_msf(:,:,jn) = ptr_sjk( pvtr(:,:,:), btmsk34(:,:,jn) ) 
-               hstr_ove(:,jp_tem,jn) = SUM( v_msf(:,:,jn)*zt_jk(:,:,jn), 2 )
-               hstr_ove(:,jp_sal,jn) = SUM( v_msf(:,:,jn)*zs_jk(:,:,jn), 2 )
-               DEALLOCATE( sjk, r1_sjk, v_msf, zt_jk, zs_jk )
-               !
-            ENDDO
-            DO jn = 1, nbasin
-               z3dtr(1,:,jn) = hstr_ove(:,jp_tem,jn) * rc_pwatt  !  (conversion in PW)
-               DO ji = 1, jpi
-                  z3dtr(ji,:,jn) = z3dtr(1,:,jn)
-               ENDDO
-            ENDDO
-            CALL iom_put( 'sophtove', z3dtr )
-            DO jn = 1, nbasin
-               z3dtr(1,:,jn) = hstr_ove(:,jp_sal,jn) * rc_ggram !  (conversion in Gg)
-               DO ji = 1, jpi
-                  z3dtr(ji,:,jn) = z3dtr(1,:,jn)
-               ENDDO
-            ENDDO
-            CALL iom_put( 'sopstove', z3dtr )
-         ENDIF
-
-         IF( iom_use( 'sopstbtr' ) .OR. iom_use( 'sophtbtr' ) ) THEN
-            ! Calculate barotropic heat and salt transport here 
-            DO jn = 1, nbasin
-               ALLOCATE( sjk(jpj,1,nbasin), r1_sjk(jpj,1,nbasin) )
-               sjk(:,1,jn) = ptr_sj( zmask(:,:,:), btmsk(:,:,jn) )
-               r1_sjk(:,1,jn) = 0._wp
-               WHERE( sjk(:,1,jn) /= 0._wp )   r1_sjk(:,1,jn) = 1._wp / sjk(:,1,jn)
-               !
-               zvsum(:) = ptr_sj( pvtr(:,:,:), btmsk34(:,:,jn) )
-               ztsum(:) = ptr_sj( zts(:,:,:,jp_tem), btmsk(:,:,jn) )
-               zssum(:) = ptr_sj( zts(:,:,:,jp_sal), btmsk(:,:,jn) )
-               hstr_btr(:,jp_tem,jn) = zvsum(:) * ztsum(:) * r1_sjk(:,1,jn)
-               hstr_btr(:,jp_sal,jn) = zvsum(:) * zssum(:) * r1_sjk(:,1,jn)
-               DEALLOCATE( sjk, r1_sjk )
-               !
-            ENDDO
-            DO jn = 1, nbasin
-               z3dtr(1,:,jn) = hstr_btr(:,jp_tem,jn) * rc_pwatt  !  (conversion in PW)
-               DO ji = 1, jpi
-                  z3dtr(ji,:,jn) = z3dtr(1,:,jn)
-               ENDDO
-            ENDDO
-            CALL iom_put( 'sophtbtr', z3dtr )
-            DO jn = 1, nbasin
-               z3dtr(1,:,jn) = hstr_btr(:,jp_sal,jn) * rc_ggram !  (conversion in Gg)
-               DO ji = 1, jpi
-                  z3dtr(ji,:,jn) = z3dtr(1,:,jn)
-               ENDDO
-            ENDDO
-            CALL iom_put( 'sopstbtr', z3dtr )
-         ENDIF 
-         !
+
+            DO jn = 1, nbasin
+               sjk(:,:,jn)   = ptr_sjk( zmask(:,:,:)     , btmsk(:,:,jn) )
+               zt_jk(:,:,jn) = ptr_sjk( zts(:,:,:,jp_tem), btmsk(:,:,jn) )
+               zs_jk(:,:,jn) = ptr_sjk( zts(:,:,:,jp_sal), btmsk(:,:,jn) )
+            ENDDO
+
+            CALL ptr_sum( pvtr_int(:,:,jp_msk,:), sjk(:,:,:)   )
+            CALL ptr_sum( pvtr_int(:,:,jp_tem,:), zt_jk(:,:,:) )
+            CALL ptr_sum( pvtr_int(:,:,jp_sal,:), zs_jk(:,:,:) )
+
+            DEALLOCATE( zmask, zts, sjk, zt_jk, zs_jk )
+         ENDIF
       ELSE
-         !
-         zmask(:,:,:) = 0._wp
-         zts(:,:,:,:) = 0._wp
-         IF( iom_use( 'zotem' ) .OR. iom_use( 'zosal' ) .OR. iom_use( 'zosrf' )  ) THEN    ! i-mean i-k-surface 
-            ALLOCATE( z4d1(jpi,jpj,jpk,nbasin), z4d2(jpi,jpj,jpk,nbasin) )
+         ! i sum of j surface area - temperature/salinity product on T grid
+         IF( iom_use( 'zotem' ) .OR. iom_use( 'zosal' ) .OR. iom_use( 'zosrf' )  ) THEN
+            ALLOCATE( zmask(A2D(nn_hls),jpk), zts(A2D(nn_hls),jpk,jpts), &
+               &      sjk(A1Dj(nn_hls),jpk,nbasin), &
+               &      zt_jk(A1Dj(nn_hls),jpk,nbasin), zs_jk(A1Dj(nn_hls),jpk,nbasin) )
+
+            zmask(:,:,:) = 0._wp
+            zts(:,:,:,:) = 0._wp
+
             DO_3D( 1, 1, 1, 1, 1, jpkm1 )
                zsfc = e1t(ji,jj) * e3t(ji,jj,jk,Kmm)
@@ -204,92 +417,24 @@
                zts(ji,jj,jk,jp_sal) = ts(ji,jj,jk,jp_sal,Kmm) * zsfc
             END_3D
-            !
-            DO jn = 1, nbasin
-               zmask(1,:,:) = ptr_sjk( zmask(:,:,:), btmsk(:,:,jn) )
-               DO ji = 1, jpi
-                  zmask(ji,:,:) = zmask(1,:,:)
-               ENDDO
-               z4d1(:,:,:,jn) = zmask(:,:,:)
-            ENDDO
-            CALL iom_put( 'zosrf', z4d1 )
-            !
-            DO jn = 1, nbasin
-               z4d2(1,:,:,jn) = ptr_sjk( zts(:,:,:,jp_tem), btmsk(:,:,jn) ) &
-                  &            / MAX( z4d1(1,:,:,jn), 10.e-15 )
-               DO ji = 1, jpi
-                  z4d2(ji,:,:,jn) = z4d2(1,:,:,jn)
-               ENDDO
-            ENDDO
-            CALL iom_put( 'zotem', z4d2 )
-            !
-            DO jn = 1, nbasin
-               z4d2(1,:,:,jn) = ptr_sjk( zts(:,:,:,jp_sal), btmsk(:,:,jn) ) &
-                  &            / MAX( z4d1(1,:,:,jn), 10.e-15 )
-               DO ji = 1, jpi
-                  z4d2(ji,:,:,jn) = z4d2(1,:,:,jn)
-               ENDDO
-            ENDDO
-            CALL iom_put( 'zosal', z4d2 )
-            DEALLOCATE( z4d1, z4d2 )
-            !
-         ENDIF
-         !
-         !                                ! Advective and diffusive heat and salt transport
-         IF( iom_use( 'sophtadv' ) .OR. iom_use( 'sopstadv' ) ) THEN  
-            ! 
-            DO jn = 1, nbasin
-               z3dtr(1,:,jn) = hstr_adv(:,jp_tem,jn) * rc_pwatt  !  (conversion in PW)
-               DO ji = 1, jpi
-                  z3dtr(ji,:,jn) = z3dtr(1,:,jn)
-               ENDDO
-            ENDDO
-            CALL iom_put( 'sophtadv', z3dtr )
-            DO jn = 1, nbasin
-               z3dtr(1,:,jn) = hstr_adv(:,jp_sal,jn) * rc_ggram !  (conversion in Gg)
-               DO ji = 1, jpi
-                  z3dtr(ji,:,jn) = z3dtr(1,:,jn)
-               ENDDO
-            ENDDO
-            CALL iom_put( 'sopstadv', z3dtr )
-         ENDIF
-         !
-         IF( iom_use( 'sophtldf' ) .OR. iom_use( 'sopstldf' ) ) THEN  
-            ! 
-            DO jn = 1, nbasin
-               z3dtr(1,:,jn) = hstr_ldf(:,jp_tem,jn) * rc_pwatt  !  (conversion in PW)
-               DO ji = 1, jpi
-                  z3dtr(ji,:,jn) = z3dtr(1,:,jn)
-               ENDDO
-            ENDDO
-            CALL iom_put( 'sophtldf', z3dtr )
-            DO jn = 1, nbasin
-               z3dtr(1,:,jn) = hstr_ldf(:,jp_sal,jn) * rc_ggram !  (conversion in Gg)
-               DO ji = 1, jpi
-                  z3dtr(ji,:,jn) = z3dtr(1,:,jn)
-               ENDDO
-            ENDDO
-            CALL iom_put( 'sopstldf', z3dtr )
-         ENDIF
-         !
-         IF( iom_use( 'sophteiv' ) .OR. iom_use( 'sopsteiv' ) ) THEN  
-            ! 
-            DO jn = 1, nbasin
-               z3dtr(1,:,jn) = hstr_eiv(:,jp_tem,jn) * rc_pwatt  !  (conversion in PW)
-               DO ji = 1, jpi
-                  z3dtr(ji,:,jn) = z3dtr(1,:,jn)
-               ENDDO
-            ENDDO
-            CALL iom_put( 'sophteiv', z3dtr )
-            DO jn = 1, nbasin
-               z3dtr(1,:,jn) = hstr_eiv(:,jp_sal,jn) * rc_ggram !  (conversion in Gg)
-               DO ji = 1, jpi
-                  z3dtr(ji,:,jn) = z3dtr(1,:,jn)
-               ENDDO
-            ENDDO
-            CALL iom_put( 'sopsteiv', z3dtr )
-         ENDIF
-         !
+
+            DO jn = 1, nbasin
+               sjk(:,:,jn)   = ptr_sjk( zmask(:,:,:)     , btmsk(:,:,jn) )
+               zt_jk(:,:,jn) = ptr_sjk( zts(:,:,:,jp_tem), btmsk(:,:,jn) )
+               zs_jk(:,:,jn) = ptr_sjk( zts(:,:,:,jp_sal), btmsk(:,:,jn) )
+            ENDDO
+
+            CALL ptr_sum( pzon_int(:,:,jp_msk,:), sjk(:,:,:)   )
+            CALL ptr_sum( pzon_int(:,:,jp_tem,:), zt_jk(:,:,:) )
+            CALL ptr_sum( pzon_int(:,:,jp_sal,:), zs_jk(:,:,:) )
+
+            DEALLOCATE( zmask, zts, sjk, zt_jk, zs_jk )
+         ENDIF
+
+         ! i-k sum of j surface area - temperature/salinity product on V grid
          IF( iom_use( 'sopstvtr' ) .OR. iom_use( 'sophtvtr' ) ) THEN
+            ALLOCATE( zts(A2D(nn_hls),jpk,jpts) )
+
             zts(:,:,:,:) = 0._wp
+
             DO_3D( 1, 0, 1, 1, 1, jpkm1 )
                zvfc = e1v(ji,jj) * e3v(ji,jj,jk,Kmm)
@@ -297,35 +442,12 @@
                zts(ji,jj,jk,jp_sal) = (ts(ji,jj,jk,jp_sal,Kmm)+ts(ji,jj+1,jk,jp_sal,Kmm)) * 0.5 * zvfc
             END_3D
-             CALL dia_ptr_hst( jp_tem, 'vtr', zts(:,:,:,jp_tem) )
-             CALL dia_ptr_hst( jp_sal, 'vtr', zts(:,:,:,jp_sal) )
-             DO jn = 1, nbasin
-                z3dtr(1,:,jn) = hstr_vtr(:,jp_tem,jn) * rc_pwatt  !  (conversion in PW)
-                DO ji = 1, jpi
-                   z3dtr(ji,:,jn) = z3dtr(1,:,jn)
-                ENDDO
-             ENDDO
-             CALL iom_put( 'sophtvtr', z3dtr )
-             DO jn = 1, nbasin
-               z3dtr(1,:,jn) = hstr_vtr(:,jp_sal,jn) * rc_ggram !  (conversion in Gg)
-               DO ji = 1, jpi
-                  z3dtr(ji,:,jn) = z3dtr(1,:,jn)
-               ENDDO
-            ENDDO
-            CALL iom_put( 'sopstvtr', z3dtr )
-         ENDIF
-         !
-         IF( iom_use( 'uocetr_vsum_cumul' ) ) THEN
-            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 )
-         ENDIF
-         !
+
+            CALL dia_ptr_hst( jp_tem, 'vtr', zts(:,:,:,jp_tem) )
+            CALL dia_ptr_hst( jp_sal, 'vtr', zts(:,:,:,jp_sal) )
+
+            DEALLOCATE( zts )
+         ENDIF
       ENDIF
-      !
-      DEALLOCATE( z3dtr )
-      !
-      IF( ln_timing )   CALL timing_stop('dia_ptr')
-      !
-   END SUBROUTINE dia_ptr
+   END SUBROUTINE dia_ptr_zint
 
 
@@ -340,5 +462,5 @@
       REAL(wp), DIMENSION(jpi,jpj) :: zmsk
       !!----------------------------------------------------------------------
-      
+
       ! l_diaptr is defined with iom_use
       !   --> dia_ptr_init must be done after the call to iom_init
@@ -347,8 +469,8 @@
          &       iom_use( 'zosrf'    ) .OR. iom_use( 'sopstove' ) .OR. iom_use( 'sophtove' ) .OR.  &
          &       iom_use( 'sopstbtr' ) .OR. iom_use( 'sophtbtr' ) .OR. iom_use( 'sophtadv' ) .OR.  &
-         &       iom_use( 'sopstadv' ) .OR. iom_use( 'sophtldf' ) .OR. iom_use( 'sopstldf' ) .OR.  & 
+         &       iom_use( 'sopstadv' ) .OR. iom_use( 'sophtldf' ) .OR. iom_use( 'sopstldf' ) .OR.  &
          &       iom_use( 'sophteiv' ) .OR. iom_use( 'sopsteiv' ) .OR. iom_use( 'sopstvtr' ) .OR.  &
-         &       iom_use( 'sophtvtr' ) .OR. iom_use( 'uocetr_vsum_cumul' ) 
- 
+         &       iom_use( 'sophtvtr' ) .OR. iom_use( 'uocetr_vsum_cumul' )
+      
       IF(lwp) THEN                     ! Control print
          WRITE(numout,*)
@@ -398,4 +520,6 @@
          hstr_btr(:,:,:) = 0._wp           !
          hstr_vtr(:,:,:) = 0._wp           !
+         pvtr_int(:,:,:,:) = 0._wp
+         pzon_int(:,:,:,:) = 0._wp
          !
          ll_init = .FALSE.
@@ -415,61 +539,101 @@
       INTEGER                         , INTENT(in )  :: ktra  ! tracer index
       CHARACTER(len=3)                , INTENT(in)   :: cptr  ! transport type  'adv'/'ldf'/'eiv'
-      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(in)   :: pvflx   ! 3D input array of advection/diffusion
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk)    , INTENT(in)   :: pvflx ! 3D input array of advection/diffusion
+      REAL(wp), DIMENSION(A1Dj(nn_hls),nbasin)                 :: zsj   !
       INTEGER                                        :: jn    !
 
+      DO jn = 1, nbasin
+         zsj(:,jn) = ptr_sj( pvflx(:,:,:), btmsk(:,:,jn) )
+      ENDDO
       !
       IF( cptr == 'adv' ) THEN
-         IF( ktra == jp_tem )  THEN
-             DO jn = 1, nbasin
-                hstr_adv(:,jp_tem,jn) = ptr_sj( pvflx(:,:,:), btmsk(:,:,jn) )
-             ENDDO
-         ENDIF
-         IF( ktra == jp_sal )  THEN
-             DO jn = 1, nbasin
-                hstr_adv(:,jp_sal,jn) = ptr_sj( pvflx(:,:,:), btmsk(:,:,jn) )
-             ENDDO
-         ENDIF
+         IF( ktra == jp_tem )  CALL ptr_sum( hstr_adv(:,jp_tem,:), zsj(:,:) )
+         IF( ktra == jp_sal )  CALL ptr_sum( hstr_adv(:,jp_sal,:), zsj(:,:) )
+      ELSE IF( cptr == 'ldf' ) THEN
+         IF( ktra == jp_tem )  CALL ptr_sum( hstr_ldf(:,jp_tem,:), zsj(:,:) )
+         IF( ktra == jp_sal )  CALL ptr_sum( hstr_ldf(:,jp_sal,:), zsj(:,:) )
+      ELSE IF( cptr == 'eiv' ) THEN
+         IF( ktra == jp_tem )  CALL ptr_sum( hstr_eiv(:,jp_tem,:), zsj(:,:) )
+         IF( ktra == jp_sal )  CALL ptr_sum( hstr_eiv(:,jp_sal,:), zsj(:,:) )
+      ELSE IF( cptr == 'vtr' ) THEN
+         IF( ktra == jp_tem )  CALL ptr_sum( hstr_vtr(:,jp_tem,:), zsj(:,:) )
+         IF( ktra == jp_sal )  CALL ptr_sum( hstr_vtr(:,jp_sal,:), zsj(:,:) )
       ENDIF
       !
-      IF( cptr == 'ldf' ) THEN
-         IF( ktra == jp_tem )  THEN
-             DO jn = 1, nbasin
-                hstr_ldf(:,jp_tem,jn) = ptr_sj( pvflx(:,:,:), btmsk(:,:,jn) )
-             ENDDO
-         ENDIF
-         IF( ktra == jp_sal )  THEN
-             DO jn = 1, nbasin
-                hstr_ldf(:,jp_sal,jn) = ptr_sj( pvflx(:,:,:), btmsk(:,:,jn) )
-             ENDDO
-         ENDIF
+   END SUBROUTINE dia_ptr_hst
+
+
+   SUBROUTINE ptr_sum_2d( phstr, pva )
+      !!----------------------------------------------------------------------
+      !!                    ***  ROUTINE ptr_sum_2d ***
+      !!----------------------------------------------------------------------
+      !! ** Purpose : Add two 2D arrays with (j,nbasin) dimensions
+      !!
+      !! ** Method  : - phstr = phstr + pva
+      !!              - Call mpp_sum if the final tile
+      !!
+      !! ** Action  : phstr
+      !!----------------------------------------------------------------------
+      REAL(wp), DIMENSION(jpj,nbasin) , INTENT(inout)         ::  phstr  !
+      REAL(wp), DIMENSION(A1Dj(nn_hls),nbasin), INTENT(in)            ::  pva    !
+      INTEGER                                               ::  jj
+#if defined key_mpp_mpi
+      INTEGER, DIMENSION(1)           ::  ish1d
+      INTEGER, DIMENSION(2)           ::  ish2d
+      REAL(wp), DIMENSION(jpj*nbasin) ::  zwork
+#endif
+
+      DO jj = ntsj, ntej
+         phstr(jj,:) = phstr(jj,:)  + pva(jj,:)
+      END DO
+
+#if defined key_mpp_mpi
+      IF( ntile == 0 .OR. ntile == nijtile ) THEN
+         ish1d(1) = jpj*nbasin
+         ish2d(1) = jpj ; ish2d(2) = nbasin
+         zwork(:) = RESHAPE( phstr(:,:), ish1d )
+         CALL mpp_sum( 'diaptr', zwork, ish1d(1), ncomm_znl )
+         phstr(:,:) = RESHAPE( zwork, ish2d )
       ENDIF
-      !
-      IF( cptr == 'eiv' ) THEN
-         IF( ktra == jp_tem )  THEN
-             DO jn = 1, nbasin
-                hstr_eiv(:,jp_tem,jn) = ptr_sj( pvflx(:,:,:), btmsk(:,:,jn) )
-             ENDDO
-         ENDIF
-         IF( ktra == jp_sal )  THEN
-             DO jn = 1, nbasin
-                hstr_eiv(:,jp_sal,jn) = ptr_sj( pvflx(:,:,:), btmsk(:,:,jn) )
-             ENDDO
-         ENDIF
+#endif
+   END SUBROUTINE ptr_sum_2d
+
+
+   SUBROUTINE ptr_sum_3d( phstr, pva )
+      !!----------------------------------------------------------------------
+      !!                    ***  ROUTINE ptr_sum_3d ***
+      !!----------------------------------------------------------------------
+      !! ** Purpose : Add two 3D arrays with (j,k,nbasin) dimensions
+      !!
+      !! ** Method  : - phstr = phstr + pva
+      !!              - Call mpp_sum if the final tile
+      !!
+      !! ** Action  : phstr
+      !!----------------------------------------------------------------------
+      REAL(wp), DIMENSION(jpj,jpk,nbasin) , INTENT(inout)     ::  phstr  !
+      REAL(wp), DIMENSION(A1Dj(nn_hls),jpk,nbasin), INTENT(in)        ::  pva    !
+      INTEGER                                               ::  jj, jk
+#if defined key_mpp_mpi
+      INTEGER, DIMENSION(1)              ::  ish1d
+      INTEGER, DIMENSION(3)              ::  ish3d
+      REAL(wp), DIMENSION(jpj*jpk*nbasin)  ::  zwork
+#endif
+
+      DO jk = 1, jpk
+         DO jj = ntsj, ntej
+            phstr(jj,jk,:) = phstr(jj,jk,:)  + pva(jj,jk,:)
+         END DO
+      END DO
+
+#if defined key_mpp_mpi
+      IF( ntile == 0 .OR. ntile == nijtile ) THEN
+         ish1d(1) = jpj*jpk*nbasin
+         ish3d(1) = jpj ; ish3d(2) = jpk ; ish3d(3) = nbasin
+         zwork(:) = RESHAPE( phstr(:,:,:), ish1d )
+         CALL mpp_sum( 'diaptr', zwork, ish1d(1), ncomm_znl )
+         phstr(:,:,:) = RESHAPE( zwork, ish3d )
       ENDIF
-      !
-      IF( cptr == 'vtr' ) THEN
-         IF( ktra == jp_tem )  THEN
-             DO jn = 1, nbasin
-                hstr_vtr(:,jp_tem,jn) = ptr_sj( pvflx(:,:,:), btmsk(:,:,jn) )
-             ENDDO
-         ENDIF
-         IF( ktra == jp_sal )  THEN
-             DO jn = 1, nbasin
-                hstr_vtr(:,jp_sal,jn) = ptr_sj( pvflx(:,:,:), btmsk(:,:,jn) )
-             ENDDO
-         ENDIF
-      ENDIF
-      !
-   END SUBROUTINE dia_ptr_hst
+#endif
+   END SUBROUTINE ptr_sum_3d
 
 
@@ -479,5 +643,5 @@
       !!----------------------------------------------------------------------
       INTEGER               ::   dia_ptr_alloc   ! return value
-      INTEGER, DIMENSION(3) ::   ierr
+      INTEGER, DIMENSION(2) ::   ierr
       !!----------------------------------------------------------------------
       ierr(:) = 0
@@ -491,5 +655,6 @@
             &      hstr_ldf(jpj,jpts,nbasin), hstr_vtr(jpj,jpts,nbasin), STAT=ierr(1)  )
             !
-         ALLOCATE( p_fval1d(jpj), p_fval2d(jpj,jpk), Stat=ierr(2))
+         ALLOCATE( pvtr_int(jpj,jpk,jpts+2,nbasin), &
+            &      pzon_int(jpj,jpk,jpts+1,nbasin), STAT=ierr(2) )
          !
          dia_ptr_alloc = MAXVAL( ierr )
@@ -511,23 +676,15 @@
       !! ** Action  : - p_fval: i-k-mean poleward flux of pvflx
       !!----------------------------------------------------------------------
-      REAL(wp), INTENT(in), DIMENSION(jpi,jpj,jpk)  ::   pvflx  ! mask flux array at V-point
-      REAL(wp), INTENT(in), DIMENSION(jpi,jpj)      ::   pmsk   ! Optional 2D basin mask
+      REAL(wp), INTENT(in), DIMENSION(A2D(nn_hls),jpk)  ::   pvflx  ! mask flux array at V-point
+      REAL(wp), INTENT(in), DIMENSION(jpi,jpj)  ::   pmsk   ! Optional 2D basin mask
       !
       INTEGER                  ::   ji, jj, jk   ! dummy loop arguments
-      INTEGER                  ::   ijpj         ! ???
-      REAL(wp), POINTER, DIMENSION(:) :: p_fval  ! function value
+      REAL(wp), DIMENSION(A1Dj(nn_hls)) :: p_fval  ! function value
       !!--------------------------------------------------------------------
       !
-      p_fval => p_fval1d
-
-      ijpj = jpj
       p_fval(:) = 0._wp
       DO_3D( 0, 0, 0, 0, 1, jpkm1 )
          p_fval(jj) = p_fval(jj) + pvflx(ji,jj,jk) * pmsk(ji,jj) * tmask_i(ji,jj)
       END_3D
-#if defined key_mpp_mpi
-      CALL mpp_sum( 'diaptr', p_fval, ijpj, ncomm_znl)
-#endif
-      !
    END FUNCTION ptr_sj_3d
 
@@ -544,23 +701,15 @@
       !! ** Action  : - p_fval: i-k-mean poleward flux of pvflx
       !!----------------------------------------------------------------------
-      REAL(wp) , INTENT(in), DIMENSION(jpi,jpj) ::   pvflx  ! mask flux array at V-point
+      REAL(wp) , INTENT(in), DIMENSION(A2D(nn_hls))     ::   pvflx  ! mask flux array at V-point
       REAL(wp) , INTENT(in), DIMENSION(jpi,jpj) ::   pmsk   ! Optional 2D basin mask
       !
       INTEGER                  ::   ji,jj       ! dummy loop arguments
-      INTEGER                  ::   ijpj        ! ???
-      REAL(wp), POINTER, DIMENSION(:) :: p_fval ! function value
+      REAL(wp), DIMENSION(A1Dj(nn_hls)) :: p_fval ! function value
       !!--------------------------------------------------------------------
-      ! 
-      p_fval => p_fval1d
-
-      ijpj = jpj
+      !
       p_fval(:) = 0._wp
       DO_2D( 0, 0, 0, 0 )
          p_fval(jj) = p_fval(jj) + pvflx(ji,jj) * pmsk(ji,jj) * tmask_i(ji,jj)
       END_2D
-#if defined key_mpp_mpi
-      CALL mpp_sum( 'diaptr', p_fval, ijpj, ncomm_znl )
-#endif
-      ! 
    END FUNCTION ptr_sj_2d
 
@@ -588,5 +737,4 @@
             p_fval(ji,jj) = p_fval(ji,jj-1) + pva(ji,jj) * tmask_i(ji,jj)
          END_2D
-         CALL lbc_lnk( 'diaptr', p_fval, 'U', -1.0_wp )
       END DO
       ! 
@@ -607,19 +755,11 @@
       !!
       IMPLICIT none
-      REAL(wp) , INTENT(in), DIMENSION(jpi,jpj,jpk) ::   pta    ! mask flux array at V-point
-      REAL(wp) , INTENT(in), DIMENSION(jpi,jpj)     ::   pmsk   ! Optional 2D basin mask
+      REAL(wp) , INTENT(in), DIMENSION(A2D(nn_hls),jpk) ::   pta    ! mask flux array at V-point
+      REAL(wp) , INTENT(in), DIMENSION(jpi,jpj) ::   pmsk   ! Optional 2D basin mask
       !!
       INTEGER                           :: ji, jj, jk ! dummy loop arguments
-      REAL(wp), POINTER, DIMENSION(:,:) :: p_fval     ! return function value
-#if defined key_mpp_mpi
-      INTEGER, DIMENSION(1) ::   ish
-      INTEGER, DIMENSION(2) ::   ish2
-      INTEGER               ::   ijpjjpk
-      REAL(wp), DIMENSION(jpj*jpk) ::   zwork    ! mask flux array at V-point
-#endif
+      REAL(wp), DIMENSION(A1Dj(nn_hls),jpk) :: p_fval     ! return function value
       !!--------------------------------------------------------------------
       !
-      p_fval => p_fval2d
-
       p_fval(:,:) = 0._wp
       !
@@ -627,13 +767,4 @@
          p_fval(jj,jk) = p_fval(jj,jk) + pta(ji,jj,jk) * pmsk(ji,jj) * tmask_i(ji,jj)
       END_3D
-      !
-#if defined key_mpp_mpi
-      ijpjjpk = jpj*jpk
-      ish(1) = ijpjjpk  ;   ish2(1) = jpj   ;   ish2(2) = jpk
-      zwork(1:ijpjjpk) = RESHAPE( p_fval, ish )
-      CALL mpp_sum( 'diaptr', zwork, ijpjjpk, ncomm_znl )
-      p_fval(:,:) = RESHAPE( zwork, ish2 )
-#endif
-      !
    END FUNCTION ptr_sjk
 
Index: /NEMO/trunk/src/OCE/DOM/dom_oce.F90
===================================================================
--- /NEMO/trunk/src/OCE/DOM/dom_oce.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/DOM/dom_oce.F90	(revision 13982)
@@ -74,4 +74,14 @@
    LOGICAL, PUBLIC ::   l_Iperio, l_Jperio   !   should we explicitely take care I/J periodicity 
 
+   ! Tiling namelist
+   LOGICAL, PUBLIC ::   ln_tile
+   INTEGER         ::   nn_ltile_i, nn_ltile_j
+
+   ! Domain tiling (all tiles)
+   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       !
+
    !                             !: domain MPP decomposition parameters
    INTEGER             , PUBLIC ::   nimpp, njmpp     !: i- & j-indexes for mpp-subdomain left bottom
@@ -87,4 +97,8 @@
    INTEGER, PUBLIC ::   noea, nowe        !: index of the local neighboring processors in
    INTEGER, PUBLIC ::   noso, nono        !: east, west, south and north directions
+   INTEGER, PUBLIC ::   nones, nonws        !: north-east, north-west directions for sending 
+   INTEGER, PUBLIC ::   noses, nosws        !: south-east, south-west directions for sending
+   INTEGER, PUBLIC ::   noner, nonwr        !: north-east, north-west directions for receiving
+   INTEGER, PUBLIC ::   noser, noswr        !: south-east, south-west directions for receiving
    INTEGER, PUBLIC ::   nidom             !: ???
 
@@ -296,9 +310,9 @@
       ALLOCATE( e3t(jpi,jpj,jpk,jpt) , e3u (jpi,jpj,jpk,jpt) , e3v (jpi,jpj,jpk,jpt) , e3f(jpi,jpj,jpk) ,      &
          &      e3w(jpi,jpj,jpk,jpt) , e3uw(jpi,jpj,jpk,jpt) , e3vw(jpi,jpj,jpk,jpt)                    ,  STAT=ierr(ii) )
-#endif  
+#endif
          !
       ii = ii+1
       ALLOCATE( r3t  (jpi,jpj,jpt)   , r3u  (jpi,jpj,jpt)    , r3v  (jpi,jpj,jpt)    , r3f  (jpi,jpj) ,  &
-         &      r3t_f(jpi,jpj)       , r3u_f(jpi,jpj)        , r3v_f(jpi,jpj)                         ,  STAT=ierr(ii) )       
+         &      r3t_f(jpi,jpj)       , r3u_f(jpi,jpj)        , r3v_f(jpi,jpj)                         ,  STAT=ierr(ii) )
          !
       ii = ii+1
@@ -317,5 +331,5 @@
          !
       ii = ii+1
-      ALLOCATE( risfdep(jpi,jpj) , bathy(jpi,jpj) , STAT=ierr(ii)  ) 
+      ALLOCATE( risfdep(jpi,jpj) , bathy(jpi,jpj) , STAT=ierr(ii)  )
          !
       ii = ii+1
@@ -323,5 +337,5 @@
          !
       ii = ii+1
-      ALLOCATE( tmask_i(jpi,jpj) , tmask_h(jpi,jpj) ,                        & 
+      ALLOCATE( tmask_i(jpi,jpj) , tmask_h(jpi,jpj) ,                        &
          &      ssmask (jpi,jpj) , ssumask(jpi,jpj) , ssvmask(jpi,jpj) , ssfmask(jpi,jpj) ,     &
          &      mbkt   (jpi,jpj) , mbku   (jpi,jpj) , mbkv   (jpi,jpj) ,                    STAT=ierr(ii) )
@@ -331,5 +345,5 @@
          !
       ii = ii+1
-      ALLOCATE( tmask(jpi,jpj,jpk) , umask(jpi,jpj,jpk) ,     & 
+      ALLOCATE( tmask(jpi,jpj,jpk) , umask(jpi,jpj,jpk) ,     &
          &      vmask(jpi,jpj,jpk) , fmask(jpi,jpj,jpk) , STAT=ierr(ii) )
          !
Index: /NEMO/trunk/src/OCE/DOM/domain.F90
===================================================================
--- /NEMO/trunk/src/OCE/DOM/domain.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/DOM/domain.F90	(revision 13982)
@@ -45,4 +45,5 @@
    USE closea , ONLY : dom_clo ! closed seas
    !
+   USE prtctl         ! Print control (prt_ctl_info routine)
    USE in_out_manager ! I/O manager
    USE iom            ! I/O library
@@ -55,4 +56,5 @@
    PUBLIC   dom_init     ! called by nemogcm.F90
    PUBLIC   domain_cfg   ! called by nemogcm.F90
+   PUBLIC   dom_tile     ! called by step.F90
 
    !!-------------------------------------------------------------------------
@@ -124,6 +126,8 @@
       !           !==  Reference coordinate system  ==!
       !
-      CALL dom_glo                     ! global domain versus local domain
-      CALL dom_nam                     ! read namelist ( namrun, namdom )
+      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_hgr                      ! Horizontal mesh
@@ -273,4 +277,87 @@
 
 
+   SUBROUTINE dom_tile( ktsi, ktsj, ktei, ktej, ktile )
+      !!----------------------------------------------------------------------
+      !!                     ***  ROUTINE dom_tile  ***
+      !!
+      !! ** Purpose :   Set tile domain variables
+      !!
+      !! ** 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
+      !!----------------------------------------------------------------------
+      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)
+
+         IF(sn_cfctl%l_prtctl) THEN
+            WRITE(charout, FMT="('ntile =', I4)") ktile
+            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
+   END SUBROUTINE dom_tile
+
+
    SUBROUTINE dom_nam
       !!----------------------------------------------------------------------
@@ -281,4 +368,5 @@
       !! ** input   : - namrun namelist
       !!              - namdom namelist
+      !!              - namtile namelist
       !!              - namnc4 namelist   ! "key_netcdf4" only
       !!----------------------------------------------------------------------
@@ -293,4 +381,5 @@
          &             ln_cfmeta, ln_xios_read, nn_wxios
       NAMELIST/namdom/ ln_linssh, rn_Dt, rn_atfp, ln_crs, ln_meshmask
+      NAMELIST/namtile/ ln_tile, nn_ltile_i, nn_ltile_j
 #if defined key_netcdf4
       NAMELIST/namnc4/ nn_nchunks_i, nn_nchunks_j, nn_nchunks_k, ln_nc4zip
@@ -429,4 +518,24 @@
       r1_Dt = 1._wp / rDt
 
+      READ  ( numnam_ref, namtile, IOSTAT = ios, ERR = 905 )
+905   IF( ios /= 0 )   CALL ctl_nam ( ios , 'namtile in reference namelist' )
+      READ  ( numnam_cfg, namtile, IOSTAT = ios, ERR = 906 )
+906   IF( ios >  0 )   CALL ctl_nam ( ios , 'namtile in configuration namelist' )
+      IF(lwm) WRITE( numond, namtile )
+
+      IF(lwp) THEN
+         WRITE(numout,*)
+         WRITE(numout,*)    '   Namelist : namtile   ---   Domain tiling decomposition'
+         WRITE(numout,*)    '      Tiling (T) or not (F)                ln_tile    = ', ln_tile
+         WRITE(numout,*)    '      Length of tile in i                  nn_ltile_i = ', nn_ltile_i
+         WRITE(numout,*)    '      Length of tile in j                  nn_ltile_j = ', nn_ltile_j
+         WRITE(numout,*)
+         IF( ln_tile ) THEN
+            WRITE(numout,*) '      The domain will be decomposed into tiles of size', nn_ltile_i, 'x', nn_ltile_j
+         ELSE
+            WRITE(numout,*) '      Domain tiling will NOT be used'
+         ENDIF
+      ENDIF
+
       IF( TRIM(Agrif_CFixed()) == '0' ) THEN
          lrxios = ln_xios_read.AND.ln_rstart
Index: /NEMO/trunk/src/OCE/DOM/domutl.F90
===================================================================
--- /NEMO/trunk/src/OCE/DOM/domutl.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/DOM/domutl.F90	(revision 13982)
@@ -21,6 +21,11 @@
    PRIVATE
 
+   INTERFACE is_tile
+      MODULE PROCEDURE is_tile_2d, is_tile_3d, is_tile_4d
+   END INTERFACE is_tile
+
    PUBLIC dom_ngb    ! routine called in iom.F90 module
    PUBLIC dom_uniq   ! Called by dommsk and domwri
+   PUBLIC is_tile
 
    !!----------------------------------------------------------------------
@@ -109,5 +114,44 @@
       !
    END SUBROUTINE dom_uniq
-   
+
+
+   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
+      ELSE
+         is_tile_2d = 0
+      ENDIF
+   END FUNCTION is_tile_2d
+
+
+   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
+      ELSE
+         is_tile_3d = 0
+      ENDIF
+   END FUNCTION is_tile_3d
+
+
+   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
+      ELSE
+         is_tile_4d = 0
+      ENDIF
+   END FUNCTION is_tile_4d
+
    !!======================================================================
 END MODULE domutl
Index: /NEMO/trunk/src/OCE/DOM/domvvl.F90
===================================================================
--- /NEMO/trunk/src/OCE/DOM/domvvl.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/DOM/domvvl.F90	(revision 13982)
@@ -422,5 +422,4 @@
          !                             (stored for tracer advction and continuity equation)
          CALL lbc_lnk_multi( 'domvvl', un_td , 'U' , -1._wp, vn_td , 'V' , -1._wp)
-
          ! 4 - Time stepping of baroclinic scale factors
          ! ---------------------------------------------
Index: /NEMO/trunk/src/OCE/DOM/dtatsd.F90
===================================================================
--- /NEMO/trunk/src/OCE/DOM/dtatsd.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/DOM/dtatsd.F90	(revision 13982)
@@ -18,4 +18,5 @@
    USE phycst          ! physical constants
    USE dom_oce         ! ocean space and time domain
+   USE domain, ONLY : dom_tile
    USE fldread         ! read input fields
    !
@@ -135,56 +136,67 @@
       !! ** Action  :   ptsd   T-S data on medl mesh and interpolated at time-step kt
       !!----------------------------------------------------------------------
-      INTEGER                              , INTENT(in   ) ::   kt     ! ocean time-step
-      REAL(wp), DIMENSION(jpi,jpj,jpk,jpts), INTENT(  out) ::   ptsd   ! T & S data
+      INTEGER                          , INTENT(in   ) ::   kt     ! ocean time-step
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk,jpts), INTENT(  out) ::   ptsd   ! T & S data
       !
       INTEGER ::   ji, jj, jk, jl, jkk   ! dummy loop indicies
       INTEGER ::   ik, il0, il1, ii0, ii1, ij0, ij1   ! local integers
+      INTEGER ::   itile
       REAL(wp)::   zl, zi                             ! local scalars
       REAL(wp), DIMENSION(jpk) ::  ztp, zsp   ! 1D workspace
       !!----------------------------------------------------------------------
       !
-      CALL fld_read( kt, 1, sf_tsd )      !==   read T & S data at kt time step   ==!
+      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
+            CALL fld_read( kt, 1, sf_tsd )   !==   read T & S data at kt time step   ==!
       !
       !
 !!gm  This should be removed from the code   ===>>>>  T & S files has to be changed
-      !
-      !                                   !==   ORCA_R2 configuration and T & S damping   ==! 
-      IF( cn_cfg == "orca" .OR. cn_cfg == "ORCA" ) THEN
-         IF( nn_cfg == 2 .AND. ln_tsd_dmp ) THEN    ! some hand made alterations
-            !
-            ij0 = 101 + nn_hls       ;   ij1 = 109 + nn_hls                       ! Reduced T & S in the Alboran Sea
-            ii0 = 141 + nn_hls - 1   ;   ii1 = 155 + nn_hls - 1
-            DO jj = mj0(ij0), mj1(ij1)
-               DO ji = mi0(ii0), mi1(ii1)
-                  sf_tsd(jp_tem)%fnow(ji,jj,13:13) = sf_tsd(jp_tem)%fnow(ji,jj,13:13) - 0.20_wp
-                  sf_tsd(jp_tem)%fnow(ji,jj,14:15) = sf_tsd(jp_tem)%fnow(ji,jj,14:15) - 0.35_wp
-                  sf_tsd(jp_tem)%fnow(ji,jj,16:25) = sf_tsd(jp_tem)%fnow(ji,jj,16:25) - 0.40_wp
-                  !
-                  sf_tsd(jp_sal)%fnow(ji,jj,13:13) = sf_tsd(jp_sal)%fnow(ji,jj,13:13) - 0.15_wp
-                  sf_tsd(jp_sal)%fnow(ji,jj,14:15) = sf_tsd(jp_sal)%fnow(ji,jj,14:15) - 0.25_wp
-                  sf_tsd(jp_sal)%fnow(ji,jj,16:17) = sf_tsd(jp_sal)%fnow(ji,jj,16:17) - 0.30_wp
-                  sf_tsd(jp_sal)%fnow(ji,jj,18:25) = sf_tsd(jp_sal)%fnow(ji,jj,18:25) - 0.35_wp
+         !
+         !                                   !==   ORCA_R2 configuration and T & S damping   ==!
+         IF( cn_cfg == "orca" .OR. cn_cfg == "ORCA" ) THEN
+            IF( nn_cfg == 2 .AND. ln_tsd_dmp ) THEN    ! some hand made alterations
+               !
+               ij0 = 101 + nn_hls       ;   ij1 = 109 + nn_hls                       ! Reduced T & S in the Alboran Sea
+               ii0 = 141 + nn_hls - 1   ;   ii1 = 155 + nn_hls - 1
+               DO jj = mj0(ij0), mj1(ij1)
+                  DO ji = mi0(ii0), mi1(ii1)
+                     sf_tsd(jp_tem)%fnow(ji,jj,13:13) = sf_tsd(jp_tem)%fnow(ji,jj,13:13) - 0.20_wp
+                     sf_tsd(jp_tem)%fnow(ji,jj,14:15) = sf_tsd(jp_tem)%fnow(ji,jj,14:15) - 0.35_wp
+                     sf_tsd(jp_tem)%fnow(ji,jj,16:25) = sf_tsd(jp_tem)%fnow(ji,jj,16:25) - 0.40_wp
+                     !
+                     sf_tsd(jp_sal)%fnow(ji,jj,13:13) = sf_tsd(jp_sal)%fnow(ji,jj,13:13) - 0.15_wp
+                     sf_tsd(jp_sal)%fnow(ji,jj,14:15) = sf_tsd(jp_sal)%fnow(ji,jj,14:15) - 0.25_wp
+                     sf_tsd(jp_sal)%fnow(ji,jj,16:17) = sf_tsd(jp_sal)%fnow(ji,jj,16:17) - 0.30_wp
+                     sf_tsd(jp_sal)%fnow(ji,jj,18:25) = sf_tsd(jp_sal)%fnow(ji,jj,18:25) - 0.35_wp
+                  END DO
                END DO
-            END DO
-            ij0 =  87 + nn_hls       ;   ij1 =  96 + nn_hls                       ! Reduced temperature in Red Sea
-            ii0 = 148 + nn_hls - 1   ;   ii1 = 160 + nn_hls - 1
-            sf_tsd(jp_tem)%fnow( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ,  4:10 ) = 7.0_wp
-            sf_tsd(jp_tem)%fnow( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) , 11:13 ) = 6.5_wp
-            sf_tsd(jp_tem)%fnow( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) , 14:20 ) = 6.0_wp
-         ENDIF
-      ENDIF
+               ij0 =  87 + nn_hls       ;   ij1 =  96 + nn_hls                       ! Reduced temperature in Red Sea
+               ii0 = 148 + nn_hls - 1   ;   ii1 = 160 + nn_hls - 1
+               sf_tsd(jp_tem)%fnow( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ,  4:10 ) = 7.0_wp
+               sf_tsd(jp_tem)%fnow( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) , 11:13 ) = 6.5_wp
+               sf_tsd(jp_tem)%fnow( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) , 14:20 ) = 6.0_wp
+            ENDIF
+         ENDIF
 !!gm end
-      !
-      ptsd(:,:,:,jp_tem) = sf_tsd(jp_tem)%fnow(:,:,:)    ! NO mask
-      ptsd(:,:,:,jp_sal) = sf_tsd(jp_sal)%fnow(:,:,:) 
+         IF( ln_tile ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = itile )            ! Revert to tile domain
+      ENDIF
+      !
+      DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpk )
+         ptsd(ji,jj,jk,jp_tem) = sf_tsd(jp_tem)%fnow(ji,jj,jk)    ! NO mask
+         ptsd(ji,jj,jk,jp_sal) = sf_tsd(jp_sal)%fnow(ji,jj,jk)
+      END_3D
       !
       IF( ln_sco ) THEN                   !==   s- or mixed s-zps-coordinate   ==!
          !
-         IF( kt == nit000 .AND. lwp )THEN
-            WRITE(numout,*)
-            WRITE(numout,*) 'dta_tsd: interpolates T & S data onto the s- or mixed s-z-coordinate mesh'
-         ENDIF
-         !
-         DO_2D( 1, 1, 1, 1 )                  ! vertical interpolation of T & S
+         IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+            IF( kt == nit000 .AND. lwp )THEN
+               WRITE(numout,*)
+               WRITE(numout,*) 'dta_tsd: interpolates T & S data onto the s- or mixed s-z-coordinate mesh'
+            ENDIF
+         ENDIF
+         !
+         ! NOTE: [tiling-comms-merge] This fix was necessary to take out tra_adv lbc_lnk statements in the zps case, but did not work in the zco case
+         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)
@@ -215,9 +227,12 @@
       ELSE                                !==   z- or zps- coordinate   ==!
          !                             
-         ptsd(:,:,:,jp_tem) = ptsd(:,:,:,jp_tem) * tmask(:,:,:)    ! Mask
-         ptsd(:,:,:,jp_sal) = ptsd(:,:,:,jp_sal) * tmask(:,:,:)
+         DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpk )
+            ptsd(ji,jj,jk,jp_tem) = ptsd(ji,jj,jk,jp_tem) * tmask(ji,jj,jk)    ! Mask
+            ptsd(ji,jj,jk,jp_sal) = ptsd(ji,jj,jk,jp_sal) * tmask(ji,jj,jk)
+         END_3D
          !
          IF( ln_zps ) THEN                      ! zps-coordinate (partial steps) interpolation at the last ocean level
-            DO_2D( 1, 1, 1, 1 )
+            ! NOTE: [tiling-comms-merge] This fix was necessary to take out tra_adv lbc_lnk statements in the zps case
+            DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
                ik = mbkt(ji,jj) 
                IF( ik > 1 ) THEN
Index: /NEMO/trunk/src/OCE/DYN/dynhpg.F90
===================================================================
--- /NEMO/trunk/src/OCE/DYN/dynhpg.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/DYN/dynhpg.F90	(revision 13982)
@@ -302,6 +302,7 @@
       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) :: zgtsu, zgtsv, zgru, zgrv
+      REAL(wp), DIMENSION(jpi,jpj,jpk) :: zhpi, zhpj
+      REAL(wp), DIMENSION(jpi,jpj,jpts)   :: zgtsu, zgtsv
+      REAL(wp), DIMENSION(jpi,jpj)     :: zgru, zgrv
       !!----------------------------------------------------------------------
       !
Index: /NEMO/trunk/src/OCE/IOM/iom.F90
===================================================================
--- /NEMO/trunk/src/OCE/IOM/iom.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/IOM/iom.F90	(revision 13982)
@@ -1960,5 +1960,5 @@
       CHARACTER(LEN=*), INTENT(in) ::   cdname
       REAL(sp)        , INTENT(in) ::   pfield0d
-!!      REAL(wp)        , DIMENSION(jpi,jpj) ::   zz     ! masson
+      !!      REAL(wp)        , DIMENSION(jpi,jpj) ::   zz     ! masson
 #if defined key_iomput
 !!clem      zz(:,:)=pfield0d
Index: /NEMO/trunk/src/OCE/IOM/prtctl.F90
===================================================================
--- /NEMO/trunk/src/OCE/IOM/prtctl.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/IOM/prtctl.F90	(revision 13982)
@@ -8,4 +8,5 @@
    !!----------------------------------------------------------------------
    USE dom_oce          ! ocean space and time domain variables
+   USE domutl, ONLY : is_tile
    USE in_out_manager   ! I/O manager
    USE mppini           ! distributed memory computing
@@ -26,4 +27,6 @@
    PUBLIC prt_ctl_init    ! called by nemogcm.F90 and prt_ctl_trc_init
 
+   !! * Substitutions
+#  include "do_loop_substitute.h90"
    !!----------------------------------------------------------------------
    !! NEMO/OCE 4.0 , NEMO Consortium (2018)
@@ -35,4 +38,33 @@
    SUBROUTINE prt_ctl (tab2d_1, tab3d_1, tab4d_1, tab2d_2, tab3d_2, mask1, mask2,   &
       &                 clinfo, clinfo1, clinfo2, clinfo3, kdim )
+      !!
+      REAL(wp),         DIMENSION(:,:)    , INTENT(in), OPTIONAL ::   tab2d_1
+      REAL(wp),         DIMENSION(:,:,:)  , INTENT(in), OPTIONAL ::   tab3d_1
+      REAL(wp),         DIMENSION(:,:,:,:), INTENT(in), OPTIONAL ::   tab4d_1
+      REAL(wp),         DIMENSION(:,:)    , INTENT(in), OPTIONAL ::   tab2d_2
+      REAL(wp),         DIMENSION(:,:,:)  , INTENT(in), OPTIONAL ::   tab3d_2
+      REAL(wp),         DIMENSION(:,:,:)  , INTENT(in), OPTIONAL ::   mask1
+      REAL(wp),         DIMENSION(:,:,:)  , INTENT(in), OPTIONAL ::   mask2
+      CHARACTER(len=*), DIMENSION(:)      , INTENT(in), OPTIONAL ::   clinfo    ! information about the tab3d array
+      CHARACTER(len=*)                    , INTENT(in), OPTIONAL ::   clinfo1
+      CHARACTER(len=*)                    , INTENT(in), OPTIONAL ::   clinfo2
+      CHARACTER(len=*)                    , INTENT(in), OPTIONAL ::   clinfo3
+      INTEGER                             , INTENT(in), OPTIONAL ::   kdim
+      !
+      INTEGER :: itab2d_1, itab3d_1, itab4d_1, itab2d_2, itab3d_2
+      !!
+      IF( PRESENT(tab2d_1)  ) THEN ; itab2d_1 = is_tile(tab2d_1)  ; ELSE ; itab2d_1 = 0 ; ENDIF
+      IF( PRESENT(tab3d_1)  ) THEN ; itab3d_1 = is_tile(tab3d_1)  ; ELSE ; itab3d_1 = 0 ; ENDIF
+      IF( PRESENT(tab4d_1)  ) THEN ; itab4d_1 = is_tile(tab4d_1)  ; ELSE ; itab4d_1 = 0 ; ENDIF
+      IF( PRESENT(tab2d_2)  ) THEN ; itab2d_2 = is_tile(tab2d_2)  ; ELSE ; itab2d_2 = 0 ; ENDIF
+      IF( PRESENT(tab3d_2)  ) THEN ; itab3d_2 = is_tile(tab3d_2)  ; ELSE ; itab3d_2 = 0 ; ENDIF
+
+      CALL prt_ctl_t (tab2d_1, itab2d_1, tab3d_1, itab3d_1, tab4d_1, itab4d_1, tab2d_2, itab2d_2, tab3d_2, itab3d_2,  &
+      &               mask1, mask2, clinfo, clinfo1, clinfo2, clinfo3, kdim )
+   END SUBROUTINE prt_ctl
+
+
+   SUBROUTINE prt_ctl_t (tab2d_1, ktab2d_1, tab3d_1, ktab3d_1, tab4d_1, ktab4d_1, tab2d_2, ktab2d_2, tab3d_2, ktab3d_2,  &
+      &                  mask1, mask2, clinfo, clinfo1, clinfo2, clinfo3, kdim )
       !!----------------------------------------------------------------------
       !!                     ***  ROUTINE prt_ctl  ***
@@ -70,9 +102,10 @@
       !!                    clinfo3 : additional information 
       !!----------------------------------------------------------------------
-      REAL(wp),         DIMENSION(:,:)    , INTENT(in), OPTIONAL ::   tab2d_1
-      REAL(wp),         DIMENSION(:,:,:)  , INTENT(in), OPTIONAL ::   tab3d_1
-      REAL(wp),         DIMENSION(:,:,:,:), INTENT(in), OPTIONAL ::   tab4d_1
-      REAL(wp),         DIMENSION(:,:)    , INTENT(in), OPTIONAL ::   tab2d_2
-      REAL(wp),         DIMENSION(:,:,:)  , INTENT(in), OPTIONAL ::   tab3d_2
+      INTEGER                             , INTENT(in)           ::   ktab2d_1, ktab3d_1, ktab4d_1, ktab2d_2, ktab3d_2
+      REAL(wp),         DIMENSION(A2D_T(ktab2d_1))    , INTENT(in), OPTIONAL ::   tab2d_1
+      REAL(wp),         DIMENSION(A2D_T(ktab3d_1),:)  , INTENT(in), OPTIONAL ::   tab3d_1
+      REAL(wp),         DIMENSION(A2D_T(ktab4d_1),:,:), INTENT(in), OPTIONAL ::   tab4d_1
+      REAL(wp),         DIMENSION(A2D_T(ktab2d_2))    , INTENT(in), OPTIONAL ::   tab2d_2
+      REAL(wp),         DIMENSION(A2D_T(ktab3d_2),:)  , INTENT(in), OPTIONAL ::   tab3d_2
       REAL(wp),         DIMENSION(:,:,:)  , INTENT(in), OPTIONAL ::   mask1
       REAL(wp),         DIMENSION(:,:,:)  , INTENT(in), OPTIONAL ::   mask2
@@ -106,8 +139,8 @@
 
          ! define shoter names...
-         iis = nall_ictls(jl)
-         iie = nall_ictle(jl)
-         jjs = nall_jctls(jl)
-         jje = nall_jctle(jl)
+         iis = MAX( nall_ictls(jl), ntsi )
+         iie = MIN( nall_ictle(jl), ntei )
+         jjs = MAX( nall_jctls(jl), ntsj )
+         jje = MIN( nall_jctle(jl), ntej )
 
          IF( PRESENT(clinfo) ) THEN   ;   inum = numprt_top(jl)
@@ -115,83 +148,86 @@
          ENDIF
 
-         DO jn = 1, itra
-
-            IF( PRESENT(clinfo3) ) THEN
-               IF    ( clinfo3 == 'tra-ta' )   THEN
-                  zvctl1 = t_ctl(jl)
-               ELSEIF( clinfo3 == 'tra'    )   THEN
-                  zvctl1 = t_ctl(jl)
-                  zvctl2 = s_ctl(jl)
-               ELSEIF( clinfo3 == 'dyn'    )   THEN
-                  zvctl1 = u_ctl(jl)
-                  zvctl2 = v_ctl(jl)
+         ! Compute the sum control only where the tile domain and control print area overlap
+         IF( iie >= iis .AND. jje >= jjs ) THEN
+            DO jn = 1, itra
+
+               IF( PRESENT(clinfo3) ) THEN
+                  IF    ( clinfo3 == 'tra-ta' )   THEN
+                     zvctl1 = t_ctl(jl)
+                  ELSEIF( clinfo3 == 'tra'    )   THEN
+                     zvctl1 = t_ctl(jl)
+                     zvctl2 = s_ctl(jl)
+                  ELSEIF( clinfo3 == 'dyn'    )   THEN
+                     zvctl1 = u_ctl(jl)
+                     zvctl2 = v_ctl(jl)
+                  ELSE
+                     zvctl1 = tra_ctl(jn,jl)
+                  ENDIF
+               ENDIF
+
+               ! 2D arrays
+               IF( PRESENT(tab2d_1) ) THEN
+                  IF( PRESENT(mask1) ) THEN   ;   zsum1 = SUM( tab2d_1(iis:iie,jjs:jje) * mask1(iis:iie,jjs:jje,1) )
+                  ELSE                        ;   zsum1 = SUM( tab2d_1(iis:iie,jjs:jje)                            )
+                  ENDIF
+               ENDIF
+               IF( PRESENT(tab2d_2) ) THEN
+                  IF( PRESENT(mask2) ) THEN   ;   zsum2 = SUM( tab2d_2(iis:iie,jjs:jje) * mask2(iis:iie,jjs:jje,1) )
+                  ELSE                        ;   zsum2 = SUM( tab2d_2(iis:iie,jjs:jje)                            )
+                  ENDIF
+               ENDIF
+
+               ! 3D arrays
+               IF( PRESENT(tab3d_1) ) THEN
+                  IF( PRESENT(mask1) ) THEN   ;   zsum1 = SUM( tab3d_1(iis:iie,jjs:jje,1:kdir) * mask1(iis:iie,jjs:jje,1:kdir) )
+                  ELSE                        ;   zsum1 = SUM( tab3d_1(iis:iie,jjs:jje,1:kdir)                                 )
+                  ENDIF
+               ENDIF
+               IF( PRESENT(tab3d_2) ) THEN
+                  IF( PRESENT(mask2) ) THEN   ;   zsum2 = SUM( tab3d_2(iis:iie,jjs:jje,1:kdir) * mask2(iis:iie,jjs:jje,1:kdir) )
+                  ELSE                        ;   zsum2 = SUM( tab3d_2(iis:iie,jjs:jje,1:kdir)                                 )
+                  ENDIF
+               ENDIF
+
+               ! 4D arrays
+               IF( PRESENT(tab4d_1) ) THEN
+                  IF( PRESENT(mask1) ) THEN   ;   zsum1 = SUM( tab4d_1(iis:iie,jjs:jje,1:kdir,jn) * mask1(iis:iie,jjs:jje,1:kdir) )
+                  ELSE                        ;   zsum1 = SUM( tab4d_1(iis:iie,jjs:jje,1:kdir,jn)                                 )
+                  ENDIF
+               ENDIF
+
+               ! Print the result
+               IF( PRESENT(clinfo ) )   cl1  = clinfo(jn)
+               IF( PRESENT(clinfo3) )   THEN
+                  !
+                  IF( PRESENT(tab2d_2) .OR. PRESENT(tab3d_2) ) THEN
+                     WRITE(inum, "(3x,a,' : ',D23.16,3x,a,' : ',D23.16)") cl1, zsum1 - zvctl1, cl2, zsum2 - zvctl2
+                  ELSE
+                     WRITE(inum, "(3x,a,' : ',D23.16                  )") cl1, zsum1 - zvctl1
+                  ENDIF
+                  !
+                  SELECT CASE( clinfo3 )
+                  CASE ( 'tra-ta' )
+                     t_ctl(jl) = zsum1
+                  CASE ( 'tra' )
+                     t_ctl(jl) = zsum1
+                     s_ctl(jl) = zsum2
+                  CASE ( 'dyn' )
+                     u_ctl(jl) = zsum1
+                     v_ctl(jl) = zsum2
+                  CASE default
+                     tra_ctl(jn,jl) = zsum1
+                  END SELECT
+               ELSEIF ( PRESENT(tab2d_2) .OR. PRESENT(tab3d_2) )   THEN
+                  WRITE(inum, "(3x,a,' : ',D23.16,3x,a,' : ',D23.16)") cl1, zsum1, cl2, zsum2
                ELSE
-                  zvctl1 = tra_ctl(jn,jl)
-               ENDIF
-            ENDIF
-
-            ! 2D arrays
-            IF( PRESENT(tab2d_1) ) THEN
-               IF( PRESENT(mask1) ) THEN   ;   zsum1 = SUM( tab2d_1(iis:iie,jjs:jje) * mask1(iis:iie,jjs:jje,1) )
-               ELSE                        ;   zsum1 = SUM( tab2d_1(iis:iie,jjs:jje)                            )
-               ENDIF
-            ENDIF
-            IF( PRESENT(tab2d_2) ) THEN
-               IF( PRESENT(mask2) ) THEN   ;   zsum2 = SUM( tab2d_2(iis:iie,jjs:jje) * mask2(iis:iie,jjs:jje,1) )
-               ELSE                        ;   zsum2 = SUM( tab2d_2(iis:iie,jjs:jje)                            )
-               ENDIF
-            ENDIF
-
-            ! 3D arrays
-            IF( PRESENT(tab3d_1) ) THEN
-               IF( PRESENT(mask1) ) THEN   ;   zsum1 = SUM( tab3d_1(iis:iie,jjs:jje,1:kdir) * mask1(iis:iie,jjs:jje,1:kdir) )
-               ELSE                        ;   zsum1 = SUM( tab3d_1(iis:iie,jjs:jje,1:kdir)                                 )
-               ENDIF
-            ENDIF
-            IF( PRESENT(tab3d_2) ) THEN
-               IF( PRESENT(mask2) ) THEN   ;   zsum2 = SUM( tab3d_2(iis:iie,jjs:jje,1:kdir) * mask2(iis:iie,jjs:jje,1:kdir) )
-               ELSE                        ;   zsum2 = SUM( tab3d_2(iis:iie,jjs:jje,1:kdir)                                 )
-               ENDIF
-            ENDIF
-
-            ! 4D arrays
-            IF( PRESENT(tab4d_1) ) THEN
-               IF( PRESENT(mask1) ) THEN   ;   zsum1 = SUM( tab4d_1(iis:iie,jjs:jje,1:kdir,jn) * mask1(iis:iie,jjs:jje,1:kdir) )
-               ELSE                        ;   zsum1 = SUM( tab4d_1(iis:iie,jjs:jje,1:kdir,jn)                                 )
-               ENDIF
-            ENDIF
-
-            ! Print the result
-            IF( PRESENT(clinfo ) )   cl1  = clinfo(jn)
-            IF( PRESENT(clinfo3) )   THEN
-               !
-               IF( PRESENT(tab2d_2) .OR. PRESENT(tab3d_2) ) THEN
-                  WRITE(inum, "(3x,a,' : ',D23.16,3x,a,' : ',D23.16)") cl1, zsum1 - zvctl1, cl2, zsum2 - zvctl2
-               ELSE
-                  WRITE(inum, "(3x,a,' : ',D23.16                  )") cl1, zsum1 - zvctl1
-               ENDIF
-               !
-               SELECT CASE( clinfo3 )
-               CASE ( 'tra-ta' ) 
-                  t_ctl(jl) = zsum1
-               CASE ( 'tra' ) 
-                  t_ctl(jl) = zsum1
-                  s_ctl(jl) = zsum2
-               CASE ( 'dyn' ) 
-                  u_ctl(jl) = zsum1
-                  v_ctl(jl) = zsum2
-               CASE default
-                  tra_ctl(jn,jl) = zsum1
-               END SELECT
-            ELSEIF ( PRESENT(tab2d_2) .OR. PRESENT(tab3d_2) )   THEN
-               WRITE(inum, "(3x,a,' : ',D23.16,3x,a,' : ',D23.16)") cl1, zsum1, cl2, zsum2
-            ELSE
-               WRITE(inum, "(3x,a,' : ',D23.16                  )") cl1, zsum1
-            ENDIF
-
-         END DO
+                  WRITE(inum, "(3x,a,' : ',D23.16                  )") cl1, zsum1
+               ENDIF
+
+            END DO
+         ENDIF
       END DO
       !
-   END SUBROUTINE prt_ctl
+   END SUBROUTINE prt_ctl_t
 
 
Index: /NEMO/trunk/src/OCE/LBC/lbc_lnk_multi_generic.h90
===================================================================
--- /NEMO/trunk/src/OCE/LBC/lbc_lnk_multi_generic.h90	(revision 13981)
+++ /NEMO/trunk/src/OCE/LBC/lbc_lnk_multi_generic.h90	(revision 13982)
@@ -40,5 +40,5 @@
       &                    , pt9 , cdna9 , psgn9 , pt10, cdna10, psgn10, pt11, cdna11, psgn11, pt12, cdna12, psgn12  &
       &                    , pt13, cdna13, psgn13, pt14, cdna14, psgn14, pt15, cdna15, psgn15, pt16, cdna16, psgn16  &
-      &                    , kfillmode, pfillval, lsend, lrecv )
+      &                    , kfillmode, pfillval, lsend, lrecv, ncsten )
       !!---------------------------------------------------------------------
       CHARACTER(len=*)     ,                   INTENT(in   ) ::   cdname  ! name of the calling subroutine
@@ -55,4 +55,5 @@
       REAL(wp)             , OPTIONAL        , INTENT(in   ) ::   pfillval    ! background value (used at closed boundaries)
       LOGICAL, DIMENSION(4), OPTIONAL        , INTENT(in   ) ::   lsend, lrecv   ! indicate how communications are to be carried out
+      LOGICAL              , OPTIONAL        , INTENT(in   ) ::   ncsten
       !!
       INTEGER                          ::   kfld        ! number of elements that will be attributed
@@ -84,5 +85,5 @@
       IF( PRESENT(psgn16) )   CALL ROUTINE_LOAD( pt16, cdna16, psgn16, ptab_ptr, cdna_ptr, psgn_ptr, kfld )
       !
-      CALL lbc_lnk_ptr( cdname, ptab_ptr, cdna_ptr, psgn_ptr, kfld, kfillmode, pfillval, lsend, lrecv )
+      CALL lbc_lnk_ptr( cdname, ptab_ptr, cdna_ptr, psgn_ptr, kfld, kfillmode, pfillval, lsend, lrecv, ncsten )
       !
    END SUBROUTINE ROUTINE_MULTI
Index: /NEMO/trunk/src/OCE/LBC/lbc_lnk_nc_generic.h90
===================================================================
--- /NEMO/trunk/src/OCE/LBC/lbc_lnk_nc_generic.h90	(revision 13982)
+++ /NEMO/trunk/src/OCE/LBC/lbc_lnk_nc_generic.h90	(revision 13982)
@@ -0,0 +1,113 @@
+#if defined SINGLE_PRECISION
+#   if defined DIM_2d
+#      define ARRAY_TYPE(i,j,k,l)   REAL(sp), DIMENSION(i,j)
+#      define PTR_TYPE              TYPE(PTR_2D_sp)
+#      define PTR_ptab              pt2d
+#   endif
+#   if defined DIM_3d
+#      define ARRAY_TYPE(i,j,k,l)   REAL(sp), DIMENSION(i,j,k)
+#      define PTR_TYPE              TYPE(PTR_3D_sp)
+#      define PTR_ptab              pt3d
+#   endif
+#   if defined DIM_4d
+#      define ARRAY_TYPE(i,j,k,l)   REAL(sp), DIMENSION(i,j,k,l)
+#      define PTR_TYPE              TYPE(PTR_4D_sp)
+#      define PTR_ptab              pt4d
+#   endif
+#   define PRECISION sp
+#else
+#   if defined DIM_2d
+#      define ARRAY_TYPE(i,j,k,l)   REAL(dp), DIMENSION(i,j)
+#      define PTR_TYPE              TYPE(PTR_2D_dp)
+#      define PTR_ptab              pt2d
+#   endif
+#   if defined DIM_3d
+#      define ARRAY_TYPE(i,j,k,l)   REAL(dp), DIMENSION(i,j,k)
+#      define PTR_TYPE              TYPE(PTR_3D_dp)
+#      define PTR_ptab              pt3d
+#   endif
+#   if defined DIM_4d
+#      define ARRAY_TYPE(i,j,k,l)   REAL(dp), DIMENSION(i,j,k,l)
+#      define PTR_TYPE              TYPE(PTR_4D_dp)
+#      define PTR_ptab              pt4d
+#   endif
+#   define PRECISION dp
+#endif
+
+   SUBROUTINE ROUTINE_MULTI_NC( cdname                                                                             &
+      &                    , pt1 , cdna1 , psgn1 , pt2 , cdna2 , psgn2 , pt3 , cdna3 , psgn3 , pt4 , cdna4 , psgn4   &
+      &                    , pt5 , cdna5 , psgn5 , pt6 , cdna6 , psgn6 , pt7 , cdna7 , psgn7 , pt8 , cdna8 , psgn8   &
+      &                    , pt9 , cdna9 , psgn9 , pt10, cdna10, psgn10, pt11, cdna11, psgn11, pt12, cdna12, psgn12  &
+      &                    , pt13, cdna13, psgn13, pt14, cdna14, psgn14, pt15, cdna15, psgn15, pt16, cdna16, psgn16  &
+      &                    , kfillmode, pfillval, lsend, lrecv, ncsten )
+      !!---------------------------------------------------------------------
+      CHARACTER(len=*)   ,                   INTENT(in   ) :: cdname  ! name of the calling subroutine
+      ARRAY_TYPE(:,:,:,:)          , TARGET, INTENT(inout) :: pt1     ! arrays on which the lbc is applied
+      ARRAY_TYPE(:,:,:,:), OPTIONAL, TARGET, INTENT(inout) :: pt2  , pt3  , pt4  , pt5  , pt6  , pt7  , pt8  , pt9  , &
+         &                                                    pt10  , pt11  , pt12  , pt13  , pt14  , pt15  , pt16
+      CHARACTER(len=1)                     , INTENT(in   ) :: cdna1   ! nature of pt2D. array grid-points
+      CHARACTER(len=1)   , OPTIONAL        , INTENT(in   ) :: cdna2, cdna3, cdna4, cdna5, cdna6, cdna7, cdna8, cdna9, &
+         &                                                    cdna10, cdna11, cdna12, cdna13, cdna14, cdna15, cdna16
+      REAL(wp)                             , INTENT(in   ) :: psgn1   ! sign used across the north fold
+      REAL(wp)           , OPTIONAL        , INTENT(in   ) :: psgn2, psgn3, psgn4, psgn5, psgn6, psgn7, psgn8, psgn9, &
+         &                                                    psgn10, psgn11, psgn12, psgn13, psgn14, psgn15, psgn16
+      INTEGER            , OPTIONAL        , INTENT(in   ) :: kfillmode   ! filling method for halo over land (default = constant)
+      REAL(wp)           , OPTIONAL        , INTENT(in   ) :: pfillval    ! background value (used at closed boundaries)
+      LOGICAL, DIMENSION(4), OPTIONAL      , INTENT(in   ) :: lsend, lrecv   ! indicate how communications are to be carried out
+      LOGICAL            , OPTIONAL      , INTENT(in   ) :: ncsten
+      !!
+      INTEGER                          ::   kfld        ! number of elements that will be attributed
+      PTR_TYPE         , DIMENSION(16) ::   ptab_ptr    ! pointer array
+      CHARACTER(len=1) , DIMENSION(16) ::   cdna_ptr    ! nature of ptab_ptr grid-points
+      REAL(wp)         , DIMENSION(16) ::   psgn_ptr    ! sign used across the north fold boundary
+      !!---------------------------------------------------------------------
+      !
+      kfld = 0          ! initial array of pointer size
+      !
+      !                 ! Load the first array
+      CALL ROUTINE_NC_LOAD( pt1, cdna1, psgn1, ptab_ptr, cdna_ptr, psgn_ptr, kfld )
+      !
+      !                 ! Look if more arrays are added
+      IF( PRESENT(psgn2 ) )   CALL ROUTINE_NC_LOAD( pt2 , cdna2 , psgn2 , ptab_ptr, cdna_ptr, psgn_ptr, kfld )
+      IF( PRESENT(psgn3 ) )   CALL ROUTINE_NC_LOAD( pt3 , cdna3 , psgn3 , ptab_ptr, cdna_ptr, psgn_ptr, kfld )
+      IF( PRESENT(psgn4 ) )   CALL ROUTINE_NC_LOAD( pt4 , cdna4 , psgn4 , ptab_ptr, cdna_ptr, psgn_ptr, kfld )
+      IF( PRESENT(psgn5 ) )   CALL ROUTINE_NC_LOAD( pt5 , cdna5 , psgn5 , ptab_ptr, cdna_ptr, psgn_ptr, kfld )
+      IF( PRESENT(psgn6 ) )   CALL ROUTINE_NC_LOAD( pt6 , cdna6 , psgn6 , ptab_ptr, cdna_ptr, psgn_ptr, kfld )
+      IF( PRESENT(psgn7 ) )   CALL ROUTINE_NC_LOAD( pt7 , cdna7 , psgn7 , ptab_ptr, cdna_ptr, psgn_ptr, kfld )
+      IF( PRESENT(psgn8 ) )   CALL ROUTINE_NC_LOAD( pt8 , cdna8 , psgn8 , ptab_ptr, cdna_ptr, psgn_ptr, kfld )
+      IF( PRESENT(psgn9 ) )   CALL ROUTINE_NC_LOAD( pt9 , cdna9 , psgn9 , ptab_ptr, cdna_ptr, psgn_ptr, kfld )
+      IF( PRESENT(psgn10) )   CALL ROUTINE_NC_LOAD( pt10, cdna10, psgn10, ptab_ptr, cdna_ptr, psgn_ptr, kfld )
+      IF( PRESENT(psgn11) )   CALL ROUTINE_NC_LOAD( pt11, cdna11, psgn11, ptab_ptr, cdna_ptr, psgn_ptr, kfld )
+      IF( PRESENT(psgn12) )   CALL ROUTINE_NC_LOAD( pt12, cdna12, psgn12, ptab_ptr, cdna_ptr, psgn_ptr, kfld )
+      IF( PRESENT(psgn13) )   CALL ROUTINE_NC_LOAD( pt13, cdna13, psgn13, ptab_ptr, cdna_ptr, psgn_ptr, kfld )
+      IF( PRESENT(psgn14) )   CALL ROUTINE_NC_LOAD( pt14, cdna14, psgn14, ptab_ptr, cdna_ptr, psgn_ptr, kfld )
+      IF( PRESENT(psgn15) )   CALL ROUTINE_NC_LOAD( pt15, cdna15, psgn15, ptab_ptr, cdna_ptr, psgn_ptr, kfld )
+      IF( PRESENT(psgn16) )   CALL ROUTINE_NC_LOAD( pt16, cdna16, psgn16, ptab_ptr, cdna_ptr, psgn_ptr, kfld )
+      !
+      CALL lbc_lnk_nc    ( cdname,               ptab_ptr, cdna_ptr, psgn_ptr, kfld, kfillmode, pfillval, lsend, lrecv, ncsten )
+      !
+   END SUBROUTINE ROUTINE_MULTI_NC
+
+
+   SUBROUTINE ROUTINE_NC_LOAD( ptab, cdna, psgn, ptab_ptr, cdna_ptr, psgn_ptr, kfld )
+      !!---------------------------------------------------------------------
+      ARRAY_TYPE(:,:,:,:)   , TARGET, INTENT(inout) ::   ptab       ! arrays on which the lbc is applied
+      CHARACTER(len=1)              , INTENT(in   ) ::   cdna       ! nature of pt2d array grid-points
+      REAL(wp)                      , INTENT(in   ) ::   psgn       ! sign used across the north fold boundary
+      PTR_TYPE        , DIMENSION(:), INTENT(inout) ::   ptab_ptr   ! array of pointers
+      CHARACTER(len=1), DIMENSION(:), INTENT(inout) ::   cdna_ptr   ! nature of pt2d_array array grid-points
+      REAL(wp)        , DIMENSION(:), INTENT(inout) ::   psgn_ptr   ! sign used across the north fold boundary
+      INTEGER                       , INTENT(inout) ::   kfld       ! number of elements that has been attributed
+      !!---------------------------------------------------------------------
+      !
+      kfld                    =  kfld + 1
+      ptab_ptr(kfld)%PTR_ptab => ptab
+      cdna_ptr(kfld)          =  cdna
+      psgn_ptr(kfld)          =  psgn
+      !
+   END SUBROUTINE ROUTINE_NC_LOAD
+
+#undef PRECISION
+#undef ARRAY_TYPE
+#undef PTR_TYPE
+#undef PTR_ptab
Index: /NEMO/trunk/src/OCE/LBC/lbclnk.F90
===================================================================
--- /NEMO/trunk/src/OCE/LBC/lbclnk.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/LBC/lbclnk.F90	(revision 13982)
@@ -39,4 +39,12 @@
       MODULE PROCEDURE   lbc_lnk_2d_multi_dp , lbc_lnk_3d_multi_dp, lbc_lnk_4d_multi_dp
    END INTERFACE
+   INTERFACE lbc_lnk_nc_multi
+      MODULE PROCEDURE   lbc_lnk_nc_2d_sp, lbc_lnk_nc_3d_sp, lbc_lnk_nc_4d_sp
+      MODULE PROCEDURE   lbc_lnk_nc_2d_dp, lbc_lnk_nc_3d_dp, lbc_lnk_nc_4d_dp
+   END INTERFACE
+   INTERFACE lbc_lnk_nc
+      MODULE PROCEDURE   mpp_lnk_nc_2d_sp, mpp_lnk_nc_3d_sp, mpp_lnk_nc_4d_sp
+      MODULE PROCEDURE   mpp_lnk_nc_2d_dp, mpp_lnk_nc_3d_dp, mpp_lnk_nc_4d_dp
+   END INTERFACE
    !
    INTERFACE lbc_lnk_icb
@@ -52,7 +60,9 @@
    END INTERFACE
 
-   PUBLIC   lbc_lnk       ! ocean/ice lateral boundary conditions
-   PUBLIC   lbc_lnk_multi ! modified ocean/ice lateral boundary conditions
-   PUBLIC   lbc_lnk_icb   ! iceberg lateral boundary conditions
+   PUBLIC   lbc_lnk            ! ocean/ice lateral boundary conditions
+   PUBLIC   lbc_lnk_multi      ! modified ocean/ice lateral boundary conditions
+   PUBLIC   lbc_lnk_icb        ! iceberg lateral boundary conditions
+   PUBLIC   lbc_lnk_nc         ! ocean/ice lateral boundary conditions (MPI3 version)
+   PUBLIC   lbc_lnk_nc_multi   ! modified ocean/ice lateral boundary conditions (MPI3 version)
 
 #if   defined key_mpp_mpi
@@ -250,4 +260,146 @@
 #  undef DIM_4d
 
+   !!----------------------------------------------------------------------
+   !!                   ***   load_ptr_(2,3,4)d   ***
+   !!
+   !!   * Dummy Argument :
+   !!       in    ==>   ptab       ! array to be loaded (2D, 3D or 4D)
+   !!                   cd_nat     ! nature of pt2d array grid-points
+   !!                   psgn       ! sign used across the north fold boundary
+   !!       inout <=>   ptab_ptr   ! array of 2D, 3D or 4D pointers
+   !!                   cdna_ptr   ! nature of ptab array grid-points
+   !!                   psgn_ptr   ! sign used across the north fold boundary
+   !!                   kfld       ! number of elements that has been attributed
+   !!----------------------------------------------------------------------
+
+   !!----------------------------------------------------------------------
+   !!                  ***   lbc_lnk_nc(2,3,4)d_multi   ***
+   !!                     ***   load_ptr_(2,3,4)d   ***
+   !!
+   !!   * Argument : dummy argument use in lbc_lnk_nc_multi_... routines
+   !!
+   !!----------------------------------------------------------------------
+
+   !!
+   !!   ----   SINGLE PRECISION VERSIONS
+   !!
+#  define SINGLE_PRECISION
+#  define DIM_2d
+#     define ROUTINE_NC_LOAD           load_ptr_nc_2d_sp
+#     define ROUTINE_MULTI_NC          lbc_lnk_nc_2d_sp
+#     include "lbc_lnk_nc_generic.h90"
+#     undef ROUTINE_MULTI_NC
+#     undef ROUTINE_NC_LOAD
+#  undef DIM_2d
+
+#  define DIM_3d
+#     define ROUTINE_NC_LOAD           load_ptr_nc_3d_sp
+#     define ROUTINE_MULTI_NC          lbc_lnk_nc_3d_sp
+#     include "lbc_lnk_nc_generic.h90"
+#     undef ROUTINE_MULTI_NC
+#     undef ROUTINE_NC_LOAD
+#  undef DIM_3d
+
+#  define DIM_4d
+#     define ROUTINE_NC_LOAD           load_ptr_nc_4d_sp
+#     define ROUTINE_MULTI_NC          lbc_lnk_nc_4d_sp
+#     include "lbc_lnk_nc_generic.h90"
+#     undef ROUTINE_MULTI_NC
+#     undef ROUTINE_NC_LOAD
+#  undef DIM_4d
+#  undef SINGLE_PRECISION
+   !!
+   !!   ----   DOUBLE PRECISION VERSIONS
+   !!
+
+#  define DIM_2d
+#     define ROUTINE_NC_LOAD           load_ptr_nc_2d_dp
+#     define ROUTINE_MULTI_NC          lbc_lnk_nc_2d_dp
+#     include "lbc_lnk_nc_generic.h90"
+#     undef ROUTINE_MULTI_NC
+#     undef ROUTINE_NC_LOAD
+#  undef DIM_2d
+
+#  define DIM_3d
+#     define ROUTINE_NC_LOAD           load_ptr_nc_3d_dp
+#     define ROUTINE_MULTI_NC          lbc_lnk_nc_3d_dp
+#     include "lbc_lnk_nc_generic.h90"
+#     undef ROUTINE_MULTI_NC
+#     undef ROUTINE_NC_LOAD
+#  undef DIM_3d
+
+#  define DIM_4d
+#     define ROUTINE_NC_LOAD           load_ptr_nc_4d_dp
+#     define ROUTINE_MULTI_NC          lbc_lnk_nc_4d_dp
+#     include "lbc_lnk_nc_generic.h90"
+#     undef ROUTINE_MULTI_NC
+#     undef ROUTINE_NC_LOAD
+#  undef DIM_4d
+
+   !!----------------------------------------------------------------------
+   !!                   ***  routine mpp_lnk_nc_(2,3,4)d  ***
+   !!
+   !!   * Argument : dummy argument use in mpp_lnk_... routines
+   !!                ptab      :   array or pointer of arrays on which the boundary condition is applied
+   !!                cd_nat    :   nature of array grid-points
+   !!                psgn      :   sign used across the north fold boundary
+   !!                kfld      :   optional, number of pt3d arrays
+   !!                kfillmode :   optional, method to be use to fill the halos (see jpfill* variables)
+   !!                pfillval  :   optional, background value (used with jpfillcopy)
+   !!----------------------------------------------------------------------
+   !
+   !                       !==  2D array and array of 2D pointer  ==!
+   !
+   !!
+   !!   ----   SINGLE PRECISION VERSIONS
+   !!
+# define SINGLE_PRECISION
+#  define DIM_2d
+#     define ROUTINE_NC           mpp_lnk_nc_2d_sp
+#     include "mpp_nc_generic.h90"
+#     undef ROUTINE_NC
+#  undef DIM_2d
+   !
+   !                       !==  3D array and array of 3D pointer  ==!
+   !
+#  define DIM_3d
+#     define ROUTINE_NC           mpp_lnk_nc_3d_sp
+#     include "mpp_nc_generic.h90"
+#     undef ROUTINE_NC
+#  undef DIM_3d
+   !
+   !                       !==  4D array and array of 4D pointer  ==!
+   !
+#  define DIM_4d
+#     define ROUTINE_NC           mpp_lnk_nc_4d_sp
+#     include "mpp_nc_generic.h90"
+#     undef ROUTINE_NC
+#  undef DIM_4d
+# undef SINGLE_PRECISION
+
+   !!
+   !!   ----   DOUBLE PRECISION VERSIONS
+   !!
+#  define DIM_2d
+#     define ROUTINE_NC           mpp_lnk_nc_2d_dp
+#     include "mpp_nc_generic.h90"
+#     undef ROUTINE_NC
+#  undef DIM_2d
+   !
+   !                       !==  3D array and array of 3D pointer  ==!
+   !
+#  define DIM_3d
+#     define ROUTINE_NC           mpp_lnk_nc_3d_dp
+#     include "mpp_nc_generic.h90"
+#     undef ROUTINE_NC
+#  undef DIM_3d
+   !
+   !                       !==  4D array and array of 4D pointer  ==!
+   !
+#  define DIM_4d
+#     define ROUTINE_NC           mpp_lnk_nc_4d_dp
+#     include "mpp_nc_generic.h90"
+#     undef ROUTINE_NC
+#  undef DIM_4d
 
    !!----------------------------------------------------------------------
Index: /NEMO/trunk/src/OCE/LBC/lib_mpp.F90
===================================================================
--- /NEMO/trunk/src/OCE/LBC/lib_mpp.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/LBC/lib_mpp.F90	(revision 13982)
@@ -66,4 +66,5 @@
    PUBLIC   mppscatter, mppgather
    PUBLIC   mpp_ini_znl
+   PUBLIC   mpp_ini_nc
    PUBLIC   mppsend, mpprecv                          ! needed by TAM and ICB routines
    PUBLIC   mppsend_sp, mpprecv_sp                          ! needed by TAM and ICB routines
@@ -137,4 +138,8 @@
    INTEGER         ::   ndim_rank_znl   !  number of processors on the same zonal average
    INTEGER, DIMENSION(:), ALLOCATABLE, SAVE ::   nrank_znl  ! dimension ndim_rank_znl, number of the procs into the same znl domain
+
+   ! variables used for MPI3 neighbourhood collectives
+   INTEGER, PUBLIC :: mpi_nc_com                   ! MPI3 neighbourhood collectives communicator
+   INTEGER, PUBLIC :: mpi_nc_all_com               ! MPI3 neighbourhood collectives communicator (with diagionals)
 
    ! North fold condition in mpp_mpi with jpni > 1 (PUBLIC for TAM)
@@ -1067,4 +1072,151 @@
 
    END SUBROUTINE mpp_ini_znl
+
+   SUBROUTINE mpp_ini_nc
+      !!----------------------------------------------------------------------
+      !!               ***  routine mpp_ini_nc  ***
+      !!
+      !! ** Purpose :   Initialize special communicators for MPI3 neighbourhood
+      !!                collectives
+      !!
+      !! ** Method  : - Create graph communicators starting from the processes   
+      !!                distribution along i and j directions
+      !
+      !! ** output
+      !!         mpi_nc_com = MPI3 neighbourhood collectives communicator
+      !!         mpi_nc_all_com = MPI3 neighbourhood collectives communicator
+      !!                          (with diagonals)
+      !!
+      !!----------------------------------------------------------------------
+      INTEGER, DIMENSION(:), ALLOCATABLE :: ineigh, ineighalls, ineighallr
+      INTEGER :: ideg, idegalls, idegallr, icont, icont1
+      INTEGER :: ierr
+      LOGICAL, PARAMETER :: ireord = .FALSE.
+
+#if defined key_mpp_mpi
+
+      ideg = 0
+      idegalls = 0
+      idegallr = 0
+      icont = 0
+      icont1 = 0
+
+      IF (nbondi .eq. 1) THEN
+         ideg = ideg + 1
+      ELSEIF (nbondi .eq. -1) THEN
+         ideg = ideg + 1
+      ELSEIF (nbondi .eq. 0) THEN
+         ideg = ideg + 2
+      ENDIF
+
+      IF (nbondj .eq. 1) THEN
+         ideg = ideg + 1
+      ELSEIF (nbondj .eq. -1) THEN
+         ideg = ideg + 1
+      ELSEIF (nbondj .eq. 0) THEN
+         ideg = ideg + 2
+      ENDIF
+
+      idegalls = ideg
+      idegallr = ideg
+
+      IF (nones .ne. -1) idegalls = idegalls + 1
+      IF (nonws .ne. -1) idegalls = idegalls + 1
+      IF (noses .ne. -1) idegalls = idegalls + 1
+      IF (nosws .ne. -1) idegalls = idegalls + 1
+      IF (noner .ne. -1) idegallr = idegallr + 1
+      IF (nonwr .ne. -1) idegallr = idegallr + 1
+      IF (noser .ne. -1) idegallr = idegallr + 1
+      IF (noswr .ne. -1) idegallr = idegallr + 1
+
+      ALLOCATE(ineigh(ideg))
+      ALLOCATE(ineighalls(idegalls))
+      ALLOCATE(ineighallr(idegallr))
+
+      IF (nbondi .eq. 1) THEN
+         icont = icont + 1
+         ineigh(icont) = nowe
+         ineighalls(icont) = nowe
+         ineighallr(icont) = nowe
+      ELSEIF (nbondi .eq. -1) THEN
+         icont = icont + 1
+         ineigh(icont) = noea
+         ineighalls(icont) = noea
+         ineighallr(icont) = noea
+      ELSEIF (nbondi .eq. 0) THEN
+         icont = icont + 1
+         ineigh(icont) = nowe
+         ineighalls(icont) = nowe
+         ineighallr(icont) = nowe
+         icont = icont + 1
+         ineigh(icont) = noea
+         ineighalls(icont) = noea
+         ineighallr(icont) = noea
+      ENDIF
+
+      IF (nbondj .eq. 1) THEN
+         icont = icont + 1
+         ineigh(icont) = noso
+         ineighalls(icont) = noso
+         ineighallr(icont) = noso
+      ELSEIF (nbondj .eq. -1) THEN
+         icont = icont + 1
+         ineigh(icont) = nono
+         ineighalls(icont) = nono
+         ineighallr(icont) = nono
+      ELSEIF (nbondj .eq. 0) THEN
+         icont = icont + 1
+         ineigh(icont) = noso
+         ineighalls(icont) = noso
+         ineighallr(icont) = noso
+         icont = icont + 1
+         ineigh(icont) = nono
+         ineighalls(icont) = nono
+         ineighallr(icont) = nono
+      ENDIF
+
+      icont1 = icont
+      IF (nosws .ne. -1) THEN
+         icont = icont + 1
+         ineighalls(icont) = nosws
+      ENDIF
+      IF (noses .ne. -1) THEN
+         icont = icont + 1
+         ineighalls(icont) = noses
+      ENDIF
+      IF (nonws .ne. -1) THEN
+         icont = icont + 1
+         ineighalls(icont) = nonws
+      ENDIF
+      IF (nones .ne. -1) THEN
+         icont = icont + 1
+         ineighalls(icont) = nones
+      ENDIF
+      IF (noswr .ne. -1) THEN
+         icont1 = icont1 + 1
+         ineighallr(icont1) = noswr
+      ENDIF
+      IF (noser .ne. -1) THEN
+         icont1 = icont1 + 1
+         ineighallr(icont1) = noser
+      ENDIF
+      IF (nonwr .ne. -1) THEN
+         icont1 = icont1 + 1
+         ineighallr(icont1) = nonwr
+      ENDIF
+      IF (noner .ne. -1) THEN
+         icont1 = icont1 + 1
+         ineighallr(icont1) = noner
+      ENDIF
+
+      CALL MPI_Dist_graph_create_adjacent(mpi_comm_oce, ideg, ineigh, MPI_UNWEIGHTED, ideg, ineigh, MPI_UNWEIGHTED, MPI_INFO_NULL, ireord, mpi_nc_com, ierr)
+      CALL MPI_Dist_graph_create_adjacent(mpi_comm_oce, idegallr, ineighallr, MPI_UNWEIGHTED, idegalls, ineighalls, MPI_UNWEIGHTED, MPI_INFO_NULL, ireord, mpi_nc_all_com, ierr)
+
+      DEALLOCATE (ineigh)
+      DEALLOCATE (ineighalls)
+      DEALLOCATE (ineighallr)
+#endif
+   END SUBROUTINE mpp_ini_nc
+
 
 
Index: /NEMO/trunk/src/OCE/LBC/mpp_lnk_generic.h90
===================================================================
--- /NEMO/trunk/src/OCE/LBC/mpp_lnk_generic.h90	(revision 13981)
+++ /NEMO/trunk/src/OCE/LBC/mpp_lnk_generic.h90	(revision 13982)
@@ -72,8 +72,8 @@
 
 #if defined MULTI
-   SUBROUTINE ROUTINE_LNK( cdname, ptab, cd_nat, psgn, kfld, kfillmode, pfillval, lsend, lrecv )
+   SUBROUTINE ROUTINE_LNK( cdname, ptab, cd_nat, psgn, kfld, kfillmode, pfillval, lsend, lrecv, ncsten )
       INTEGER             , INTENT(in   ) ::   kfld        ! number of pt3d arrays
 #else
-   SUBROUTINE ROUTINE_LNK( cdname, ptab, cd_nat, psgn      , kfillmode, pfillval, lsend, lrecv )
+   SUBROUTINE ROUTINE_LNK( cdname, ptab, cd_nat, psgn      , kfillmode, pfillval, lsend, lrecv, ncsten )
 #endif
       ARRAY_TYPE(:,:,:,:,:)                                        ! array or pointer of arrays on which the boundary condition is applied
@@ -84,4 +84,5 @@
       REAL(wp),             OPTIONAL, INTENT(in   ) ::   pfillval    ! background value (used at closed boundaries)
       LOGICAL, DIMENSION(4),OPTIONAL, INTENT(in   ) ::   lsend, lrecv  ! communication with other 4 proc
+      LOGICAL,              OPTIONAL, INTENT(in   ) ::   ncsten      ! 5-point or 9-point stencil
       !
       INTEGER  ::    ji,  jj,  jk,  jl,  jf      ! dummy loop indices
@@ -100,4 +101,12 @@
       !!----------------------------------------------------------------------
       !
+#if defined key_mpi3
+#   if defined MULTI
+      CALL lbc_lnk_nc    ( cdname,  ptab, cd_nat, psgn, kfld, kfillmode, pfillval, lsend, lrecv, ncsten )
+#   else
+      CALL lbc_lnk_nc_multi(cdname, ptab, cd_nat, psgn, kfillmode=kfillmode, pfillval=pfillval, lsend=lsend, lrecv=lrecv, ncsten=ncsten)
+#   endif
+#else
+
       ! ----------------------------------------- !
       !     0. local variables initialization     !
@@ -387,4 +396,5 @@
       IF( llrecv_no )   DEALLOCATE( zrcv_no )
       !
+#endif
    END SUBROUTINE ROUTINE_LNK
 #undef PRECISION
Index: /NEMO/trunk/src/OCE/LBC/mpp_nc_generic.h90
===================================================================
--- /NEMO/trunk/src/OCE/LBC/mpp_nc_generic.h90	(revision 13982)
+++ /NEMO/trunk/src/OCE/LBC/mpp_nc_generic.h90	(revision 13982)
@@ -0,0 +1,950 @@
+#   define NAT_IN(k)                cd_nat(k)   
+#   define SGN_IN(k)                psgn(k)
+#   define F_SIZE(ptab)             kfld
+#   define OPT_K(k)                 ,ipf
+#   if defined DIM_2d
+#      if defined SINGLE_PRECISION
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D_sp)                , INTENT(inout) ::   ptab(f)
+#      else
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D_dp)                , INTENT(inout) ::   ptab(f)
+#      endif
+#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt2d(i,j)
+#      define K_SIZE(ptab)             1
+#      define L_SIZE(ptab)             1
+#   endif
+#   if defined DIM_3d
+#      if defined SINGLE_PRECISION
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D_sp)                , INTENT(inout) ::   ptab(f)
+#      else
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D_dp)                , INTENT(inout) ::   ptab(f)
+#      endif
+#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt3d(i,j,k)
+#      define K_SIZE(ptab)             SIZE(ptab(1)%pt3d,3)
+#      define L_SIZE(ptab)             1
+#   endif
+#   if defined DIM_4d
+#      if defined SINGLE_PRECISION
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D_sp)                , INTENT(inout) ::   ptab(f)
+#      else
+#         define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D_dp)                , INTENT(inout) ::   ptab(f)
+#      endif
+#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt4d(i,j,k,l)
+#      define K_SIZE(ptab)             SIZE(ptab(1)%pt4d,3)
+#      define L_SIZE(ptab)             SIZE(ptab(1)%pt4d,4)
+#   endif
+#   if defined SINGLE_PRECISION
+#      define PRECISION sp
+#      define MPI_TYPE MPI_REAL
+#   else
+#      define PRECISION dp
+#      define MPI_TYPE MPI_DOUBLE_PRECISION
+#   endif
+
+   SUBROUTINE ROUTINE_NC( cdname, ptab, cd_nat, psgn, kfld, kfillmode, pfillval, lsend, lrecv, ncsten )
+      INTEGER             , INTENT(in   ) ::   kfld        ! number of pt3d arrays
+      ARRAY_TYPE(:,:,:,:,:)                                        ! array or pointer of arrays on which the boundary condition is applied
+      CHARACTER(len=*)              , INTENT(in   ) ::   cdname      ! name of the calling subroutine
+      CHARACTER(len=1)              , INTENT(in   ) ::   NAT_IN(:)   ! nature of array grid-points
+      REAL(wp)                      , INTENT(in   ) ::   SGN_IN(:)   ! sign used across the north fold boundary
+      INTEGER ,             OPTIONAL, INTENT(in   ) ::   kfillmode   ! filling method for halo over land (default = constant)
+      REAL(wp),             OPTIONAL, INTENT(in   ) ::   pfillval    ! background value (used at closed boundaries)
+      LOGICAL, DIMENSION(4),OPTIONAL, INTENT(in   ) ::   lsend, lrecv  ! communication with other 4 proc
+      LOGICAL,              OPTIONAL, INTENT(in   ) ::   ncsten      ! 5-point or 9-point stencil
+      !
+      INTEGER  ::   ji,  jj,  jk,  jl,  jf                                      ! dummy loop indices
+      INTEGER  ::   ipi, ipj, ipk, ipl, ipf                                     ! dimension of the input array
+      INTEGER  ::   ishift, ishift2, idx, icount, icount1                       ! local integers
+      INTEGER  ::   idims, idimr, isizet, isizets, isizetr, izsnd, izrcv        ! local integers
+      INTEGER  ::   ierr
+      INTEGER  ::   ifill_we, ifill_ea, ifill_so, ifill_no
+      INTEGER  ::   ifill_web, ifill_eab
+      REAL(wp) ::   zland
+      INTEGER , DIMENSION(MPI_STATUS_SIZE)                        ::   istate              ! for mpi_isend
+      REAL(PRECISION), DIMENSION(:), ALLOCATABLE                  ::   zsnd, zrcv          ! halos arrays
+      INTEGER , DIMENSION(:), ALLOCATABLE                         ::   isizes              ! number of elements to be sent
+      INTEGER , DIMENSION(:), ALLOCATABLE                         ::   isizer              ! number of elements to be received
+      INTEGER , DIMENSION(:), ALLOCATABLE                         ::   idatatys, idatatyr  ! datatype of halos arrays
+      INTEGER (KIND=MPI_ADDRESS_KIND), DIMENSION (:), ALLOCATABLE ::   idispls, idisplr    ! displacement in halos arrays
+      LOGICAL  ::   llsend_we, llsend_ea, llsend_no, llsend_so       ! communication send
+      LOGICAL  ::   llrecv_we, llrecv_ea, llrecv_no, llrecv_so       ! communication receive 
+      LOGICAL  ::   lldo_nfd                                         ! do north pole folding
+      LOGICAL  ::   llncall                                          ! default: 9-point stencil
+
+      !!----------------------------------------------------------------------
+      !
+      ! ----------------------------------------- !
+      !     0. local variables initialization     !
+      ! ----------------------------------------- !
+      !
+      llncall = .TRUE. 
+      ipk = K_SIZE(ptab)   ! 3rd dimension
+      ipl = L_SIZE(ptab)   ! 4th    -
+      ipf = F_SIZE(ptab)   ! 5th    -      use in "multi" case (array of pointers)
+      !
+      IF( narea == 1 .AND. numcom == -1 ) CALL mpp_report( cdname, ipk, ipl, ipf, ld_lbc = .TRUE. )
+      !
+      IF     ( PRESENT(lsend) .AND. PRESENT(lrecv) ) THEN
+         llsend_we = lsend(1)   ;   llsend_ea = lsend(2)   ;   llsend_so = lsend(3)   ;   llsend_no = lsend(4)
+         llrecv_we = lrecv(1)   ;   llrecv_ea = lrecv(2)   ;   llrecv_so = lrecv(3)   ;   llrecv_no = lrecv(4)
+      ELSE IF( PRESENT(lsend) .OR.  PRESENT(lrecv) ) THEN
+         WRITE(ctmp1,*) ' E R R O R : Routine ', cdname, '  is calling lbc_lnk with only one of the two arguments lsend or lrecv'
+         WRITE(ctmp2,*) ' ========== '
+         CALL ctl_stop( ' ', ctmp1, ctmp2, ' ' )
+      ELSE   ! send and receive with every neighbour
+         llsend_we = nbondi ==  1 .OR. nbondi == 0   ! keep for compatibility, should be defined in mppini
+         llsend_ea = nbondi == -1 .OR. nbondi == 0   ! keep for compatibility, should be defined in mppini
+         llsend_so = nbondj ==  1 .OR. nbondj == 0   ! keep for compatibility, should be defined in mppini
+         llsend_no = nbondj == -1 .OR. nbondj == 0   ! keep for compatibility, should be defined in mppini
+         llrecv_we = llsend_we   ;   llrecv_ea = llsend_ea   ;   llrecv_so = llsend_so   ;   llrecv_no = llsend_no
+      END IF
+         
+      lldo_nfd = npolj /= 0                      ! keep for compatibility, should be defined in mppini
+
+      zland = 0._wp                                     ! land filling value: zero by default
+      IF( PRESENT( pfillval ) )   zland = pfillval      ! set land value
+
+
+      ! define the method we will use to fill the halos in each direction
+      IF(              llrecv_we ) THEN   ;   ifill_we = jpfillmpi
+      ELSEIF(           l_Iperio ) THEN   ;   ifill_we = jpfillperio
+      ELSEIF( PRESENT(kfillmode) ) THEN   ;   ifill_we = kfillmode
+      ELSE                                ;   ifill_we = jpfillcst
+      END IF
+      IF(               l_Iperio ) THEN   ;   ifill_web = jpfillperio
+      ELSEIF( PRESENT(kfillmode) ) THEN   ;   ifill_web = kfillmode
+      ELSE                                ;   ifill_web = jpfillcst
+      END IF
+      !
+      IF(              llrecv_ea ) THEN   ;   ifill_ea = jpfillmpi
+      ELSEIF(           l_Iperio ) THEN   ;   ifill_ea = jpfillperio
+      ELSEIF( PRESENT(kfillmode) ) THEN   ;   ifill_ea = kfillmode
+      ELSE                                ;   ifill_ea = jpfillcst
+      END IF
+      IF(               l_Iperio ) THEN   ;   ifill_eab = jpfillperio
+      ELSEIF( PRESENT(kfillmode) ) THEN   ;   ifill_eab = kfillmode
+      ELSE                                ;   ifill_eab = jpfillcst
+      END IF
+      !
+      IF(              llrecv_so ) THEN   ;   ifill_so = jpfillmpi
+      ELSEIF(           l_Jperio ) THEN   ;   ifill_so = jpfillperio
+      ELSEIF( PRESENT(kfillmode) ) THEN   ;   ifill_so = kfillmode
+      ELSE                                ;   ifill_so = jpfillcst
+      END IF
+      !
+      IF(              llrecv_no ) THEN   ;   ifill_no = jpfillmpi
+      ELSEIF(           l_Jperio ) THEN   ;   ifill_no = jpfillperio
+      ELSEIF( PRESENT(kfillmode) ) THEN   ;   ifill_no = kfillmode
+      ELSE                                ;   ifill_no = jpfillcst
+      END IF
+      !
+      IF(PRESENT(ncsten)) llncall = ncsten 
+#if defined PRINT_CAUTION
+      !
+      ! ================================================================================== !
+      ! CAUTION: semi-column notation is often impossible because of the cpp preprocessing !
+      ! ================================================================================== !
+      !
+#endif
+      !
+      ! -------------------------------------------------- !
+      !     1. Do west, east, south and north MPI exchange !
+      ! -------------------------------------------------- !
+      !
+      ! Allocate local temporary arrays to be sent/received. Fill arrays to be sent
+
+      idims = 0
+      idimr = 0
+      izsnd = 0
+      izrcv = 0
+
+      IF(llsend_we) idims = idims + 1
+      IF(llsend_ea) idims = idims + 1
+      IF(llsend_so) idims = idims + 1
+      IF(llsend_no) idims = idims + 1
+
+      idimr = idims
+
+      IF(llncall) THEN
+         IF(noswr .ne. -1) idimr = idimr + 1
+         IF(noser .ne. -1) idimr = idimr + 1
+         IF(nonwr .ne. -1) idimr = idimr + 1
+         IF(noner .ne. -1) idimr = idimr + 1
+      
+         IF(nosws .ne. -1) idims = idims + 1
+         IF(noses .ne. -1) idims = idims + 1
+         IF(nonws .ne. -1) idims = idims + 1
+         IF(nones .ne. -1) idims = idims + 1
+      END IF
+
+      IF(llsend_we) izsnd = izsnd + nn_hls * (jpj - 2*nn_hls) * ipk * ipl * ipf
+      IF(llsend_ea) izsnd = izsnd + nn_hls * (jpj - 2*nn_hls) * ipk * ipl * ipf
+      IF(llsend_so) izsnd = izsnd + (jpi - 2*nn_hls) * nn_hls * ipk * ipl * ipf
+      IF(llsend_no) izsnd = izsnd + (jpi - 2*nn_hls) * nn_hls * ipk * ipl * ipf
+
+      izrcv = izsnd
+      
+      IF(llncall) THEN
+         IF(noswr .ne. -1) izrcv = izrcv + nn_hls * nn_hls * ipk * ipl * ipf
+         IF(noser .ne. -1) izrcv = izrcv + nn_hls * nn_hls * ipk * ipl * ipf
+         IF(nonwr .ne. -1) izrcv = izrcv + nn_hls * nn_hls * ipk * ipl * ipf
+         IF(noner .ne. -1) izrcv = izrcv + nn_hls * nn_hls * ipk * ipl * ipf
+
+         IF(nosws .ne. -1) izsnd = izsnd + nn_hls * nn_hls * ipk * ipl * ipf
+         IF(noses .ne. -1) izsnd = izsnd + nn_hls * nn_hls * ipk * ipl * ipf
+         IF(nonws .ne. -1) izsnd = izsnd + nn_hls * nn_hls * ipk * ipl * ipf
+         IF(nones .ne. -1) izsnd = izsnd + nn_hls * nn_hls * ipk * ipl * ipf
+      END IF
+
+      ALLOCATE(zsnd(izsnd))
+      ALLOCATE(zrcv(izrcv))
+      ALLOCATE(isizes(idims))
+      ALLOCATE(isizer(idimr))
+      ALLOCATE(idatatys(idims))
+      ALLOCATE(idatatyr(idimr))
+      ALLOCATE(idispls(idims))
+      ALLOCATE(idisplr(idimr))
+
+      zrcv(:)=-1
+      zsnd(:)=-1
+      isizes(:) = 0
+      isizer(:) = 0
+      idispls(:) = 0
+      idisplr(:) = 0
+      isizet = 0 
+     
+      idx = 1
+      icount = 1
+
+      IF(llsend_we) THEN
+         DO jf = 1, ipf  ;  DO jl = 1, ipl  ;  DO jk = 1, ipk  ;  DO jj = nn_hls + 1, jpj - nn_hls  ;  DO ji = 1, nn_hls
+            zsnd(idx) = ARRAY_IN(nn_hls+ji,jj,jk,jl,jf)
+            idx = idx + 1
+         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+
+         isizes(icount) = nn_hls * (jpj - 2*nn_hls) * ipk * ipl * ipf
+         IF(icount .gt. 1) isizet = isizet + isizes(icount - 1)
+         idispls(icount) = jpbyt*isizet
+         icount = icount + 1
+      END IF
+
+      IF(llsend_ea) THEN
+         ishift = jpi-2*nn_hls
+
+         DO jf = 1, ipf  ;  DO jl = 1, ipl  ;  DO jk = 1, ipk  ;  DO jj = nn_hls + 1, jpj - nn_hls  ;  DO ji = 1, nn_hls
+            zsnd(idx) = ARRAY_IN(ishift+ji,jj,jk,jl,jf)
+            idx = idx + 1
+         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+
+         isizes(icount) = nn_hls * (jpj - 2*nn_hls) * ipk * ipl * ipf
+         IF(icount .gt. 1) isizet = isizet + isizes(icount - 1)
+         idispls(icount) = jpbyt*isizet
+         icount = icount + 1
+      END IF
+
+      IF(llsend_so) THEN
+         DO jf = 1, ipf  ;  DO jl = 1, ipl  ;  DO jk = 1, ipk  ;  DO jj = 1, nn_hls  ;  DO ji = nn_hls + 1, jpi - nn_hls
+            zsnd(idx) = ARRAY_IN(ji,nn_hls+jj,jk,jl,jf)
+            idx = idx + 1
+         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+
+         isizes(icount) = (jpi - 2*nn_hls) * nn_hls * ipk * ipl * ipf
+         IF(icount .gt. 1) isizet = isizet + isizes(icount - 1)
+         idispls(icount) = jpbyt*isizet
+         icount = icount + 1
+      END IF
+
+      IF(llsend_no) THEN
+         ishift = jpj-2*nn_hls
+
+         DO jf = 1, ipf  ;  DO jl = 1, ipl  ;  DO jk = 1, ipk  ;  DO jj = 1, nn_hls  ;  DO ji = nn_hls + 1, jpi - nn_hls
+            zsnd(idx) = ARRAY_IN(ji,ishift+jj,jk,jl,jf)
+            idx = idx + 1
+         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+
+         isizes(icount) = (jpi - 2*nn_hls) * nn_hls * ipk * ipl * ipf
+         IF(icount .gt. 1) isizet = isizet + isizes(icount - 1)
+         idispls(icount) = jpbyt*isizet
+         icount = icount + 1
+      END IF
+
+      isizer(:) = isizes(:)
+      idisplr(:) = idispls(:)
+      
+      icount1 = icount
+      isizets = isizet 
+      isizetr = isizet 
+
+      IF(llncall) THEN
+         IF(noswr .ne. -1) THEN
+            isizer(icount1) = nn_hls * nn_hls * ipk * ipl * ipf
+            IF(icount1 .gt. 1) isizetr = isizetr + isizer(icount1 - 1)
+            idisplr(icount1) = jpbyt*isizetr
+            icount1 = icount1 + 1
+         END IF
+         IF(noser .ne. -1) THEN
+            isizer(icount1) = nn_hls * nn_hls * ipk * ipl * ipf
+            IF(icount1 .gt. 1) isizetr = isizetr + isizer(icount1 - 1)
+            idisplr(icount1) = jpbyt*isizetr
+            icount1 = icount1 + 1
+         END IF
+         IF(nonwr .ne. -1) THEN
+            isizer(icount1) = nn_hls * nn_hls * ipk * ipl * ipf
+            IF(icount1 .gt. 1) isizetr = isizetr + isizer(icount1 - 1)
+            idisplr(icount1) = jpbyt*isizetr
+            icount1 = icount1 + 1
+         END IF
+         IF(noner .ne. -1) THEN
+            isizer(icount1) = nn_hls * nn_hls * ipk * ipl * ipf
+            IF(icount1 .gt. 1) isizetr = isizetr + isizer(icount1 - 1)
+            idisplr(icount1) = jpbyt*isizetr
+            icount1 = icount1 + 1
+         END IF
+
+         IF(nosws .ne. -1) THEN
+            DO jf = 1, ipf  ;  DO jl = 1, ipl  ;  DO jk = 1, ipk  ;  DO jj = 1, nn_hls  ;  DO ji = 1, nn_hls
+               zsnd(idx) = ARRAY_IN(nn_hls+ji,nn_hls+jj,jk,jl,jf)
+               idx = idx + 1
+            END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+
+            isizes(icount) = nn_hls * nn_hls * ipk * ipl * ipf
+            IF(icount .gt. 1) isizets = isizets + isizes(icount - 1)
+            idispls(icount) = jpbyt*isizets
+            icount = icount + 1
+         END IF
+         IF(noses .ne. -1) THEN
+            ishift = jpi-2*nn_hls
+            DO jf = 1, ipf  ;  DO jl = 1, ipl  ;  DO jk = 1, ipk  ;  DO jj = 1, nn_hls  ;  DO ji = 1, nn_hls
+               zsnd(idx) = ARRAY_IN(ji+ishift,nn_hls+jj,jk,jl,jf)
+               idx = idx + 1
+            END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+
+            isizes(icount) = nn_hls * nn_hls * ipk * ipl * ipf
+            IF(icount .gt. 1) isizets = isizets + isizes(icount - 1)
+            idispls(icount) = jpbyt*isizets
+            icount = icount + 1
+         END IF
+         IF(nonws .ne. -1) THEN
+            ishift = jpj-2*nn_hls
+            DO jf = 1, ipf  ;  DO jl = 1, ipl  ;  DO jk = 1, ipk  ;  DO jj = 1, nn_hls  ;  DO ji = 1, nn_hls
+               zsnd(idx) = ARRAY_IN(nn_hls+ji,jj+ishift,jk,jl,jf)
+               idx = idx + 1
+            END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+
+            isizes(icount) = nn_hls * nn_hls * ipk * ipl * ipf
+            IF(icount .gt. 1) isizets = isizets + isizes(icount - 1)
+            idispls(icount) = jpbyt*isizets
+            icount = icount + 1
+         END IF
+         IF(nones .ne. -1) THEN
+            ishift = jpi-2*nn_hls
+            ishift2 = jpj-2*nn_hls
+            DO jf = 1, ipf  ;  DO jl = 1, ipl  ;  DO jk = 1, ipk  ;  DO jj = 1, nn_hls  ;  DO ji = 1, nn_hls
+               zsnd(idx) = ARRAY_IN(ji+ishift,jj+ishift2,jk,jl,jf)
+               idx = idx + 1
+            END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+
+            isizes(icount) = nn_hls * nn_hls * ipk * ipl * ipf
+            IF(icount .gt. 1) isizets = isizets + isizes(icount - 1)
+            idispls(icount) = jpbyt*isizets
+            icount = icount + 1
+         END IF
+      END IF
+
+      idatatys(:) = MPI_TYPE
+      idatatyr(:) = MPI_TYPE
+
+      IF(llncall) THEN
+         IF( ln_timing ) CALL tic_tac(.TRUE.)
+         CALL mpi_neighbor_alltoallw (zsnd, isizes, idispls, idatatys, zrcv, isizer, idisplr, idatatyr, mpi_nc_all_com, ierr)
+         IF( ln_timing ) CALL tic_tac(.FALSE.)
+      ELSE
+         IF( ln_timing ) CALL tic_tac(.TRUE.)
+         CALL mpi_neighbor_alltoallw (zsnd, isizes, idispls, idatatys, zrcv, isizer, idisplr, idatatyr, mpi_nc_com, ierr)
+         IF( ln_timing ) CALL tic_tac(.FALSE.)
+      END IF
+
+      ! --------------------------------------------------- !
+      !     2. Fill east and west north and south halos     !
+      ! --------------------------------------------------- !
+      !
+      !!! Patch to solve MPI3 bug when we have only two processes columns
+      IF(jpni .eq. 2) THEN
+         ! ---------------------
+         ! 2.2 fill eastern halo
+         ! ---------------------
+         idx = 1
+         ishift = jpi - nn_hls                ! fill halo from ji = jpi-nn_hls+1 to jpi
+         SELECT CASE ( ifill_ea )
+         CASE ( jpfillnothing )               ! no filling
+         CASE ( jpfillmpi   )                 ! use data received by MPI
+            DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = nn_hls + 1, jpj - nn_hls   ;   DO ji = 1, nn_hls
+               ARRAY_IN(ishift+ji,jj,jk,jl,jf) = zrcv(idx)   ! jpi - nn_hls + 1 -> jpi
+               idx = idx + 1
+            END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+         CASE ( jpfillperio )                 ! use east-weast periodicity
+            ishift2 = nn_hls
+            DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, nn_hls
+               ARRAY_IN(ishift+ji,jj,jk,jl,jf) = ARRAY_IN(ishift2+ji,jj,jk,jl,jf)
+            END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+         CASE ( jpfillcopy  )                 ! filling with inner domain values
+            DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, nn_hls
+               ARRAY_IN(ishift+ji,jj,jk,jl,jf) = ARRAY_IN(ishift,jj,jk,jl,jf)
+            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, jpj   ;   DO ji = 1, nn_hls
+               ARRAY_IN(ishift+ji,jj,jk,jl,jf) = zland
+            END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+         END SELECT
+         ! ----------------------
+         ! 2.1 fill weastern halo
+         ! ----------------------
+         SELECT CASE ( ifill_we )
+         CASE ( jpfillnothing )               ! no filling
+         CASE ( jpfillmpi   )                 ! use data received by MPI
+            DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = nn_hls + 1, jpj - nn_hls   ;   DO ji = 1, nn_hls
+               ARRAY_IN(ji,jj,jk,jl,jf) = zrcv(idx)   ! 1 -> nn_hls
+               idx = idx + 1
+            END DO;   END DO   ;   END DO   ;   END DO   ;   END DO
+         CASE ( jpfillperio )                 ! use east-weast periodicity
+            ishift2 = jpi - 2 * nn_hls
+            DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, nn_hls
+               ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(ishift2+ji,jj,jk,jl,jf)
+            END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+         CASE ( jpfillcopy  )                 ! filling with inner domain values
+            DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, nn_hls
+               ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(nn_hls+1,jj,jk,jl,jf)
+            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, jpj   ;   DO ji = 1, nn_hls
+               ARRAY_IN(ji,jj,jk,jl,jf) = zland
+            END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+         END SELECT
+
+      ELSE
+
+         ! ----------------------
+         ! 2.1 fill weastern halo
+         ! ----------------------
+         idx = 1
+         SELECT CASE ( ifill_we )
+         CASE ( jpfillnothing )               ! no filling 
+         CASE ( jpfillmpi   )                 ! use data received by MPI 
+            DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = nn_hls + 1, jpj - nn_hls   ;   DO ji = 1, nn_hls
+               ARRAY_IN(ji,jj,jk,jl,jf) = zrcv(idx)   ! 1 -> nn_hls
+               idx = idx + 1
+            END DO;   END DO   ;   END DO   ;   END DO   ;   END DO
+         CASE ( jpfillperio )                 ! use east-weast periodicity
+            ishift2 = jpi - 2 * nn_hls
+            DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, nn_hls
+               ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(ishift2+ji,jj,jk,jl,jf)
+            END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+         CASE ( jpfillcopy  )                 ! filling with inner domain values
+            DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, nn_hls
+               ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(nn_hls+1,jj,jk,jl,jf)
+            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, jpj   ;   DO ji = 1, nn_hls
+               ARRAY_IN(ji,jj,jk,jl,jf) = zland
+            END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+         END SELECT
+         ! ---------------------
+         ! 2.2 fill eastern halo
+         ! ---------------------
+         ishift = jpi - nn_hls                ! fill halo from ji = jpi-nn_hls+1 to jpi 
+         SELECT CASE ( ifill_ea )
+         CASE ( jpfillnothing )               ! no filling 
+         CASE ( jpfillmpi   )                 ! use data received by MPI 
+            DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = nn_hls + 1, jpj - nn_hls   ;   DO ji = 1, nn_hls
+               ARRAY_IN(ishift+ji,jj,jk,jl,jf) = zrcv(idx)   ! jpi - nn_hls + 1 -> jpi
+               idx = idx + 1
+            END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+         CASE ( jpfillperio )                 ! use east-weast periodicity
+            ishift2 = nn_hls
+            DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, nn_hls
+               ARRAY_IN(ishift+ji,jj,jk,jl,jf) = ARRAY_IN(ishift2+ji,jj,jk,jl,jf)
+            END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+         CASE ( jpfillcopy  )                 ! filling with inner domain values
+            DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, jpj   ;   DO ji = 1, nn_hls
+               ARRAY_IN(ishift+ji,jj,jk,jl,jf) = ARRAY_IN(ishift,jj,jk,jl,jf)
+            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, jpj   ;   DO ji = 1, nn_hls
+               ARRAY_IN(ishift+ji,jj,jk,jl,jf) = zland
+            END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+         END SELECT
+
+      ENDIF
+
+      !!! Patch to solve MPI3 bug when we have only two processes rows
+      IF(jpnj .eq. 2) THEN
+         ! ----------------------
+         ! 2.3 fill northern halo
+         ! ----------------------
+         ishift = jpj - nn_hls                ! fill halo from jj = jpj-nn_hls+1 to jpj 
+         SELECT CASE ( ifill_no )
+         CASE ( jpfillnothing )               ! no filling 
+         CASE ( jpfillmpi   )                 ! use data received by MPI 
+            DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = nn_hls + 1, jpi - nn_hls
+               ARRAY_IN(ji,ishift+jj,jk,jl,jf) = zrcv(idx)   ! jpj-nn_hls+1 -> jpj
+               idx = idx + 1
+            END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+            IF(nonwr .eq. -1) THEN
+               ishift = jpj - nn_hls
+               SELECT CASE ( ifill_web )
+                  CASE ( jpfillperio )
+                     ishift2 = jpi - 2 * nn_hls
+                     DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1 + ishift, jpj   ;  DO ji = 1, nn_hls
+                        ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(ishift2+ji,jj,jk,jl,jf)
+                     END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+                  CASE ( jpfillcopy  )
+                     DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1 + ishift, jpj   ;  DO ji = 1, nn_hls
+                        ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(nn_hls+1,jj,jk,jl,jf)
+                     END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+
+                  CASE ( jpfillcst   )
+                     DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1 + ishift, jpj   ;  DO ji = 1, nn_hls
+                        ARRAY_IN(ji,jj,jk,jl,jf) = zland
+                     END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+               END SELECT
+            END IF
+            IF(noner .eq. -1) THEN
+               ishift = jpi - nn_hls
+               ishift2 = jpj - nn_hls
+               SELECT CASE ( ifill_eab )
+                  CASE ( jpfillperio )
+                     DO jf = 1, ipf  ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1 + ishift2, jpj   ;  DO ji = 1, nn_hls
+                        ARRAY_IN(ishift+ji,jj,jk,jl,jf) = ARRAY_IN(ji,jj,jk,jl,jf)
+                     END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+
+                  CASE ( jpfillcopy  )
+                     DO jf = 1, ipf  ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1 + ishift2, jpj   ;  DO ji = 1, nn_hls
+                        ARRAY_IN(ishift+ji,jj,jk,jl,jf) = ARRAY_IN(ishift,jj,jk,jl,jf)
+                     END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+                  CASE ( jpfillcst   )
+                     DO jf = 1, ipf  ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1 + ishift2, jpj   ;  DO ji = 1, nn_hls
+                        ARRAY_IN(ishift+ji,jj,jk,jl,jf) = zland
+                     END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+               END SELECT
+            END IF
+         CASE ( jpfillperio )                 ! use north-south periodicity
+            ishift2 = nn_hls
+            DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi
+               ARRAY_IN(ji,ishift+jj,jk,jl,jf) = ARRAY_IN(ji,ishift2+jj,jk,jl,jf)
+            END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+         CASE ( jpfillcopy  )                 ! filling with inner domain values
+            DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi
+               ARRAY_IN(ji,ishift+jj,jk,jl,jf) = ARRAY_IN(ji,ishift,jk,jl,jf)
+            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, nn_hls   ;   DO ji = 1, jpi
+               ARRAY_IN(ji,ishift+jj,jk,jl,jf) = zland
+            END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+         END SELECT
+
+         ! ----------------------
+         ! 2.4 fill southern halo
+         ! ----------------------
+         SELECT CASE ( ifill_so )
+         CASE ( jpfillnothing )               ! no filling 
+         CASE ( jpfillmpi   )                 ! use data received by MPI 
+            DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = nn_hls + 1, jpi - nn_hls
+               ARRAY_IN(ji,jj,jk,jl,jf) = zrcv(idx)   ! 1 -> nn_hls
+               idx = idx + 1
+            END DO;   END DO   ;   END DO   ;   END DO   ;   END DO
+            IF(noswr .eq. -1) THEN
+               SELECT CASE ( ifill_web )
+                  CASE ( jpfillperio )
+                     ishift2 = jpi - 2 * nn_hls
+                     DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = 1, nn_hls
+                        ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(ishift2+ji,jj,jk,jl,jf)
+                     END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+                  CASE ( jpfillcopy  )
+                     DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = 1, nn_hls
+                        ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(nn_hls+1,jj,jk,jl,jf)
+                     END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+
+                  CASE ( jpfillcst   )
+                     DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = 1, nn_hls
+                        ARRAY_IN(ji,jj,jk,jl,jf) = zland
+                     END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+               END SELECT
+            END IF
+            IF(noser .eq. -1) THEN
+               ishift = jpi - nn_hls
+               SELECT CASE ( ifill_eab )
+                  CASE ( jpfillperio )
+                     DO jf = 1, ipf  ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = 1, nn_hls
+                        ARRAY_IN(ishift+ji,jj,jk,jl,jf) = ARRAY_IN(ji+nn_hls,jj,jk,jl,jf)
+                     END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+
+                  CASE ( jpfillcopy  )
+                     DO jf = 1, ipf  ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = 1, nn_hls
+                        ARRAY_IN(ishift+ji,jj,jk,jl,jf) = ARRAY_IN(ishift,jj,jk,jl,jf)
+                     END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+                  CASE ( jpfillcst   )
+                     DO jf = 1, ipf  ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = 1, nn_hls
+                        ARRAY_IN(ishift+ji,jj,jk,jl,jf) = zland
+                     END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+               END SELECT
+            END IF
+         CASE ( jpfillperio )                 ! use north-south periodicity
+            ishift2 = jpj - 2 * nn_hls
+            DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi
+               ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(ji,ishift2+jj,jk,jl,jf)
+            END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+         CASE ( jpfillcopy  )                 ! filling with inner domain values
+            DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi
+               ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(ji,nn_hls+1,jk,jl,jf)
+            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, nn_hls   ;   DO ji = 1, jpi
+               ARRAY_IN(ji,jj,jk,jl,jf) = zland
+            END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+         END SELECT
+      ELSE
+         ! ----------------------
+         ! 2.3 fill southern halo
+         ! ----------------------
+         SELECT CASE ( ifill_so )
+         CASE ( jpfillnothing )               ! no filling 
+         CASE ( jpfillmpi   )                 ! use data received by MPI 
+            DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = nn_hls + 1, jpi - nn_hls
+               ARRAY_IN(ji,jj,jk,jl,jf) = zrcv(idx)   ! 1 -> nn_hls
+               idx = idx + 1
+            END DO;   END DO   ;   END DO   ;   END DO   ;   END DO
+            IF(noswr .eq. -1) THEN
+               SELECT CASE ( ifill_web )
+                  CASE ( jpfillperio )
+                     ishift2 = jpi - 2 * nn_hls
+                     DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = 1, nn_hls
+                        ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(ishift2+ji,jj,jk,jl,jf)
+                     END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+                  CASE ( jpfillcopy  )
+                     DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = 1, nn_hls
+                        ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(nn_hls+1,jj,jk,jl,jf)
+                     END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+
+                  CASE ( jpfillcst   )
+                     DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = 1, nn_hls
+                        ARRAY_IN(ji,jj,jk,jl,jf) = zland
+                     END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+               END SELECT
+            END IF
+            IF(noser .eq. -1) THEN
+               ishift = jpi - nn_hls
+               SELECT CASE ( ifill_eab )
+                  CASE ( jpfillperio )
+                     DO jf = 1, ipf  ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = 1, nn_hls
+                        ARRAY_IN(ishift+ji,jj,jk,jl,jf) = ARRAY_IN(ji+nn_hls,jj,jk,jl,jf)
+                     END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+
+                  CASE ( jpfillcopy  )
+                     DO jf = 1, ipf  ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = 1, nn_hls
+                        ARRAY_IN(ishift+ji,jj,jk,jl,jf) = ARRAY_IN(ishift,jj,jk,jl,jf)
+                     END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+                  CASE ( jpfillcst   )
+                     DO jf = 1, ipf  ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = 1, nn_hls
+                        ARRAY_IN(ishift+ji,jj,jk,jl,jf) = zland
+                     END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+               END SELECT
+            END IF
+         CASE ( jpfillperio )                 ! use north-south periodicity
+            ishift2 = jpj - 2 * nn_hls
+            DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi
+               ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(ji,ishift2+jj,jk,jl,jf)
+            END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+         CASE ( jpfillcopy  )                 ! filling with inner domain values
+            DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi
+               ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(ji,nn_hls+1,jk,jl,jf)
+            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, nn_hls   ;   DO ji = 1, jpi
+               ARRAY_IN(ji,jj,jk,jl,jf) = zland
+            END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+         END SELECT
+
+         ! ----------------------
+         ! 2.4 fill northern halo
+         ! ----------------------
+         ishift = jpj - nn_hls                ! fill halo from jj = jpj-nn_hls+1 to jpj 
+         SELECT CASE ( ifill_no )
+         CASE ( jpfillnothing )               ! no filling 
+         CASE ( jpfillmpi   )                 ! use data received by MPI 
+            DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = nn_hls + 1, jpi - nn_hls
+               ARRAY_IN(ji,ishift+jj,jk,jl,jf) = zrcv(idx)   ! jpj-nn_hls+1 -> jpj
+               idx = idx + 1
+            END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+            IF(nonwr .eq. -1) THEN
+               ishift = jpj - nn_hls
+               SELECT CASE ( ifill_web )
+                  CASE ( jpfillperio )
+                     ishift2 = jpi - 2 * nn_hls
+                     DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1 + ishift, jpj   ;  DO ji = 1, nn_hls
+                        ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(ishift2+ji,jj,jk,jl,jf)
+                     END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+                  CASE ( jpfillcopy  )
+                     DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1 + ishift, jpj   ;  DO ji = 1, nn_hls
+                        ARRAY_IN(ji,jj,jk,jl,jf) = ARRAY_IN(nn_hls+1,jj,jk,jl,jf)
+                     END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+
+                  CASE ( jpfillcst   )
+                     DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1 + ishift, jpj   ;  DO ji = 1, nn_hls
+                        ARRAY_IN(ji,jj,jk,jl,jf) = zland
+                     END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+               END SELECT
+            END IF
+            IF(noner .eq. -1) THEN
+               ishift = jpi - nn_hls
+               ishift2 = jpj - nn_hls
+               SELECT CASE ( ifill_eab )
+                  CASE ( jpfillperio )
+                     DO jf = 1, ipf  ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1 + ishift2, jpj   ;  DO ji = 1, nn_hls
+                        ARRAY_IN(ishift+ji,jj,jk,jl,jf) = ARRAY_IN(ji,jj,jk,jl,jf)
+                     END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+
+                  CASE ( jpfillcopy  )
+                     DO jf = 1, ipf  ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1 + ishift2, jpj   ;  DO ji = 1, nn_hls
+                        ARRAY_IN(ishift+ji,jj,jk,jl,jf) = ARRAY_IN(ishift,jj,jk,jl,jf)
+                     END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+                  CASE ( jpfillcst   )
+                     DO jf = 1, ipf  ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1 + ishift2, jpj   ;  DO ji = 1, nn_hls
+                        ARRAY_IN(ishift+ji,jj,jk,jl,jf) = zland
+                     END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+               END SELECT
+            END IF
+         CASE ( jpfillperio )                 ! use north-south periodicity
+            ishift2 = nn_hls
+            DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi
+               ARRAY_IN(ji,ishift+jj,jk,jl,jf) = ARRAY_IN(ji,ishift2+jj,jk,jl,jf)
+            END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+         CASE ( jpfillcopy  )                 ! filling with inner domain values
+            DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi
+               ARRAY_IN(ji,ishift+jj,jk,jl,jf) = ARRAY_IN(ji,ishift,jk,jl,jf)
+            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, nn_hls   ;   DO ji = 1, jpi
+               ARRAY_IN(ji,ishift+jj,jk,jl,jf) = zland
+            END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+         END SELECT
+      ENDIF
+
+      IF(llncall) THEN
+
+         !!! Patch to solve MPI3 bug when we have only two processes columns
+         IF(jpni .eq. 2) THEN
+            !!! Patch to solve MPI3 bug when we have only two processes rows
+            IF(jpnj .eq. 2) THEN
+               ! ---------------------------
+               ! 2.5 fill east-nouthern halo
+               ! ---------------------------
+                 IF(noner .ne. -1) THEN
+                    ishift = jpi - nn_hls
+                    ishift2 = jpj - nn_hls
+                    DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = 1, nn_hls
+                       ARRAY_IN(ji+ishift,jj+ishift2,jk,jl,jf) = zrcv(idx)
+                       idx = idx + 1
+                    END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+                 END IF
+               ! ---------------------------
+               ! 2.6 fill west-nouthern halo
+               ! ---------------------------
+                 IF(nonwr .ne. -1) THEN
+                    ishift = jpj - nn_hls
+                    DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = 1, nn_hls
+                       ARRAY_IN(ji,jj+ishift,jk,jl,jf) = zrcv(idx)
+                       idx = idx + 1
+                    END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+                 END IF
+               ! ---------------------------
+               ! 2.7 fill east-southern halo
+               ! ---------------------------
+                 IF(noser .ne. -1) THEN
+                    ishift = jpi - nn_hls
+                    DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = 1, nn_hls
+                       ARRAY_IN(ji+ishift,jj,jk,jl,jf) = zrcv(idx)
+                       idx = idx + 1
+                    END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+                 END IF
+               ! ---------------------------
+               ! 2.8 fill west-southern halo
+               ! ---------------------------
+                 IF(noswr .ne. -1) THEN
+                    DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = 1, nn_hls
+                       ARRAY_IN(ji,jj,jk,jl,jf) = zrcv(idx)
+                       idx = idx + 1
+                    END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+                 END IF
+
+            ELSE
+               ! ---------------------------
+               ! 2.5 fill east-southern halo
+               ! ---------------------------
+                 IF(noser .ne. -1) THEN
+                    ishift = jpi - nn_hls
+                    DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = 1, nn_hls
+                       ARRAY_IN(ji+ishift,jj,jk,jl,jf) = zrcv(idx)
+                       idx = idx + 1
+                    END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+                 END IF
+               ! ---------------------------
+               ! 2.6 fill west-southern halo
+               ! ---------------------------
+                 IF(noswr .ne. -1) THEN
+                    DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = 1, nn_hls
+                       ARRAY_IN(ji,jj,jk,jl,jf) = zrcv(idx)
+                       idx = idx + 1
+                    END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+                 END IF
+               ! ---------------------------
+               ! 2.7 fill east-nouthern halo
+               ! ---------------------------
+                 IF(noner .ne. -1) THEN
+                    ishift = jpi - nn_hls
+                    ishift2 = jpj - nn_hls
+                    DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = 1, nn_hls
+                       ARRAY_IN(ji+ishift,jj+ishift2,jk,jl,jf) = zrcv(idx)
+                       idx = idx + 1
+                    END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+                 END IF
+               ! ---------------------------
+               ! 2.8 fill west-nouthern halo
+               ! ---------------------------
+                 IF(nonwr .ne. -1) THEN
+                    ishift = jpj - nn_hls
+                    DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = 1, nn_hls
+                       ARRAY_IN(ji,jj+ishift,jk,jl,jf) = zrcv(idx)
+                       idx = idx + 1
+                    END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+                 END IF
+            ENDIF
+         ELSE
+            !!! Patch to solve MPI3 bug when we have only two processes rows
+            IF(jpnj .eq. 2) THEN
+               ! ---------------------------
+               ! 2.5 fill west-nouthern halo
+               ! ---------------------------
+                 IF(nonwr .ne. -1) THEN
+                    ishift = jpj - nn_hls
+                    DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = 1, nn_hls
+                       ARRAY_IN(ji,jj+ishift,jk,jl,jf) = zrcv(idx)
+                       idx = idx + 1
+                    END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+                 END IF
+               ! ---------------------------
+               ! 2.6 fill east-nouthern halo
+               ! ---------------------------
+                 IF(noner .ne. -1) THEN
+                    ishift = jpi - nn_hls
+                    ishift2 = jpj - nn_hls
+                    DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = 1, nn_hls
+                       ARRAY_IN(ji+ishift,jj+ishift2,jk,jl,jf) = zrcv(idx)
+                       idx = idx + 1
+                    END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+                 END IF
+               ! ---------------------------
+               ! 2.7 fill west-southern halo
+               ! ---------------------------
+                 IF(noswr .ne. -1) THEN
+                    DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = 1, nn_hls
+                       ARRAY_IN(ji,jj,jk,jl,jf) = zrcv(idx)
+                       idx = idx + 1
+                    END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+                 END IF
+               ! ---------------------------
+               ! 2.8 fill east-southern halo
+               ! ---------------------------
+                 IF(noser .ne. -1) THEN
+                    ishift = jpi - nn_hls
+                    DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = 1, nn_hls
+                       ARRAY_IN(ji+ishift,jj,jk,jl,jf) = zrcv(idx)
+                       idx = idx + 1
+                    END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+                 END IF
+
+            ELSE
+               ! ---------------------------
+               ! 2.5 fill west-southern halo
+               ! ---------------------------
+                 IF(noswr .ne. -1) THEN
+                    DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = 1, nn_hls
+                       ARRAY_IN(ji,jj,jk,jl,jf) = zrcv(idx)
+                       idx = idx + 1
+                    END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+                 END IF
+               ! ---------------------------
+               ! 2.6 fill east-southern halo
+               ! ---------------------------
+                 IF(noser .ne. -1) THEN
+                    ishift = jpi - nn_hls
+                    DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = 1, nn_hls
+                       ARRAY_IN(ji+ishift,jj,jk,jl,jf) = zrcv(idx)
+                       idx = idx + 1
+                    END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+                 END IF
+               ! ---------------------------
+               ! 2.7 fill west-nouthern halo
+               ! ---------------------------
+                 IF(nonwr .ne. -1) THEN
+                    ishift = jpj - nn_hls
+                    DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = 1, nn_hls
+                       ARRAY_IN(ji,jj+ishift,jk,jl,jf) = zrcv(idx)
+                       idx = idx + 1
+                    END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+                 END IF
+               ! ---------------------------
+               ! 2.8 fill east-nouthern halo
+               ! ---------------------------
+                 IF(noner .ne. -1) THEN
+                    ishift = jpi - nn_hls
+                    ishift2 = jpj - nn_hls
+                    DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;  DO ji = 1, nn_hls
+                       ARRAY_IN(ji+ishift,jj+ishift2,jk,jl,jf) = zrcv(idx)
+                       idx = idx + 1
+                    END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+                 END IF
+            ENDIF
+         END IF
+      END IF
+
+
+      !
+      ! -------------------------------------------- !
+      !     3. deallocate local temporary arrays     !
+      ! -------------------------------------------- !
+      !
+      DEALLOCATE( zsnd )
+      DEALLOCATE( zrcv )
+      DEALLOCATE(isizes)
+      DEALLOCATE(isizer)
+      DEALLOCATE(idatatys)
+      DEALLOCATE(idatatyr)
+      DEALLOCATE(idispls)
+      DEALLOCATE(idisplr)
+      !
+      ! ------------------------------- !
+      !     4. north fold treatment     !
+      ! ------------------------------- !
+      !
+      IF( lldo_nfd .AND. ifill_no /= jpfillnothing ) THEN
+         !
+         SELECT CASE ( jpni )
+         CASE ( 1 )     ;   CALL lbc_nfd( ptab, NAT_IN(:), SGN_IN(:)                  OPT_K(:) )   ! only 1 northern proc, no mpp
+         CASE DEFAULT   ;   CALL mpp_nfd( ptab, NAT_IN(:), SGN_IN(:), ifill_no, zland OPT_K(:) )   ! for all northern procs.
+         END SELECT
+         !
+         ifill_no = jpfillnothing  ! force to do nothing for the northern halo as we just done the north pole folding
+         !
+      ENDIF
+
+   END SUBROUTINE ROUTINE_NC
+
+#undef PRECISION
+#undef ARRAY_TYPE
+#undef NAT_IN
+#undef SGN_IN
+#undef ARRAY_IN
+#undef K_SIZE
+#undef L_SIZE
+#undef F_SIZE
+#undef OPT_K
+#undef MPI_TYPE
Index: /NEMO/trunk/src/OCE/LBC/mppini.F90
===================================================================
--- /NEMO/trunk/src/OCE/LBC/mppini.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/LBC/mppini.F90	(revision 13982)
@@ -542,9 +542,4 @@
       ij = ijn(narea)
       !
-      ! set default neighbours
-      noso = ii_noso(narea)
-      nowe = ii_nowe(narea)
-      noea = ii_noea(narea)
-      nono = ii_nono(narea)
       jpi    = ijpi(ii,ij)  
 !!$      Nis0  = iis0(ii,ij)
@@ -558,4 +553,63 @@
       njmpp = ijmppt(ii,ij)
       jpk = jpkglo                              ! third dim
+
+      ! set default neighbours
+      noso = ii_noso(narea)
+      nowe = ii_nowe(narea)
+      noea = ii_noea(narea)
+      nono = ii_nono(narea)
+
+      nones = -1
+      nonws = -1
+      noses = -1
+      nosws = -1
+      
+      noner = -1
+      nonwr = -1
+      noser = -1
+      noswr = -1
+
+      IF((nbondi .eq. -1) .or. (nbondi .eq. 0)) THEN ! east neighbour exists
+         IF(ibondj(iin(noea+1),ijn(noea+1)) .eq. 0) THEN
+            nones = ii_nono(noea+1)                  ! east neighbour has north and south neighbours
+            noses = ii_noso(noea+1)
+         ELSEIF(ibondj(iin(noea+1),ijn(noea+1)) .eq. -1) THEN
+            nones = ii_nono(noea+1)                  ! east neighbour has north neighbour
+         ELSEIF(ibondj(iin(noea+1),ijn(noea+1)) .eq. 1) THEN
+            noses = ii_noso(noea+1)                  ! east neighbour has south neighbour
+         END IF
+      END IF
+      IF((nbondi .eq. 1) .or. (nbondi .eq. 0)) THEN  ! west neighbour exists
+         IF(ibondj(iin(nowe+1),ijn(nowe+1)) .eq. 0) THEN
+            nonws = ii_nono(nowe+1)                  ! west neighbour has north and south neighbours
+            nosws = ii_noso(nowe+1)
+         ELSEIF(ibondj(iin(nowe+1),ijn(nowe+1)) .eq. -1) THEN
+            nonws = ii_nono(nowe+1)                  ! west neighbour has north neighbour
+         ELSEIF(ibondj(iin(nowe+1),ijn(nowe+1)) .eq. 1)  THEN
+            nosws = ii_noso(nowe+1)                  ! west neighbour has north neighbour
+         END IF
+      END IF
+
+      IF((nbondj .eq. -1) .or. (nbondj .eq. 0)) THEN ! north neighbour exists
+         IF(ibondi(iin(nono+1),ijn(nono+1)) .eq. 0) THEN
+            noner = ii_noea(nono+1)                  ! north neighbour has east and west neighbours
+            nonwr = ii_nowe(nono+1)
+         ELSEIF(ibondi(iin(nono+1),ijn(nono+1)) .eq. -1) THEN
+            noner = ii_noea(nono+1)                  ! north neighbour has east neighbour
+         ELSEIF(ibondi(iin(nono+1),ijn(nono+1)) .eq. 1) THEN
+            nonwr = ii_nowe(nono+1)                  ! north neighbour has west neighbour
+         END IF
+      END IF
+      IF((nbondj .eq. 1) .or. (nbondj .eq. 0)) THEN  ! south neighbour exists
+         IF(ibondi(iin(noso+1),ijn(noso+1)) .eq. 0) THEN
+            noser = ii_noea(noso+1)                  ! south neighbour has east and west neighbours
+            noswr = ii_nowe(noso+1)
+         ELSEIF(ibondi(iin(noso+1),ijn(noso+1)) .eq. -1) THEN
+            noser = ii_noea(noso+1)                  ! south neighbour has east neighbour
+         ELSEIF(ibondi(iin(noso+1),ijn(noso+1)) .eq. 1) THEN
+            noswr = ii_nowe(noso+1)                  ! south neighbour has west neighbour
+         END IF
+      END IF
+
       !
       CALL init_doloop                          ! set start/end indices of do-loop, depending on the halo width value (nn_hls) 
@@ -648,4 +702,7 @@
          ENDIF
       ENDIF
+
+      !
+      CALL mpp_ini_nc        ! Initialize communicator for neighbourhood collective communications
       !
       CALL init_ioipsl       ! Prepare NetCDF output file (if necessary)
Index: /NEMO/trunk/src/OCE/LDF/ldfc1d_c2d.F90
===================================================================
--- /NEMO/trunk/src/OCE/LDF/ldfc1d_c2d.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/LDF/ldfc1d_c2d.F90	(revision 13982)
@@ -140,5 +140,6 @@
          END_2D
       CASE( 'TRA' )                       ! U- and V-points
-         DO_2D( 1, 1, 1, 1 )
+         ! NOTE: [tiling-comms-merge] Change needed to preserve results with respect to the trunk
+         DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
             pah1(ji,jj,1) = pUfac * MAX( e1u(ji,jj), e2u(ji,jj) )**knn
             pah2(ji,jj,1) = pUfac * MAX( e1v(ji,jj), e2v(ji,jj) )**knn
Index: /NEMO/trunk/src/OCE/LDF/ldftra.F90
===================================================================
--- /NEMO/trunk/src/OCE/LDF/ldftra.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/LDF/ldftra.F90	(revision 13982)
@@ -427,5 +427,6 @@
          zaht_min = 0.2_wp * aht0                                       ! minimum value for aht
          zDaht    = aht0 - zaht_min                                      
-         DO_2D( 1, 1, 1, 1 )
+         ! NOTE: [tiling-comms-merge] Change needed to preserve results with respect to the trunk
+         DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
             !!gm CAUTION : here we assume lat/lon grid in 20deg N/S band (like all ORCA cfg)
             !!     ==>>>   The Coriolis value is identical for t- & u_points, and for v- and f-points
@@ -725,22 +726,24 @@
       !! ** Action  : pu, pv increased by the eiv transport
       !!----------------------------------------------------------------------
-      INTEGER                         , INTENT(in   ) ::   kt        ! ocean time-step index
-      INTEGER                         , INTENT(in   ) ::   kit000    ! first time step index
-      INTEGER                         , INTENT(in   ) ::   Kmm, Krhs ! ocean time level indices
-      CHARACTER(len=3)                , INTENT(in   ) ::   cdtype    ! =TRA or TRC (tracer indicator)
-      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                     , INTENT(in   ) ::   kt        ! ocean time-step index
+      INTEGER                     , INTENT(in   ) ::   kit000    ! first time step index
+      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]
       !!
       INTEGER  ::   ji, jj, jk                 ! dummy loop indices
       REAL(wp) ::   zuwk, zuwk1, zuwi, zuwi1   ! local scalars
       REAL(wp) ::   zvwk, zvwk1, zvwj, zvwj1   !   -      -
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zpsi_uw, zpsi_vw
-      !!----------------------------------------------------------------------
-      !
-      IF( kt == kit000 )  THEN
-         IF(lwp) WRITE(numout,*)
-         IF(lwp) WRITE(numout,*) 'ldf_eiv_trp : eddy induced advection on ', cdtype,' :'
-         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~   add to velocity fields the eiv component'
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zpsi_uw, zpsi_vw
+      !!----------------------------------------------------------------------
+      !
+      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,*) 'ldf_eiv_trp : eddy induced advection on ', cdtype,' :'
+            IF(lwp) WRITE(numout,*) '~~~~~~~~~~~   add to velocity fields the eiv component'
+         ENDIF
       ENDIF
 
@@ -781,11 +784,11 @@
       !!
       !!----------------------------------------------------------------------
-      REAL(wp), DIMENSION(jpi,jpj,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(inout) ::   psi_uw, psi_vw   ! streamfunction   [m3/s]
+      INTEGER                     , INTENT(in   ) ::   Kmm   ! ocean time level indices
       !
       INTEGER  ::   ji, jj, jk    ! dummy loop indices
       REAL(wp) ::   zztmp   ! local scalar
-      REAL(wp), DIMENSION(jpi,jpj)     ::   zw2d   ! 2D workspace
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zw3d   ! 3D workspace
+      REAL(wp), DIMENSION(A2D(nn_hls))     ::   zw2d   ! 2D workspace
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zw3d   ! 3D workspace
       !!----------------------------------------------------------------------
       !
@@ -793,6 +796,4 @@
 !!gm     to be redesigned....   
       !                                                  !==  eiv stream function: output  ==!
-      CALL lbc_lnk_multi( 'ldftra', psi_uw, 'U', -1.0_wp , psi_vw, 'V', -1.0_wp )
-      !
 !!gm      CALL iom_put( "psi_eiv_uw", psi_uw )                 ! output
 !!gm      CALL iom_put( "psi_eiv_vw", psi_vw )
@@ -802,12 +803,12 @@
       zw3d(:,:,jpk) = 0._wp                                    ! bottom value always 0
       !
-      DO jk = 1, jpkm1                                         ! e2u e3u u_eiv = -dk[psi_uw]
-         zw3d(:,:,jk) = ( psi_uw(:,:,jk+1) - psi_uw(:,:,jk) ) / ( e2u(:,:) * e3u(:,:,jk,Kmm) )
-      END DO
+      DO_3D( 0, 0, 0, 0, 1, jpkm1 )                                  ! e2u e3u u_eiv = -dk[psi_uw]
+         zw3d(ji,jj,jk) = ( psi_uw(ji,jj,jk+1) - psi_uw(ji,jj,jk) ) / ( e2u(ji,jj) * e3u(ji,jj,jk,Kmm) )
+      END_3D
       CALL iom_put( "uoce_eiv", zw3d )
       !
-      DO jk = 1, jpkm1                                         ! e1v e3v v_eiv = -dk[psi_vw]
-         zw3d(:,:,jk) = ( psi_vw(:,:,jk+1) - psi_vw(:,:,jk) ) / ( e1v(:,:) * e3v(:,:,jk,Kmm) )
-      END DO
+      DO_3D( 0, 0, 0, 0, 1, jpkm1 )                                  ! e1v e3v v_eiv = -dk[psi_vw]
+         zw3d(ji,jj,jk) = ( psi_vw(ji,jj,jk+1) - psi_vw(ji,jj,jk) ) / ( e1v(ji,jj) * e3v(ji,jj,jk,Kmm) )
+      END_3D
       CALL iom_put( "voce_eiv", zw3d )
       !
@@ -816,9 +817,10 @@
             &              + psi_uw(ji,jj,jk) - psi_uw(ji-1,jj  ,jk)  ) / e1e2t(ji,jj)
       END_3D
-      CALL lbc_lnk( 'ldftra', zw3d, 'T', 1.0_wp )      ! lateral boundary condition
       CALL iom_put( "woce_eiv", zw3d )
       !
       IF( iom_use('weiv_masstr') ) THEN   ! vertical mass transport & its square value
-         zw2d(:,:) = rho0 * e1e2t(:,:)
+         DO_2D( 0, 0, 0, 0 )
+            zw2d(ji,jj) = rho0 * e1e2t(ji,jj)
+         END_2D
          DO jk = 1, jpk
             zw3d(:,:,jk) = zw3d(:,:,jk) * zw2d(:,:)
@@ -844,6 +846,4 @@
            zw2d(ji,jj) = zw2d(ji,jj) + zw3d(ji,jj,jk)
         END_3D
-        CALL lbc_lnk( 'ldftra', zw2d, 'U', -1.0_wp )
-        CALL lbc_lnk( 'ldftra', zw3d, 'U', -1.0_wp )
         CALL iom_put( "ueiv_heattr"  , zztmp * zw2d )                  ! heat transport in i-direction
         CALL iom_put( "ueiv_heattr3d", zztmp * zw3d )                  ! heat transport in i-direction
@@ -865,7 +865,6 @@
          zw2d(ji,jj) = zw2d(ji,jj) + zw3d(ji,jj,jk)
       END_3D
-      CALL lbc_lnk( 'ldftra', zw2d, 'V', -1.0_wp )
-      CALL iom_put( "veiv_heattr", zztmp * zw2d )                  !  heat transport in j-direction
-      CALL iom_put( "veiv_heattr", zztmp * zw3d )                  !  heat transport in j-direction
+      CALL iom_put( "veiv_heattr"  , zztmp * zw2d )                  !  heat transport in j-direction
+      CALL iom_put( "veiv_heattr3d", zztmp * zw3d )                  !  heat transport in j-direction
       !
       IF( iom_use( 'sophteiv' ) )   CALL dia_ptr_hst( jp_tem, 'eiv', 0.5 * zw3d )
@@ -880,6 +879,4 @@
            zw2d(ji,jj) = zw2d(ji,jj) + zw3d(ji,jj,jk)
         END_3D
-        CALL lbc_lnk( 'ldftra', zw2d, 'U', -1.0_wp )
-        CALL lbc_lnk( 'ldftra', zw3d, 'U', -1.0_wp )
         CALL iom_put( "ueiv_salttr", zztmp * zw2d )                  ! salt transport in i-direction
         CALL iom_put( "ueiv_salttr3d", zztmp * zw3d )                ! salt transport in i-direction
@@ -892,7 +889,6 @@
          zw2d(ji,jj) = zw2d(ji,jj) + zw3d(ji,jj,jk)
       END_3D
-      CALL lbc_lnk( 'ldftra', zw2d, 'V', -1.0_wp )
-      CALL iom_put( "veiv_salttr", zztmp * zw2d )                  !  salt transport in j-direction
-      CALL iom_put( "veiv_salttr", zztmp * zw3d )                  !  salt transport in j-direction
+      CALL iom_put( "veiv_salttr"  , zztmp * zw2d )                  !  salt transport in j-direction
+      CALL iom_put( "veiv_salttr3d", zztmp * zw3d )                  !  salt transport in j-direction
       !
       IF( iom_use( 'sopsteiv' ) ) CALL dia_ptr_hst( jp_sal, 'eiv', 0.5 * zw3d )
Index: /NEMO/trunk/src/OCE/SBC/sbcflx.F90
===================================================================
--- /NEMO/trunk/src/OCE/SBC/sbcflx.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/SBC/sbcflx.F90	(revision 13982)
@@ -127,5 +127,5 @@
 
          IF( ln_dm2dc ) THEN   ! modify now Qsr to include the diurnal cycle
-            qsr(:,:) = sbc_dcy( sf(jp_qsr)%fnow(:,:,1) ) * tmask(ji,jj,1)
+            qsr(:,:) = sbc_dcy( sf(jp_qsr)%fnow(:,:,1) ) * tmask(:,:,1)
          ELSE
             DO_2D( 0, 0, 0, 0 )
Index: /NEMO/trunk/src/OCE/TRA/eosbn2.F90
===================================================================
--- /NEMO/trunk/src/OCE/TRA/eosbn2.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/TRA/eosbn2.F90	(revision 13982)
@@ -39,4 +39,5 @@
    !!----------------------------------------------------------------------
    USE dom_oce        ! ocean space and time domain
+   USE domutl, ONLY : is_tile
    USE phycst         ! physical constants
    USE stopar         ! Stochastic T/S fluctuations
@@ -189,4 +190,14 @@
 
    SUBROUTINE eos_insitu( pts, prd, pdep )
+      !!
+      REAL(wp), DIMENSION(:,:,:,:), INTENT(in   ) ::   pts   ! 1 : potential temperature  [Celsius]
+      !                                                      ! 2 : salinity               [psu]
+      REAL(wp), DIMENSION(:,:,:)  , INTENT(  out) ::   prd   ! in situ density            [-]
+      REAL(wp), DIMENSION(:,:,:)  , INTENT(in   ) ::   pdep  ! depth                      [m]
+      !!
+      CALL eos_insitu_t( pts, is_tile(pts), prd, is_tile(prd), pdep, is_tile(pdep) )
+   END SUBROUTINE eos_insitu
+
+   SUBROUTINE eos_insitu_t( pts, ktts, prd, ktrd, pdep, ktdep )
       !!----------------------------------------------------------------------
       !!                   ***  ROUTINE eos_insitu  ***
@@ -222,8 +233,9 @@
       !!                TEOS-10 Manual, 2010
       !!----------------------------------------------------------------------
-      REAL(wp), DIMENSION(jpi,jpj,jpk,jpts), INTENT(in   ) ::   pts   ! 1 : potential temperature  [Celsius]
-      !                                                               ! 2 : salinity               [psu]
-      REAL(wp), DIMENSION(jpi,jpj,jpk     ), INTENT(  out) ::   prd   ! in situ density            [-]
-      REAL(wp), DIMENSION(jpi,jpj,jpk     ), INTENT(in   ) ::   pdep  ! depth                      [m]
+      INTEGER                                 , INTENT(in   ) ::   ktts, ktrd, ktdep
+      REAL(wp), DIMENSION(A2D_T(ktts) ,JPK,JPTS), INTENT(in   ) ::   pts   ! 1 : potential temperature  [Celsius]
+      !                                                                  ! 2 : salinity               [psu]
+      REAL(wp), DIMENSION(A2D_T(ktrd) ,JPK     ), INTENT(  out) ::   prd   ! in situ density            [-]
+      REAL(wp), DIMENSION(A2D_T(ktdep),JPK     ), INTENT(in   ) ::   pdep  ! depth                      [m]
       !
       INTEGER  ::   ji, jj, jk                ! dummy loop indices
@@ -238,5 +250,5 @@
       CASE( np_teos10, np_eos80 )                !==  polynomial TEOS-10 / EOS-80 ==!
          !
-         DO_3D( 1, 1, 1, 1, 1, jpkm1 )
+         DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpkm1 )
             !
             zh  = pdep(ji,jj,jk) * r1_Z0                                  ! depth
@@ -274,5 +286,5 @@
       CASE( np_seos )                !==  simplified EOS  ==!
          !
-         DO_3D( 1, 1, 1, 1, 1, jpkm1 )
+         DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpkm1 )
             zt  = pts  (ji,jj,jk,jp_tem) - 10._wp
             zs  = pts  (ji,jj,jk,jp_sal) - 35._wp
@@ -293,8 +305,20 @@
       IF( ln_timing )   CALL timing_stop('eos-insitu')
       !
-   END SUBROUTINE eos_insitu
+   END SUBROUTINE eos_insitu_t
 
 
    SUBROUTINE eos_insitu_pot( pts, prd, prhop, pdep )
+      !!
+      REAL(wp), DIMENSION(:,:,:,:), INTENT(in   ) ::   pts    ! 1 : potential temperature  [Celsius]
+      !                                                       ! 2 : salinity               [psu]
+      REAL(wp), DIMENSION(:,:,:)  , INTENT(  out) ::   prd    ! in situ density            [-]
+      REAL(wp), DIMENSION(:,:,:)  , INTENT(  out) ::   prhop  ! potential density (surface referenced)
+      REAL(wp), DIMENSION(:,:,:)  , INTENT(in   ) ::   pdep   ! depth                      [m]
+      !!
+      CALL eos_insitu_pot_t( pts, is_tile(pts), prd, is_tile(prd), prhop, is_tile(prhop), pdep, is_tile(pdep) )
+   END SUBROUTINE eos_insitu_pot
+
+
+   SUBROUTINE eos_insitu_pot_t( pts, ktts, prd, ktrd, prhop, ktrhop, pdep, ktdep )
       !!----------------------------------------------------------------------
       !!                  ***  ROUTINE eos_insitu_pot  ***
@@ -309,9 +333,10 @@
       !!
       !!----------------------------------------------------------------------
-      REAL(wp), DIMENSION(jpi,jpj,jpk,jpts), INTENT(in   ) ::   pts    ! 1 : potential temperature  [Celsius]
-      !                                                                ! 2 : salinity               [psu]
-      REAL(wp), DIMENSION(jpi,jpj,jpk     ), INTENT(  out) ::   prd    ! in situ density            [-]
-      REAL(wp), DIMENSION(jpi,jpj,jpk     ), INTENT(  out) ::   prhop  ! potential density (surface referenced)
-      REAL(wp), DIMENSION(jpi,jpj,jpk     ), INTENT(in   ) ::   pdep   ! depth                      [m]
+      INTEGER                                  , INTENT(in   ) ::   ktts, ktrd, ktrhop, ktdep
+      REAL(wp), DIMENSION(A2D_T(ktts)  ,JPK,JPTS), INTENT(in   ) ::   pts    ! 1 : potential temperature  [Celsius]
+      !                                                                    ! 2 : salinity               [psu]
+      REAL(wp), DIMENSION(A2D_T(ktrd)  ,JPK     ), INTENT(  out) ::   prd    ! in situ density            [-]
+      REAL(wp), DIMENSION(A2D_T(ktrhop),JPK     ), INTENT(  out) ::   prhop  ! potential density (surface referenced)
+      REAL(wp), DIMENSION(A2D_T(ktdep) ,JPK     ), INTENT(in   ) ::   pdep   ! depth                      [m]
       !
       INTEGER  ::   ji, jj, jk, jsmp             ! dummy loop indices
@@ -338,5 +363,5 @@
             END DO
             !
-            DO_3D( 1, 1, 1, 1, 1, jpkm1 )
+            DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpkm1 )
                !
                ! compute density (2*nn_sto_eos) times:
@@ -388,5 +413,5 @@
          ! Non-stochastic equation of state
          ELSE
-            DO_3D( 1, 1, 1, 1, 1, jpkm1 )
+            DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpkm1 )
                !
                zh  = pdep(ji,jj,jk) * r1_Z0                                  ! depth
@@ -426,5 +451,5 @@
       CASE( np_seos )                !==  simplified EOS  ==!
          !
-         DO_3D( 1, 1, 1, 1, 1, jpkm1 )
+         DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpkm1 )
             zt  = pts  (ji,jj,jk,jp_tem) - 10._wp
             zs  = pts  (ji,jj,jk,jp_sal) - 35._wp
@@ -444,12 +469,24 @@
       END SELECT
       !
-      IF(sn_cfctl%l_prtctl)   CALL prt_ctl( tab3d_1=prd, clinfo1=' eos-pot: ', tab3d_2=prhop, clinfo2=' pot : ', kdim=jpk )
+      IF(sn_cfctl%l_prtctl)   CALL prt_ctl( tab3d_1=prd, clinfo1=' eos-pot: ', &
+         &                                  tab3d_2=prhop, clinfo2=' pot : ', kdim=jpk )
       !
       IF( ln_timing )   CALL timing_stop('eos-pot')
       !
-   END SUBROUTINE eos_insitu_pot
+   END SUBROUTINE eos_insitu_pot_t
 
 
    SUBROUTINE eos_insitu_2d( pts, pdep, prd )
+      !!
+      REAL(wp), DIMENSION(:,:,:), INTENT(in   ) ::   pts   ! 1 : potential temperature  [Celsius]
+      !                                                    ! 2 : salinity               [psu]
+      REAL(wp), DIMENSION(:,:)  , INTENT(in   ) ::   pdep  ! depth                      [m]
+      REAL(wp), DIMENSION(:,:)  , INTENT(  out) ::   prd   ! in situ density
+      !!
+      CALL eos_insitu_2d_t( pts, is_tile(pts), pdep, is_tile(pdep), prd, is_tile(prd) )
+   END SUBROUTINE eos_insitu_2d
+
+
+   SUBROUTINE eos_insitu_2d_t( pts, ktts, pdep, ktdep, prd, ktrd )
       !!----------------------------------------------------------------------
       !!                  ***  ROUTINE eos_insitu_2d  ***
@@ -462,8 +499,9 @@
       !!
       !!----------------------------------------------------------------------
-      REAL(wp), DIMENSION(jpi,jpj,jpts), INTENT(in   ) ::   pts   ! 1 : potential temperature  [Celsius]
-      !                                                           ! 2 : salinity               [psu]
-      REAL(wp), DIMENSION(jpi,jpj)     , INTENT(in   ) ::   pdep  ! depth                      [m]
-      REAL(wp), DIMENSION(jpi,jpj)     , INTENT(  out) ::   prd   ! in situ density
+      INTEGER                            , INTENT(in   ) ::   ktts, ktdep, ktrd
+      REAL(wp), DIMENSION(A2D_T(ktts),JPTS), INTENT(in   ) ::   pts   ! 1 : potential temperature  [Celsius]
+      !                                                             ! 2 : salinity               [psu]
+      REAL(wp), DIMENSION(A2D_T(ktdep)    ), INTENT(in   ) ::   pdep  ! depth                      [m]
+      REAL(wp), DIMENSION(A2D_T(ktrd)     ), INTENT(  out) ::   prd   ! in situ density
       !
       INTEGER  ::   ji, jj, jk                ! dummy loop indices
@@ -480,5 +518,5 @@
       CASE( np_teos10, np_eos80 )                !==  polynomial TEOS-10 / EOS-80 ==!
          !
-         DO_2D( 1, 1, 1, 1 )
+         DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
             !
             zh  = pdep(ji,jj) * r1_Z0                                  ! depth
@@ -515,5 +553,5 @@
       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
@@ -535,8 +573,18 @@
       IF( ln_timing )   CALL timing_stop('eos2d')
       !
-   END SUBROUTINE eos_insitu_2d
+   END SUBROUTINE eos_insitu_2d_t
 
 
    SUBROUTINE rab_3d( pts, pab, Kmm )
+      !!
+      INTEGER                     , INTENT(in   ) ::   Kmm   ! time level index
+      REAL(wp), DIMENSION(:,:,:,:), INTENT(in   ) ::   pts   ! pot. temperature & salinity
+      REAL(wp), DIMENSION(:,:,:,:), INTENT(  out) ::   pab   ! thermal/haline expansion ratio
+      !!
+      CALL rab_3d_t( pts, is_tile(pts), pab, is_tile(pab), Kmm )
+   END SUBROUTINE rab_3d
+
+
+   SUBROUTINE rab_3d_t( pts, ktts, pab, ktab, Kmm )
       !!----------------------------------------------------------------------
       !!                 ***  ROUTINE rab_3d  ***
@@ -548,7 +596,8 @@
       !! ** Action  : - pab     : thermal/haline expansion ratio at T-points
       !!----------------------------------------------------------------------
-      INTEGER                              , INTENT(in   ) ::   Kmm   ! time level index
-      REAL(wp), DIMENSION(jpi,jpj,jpk,jpts), INTENT(in   ) ::   pts   ! pot. temperature & salinity
-      REAL(wp), DIMENSION(jpi,jpj,jpk,jpts), INTENT(  out) ::   pab   ! thermal/haline expansion ratio
+      INTEGER                                , INTENT(in   ) ::   Kmm   ! time level index
+      INTEGER                                , INTENT(in   ) ::   ktts, ktab
+      REAL(wp), DIMENSION(A2D_T(ktts),JPK,JPTS), INTENT(in   ) ::   pts   ! pot. temperature & salinity
+      REAL(wp), DIMENSION(A2D_T(ktab),JPK,JPTS), INTENT(  out) ::   pab   ! thermal/haline expansion ratio
       !
       INTEGER  ::   ji, jj, jk                ! dummy loop indices
@@ -563,5 +612,5 @@
       CASE( np_teos10, np_eos80 )                !==  polynomial TEOS-10 / EOS-80 ==!
          !
-         DO_3D( 1, 1, 1, 1, 1, jpkm1 )
+         DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpkm1 )
             !
             zh  = gdept(ji,jj,jk,Kmm) * r1_Z0                                ! depth
@@ -616,5 +665,5 @@
       CASE( np_seos )                  !==  simplified EOS  ==!
          !
-         DO_3D( 1, 1, 1, 1, 1, jpkm1 )
+         DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpkm1 )
             zt  = pts (ji,jj,jk,jp_tem) - 10._wp   ! pot. temperature anomaly (t-T0)
             zs  = pts (ji,jj,jk,jp_sal) - 35._wp   ! abs. salinity anomaly (s-S0)
@@ -641,8 +690,19 @@
       IF( ln_timing )   CALL timing_stop('rab_3d')
       !
-   END SUBROUTINE rab_3d
+   END SUBROUTINE rab_3d_t
 
 
    SUBROUTINE rab_2d( pts, pdep, pab, Kmm )
+      !!
+      INTEGER                   , INTENT(in   ) ::   Kmm   ! time level index
+      REAL(wp), DIMENSION(:,:,:), INTENT(in   ) ::   pts    ! pot. temperature & salinity
+      REAL(wp), DIMENSION(:,:)  , INTENT(in   ) ::   pdep   ! depth                  [m]
+      REAL(wp), DIMENSION(:,:,:), INTENT(  out) ::   pab    ! thermal/haline expansion ratio
+      !!
+      CALL rab_2d_t(pts, is_tile(pts), pdep, is_tile(pdep), pab, is_tile(pab), Kmm)
+   END SUBROUTINE rab_2d
+
+
+   SUBROUTINE rab_2d_t( pts, ktts, pdep, ktdep, pab, ktab, Kmm )
       !!----------------------------------------------------------------------
       !!                 ***  ROUTINE rab_2d  ***
@@ -652,8 +712,9 @@
       !! ** Action  : - pab     : thermal/haline expansion ratio at T-points
       !!----------------------------------------------------------------------
-      INTEGER                              , INTENT(in   ) ::   Kmm   ! time level index
-      REAL(wp), DIMENSION(jpi,jpj,jpts)    , INTENT(in   ) ::   pts    ! pot. temperature & salinity
-      REAL(wp), DIMENSION(jpi,jpj)         , INTENT(in   ) ::   pdep   ! depth                  [m]
-      REAL(wp), DIMENSION(jpi,jpj,jpts)    , INTENT(  out) ::   pab    ! thermal/haline expansion ratio
+      INTEGER                            , INTENT(in   ) ::   Kmm   ! time level index
+      INTEGER                            , INTENT(in   ) ::   ktts, ktdep, ktab
+      REAL(wp), DIMENSION(A2D_T(ktts),JPTS), INTENT(in   ) ::   pts    ! pot. temperature & salinity
+      REAL(wp), DIMENSION(A2D_T(ktdep)    ), INTENT(in   ) ::   pdep   ! depth                  [m]
+      REAL(wp), DIMENSION(A2D_T(ktab),JPTS), INTENT(  out) ::   pab    ! thermal/haline expansion ratio
       !
       INTEGER  ::   ji, jj, jk                ! dummy loop indices
@@ -670,5 +731,5 @@
       CASE( np_teos10, np_eos80 )                !==  polynomial TEOS-10 / EOS-80 ==!
          !
-         DO_2D( 1, 1, 1, 1 )
+         DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
             !
             zh  = pdep(ji,jj) * r1_Z0                                  ! depth
@@ -723,5 +784,5 @@
       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   ! pot. temperature anomaly (t-T0)
@@ -748,5 +809,5 @@
       IF( ln_timing )   CALL timing_stop('rab_2d')
       !
-   END SUBROUTINE rab_2d
+   END SUBROUTINE rab_2d_t
 
 
@@ -849,4 +910,15 @@
 
    SUBROUTINE bn2( pts, pab, pn2, Kmm )
+      !!
+      INTEGER                              , INTENT(in   ) ::  Kmm   ! time level index
+      REAL(wp), DIMENSION(jpi,jpj,jpk,jpts), INTENT(in   ) ::  pts   ! pot. temperature and salinity   [Celsius,psu]
+      REAL(wp), DIMENSION(:,:,:,:)         , INTENT(in   ) ::  pab   ! thermal/haline expansion coef.  [Celsius-1,psu-1]
+      REAL(wp), DIMENSION(:,:,:)           , INTENT(  out) ::  pn2   ! Brunt-Vaisala frequency squared [1/s^2]
+      !!
+      CALL bn2_t( pts, pab, is_tile(pab), pn2, is_tile(pn2), Kmm )
+   END SUBROUTINE bn2
+
+
+   SUBROUTINE bn2_t( pts, pab, ktab, pn2, ktn2, Kmm )
       !!----------------------------------------------------------------------
       !!                  ***  ROUTINE bn2  ***
@@ -862,8 +934,9 @@
       !!
       !!----------------------------------------------------------------------
-      INTEGER                              , INTENT(in   ) ::   Kmm   ! time level index
-      REAL(wp), DIMENSION(jpi,jpj,jpk,jpts), INTENT(in   ) ::  pts   ! pot. temperature and salinity   [Celsius,psu]
-      REAL(wp), DIMENSION(jpi,jpj,jpk,jpts), INTENT(in   ) ::  pab   ! thermal/haline expansion coef.  [Celsius-1,psu-1]
-      REAL(wp), DIMENSION(jpi,jpj,jpk     ), INTENT(  out) ::  pn2   ! Brunt-Vaisala frequency squared [1/s^2]
+      INTEGER                                , INTENT(in   ) ::  Kmm   ! time level index
+      INTEGER                                , INTENT(in   ) ::  ktab, ktn2
+      REAL(wp), DIMENSION(jpi,jpj,  jpk,jpts), INTENT(in   ) ::  pts   ! pot. temperature and salinity   [Celsius,psu]
+      REAL(wp), DIMENSION(A2D_T(ktab),JPK,JPTS), INTENT(in   ) ::  pab   ! thermal/haline expansion coef.  [Celsius-1,psu-1]
+      REAL(wp), DIMENSION(A2D_T(ktn2),JPK     ), INTENT(  out) ::  pn2   ! Brunt-Vaisala frequency squared [1/s^2]
       !
       INTEGER  ::   ji, jj, jk      ! dummy loop indices
@@ -873,5 +946,5 @@
       IF( ln_timing )   CALL timing_start('bn2')
       !
-      DO_3D( 1, 1, 1, 1, 2, jpkm1 )      ! interior points only (2=< jk =< jpkm1 ); surface and bottom value set to zero one for all in istate.F90
+      DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 2, jpkm1 )      ! interior points only (2=< jk =< jpkm1 ); surface and bottom value set to zero one for all in istate.F90
          zrw =   ( gdepw(ji,jj,jk  ,Kmm) - gdept(ji,jj,jk,Kmm) )   &
             &  / ( gdept(ji,jj,jk-1,Kmm) - gdept(ji,jj,jk,Kmm) ) 
@@ -889,5 +962,5 @@
       IF( ln_timing )   CALL timing_stop('bn2')
       !
-   END SUBROUTINE bn2
+   END SUBROUTINE bn2_t
 
 
@@ -949,5 +1022,15 @@
 
 
-   SUBROUTINE  eos_fzp_2d( psal, ptf, pdep )
+   SUBROUTINE eos_fzp_2d( psal, ptf, pdep )
+      !!
+      REAL(wp), DIMENSION(jpi,jpj), INTENT(in   )           ::   psal   ! salinity   [psu]
+      REAL(wp), DIMENSION(jpi,jpj), INTENT(in   ), OPTIONAL ::   pdep   ! depth      [m]
+      REAL(wp), DIMENSION(:,:)    , INTENT(out  )           ::   ptf    ! freezing temperature [Celsius]
+      !!
+      CALL eos_fzp_2d_t( psal, ptf, is_tile(ptf), pdep )
+   END SUBROUTINE eos_fzp_2d
+
+
+   SUBROUTINE  eos_fzp_2d_t( psal, ptf, kttf, pdep )
       !!----------------------------------------------------------------------
       !!                 ***  ROUTINE eos_fzp  ***
@@ -961,7 +1044,8 @@
       !! Reference  :   UNESCO tech. papers in the marine science no. 28. 1978
       !!----------------------------------------------------------------------
-      REAL(wp), DIMENSION(jpi,jpj), INTENT(in   )           ::   psal   ! salinity   [psu]
-      REAL(wp), DIMENSION(jpi,jpj), INTENT(in   ), OPTIONAL ::   pdep   ! depth      [m]
-      REAL(wp), DIMENSION(jpi,jpj), INTENT(out  )           ::   ptf    ! freezing temperature [Celsius]
+      INTEGER                       , INTENT(in   )           ::   kttf
+      REAL(wp), DIMENSION(jpi,jpj)  , INTENT(in   )           ::   psal   ! salinity   [psu]
+      REAL(wp), DIMENSION(jpi,jpj)  , INTENT(in   ), OPTIONAL ::   pdep   ! depth      [m]
+      REAL(wp), DIMENSION(A2D_T(kttf)), INTENT(out  )           ::   ptf    ! freezing temperature [Celsius]
       !
       INTEGER  ::   ji, jj          ! dummy loop indices
@@ -996,5 +1080,5 @@
       END SELECT      
       !
-  END SUBROUTINE eos_fzp_2d
+  END SUBROUTINE eos_fzp_2d_t
 
 
Index: /NEMO/trunk/src/OCE/TRA/traadv.F90
===================================================================
--- /NEMO/trunk/src/OCE/TRA/traadv.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/TRA/traadv.F90	(revision 13982)
@@ -18,4 +18,6 @@
    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
+   USE domain, ONLY : dom_tile
    USE domvvl         ! variable vertical scale factors
    USE sbcwave        ! wave module
@@ -23,5 +25,7 @@
    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)
@@ -65,5 +69,7 @@
    INTEGER, PARAMETER ::   np_UBS     = 4   ! 3rd order Upstream Biased Scheme
    INTEGER, PARAMETER ::   np_QCK     = 5   ! QUICK scheme
-   
+
+   !! * Substitutions
+#  include "do_loop_substitute.h90"
 #  include "domzgr_substitute.h90"
    !!----------------------------------------------------------------------
@@ -86,88 +92,151 @@
       REAL(wp), DIMENSION(jpi,jpj,jpk,jpts,jpt), INTENT(inout) :: pts            ! active tracers and RHS of tracer equation
       !
-      INTEGER ::   jk   ! dummy loop index
-      REAL(wp), DIMENSION(jpi,jpj,jpk)        :: zuu, zvv, zww   ! 3D workspace
-      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::   ztrdt, ztrds
+      INTEGER ::   ji, jj, jk   ! dummy loop index
+      ! TEMP: [tiling] This change not necessary and can be A2D(nn_hls) if using XIOS (subdomain support)
+      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
+      LOGICAL :: lskip
       !!----------------------------------------------------------------------
       !
       IF( ln_timing )   CALL timing_start('tra_adv')
       !
-      !                                         !==  effective transport  ==!
-      zuu(:,:,jpk) = 0._wp
-      zvv(:,:,jpk) = 0._wp
-      zww(:,:,jpk) = 0._wp
-      IF( ln_wave .AND. ln_sdw )  THEN
-         DO jk = 1, jpkm1                                                       ! eulerian transport + Stokes Drift
-            zuu(:,:,jk) =   &
-               &  e2u  (:,:) * e3u(:,:,jk,Kmm) * ( uu(:,:,jk,Kmm) + usd(:,:,jk) )
-            zvv(:,:,jk) =   & 
-               &  e1v  (:,:) * e3v(:,:,jk,Kmm) * ( vv(:,:,jk,Kmm) + vsd(:,:,jk) )
-            zww(:,:,jk) =   & 
-               &  e1e2t(:,:)                 * ( ww(:,:,jk) + wsd(:,:,jk) )
-         END DO
-      ELSE
-         DO jk = 1, jpkm1
-            zuu(:,:,jk) = e2u  (:,:) * e3u(:,:,jk,Kmm) * uu(:,:,jk,Kmm)               ! eulerian transport only
-            zvv(:,:,jk) = e1v  (:,:) * e3v(:,:,jk,Kmm) * vv(:,:,jk,Kmm)
-            zww(:,:,jk) = e1e2t(:,:)                 * ww(:,:,jk)
-         END DO
-      ENDIF
-      !
-      IF( ln_vvl_ztilde .OR. ln_vvl_layer ) THEN                                ! add z-tilde and/or vvl corrections
-         zuu(:,:,:) = zuu(:,:,:) + un_td(:,:,:)
-         zvv(:,:,:) = zvv(:,:,:) + vn_td(:,:,:)
-      ENDIF
-      !
-      zuu(:,:,jpk) = 0._wp                                                      ! no transport trough the bottom
-      zvv(:,:,jpk) = 0._wp
-      zww(:,:,jpk) = 0._wp
-      !
-      IF( ln_ldfeiv .AND. .NOT. ln_traldf_triad )   &
-         &              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)
-      !
-      CALL iom_put( "uocetr_eff", zuu )                                        ! output effective transport      
-      CALL iom_put( "vocetr_eff", zvv )
-      CALL iom_put( "wocetr_eff", zww )
-      !
-!!gm ???
-      CALL dia_ptr( kt, Kmm, zvv )                                    ! diagnose the effective MSF 
-!!gm ???
-      !
-
-      IF( l_trdtra )   THEN                    !* Save ta and sa trends
-         ALLOCATE( ztrdt(jpi,jpj,jpk), ztrds(jpi,jpj,jpk) )
-         ztrdt(:,:,:) = pts(:,:,:,jp_tem,Krhs)
-         ztrds(:,:,:) = pts(:,:,:,jp_sal,Krhs)
-      ENDIF
-      !
-      SELECT CASE ( nadv )                      !==  compute advection trend and add it to general trend  ==!
-      !
-      CASE ( np_CEN )                                 ! Centered scheme : 2nd / 4th order
-         CALL tra_adv_cen    ( kt, nit000, 'TRA',         zuu, zvv, zww, Kmm, pts, jpts, Krhs, nn_cen_h, nn_cen_v )
-      CASE ( np_FCT )                                 ! FCT scheme      : 2nd / 4th order
-         CALL tra_adv_fct    ( kt, nit000, 'TRA', rDt, zuu, zvv, zww, Kbb, Kmm, pts, jpts, Krhs, nn_fct_h, nn_fct_v )
-      CASE ( np_MUS )                                 ! MUSCL
-         CALL tra_adv_mus    ( kt, nit000, 'TRA', rDt, zuu, zvv, zww, Kbb, Kmm, pts, jpts, Krhs, ln_mus_ups ) 
-      CASE ( np_UBS )                                 ! UBS
-         CALL tra_adv_ubs    ( kt, nit000, 'TRA', rDt, zuu, zvv, zww, Kbb, Kmm, pts, jpts, Krhs, nn_ubs_v   )
-      CASE ( np_QCK )                                 ! QUICKEST
-         CALL tra_adv_qck    ( kt, nit000, 'TRA', rDt, zuu, zvv, zww, Kbb, Kmm, pts, jpts, Krhs )
-      !
-      END SELECT
-      !
-      IF( l_trdtra )   THEN                      ! save the advective trends for further diagnostics
-         DO jk = 1, jpkm1
-            ztrdt(:,:,jk) = pts(:,:,jk,jp_tem,Krhs) - ztrdt(:,:,jk)
-            ztrds(:,:,jk) = pts(:,:,jk,jp_sal,Krhs) - ztrds(:,:,jk)
-         END DO
-         CALL trd_tra( kt, Kmm, Krhs, 'TRA', jp_tem, jptra_totad, ztrdt )
-         CALL trd_tra( kt, Kmm, Krhs, 'TRA', jp_sal, jptra_totad, ztrds )
-         DEALLOCATE( ztrdt, ztrds )
+      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
+         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
+         ENDIF
+      ENDIF
+      IF( .NOT. lskip ) THEN
+         !                                         !==  effective transport  ==!
+         IF( ln_wave .AND. ln_sdw )  THEN
+            DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 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) )
+               zww(ji,jj,jk) = e1e2t(ji,jj)                     * ( ww(ji,jj,jk)     + wsd(ji,jj,jk) )
+            END_3D
+         ELSE
+            DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 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)
+               zww(ji,jj,jk) = e1e2t(ji,jj)                     * ww(ji,jj,jk)
+            END_3D
+         ENDIF
+         !
+         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 )
+               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)
+            END_3D
+         ENDIF
+         !
+         DO_2D( nn_hls, nn_hls, nn_hls, nn_hls )
+            zuu(ji,jj,jpk) = 0._wp                                                      ! no transport trough the bottom
+            zvv(ji,jj,jpk) = 0._wp
+            zww(ji,jj,jpk) = 0._wp
+         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 iom_put( "uocetr_eff", zuu )                                        ! output effective transport
+            CALL iom_put( "vocetr_eff", zvv )
+            CALL iom_put( "wocetr_eff", zww )
+         ENDIF
+         !
+   !!gm ???
+         ! TEMP: [tiling] This change not necessary if using XIOS (subdomain support)
+         CALL dia_ptr( kt, Kmm, zvv(A2D(nn_hls),:) )                                    ! diagnose the effective MSF
+   !!gm ???
+         !
+
+         IF( l_trdtra )   THEN                    !* Save ta and sa trends
+            ALLOCATE( ztrdt(jpi,jpj,jpk), ztrds(jpi,jpj,jpk) )
+            ztrdt(:,:,:) = pts(:,:,:,jp_tem,Krhs)
+            ztrds(:,:,:) = pts(:,:,:,jp_sal,Krhs)
+         ENDIF
+         !
+         ! NOTE: [tiling-comms-merge] These lbc_lnk calls are still needed (pts in the zco case because zps_hde is not called in step, zuu/zvv/zww in all cases, I think because DO loop bounds need to be updated in DYN as done in TRA)
+         SELECT CASE ( nadv )                      !==  compute advection trend and add it to general trend  ==!
+         !
+         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_multi( 'traadv', pts(:,:,:,:,Kbb), 'T', 1., pts(:,:,:,:,Kmm), 'T', 1.)
+               CALL lbc_lnk_multi( '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
+            ! NOTE: [tiling-comms-merge] I added this lbc_lnk as it did not validate against the trunk when using ln_zco
+            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_multi( '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 )
+         !
+         END SELECT
+         !
+         IF( l_trdtra )   THEN                      ! save the advective trends for further diagnostics
+            DO jk = 1, jpkm1
+               ztrdt(:,:,jk) = pts(:,:,jk,jp_tem,Krhs) - ztrdt(:,:,jk)
+               ztrds(:,:,jk) = pts(:,:,jk,jp_sal,Krhs) - ztrds(:,:,jk)
+            END DO
+            CALL trd_tra( kt, Kmm, Krhs, 'TRA', jp_tem, jptra_totad, ztrdt )
+            CALL trd_tra( kt, Kmm, Krhs, 'TRA', jp_sal, jptra_totad, ztrds )
+            DEALLOCATE( ztrdt, ztrds )
+         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 )
+
       ENDIF
       !                                              ! print mean trends (used for debugging)
-      IF(sn_cfctl%l_prtctl)   CALL prt_ctl( tab3d_1=pts(:,:,:,jp_tem,Krhs), clinfo1=' adv  - Ta: ', mask1=tmask,               &
+      IF(sn_cfctl%l_prtctl)   CALL prt_ctl( tab3d_1=pts(:,:,:,jp_tem,Krhs), clinfo1=' adv  - Ta: ', mask1=tmask, &
          &                                  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
+         DEALLOCATE( zuu, zvv, zww )
+      ENDIF
       !
       IF( ln_timing )   CALL timing_stop( 'tra_adv' )
Index: /NEMO/trunk/src/OCE/TRA/traadv_cen.F90
===================================================================
--- /NEMO/trunk/src/OCE/TRA/traadv_cen.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/TRA/traadv_cen.F90	(revision 13982)
@@ -71,4 +71,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)
       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
@@ -78,20 +79,22 @@
       REAL(wp) ::   zC2t_u, zC4t_u   ! local scalars
       REAL(wp) ::   zC2t_v, zC4t_v   !   -      -
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zwx, zwy, zwz, ztu, ztv, ztw
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zwx, zwy, zwz, ztu, ztv, ztw
       !!----------------------------------------------------------------------
       !
-      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,*) '~~~~~~~~~~~~ '
+      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
-      !                          ! 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.
       !
       !                    
@@ -112,11 +115,11 @@
             ztu(:,:,jpk) = 0._wp                   ! Bottom value : flux set to zero
             ztv(:,:,jpk) = 0._wp
-            DO_3D( 0, 0, 0, 0, 1, jpkm1 )          ! masked gradient
+            DO_3D( nn_hls, nn_hls-1, nn_hls, nn_hls-1, 1, jpkm1 )          ! masked 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
-            CALL lbc_lnk_multi( 'traadv_cen', ztu, 'U', -1.0_wp , ztv, 'V', -1.0_wp )   ! Lateral boundary cond.
+            IF (nn_hls.EQ.1) CALL lbc_lnk_multi( 'traadv_cen', ztu, 'U', -1.0_wp , ztv, 'V', -1.0_wp )   ! Lateral boundary cond.
             !
-            DO_3D( 0, 0, 0, 0, 1, jpkm1 )           ! Horizontal advective fluxes
+            DO_3D( nn_hls-1, 0, nn_hls-1, 0, 1, jpkm1 )           ! Horizontal advective fluxes
                zC2t_u = pt(ji,jj,jk,jn,Kmm) + pt(ji+1,jj  ,jk,jn,Kmm)   ! C2 interpolation of T at u- & v-points (x2)
                zC2t_v = pt(ji,jj,jk,jn,Kmm) + pt(ji  ,jj+1,jk,jn,Kmm)
@@ -128,5 +131,5 @@
                zwy(ji,jj,jk) =  0.5_wp * pV(ji,jj,jk) * zC4t_v
             END_3D
-            CALL lbc_lnk_multi( 'traadv_cen', zwx, 'U', -1. , zwy, 'V', -1. )
+            IF (nn_hls.EQ.1) CALL lbc_lnk_multi( 'traadv_cen', zwx, 'U', -1. , zwy, 'V', -1. )
             !
          CASE DEFAULT
@@ -155,5 +158,7 @@
                END_2D
             ELSE                                   ! no ice-shelf cavities (only ocean surface)
-               zwz(:,:,1) = pW(:,:,1) * pt(:,:,1,jn,Kmm)
+               DO_2D( 1, 1, 1, 1 )
+                  zwz(ji,jj,1) = pW(ji,jj,1) * pt(ji,jj,1,jn,Kmm)
+               END_2D
             ENDIF
          ENDIF
@@ -171,6 +176,6 @@
             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) )
-         END IF
-         !                                 ! "Poleward" heat and salt transports 
+         ENDIF
+         !                                 ! "Poleward" heat and salt transports
          IF( l_ptr )   CALL dia_ptr_hst( jn, 'adv', zwy(:,:,:) )
          !                                 !  heat and salt transport
Index: /NEMO/trunk/src/OCE/TRA/traadv_fct.F90
===================================================================
--- /NEMO/trunk/src/OCE/TRA/traadv_fct.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/TRA/traadv_fct.F90	(revision 13982)
@@ -34,4 +34,6 @@
    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
@@ -79,12 +81,14 @@
       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)
+      ! NOTE: [tiling-comms-merge] These were changed to INTENT(inout) but they are not modified, so it is reverted
       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  ::   ji, jj, jk, jn                           ! dummy loop indices
       REAL(wp) ::   ztra                                     ! local scalar
       REAL(wp) ::   zfp_ui, zfp_vj, zfp_wk, zC2t_u, zC4t_u   !   -      -
       REAL(wp) ::   zfm_ui, zfm_vj, zfm_wk, zC2t_v, zC4t_v   !   -      -
-      REAL(wp), DIMENSION(jpi,jpj,jpk)        ::   zwi, zwx, zwy, zwz, ztu, ztv, zltu, zltv, ztw
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk)        ::   zwi, zwx, zwy, zwz, ztu, ztv, zltu, zltv, ztw
       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::   ztrdx, ztrdy, ztrdz, zptry
       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::   zwinf, zwdia, zwsup
@@ -92,9 +96,23 @@
       !!----------------------------------------------------------------------
       !
-      IF( kt == kit000 )  THEN
-         IF(lwp) WRITE(numout,*)
-         IF(lwp) WRITE(numout,*) 'tra_adv_fct : FCT advection scheme on ', cdtype
-         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~'
+      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_fct : FCT advection scheme on ', cdtype
+            IF(lwp) WRITE(numout,*) '~~~~~~~~~~~'
+         ENDIF
+         ! NOTE: [tiling-comms-merge] Bug fix- move array zeroing out of this IF block
+         !
+         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.
+         !
       ENDIF
+
       !! -- init to 0
       zwi(:,:,:) = 0._wp
@@ -108,36 +126,22 @@
       ztw(:,:,:) = 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) )
+         ALLOCATE( ztrdx(A2D(nn_hls),jpk), ztrdy(A2D(nn_hls),jpk), ztrdz(A2D(nn_hls),jpk) )
          ztrdx(:,:,:) = 0._wp   ;    ztrdy(:,:,:) = 0._wp   ;   ztrdz(:,:,:) = 0._wp
       ENDIF
       !
-      IF( l_ptr ) THEN  
-         ALLOCATE( zptry(jpi,jpj,jpk) )
+      IF( l_ptr ) THEN
+         ALLOCATE( zptry(A2D(nn_hls),jpk) )
          zptry(:,:,:) = 0._wp
       ENDIF
-      !                          ! surface & bottom value : flux set to zero one for all
-      zwz(:,:, 1 ) = 0._wp            
-      zwx(:,:,jpk) = 0._wp   ;   zwy(:,:,jpk) = 0._wp    ;    zwz(:,:,jpk) = 0._wp
-      !
-      zwi(:,:,:) = 0._wp        
       !
       ! 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.
+         IF( MAXVAL( ABS( wi(A2D(nn_hls),:) ) ) > 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( 0, 0, 0, 0, 1, jpkm1 )
+         ALLOCATE(zwdia(A2D(nn_hls),jpk), zwinf(A2D(nn_hls),jpk), zwsup(A2D(nn_hls),jpk))
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-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)
@@ -151,5 +155,5 @@
          !        !==  upstream advection with initial mass fluxes & intermediate update  ==!
          !                    !* upstream tracer flux in the i and j direction 
-         DO_3D( 1, 0, 1, 0, 1, jpkm1 )
+         DO_3D( nn_hls, nn_hls-1, nn_hls, nn_hls-1, 1, jpkm1 )
             ! upstream scheme
             zfp_ui = pU(ji,jj,jk) + ABS( pU(ji,jj,jk) )
@@ -178,5 +182,5 @@
          ENDIF
          !               
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )   !* trend and after field with monotonic scheme
+         DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpkm1 )   !* trend and after field with monotonic scheme
             !                               ! total intermediate advective trends
             ztra = - (  zwx(ji,jj,jk) - zwx(ji-1,jj  ,jk  )   &
@@ -194,5 +198,5 @@
             !
             ztw(:,:,1) = 0._wp ; ztw(:,:,jpk) = 0._wp ;
-            DO_3D( 0, 0, 0, 0, 2, jpkm1 )       ! Interior value ( multiplied by wmask)
+            DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-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) )
@@ -206,5 +210,5 @@
             !
          END IF
-         !                
+         !
          IF( l_trd .OR. l_hst )  THEN             ! trend diagnostics (contribution of upstream fluxes)
             ztrdx(:,:,:) = zwx(:,:,:)   ;   ztrdy(:,:,:) = zwy(:,:,:)   ;   ztrdz(:,:,:) = zwz(:,:,:)
@@ -218,5 +222,5 @@
          !
          CASE(  2  )                   !- 2nd order centered
-            DO_3D( 1, 0, 1, 0, 1, jpkm1 )
+            DO_3D( nn_hls, nn_hls-1, nn_hls, nn_hls-1, 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) ) - zwx(ji,jj,jk)
                zwy(ji,jj,jk) = 0.5_wp * pV(ji,jj,jk) * ( pt(ji,jj,jk,jn,Kmm) + pt(ji,jj+1,jk,jn,Kmm) ) - zwy(ji,jj,jk)
@@ -238,20 +242,23 @@
             CALL lbc_lnk_multi( '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 )    ! Horizontal advective fluxes
+            DO_3D( 1, 0, 1, 0, 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 
+               !                                                        ! 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_multi( 'traadv_fct', zwx, 'U', -1.0_wp, zwy, 'V', -1.0_wp )   ! Lateral boundary cond. (unchanged sgn)
             !
          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( 1, 0, 1, 0, 1, jpkm1 )    ! 1st derivative (gradient)
+            DO_3D( nn_hls, nn_hls-1, nn_hls, 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
-            CALL lbc_lnk_multi( 'traadv_fct', ztu, 'U', -1.0_wp , ztv, 'V', -1.0_wp )   ! Lateral boundary cond. (unchanged sgn)
+            IF (nn_hls.EQ.1) CALL lbc_lnk_multi( 'traadv_fct', ztu, 'U', -1.0_wp , ztv, 'V', -1.0_wp )   ! Lateral boundary cond. (unchanged sgn)
+            !
+            IF (nn_hls.EQ.1) CALL lbc_lnk_multi( 'traadv_fct', ztu, 'U', -1.0_wp , ztv, 'V', -1.0_wp )   ! Lateral boundary cond. (unchanged sgn)
             !
             DO_3D( 0, 0, 0, 0, 1, jpkm1 )    ! Horizontal advective fluxes
@@ -265,4 +272,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_multi( 'traadv_fct', zwx, 'U', -1.0_wp , zwy, 'V', -1.0_wp )   ! Lateral boundary cond. (unchanged sgn)
             !
          END SELECT
@@ -271,5 +279,5 @@
          !
          CASE(  2  )                   !- 2nd order centered
-            DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+            DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-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)
@@ -278,5 +286,5 @@
          CASE(  4  )                   !- 4th order COMPACT
             CALL interp_4th_cpt( pt(:,:,:,jn,Kmm) , ztw )   ! zwt = COMPACT interpolation of T at w-point
-            DO_3D( 0, 0, 0, 0, 2, jpkm1 )
+            DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-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
@@ -286,24 +294,34 @@
             zwz(:,:,1) = 0._wp   ! only ocean surface as interior zwz values have been w-masked
          ENDIF
-         !         
+         !
+         IF (nn_hls.EQ.1) THEN
+            CALL lbc_lnk_multi( 'traadv_fct', zwi, 'T', 1.0_wp, zwx, 'U', -1.0_wp , zwy, 'V', -1.0_wp, zwz, 'T', 1.0_wp )
+         ELSE
+            CALL lbc_lnk( 'traadv_fct', zwi, 'T', 1.0_wp)
+         END IF
+         !
+         IF (nn_hls.EQ.1) THEN
+            CALL lbc_lnk_multi( 'traadv_fct', zwi, 'T', 1.0_wp, zwx, 'U', -1.0_wp , zwy, 'V', -1.0_wp, zwz, 'T', 1.0_wp )
+         ELSE
+            CALL lbc_lnk( 'traadv_fct', zwi, 'T', 1.0_wp)
+         END IF
+         !
          IF ( ll_zAimp ) THEN
-            DO_3D( 0, 0, 0, 0, 1, jpkm1 )    !* trend and after field with monotonic scheme
+            DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 1, jpkm1 )    !* trend and after field with monotonic scheme
                !                                                ! total intermediate advective trends
                ztra = - (  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)
-               ztw(ji,jj,jk)  = zwi(ji,jj,jk) + p2dt * ztra / e3t(ji,jj,jk,Krhs) * tmask(ji,jj,jk)
+               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( 0, 0, 0, 0, 2, jpkm1 )       ! Interior value ( multiplied by wmask)
+            DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-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)
+               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
-         !
-         CALL lbc_lnk_multi( 'traadv_fct', zwi, 'T', 1.0_wp, zwx, 'U', -1.0_wp , zwy, 'V', -1.0_wp,  zwz, 'W',  1.0_wp )
          !
          !        !==  monotonicity algorithm  ==!
@@ -334,8 +352,9 @@
                   &                                        * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
             END_3D
-         END IF         
-         !
+         END IF
+         ! NOTE: [tiling-comms-merge] I tested this
+         ! NOT TESTED - NEED l_trd OR l_hst TRUE
          IF( l_trd .OR. l_hst ) THEN   ! trend diagnostics // heat/salt transport
-            ztrdx(:,:,:) = ztrdx(:,:,:) + zwx(:,:,:)  ! <<< add anti-diffusive fluxes 
+            ztrdx(:,:,:) = ztrdx(:,:,:) + zwx(:,:,:)  ! <<< add anti-diffusive fluxes
             ztrdy(:,:,:) = ztrdy(:,:,:) + zwy(:,:,:)  !     to upstream fluxes
             ztrdz(:,:,:) = ztrdz(:,:,:) + zwz(:,:,:)  !
@@ -350,4 +369,6 @@
             !
          ENDIF
+         ! NOTE: [tiling-comms-merge] I tested this
+         ! NOT TESTED - NEED l_ptr TRUE
          IF( l_ptr ) THEN              ! "Poleward" transports
             zptry(:,:,:) = zptry(:,:,:) + zwy(:,:,:)  ! <<< add anti-diffusive fluxes
@@ -360,5 +381,5 @@
          DEALLOCATE( zwdia, zwinf, zwsup )
       ENDIF
-      IF( l_trd .OR. l_hst ) THEN 
+      IF( l_trd .OR. l_hst ) THEN
          DEALLOCATE( ztrdx, ztrdy, ztrdz )
       ENDIF
@@ -383,8 +404,9 @@
       !!       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
+      INTEGER                         , INTENT(in   ) ::   Kmm             ! time level index
+      REAL(wp)                        , INTENT(in   ) ::   p2dt            ! tracer time-step
+      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(in   ) ::   pbef            ! before field
+      REAL(wp), DIMENSION(A2D(nn_hls)    ,jpk), INTENT(in   ) ::   paft            ! after field
+      REAL(wp), DIMENSION(A2D(nn_hls)    ,jpk), INTENT(inout) ::   paa, pbb, pcc   ! monotonic fluxes in the 3 directions
       !
       INTEGER  ::   ji, jj, jk   ! dummy loop indices
@@ -392,5 +414,5 @@
       REAL(dp) ::   zpos, zneg, zbt, za, zb, zc, zbig, zrtrn    ! local scalars
       REAL(dp) ::   zau, zbu, zcu, zav, zbv, zcv, zup, zdo            !   -      -
-      REAL(dp), DIMENSION(jpi,jpj,jpk) :: zbetup, zbetdo, zbup, zbdo
+      REAL(dp), DIMENSION(A2D(nn_hls),jpk) :: zbetup, zbetdo, zbup, zbdo
       !!----------------------------------------------------------------------
       !
@@ -402,12 +424,14 @@
       ! --------------------
       ! 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 )  )
+      DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpk )
+         zbup(ji,jj,jk) = MAX( pbef(ji,jj,jk) * tmask(ji,jj,jk) - zbig * ( 1._wp - tmask(ji,jj,jk) ),   &
+            &                  paft(ji,jj,jk) * tmask(ji,jj,jk) - zbig * ( 1._wp - tmask(ji,jj,jk) )  )
+         zbdo(ji,jj,jk) = MIN( pbef(ji,jj,jk) * tmask(ji,jj,jk) + zbig * ( 1._wp - tmask(ji,jj,jk) ),   &
+            &                  paft(ji,jj,jk) * tmask(ji,jj,jk) + zbig * ( 1._wp - tmask(ji,jj,jk) )  )
+      END_3D
 
       DO jk = 1, jpkm1
          ikm1 = MAX(jk-1,1)
-         DO_2D( 0, 0, 0, 0 )
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
 
             ! search maximum in neighbourhood
@@ -439,9 +463,9 @@
          END_2D
       END DO
-      CALL lbc_lnk_multi( 'traadv_fct', zbetup, 'T', 1.0_wp , zbetdo, 'T', 1.0_wp )   ! lateral boundary cond. (unchanged sign)
+      IF (nn_hls.EQ.1) CALL lbc_lnk_multi( 'traadv_fct', zbetup, 'T', 1.0_wp , zbetdo, 'T', 1.0_wp )   ! lateral boundary cond. (unchanged sign)
 
       ! 3. monotonic flux in the i & j direction (paa & pbb)
       ! ----------------------------------------
-      DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+      DO_3D( 1, 0, 1, 0, 1, jpkm1 )
          zau = MIN( 1._wp, zbetdo(ji,jj,jk), zbetup(ji+1,jj,jk) )
          zbu = MIN( 1._wp, zbetup(ji,jj,jk), zbetdo(ji+1,jj,jk) )
@@ -461,5 +485,4 @@
          pcc(ji,jj,jk+1) = pcc(ji,jj,jk+1) * ( zc * za + ( 1._wp - zc) * zb )
       END_3D
-      CALL lbc_lnk_multi( 'traadv_fct', paa, 'U', -1.0_wp , pbb, 'V', -1.0_wp )   ! lateral boundary condition (changed sign)
       !
    END SUBROUTINE nonosc
@@ -537,14 +560,14 @@
       !!----------------------------------------------------------------------
       REAL(wp),DIMENSION(jpi,jpj,jpk), INTENT(in   ) ::   pt_in    ! field at t-point
-      REAL(wp),DIMENSION(jpi,jpj,jpk), INTENT(  out) ::   pt_out   ! field interpolated at w-point
+      REAL(wp),DIMENSION(A2D(nn_hls)    ,jpk), INTENT(  out) ::   pt_out   ! field interpolated at w-point
       !
       INTEGER ::   ji, jj, jk   ! dummy loop integers
       INTEGER ::   ikt, ikb     ! local integers
-      REAL(wp),DIMENSION(jpi,jpj,jpk) :: zwd, zwi, zws, zwrm, zwt
+      REAL(wp),DIMENSION(A2D(nn_hls),jpk) :: zwd, zwi, zws, zwrm, zwt
       !!----------------------------------------------------------------------
       !
       !                      !==  build the three diagonal matrix & the RHS  ==!
       !
-      DO_3D( 0, 0, 0, 0, 3, jpkm1 )    ! interior (from jk=3 to jpk-1)
+      DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 3, jpkm1 )    ! interior (from jk=3 to jpk-1)
          zwd (ji,jj,jk) = 3._wp * wmask(ji,jj,jk) + 1._wp                 !       diagonal
          zwi (ji,jj,jk) =         wmask(ji,jj,jk)                         ! lower diagonal
@@ -565,5 +588,5 @@
       END IF
       !
-      DO_2D( 0, 0, 0, 0 )              ! 2nd order centered at top & bottom
+      DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )              ! 2nd order centered at top & bottom
          ikt = mikt(ji,jj) + 1            ! w-point below the 1st  wet point
          ikb = MAX(mbkt(ji,jj), 2)        !     -   above the last wet point
@@ -582,22 +605,22 @@
       !                       !==  tridiagonal solver  ==!
       !
-      DO_2D( 0, 0, 0, 0 )           !* 1st recurrence:   Tk = Dk - Ik Sk-1 / Tk-1
+      DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )           !* 1st recurrence:   Tk = Dk - Ik Sk-1 / Tk-1
          zwt(ji,jj,2) = zwd(ji,jj,2)
       END_2D
-      DO_3D( 0, 0, 0, 0, 3, jpkm1 )
+      DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 3, jpkm1 )
          zwt(ji,jj,jk) = zwd(ji,jj,jk) - zwi(ji,jj,jk) * zws(ji,jj,jk-1) /zwt(ji,jj,jk-1)
       END_3D
       !
-      DO_2D( 0, 0, 0, 0 )           !* 2nd recurrence:    Zk = Yk - Ik / Tk-1  Zk-1
+      DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )           !* 2nd recurrence:    Zk = Yk - Ik / Tk-1  Zk-1
          pt_out(ji,jj,2) = zwrm(ji,jj,2)
       END_2D
-      DO_3D( 0, 0, 0, 0, 3, jpkm1 )
+      DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, 3, jpkm1 )
          pt_out(ji,jj,jk) = zwrm(ji,jj,jk) - zwi(ji,jj,jk) / zwt(ji,jj,jk-1) *pt_out(ji,jj,jk-1)             
       END_3D
 
-      DO_2D( 0, 0, 0, 0 )           !* 3d recurrence:    Xk = (Zk - Sk Xk+1 ) / Tk
+      DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )           !* 3d recurrence:    Xk = (Zk - Sk Xk+1 ) / Tk
          pt_out(ji,jj,jpkm1) = pt_out(ji,jj,jpkm1) / zwt(ji,jj,jpkm1)
       END_2D
-      DO_3DS( 0, 0, 0, 0, jpk-2, 2, -1 )
+      DO_3DS( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, jpk-2, 2, -1 )
          pt_out(ji,jj,jk) = ( pt_out(ji,jj,jk) - zws(ji,jj,jk) * pt_out(ji,jj,jk+1) ) / zwt(ji,jj,jk)
       END_3D
@@ -626,34 +649,34 @@
       !!        The 3d array zwt is used as a work space array.
       !!----------------------------------------------------------------------
-      REAL(wp),DIMENSION(:,:,:), INTENT(in   ) ::   pD, pU, PL    ! 3-diagonal matrix
-      REAL(wp),DIMENSION(:,:,:), INTENT(in   ) ::   pRHS          ! Right-Hand-Side
-      REAL(wp),DIMENSION(:,:,:), INTENT(  out) ::   pt_out        !!gm field at level=F(klev)
-      INTEGER                  , INTENT(in   ) ::   klev          ! =1 pt_out at w-level 
-      !                                                           ! =0 pt at t-level
+      REAL(wp),DIMENSION(A2D(nn_hls),jpk), INTENT(in   ) ::   pD, pU, PL    ! 3-diagonal matrix
+      REAL(wp),DIMENSION(A2D(nn_hls),jpk), INTENT(in   ) ::   pRHS          ! Right-Hand-Side
+      REAL(wp),DIMENSION(A2D(nn_hls),jpk), INTENT(  out) ::   pt_out        !!gm field at level=F(klev)
+      INTEGER                    , INTENT(in   ) ::   klev          ! =1 pt_out at w-level
+      !                                                             ! =0 pt at t-level
       INTEGER ::   ji, jj, jk   ! dummy loop integers
       INTEGER ::   kstart       ! local indices
-      REAL(wp),DIMENSION(jpi,jpj,jpk) ::   zwt   ! 3D work array
+      REAL(wp),DIMENSION(A2D(nn_hls),jpk) ::   zwt   ! 3D work array
       !!----------------------------------------------------------------------
       !
       kstart =  1  + klev
       !
-      DO_2D( 0, 0, 0, 0 )                         !* 1st recurrence:   Tk = Dk - Ik Sk-1 / Tk-1
+      DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )                         !* 1st recurrence:   Tk = Dk - Ik Sk-1 / Tk-1
          zwt(ji,jj,kstart) = pD(ji,jj,kstart)
       END_2D
-      DO_3D( 0, 0, 0, 0, kstart+1, jpkm1 )
+      DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, kstart+1, jpkm1 )
          zwt(ji,jj,jk) = pD(ji,jj,jk) - pL(ji,jj,jk) * pU(ji,jj,jk-1) /zwt(ji,jj,jk-1)
       END_3D
       !
-      DO_2D( 0, 0, 0, 0 )                        !* 2nd recurrence:    Zk = Yk - Ik / Tk-1  Zk-1
+      DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )                        !* 2nd recurrence:    Zk = Yk - Ik / Tk-1  Zk-1
          pt_out(ji,jj,kstart) = pRHS(ji,jj,kstart)
       END_2D
-      DO_3D( 0, 0, 0, 0, kstart+1, jpkm1 )
+      DO_3D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, kstart+1, jpkm1 )
          pt_out(ji,jj,jk) = pRHS(ji,jj,jk) - pL(ji,jj,jk) / zwt(ji,jj,jk-1) *pt_out(ji,jj,jk-1)             
       END_3D
 
-      DO_2D( 0, 0, 0, 0 )                       !* 3d recurrence:    Xk = (Zk - Sk Xk+1 ) / Tk
+      DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )                       !* 3d recurrence:    Xk = (Zk - Sk Xk+1 ) / Tk
          pt_out(ji,jj,jpkm1) = pt_out(ji,jj,jpkm1) / zwt(ji,jj,jpkm1)
       END_2D
-      DO_3DS( 0, 0, 0, 0, jpk-2, kstart, -1 )
+      DO_3DS( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1, jpk-2, kstart, -1 )
          pt_out(ji,jj,jk) = ( pt_out(ji,jj,jk) - pU(ji,jj,jk) * pt_out(ji,jj,jk+1) ) / zwt(ji,jj,jk)
       END_3D
Index: /NEMO/trunk/src/OCE/TRA/traadv_fct_lf.F90
===================================================================
--- /NEMO/trunk/src/OCE/TRA/traadv_fct_lf.F90	(revision 13982)
+++ /NEMO/trunk/src/OCE/TRA/traadv_fct_lf.F90	(revision 13982)
@@ -0,0 +1,553 @@
+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_multi( '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_multi( '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_multi( '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/trunk/src/OCE/TRA/traadv_mus.F90
===================================================================
--- /NEMO/trunk/src/OCE/TRA/traadv_mus.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/TRA/traadv_mus.F90	(revision 13982)
@@ -81,4 +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)
       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
@@ -88,40 +89,42 @@
       REAL(wp) ::   zu, z0u, zzwx, zw , zalpha   ! local scalars
       REAL(wp) ::   zv, z0v, zzwy, z0w           !   -      -
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zwx, zslpx   ! 3D workspace
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zwy, zslpy   ! -      - 
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zwx, zslpx   ! 3D workspace
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zwy, zslpy   ! -      -
       !!----------------------------------------------------------------------
       !
-      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.
+      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 : 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.
+      ENDIF
       !
       DO jn = 1, kjpt            !==  loop over the tracers  ==!
@@ -132,14 +135,14 @@
          zwx(:,:,jpk) = 0._wp                   ! bottom values
          zwy(:,:,jpk) = 0._wp  
-         DO_3D( 1, 0, 1, 0, 1, jpkm1 )
+         DO_3D( nn_hls, nn_hls-1, nn_hls, nn_hls-1, 1, jpkm1 )
             zwx(ji,jj,jk) = umask(ji,jj,jk) * ( pt(ji+1,jj,jk,jn,Kbb) - pt(ji,jj,jk,jn,Kbb) )
             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)
-         CALL lbc_lnk_multi( 'traadv_mus', zwx, 'U', -1.0_wp , zwy, 'V', -1.0_wp )
+         IF ( nn_hls.EQ.1 ) CALL lbc_lnk_multi( '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( 0, 1, 0, 1, 1, jpkm1 )
+         DO_3D( nn_hls-1, 1, nn_hls-1, 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) ) )
@@ -148,5 +151,5 @@
          END_3D
          !
-         DO_3D( 0, 1, 0, 1, 1, jpkm1 )    !-- Slopes limitation
+         DO_3D( nn_hls-1, 1, nn_hls-1, 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) ),   &
@@ -157,5 +160,5 @@
          END_3D
          !
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )    !-- MUSCL horizontal advective fluxes
+         DO_3D( nn_hls-1, 0, nn_hls-1, 0, 1, jpkm1 )    !-- MUSCL horizontal advective fluxes
             ! MUSCL fluxes
             z0u = SIGN( 0.5_wp, pU(ji,jj,jk) )
@@ -173,5 +176,5 @@
             zwy(ji,jj,jk) = pV(ji,jj,jk) * ( zalpha * zzwx + (1.-zalpha) * zzwy )
          END_3D
-         CALL lbc_lnk_multi( 'traadv_mus', zwx, 'U', -1.0_wp , zwy, 'V', -1.0_wp )   ! lateral boundary conditions   (changed sign)
+         IF ( nn_hls.EQ.1 ) CALL lbc_lnk_multi( '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
@@ -195,7 +198,7 @@
          zwx(:,:, 1 ) = 0._wp                   ! surface & bottom boundary conditions
          zwx(:,:,jpk) = 0._wp
-         DO jk = 2, jpkm1                       ! interior values
-            zwx(:,:,jk) = tmask(:,:,jk) * ( pt(:,:,jk-1,jn,Kbb) - pt(:,:,jk,jn,Kbb) )
-         END DO
+         DO_3D( 1, 1, 1, 1, 2, jpkm1 )                ! interior values
+            zwx(ji,jj,jk) = tmask(ji,jj,jk) * ( pt(ji,jj,jk-1,jn,Kbb) - pt(ji,jj,jk,jn,Kbb) )
+         END_3D
          !                                !-- Slopes of tracer
          zslpx(:,:,1) = 0._wp                   ! surface values
@@ -223,5 +226,7 @@
                END_2D
             ELSE                                      ! no cavities: only at the ocean surface
-               zwx(:,:,1) = pW(:,:,1) * pt(:,:,1,jn,Kbb)
+               DO_2D( 1, 1, 1, 1 )
+                  zwx(ji,jj,1) = pW(ji,jj,1) * pt(ji,jj,1,jn,Kbb)
+               END_2D
             ENDIF
          ENDIF
Index: /NEMO/trunk/src/OCE/TRA/traadv_mus_lf.F90
===================================================================
--- /NEMO/trunk/src/OCE/TRA/traadv_mus_lf.F90	(revision 13982)
+++ /NEMO/trunk/src/OCE/TRA/traadv_mus_lf.F90	(revision 13982)
@@ -0,0 +1,289 @@
+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/trunk/src/OCE/TRA/traadv_qck.F90
===================================================================
--- /NEMO/trunk/src/OCE/TRA/traadv_qck.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/TRA/traadv_qck.F90	(revision 13982)
@@ -91,20 +91,23 @@
       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)
+      ! NOTE: [tiling-comms-merge] These were changed to INTENT(inout) but they are not modified, so it is reverted
       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( 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,*)
+      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
-      !
-      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. 
-      !
       !
       !        ! horizontal fluxes are computed with the QUICKEST + ULTIMATE scheme
@@ -127,4 +130,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)
       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
@@ -132,5 +136,5 @@
       INTEGER  ::   ji, jj, jk, jn   ! dummy loop indices
       REAL(wp) ::   ztra, zbtr, zdir, zdx, zmsk   ! local scalars
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zwx, zfu, zfc, zfd
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zwx, zfu, zfc, zfd
       !----------------------------------------------------------------------
       !
@@ -142,19 +146,19 @@
          !
 !!gm why not using a SHIFT instruction...
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )     !--- 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 )     !--- Computation of the ustream and downstream value of the tracer and the mask
             zfc(ji,jj,jk) = pt(ji-1,jj,jk,jn,Kbb)        ! Upstream   in the x-direction for the tracer
             zfd(ji,jj,jk) = pt(ji+1,jj,jk,jn,Kbb)        ! Downstream in the x-direction for the tracer
          END_3D
-         CALL lbc_lnk_multi( 'traadv_qck', zfc(:,:,:), 'T', 1.0_wp , zfd(:,:,:), 'T', 1.0_wp )   ! Lateral boundary conditions 
+         IF (nn_hls.EQ.1) CALL lbc_lnk_multi( 'traadv_qck', zfc(:,:,:), 'T', 1.0_wp , zfd(:,:,:), 'T', 1.0_wp )   ! Lateral boundary conditions
          
          !
          ! Horizontal advective fluxes
          ! ---------------------------
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+         DO_3D( 0, 0, nn_hls-1, 0, 1, jpkm1 )
             zdir = 0.5 + SIGN( 0.5_wp, pU(ji,jj,jk) )   ! if pU > 0 : zdir = 1 otherwise zdir = 0 
             zfu(ji,jj,jk) = zdir * zfc(ji,jj,jk ) + ( 1. - zdir ) * zfd(ji+1,jj,jk)  ! FU in the x-direction for T 
          END_3D
          !
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+         DO_3D( 0, 0, nn_hls-1, 0, 1, jpkm1 )
             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)
@@ -164,5 +168,5 @@
          END_3D
          !--- Lateral boundary conditions 
-         CALL lbc_lnk_multi( '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.EQ.1) CALL lbc_lnk_multi( 'traadv_qck', zfu(:,:,:), 'T', 1.0_wp , zfd(:,:,:), 'T', 1.0_wp, zfc(:,:,:), 'T', 1.0_wp,  zwx(:,:,:), 'T', 1.0_wp )
 
          !--- QUICKEST scheme
@@ -170,24 +174,19 @@
          !
          ! Mask at the T-points in the x-direction (mask=0 or mask=1)
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+         DO_3D( 0, 0, nn_hls-1, nn_hls-1, 1, jpkm1 )
             zfu(ji,jj,jk) = tmask(ji-1,jj,jk) + tmask(ji,jj,jk) + tmask(ji+1,jj,jk) - 2.
          END_3D
-         CALL lbc_lnk( 'traadv_qck', zfu(:,:,:), 'T', 1.0_wp )      ! Lateral boundary conditions 
+         IF (nn_hls.EQ.1) CALL lbc_lnk( 'traadv_qck', zfu(:,:,:), 'T', 1.0_wp )      ! Lateral boundary conditions
 
          !
          ! Tracer flux on the x-direction
-         DO jk = 1, jpkm1  
-            !
-            DO_2D( 0, 0, 0, 0 )
-               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 * zfu(ji,jj,jk) + ( 1. - zdir ) * zfu(ji+1,jj,jk)
-               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_2D
-         END DO
-         !
-         CALL lbc_lnk( 'traadv_qck', zwx(:,:,:), 'T', 1.0_wp ) ! Lateral boundary conditions
+         DO_3D( 0, 0, 1, 0, 1, jpkm1 )
+            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 * zfu(ji,jj,jk) + ( 1. - zdir ) * zfu(ji+1,jj,jk)
+            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
@@ -216,4 +215,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)
       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
@@ -221,5 +221,5 @@
       INTEGER  :: ji, jj, jk, jn                ! dummy loop indices
       REAL(wp) :: ztra, zbtr, zdir, zdx, zmsk   ! local scalars
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zwy, zfu, zfc, zfd   ! 3D workspace
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zwy, zfu, zfc, zfd   ! 3D workspace
       !----------------------------------------------------------------------
       !
@@ -233,5 +233,5 @@
             !                                             
             !--- Computation of the ustream and downstream value of the tracer and the mask
-            DO_2D( 0, 0, 0, 0 )
+            DO_2D( nn_hls-1, nn_hls-1, 0, 0 )
                ! Upstream in the x-direction for the tracer
                zfc(ji,jj,jk) = pt(ji,jj-1,jk,jn,Kbb)
@@ -240,6 +240,5 @@
             END_2D
          END DO
-         CALL lbc_lnk_multi( 'traadv_qck', zfc(:,:,:), 'T', 1.0_wp , zfd(:,:,:), 'T', 1.0_wp )   ! Lateral boundary conditions 
-
+         IF (nn_hls.EQ.1) CALL lbc_lnk_multi( 'traadv_qck', zfc(:,:,:), 'T', 1.0_wp , zfd(:,:,:), 'T', 1.0_wp )   ! Lateral boundary conditions
          
          !
@@ -247,10 +246,10 @@
          ! ---------------------------
          !
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+         DO_3D( nn_hls-1, 0, 0, 0, 1, jpkm1 )
             zdir = 0.5 + SIGN( 0.5_wp, pV(ji,jj,jk) )   ! if pU > 0 : zdir = 1 otherwise zdir = 0 
             zfu(ji,jj,jk) = zdir * zfc(ji,jj,jk ) + ( 1. - zdir ) * zfd(ji,jj+1,jk)  ! FU in the x-direction for T 
          END_3D
          !
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+         DO_3D( nn_hls-1, 0, 0, 0, 1, jpkm1 )
             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)
@@ -261,5 +260,5 @@
 
          !--- Lateral boundary conditions 
-         CALL lbc_lnk_multi( '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.EQ.1) CALL lbc_lnk_multi( 'traadv_qck', zfu(:,:,:), 'T', 1.0_wp , zfd(:,:,:), 'T', 1.0_wp, zfc(:,:,:), 'T', 1.0_wp, zwy(:,:,:), 'T', 1.0_wp )
 
          !--- QUICKEST scheme
@@ -267,23 +266,18 @@
          !
          ! Mask at the T-points in the x-direction (mask=0 or mask=1)
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+         DO_3D( nn_hls-1, nn_hls-1, 0, 0, 1, jpkm1 )
             zfu(ji,jj,jk) = tmask(ji,jj-1,jk) + tmask(ji,jj,jk) + tmask(ji,jj+1,jk) - 2.
          END_3D
-         CALL lbc_lnk( 'traadv_qck', zfu(:,:,:), 'T', 1.0_wp )    !--- Lateral boundary conditions 
+         IF (nn_hls.EQ.1) CALL lbc_lnk( 'traadv_qck', zfu(:,:,:), 'T', 1.0_wp )    !--- Lateral boundary conditions
          !
          ! Tracer flux on the x-direction
-         DO jk = 1, jpkm1  
-            !
-            DO_2D( 0, 0, 0, 0 )
-               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 * zfu(ji,jj,jk) + ( 1. - zdir ) * zfu(ji,jj+1,jk)
-               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_2D
-         END DO
-         !
-         CALL lbc_lnk( 'traadv_qck', zwy(:,:,:), 'T', 1.0_wp ) ! Lateral boundary conditions
+         DO_3D( 1, 0, 0, 0, 1, jpkm1 )
+            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 * zfu(ji,jj,jk) + ( 1. - zdir ) * zfu(ji,jj+1,jk)
+            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
@@ -313,9 +307,10 @@
       CHARACTER(len=3)                         , INTENT(in   ) ::   cdtype   ! =TRA or TRC (tracer indicator)
       INTEGER                                  , INTENT(in   ) ::   kjpt     ! number of tracers
-      REAL(wp), DIMENSION(jpi,jpj,jpk         ), INTENT(in   ) ::   pW      ! vertical velocity 
+      ! 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(jpi,jpj,jpk) ::   zwz   ! 3D workspace
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zwz   ! 3D workspace
       !!----------------------------------------------------------------------
       !
@@ -332,9 +327,11 @@
          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( 1, 1, 1, 1 )
+               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)
-               zwz(:,:,1) = pW(:,:,1) * pt(:,:,1,jn,Kmm)
+               DO_2D( 0, 0, 0, 0 )
+                  zwz(ji,jj,1) = pW(ji,jj,1) * pt(ji,jj,1,jn,Kmm)
+               END_2D
             ENDIF
          ENDIF
@@ -359,8 +356,8 @@
       !! ** Method :   
       !!----------------------------------------------------------------------
-      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(in   ) ::   pfu   ! second upwind point
-      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(in   ) ::   pfd   ! first douwning point
-      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(in   ) ::   pfc   ! the central point (or the first upwind point)
-      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   puc   ! input as Courant number ; output as flux
+      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 
@@ -369,5 +366,5 @@
       !----------------------------------------------------------------------
       !
-      DO_3D( 1, 1, 1, 1, 1, jpkm1 )
+      DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 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/trunk/src/OCE/TRA/traadv_ubs.F90
===================================================================
--- /NEMO/trunk/src/OCE/TRA/traadv_ubs.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/TRA/traadv_ubs.F90	(revision 13982)
@@ -92,4 +92,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)
       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
@@ -99,25 +100,26 @@
       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), DIMENSION(jpi,jpj,jpk) ::   ztu, ztv, zltu, zltv, zti, ztw   ! 3D workspace
-      !!----------------------------------------------------------------------
-      !
-      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,*) '~~~~~~~~~~~~'
+      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
-      !
-      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.
       !
       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
@@ -125,5 +127,5 @@
          !                                              
          DO jk = 1, jpkm1                !==  horizontal laplacian of before tracer ==!
-            DO_2D( 1, 0, 1, 0 )                   ! First derivative (masked gradient)
+            DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-1 )                   ! First derivative (masked gradient)
                zeeu = e2_e1u(ji,jj) * e3u(ji,jj,jk,Kmm) * umask(ji,jj,jk)
                zeev = e1_e2v(ji,jj) * e3v(ji,jj,jk,Kmm) * vmask(ji,jj,jk)
@@ -131,5 +133,5 @@
                ztv(ji,jj,jk) = zeev * ( pt(ji  ,jj+1,jk,jn,Kbb) - pt(ji,jj,jk,jn,Kbb) )
             END_2D
-            DO_2D( 0, 0, 0, 0 )                   ! Second derivative (divergence)
+            DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )                   ! Second derivative (divergence)
                zcoef = 1._wp / ( 6._wp * e3t(ji,jj,jk,Kmm) )
                zltu(ji,jj,jk) = (  ztu(ji,jj,jk) - ztu(ji-1,jj,jk)  ) * zcoef
@@ -138,5 +140,5 @@
             !                                    
          END DO         
-         CALL lbc_lnk( 'traadv_ubs', zltu, 'T', 1.0_wp )   ;    CALL lbc_lnk( 'traadv_ubs', zltv, 'T', 1.0_wp )   ! Lateral boundary cond. (unchanged sgn)
+         IF (nn_hls.EQ.1) CALL lbc_lnk_multi( 'traadv_ubs', zltu, 'T', 1.0_wp, zltv, 'T', 1.0_wp )   ! Lateral boundary cond. (unchanged sgn)
          !    
          DO_3D( 1, 0, 1, 0, 1, jpkm1 )   !==  Horizontal advective fluxes  ==!     (UBS)
@@ -153,5 +155,7 @@
          END_3D
          !
-         zltu(:,:,:) = pt(:,:,:,jn,Krhs)      ! store the initial trends before its update
+         DO_3D( 1, 1, 1, 1, 1, jpk )
+            zltu(ji,jj,jk) = pt(ji,jj,jk,jn,Krhs)      ! store the initial trends before its update
+         END_3D
          !
          DO jk = 1, jpkm1        !==  add the horizontal advective trend  ==!
@@ -165,7 +169,8 @@
          END DO
          !
-         zltu(:,:,:) = pt(:,:,:,jn,Krhs) - zltu(:,:,:)    ! Horizontal advective trend used in vertical 2nd order FCT case
-         !                                                ! and/or in trend diagnostic (l_trd=T) 
-         !                
+         DO_3D( 1, 1, 1, 1, 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) )
@@ -185,5 +190,9 @@
          CASE(  2  )                   ! 2nd order FCT 
             !         
-            IF( l_trd )   zltv(:,:,:) = pt(:,:,:,jn,Krhs)          ! store pt(:,:,:,:,Krhs) if trend diag.
+            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  ==!
@@ -199,5 +208,7 @@
                   END_2D
                ELSE                                   ! no cavities: only at the ocean surface
-                  ztw(:,:,1) = pW(:,:,1) * pt(:,:,1,jn,Kbb)
+                  DO_2D( 1, 1, 1, 1 )
+                     ztw(ji,jj,1) = pW(ji,jj,1) * pt(ji,jj,1,jn,Kbb)
+                  END_2D
                ENDIF
             ENDIF
@@ -209,5 +220,4 @@
                zti(ji,jj,jk)    = ( pt(ji,jj,jk,jn,Kbb) + p2dt * ( ztak + zltu(ji,jj,jk) ) ) * tmask(ji,jj,jk)
             END_3D
-            CALL lbc_lnk( 'traadv_ubs', zti, 'T', 1.0_wp )      ! Lateral boundary conditions on zti, zsi   (unchanged sign)
             !
             !                          !*  anti-diffusive flux : high order minus low order
@@ -226,5 +236,9 @@
                ztw(ji,jj,jk) = pW(ji,jj,jk) * ztw(ji,jj,jk) * wmask(ji,jj,jk)
             END_3D
-            IF( ln_linssh )   ztw(:,:, 1 ) = pW(:,:,1) * pt(:,:,1,jn,Kmm)     !!gm ISF & 4th COMPACT doesn't work
+            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
@@ -262,14 +276,14 @@
       !!       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 (jpi,jpj,jpk) ::   paft   ! after field
-      REAL(wp), INTENT(inout), DIMENSION (jpi,jpj,jpk) ::   pcc    ! monotonic flux in the k direction
+      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(jpi,jpj,jpk) ::   zbetup, zbetdo     ! 3D workspace
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zbetup, zbetdo         ! 3D workspace
       !!----------------------------------------------------------------------
       !
@@ -281,6 +295,8 @@
       ! --------------------
       !                    ! large negative value (-zbig) inside land
-      pbef(:,:,:) = pbef(:,:,:) * tmask(:,:,:) - zbig * ( 1.e0 - tmask(:,:,:) )
-      paft(:,:,:) = paft(:,:,:) * tmask(:,:,:) - zbig * ( 1.e0 - tmask(:,:,:) )
+      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
@@ -293,6 +309,8 @@
       END DO
       !                    ! large positive value (+zbig) inside land
-      pbef(:,:,:) = pbef(:,:,:) * tmask(:,:,:) + zbig * ( 1.e0 - tmask(:,:,:) )
-      paft(:,:,:) = paft(:,:,:) * tmask(:,:,:) + zbig * ( 1.e0 - tmask(:,:,:) )
+      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
@@ -305,6 +323,8 @@
       END DO
       !                    ! restore masked values to zero
-      pbef(:,:,:) = pbef(:,:,:) * tmask(:,:,:)
-      paft(:,:,:) = paft(:,:,:) * tmask(:,:,:)
+      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
Index: /NEMO/trunk/src/OCE/TRA/traatf.F90
===================================================================
--- /NEMO/trunk/src/OCE/TRA/traatf.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/TRA/traatf.F90	(revision 13982)
@@ -156,8 +156,6 @@
          ENDIF
          !
-         CALL lbc_lnk_multi( 'traatf', pts(:,:,:,jp_tem,Kbb) , 'T', 1.0_wp, pts(:,:,:,jp_sal,Kbb) , 'T', 1.0_wp, &
-                  &                    pts(:,:,:,jp_tem,Kmm) , 'T', 1.0_wp, pts(:,:,:,jp_sal,Kmm) , 'T', 1.0_wp, &
-                  &                    pts(:,:,:,jp_tem,Kaa), 'T', 1.0_wp, pts(:,:,:,jp_sal,Kaa), 'T', 1.0_wp  )
-         !
+         CALL lbc_lnk_multi( 'traatf',  pts(:,:,:,jp_tem,Kmm) , 'T', 1.0_wp, pts(:,:,:,jp_sal,Kmm) , 'T', 1.0_wp ) 
+
       ENDIF     
       !
@@ -210,5 +208,5 @@
       DO jn = 1, kjpt
          !
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+         DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpkm1 )
             ztn = pt(ji,jj,jk,jn,Kmm)                                    
             ztd = pt(ji,jj,jk,jn,Kaa) - 2._wp * ztn + pt(ji,jj,jk,jn,Kbb)  ! time laplacian on tracers
@@ -275,5 +273,5 @@
       zfact2 = zfact1 * r1_rho0
       DO jn = 1, kjpt      
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+         DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpkm1 )
             ze3t_b = e3t(ji,jj,jk,Kbb)
             ze3t_n = e3t(ji,jj,jk,Kmm)
Index: /NEMO/trunk/src/OCE/TRA/traatf_qco.F90
===================================================================
--- /NEMO/trunk/src/OCE/TRA/traatf_qco.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/TRA/traatf_qco.F90	(revision 13982)
@@ -149,8 +149,6 @@
          ENDIF
          !
-         CALL lbc_lnk_multi( 'traatfqco', pts(:,:,:,jp_tem,Kbb) , 'T', 1., pts(:,:,:,jp_sal,Kbb) , 'T', 1., &
-                  &                    pts(:,:,:,jp_tem,Kmm) , 'T', 1., pts(:,:,:,jp_sal,Kmm) , 'T', 1., &
-                  &                    pts(:,:,:,jp_tem,Kaa), 'T', 1., pts(:,:,:,jp_sal,Kaa), 'T', 1.  )
-         !
+         CALL lbc_lnk_multi( 'traatfqco', pts(:,:,:,jp_tem,Kmm) , 'T', 1., pts(:,:,:,jp_sal,Kmm) , 'T', 1. )
+
       ENDIF
       !
@@ -203,5 +201,5 @@
       DO jn = 1, kjpt
          !
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+         DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpkm1 )
             ztn = pt(ji,jj,jk,jn,Kmm)
             ztd = pt(ji,jj,jk,jn,Kaa) - 2._wp * ztn + pt(ji,jj,jk,jn,Kbb)  ! time laplacian on tracers
@@ -268,5 +266,5 @@
       zfact2 = zfact1 * r1_rho0
       DO jn = 1, kjpt
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
+         DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpkm1 )
             ze3t_b = e3t(ji,jj,jk,Kbb)
             ze3t_n = e3t(ji,jj,jk,Kmm)
Index: /NEMO/trunk/src/OCE/TRA/trabbc.F90
===================================================================
--- /NEMO/trunk/src/OCE/TRA/trabbc.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/TRA/trabbc.F90	(revision 13982)
@@ -80,5 +80,5 @@
       REAL(wp), DIMENSION(jpi,jpj,jpk,jpts,jpt), INTENT(inout) :: pts        ! active tracers and RHS of tracer equation
       !
-      INTEGER  ::   ji, jj    ! dummy loop indices
+      INTEGER  ::   ji, jj, jk    ! dummy loop indices
       REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) ::   ztrdt   ! 3D workspace
       !!----------------------------------------------------------------------
@@ -86,5 +86,5 @@
       IF( ln_timing )   CALL timing_start('tra_bbc')
       !
-      IF( l_trdtra )   THEN         ! Save the input temperature trend
+      IF( l_trdtra ) THEN           ! Save the input temperature trend
          ALLOCATE( ztrdt(jpi,jpj,jpk) )
          ztrdt(:,:,:) = pts(:,:,:,jp_tem,Krhs)
@@ -96,6 +96,4 @@
       END_2D
       !
-      CALL lbc_lnk( 'trabbc', pts(:,:,:,jp_tem,Krhs) , 'T', 1.0_wp )
-      !
       IF( l_trdtra ) THEN        ! Send the trend for diagnostics
          ztrdt(:,:,:) = pts(:,:,:,jp_tem,Krhs) - ztrdt(:,:,:)
@@ -104,5 +102,7 @@
       ENDIF
       !
-      CALL iom_put ( "hfgeou" , rho0_rcp * qgh_trd0(:,:) )
+      IF( ntile == 0 .OR. ntile == nijtile )  THEN                ! Do only for the full domain
+         CALL iom_put ( "hfgeou" , rho0_rcp * qgh_trd0(:,:) )
+      ENDIF
       IF(sn_cfctl%l_prtctl)   CALL prt_ctl( tab3d_1=pts(:,:,:,jp_tem,Krhs), clinfo1=' bbc  - Ta: ', mask1=tmask, clinfo3='tra-ta' )
       !
Index: /NEMO/trunk/src/OCE/TRA/trabbl.F90
===================================================================
--- /NEMO/trunk/src/OCE/TRA/trabbl.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/TRA/trabbl.F90	(revision 13982)
@@ -106,4 +106,5 @@
       REAL(wp), DIMENSION(jpi,jpj,jpk,jpts,jpt), INTENT(inout) :: pts             ! active tracers and RHS of tracer equation
       !
+      INTEGER  ::   ji, jj, jk   ! Dummy loop indices
       REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) ::   ztrdt, ztrds
       !!----------------------------------------------------------------------
@@ -112,5 +113,5 @@
       !
       IF( l_trdtra )   THEN                         !* Save the T-S input trends
-         ALLOCATE( ztrdt(jpi,jpj,jpk) , ztrds(jpi,jpj,jpk) )
+         ALLOCATE( ztrdt(jpi,jpj,jpk), ztrds(jpi,jpj,jpk) )
          ztrdt(:,:,:) = pts(:,:,:,jp_tem,Krhs)
          ztrds(:,:,:) = pts(:,:,:,jp_sal,Krhs)
@@ -125,8 +126,8 @@
          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' )
-         ! lateral boundary conditions ; just need for outputs
-         CALL lbc_lnk_multi( 'trabbl', ahu_bbl, 'U', 1.0_wp , ahv_bbl, 'V', 1.0_wp )
-         CALL iom_put( "ahu_bbl", ahu_bbl )   ! bbl diffusive flux i-coef
-         CALL iom_put( "ahv_bbl", ahv_bbl )   ! bbl diffusive flux j-coef
+         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
          !
       ENDIF
@@ -136,10 +137,13 @@
          CALL tra_bbl_adv( pts(:,:,:,:,Kbb), pts(:,:,:,:,Krhs), jpts, Kmm )
          IF(sn_cfctl%l_prtctl)   &
-         CALL prt_ctl( tab3d_1=pts(:,:,:,jp_tem,Krhs), clinfo1=' bbl_adv  - Ta: ', mask1=tmask,   &
+         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' )
-         ! lateral boundary conditions ; just need for outputs
-         CALL lbc_lnk_multi( '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
+         IF( ntile == 0 .OR. ntile == nijtile ) THEN                       ! Do only on the last tile
+            ! lateral boundary conditions ; just need for outputs
+            ! NOTE: [tiling-comms-merge] The diagnostic results change along the north fold if this is removed
+            CALL lbc_lnk_multi( '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
          !
       ENDIF
@@ -187,5 +191,5 @@
       INTEGER  ::   ik           ! local integers
       REAL(wp) ::   zbtr         ! local scalars
-      REAL(wp), DIMENSION(jpi,jpj) ::   zptb   ! workspace
+      REAL(wp), DIMENSION(A2D(nn_hls)) ::   zptb   ! workspace
       !!----------------------------------------------------------------------
       !
@@ -235,62 +239,63 @@
       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 jj = 1, jpjm1
-            DO ji = 1, jpim1            ! 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)
-                  iid  = ji + MAX( 0, mgrhu(ji,jj) )   ;   iis  = ji + 1 - MAX( 0, mgrhu(ji,jj) )
-                  ikud = mbku_d(ji,jj)                 ;   ikus = mbku(ji,jj)
-                  zu_bbl = ABS( utr_bbl(ji,jj) )
-                  !
-                  !                                               ! up  -slope T-point (shelf bottom point)
-                  zbtr = r1_e1e2t(iis,jj) / e3t(iis,jj,ikus,Kmm)
-                  ztra = zu_bbl * ( pt(iid,jj,ikus,jn) - pt(iis,jj,ikus,jn) ) * zbtr
-                  pt_rhs(iis,jj,ikus,jn) = pt_rhs(iis,jj,ikus,jn) + ztra
-                  !
-                  DO jk = ikus, ikud-1                            ! down-slope upper to down T-point (deep column)
-                     zbtr = r1_e1e2t(iid,jj) / e3t(iid,jj,jk,Kmm)
-                     ztra = zu_bbl * ( pt(iid,jj,jk+1,jn) - pt(iid,jj,jk,jn) ) * zbtr
-                     pt_rhs(iid,jj,jk,jn) = pt_rhs(iid,jj,jk,jn) + ztra
-                  END DO
-                  !
-                  zbtr = r1_e1e2t(iid,jj) / e3t(iid,jj,ikud,Kmm)
-                  ztra = zu_bbl * ( pt(iis,jj,ikus,jn) - pt(iid,jj,ikud,jn) ) * zbtr
-                  pt_rhs(iid,jj,ikud,jn) = pt_rhs(iid,jj,ikud,jn) + ztra
-               ENDIF
-               !
-               IF( vtr_bbl(ji,jj) /= 0.e0 ) THEN            ! non-zero j-direction bbl advection
-                  ! down-slope j/k-indices (deep)        &   up-slope j/k indices (shelf)
-                  ijd  = jj + MAX( 0, mgrhv(ji,jj) )     ;   ijs  = jj + 1 - MAX( 0, mgrhv(ji,jj) )
-                  ikvd = mbkv_d(ji,jj)                   ;   ikvs = mbkv(ji,jj)
-                  zv_bbl = ABS( vtr_bbl(ji,jj) )
-                  !
-                  ! up  -slope T-point (shelf bottom point)
-                  zbtr = r1_e1e2t(ji,ijs) / e3t(ji,ijs,ikvs,Kmm)
-                  ztra = zv_bbl * ( pt(ji,ijd,ikvs,jn) - pt(ji,ijs,ikvs,jn) ) * zbtr
-                  pt_rhs(ji,ijs,ikvs,jn) = pt_rhs(ji,ijs,ikvs,jn) + ztra
-                  !
-                  DO jk = ikvs, ikvd-1                            ! down-slope upper to down T-point (deep column)
-                     zbtr = r1_e1e2t(ji,ijd) / e3t(ji,ijd,jk,Kmm)
-                     ztra = zv_bbl * ( pt(ji,ijd,jk+1,jn) - pt(ji,ijd,jk,jn) ) * zbtr
-                     pt_rhs(ji,ijd,jk,jn) = pt_rhs(ji,ijd,jk,jn)  + ztra
-                  END DO
-                  !                                               ! down-slope T-point (deep bottom point)
-                  zbtr = r1_e1e2t(ji,ijd) / e3t(ji,ijd,ikvd,Kmm)
-                  ztra = zv_bbl * ( pt(ji,ijs,ikvs,jn) - pt(ji,ijd,ikvd,jn) ) * zbtr
-                  pt_rhs(ji,ijd,ikvd,jn) = pt_rhs(ji,ijd,ikvd,jn) + ztra
-               ENDIF
-            END DO
+         ! NOTE: [tiling-comms-merge] Bug fix- correct order of indices
+         DO_2D( isj, 0, isi, 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)
+               iid  = ji + MAX( 0, mgrhu(ji,jj) )   ;   iis  = ji + 1 - MAX( 0, mgrhu(ji,jj) )
+               ikud = mbku_d(ji,jj)                 ;   ikus = mbku(ji,jj)
+               zu_bbl = ABS( utr_bbl(ji,jj) )
+               !
+               !                                               ! up  -slope T-point (shelf bottom point)
+               zbtr = r1_e1e2t(iis,jj) / e3t(iis,jj,ikus,Kmm)
+               ztra = zu_bbl * ( pt(iid,jj,ikus,jn) - pt(iis,jj,ikus,jn) ) * zbtr
+               pt_rhs(iis,jj,ikus,jn) = pt_rhs(iis,jj,ikus,jn) + ztra
+               !
+               DO jk = ikus, ikud-1                            ! down-slope upper to down T-point (deep column)
+                  zbtr = r1_e1e2t(iid,jj) / e3t(iid,jj,jk,Kmm)
+                  ztra = zu_bbl * ( pt(iid,jj,jk+1,jn) - pt(iid,jj,jk,jn) ) * zbtr
+                  pt_rhs(iid,jj,jk,jn) = pt_rhs(iid,jj,jk,jn) + ztra
+               END DO
+               !
+               zbtr = r1_e1e2t(iid,jj) / e3t(iid,jj,ikud,Kmm)
+               ztra = zu_bbl * ( pt(iis,jj,ikus,jn) - pt(iid,jj,ikud,jn) ) * zbtr
+               pt_rhs(iid,jj,ikud,jn) = pt_rhs(iid,jj,ikud,jn) + ztra
+            ENDIF
             !
-         END DO
-         !                                                  ! ===========
-      END DO                                                ! end tracer
-      !                                                     ! ===========
+            IF( vtr_bbl(ji,jj) /= 0.e0 ) THEN            ! non-zero j-direction bbl advection
+               ! down-slope j/k-indices (deep)        &   up-slope j/k indices (shelf)
+               ijd  = jj + MAX( 0, mgrhv(ji,jj) )     ;   ijs  = jj + 1 - MAX( 0, mgrhv(ji,jj) )
+               ikvd = mbkv_d(ji,jj)                   ;   ikvs = mbkv(ji,jj)
+               zv_bbl = ABS( vtr_bbl(ji,jj) )
+               !
+               ! up  -slope T-point (shelf bottom point)
+               zbtr = r1_e1e2t(ji,ijs) / e3t(ji,ijs,ikvs,Kmm)
+               ztra = zv_bbl * ( pt(ji,ijd,ikvs,jn) - pt(ji,ijs,ikvs,jn) ) * zbtr
+               pt_rhs(ji,ijs,ikvs,jn) = pt_rhs(ji,ijs,ikvs,jn) + ztra
+               !
+               DO jk = ikvs, ikvd-1                            ! down-slope upper to down T-point (deep column)
+                  zbtr = r1_e1e2t(ji,ijd) / e3t(ji,ijd,jk,Kmm)
+                  ztra = zv_bbl * ( pt(ji,ijd,jk+1,jn) - pt(ji,ijd,jk,jn) ) * zbtr
+                  pt_rhs(ji,ijd,jk,jn) = pt_rhs(ji,ijd,jk,jn)  + ztra
+               END DO
+               !                                               ! down-slope T-point (deep bottom point)
+               zbtr = r1_e1e2t(ji,ijd) / e3t(ji,ijd,ikvd,Kmm)
+               ztra = zv_bbl * ( pt(ji,ijs,ikvs,jn) - pt(ji,ijd,ikvd,jn) ) * zbtr
+               pt_rhs(ji,ijd,ikvd,jn) = pt_rhs(ji,ijd,ikvd,jn) + ztra
+            ENDIF
+         END_2D
+         !                                                       ! ===========
+      END DO                                                     ! end tracer
+      !                                                          ! ===========
    END SUBROUTINE tra_bbl_adv
 
@@ -333,12 +338,14 @@
       REAL(wp) ::   za, zb, zgdrho            ! local scalars
       REAL(wp) ::   zsign, zsigna, zgbbl      !   -      -
-      REAL(wp), DIMENSION(jpi,jpj,jpts)   :: zts, zab         ! 3D workspace
-      REAL(wp), DIMENSION(jpi,jpj)        :: zub, zvb, zdep   ! 2D workspace
-      !!----------------------------------------------------------------------
-      !
-      IF( kt == kit000 )  THEN
-         IF(lwp)  WRITE(numout,*)
-         IF(lwp)  WRITE(numout,*) 'trabbl:bbl : Compute bbl velocities and diffusive coefficients in ', cdtype
-         IF(lwp)  WRITE(numout,*) '~~~~~~~~~~'
+      REAL(wp), DIMENSION(A2D(nn_hls),jpts)   :: zts, zab         ! 3D workspace
+      REAL(wp), DIMENSION(A2D(nn_hls))        :: zub, zvb, zdep   ! 2D 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,*) 'trabbl:bbl : Compute bbl velocities and diffusive coefficients in ', cdtype
+            IF(lwp)  WRITE(numout,*) '~~~~~~~~~~'
+         ENDIF
       ENDIF
       !                                        !* bottom variables (T, S, alpha, beta, depth, velocity)
Index: /NEMO/trunk/src/OCE/TRA/tradmp.F90
===================================================================
--- /NEMO/trunk/src/OCE/TRA/tradmp.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/TRA/tradmp.F90	(revision 13982)
@@ -95,5 +95,5 @@
       !
       INTEGER ::   ji, jj, jk, jn   ! dummy loop indices
-      REAL(wp), DIMENSION(jpi,jpj,jpk,jpts)     ::  zts_dta
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk,jpts)     ::  zts_dta
       REAL(wp), DIMENSION(:,:,:,:), ALLOCATABLE ::  ztrdts
       !!----------------------------------------------------------------------
@@ -102,6 +102,6 @@
       !
       IF( l_trdtra )   THEN                    !* Save ta and sa trends
-         ALLOCATE( ztrdts(jpi,jpj,jpk,jpts) ) 
-         ztrdts(:,:,:,:) = pts(:,:,:,:,Krhs) 
+         ALLOCATE( ztrdts(jpi,jpj,jpk,jpts) )
+         ztrdts(:,:,:,:) = pts(:,:,:,:,Krhs)
       ENDIF
       !                           !==  input T-S data at kt  ==!
@@ -144,5 +144,5 @@
          CALL trd_tra( kt, Kmm, Krhs, 'TRA', jp_tem, jptra_dmp, ztrdts(:,:,:,jp_tem) )
          CALL trd_tra( kt, Kmm, Krhs, 'TRA', jp_sal, jptra_dmp, ztrdts(:,:,:,jp_sal) )
-         DEALLOCATE( ztrdts ) 
+         DEALLOCATE( ztrdts )
       ENDIF
       !                           ! Control print
Index: /NEMO/trunk/src/OCE/TRA/traisf.F90
===================================================================
--- /NEMO/trunk/src/OCE/TRA/traisf.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/TRA/traisf.F90	(revision 13982)
@@ -11,4 +11,5 @@
    !!----------------------------------------------------------------------
    USE isf_oce                                     ! Ice shelf variables
+   USE par_oce , ONLY : nijtile, ntile, ntsi, ntei, ntsj, ntej
    USE dom_oce                                     ! ocean space domain variables
    USE isfutils, ONLY : debug                      ! debug option
@@ -46,8 +47,10 @@
       IF( ln_timing )   CALL timing_start('tra_isf')
       !
-      IF( kt == nit000 ) THEN
-         IF(lwp) WRITE(numout,*)
-         IF(lwp) WRITE(numout,*) 'tra_isf : Ice shelf heat fluxes'
-         IF(lwp) WRITE(numout,*) '~~~~~~~ '
+      IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+         IF( kt == nit000 ) THEN
+            IF(lwp) WRITE(numout,*)
+            IF(lwp) WRITE(numout,*) 'tra_isf : Ice shelf heat fluxes'
+            IF(lwp) WRITE(numout,*) '~~~~~~~ '
+         ENDIF
       ENDIF
       !
@@ -76,6 +79,8 @@
       !
       IF ( ln_isfdebug ) THEN
-         CALL debug('tra_isf: pts(:,:,:,:,Krhs) T', pts(:,:,:,1,Krhs))
-         CALL debug('tra_isf: pts(:,:,:,:,Krhs) S', pts(:,:,:,2,Krhs))
+         IF( ntile == 0 .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))
+         ENDIF
       END IF
       !
@@ -101,12 +106,14 @@
       INTEGER                      :: ji,jj,jk  ! loop index   
       INTEGER                      :: ikt, ikb  ! top and bottom level of the tbl
-      REAL(wp), DIMENSION(jpi,jpj) :: ztc       ! total ice shelf tracer trend
+      REAL(wp), DIMENSION(A2D(nn_hls))     :: ztc       ! total ice shelf tracer trend
       !!----------------------------------------------------------------------
       !
       ! compute 2d total trend due to isf
-      ztc(:,:) = 0.5_wp * ( ptsc(:,:,jp_tem) + ptsc_b(:,:,jp_tem) ) / phtbl(:,:)
+      DO_2D( 0, 0, 0, 0 )
+         ztc(ji,jj) = 0.5_wp * ( ptsc(ji,jj,jp_tem) + ptsc_b(ji,jj,jp_tem) ) / phtbl(ji,jj)
+      END_2D
       !
       ! update pts(:,:,:,:,Krhs)
-      DO_2D( 1, 1, 1, 1 )
+      DO_2D( 0, 0, 0, 0 )
          !
          ikt = ktop(ji,jj)
@@ -137,13 +144,11 @@
       REAL(wp), DIMENSION(jpi,jpj,jpk,jpts), INTENT(in   ) :: ptsc
       !!----------------------------------------------------------------------
-      INTEGER :: jk
+      INTEGER :: ji, jj, jk
       !!----------------------------------------------------------------------
       !
-      DO jk = 1,jpk
-         ptsa(:,:,jk,jp_tem) =   &
-            &  ptsa(:,:,jk,jp_tem) + ptsc(:,:,jk,jp_tem) * r1_e1e2t(:,:) / e3t(:,:,jk,Kmm)
-         ptsa(:,:,jk,jp_sal) =   &
-            &  ptsa(:,:,jk,jp_sal) + ptsc(:,:,jk,jp_sal) * r1_e1e2t(:,:) / e3t(:,:,jk,Kmm)
-      END DO
+      DO_3D( 0, 0, 0, 0, 1, jpk )
+         ptsa(ji,jj,jk,jp_tem) = ptsa(ji,jj,jk,jp_tem) + ptsc(ji,jj,jk,jp_tem) * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
+         ptsa(ji,jj,jk,jp_sal) = ptsa(ji,jj,jk,jp_sal) + ptsc(ji,jj,jk,jp_sal) * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
+      END_3D
       !
    END SUBROUTINE tra_isf_cpl
Index: /NEMO/trunk/src/OCE/TRA/traldf.F90
===================================================================
--- /NEMO/trunk/src/OCE/TRA/traldf.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/TRA/traldf.F90	(revision 13982)
@@ -17,4 +17,6 @@
    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 domain, ONLY : dom_tile
    USE phycst         ! physical constants
    USE ldftra         ! lateral diffusion: eddy diffusivity & EIV coeff.
@@ -37,5 +39,5 @@
    PUBLIC   tra_ldf        ! called by step.F90 
    PUBLIC   tra_ldf_init   ! called by nemogcm.F90 
-   
+
    !!----------------------------------------------------------------------
    !! NEMO/OCE 4.0 , NEMO Consortium (2018)
@@ -56,34 +58,56 @@
       !!
       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) ) 
-         ztrdt(:,:,:) = pts(:,:,:,jp_tem,Krhs) 
+         ALLOCATE( ztrdt(jpi,jpj,jpk) , ztrds(jpi,jpj,jpk) )
+         ztrdt(:,:,:) = pts(:,:,:,jp_tem,Krhs)
          ztrds(:,:,:) = pts(:,:,:,jp_sal,Krhs)
       ENDIF
-      !
-      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 ) 
+
+      ! 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
+            ! NOTE: [tiling-comms-merge] This lbc_lnk is still needed in the zco case, because zps_hde is not called in step
+            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 )
       ENDIF
       !                                        !* print mean trends (used for debugging)
-      IF(sn_cfctl%l_prtctl)   CALL prt_ctl( tab3d_1=pts(:,:,:,jp_tem,Krhs), clinfo1=' ldf  - Ta: ', mask1=tmask,               &
+      IF(sn_cfctl%l_prtctl)   CALL prt_ctl( tab3d_1=pts(:,:,:,jp_tem,Krhs), clinfo1=' ldf  - Ta: ', mask1=tmask, &
          &                                  tab3d_2=pts(:,:,:,jp_sal,Krhs), clinfo2=       ' Sa: ', mask2=tmask, clinfo3='tra' )
       !
Index: /NEMO/trunk/src/OCE/TRA/traldf_iso.F90
===================================================================
--- /NEMO/trunk/src/OCE/TRA/traldf_iso.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/TRA/traldf_iso.F90	(revision 13982)
@@ -19,4 +19,5 @@
    USE oce            ! ocean dynamics and active tracers
    USE dom_oce        ! ocean space and time domain
+   USE domutl, ONLY : is_tile
    USE trc_oce        ! share passive tracers/Ocean variables
    USE zdf_oce        ! ocean vertical physics
@@ -49,7 +50,30 @@
 CONTAINS
 
-  SUBROUTINE tra_ldf_iso( kt, Kmm, kit000, cdtype, pahu, pahv,                    &
-      &                                            pgu , pgv    ,   pgui, pgvi,   &
-      &                                       pt , pt2 , pt_rhs , kjpt  , kpass )
+   SUBROUTINE tra_ldf_iso( kt, Kmm, kit000, cdtype, pahu, pahv,             &
+      &                                             pgu , pgv , pgui, pgvi, &
+      &                                             pt, pt2, pt_rhs, kjpt, kpass )
+      !!
+      INTEGER                     , INTENT(in   ) ::   kt         ! ocean time-step index
+      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   ) ::   kpass      ! =1/2 first or second passage
+      INTEGER                     , INTENT(in   ) ::   Kmm        ! ocean time level index
+      REAL(wp), DIMENSION(:,:,:)  , INTENT(in   ) ::   pahu, pahv ! eddy diffusivity at u- and v-points  [m2/s]
+      REAL(wp), DIMENSION(:,:,:)  , INTENT(in   ) ::   pgu, pgv   ! tracer gradient at pstep levels
+      REAL(wp), DIMENSION(:,:,:)  , INTENT(in   ) ::   pgui, pgvi ! tracer gradient at top   levels
+      REAL(wp), DIMENSION(:,:,:,:), INTENT(in   ) ::   pt         ! tracer (kpass=1) or laplacian of tracer (kpass=2)
+      REAL(wp), DIMENSION(:,:,:,:), INTENT(in   ) ::   pt2        ! tracer (only used in kpass=2)
+      REAL(wp), DIMENSION(:,:,:,:), INTENT(inout) ::   pt_rhs     ! tracer trend
+      !!
+      CALL tra_ldf_iso_t( kt, Kmm, kit000, cdtype, pahu, pahv, is_tile(pahu),                             &
+         &                                         pgu , pgv , is_tile(pgu) , pgui, pgvi, is_tile(pgui),  &
+         &                                         pt, is_tile(pt), pt2, is_tile(pt2), pt_rhs, is_tile(pt_rhs), kjpt, kpass )
+   END SUBROUTINE tra_ldf_iso
+
+
+  SUBROUTINE tra_ldf_iso_t( kt, Kmm, kit000, cdtype, pahu, pahv, ktah,                    &
+      &                                              pgu , pgv , ktg , pgui, pgvi, ktgi,  &
+      &                                              pt, ktt, pt2, ktt2, pt_rhs, ktt_rhs, kjpt, kpass )
       !!----------------------------------------------------------------------
       !!                  ***  ROUTINE tra_ldf_iso  ***
@@ -92,16 +116,17 @@
       !! ** Action :   Update pt_rhs arrays with the before rotated diffusion
       !!----------------------------------------------------------------------
-      INTEGER                              , INTENT(in   ) ::   kt         ! ocean time-step index
-      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   ) ::   kpass      ! =1/2 first or second passage
-      INTEGER                              , INTENT(in   ) ::   Kmm        ! ocean time level index
-      REAL(wp), DIMENSION(jpi,jpj,jpk)     , INTENT(in   ) ::   pahu, pahv ! eddy diffusivity at u- and v-points  [m2/s]
-      REAL(wp), DIMENSION(jpi,jpj    ,kjpt), INTENT(in   ) ::   pgu, pgv   ! tracer gradient at pstep levels
-      REAL(wp), DIMENSION(jpi,jpj,    kjpt), INTENT(in   ) ::   pgui, pgvi ! tracer gradient at top   levels
-      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(in   ) ::   pt         ! tracer (kpass=1) or laplacian of tracer (kpass=2)
-      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(in   ) ::   pt2        ! tracer (only used in kpass=2)
-      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(inout) ::   pt_rhs     ! tracer trend
+      INTEGER                                   , INTENT(in   ) ::   kt         ! ocean time-step index
+      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   ) ::   kpass      ! =1/2 first or second passage
+      INTEGER                                   , INTENT(in   ) ::   Kmm        ! ocean time level index
+      INTEGER                                   , INTENT(in   ) ::   ktah, ktg, ktgi, ktt, ktt2, ktt_rhs
+      REAL(wp), DIMENSION(A2D_T(ktah)   ,JPK)     , INTENT(in   ) ::   pahu, pahv ! eddy diffusivity at u- and v-points  [m2/s]
+      REAL(wp), DIMENSION(A2D_T(ktg)        ,KJPT), INTENT(in   ) ::   pgu, pgv   ! tracer gradient at pstep levels
+      REAL(wp), DIMENSION(A2D_T(ktgi)       ,KJPT), INTENT(in   ) ::   pgui, pgvi ! tracer gradient at top   levels
+      REAL(wp), DIMENSION(A2D_T(ktt)    ,JPK,KJPT), INTENT(in   ) ::   pt         ! tracer (kpass=1) or laplacian of tracer (kpass=2)
+      REAL(wp), DIMENSION(A2D_T(ktt2)   ,JPK,KJPT), INTENT(in   ) ::   pt2        ! tracer (only used in kpass=2)
+      REAL(wp), DIMENSION(A2D_T(ktt_rhs),JPK,KJPT), INTENT(inout) ::   pt_rhs     ! tracer trend
       !
       INTEGER  ::  ji, jj, jk, jn   ! dummy loop indices
@@ -111,22 +136,28 @@
       REAL(wp) ::  zmskv, zahv_w, zabe2, zcof2, zcoef4   !   -      -
       REAL(wp) ::  zcoef0, ze3w_2, zsign                 !   -      -
-      REAL(wp), DIMENSION(jpi,jpj)     ::   zdkt, zdk1t, z2d
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zdit, zdjt, zftu, zftv, ztfw 
+      REAL(wp), DIMENSION(A2D(nn_hls))     ::   zdkt, zdk1t, z2d
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zdit, zdjt, zftu, zftv, ztfw
       !!----------------------------------------------------------------------
       !
       IF( kpass == 1 .AND. kt == kit000 )  THEN
-         IF(lwp) WRITE(numout,*)
-         IF(lwp) WRITE(numout,*) 'tra_ldf_iso : rotated laplacian diffusion operator on ', cdtype
-         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~'
-         !
-         akz     (:,:,:) = 0._wp      
-         ah_wslp2(:,:,:) = 0._wp
+         IF( ntile == 0 .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
+            IF(lwp) WRITE(numout,*) '~~~~~~~~~~~'
+         ENDIF
+         !
+         DO_3D( 0, 0, 0, 0, 1, jpk )
+            akz     (ji,jj,jk) = 0._wp
+            ah_wslp2(ji,jj,jk) = 0._wp
+         END_3D
       ENDIF
-      !   
-      l_hst = .FALSE.
-      l_ptr = .FALSE.
-      IF( cdtype == 'TRA' .AND. ( iom_use( 'sophtldf' ) .OR. iom_use( 'sopstldf' ) ) )     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( ntile == 0 .OR. ntile == 1 )  THEN                           ! Do only on the first tile
+         l_hst = .FALSE.
+         l_ptr = .FALSE.
+         IF( cdtype == 'TRA' .AND. ( iom_use( 'sophtldf' ) .OR. iom_use( 'sopstldf' ) ) )     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
       !
       !
@@ -167,5 +198,5 @@
             !
             IF( ln_traldf_blp ) THEN                ! bilaplacian operator
-               DO_3D( 1, 0, 1, 0, 2, jpkm1 )
+               DO_3D( 0, 0, 0, 0, 2, jpkm1 )
                   akz(ji,jj,jk) = 16._wp   &
                      &   * ah_wslp2   (ji,jj,jk)   &
@@ -175,5 +206,5 @@
                END_3D
             ELSEIF( ln_traldf_lap ) THEN              ! laplacian operator
-               DO_3D( 1, 0, 1, 0, 2, jpkm1 )
+               DO_3D( 0, 0, 0, 0, 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  )
@@ -183,5 +214,7 @@
            !
          ELSE                                    ! 33 flux set to zero with akz=ah_wslp2 ==>> computed in full implicit
-            akz(:,:,:) = ah_wslp2(:,:,:)      
+            DO_3D( 0, 0, 0, 0, 1, jpk )
+               akz(ji,jj,jk) = ah_wslp2(ji,jj,jk)
+            END_3D
          ENDIF
       ENDIF
@@ -195,6 +228,6 @@
          !!----------------------------------------------------------------------
 !!gm : bug.... why (x,:,:)?   (1,jpj,:) and (jpi,1,:) should be sufficient....
-         zdit (1,:,:) = 0._wp     ;     zdit (jpi,:,:) = 0._wp
-         zdjt (1,:,:) = 0._wp     ;     zdjt (jpi,:,:) = 0._wp
+         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
 
@@ -223,10 +256,13 @@
          DO jk = 1, jpkm1                                 ! Horizontal slab
             !
-            !                             !== Vertical tracer gradient
-            zdk1t(:,:) = ( pt(:,:,jk,jn) - pt(:,:,jk+1,jn) ) * wmask(:,:,jk+1)     ! level jk+1
-            !
-            IF( jk == 1 ) THEN   ;   zdkt(:,:) = zdk1t(:,:)                          ! surface: zdkt(jk=1)=zdkt(jk=2)
-            ELSE                 ;   zdkt(:,:) = ( pt(:,:,jk-1,jn) - pt(:,:,jk,jn) ) * wmask(:,:,jk)
-            ENDIF
+            DO_2D( 1, 1, 1, 1 )
+               !                             !== 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
+               !
+               IF( jk == 1 ) THEN   ;   zdkt(ji,jj) = zdk1t(ji,jj)                            ! surface: zdkt(jk=1)=zdkt(jk=2)
+               ELSE                 ;   zdkt(ji,jj) = ( pt(ji,jj,jk-1,jn) - pt(ji,jj,jk,jn) ) * wmask(ji,jj,jk)
+               ENDIF
+            END_2D
+            !
             DO_2D( 1, 0, 1, 0 )           !==  Horizontal fluxes
                zabe1 = pahu(ji,jj,jk) * e2_e1u(ji,jj) * e3u(ji,jj,jk,Kmm)
@@ -330,5 +366,5 @@
       END DO                                                      ! end tracer loop
       !
-   END SUBROUTINE tra_ldf_iso
+   END SUBROUTINE tra_ldf_iso_t
 
    !!==============================================================================
Index: /NEMO/trunk/src/OCE/TRA/traldf_lap_blp.F90
===================================================================
--- /NEMO/trunk/src/OCE/TRA/traldf_lap_blp.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/TRA/traldf_lap_blp.F90	(revision 13982)
@@ -13,4 +13,5 @@
    USE oce            ! ocean dynamics and active tracers
    USE dom_oce        ! ocean space and time domain
+   USE domutl, ONLY : is_tile
    USE ldftra         ! lateral physics: eddy diffusivity
    USE traldf_iso     ! iso-neutral lateral diffusion (standard operator)     (tra_ldf_iso   routine)
@@ -46,7 +47,29 @@
 CONTAINS
 
-   SUBROUTINE tra_ldf_lap( kt, Kmm, kit000, cdtype, pahu, pahv  ,               &
-      &                                             pgu , pgv   , pgui, pgvi,   &
-      &                                             pt  , pt_rhs, kjpt, kpass ) 
+   SUBROUTINE tra_ldf_lap( kt, Kmm, kit000, cdtype, pahu, pahv,             &
+      &                                             pgu , pgv , pgui, pgvi, &
+      &                                             pt, pt_rhs, kjpt, kpass )
+      !!
+      INTEGER                     , INTENT(in   ) ::   kt         ! ocean time-step index
+      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   ) ::   kpass      ! =1/2 first or second passage
+      INTEGER                     , INTENT(in   ) ::   Kmm        ! ocean time level index
+      REAL(wp), DIMENSION(:,:,:)  , INTENT(in   ) ::   pahu, pahv ! eddy diffusivity at u- and v-points  [m2/s]
+      REAL(wp), DIMENSION(:,:,:)  , INTENT(in   ) ::   pgu, pgv   ! tracer gradient at pstep levels
+      REAL(wp), DIMENSION(:,:,:)  , INTENT(in   ) ::   pgui, pgvi ! tracer gradient at top   levels
+      REAL(wp), DIMENSION(:,:,:,:), INTENT(in   ) ::   pt         ! before tracer fields
+      REAL(wp), DIMENSION(:,:,:,:), INTENT(inout) ::   pt_rhs     ! tracer trend
+      !!
+      CALL tra_ldf_lap_t( kt, Kmm, kit000, cdtype, pahu, pahv, is_tile(pahu),                            &
+      &                                            pgu , pgv , is_tile(pgu) , pgui, pgvi, is_tile(pgui), &
+      &                                            pt, is_tile(pt), pt_rhs, is_tile(pt_rhs), kjpt, kpass )
+   END SUBROUTINE tra_ldf_lap
+
+
+   SUBROUTINE tra_ldf_lap_t( kt, Kmm, kit000, cdtype, pahu, pahv, ktah,                   &
+      &                                               pgu , pgv , ktg , pgui, pgvi, ktgi, &
+      &                                               pt, ktt, pt_rhs, ktt_rhs, kjpt, kpass )
       !!----------------------------------------------------------------------
       !!                  ***  ROUTINE tra_ldf_lap  ***
@@ -72,26 +95,30 @@
       INTEGER                              , INTENT(in   ) ::   kpass      ! =1/2 first or second passage
       INTEGER                              , INTENT(in   ) ::   Kmm        ! ocean time level index
-      REAL(wp), DIMENSION(jpi,jpj,jpk)     , INTENT(in   ) ::   pahu, pahv ! eddy diffusivity at u- and v-points  [m2/s]
-      REAL(wp), DIMENSION(jpi,jpj    ,kjpt), INTENT(in   ) ::   pgu, pgv   ! tracer gradient at pstep levels
-      REAL(wp), DIMENSION(jpi,jpj,    kjpt), INTENT(in   ) ::   pgui, pgvi ! tracer gradient at top   levels
-      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(in   ) ::   pt         ! before tracer fields
-      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(inout) ::   pt_rhs     ! tracer trend 
-      !
-      INTEGER  ::   ji, jj, jk, jn   ! dummy loop indices
-      REAL(wp) ::   zsign            ! local scalars
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   ztu, ztv, zaheeu, zaheev
-      !!----------------------------------------------------------------------
-      !
-      IF( kt == nit000 .AND. lwp )  THEN
-         WRITE(numout,*)
-         WRITE(numout,*) 'tra_ldf_lap : iso-level laplacian diffusion on ', cdtype, ', pass=', kpass
-         WRITE(numout,*) '~~~~~~~~~~~ '
-      ENDIF
-      !
-      l_hst = .FALSE.
-      l_ptr = .FALSE.
-      IF( cdtype == 'TRA' .AND. ( iom_use( 'sophtldf' ) .OR. iom_use( 'sopstldf' ) ) )     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.
+      INTEGER                              , INTENT(in   ) ::   ktah, ktg, ktgi, ktt, ktt_rhs
+      REAL(wp), DIMENSION(A2D_T(ktah),   JPK)     , INTENT(in   ) ::   pahu, pahv ! eddy diffusivity at u- and v-points  [m2/s]
+      REAL(wp), DIMENSION(A2D_T(ktg),        KJPT), INTENT(in   ) ::   pgu, pgv   ! tracer gradient at pstep levels
+      REAL(wp), DIMENSION(A2D_T(ktgi),       KJPT), INTENT(in   ) ::   pgui, pgvi ! tracer gradient at top   levels
+      REAL(wp), DIMENSION(A2D_T(ktt),    JPK,KJPT), INTENT(in   ) ::   pt         ! before tracer fields
+      REAL(wp), DIMENSION(A2D_T(ktt_rhs),JPK,KJPT), INTENT(inout) ::   pt_rhs     ! tracer trend
+      !
+      INTEGER  ::   ji, jj, jk, jn      ! dummy loop indices
+      INTEGER  ::   isi, iei, isj, iej  ! local integers
+      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( kt == nit000 .AND. lwp )  THEN
+            WRITE(numout,*)
+            WRITE(numout,*) 'tra_ldf_lap : iso-level laplacian diffusion on ', cdtype, ', pass=', kpass
+            WRITE(numout,*) '~~~~~~~~~~~ '
+         ENDIF
+         !
+         l_hst = .FALSE.
+         l_ptr = .FALSE.
+         IF( cdtype == 'TRA' .AND. ( iom_use( 'sophtldf' ) .OR. iom_use( 'sopstldf' ) ) )     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
       !
       !                                !==  Initialization of metric arrays used for all tracers  ==!
@@ -99,5 +126,11 @@
       ELSE                    ;   zsign = -1._wp
       ENDIF
-      DO_3D( 1, 0, 1, 0, 1, jpkm1 )
+
+      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)  ==!
          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)
@@ -108,15 +141,15 @@
          !                          ! =========== !    
          !                               
-         DO_3D( 1, 0, 1, 0, 1, jpkm1 )            !== First derivative (gradient)  ==!
+         DO_3D( nn_hls, nn_hls-1, nn_hls, nn_hls-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( 1, 0, 1, 0 )                              ! bottom
+            DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-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( 1, 0, 1, 0 )
+               DO_2D( nn_hls, nn_hls-1, nn_hls, nn_hls-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) 
@@ -125,5 +158,6 @@
          ENDIF
          !
-         DO_3D( 0, 0, 0, 0, 1, jpkm1 )            !== Second derivative (divergence) added to the general tracer trends  ==!
+         ! NOTE: [tiling-comms-merge] Bounds changed to avoid repeating this calculation for overlapping rows when using tiling
+         DO_3D( isj, iej, isi, iei, 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) )   &
@@ -142,5 +176,5 @@
       !                             ! ==================
       !
-   END SUBROUTINE tra_ldf_lap
+   END SUBROUTINE tra_ldf_lap_t
    
 
@@ -173,17 +207,19 @@
       !
       INTEGER ::   ji, jj, jk, jn   ! dummy loop indices
-      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt) :: zlap         ! laplacian at t-point
-      REAL(wp), DIMENSION(jpi,jpj,    kjpt) :: zglu, zglv   ! bottom GRADh of the laplacian (u- and v-points)
-      REAL(wp), DIMENSION(jpi,jpj,    kjpt) :: zgui, zgvi   ! top    GRADh of the laplacian (u- and v-points)
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk,kjpt) :: zlap         ! laplacian at t-point
+      REAL(wp), DIMENSION(A2D(nn_hls),    kjpt) :: zglu, zglv   ! bottom GRADh of the laplacian (u- and v-points)
+      REAL(wp), DIMENSION(A2D(nn_hls),    kjpt) :: zgui, zgvi   ! top    GRADh of the laplacian (u- and v-points)
       !!---------------------------------------------------------------------
       !
-      IF( kt == kit000 .AND. lwp )  THEN
-         WRITE(numout,*)
-         SELECT CASE ( kldf )
-         CASE ( np_blp    )   ;   WRITE(numout,*) 'tra_ldf_blp : iso-level   bilaplacian operator on ', cdtype
-         CASE ( np_blp_i  )   ;   WRITE(numout,*) 'tra_ldf_blp : iso-neutral bilaplacian operator on ', cdtype, ' (Standard)'
-         CASE ( np_blp_it )   ;   WRITE(numout,*) 'tra_ldf_blp : iso-neutral bilaplacian operator on ', cdtype, ' (triad)'
-         END SELECT
-         WRITE(numout,*) '~~~~~~~~~~~'
+      IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+         IF( kt == kit000 .AND. lwp )  THEN
+            WRITE(numout,*)
+            SELECT CASE ( kldf )
+            CASE ( np_blp    )   ;   WRITE(numout,*) 'tra_ldf_blp : iso-level   bilaplacian operator on ', cdtype
+            CASE ( np_blp_i  )   ;   WRITE(numout,*) 'tra_ldf_blp : iso-neutral bilaplacian operator on ', cdtype, ' (Standard)'
+            CASE ( np_blp_it )   ;   WRITE(numout,*) 'tra_ldf_blp : iso-neutral bilaplacian operator on ', cdtype, ' (triad)'
+            END SELECT
+            WRITE(numout,*) '~~~~~~~~~~~'
+         ENDIF
       ENDIF
 
@@ -200,4 +236,5 @@
       END SELECT
       !
+      ! NOTE: [tiling-comms-merge] Needed for both nn_hls as tra_ldf_iso and tra_ldf_triad have not yet been adjusted to work with nn_hls = 2. In the zps case the lbc_lnk in zps_hde handles this, but in the zco case zlap always needs this lbc_lnk. I did try adjusting the bounds in tra_ldf_iso and tra_ldf_triad so this lbc_lnk was only needed for nn_hls = 1, but this was not correct and I did not have time to figure out why
       CALL lbc_lnk( 'traldf_lap_blp', zlap(:,:,:,:) , 'T', 1.0_wp )     ! Lateral boundary conditions (unchanged sign)
       !                                               ! Partial top/bottom cell: GRADh( zlap )  
Index: /NEMO/trunk/src/OCE/TRA/traldf_triad.F90
===================================================================
--- /NEMO/trunk/src/OCE/TRA/traldf_triad.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/TRA/traldf_triad.F90	(revision 13982)
@@ -13,4 +13,7 @@
    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 domain, ONLY : dom_tile
+   USE domutl, ONLY : is_tile
    USE phycst         ! physical constants
    USE trc_oce        ! share passive tracers/Ocean variables
@@ -33,6 +36,4 @@
    PUBLIC   tra_ldf_triad   ! routine called by traldf.F90
 
-   REAL(wp), DIMENSION(:,:,:), ALLOCATABLE, SAVE ::   zdkt3d   !: vertical tracer gradient at 2 levels
-
    LOGICAL  ::   l_ptr   ! flag to compute poleward transport
    LOGICAL  ::   l_hst   ! flag to compute heat transport
@@ -49,7 +50,30 @@
 CONTAINS
 
-  SUBROUTINE tra_ldf_triad( kt, Kmm, kit000, cdtype, pahu, pahv,               &
-      &                                              pgu , pgv  , pgui, pgvi , &
-      &                                         pt , pt2, pt_rhs, kjpt, kpass )
+   SUBROUTINE tra_ldf_triad( kt, Kmm, kit000, cdtype, pahu, pahv,             &
+      &                                               pgu , pgv , pgui, pgvi, &
+      &                                               pt, pt2, pt_rhs, kjpt, kpass )
+      !!
+      INTEGER                     , INTENT(in   ) ::   kt         ! ocean time-step index
+      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   ) ::   kpass      ! =1/2 first or second passage
+      INTEGER                     , INTENT(in   ) ::   Kmm        ! ocean time level indices
+      REAL(wp), DIMENSION(:,:,:)  , INTENT(in   ) ::   pahu, pahv ! eddy diffusivity at u- and v-points  [m2/s]
+      REAL(wp), DIMENSION(:,:,:)  , INTENT(in   ) ::   pgu , pgv  ! tracer gradient at pstep levels
+      REAL(wp), DIMENSION(:,:,:)  , INTENT(in   ) ::   pgui, pgvi ! tracer gradient at top   levels
+      REAL(wp), DIMENSION(:,:,:,:), INTENT(in   ) ::   pt         ! tracer (kpass=1) or laplacian of tracer (kpass=2)
+      REAL(wp), DIMENSION(:,:,:,:), INTENT(in   ) ::   pt2        ! tracer (only used in kpass=2)
+      REAL(wp), DIMENSION(:,:,:,:), INTENT(inout) ::   pt_rhs     ! tracer trend
+      !!
+      CALL tra_ldf_triad_t( kt, Kmm, kit000, cdtype, pahu, pahv, is_tile(pahu),                            &
+      &                                              pgu , pgv , is_tile(pgu) , pgui, pgvi, is_tile(pgui), &
+      &                                              pt, is_tile(pt), pt2, is_tile(pt2), pt_rhs, is_tile(pt_rhs), kjpt, kpass )
+   END SUBROUTINE tra_ldf_triad
+
+
+  SUBROUTINE tra_ldf_triad_t( kt, Kmm, kit000, cdtype, pahu, pahv, ktah,                   &
+      &                                                pgu , pgv , ktg , pgui, pgvi, ktgi, &
+      &                                                pt, ktt, pt2, ktt2, pt_rhs, ktt_rhs, kjpt, kpass )
       !!----------------------------------------------------------------------
       !!                  ***  ROUTINE tra_ldf_triad  ***
@@ -77,10 +101,11 @@
       INTEGER                              , INTENT(in   ) ::   kpass      ! =1/2 first or second passage
       INTEGER                              , INTENT(in)    ::   Kmm        ! ocean time level indices
-      REAL(wp), DIMENSION(jpi,jpj,jpk)     , INTENT(in   ) ::   pahu, pahv ! eddy diffusivity at u- and v-points  [m2/s]
-      REAL(wp), DIMENSION(jpi,jpj    ,kjpt), INTENT(in   ) ::   pgu , pgv  ! tracer gradient at pstep levels
-      REAL(wp), DIMENSION(jpi,jpj,    kjpt), INTENT(in   ) ::   pgui, pgvi ! tracer gradient at top   levels
-      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(in   ) ::   pt         ! tracer (kpass=1) or laplacian of tracer (kpass=2)
-      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(in   ) ::   pt2        ! tracer (only used in kpass=2)
-      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(inout) ::   pt_rhs     ! tracer trend
+      INTEGER                              , INTENT(in   ) ::   ktah, ktg, ktgi, ktt, ktt2, ktt_rhs
+      REAL(wp), DIMENSION(A2D_T(ktah),   JPK)     , INTENT(in   ) ::   pahu, pahv ! eddy diffusivity at u- and v-points  [m2/s]
+      REAL(wp), DIMENSION(A2D_T(ktg),        KJPT), INTENT(in   ) ::   pgu , pgv  ! tracer gradient at pstep levels
+      REAL(wp), DIMENSION(A2D_T(ktgi),       KJPT), INTENT(in   ) ::   pgui, pgvi ! tracer gradient at top   levels
+      REAL(wp), DIMENSION(A2D_T(ktt),    JPK,KJPT), INTENT(in   ) ::   pt         ! tracer (kpass=1) or laplacian of tracer (kpass=2)
+      REAL(wp), DIMENSION(A2D_T(ktt2),   JPK,KJPT), INTENT(in   ) ::   pt2        ! tracer (only used in kpass=2)
+      REAL(wp), DIMENSION(A2D_T(ktt_rhs),JPK,KJPT), INTENT(inout) ::   pt_rhs     ! tracer trend
       !
       INTEGER  ::  ji, jj, jk, jn   ! dummy loop indices
@@ -94,26 +119,25 @@
       REAL(wp) ::   ze1ur, ze2vr, ze3wr, zdxt, zdyt, zdzt
       REAL(wp) ::   zah, zah_slp, zaei_slp
-      REAL(wp), DIMENSION(jpi,jpj    ) ::   z2d                                              ! 2D workspace
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zdit, zdjt, zftu, zftv, ztfw, zpsi_uw, zpsi_vw   ! 3D     -
+      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
       !!----------------------------------------------------------------------
       !
-      IF( .NOT.ALLOCATED(zdkt3d) )  THEN
-         ALLOCATE( zdkt3d(jpi,jpj,0:1) , STAT=ierr )
-         CALL mpp_sum ( 'traldf_triad', ierr )
-         IF( ierr > 0 )   CALL ctl_stop('STOP', 'tra_ldf_triad: unable to allocate arrays')
-      ENDIF
-     !
-      IF( kpass == 1 .AND. kt == kit000 )  THEN
-         IF(lwp) WRITE(numout,*)
-         IF(lwp) WRITE(numout,*) 'tra_ldf_triad : rotated laplacian diffusion operator on ', cdtype
-         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~~'
-      ENDIF
-      !   
-      l_hst = .FALSE.
-      l_ptr = .FALSE.
-      IF( cdtype == 'TRA' ) THEN
-         IF( iom_use( 'sophtldf' ) .OR. iom_use( 'sopstldf') )      l_ptr = .TRUE. 
-         IF( iom_use("uadv_heattr") .OR. iom_use("vadv_heattr") .OR.                   &
-         &   iom_use("uadv_salttr") .OR. iom_use("vadv_salttr")  )   l_hst = .TRUE.
+      IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+         IF( kpass == 1 .AND. kt == kit000 )  THEN
+            IF(lwp) WRITE(numout,*)
+            IF(lwp) WRITE(numout,*) 'tra_ldf_triad : rotated laplacian diffusion operator on ', cdtype
+            IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~~'
+         ENDIF
+         !
+         l_hst = .FALSE.
+         l_ptr = .FALSE.
+         IF( cdtype == 'TRA' ) THEN
+            IF( iom_use( 'sophtldf' ) .OR. iom_use( 'sopstldf') )      l_ptr = .TRUE.
+            IF( iom_use("uadv_heattr") .OR. iom_use("vadv_heattr") .OR.                   &
+            &   iom_use("uadv_salttr") .OR. iom_use("vadv_salttr")  )   l_hst = .TRUE.
+         ENDIF
       ENDIF
       !
@@ -128,27 +152,23 @@
       IF( kpass == 1 ) THEN         !==  first pass only  and whatever the tracer is  ==!
          !
-         akz     (:,:,:) = 0._wp      
-         ah_wslp2(:,:,:) = 0._wp
-         IF( ln_ldfeiv_dia ) THEN
-            zpsi_uw(:,:,:) = 0._wp
-            zpsi_vw(:,:,:) = 0._wp
-         ENDIF
+         DO_3D( 0, 0, 0, 0, 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( 1, 0, 1, 0, 1, jpkm1 )
-                  ze3wr = 1._wp / e3w(ji+ip,jj,jk+kp,Kmm)
-                  zbu   = e1e2u(ji,jj) * e3u(ji,jj,jk,Kmm)
-                  zah   = 0.25_wp * pahu(ji,jj,jk)
-                  zslope_skew = triadi_g(ji+ip,jj,jk,1-ip,kp)
+               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+1,jj,jk,Kmm) - gdept(ji,jj,jk,Kmm) ) * r1_e1u(ji,jj) * umask(ji,jj,jk+kp)
+                  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+ip,jj,jk+kp) = ah_wslp2(ji+ip,jj,jk+kp) + zah * zbu * ze3wr * r1_e1e2t(ji+ip,jj) * zslope2
-                  akz     (ji+ip,jj,jk+kp) = akz     (ji+ip,jj,jk+kp) + zah * r1_e1u(ji,jj)       &
-                     &                                                      * r1_e1u(ji,jj) * umask(ji,jj,jk+kp)
+                  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)
                      !
-                 IF( ln_ldfeiv_dia )   zpsi_uw(ji,jj,jk+kp) = zpsi_uw(ji,jj,jk+kp)   &
-                     &                                       + 0.25_wp * aeiu(ji,jj,jk) * e2u(ji,jj) * zslope_skew
                END_3D
             END DO
@@ -157,19 +177,17 @@
          DO jp = 0, 1                            ! j-k triads 
             DO kp = 0, 1
-               DO_3D( 1, 0, 1, 0, 1, jpkm1 )
-                  ze3wr = 1.0_wp / e3w(ji,jj+jp,jk+kp,Kmm)
-                  zbv   = e1e2v(ji,jj) * e3v(ji,jj,jk,Kmm)
-                  zah   = 0.25_wp * pahv(ji,jj,jk)
-                  zslope_skew = triadj_g(ji,jj+jp,jk,1-jp,kp)
+               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+1,jk,Kmm) - gdept(ji,jj,jk,Kmm) ) * r1_e2v(ji,jj) * vmask(ji,jj,jk+kp)
+                  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+jp,jk+kp) = ah_wslp2(ji,jj+jp,jk+kp) + zah * zbv * ze3wr * r1_e1e2t(ji,jj+jp) * zslope2
-                  akz     (ji,jj+jp,jk+kp) = akz     (ji,jj+jp,jk+kp) + zah * r1_e2v(ji,jj)     &
-                     &                                                      * r1_e2v(ji,jj) * vmask(ji,jj,jk+kp)
+                  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)
                   !
-                  IF( ln_ldfeiv_dia )   zpsi_vw(ji,jj,jk+kp) = zpsi_vw(ji,jj,jk+kp)   &
-                     &                                       + 0.25 * aeiv(ji,jj,jk) * e1v(ji,jj) * zslope_skew
                END_3D
             END DO
@@ -179,5 +197,5 @@
             !
             IF( ln_traldf_blp ) THEN                ! bilaplacian operator
-               DO_3D( 1, 0, 1, 0, 2, jpkm1 )
+               DO_3D( 0, 0, 0, 0, 2, jpkm1 )
                   akz(ji,jj,jk) = 16._wp           &
                      &   * ah_wslp2   (ji,jj,jk)   &
@@ -187,5 +205,5 @@
                END_3D
             ELSEIF( ln_traldf_lap ) THEN              ! laplacian operator
-               DO_3D( 1, 0, 1, 0, 2, jpkm1 )
+               DO_3D( 0, 0, 0, 0, 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  )
@@ -195,8 +213,32 @@
            !
          ELSE                                    ! 33 flux set to zero with akz=ah_wslp2 ==>> computed in full implicit
-            akz(:,:,:) = ah_wslp2(:,:,:)      
-         ENDIF
-         !
-         IF( ln_ldfeiv_dia .AND. cdtype == 'TRA' )   CALL ldf_eiv_dia( zpsi_uw, zpsi_vw, Kmm )
+            DO_3D( 0, 0, 0, 0, 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
+         ENDIF
          !
       ENDIF                                  !==  end 1st pass only  ==!
@@ -234,9 +276,14 @@
          DO jk = 1, jpkm1
             !                    !==  Vertical tracer gradient at level jk and jk+1
-            zdkt3d(:,:,1) = ( pt(:,:,jk,jn) - pt(:,:,jk+1,jn) ) * tmask(:,:,jk+1)
+            DO_2D( 1, 1, 1, 1 )
+               zdkt3d(ji,jj,1) = ( pt(ji,jj,jk,jn) - pt(ji,jj,jk+1,jn) ) * tmask(ji,jj,jk+1)
+            END_2D
             !
             !                    ! surface boundary condition: zdkt3d(jk=0)=zdkt3d(jk=1)
             IF( jk == 1 ) THEN   ;   zdkt3d(:,:,0) = zdkt3d(:,:,1)
-            ELSE                 ;   zdkt3d(:,:,0) = ( pt(:,:,jk-1,jn) - pt(:,:,jk,jn) ) * tmask(:,:,jk)
+            ELSE
+               DO_2D( 1, 1, 1, 1 )
+                  zdkt3d(ji,jj,0) = ( pt(ji,jj,jk-1,jn) - pt(ji,jj,jk,jn) ) * tmask(ji,jj,jk)
+               END_2D
             ENDIF
             !
@@ -380,5 +427,5 @@
       END DO                                                      ! end tracer loop
       !                                                           ! ===============
-   END SUBROUTINE tra_ldf_triad
+   END SUBROUTINE tra_ldf_triad_t
 
    !!==============================================================================
Index: /NEMO/trunk/src/OCE/TRA/tramle.F90
===================================================================
--- /NEMO/trunk/src/OCE/TRA/tramle.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/TRA/tramle.F90	(revision 13982)
@@ -79,11 +79,11 @@
       !!             Fox-Kemper and Ferrari, JPO, 38, 1166-1179, 2008
       !!----------------------------------------------------------------------
-      INTEGER                         , INTENT(in   ) ::   kt         ! ocean time-step index
-      INTEGER                         , INTENT(in   ) ::   kit000     ! first time step index
-      INTEGER                         , INTENT(in   ) ::   Kmm        ! ocean time level index
-      CHARACTER(len=3)                , INTENT(in   ) ::   cdtype     ! =TRA or TRC (tracer indicator)
-      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                     , INTENT(in   ) ::   kt         ! ocean time-step index
+      INTEGER                     , INTENT(in   ) ::   kit000     ! first time step index
+      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
       !
       INTEGER  ::   ji, jj, jk          ! dummy loop indices
@@ -91,12 +91,17 @@
       REAL(wp) ::   zcuw, zmuw, zc      ! local scalar
       REAL(wp) ::   zcvw, zmvw          !   -      -
-      INTEGER , DIMENSION(jpi,jpj)     :: inml_mle
-      REAL(wp), DIMENSION(jpi,jpj)     :: zpsim_u, zpsim_v, zmld, zbm, zhu, zhv, zn2, zLf_NH, zLf_MH
-      REAL(wp), DIMENSION(jpi,jpj,jpk) :: zpsi_uw, zpsi_vw
+      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),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
       !!----------------------------------------------------------------------
       !
       !                                      !==  MLD used for MLE  ==!
       !                                                ! compute from the 10m density to deal with the diurnal cycle
-      inml_mle(:,:) = mbkt(:,:) + 1                    ! init. to number of ocean w-level (T-level + 1)
+      DO_2D( 1, 1, 1, 1 )
+         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)
@@ -135,5 +140,7 @@
       END SELECT
       !                                                ! convert density into buoyancy
-      zbm(:,:) = + grav * zbm(:,:) / MAX( e3t(:,:,1,Kmm), zmld(:,:) )
+      DO_2D( 1, 1, 1, 1 )
+         zbm(ji,jj) = + grav * zbm(ji,jj) / MAX( e3t(ji,jj,1,Kmm), zmld(ji,jj) )
+      END_2D
       !
       !
@@ -206,16 +213,27 @@
       END DO
 
+      ! TEMP: [tiling] These changes not necessary if using XIOS (subdomain support)
       IF( cdtype == 'TRA') THEN              !==  outputs  ==!
-         !
-         zLf_NH(:,:) = SQRT( rb_c * zmld(:,:) ) * r1_ft(:,:)      ! Lf = N H / f
-         CALL iom_put( "Lf_NHpf" , zLf_NH  )    ! Lf = N H / f
+         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
+         !
+         DO_2D( 0, 0, 0, 0 )
+            zLf_NH(ji,jj) = SQRT( rb_c * zmld(ji,jj) ) * r1_ft(ji,jj)      ! Lf = N H / f
+         END_2D
          !
          ! divide by cross distance to give streamfunction with dimensions m^2/s
-         DO jk = 1, ikmax+1
-            zpsi_uw(:,:,jk) = zpsi_uw(:,:,jk) * r1_e2u(:,:)
-            zpsi_vw(:,:,jk) = zpsi_vw(:,:,jk) * r1_e1v(:,:)
-         END DO
-         CALL iom_put( "psiu_mle", zpsi_uw )    ! i-mle streamfunction
-         CALL iom_put( "psiv_mle", zpsi_vw )    ! j-mle streamfunction
+         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)
+         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
       ENDIF
       !
@@ -283,5 +301,5 @@
             IF( ierr /= 0 )   CALL ctl_stop( 'tra_adv_mle_init: failed to allocate arrays' )
             z1_t2 = 1._wp / ( rn_time * rn_time )
-            DO_2D( 0, 1, 0, 1 )                      ! "coriolis+ time^-1" at u- & v-points
+            DO_2D( nn_hls-1, nn_hls, nn_hls-1, nn_hls )                      ! "coriolis+ time^-1" at u- & v-points
                zfu = ( ff_f(ji,jj) + ff_f(ji,jj-1) ) * 0.5_wp
                zfv = ( ff_f(ji,jj) + ff_f(ji-1,jj) ) * 0.5_wp
@@ -289,5 +307,5 @@
                rfv(ji,jj) = SQRT(  zfv * zfv + z1_t2 )
             END_2D
-            CALL lbc_lnk_multi( 'tramle', rfu, 'U', 1.0_wp , rfv, 'V', 1.0_wp )
+            IF (nn_hls.EQ.1) CALL lbc_lnk_multi( 'tramle', rfu, 'U', 1.0_wp , rfv, 'V', 1.0_wp )
             !
          ELSEIF( nn_mle == 1 ) THEN           ! MLE array allocation & initialisation
Index: /NEMO/trunk/src/OCE/TRA/tranpc.F90
===================================================================
--- /NEMO/trunk/src/OCE/TRA/tranpc.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/TRA/tranpc.F90	(revision 13982)
@@ -17,4 +17,6 @@
    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 domain, ONLY : dom_tile
    USE phycst         ! physical constants
    USE zdf_oce        ! ocean vertical physics
@@ -32,4 +34,6 @@
 
    PUBLIC   tra_npc    ! routine called by step.F90
+
+   INTEGER  ::   nnpcc        ! number of statically instable water column
 
    !! * Substitutions
@@ -64,5 +68,4 @@
       !
       INTEGER  ::   ji, jj, jk   ! dummy loop indices
-      INTEGER  ::   inpcc        ! number of statically instable water column
       INTEGER  ::   jiter, ikbot, ikp, ikup, ikdown, ilayer, ik_low   ! local integers
       LOGICAL  ::   l_bottom_reached, l_column_treated
@@ -70,12 +73,13 @@
       REAL(wp) ::   zsa, zbeta, zsum_sali, zsum_beta, zbw, zrw, z1_rDt
       REAL(wp), PARAMETER ::   zn2_zero = 1.e-14_wp             ! acceptance criteria for neutrality (N2==0)
-      REAL(wp), DIMENSION(        jpk     )   ::   zvn2         ! vertical profile of N2 at 1 given point...
-      REAL(wp), DIMENSION(        jpk,jpts)   ::   zvts, zvab   ! vertical profile of T & S , and  alpha & betaat 1 given point
-      REAL(wp), DIMENSION(jpi,jpj,jpk     )   ::   zn2          ! N^2 
-      REAL(wp), DIMENSION(jpi,jpj,jpk,jpts)   ::   zab          ! alpha and beta
+      REAL(wp), DIMENSION(    jpk     )   ::   zvn2             ! vertical profile of N2 at 1 given point...
+      REAL(wp), DIMENSION(    jpk,jpts)   ::   zvts, zvab       ! vertical profile of T & S , and  alpha & betaat 1 given point
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk     )   ::   zn2              ! N^2
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk,jpts)   ::   zab              ! alpha and beta
       REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) ::   ztrdt, ztrds ! 3D workspace
       !
       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"
       !!----------------------------------------------------------------------
@@ -87,5 +91,5 @@
          IF( l_trdtra )   THEN                    !* Save initial after fields
             ALLOCATE( ztrdt(jpi,jpj,jpk) , ztrds(jpi,jpj,jpk) )
-            ztrdt(:,:,:) = pts(:,:,:,jp_tem,Kaa) 
+            ztrdt(:,:,:) = pts(:,:,:,jp_tem,Kaa)
             ztrds(:,:,:) = pts(:,:,:,jp_sal,Kaa)
          ENDIF
@@ -101,7 +105,13 @@
          CALL bn2    ( pts(:,:,:,:,Kaa), zab, zn2, Kmm )    ! after Brunt-Vaisala  (given on W-points)
          !
-         inpcc = 0
-         !
-         DO_2D( 0, 0, 0, 0 )                                ! interior column only
+         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
+         !
+         ! NOTE: [tiling-comms-merge] Bounds changed to avoid repeating this calculation for overlapping rows when using tiling
+         DO_2D( isj, iej, isi, iei )                        ! interior column only
             !
             IF( tmask(ji,jj,2) == 1 ) THEN      ! At least 2 ocean points
@@ -160,5 +170,5 @@
                         ENDIF
                         !
-                        IF( jiter == 1 )   inpcc = inpcc + 1 
+                        IF( jiter == 1 )   nnpcc = nnpcc + 1
                         !
                         IF( lp_monitor_point )   WRITE(numout, *) 'Negative N2 at ikp =',ikp,' for layer #', ilayer
@@ -310,9 +320,9 @@
          ENDIF
          !
-         CALL lbc_lnk_multi( 'tranpc', pts(:,:,:,jp_tem,Kaa), 'T', 1.0_wp, pts(:,:,:,jp_sal,Kaa), 'T', 1.0_wp )
-         !
-         IF( lwp .AND. l_LB_debug ) THEN
-            WRITE(numout,*) 'Exiting tra_npc , kt = ',kt,', => numb. of statically instable water-columns: ', inpcc
-            WRITE(numout,*)
+         IF( ntile == 0 .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
+               WRITE(numout,*)
+            ENDIF
          ENDIF
          !
Index: /NEMO/trunk/src/OCE/TRA/traqsr.F90
===================================================================
--- /NEMO/trunk/src/OCE/TRA/traqsr.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/TRA/traqsr.F90	(revision 13982)
@@ -22,4 +22,5 @@
    USE phycst         ! physical constants
    USE dom_oce        ! ocean space and time domain
+   USE domain, ONLY : dom_tile
    USE sbc_oce        ! surface boundary condition: ocean
    USE trc_oce        ! share SMS/Ocean variables
@@ -107,5 +108,5 @@
       !
       INTEGER  ::   ji, jj, jk               ! dummy loop indices
-      INTEGER  ::   irgb                     ! local integers
+      INTEGER  ::   irgb, isi, iei, isj, iej ! local integers
       REAL(wp) ::   zchl, zcoef, z1_2        ! local scalars
       REAL(wp) ::   zc0 , zc1 , zc2 , zc3    !    -         -
@@ -120,12 +121,14 @@
       IF( ln_timing )   CALL timing_start('tra_qsr')
       !
-      IF( kt == nit000 ) THEN
-         IF(lwp) WRITE(numout,*)
-         IF(lwp) WRITE(numout,*) 'tra_qsr : penetration of the surface solar radiation'
-         IF(lwp) WRITE(numout,*) '~~~~~~~'
+      IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+         IF( kt == nit000 ) THEN
+            IF(lwp) WRITE(numout,*)
+            IF(lwp) WRITE(numout,*) 'tra_qsr : penetration of the surface solar radiation'
+            IF(lwp) WRITE(numout,*) '~~~~~~~'
+         ENDIF
       ENDIF
       !
       IF( l_trdtra ) THEN      ! trends diagnostic: save the input temperature trend
-         ALLOCATE( ztrdt(jpi,jpj,jpk) ) 
+         ALLOCATE( ztrdt(jpi,jpj,jpk) )
          ztrdt(:,:,:) = pts(:,:,:,jp_tem,Krhs)
       ENDIF
@@ -134,16 +137,28 @@
       !                         !  before qsr induced heat content  !
       !                         !-----------------------------------!
+      ! NOTE: [tiling-comms-merge] Many DO loop bounds changed (probably more than necessary) to avoid changing results when using tiling. Some bounds were also adjusted to account for those changed in tra_atf
+      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. iom_varid( numror, 'qsr_hc_b', ldstop = .FALSE. ) > 0  .AND. .NOT.l_1st_euler ) THEN    ! read in restart
-            IF(lwp) WRITE(numout,*) '          nit000-1 qsr tracer content forcing field read in the restart file'
             z1_2 = 0.5_wp
-            CALL iom_get( numror, jpdom_auto, 'qsr_hc_b', qsr_hc_b )   ! before heat content trend due to Qsr flux
+            IF( ntile == 0 .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
+            ENDIF
          ELSE                                           ! No restart or restart not found: Euler forward time stepping
             z1_2 = 1._wp
-            qsr_hc_b(:,:,:) = 0._wp
+            DO_3D( isj, iej, isi, iei, 1, jpk )
+               qsr_hc_b(ji,jj,jk) = 0._wp
+            END_3D
          ENDIF
       ELSE                             !==  Swap of qsr heat content  ==!
          z1_2 = 0.5_wp
-         qsr_hc_b(:,:,:) = qsr_hc(:,:,:)
+         DO_3D( isj, iej, isi, iei, 1, jpk )
+            qsr_hc_b(ji,jj,jk) = qsr_hc(ji,jj,jk)
+         END_3D
       ENDIF
       !
@@ -154,16 +169,20 @@
       CASE( np_BIO )                   !==  bio-model fluxes  ==!
          !
-         DO jk = 1, nksr
-            qsr_hc(:,:,jk) = r1_rho0_rcp * ( etot3(:,:,jk) - etot3(:,:,jk+1) )
-         END DO
+         DO_3D( isj, iej, isi, iei, 1, nksr )
+            qsr_hc(ji,jj,jk) = r1_rho0_rcp * ( etot3(ji,jj,jk) - etot3(ji,jj,jk+1) )
+         END_3D
          !
       CASE( np_RGB , np_RGBc )         !==  R-G-B fluxes  ==!
          !
-         ALLOCATE( ze0 (jpi,jpj)           , ze1 (jpi,jpj) ,   &
-            &      ze2 (jpi,jpj)           , ze3 (jpi,jpj) ,   &
-            &      ztmp3d(jpi,jpj,nksr + 1)                     )
+         ALLOCATE( ze0 (A2D(nn_hls))           , ze1 (A2D(nn_hls)) ,   &
+            &      ze2 (A2D(nn_hls))           , ze3 (A2D(nn_hls)) ,   &
+            &      ztmp3d(A2D(nn_hls),nksr + 1)                     )
          !
          IF( nqsr == np_RGBc ) THEN          !*  Variable Chlorophyll
-            CALL fld_read( kt, 1, sf_chl )         ! Read Chl data and provides it at the current time step
+            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
+               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
+            ENDIF
             !
             ! Separation in R-G-B depending on the surface Chl
@@ -172,5 +191,5 @@
             ! most expensive calculations)
             !
-            DO_2D( 0, 0, 0, 0 )
+            DO_2D( isj, iej, isi, iei )
                        ! zlogc = log(zchl)
                zlogc = LOG ( MIN( 10. , MAX( 0.03, sf_chl(1)%fnow(ji,jj,1) ) ) )     
@@ -191,5 +210,5 @@
             
 !
-            DO_3D( 0, 0, 0, 0, 1, nksr + 1 )
+            DO_3D( isj, iej, isi, iei, 1, nksr + 1 )
                ! zchl    = ALOG( ze0(ji,jj) )
                zlogc = ze0(ji,jj)
@@ -216,10 +235,10 @@
             zlui = 41 + 20.*LOG10(zchl) + 1.e-15
             DO jk = 1, nksr + 1
-               ztmp3d(:,:,jk) = zlui 
+               ztmp3d(:,:,jk) = zlui
             END DO
          ENDIF
          !
          zcoef  = ( 1. - rn_abs ) / 3._wp    !* surface equi-partition in R-G-B
-         DO_2D( 0, 0, 0, 0 )
+         DO_2D( isj, iej, isi, iei )
             ze0(ji,jj) = rn_abs * qsr(ji,jj)
             ze1(ji,jj) = zcoef  * qsr(ji,jj)
@@ -232,5 +251,5 @@
          !
          !                                    !* interior equi-partition in R-G-B depending on vertical profile of Chl
-         DO_3D( 0, 0, 0, 0, 2, nksr + 1 )
+         DO_3D( isj, iej, isi, iei, 2, nksr + 1 )
             ze3t = e3t(ji,jj,jk-1,Kmm)
             irgb = NINT( ztmp3d(ji,jj,jk) )
@@ -246,5 +265,5 @@
          END_3D
          !
-         DO_3D( 0, 0, 0, 0, 1, nksr )          !* now qsr induced heat content
+         DO_3D( isj, iej, isi, iei, 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
@@ -256,5 +275,5 @@
          zz0 =        rn_abs   * r1_rho0_rcp      ! surface equi-partition in 2-bands
          zz1 = ( 1. - rn_abs ) * r1_rho0_rcp
-         DO_3D( 0, 0, 0, 0, 1, nksr )             ! solar heat absorbed at T-point in the top 400m 
+         DO_3D( isj, iej, isi, iei, 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 )
@@ -274,24 +293,28 @@
       !
       ! sea-ice: store the 1st ocean level attenuation coefficient
-      DO_2D( 0, 0, 0, 0 )
+      DO_2D( isj, iej, isi, iei )
          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
          ENDIF
       END_2D
-      CALL lbc_lnk( 'traqsr', fraqsr_1lev(:,:), 'T', 1._wp )
-      !
-      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
-      !
-      IF( lrst_oce ) THEN     ! write in the ocean restart file
-         CALL iom_rstput( kt, nitrst, numrow, 'qsr_hc_b'   , qsr_hc      )
-         CALL iom_rstput( kt, nitrst, numrow, 'fraqsr_1lev', fraqsr_1lev ) 
+      !
+      ! 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( lrst_oce ) THEN     ! write in the ocean restart file
+            CALL iom_rstput( kt, nitrst, numrow, 'qsr_hc_b'   , qsr_hc      )
+            CALL iom_rstput( kt, nitrst, numrow, 'fraqsr_1lev', fraqsr_1lev )
+         ENDIF
       ENDIF
       !
@@ -299,5 +322,5 @@
          ztrdt(:,:,:) = pts(:,:,:,jp_tem,Krhs) - ztrdt(:,:,:)
          CALL trd_tra( kt, Kmm, Krhs, 'TRA', jp_tem, jptra_qsr, ztrdt )
-         DEALLOCATE( ztrdt ) 
+         DEALLOCATE( ztrdt )
       ENDIF
       !                       ! print mean trends (used for debugging)
Index: /NEMO/trunk/src/OCE/TRA/trasbc.F90
===================================================================
--- /NEMO/trunk/src/OCE/TRA/trasbc.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/TRA/trasbc.F90	(revision 13982)
@@ -76,7 +76,7 @@
       REAL(wp), DIMENSION(jpi,jpj,jpk,jpts,jpt), INTENT(inout) :: pts        ! active tracers and RHS of tracer equation
       !
-      INTEGER  ::   ji, jj, jk, jn              ! dummy loop indices  
-      INTEGER  ::   ikt, ikb                    ! local integers
-      REAL(wp) ::   zfact, z1_e3t, zdep, ztim   ! local scalar
+      INTEGER  ::   ji, jj, jk, jn               ! dummy loop indices
+      INTEGER  ::   ikt, ikb, isi, iei, isj, iej ! local integers
+      REAL(wp) ::   zfact, z1_e3t, zdep, ztim    ! local scalar
       REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) ::  ztrdt, ztrds
       !!----------------------------------------------------------------------
@@ -84,20 +84,30 @@
       IF( ln_timing )   CALL timing_start('tra_sbc')
       !
-      IF( kt == nit000 ) THEN
-         IF(lwp) WRITE(numout,*)
-         IF(lwp) WRITE(numout,*) 'tra_sbc : TRAcer Surface Boundary Condition'
-         IF(lwp) WRITE(numout,*) '~~~~~~~ '
+      IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+         IF( kt == nit000 ) THEN
+            IF(lwp) WRITE(numout,*)
+            IF(lwp) WRITE(numout,*) 'tra_sbc : TRAcer Surface Boundary Condition'
+            IF(lwp) WRITE(numout,*) '~~~~~~~ '
+         ENDIF
       ENDIF
       !
       IF( l_trdtra ) THEN                    !* Save ta and sa trends
-         ALLOCATE( ztrdt(jpi,jpj,jpk) , ztrds(jpi,jpj,jpk) ) 
+         ALLOCATE( ztrdt(jpi,jpj,jpk), ztrds(jpi,jpj,jpk) )
          ztrdt(:,:,:) = pts(:,:,:,jp_tem,Krhs)
          ztrds(:,:,:) = pts(:,:,:,jp_sal,Krhs)
       ENDIF
       !
+      ! NOTE: [tiling-comms-merge] Many DO loop bounds changed to avoid changing results when using tiling. Some bounds were also adjusted to account for those changed in tra_atf
+      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
-         qns(:,:) = qns(:,:) + qsr(:,:)      ! total heat flux in qns
-         qsr(:,:) = 0._wp                     ! qsr set to zero
+         DO_2D( isj, iej, isi, iei )
+            qns(ji,jj) = qns(ji,jj) + qsr(ji,jj)      ! total heat flux in qns
+            qsr(ji,jj) = 0._wp                        ! qsr set to zero
+         END_2D
       ENDIF
 
@@ -109,34 +119,43 @@
          IF( ln_rstart .AND.    &               ! Restart: read in restart file
               & iom_varid( numror, 'sbc_hc_b', ldstop = .FALSE. ) > 0 ) THEN
-            IF(lwp) WRITE(numout,*) '          nit000-1 sbc tracer content field read in the restart file'
             zfact = 0.5_wp
-            sbc_tsc(:,:,:) = 0._wp
-            CALL iom_get( numror, jpdom_auto, 'sbc_hc_b', sbc_tsc_b(:,:,jp_tem) )   ! before heat content sbc trend
-            CALL iom_get( numror, jpdom_auto, 'sbc_sc_b', sbc_tsc_b(:,:,jp_sal) )   ! before salt content sbc trend
+            IF( ntile == 0 .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
+               CALL iom_get( numror, jpdom_auto, 'sbc_hc_b', sbc_tsc_b(:,:,jp_tem) )   ! before heat content sbc trend
+               CALL iom_get( numror, jpdom_auto, 'sbc_sc_b', sbc_tsc_b(:,:,jp_sal) )   ! before salt content sbc trend
+            ENDIF
          ELSE                                   ! No restart or restart not found: Euler forward time stepping
             zfact = 1._wp
-            sbc_tsc(:,:,:) = 0._wp
-            sbc_tsc_b(:,:,:) = 0._wp
+            DO_2D( isj, iej, isi, iei )
+               sbc_tsc(ji,jj,:) = 0._wp
+               sbc_tsc_b(ji,jj,:) = 0._wp
+            END_2D
          ENDIF
       ELSE                                !* other time-steps: swap of forcing fields
          zfact = 0.5_wp
-         sbc_tsc_b(:,:,:) = sbc_tsc(:,:,:)
+         DO_2D( isj, iej, isi, iei )
+            sbc_tsc_b(ji,jj,:) = sbc_tsc(ji,jj,:)
+         END_2D
       ENDIF
       !                             !==  Now sbc tracer content fields  ==!
-      DO_2D( 0, 1, 0, 0 )
+      DO_2D( isj, iej, isi, iei )
          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( 0, 1, 0, 0 )                    !==>> add concentration/dilution effect due to constant volume cell
+         DO_2D( isj, iej, isi, iei )                    !==>> 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( 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) )
+         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
       ENDIF
       !
       DO jn = 1, jpts               !==  update tracer trend  ==!
-         DO_2D( 0, 1, 0, 0 )
+         ! NOTE: [tiling-comms-merge] This looped over nn_hls, which changes the results when using tiling
+         DO_2D( 0, 0, 0, 0 )
             pts(ji,jj,1,jn,Krhs) = pts(ji,jj,1,jn,Krhs) + zfact * ( sbc_tsc_b(ji,jj,jn) + sbc_tsc(ji,jj,jn) )    &
                &                                                / e3t(ji,jj,1,Kmm)
@@ -144,7 +163,9 @@
       END DO
       !                  
-      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) )
-         CALL iom_rstput( kt, nitrst, numrow, 'sbc_sc_b', sbc_tsc(:,:,jp_sal) )
+      IF( ntile == 0 .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) )
+            CALL iom_rstput( kt, nitrst, numrow, 'sbc_sc_b', sbc_tsc(:,:,jp_sal) )
+         ENDIF
       ENDIF
       !
@@ -155,5 +176,5 @@
       IF( ln_rnf ) THEN         ! input of heat and salt due to river runoff 
          zfact = 0.5_wp
-         DO_2D( 0, 1, 0, 0 )
+         DO_2D( 0, 0, 0, 0 )
             IF( rnf(ji,jj) /= 0._wp ) THEN
                zdep = zfact / h_rnf(ji,jj)
@@ -168,6 +189,8 @@
       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( 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 defined key_asminc
@@ -180,5 +203,5 @@
       	 !
          IF( ln_linssh ) THEN 
-            DO_2D( 0, 1, 0, 0 )
+            DO_2D( 0, 0, 0, 0 )
                ztim = ssh_iau(ji,jj) / e3t(ji,jj,1,Kmm)
                pts(ji,jj,1,jp_tem,Krhs) = pts(ji,jj,1,jp_tem,Krhs) + pts(ji,jj,1,jp_tem,Kmm) * ztim
@@ -186,5 +209,5 @@
             END_2D
          ELSE
-            DO_2D( 0, 1, 0, 0 )
+            DO_2D( 0, 0, 0, 0 )
                ztim = ssh_iau(ji,jj) / ( ht(ji,jj) + 1. - ssmask(ji, jj) )
                pts(ji,jj,:,jp_tem,Krhs) = pts(ji,jj,:,jp_tem,Krhs) + pts(ji,jj,:,jp_tem,Kmm) * ztim
@@ -202,5 +225,5 @@
          CALL trd_tra( kt, Kmm, Krhs, 'TRA', jp_tem, jptra_nsr, ztrdt )
          CALL trd_tra( kt, Kmm, Krhs, 'TRA', jp_sal, jptra_nsr, ztrds )
-         DEALLOCATE( ztrdt , ztrds ) 
+         DEALLOCATE( ztrdt , ztrds )
       ENDIF
       !
Index: /NEMO/trunk/src/OCE/TRA/trazdf.F90
===================================================================
--- /NEMO/trunk/src/OCE/TRA/trazdf.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/TRA/trazdf.F90	(revision 13982)
@@ -13,5 +13,5 @@
    !!----------------------------------------------------------------------
    USE oce            ! ocean dynamics and tracers variables
-   USE dom_oce        ! ocean space and time domain variables 
+   USE dom_oce        ! ocean space and time domain variables
    USE domvvl         ! variable volume
    USE phycst         ! physical constant
@@ -55,5 +55,5 @@
       REAL(wp), DIMENSION(jpi,jpj,jpk,jpts,jpt), INTENT(inout) :: pts                 ! active tracers and RHS of tracer equation
       !
-      INTEGER  ::   jk   ! Dummy loop indices
+      INTEGER  ::   ji, jj, jk   ! Dummy loop indices
       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::   ztrdt, ztrds   ! 3D workspace
       !!---------------------------------------------------------------------
@@ -62,11 +62,13 @@
       !
       IF( kt == nit000 )  THEN
-         IF(lwp)WRITE(numout,*)
-         IF(lwp)WRITE(numout,*) 'tra_zdf : implicit vertical mixing on T & S'
-         IF(lwp)WRITE(numout,*) '~~~~~~~ '
+         IF( ntile == 0 .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'
+            IF(lwp)WRITE(numout,*) '~~~~~~~ '
+         ENDIF
       ENDIF
       !
       IF( l_trdtra )   THEN                  !* Save ta and sa trends
-         ALLOCATE( ztrdt(jpi,jpj,jpk) , ztrds(jpi,jpj,jpk) )
+         ALLOCATE( ztrdt(jpi,jpj,jpk), ztrds(jpi,jpj,jpk) )
          ztrdt(:,:,:) = pts(:,:,:,jp_tem,Kaa)
          ztrds(:,:,:) = pts(:,:,:,jp_sal,Kaa)
@@ -80,9 +82,9 @@
       ! JMM avoid negative salinities near river outlet ! Ugly fix
       ! JMM : restore negative salinities to small salinities:
-      WHERE( pts(:,:,:,jp_sal,Kaa) < 0._wp )   pts(:,:,:,jp_sal,Kaa) = 0.1_wp
+      WHERE( pts(A2D(0),:,jp_sal,Kaa) < 0._wp )   pts(A2D(0),:,jp_sal,Kaa) = 0.1_wp
 !!gm
 
       IF( l_trdtra )   THEN                      ! save the vertical diffusive trends for further diagnostics
-         DO jk = 1, jpkm1
+         DO jk = 1, jpk
             ztrdt(:,:,jk) = (   (  pts(:,:,jk,jp_tem,Kaa)*e3t(:,:,jk,Kaa)     &
                &                 - pts(:,:,jk,jp_tem,Kbb)*e3t(:,:,jk,Kbb)  )  &
@@ -94,4 +96,5 @@
                &          - ztrds(:,:,jk)
          END DO
+         ! NOTE: [tiling-comms-merge] The diagnostic results change along the north fold if this is removed
 !!gm this should be moved in trdtra.F90 and done on all trends
          CALL lbc_lnk_multi( 'trazdf', ztrdt, 'T', 1.0_wp , ztrds, 'T', 1.0_wp )
@@ -140,5 +143,5 @@
       INTEGER  ::  ji, jj, jk, jn   ! dummy loop indices
       REAL(wp) ::  zrhs, zzwi, zzws ! local scalars
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::  zwi, zwt, zwd, zws
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::  zwi, zwt, zwd, zws
       !!---------------------------------------------------------------------
       !
@@ -154,6 +157,12 @@
             !
             ! vertical mixing coef.: avt for temperature, avs for salinity and passive tracers
-            IF( cdtype == 'TRA' .AND. jn == jp_tem ) THEN   ;   zwt(:,:,2:jpk) = avt(:,:,2:jpk)
-            ELSE                                            ;   zwt(:,:,2:jpk) = avs(:,:,2:jpk)
+            IF( cdtype == 'TRA' .AND. jn == jp_tem ) THEN
+               DO_3D( 1, 1, 1, 1, 2, jpk )
+                  zwt(ji,jj,jk) = avt(ji,jj,jk)
+               END_3D
+            ELSE
+               DO_3D( 1, 1, 1, 1, 2, jpk )
+                  zwt(ji,jj,jk) = avs(ji,jj,jk)
+               END_3D
             ENDIF
             zwt(:,:,1) = 0._wp
@@ -222,5 +231,5 @@
          END_2D
          DO_3D( 0, 0, 0, 0, 2, jpkm1 )
-            zrhs =        e3t(ji,jj,jk,Kbb) * pt(ji,jj,jk,jn,Kbb)    & 
+            zrhs =        e3t(ji,jj,jk,Kbb) * pt(ji,jj,jk,jn,Kbb)    &
                & + p2dt * e3t(ji,jj,jk,Kmm) * pt(ji,jj,jk,jn,Krhs)   ! zrhs=right hand side
             pt(ji,jj,jk,jn,Kaa) = zrhs - zwi(ji,jj,jk) / zwt(ji,jj,jk-1) * pt(ji,jj,jk-1,jn,Kaa)
Index: /NEMO/trunk/src/OCE/TRA/zpshde.F90
===================================================================
--- /NEMO/trunk/src/OCE/TRA/zpshde.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/TRA/zpshde.F90	(revision 13982)
@@ -17,4 +17,5 @@
    USE oce             ! ocean: dynamics and tracers variables
    USE dom_oce         ! domain: ocean variables
+   USE domutl, ONLY : is_tile
    USE phycst          ! physical constants
    USE eosbn2          ! ocean equation of state
@@ -40,6 +41,27 @@
 CONTAINS
 
-   SUBROUTINE zps_hde( kt, Kmm, kjpt, pta, pgtu, pgtv,   &
-      &                          prd, pgru, pgrv    )
+   SUBROUTINE zps_hde( kt, Kmm, kjpt, pta, pgtu, pgtv,  &
+      &                               prd, pgru, pgrv )
+      !!
+      INTEGER                     , INTENT(in   )           ::  kt          ! ocean time-step index
+      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(  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(  out), OPTIONAL ::  pgru, pgrv  ! hor. grad of prd at u- & v-pts (bottom)
+      !
+      INTEGER :: itrd, itgr
+      !!
+      IF( PRESENT(prd)  ) THEN ; itrd = is_tile(prd)  ; ELSE ; itrd = 0 ; ENDIF
+      IF( PRESENT(pgru) ) THEN ; itgr = is_tile(pgru) ; ELSE ; itgr = 0 ; ENDIF
+
+      CALL zps_hde_t( kt, Kmm, kjpt, pta, is_tile(pta), pgtu, pgtv, is_tile(pgtu), &
+         &                           prd, itrd,         pgru, pgrv, itgr )
+   END SUBROUTINE zps_hde
+
+
+   SUBROUTINE zps_hde_t( kt, Kmm, kjpt, pta, ktta, pgtu, pgtv, ktgt,   &
+      &                                 prd, ktrd, pgru, pgrv, ktgr )
       !!----------------------------------------------------------------------
       !!                     ***  ROUTINE zps_hde  ***
@@ -85,20 +107,26 @@
       !!              - pgru, pgrv: horizontal gradient of rho (if present) at u- & v-points
       !!----------------------------------------------------------------------
-      INTEGER                              , INTENT(in   )           ::  kt          ! ocean time-step index
-      INTEGER                              , INTENT(in   )           ::  Kmm         ! ocean time level index
-      INTEGER                              , INTENT(in   )           ::  kjpt        ! number of tracers
-      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(in   )           ::  pta         ! 4D tracers fields
-      REAL(wp), DIMENSION(jpi,jpj,    kjpt), INTENT(  out)           ::  pgtu, pgtv  ! hor. grad. of ptra at u- & v-pts 
-      REAL(wp), DIMENSION(jpi,jpj,jpk     ), INTENT(in   ), OPTIONAL ::  prd         ! 3D density anomaly fields
-      REAL(wp), DIMENSION(jpi,jpj         ), INTENT(  out), OPTIONAL ::  pgru, pgrv  ! hor. grad of prd at u- & v-pts (bottom)
+      INTEGER                                , INTENT(in   )           ::  kt          ! ocean time-step index
+      INTEGER                                , INTENT(in   )           ::  Kmm         ! ocean time level index
+      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(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(ktgr)         ), INTENT(  out), OPTIONAL ::  pgru, pgrv  ! hor. grad of prd at u- & v-pts (bottom)
       !
       INTEGER  ::   ji, jj, jn                  ! Dummy loop indices
       INTEGER  ::   iku, ikv, ikum1, ikvm1      ! partial step level (ocean bottom level) at u- and v-points
       REAL(wp) ::   ze3wu, ze3wv, zmaxu, zmaxv  ! local scalars
-      REAL(wp), DIMENSION(jpi,jpj)      ::   zri, zrj, zhi, zhj   ! NB: 3rd dim=1 to use eos
-      REAL(wp), DIMENSION(jpi,jpj,kjpt) ::   zti, ztj             ! 
+      REAL(wp), DIMENSION(A2D(nn_hls))      ::   zri, zrj, zhi, zhj   ! NB: 3rd dim=1 to use eos
+      REAL(wp), DIMENSION(A2D(nn_hls),kjpt) ::   zti, ztj             !
       !!----------------------------------------------------------------------
       !
       IF( ln_timing )   CALL timing_start( 'zps_hde')
+      ! NOTE: [tiling-comms-merge] Some lbc_lnks in tra_adv and tra_ldf can be taken out in the zps case, because this lbc_lnk is called when zps_hde is called in the stp routine. In the zco case they are still needed.
+      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
@@ -107,5 +135,5 @@
       DO jn = 1, kjpt      !==   Interpolation of tracers at the last ocean level   ==!
          !
-         DO_2D( 1, 0, 1, 0 )
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, 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
@@ -146,10 +174,10 @@
       END DO
       !
-      CALL lbc_lnk_multi( 'zpshde', pgtu(:,:,:), 'U', -1.0_wp , pgtv(:,:,:), 'V', -1.0_wp )   ! Lateral boundary cond.
+      IF (nn_hls.EQ.1) CALL lbc_lnk_multi( '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)
          pgru(:,:) = 0._wp
          pgrv(:,:) = 0._wp                ! depth of the partial step level
-         DO_2D( 1, 0, 1, 0 )
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
             iku = mbku(ji,jj)
             ikv = mbkv(ji,jj)
@@ -167,5 +195,5 @@
          CALL eos( ztj, zhj, zrj )        ! at the partial step depth output in  zri, zrj 
          !
-         DO_2D( 1, 0, 1, 0 )              ! Gradient of density at the last level
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )              ! Gradient of density at the last level
             iku = mbku(ji,jj)
             ikv = mbkv(ji,jj)
@@ -179,5 +207,5 @@
             ENDIF
          END_2D
-         CALL lbc_lnk_multi( 'zpshde', pgru , 'U', -1.0_wp , pgrv , 'V', -1.0_wp )   ! Lateral boundary conditions
+         IF (nn_hls.EQ.1) CALL lbc_lnk_multi( 'zpshde', pgru , 'U', -1.0_wp , pgrv , 'V', -1.0_wp )   ! Lateral boundary conditions
          !
       END IF
@@ -185,9 +213,33 @@
       IF( ln_timing )   CALL timing_stop( 'zps_hde')
       !
-   END SUBROUTINE zps_hde
+   END SUBROUTINE zps_hde_t
 
 
    SUBROUTINE zps_hde_isf( kt, Kmm, kjpt, pta, pgtu, pgtv, pgtui, pgtvi,  &
-      &                          prd, pgru, pgrv, pgrui, pgrvi )
+      &                                   prd, pgru, pgrv, pgrui, pgrvi )
+      !!
+      INTEGER                     , INTENT(in   )           ::  kt           ! ocean time-step index
+      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(  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(  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)
+      !
+      INTEGER :: itrd, itgr, itgri
+      !!
+      IF( PRESENT(prd)   ) THEN ; itrd  = is_tile(prd)   ; ELSE ; itrd  = 0 ; ENDIF
+      IF( PRESENT(pgru)  ) THEN ; itgr  = is_tile(pgru)  ; ELSE ; itgr  = 0 ; ENDIF
+      IF( PRESENT(pgrui) ) THEN ; itgri = is_tile(pgrui) ; ELSE ; itgri = 0 ; ENDIF
+
+      CALL zps_hde_isf_t( kt, Kmm, kjpt, pta, is_tile(pta), pgtu, pgtv, is_tile(pgtu), pgtui, pgtvi, is_tile(pgtui),  &
+      &                                  prd, itrd,         pgru, pgrv, itgr,          pgrui, pgrvi, itgri )
+   END SUBROUTINE zps_hde_isf
+
+
+   SUBROUTINE zps_hde_isf_t( kt, Kmm, kjpt, pta, ktta, pgtu, pgtv, ktgt, pgtui, pgtvi, ktgti,  &
+      &                                     prd, ktrd, pgru, pgrv, ktgr, pgrui, pgrvi, ktgri )
       !!----------------------------------------------------------------------
       !!                     ***  ROUTINE zps_hde_isf  ***
@@ -236,23 +288,29 @@
       !!              - pgru, pgrv, pgrui, pgtvi: horizontal gradient of rho (if present) at u- & v-points
       !!----------------------------------------------------------------------
-      INTEGER                              , INTENT(in   )           ::  kt           ! ocean time-step index
-      INTEGER                              , INTENT(in   )           ::  Kmm          ! ocean time level index
-      INTEGER                              , INTENT(in   )           ::  kjpt         ! number of tracers
-      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(in   )           ::  pta          ! 4D tracers fields
-      REAL(wp), DIMENSION(jpi,jpj,    kjpt), INTENT(  out)           ::  pgtu, pgtv   ! hor. grad. of ptra at u- & v-pts 
-      REAL(wp), DIMENSION(jpi,jpj,    kjpt), INTENT(  out)           ::  pgtui, pgtvi ! hor. grad. of stra at u- & v-pts (ISF)
-      REAL(wp), DIMENSION(jpi,jpj,jpk     ), INTENT(in   ), OPTIONAL ::  prd          ! 3D density anomaly fields
-      REAL(wp), DIMENSION(jpi,jpj         ), INTENT(  out), OPTIONAL ::  pgru, pgrv   ! hor. grad of prd at u- & v-pts (bottom)
-      REAL(wp), DIMENSION(jpi,jpj         ), INTENT(  out), OPTIONAL ::  pgrui, pgrvi ! hor. grad of prd at u- & v-pts (top)
+      INTEGER                                , INTENT(in   )           ::  kt           ! ocean time-step index
+      INTEGER                                , INTENT(in   )           ::  Kmm          ! ocean time level index
+      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(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(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)
       !
       INTEGER  ::   ji, jj, jn      ! Dummy loop indices
       INTEGER  ::   iku, ikv, ikum1, ikvm1,ikup1, ikvp1   ! partial step level (ocean bottom level) at u- and v-points
       REAL(wp) ::  ze3wu, ze3wv, zmaxu, zmaxv             ! temporary scalars
-      REAL(wp), DIMENSION(jpi,jpj)      ::  zri, zrj, zhi, zhj   ! NB: 3rd dim=1 to use eos
-      REAL(wp), DIMENSION(jpi,jpj,kjpt) ::  zti, ztj             ! 
+      REAL(wp), DIMENSION(A2D(nn_hls))      ::  zri, zrj, zhi, zhj   ! NB: 3rd dim=1 to use eos
+      REAL(wp), DIMENSION(A2D(nn_hls),kjpt) ::  zti, ztj             !
       !!----------------------------------------------------------------------
       !
       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
@@ -262,5 +320,5 @@
       DO jn = 1, kjpt      !==   Interpolation of tracers at the last ocean level   ==!
          !
-         DO_2D( 1, 0, 1, 0 )
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
 
             iku = mbku(ji,jj); ikum1 = MAX( iku - 1 , 1 )    ! last and before last ocean level at u- & v-points
@@ -302,5 +360,5 @@
       END DO
       !
-      CALL lbc_lnk_multi( 'zpshde', pgtu(:,:,:), 'U', -1.0_wp , pgtv(:,:,:), 'V', -1.0_wp )   ! Lateral boundary cond.
+      IF (nn_hls.EQ.1) CALL lbc_lnk_multi( 'zpshde', pgtu(:,:,:), 'U', -1.0_wp , pgtv(:,:,:), 'V', -1.0_wp )   ! Lateral boundary cond.
 
       ! horizontal derivative of density anomalies (rd)
@@ -308,5 +366,5 @@
          pgru(:,:)=0.0_wp   ; pgrv(:,:)=0.0_wp ; 
          !
-         DO_2D( 1, 0, 1, 0 )
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
 
             iku = mbku(ji,jj)
@@ -329,5 +387,5 @@
          CALL eos( ztj, zhj, zrj )
 
-         DO_2D( 1, 0, 1, 0 )            ! Gradient of density at the last level
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
             iku = mbku(ji,jj)
             ikv = mbkv(ji,jj)
@@ -344,5 +402,5 @@
          END_2D
 
-         CALL lbc_lnk_multi( 'zpshde', pgru , 'U', -1.0_wp , pgrv , 'V', -1.0_wp )   ! Lateral boundary conditions
+         IF (nn_hls.EQ.1) CALL lbc_lnk_multi( 'zpshde', pgru , 'U', -1.0_wp , pgrv , 'V', -1.0_wp )   ! Lateral boundary conditions
          !
       END IF
@@ -351,5 +409,5 @@
       !
       DO jn = 1, kjpt      !==   Interpolation of tracers at the last ocean level   ==!            !
-         DO_2D( 1, 0, 1, 0 )
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
             iku = miku(ji,jj); ikup1 = miku(ji,jj) + 1
             ikv = mikv(ji,jj); ikvp1 = mikv(ji,jj) + 1
@@ -395,10 +453,10 @@
          !
       END DO
-      CALL lbc_lnk_multi( 'zpshde', pgtui(:,:,:), 'U', -1.0_wp , pgtvi(:,:,:), 'V', -1.0_wp )   ! Lateral boundary cond.
+      IF (nn_hls.EQ.1) CALL lbc_lnk_multi( '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)
          !
          pgrui(:,:)  =0.0_wp; pgrvi(:,:)  =0.0_wp;
-         DO_2D( 1, 0, 1, 0 )
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
 
             iku = miku(ji,jj)
@@ -420,5 +478,5 @@
          CALL eos( ztj, zhj, zrj )        ! at the partial step depth output in  zri, zrj 
          !
-         DO_2D( 1, 0, 1, 0 )              ! Gradient of density at the last level
+         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )
             iku = miku(ji,jj) 
             ikv = mikv(ji,jj) 
@@ -434,5 +492,5 @@
 
          END_2D
-         CALL lbc_lnk_multi( 'zpshde', pgrui, 'U', -1.0_wp , pgrvi, 'V', -1.0_wp )   ! Lateral boundary conditions
+         IF (nn_hls.EQ.1) CALL lbc_lnk_multi( 'zpshde', pgrui, 'U', -1.0_wp , pgrvi, 'V', -1.0_wp )   ! Lateral boundary conditions
          !
       END IF  
@@ -440,5 +498,5 @@
       IF( ln_timing )   CALL timing_stop( 'zps_hde_isf')
       !
-   END SUBROUTINE zps_hde_isf
+   END SUBROUTINE zps_hde_isf_t
 
    !!======================================================================
Index: /NEMO/trunk/src/OCE/TRD/trdini.F90
===================================================================
--- /NEMO/trunk/src/OCE/TRD/trdini.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/TRD/trdini.F90	(revision 13982)
@@ -11,4 +11,5 @@
    !!----------------------------------------------------------------------
    USE dom_oce        ! ocean domain
+   USE domain, ONLY : dom_tile
    USE trd_oce        ! trends: ocean variables
    USE trdken         ! trends: 3D kinetic   energy
@@ -88,5 +89,11 @@
       !
 !      IF( .NOT.ln_linssh .AND. ( l_trdtra .OR. l_trddyn ) )  CALL ctl_stop( 'trend diagnostics with variable volume not validated' )
-      
+
+      IF( ln_tile .AND. ( l_trdtra .OR. l_trddyn ) ) THEN
+         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 )
+      ENDIF
+
 !!gm  : Potential BUG : 3D output only for vector invariant form!  add a ctl_stop or code the flux form case
 !!gm  : bug/pb for vertical advection of tracer in vvl case: add T.dt[eta] in the output... 
Index: /NEMO/trunk/src/OCE/USR/usrdef_nam.F90
===================================================================
--- /NEMO/trunk/src/OCE/USR/usrdef_nam.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/USR/usrdef_nam.F90	(revision 13982)
@@ -70,5 +70,5 @@
       kk_cfg = nn_GYRE
       !
-      kpi = 30 * nn_GYRE + 2       !                     
+      kpi = 30 * nn_GYRE + 2       !
       kpj = 20 * nn_GYRE + 2
 #if defined key_agrif
Index: /NEMO/trunk/src/OCE/ZDF/zdfosm.F90
===================================================================
--- /NEMO/trunk/src/OCE/ZDF/zdfosm.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/ZDF/zdfosm.F90	(revision 13982)
@@ -1491,4 +1491,6 @@
      !!-----------------------------------------------------------------------------
      IF( TRIM(cdrw) == 'WRITE') THEN     !* Write hbli into the restart file, then return
+        IF( ntile /= 0 .AND. ntile /= nijtile ) RETURN        ! Do only on the last tile
+
         IF(lwp) WRITE(numout,*) '---- osm-rst ----'
          CALL iom_rstput( kt, nitrst, numrow, 'wn'     , ww   )
@@ -1545,7 +1547,9 @@
       !
       IF( kt == nit000 ) THEN
-         IF(lwp) WRITE(numout,*)
-         IF(lwp) WRITE(numout,*) 'tra_osm : OSM non-local tracer fluxes'
-         IF(lwp) WRITE(numout,*) '~~~~~~~   '
+         IF( ntile == 0 .OR. ntile == 1 ) THEN                    ! Do only on the first tile
+            IF(lwp) WRITE(numout,*)
+            IF(lwp) WRITE(numout,*) 'tra_osm : OSM non-local tracer fluxes'
+            IF(lwp) WRITE(numout,*) '~~~~~~~   '
+         ENDIF
       ENDIF
 
Index: /NEMO/trunk/src/OCE/do_loop_substitute.h90
===================================================================
--- /NEMO/trunk/src/OCE/do_loop_substitute.h90	(revision 13981)
+++ /NEMO/trunk/src/OCE/do_loop_substitute.h90	(revision 13982)
@@ -59,5 +59,14 @@
 #endif
 
-#define DO_2D(B, T, L, R) DO jj = Njs0-(B), Nje0+(T)   ;   DO ji = Nis0-(L), Nie0+(R)
+#define DO_2D(B, T, L, R) DO jj = ntsj-(B), ntej+(T)   ;   DO ji = ntsi-(L), ntei+(R)
+#define A1Di(H) ntsi-H:ntei+H
+#define A1Dj(H) ntsj-H:ntej+H
+#define A2D(H) A1Di(H),A1Dj(H)
+#define A1Di_T(T) (ntsi-nn_hls-1)*T+1:
+#define A1Dj_T(T) (ntsj-nn_hls-1)*T+1:
+#define A2D_T(T) A1Di_T(T),A1Dj_T(T)
+#define JPK  :
+#define JPTS  :
+#define KJPT  :
 
 #define DO_3D(B, T, L, R, ks, ke) DO jk = ks, ke   ;   DO_2D(B, T, L, R)
Index: /NEMO/trunk/src/OCE/par_oce.F90
===================================================================
--- /NEMO/trunk/src/OCE/par_oce.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/par_oce.F90	(revision 13982)
@@ -65,4 +65,12 @@
    INTEGER, PUBLIC ::   jpjmax! = ( Nj0glo + jpnj-1 ) / jpnj + 2*nn_hls            !: maximum jpj
 
+   ! Domain tiling
+   INTEGER, PUBLIC ::   nijtile    !: number of tiles in total
+   INTEGER, PUBLIC ::   ntile      !: current tile number
+   INTEGER, PUBLIC ::   ntsi       !: start of internal part of tile domain
+   INTEGER, PUBLIC ::   ntsj       !
+   INTEGER, PUBLIC ::   ntei       !: end of internal part of tile domain
+   INTEGER, PUBLIC ::   ntej       !
+
    !!---------------------------------------------------------------------
    !! Active tracer parameters
Index: /NEMO/trunk/src/OCE/step.F90
===================================================================
--- /NEMO/trunk/src/OCE/step.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/step.F90	(revision 13982)
@@ -55,4 +55,6 @@
    INTEGER, PUBLIC :: Nbb, Nnn, Naa, Nrhs          !! used by nemo_init
 
+   !! * Substitutions
+#  include "do_loop_substitute.h90"
    !!----------------------------------------------------------------------
    !! NEMO/OCE 4.0 , NEMO Consortium (2018)
@@ -85,5 +87,5 @@
       !!              -8- Outputs and diagnostics
       !!----------------------------------------------------------------------
-      INTEGER ::   ji, jj, jk   ! dummy loop indice
+      INTEGER ::   ji, jj, jk, jtile   ! dummy loop indice
 !!gm kcall can be removed, I guess
       INTEGER ::   kcall        ! optional integer argument (dom_vvl_sf_nxt)
@@ -263,28 +265,45 @@
       ! Active tracers                              
       !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
-                         ts(:,:,:,:,Nrhs) = 0._wp         ! set tracer trends to zero
-
-      IF(  lk_asminc .AND. ln_asmiau .AND. &
-         & ln_trainc )   CALL tra_asm_inc( kstp, Nbb, Nnn, ts, Nrhs )  ! apply tracer assimilation increment
-                         CALL tra_sbc    ( kstp,      Nnn, ts, Nrhs )  ! surface boundary condition
-      IF( ln_traqsr  )   CALL tra_qsr    ( kstp,      Nnn, ts, Nrhs )  ! penetrative solar radiation qsr
-      IF( ln_isf     )   CALL tra_isf    ( kstp,      Nnn, ts, Nrhs )  ! ice shelf heat flux
-      IF( ln_trabbc  )   CALL tra_bbc    ( kstp,      Nnn, ts, Nrhs )  ! bottom heat flux
-      IF( ln_trabbl  )   CALL tra_bbl    ( kstp, Nbb, Nnn, ts, Nrhs )  ! advective (and/or diffusive) bottom boundary layer scheme
-      IF( ln_tradmp  )   CALL tra_dmp    ( kstp, Nbb, Nnn, ts, Nrhs )  ! internal damping trends
-      IF( ln_bdy     )   CALL bdy_tra_dmp( kstp, Nbb,      ts, Nrhs )  ! bdy damping trends
-#if defined key_agrif
-      IF(.NOT. Agrif_Root())  & 
-               &         CALL Agrif_Sponge_tra        ! tracers sponge
-#endif
-                         CALL tra_adv    ( kstp, Nbb, Nnn, ts, Nrhs )  ! hor. + vert. advection	==> RHS
-      IF( ln_zdfosm  )   CALL tra_osm    ( kstp,      Nnn, ts, Nrhs )  ! OSMOSIS non-local tracer fluxes ==> RHS
-      IF( lrst_oce .AND. ln_zdfosm ) &
-           &             CALL osm_rst    ( kstp,      Nnn, 'WRITE'  )  ! write OSMOSIS outputs + ww (so must do here) to restarts
-                         CALL tra_ldf    ( kstp, Nbb, Nnn, ts, Nrhs )  ! lateral mixing
-
-                         CALL tra_zdf    ( kstp, Nbb, Nnn, Nrhs, ts, Naa  )  ! vertical mixing and after tracer fields
-      IF( ln_zdfnpc  )   CALL tra_npc    ( kstp,      Nnn, Nrhs, ts, Naa  )  ! update after fields by non-penetrative convection
-
+      ! 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
+
+         IF(  lk_asminc .AND. ln_asmiau .AND. &
+            & ln_trainc )   CALL tra_asm_inc( kstp, Nbb, Nnn, ts, Nrhs )  ! apply tracer assimilation increment
+                            CALL tra_sbc    ( kstp,      Nnn, ts, Nrhs )  ! surface boundary condition
+         IF( ln_traqsr  )   CALL tra_qsr    ( kstp,      Nnn, ts, Nrhs )  ! penetrative solar radiation qsr
+         IF( ln_isf     )   CALL tra_isf    ( kstp,      Nnn, ts, Nrhs )  ! ice shelf heat flux
+         IF( ln_trabbc  )   CALL tra_bbc    ( kstp,      Nnn, ts, Nrhs )  ! bottom heat flux
+         IF( ln_trabbl  )   CALL tra_bbl    ( kstp, Nbb, Nnn, ts, Nrhs )  ! advective (and/or diffusive) bottom boundary layer scheme
+         IF( ln_tradmp  )   CALL tra_dmp    ( kstp, Nbb, Nnn, ts, Nrhs )  ! internal damping trends
+         IF( ln_bdy     )   CALL bdy_tra_dmp( kstp, Nbb,      ts, Nrhs )  ! bdy damping trends
+      END DO
+
+#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
+#endif
+
+      ! 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 )
+
+                            CALL tra_adv    ( kstp, Nbb, Nnn, ts, Nrhs )  ! hor. + vert. advection	==> RHS
+         IF( ln_zdfosm  )   CALL tra_osm    ( kstp,      Nnn, ts, Nrhs )  ! OSMOSIS non-local tracer fluxes ==> RHS
+         IF( lrst_oce .AND. ln_zdfosm ) &
+              &             CALL osm_rst    ( kstp,      Nnn, 'WRITE'  )  ! write OSMOSIS outputs + ww (so must do here) to restarts
+                            CALL tra_ldf    ( kstp, Nbb, Nnn, ts, Nrhs )  ! lateral mixing
+
+                            CALL tra_zdf    ( kstp, Nbb, Nnn, Nrhs, ts, Naa  )  ! vertical mixing and after tracer fields
+         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
       !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
       ! Set boundary conditions, time filter and swap time levels
Index: /NEMO/trunk/src/OCE/step_oce.F90
===================================================================
--- /NEMO/trunk/src/OCE/step_oce.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/step_oce.F90	(revision 13982)
@@ -9,4 +9,5 @@
    USE oce             ! ocean dynamics and tracers variables
    USE dom_oce         ! ocean space and time domain variables
+   USE domain, ONLY : dom_tile
    USE zdf_oce         ! ocean vertical physics variables
    USE zdfdrg  ,  ONLY : ln_drgimp   ! implicit top/bottom friction
Index: /NEMO/trunk/src/OCE/timing.F90
===================================================================
--- /NEMO/trunk/src/OCE/timing.F90	(revision 13981)
+++ /NEMO/trunk/src/OCE/timing.F90	(revision 13982)
@@ -109,5 +109,5 @@
 
       s_timer%l_tdone = .FALSE.
-      s_timer%niter = s_timer%niter + 1
+      IF( ntile == 0 .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/trunk/src/OFF/dtadyn.F90
===================================================================
--- /NEMO/trunk/src/OFF/dtadyn.F90	(revision 13981)
+++ /NEMO/trunk/src/OFF/dtadyn.F90	(revision 13982)
@@ -795,5 +795,5 @@
       !!---------------------------------------------------------------------
       INTEGER ,                              INTENT(in ) :: kt       ! time step
-      REAL(wp), DIMENSION(jpi,jpj,jpk,jpts), INTENT(in ) :: pts      ! temperature/salinity
+      REAL(wp), DIMENSION(jpi,jpj,jpk,jpts), INTENT(inout) :: pts      ! temperature/salinity
       REAL(wp), DIMENSION(jpi,jpj,jpk)     , INTENT(out) :: puslp    ! zonal isopycnal slopes
       REAL(wp), DIMENSION(jpi,jpj,jpk)     , INTENT(out) :: pvslp    ! meridional isopycnal slopes
Index: /NEMO/trunk/src/TOP/TRP/trcadv.F90
===================================================================
--- /NEMO/trunk/src/TOP/TRP/trcadv.F90	(revision 13981)
+++ /NEMO/trunk/src/TOP/TRP/trcadv.F90	(revision 13982)
@@ -22,5 +22,7 @@
    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)
@@ -124,12 +126,37 @@
       !
       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
-         CALL tra_adv_fct( kt, nittrc000,'TRC', rDt_trc, zuu, zvv, zww, Kbb, Kmm, ptr, jptra, Krhs, nn_fct_h, nn_fct_v )
+         IF (nn_hls.EQ.2) THEN
+            CALL lbc_lnk_multi( 'trcadv', ptr(:,:,:,:,Kbb), 'T', 1., ptr(:,:,:,:,Kmm), 'T', 1.)
+            CALL lbc_lnk_multi( '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
-         CALL tra_adv_mus( kt, nittrc000,'TRC', rDt_trc, zuu, zvv, zww, Kbb, Kmm, ptr, jptra, Krhs, ln_mus_ups         ) 
+         IF (nn_hls.EQ.2) THEN
+            IF (nn_hls.EQ.2) 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
       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_multi( '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/trunk/src/TOP/TRP/trcldf.F90
===================================================================
--- /NEMO/trunk/src/TOP/TRP/trcldf.F90	(revision 13981)
+++ /NEMO/trunk/src/TOP/TRP/trcldf.F90	(revision 13982)
@@ -101,4 +101,5 @@
            &                     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/trunk/tests/CANAL/MY_SRC/trazdf.F90
===================================================================
--- /NEMO/trunk/tests/CANAL/MY_SRC/trazdf.F90	(revision 13981)
+++ /NEMO/trunk/tests/CANAL/MY_SRC/trazdf.F90	(revision 13982)
@@ -54,5 +54,5 @@
       REAL(wp), DIMENSION(jpi,jpj,jpk,jpts,jpt), INTENT(inout) :: pts                 ! active tracers and RHS of tracer equation
       !
-      INTEGER  ::   jk   ! Dummy loop indices
+      INTEGER  ::   ji, jj, jk   ! Dummy loop indices
       REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::   ztrdt, ztrds   ! 3D workspace
       !!---------------------------------------------------------------------
@@ -61,7 +61,9 @@
       !
       IF( kt == nit000 )  THEN
-         IF(lwp)WRITE(numout,*)
-         IF(lwp)WRITE(numout,*) 'tra_zdf : implicit vertical mixing on T & S'
-         IF(lwp)WRITE(numout,*) '~~~~~~~ '
+         IF( ntile == 0 .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'
+            IF(lwp)WRITE(numout,*) '~~~~~~~ '
+         ENDIF
       ENDIF
       !
@@ -83,9 +85,13 @@
 
       IF( l_trdtra )   THEN                      ! save the vertical diffusive trends for further diagnostics
-         DO jk = 1, jpkm1
-            ztrdt(:,:,jk) = ( ( pts(:,:,jk,jp_tem,Kaa)*e3t(:,:,jk,Kaa) - pts(:,:,jk,jp_tem,Kbb)*e3t(:,:,jk,Kbb) ) &
-               &          / (e3t(:,:,jk,Kmm)*rDt) ) - ztrdt(:,:,jk)
-            ztrds(:,:,jk) = ( ( pts(:,:,jk,jp_sal,Kaa)*e3t(:,:,jk,Kaa) - pts(:,:,jk,jp_sal,Kbb)*e3t(:,:,jk,Kbb) ) &
-              &           / (e3t(:,:,jk,Kmm)*rDt) ) - ztrds(:,:,jk)
+         DO jk = 1, jpk
+            ztrdt(:,:,jk) = (   (  pts(:,:,jk,jp_tem,Kaa)*e3t(:,:,jk,Kaa)     &
+               &                 - pts(:,:,jk,jp_tem,Kbb)*e3t(:,:,jk,Kbb)  )  &
+               &              / (  e3t(:,:,jk,Kmm)*rDt  )   )                 &
+               &          - ztrdt(:,:,jk)
+            ztrds(:,:,jk) = (   (  pts(:,:,jk,jp_sal,Kaa)*e3t(:,:,jk,Kaa)     &
+               &                 - pts(:,:,jk,jp_sal,Kbb)*e3t(:,:,jk,Kbb)  )  &
+               &             / (   e3t(:,:,jk,Kmm)*rDt  )   )                 &
+               &          - ztrds(:,:,jk)
          END DO
 !!gm this should be moved in trdtra.F90 and done on all trends
@@ -135,5 +141,5 @@
       INTEGER  ::  ji, jj, jk, jn   ! dummy loop indices
       REAL(wp) ::  zrhs, zzwi, zzws ! local scalars
-      REAL(wp), DIMENSION(jpi,jpj,jpk) ::  zwi, zwt, zwd, zws
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::  zwi, zwt, zwd, zws
       !!---------------------------------------------------------------------
       !
@@ -149,6 +155,12 @@
             !
             ! vertical mixing coef.: avt for temperature, avs for salinity and passive tracers
-            IF( cdtype == 'TRA' .AND. jn == jp_tem ) THEN   ;   zwt(:,:,2:jpk) = avt(:,:,2:jpk)
-            ELSE                                            ;   zwt(:,:,2:jpk) = avs(:,:,2:jpk)
+            IF( cdtype == 'TRA' .AND. jn == jp_tem ) THEN
+               DO_3D( 1, 1, 1, 1, 2, jpk )
+                  zwt(ji,jj,jk) = avt(ji,jj,jk)
+               END_3D
+            ELSE
+               DO_3D( 1, 1, 1, 1, 2, jpk )
+                  zwt(ji,jj,jk) = avs(ji,jj,jk)
+               END_3D
             ENDIF
             zwt(:,:,1) = 0._wp
Index: /NEMO/trunk/tests/CANAL/field_def_nemo-oce.xml
===================================================================
--- /NEMO/trunk/tests/CANAL/field_def_nemo-oce.xml	(revision 13982)
+++ /NEMO/trunk/tests/CANAL/field_def_nemo-oce.xml	(revision 13982)
@@ -0,0 +1,1 @@
+link ../../../cfgs/SHARED/field_def_nemo-oce.xml
Index: /NEMO/trunk/tests/ISOMIP+/MY_SRC/dtatsd.F90
===================================================================
--- /NEMO/trunk/tests/ISOMIP+/MY_SRC/dtatsd.F90	(revision 13981)
+++ /NEMO/trunk/tests/ISOMIP+/MY_SRC/dtatsd.F90	(revision 13982)
@@ -18,4 +18,5 @@
    USE phycst          ! physical constants
    USE dom_oce         ! ocean space and time domain
+   USE domain, ONLY : dom_tile
    USE fldread         ! read input fields
    !
@@ -163,21 +164,40 @@
       INTEGER                              , INTENT(in   ) ::   kt     ! ocean time-step
       CHARACTER(LEN=3)                     , INTENT(in   ) ::   cddta  ! dmp or ini
-      REAL(wp), DIMENSION(jpi,jpj,jpk,jpts), INTENT(  out) ::   ptsd   ! T & S data
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk,jpts), INTENT(  out) ::   ptsd   ! T & S data
       !
       INTEGER ::   ji, jj, jk, jl, jkk   ! dummy loop indicies
       INTEGER ::   ik, il0, il1, ii0, ii1, ij0, ij1   ! local integers
+      INTEGER ::   itile
       REAL(wp)::   zl, zi                             ! local scalars
       REAL(wp), DIMENSION(jpk) ::  ztp, zsp   ! 1D workspace
       !!----------------------------------------------------------------------
       !
+      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
+
+         SELECT CASE(cddta)
+         CASE('ini')
+            CALL fld_read( kt, 1, sf_tsdini ) !==   read T & S data at kt time step   ==!
+         CASE('dmp')
+            CALL fld_read( kt, 1, sf_tsddmp ) !==   read T & S data at kt time step   ==!
+         CASE DEFAULT
+            CALL ctl_stop('STOP', 'dta_tsd: cddta case unknown')
+         END SELECT
+
+         IF( ln_tile ) CALL dom_tile( ntsi, ntsj, ntei, ntej, ktile = itile )            ! Revert to tile domain
+      ENDIF
+      !
       SELECT CASE(cddta)
-      CASE('ini') 
-         CALL fld_read( kt, 1, sf_tsdini ) !==   read T & S data at kt time step   ==!
-         ptsd(:,:,:,jp_tem) = sf_tsdini(jp_tem)%fnow(:,:,:)    ! NO mask
-         ptsd(:,:,:,jp_sal) = sf_tsdini(jp_sal)%fnow(:,:,:) 
+      CASE('ini')
+         DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpk )
+            ptsd(ji,jj,jk,jp_tem) = sf_tsdini(jp_tem)%fnow(ji,jj,jk)    ! NO mask
+            ptsd(ji,jj,jk,jp_sal) = sf_tsdini(jp_sal)%fnow(ji,jj,jk)
+         END_3D
       CASE('dmp')
-         CALL fld_read( kt, 1, sf_tsddmp ) !==   read T & S data at kt time step   ==!
-         ptsd(:,:,:,jp_tem) = sf_tsddmp(jp_tem)%fnow(:,:,:)    ! NO mask
-         ptsd(:,:,:,jp_sal) = sf_tsddmp(jp_sal)%fnow(:,:,:) 
+         DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpk )
+            ptsd(ji,jj,jk,jp_tem) = sf_tsddmp(jp_tem)%fnow(ji,jj,jk)    ! NO mask
+            ptsd(ji,jj,jk,jp_sal) = sf_tsddmp(jp_sal)%fnow(ji,jj,jk)
+         END_3D
       CASE DEFAULT
          CALL ctl_stop('STOP', 'dta_tsd: cddta case unknown')
@@ -186,7 +206,9 @@
       IF( ln_sco ) THEN                   !==   s- or mixed s-zps-coordinate   ==!
          !
-         IF( kt == nit000 .AND. lwp )THEN
-            WRITE(numout,*)
-            WRITE(numout,*) 'dta_tsd: interpolates T & S data onto the s- or mixed s-z-coordinate mesh'
+         IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
+            IF( kt == nit000 .AND. lwp )THEN
+               WRITE(numout,*)
+               WRITE(numout,*) 'dta_tsd: interpolates T & S data onto the s- or mixed s-z-coordinate mesh'
+            ENDIF
          ENDIF
          !
@@ -220,6 +242,8 @@
       ELSE                                !==   z- or zps- coordinate   ==!
          !                             
-         ptsd(:,:,:,jp_tem) = ptsd(:,:,:,jp_tem) * tmask(:,:,:)    ! Mask
-         ptsd(:,:,:,jp_sal) = ptsd(:,:,:,jp_sal) * tmask(:,:,:)
+         DO_3D( nn_hls, nn_hls, nn_hls, nn_hls, 1, jpk )
+            ptsd(ji,jj,jk,jp_tem) = ptsd(ji,jj,jk,jp_tem) * tmask(ji,jj,jk)    ! Mask
+            ptsd(ji,jj,jk,jp_sal) = ptsd(ji,jj,jk,jp_sal) * tmask(ji,jj,jk)
+         END_3D
          !
          IF( ln_zps ) THEN                      ! zps-coordinate (partial steps) interpolation at the last ocean level
Index: /NEMO/trunk/tests/ISOMIP+/MY_SRC/eosbn2.F90
===================================================================
--- /NEMO/trunk/tests/ISOMIP+/MY_SRC/eosbn2.F90	(revision 13981)
+++ /NEMO/trunk/tests/ISOMIP+/MY_SRC/eosbn2.F90	(revision 13982)
@@ -39,4 +39,5 @@
    !!----------------------------------------------------------------------
    USE dom_oce        ! ocean space and time domain
+   USE domutl, ONLY : is_tile
    USE phycst         ! physical constants
    USE stopar         ! Stochastic T/S fluctuations
@@ -191,4 +192,14 @@
 
    SUBROUTINE eos_insitu( pts, prd, pdep )
+      !!
+      REAL(wp), DIMENSION(:,:,:,:), INTENT(in   ) ::   pts   ! 1 : potential temperature  [Celsius]
+      !                                                      ! 2 : salinity               [psu]
+      REAL(wp), DIMENSION(:,:,:)  , INTENT(  out) ::   prd   ! in situ density            [-]
+      REAL(wp), DIMENSION(:,:,:)  , INTENT(in   ) ::   pdep  ! depth                      [m]
+      !!
+      CALL eos_insitu_t( pts, is_tile(pts), prd, is_tile(prd), pdep, is_tile(pdep) )
+   END SUBROUTINE eos_insitu
+
+   SUBROUTINE eos_insitu_t( pts, ktts, prd, ktrd, pdep, ktdep )
       !!----------------------------------------------------------------------
       !!                   ***  ROUTINE eos_insitu  ***
@@ -228,8 +239,9 @@
       !!                TEOS-10 Manual, 2010
       !!----------------------------------------------------------------------
-      REAL(wp), DIMENSION(jpi,jpj,jpk,jpts), INTENT(in   ) ::   pts   ! 1 : potential temperature  [Celsius]
+      INTEGER                                 , INTENT(in   ) ::   ktts, ktrd, ktdep
+      REAL(wp), DIMENSION(A2D_T(ktts) ,JPK,JPTS), INTENT(in   ) ::   pts   ! 1 : potential temperature  [Celsius]
       !                                                               ! 2 : salinity               [psu]
-      REAL(wp), DIMENSION(jpi,jpj,jpk     ), INTENT(  out) ::   prd   ! in situ density            [-]
-      REAL(wp), DIMENSION(jpi,jpj,jpk     ), INTENT(in   ) ::   pdep  ! depth                      [m]
+      REAL(wp), DIMENSION(A2D_T(ktrd) ,JPK     ), INTENT(  out) ::   prd   ! in situ density            [-]
+      REAL(wp), DIMENSION(A2D_T(ktdep),JPK     ), INTENT(in   ) ::   pdep  ! depth                      [m]
       !
       INTEGER  ::   ji, jj, jk                ! dummy loop indices
@@ -312,8 +324,20 @@
       IF( ln_timing )   CALL timing_stop('eos-insitu')
       !
-   END SUBROUTINE eos_insitu
+   END SUBROUTINE eos_insitu_t
 
 
    SUBROUTINE eos_insitu_pot( pts, prd, prhop, pdep )
+      !!
+      REAL(wp), DIMENSION(:,:,:,:), INTENT(in   ) ::   pts    ! 1 : potential temperature  [Celsius]
+      !                                                       ! 2 : salinity               [psu]
+      REAL(wp), DIMENSION(:,:,:)  , INTENT(  out) ::   prd    ! in situ density            [-]
+      REAL(wp), DIMENSION(:,:,:)  , INTENT(  out) ::   prhop  ! potential density (surface referenced)
+      REAL(wp), DIMENSION(:,:,:)  , INTENT(in   ) ::   pdep   ! depth                      [m]
+      !!
+      CALL eos_insitu_pot_t( pts, is_tile(pts), prd, is_tile(prd), prhop, is_tile(prhop), pdep, is_tile(pdep) )
+   END SUBROUTINE eos_insitu_pot
+
+
+   SUBROUTINE eos_insitu_pot_t( pts, ktts, prd, ktrd, prhop, ktrhop, pdep, ktdep )
       !!----------------------------------------------------------------------
       !!                  ***  ROUTINE eos_insitu_pot  ***
@@ -328,9 +352,10 @@
       !!
       !!----------------------------------------------------------------------
-      REAL(wp), DIMENSION(jpi,jpj,jpk,jpts), INTENT(in   ) ::   pts    ! 1 : potential temperature  [Celsius]
+      INTEGER                                  , INTENT(in   ) ::   ktts, ktrd, ktrhop, ktdep
+      REAL(wp), DIMENSION(A2D_T(ktts)  ,JPK,JPTS), INTENT(in   ) ::   pts    ! 1 : potential temperature  [Celsius]
       !                                                                ! 2 : salinity               [psu]
-      REAL(wp), DIMENSION(jpi,jpj,jpk     ), INTENT(  out) ::   prd    ! in situ density            [-]
-      REAL(wp), DIMENSION(jpi,jpj,jpk     ), INTENT(  out) ::   prhop  ! potential density (surface referenced)
-      REAL(wp), DIMENSION(jpi,jpj,jpk     ), INTENT(in   ) ::   pdep   ! depth                      [m]
+      REAL(wp), DIMENSION(A2D_T(ktrd)  ,JPK     ), INTENT(  out) ::   prd    ! in situ density            [-]
+      REAL(wp), DIMENSION(A2D_T(ktrhop),JPK     ), INTENT(  out) ::   prhop  ! potential density (surface referenced)
+      REAL(wp), DIMENSION(A2D_T(ktdep) ,JPK     ), INTENT(in   ) ::   pdep   ! depth                      [m]
       !
       INTEGER  ::   ji, jj, jk, jsmp             ! dummy loop indices
@@ -482,8 +507,19 @@
       IF( ln_timing )   CALL timing_stop('eos-pot')
       !
-   END SUBROUTINE eos_insitu_pot
+   END SUBROUTINE eos_insitu_pot_t
 
 
    SUBROUTINE eos_insitu_2d( pts, pdep, prd )
+      !!
+      REAL(wp), DIMENSION(:,:,:), INTENT(in   ) ::   pts   ! 1 : potential temperature  [Celsius]
+      !                                                    ! 2 : salinity               [psu]
+      REAL(wp), DIMENSION(:,:)  , INTENT(in   ) ::   pdep  ! depth                      [m]
+      REAL(wp), DIMENSION(:,:)  , INTENT(  out) ::   prd   ! in situ density
+      !!
+      CALL eos_insitu_2d_t( pts, is_tile(pts), pdep, is_tile(pdep), prd, is_tile(prd) )
+   END SUBROUTINE eos_insitu_2d
+
+
+   SUBROUTINE eos_insitu_2d_t( pts, ktts, pdep, ktdep, prd, ktrd )
       !!----------------------------------------------------------------------
       !!                  ***  ROUTINE eos_insitu_2d  ***
@@ -496,8 +532,9 @@
       !!
       !!----------------------------------------------------------------------
-      REAL(wp), DIMENSION(jpi,jpj,jpts), INTENT(in   ) ::   pts   ! 1 : potential temperature  [Celsius]
+      INTEGER                            , INTENT(in   ) ::   ktts, ktdep, ktrd
+      REAL(wp), DIMENSION(A2D_T(ktts),JPTS), INTENT(in   ) ::   pts   ! 1 : potential temperature  [Celsius]
       !                                                           ! 2 : salinity               [psu]
-      REAL(wp), DIMENSION(jpi,jpj)     , INTENT(in   ) ::   pdep  ! depth                      [m]
-      REAL(wp), DIMENSION(jpi,jpj)     , INTENT(  out) ::   prd   ! in situ density
+      REAL(wp), DIMENSION(A2D_T(ktdep)    ), INTENT(in   ) ::   pdep  ! depth                      [m]
+      REAL(wp), DIMENSION(A2D_T(ktrd)     ), INTENT(  out) ::   prd   ! in situ density
       !
       INTEGER  ::   ji, jj, jk                ! dummy loop indices
@@ -584,8 +621,18 @@
       IF( ln_timing )   CALL timing_stop('eos2d')
       !
-   END SUBROUTINE eos_insitu_2d
+   END SUBROUTINE eos_insitu_2d_t
 
 
    SUBROUTINE rab_3d( pts, pab, Kmm )
+      !!
+      INTEGER                     , INTENT(in   ) ::   Kmm   ! time level index
+      REAL(wp), DIMENSION(:,:,:,:), INTENT(in   ) ::   pts   ! pot. temperature & salinity
+      REAL(wp), DIMENSION(:,:,:,:), INTENT(  out) ::   pab   ! thermal/haline expansion ratio
+      !!
+      CALL rab_3d_t( pts, is_tile(pts), pab, is_tile(pab), Kmm )
+   END SUBROUTINE rab_3d
+
+
+   SUBROUTINE rab_3d_t( pts, ktts, pab, ktab, Kmm )
       !!----------------------------------------------------------------------
       !!                 ***  ROUTINE rab_3d  ***
@@ -598,6 +645,7 @@
       !!----------------------------------------------------------------------
       INTEGER                              , INTENT(in   ) ::   Kmm   ! time level index
-      REAL(wp), DIMENSION(jpi,jpj,jpk,jpts), INTENT(in   ) ::   pts   ! pot. temperature & salinity
-      REAL(wp), DIMENSION(jpi,jpj,jpk,jpts), INTENT(  out) ::   pab   ! thermal/haline expansion ratio
+      INTEGER                                , INTENT(in   ) ::   ktts, ktab
+      REAL(wp), DIMENSION(A2D_T(ktts),JPK,JPTS), INTENT(in   ) ::   pts   ! pot. temperature & salinity
+      REAL(wp), DIMENSION(A2D_T(ktab),JPK,JPTS), INTENT(  out) ::   pab   ! thermal/haline expansion ratio
       !
       INTEGER  ::   ji, jj, jk                ! dummy loop indices
@@ -706,8 +754,19 @@
       IF( ln_timing )   CALL timing_stop('rab_3d')
       !
-   END SUBROUTINE rab_3d
+   END SUBROUTINE rab_3d_t
 
 
    SUBROUTINE rab_2d( pts, pdep, pab, Kmm )
+      !!
+      INTEGER                   , INTENT(in   ) ::   Kmm   ! time level index
+      REAL(wp), DIMENSION(:,:,:), INTENT(in   ) ::   pts    ! pot. temperature & salinity
+      REAL(wp), DIMENSION(:,:)  , INTENT(in   ) ::   pdep   ! depth                  [m]
+      REAL(wp), DIMENSION(:,:,:), INTENT(  out) ::   pab    ! thermal/haline expansion ratio
+      !!
+      CALL rab_2d_t(pts, is_tile(pts), pdep, is_tile(pdep), pab, is_tile(pab), Kmm)
+   END SUBROUTINE rab_2d
+
+
+   SUBROUTINE rab_2d_t( pts, ktts, pdep, ktdep, pab, ktab, Kmm )
       !!----------------------------------------------------------------------
       !!                 ***  ROUTINE rab_2d  ***
@@ -718,7 +777,8 @@
       !!----------------------------------------------------------------------
       INTEGER                              , INTENT(in   ) ::   Kmm   ! time level index
-      REAL(wp), DIMENSION(jpi,jpj,jpts)    , INTENT(in   ) ::   pts    ! pot. temperature & salinity
-      REAL(wp), DIMENSION(jpi,jpj)         , INTENT(in   ) ::   pdep   ! depth                  [m]
-      REAL(wp), DIMENSION(jpi,jpj,jpts)    , INTENT(  out) ::   pab    ! thermal/haline expansion ratio
+      INTEGER                            , INTENT(in   ) ::   ktts, ktdep, ktab
+      REAL(wp), DIMENSION(A2D_T(ktts),JPTS), INTENT(in   ) ::   pts    ! pot. temperature & salinity
+      REAL(wp), DIMENSION(A2D_T(ktdep)    ), INTENT(in   ) ::   pdep   ! depth                  [m]
+      REAL(wp), DIMENSION(A2D_T(ktab),JPTS), INTENT(  out) ::   pab    ! thermal/haline expansion ratio
       !
       INTEGER  ::   ji, jj, jk                ! dummy loop indices
@@ -829,5 +889,5 @@
       IF( ln_timing )   CALL timing_stop('rab_2d')
       !
-   END SUBROUTINE rab_2d
+   END SUBROUTINE rab_2d_t
 
 
@@ -942,4 +1002,15 @@
 
    SUBROUTINE bn2( pts, pab, pn2, Kmm )
+      !!
+      INTEGER                              , INTENT(in   ) ::  Kmm   ! time level index
+      REAL(wp), DIMENSION(jpi,jpj,jpk,jpts), INTENT(in   ) ::  pts   ! pot. temperature and salinity   [Celsius,psu]
+      REAL(wp), DIMENSION(:,:,:,:)         , INTENT(in   ) ::  pab   ! thermal/haline expansion coef.  [Celsius-1,psu-1]
+      REAL(wp), DIMENSION(:,:,:)           , INTENT(  out) ::  pn2   ! Brunt-Vaisala frequency squared [1/s^2]
+      !!
+      CALL bn2_t( pts, pab, is_tile(pab), pn2, is_tile(pn2), Kmm )
+   END SUBROUTINE bn2
+
+
+   SUBROUTINE bn2_t( pts, pab, ktab, pn2, ktn2, Kmm )
       !!----------------------------------------------------------------------
       !!                  ***  ROUTINE bn2  ***
@@ -956,7 +1027,8 @@
       !!----------------------------------------------------------------------
       INTEGER                              , INTENT(in   ) ::   Kmm   ! time level index
+      INTEGER                                , INTENT(in   ) ::  ktab, ktn2
       REAL(wp), DIMENSION(jpi,jpj,jpk,jpts), INTENT(in   ) ::  pts   ! pot. temperature and salinity   [Celsius,psu]
-      REAL(wp), DIMENSION(jpi,jpj,jpk,jpts), INTENT(in   ) ::  pab   ! thermal/haline expansion coef.  [Celsius-1,psu-1]
-      REAL(wp), DIMENSION(jpi,jpj,jpk     ), INTENT(  out) ::  pn2   ! Brunt-Vaisala frequency squared [1/s^2]
+      REAL(wp), DIMENSION(A2D_T(ktab),JPK,JPTS), INTENT(in   ) ::  pab   ! thermal/haline expansion coef.  [Celsius-1,psu-1]
+      REAL(wp), DIMENSION(A2D_T(ktn2),JPK     ), INTENT(  out) ::  pn2   ! Brunt-Vaisala frequency squared [1/s^2]
       !
       INTEGER  ::   ji, jj, jk      ! dummy loop indices
@@ -982,5 +1054,5 @@
       IF( ln_timing )   CALL timing_stop('bn2')
       !
-   END SUBROUTINE bn2
+   END SUBROUTINE bn2_t
 
 
@@ -1043,4 +1115,14 @@
 
    SUBROUTINE  eos_fzp_2d( psal, ptf, pdep )
+      !!
+      REAL(wp), DIMENSION(jpi,jpj), INTENT(in   )           ::   psal   ! salinity   [psu]
+      REAL(wp), DIMENSION(jpi,jpj), INTENT(in   ), OPTIONAL ::   pdep   ! depth      [m]
+      REAL(wp), DIMENSION(:,:)    , INTENT(out  )           ::   ptf    ! freezing temperature [Celsius]
+      !!
+      CALL eos_fzp_2d_t( psal, ptf, is_tile(ptf), pdep )
+   END SUBROUTINE eos_fzp_2d
+
+
+   SUBROUTINE  eos_fzp_2d_t( psal, ptf, kttf, pdep )
       !!----------------------------------------------------------------------
       !!                 ***  ROUTINE eos_fzp  ***
@@ -1054,7 +1136,8 @@
       !! Reference  :   UNESCO tech. papers in the marine science no. 28. 1978
       !!----------------------------------------------------------------------
+      INTEGER                       , INTENT(in   )           ::   kttf
       REAL(wp), DIMENSION(jpi,jpj), INTENT(in   )           ::   psal   ! salinity   [psu]
       REAL(wp), DIMENSION(jpi,jpj), INTENT(in   ), OPTIONAL ::   pdep   ! depth      [m]
-      REAL(wp), DIMENSION(jpi,jpj), INTENT(out  )           ::   ptf    ! freezing temperature [Celsius]
+      REAL(wp), DIMENSION(A2D_T(kttf)), INTENT(out  )           ::   ptf    ! freezing temperature [Celsius]
       !
       INTEGER  ::   ji, jj          ! dummy loop indices
@@ -1089,5 +1172,5 @@
       END SELECT      
       !
-  END SUBROUTINE eos_fzp_2d
+  END SUBROUTINE eos_fzp_2d_t
 
 
Index: /NEMO/trunk/tests/ISOMIP+/MY_SRC/tradmp.F90
===================================================================
--- /NEMO/trunk/tests/ISOMIP+/MY_SRC/tradmp.F90	(revision 13981)
+++ /NEMO/trunk/tests/ISOMIP+/MY_SRC/tradmp.F90	(revision 13982)
@@ -95,5 +95,5 @@
       !
       INTEGER ::   ji, jj, jk, jn   ! dummy loop indices
-      REAL(wp), DIMENSION(jpi,jpj,jpk,jpts)     ::  zts_dta
+      REAL(wp), DIMENSION(A2D(nn_hls),jpk,jpts)     ::  zts_dta
       REAL(wp), DIMENSION(:,:,:,:), ALLOCATABLE ::  ztrdts
       !!----------------------------------------------------------------------
