Index: NEMO/branches/2019/ENHANCE-02_ISF_nemo/src/OCE/LBC/lbclnk.F90
===================================================================
--- NEMO/branches/2019/ENHANCE-02_ISF_nemo/src/OCE/LBC/lbclnk.F90	(revision 11395)
+++ NEMO/branches/2019/ENHANCE-02_ISF_nemo/src/OCE/LBC/lbclnk.F90	(revision 12143)
@@ -14,8 +14,4 @@
    !!             -   ! 2017-05  (G. Madec) create generic.h90 files to generate all lbc and north fold routines
    !!----------------------------------------------------------------------
-#if defined key_mpp_mpi
-   !!----------------------------------------------------------------------
-   !!   'key_mpp_mpi'             MPI massively parallel processing library
-   !!----------------------------------------------------------------------
    !!           define the generic interfaces of lib_mpp routines
    !!----------------------------------------------------------------------
@@ -23,7 +19,11 @@
    !!   lbc_bdy_lnk   : generic interface for mpp_lnk_bdy_2d and mpp_lnk_bdy_3d routines defined in lib_mpp
    !!----------------------------------------------------------------------
-   USE par_oce        ! ocean dynamics and tracers   
+   USE dom_oce        ! ocean space and time domain
    USE lib_mpp        ! distributed memory computing library
    USE lbcnfd         ! north fold
+   USE in_out_manager ! I/O manager
+
+   IMPLICIT NONE
+   PRIVATE
 
    INTERFACE lbc_lnk
@@ -37,16 +37,28 @@
    END INTERFACE
    !
-   INTERFACE lbc_bdy_lnk
-      MODULE PROCEDURE mpp_lnk_bdy_2d, mpp_lnk_bdy_3d, mpp_lnk_bdy_4d
-   END INTERFACE
-   !
    INTERFACE lbc_lnk_icb
       MODULE PROCEDURE mpp_lnk_2d_icb
    END INTERFACE
 
+   INTERFACE mpp_nfd
+      MODULE PROCEDURE   mpp_nfd_2d    , mpp_nfd_3d    , mpp_nfd_4d
+      MODULE PROCEDURE   mpp_nfd_2d_ptr, mpp_nfd_3d_ptr, mpp_nfd_4d_ptr
+   END INTERFACE
+
    PUBLIC   lbc_lnk       ! ocean/ice lateral boundary conditions
    PUBLIC   lbc_lnk_multi ! modified ocean/ice lateral boundary conditions
-   PUBLIC   lbc_bdy_lnk   ! ocean lateral BDY boundary conditions
    PUBLIC   lbc_lnk_icb   ! iceberg lateral boundary conditions
+
+#if   defined key_mpp_mpi
+!$AGRIF_DO_NOT_TREAT
+   INCLUDE 'mpif.h'
+!$AGRIF_END_DO_NOT_TREAT
+#endif
+
+   INTEGER, PUBLIC, PARAMETER ::   jpfillnothing = 1
+   INTEGER, PUBLIC, PARAMETER ::   jpfillcst     = 2
+   INTEGER, PUBLIC, PARAMETER ::   jpfillcopy    = 3
+   INTEGER, PUBLIC, PARAMETER ::   jpfillperio   = 4
+   INTEGER, PUBLIC, PARAMETER ::   jpfillmpi     = 5
 
    !!----------------------------------------------------------------------
@@ -56,181 +68,4 @@
    !!----------------------------------------------------------------------
 CONTAINS
-
-#else
-   !!----------------------------------------------------------------------
-   !!   Default option                              shared memory computing
-   !!----------------------------------------------------------------------
-   !!                routines setting the appropriate values
-   !!         on first and last row and column of the global domain
-   !!----------------------------------------------------------------------
-   !!   lbc_lnk_sum_3d: compute sum over the halos on a 3D variable on ocean mesh
-   !!   lbc_lnk_sum_3d: compute sum over the halos on a 2D variable on ocean mesh
-   !!   lbc_lnk       : generic interface for lbc_lnk_3d and lbc_lnk_2d
-   !!   lbc_lnk_3d    : set the lateral boundary condition on a 3D variable on ocean mesh
-   !!   lbc_lnk_2d    : set the lateral boundary condition on a 2D variable on ocean mesh
-   !!   lbc_bdy_lnk   : set the lateral BDY boundary condition
-   !!----------------------------------------------------------------------
-   USE oce            ! ocean dynamics and tracers   
-   USE dom_oce        ! ocean space and time domain 
-   USE in_out_manager ! I/O manager
-   USE lbcnfd         ! north fold
-
-   IMPLICIT NONE
-   PRIVATE
-
-   INTERFACE lbc_lnk
-      MODULE PROCEDURE   lbc_lnk_2d      , lbc_lnk_3d      , lbc_lnk_4d
-   END INTERFACE
-   INTERFACE lbc_lnk_ptr
-      MODULE PROCEDURE   lbc_lnk_2d_ptr  , lbc_lnk_3d_ptr  , lbc_lnk_4d_ptr
-   END INTERFACE
-   INTERFACE lbc_lnk_multi
-      MODULE PROCEDURE   lbc_lnk_2d_multi, lbc_lnk_3d_multi, lbc_lnk_4d_multi
-   END INTERFACE
-   !
-   INTERFACE lbc_bdy_lnk
-      MODULE PROCEDURE lbc_bdy_lnk_2d, lbc_bdy_lnk_3d, lbc_bdy_lnk_4d
-   END INTERFACE
-   !
-   INTERFACE lbc_lnk_icb
-      MODULE PROCEDURE lbc_lnk_2d_icb
-   END INTERFACE
-   
-   PUBLIC   lbc_lnk       ! ocean/ice  lateral boundary conditions
-   PUBLIC   lbc_lnk_multi ! modified ocean/ice lateral boundary conditions
-   PUBLIC   lbc_bdy_lnk   ! ocean lateral BDY boundary conditions
-   PUBLIC   lbc_lnk_icb   ! iceberg lateral boundary conditions
-   
-   !!----------------------------------------------------------------------
-   !! NEMO/OCE 4.0 , NEMO Consortium (2018)
-   !! $Id$
-   !! Software governed by the CeCILL license (see ./LICENSE)
-   !!----------------------------------------------------------------------
-CONTAINS
-
-   !!======================================================================
-   !!   Default option                           3D shared memory computing
-   !!======================================================================
-   !!          routines setting land point, or east-west cyclic,
-   !!             or north-south cyclic, or north fold values
-   !!         on first and last row and column of the global domain
-   !!----------------------------------------------------------------------
-
-   !!----------------------------------------------------------------------
-   !!                   ***  routine lbc_lnk_(2,3,4)d  ***
-   !!
-   !!   * Argument : dummy argument use in lbc_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
-   !!                cd_mpp :   optional, fill the overlap area only
-   !!                pval   :   optional, background value (used at closed boundaries)
-   !!----------------------------------------------------------------------
-   !
-   !                       !==  2D array and array of 2D pointer  ==!
-   !
-#  define DIM_2d
-#     define ROUTINE_LNK           lbc_lnk_2d
-#     include "lbc_lnk_generic.h90"
-#     undef ROUTINE_LNK
-#     define MULTI
-#     define ROUTINE_LNK           lbc_lnk_2d_ptr
-#     include "lbc_lnk_generic.h90"
-#     undef ROUTINE_LNK
-#     undef MULTI
-#  undef DIM_2d
-   !
-   !                       !==  3D array and array of 3D pointer  ==!
-   !
-#  define DIM_3d
-#     define ROUTINE_LNK           lbc_lnk_3d
-#     include "lbc_lnk_generic.h90"
-#     undef ROUTINE_LNK
-#     define MULTI
-#     define ROUTINE_LNK           lbc_lnk_3d_ptr
-#     include "lbc_lnk_generic.h90"
-#     undef ROUTINE_LNK
-#     undef MULTI
-#  undef DIM_3d
-   !
-   !                       !==  4D array and array of 4D pointer  ==!
-   !
-#  define DIM_4d
-#     define ROUTINE_LNK           lbc_lnk_4d
-#     include "lbc_lnk_generic.h90"
-#     undef ROUTINE_LNK
-#     define MULTI
-#     define ROUTINE_LNK           lbc_lnk_4d_ptr
-#     include "lbc_lnk_generic.h90"
-#     undef ROUTINE_LNK
-#     undef MULTI
-#  undef DIM_4d
-   
-   !!======================================================================
-   !!   identical routines in both C1D and shared memory computing
-   !!======================================================================
-
-   !!----------------------------------------------------------------------
-   !!                   ***  routine lbc_bdy_lnk_(2,3,4)d  ***
-   !!
-   !!   wrapper rountine to 'lbc_lnk_3d'. This wrapper is used
-   !!   to maintain the same interface with regards to the mpp case
-   !!----------------------------------------------------------------------
-   
-   SUBROUTINE lbc_bdy_lnk_4d( cdname, pt4d, cd_type, psgn, ib_bdy )
-      !!----------------------------------------------------------------------
-      CHARACTER(len=*)          , INTENT(in   ) ::   cdname      ! name of the calling subroutine
-      REAL(wp), DIMENSION(:,:,:,:), INTENT(inout) ::   pt4d      ! 3D array on which the lbc is applied
-      CHARACTER(len=1)          , INTENT(in   ) ::   cd_type   ! nature of pt3d grid-points
-      REAL(wp)                  , INTENT(in   ) ::   psgn      ! sign used across north fold 
-      INTEGER                   , INTENT(in   ) ::   ib_bdy    ! BDY boundary set
-      !!----------------------------------------------------------------------
-      CALL lbc_lnk_4d( cdname, pt4d, cd_type, psgn)
-   END SUBROUTINE lbc_bdy_lnk_4d
-
-   SUBROUTINE lbc_bdy_lnk_3d( cdname, pt3d, cd_type, psgn, ib_bdy )
-      !!----------------------------------------------------------------------
-      CHARACTER(len=*)          , INTENT(in   ) ::   cdname      ! name of the calling subroutine
-      REAL(wp), DIMENSION(:,:,:), INTENT(inout) ::   pt3d      ! 3D array on which the lbc is applied
-      CHARACTER(len=1)          , INTENT(in   ) ::   cd_type   ! nature of pt3d grid-points
-      REAL(wp)                  , INTENT(in   ) ::   psgn      ! sign used across north fold 
-      INTEGER                   , INTENT(in   ) ::   ib_bdy    ! BDY boundary set
-      !!----------------------------------------------------------------------
-      CALL lbc_lnk_3d( cdname, pt3d, cd_type, psgn)
-   END SUBROUTINE lbc_bdy_lnk_3d
-
-
-   SUBROUTINE lbc_bdy_lnk_2d( cdname, pt2d, cd_type, psgn, ib_bdy )
-      !!----------------------------------------------------------------------
-      CHARACTER(len=*)        , INTENT(in   ) ::   cdname      ! name of the calling subroutine
-      REAL(wp), DIMENSION(:,:), INTENT(inout) ::   pt2d      ! 3D array on which the lbc is applied
-      CHARACTER(len=1)        , INTENT(in   ) ::   cd_type   ! nature of pt3d grid-points
-      REAL(wp)                , INTENT(in   ) ::   psgn      ! sign used across north fold 
-      INTEGER                 , INTENT(in   ) ::   ib_bdy    ! BDY boundary set
-      !!----------------------------------------------------------------------
-      CALL lbc_lnk_2d( cdname, pt2d, cd_type, psgn)
-   END SUBROUTINE lbc_bdy_lnk_2d
-
-
-!!gm  This routine should be removed with an optional halos size added in argument of generic routines
-
-   SUBROUTINE lbc_lnk_2d_icb( cdname, pt2d, cd_type, psgn, ki, kj )
-      !!----------------------------------------------------------------------
-      CHARACTER(len=*)        , INTENT(in   ) ::   cdname      ! name of the calling subroutine
-      REAL(wp), DIMENSION(:,:), INTENT(inout) ::   pt2d      ! 2D array on which the lbc is applied
-      CHARACTER(len=1)        , INTENT(in   ) ::   cd_type   ! nature of pt3d grid-points
-      REAL(wp)                , INTENT(in   ) ::   psgn      ! sign used across north fold 
-      INTEGER                 , INTENT(in   ) ::   ki, kj    ! sizes of extra halo (not needed in non-mpp)
-      !!----------------------------------------------------------------------
-      CALL lbc_lnk_2d( cdname, pt2d, cd_type, psgn )
-   END SUBROUTINE lbc_lnk_2d_icb
-!!gm end
-
-#endif
-
-   !!======================================================================
-   !!   identical routines in both distributed and shared memory computing
-   !!======================================================================
 
    !!----------------------------------------------------------------------
@@ -256,6 +91,6 @@
 
 #  define DIM_2d
+#     define ROUTINE_LOAD           load_ptr_2d
 #     define ROUTINE_MULTI          lbc_lnk_2d_multi
-#     define ROUTINE_LOAD           load_ptr_2d
 #     include "lbc_lnk_multi_generic.h90"
 #     undef ROUTINE_MULTI
@@ -263,8 +98,7 @@
 #  undef DIM_2d
 
-
 #  define DIM_3d
+#     define ROUTINE_LOAD           load_ptr_3d
 #     define ROUTINE_MULTI          lbc_lnk_3d_multi
-#     define ROUTINE_LOAD           load_ptr_3d
 #     include "lbc_lnk_multi_generic.h90"
 #     undef ROUTINE_MULTI
@@ -272,8 +106,7 @@
 #  undef DIM_3d
 
-
 #  define DIM_4d
+#     define ROUTINE_LOAD           load_ptr_4d
 #     define ROUTINE_MULTI          lbc_lnk_4d_multi
-#     define ROUTINE_LOAD           load_ptr_4d
 #     include "lbc_lnk_multi_generic.h90"
 #     undef ROUTINE_MULTI
@@ -281,5 +114,394 @@
 #  undef DIM_4d
 
+   !!----------------------------------------------------------------------
+   !!                   ***  routine mpp_lnk_(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  ==!
+   !
+#  define DIM_2d
+#     define ROUTINE_LNK           mpp_lnk_2d
+#     include "mpp_lnk_generic.h90"
+#     undef ROUTINE_LNK
+#     define MULTI
+#     define ROUTINE_LNK           mpp_lnk_2d_ptr
+#     include "mpp_lnk_generic.h90"
+#     undef ROUTINE_LNK
+#     undef MULTI
+#  undef DIM_2d
+   !
+   !                       !==  3D array and array of 3D pointer  ==!
+   !
+#  define DIM_3d
+#     define ROUTINE_LNK           mpp_lnk_3d
+#     include "mpp_lnk_generic.h90"
+#     undef ROUTINE_LNK
+#     define MULTI
+#     define ROUTINE_LNK           mpp_lnk_3d_ptr
+#     include "mpp_lnk_generic.h90"
+#     undef ROUTINE_LNK
+#     undef MULTI
+#  undef DIM_3d
+   !
+   !                       !==  4D array and array of 4D pointer  ==!
+   !
+#  define DIM_4d
+#     define ROUTINE_LNK           mpp_lnk_4d
+#     include "mpp_lnk_generic.h90"
+#     undef ROUTINE_LNK
+#     define MULTI
+#     define ROUTINE_LNK           mpp_lnk_4d_ptr
+#     include "mpp_lnk_generic.h90"
+#     undef ROUTINE_LNK
+#     undef MULTI
+#  undef DIM_4d
+
+   !!----------------------------------------------------------------------
+   !!                   ***  routine mpp_nfd_(2,3,4)d  ***
+   !!
+   !!   * Argument : dummy argument use in mpp_nfd_... 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  ==!
+   !
+#  define DIM_2d
+#     define ROUTINE_NFD           mpp_nfd_2d
+#     include "mpp_nfd_generic.h90"
+#     undef ROUTINE_NFD
+#     define MULTI
+#     define ROUTINE_NFD           mpp_nfd_2d_ptr
+#     include "mpp_nfd_generic.h90"
+#     undef ROUTINE_NFD
+#     undef MULTI
+#  undef DIM_2d
+   !
+   !                       !==  3D array and array of 3D pointer  ==!
+   !
+#  define DIM_3d
+#     define ROUTINE_NFD           mpp_nfd_3d
+#     include "mpp_nfd_generic.h90"
+#     undef ROUTINE_NFD
+#     define MULTI
+#     define ROUTINE_NFD           mpp_nfd_3d_ptr
+#     include "mpp_nfd_generic.h90"
+#     undef ROUTINE_NFD
+#     undef MULTI
+#  undef DIM_3d
+   !
+   !                       !==  4D array and array of 4D pointer  ==!
+   !
+#  define DIM_4d
+#     define ROUTINE_NFD           mpp_nfd_4d
+#     include "mpp_nfd_generic.h90"
+#     undef ROUTINE_NFD
+#     define MULTI
+#     define ROUTINE_NFD           mpp_nfd_4d_ptr
+#     include "mpp_nfd_generic.h90"
+#     undef ROUTINE_NFD
+#     undef MULTI
+#  undef DIM_4d
+
+
    !!======================================================================
+
+
+
+   SUBROUTINE mpp_lbc_north_icb( pt2d, cd_type, psgn, kextj)
+      !!---------------------------------------------------------------------
+      !!                   ***  routine mpp_lbc_north_icb  ***
+      !!
+      !! ** Purpose :   Ensure proper north fold horizontal bondary condition
+      !!              in mpp configuration in case of jpn1 > 1 and for 2d
+      !!              array with outer extra halo
+      !!
+      !! ** Method  :   North fold condition and mpp with more than one proc
+      !!              in i-direction require a specific treatment. We gather
+      !!              the 4+kextj northern lines of the global domain on 1
+      !!              processor and apply lbc north-fold on this sub array.
+      !!              Then we scatter the north fold array back to the processors.
+      !!              This routine accounts for an extra halo with icebergs
+      !!              and assumes ghost rows and columns have been suppressed.
+      !!
+      !!----------------------------------------------------------------------
+      REAL(wp), DIMENSION(:,:), INTENT(inout) ::   pt2d     ! 2D array with extra halo
+      CHARACTER(len=1)        , INTENT(in   ) ::   cd_type  ! nature of pt3d grid-points
+      !                                                     !   = T ,  U , V , F or W -points
+      REAL(wp)                , INTENT(in   ) ::   psgn     ! = -1. the sign change across the
+      !!                                                    ! north fold, =  1. otherwise
+      INTEGER                 , INTENT(in   ) ::   kextj    ! Extra halo width at north fold
+      !
+      INTEGER ::   ji, jj, jr
+      INTEGER ::   ierr, itaille, ildi, ilei, iilb
+      INTEGER ::   ipj, ij, iproc
+      !
+      REAL(wp), DIMENSION(:,:)  , ALLOCATABLE  ::  ztab_e, znorthloc_e
+      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE  ::  znorthgloio_e
+      !!----------------------------------------------------------------------
+#if defined key_mpp_mpi
+      !
+      ipj=4
+      ALLOCATE(        ztab_e(jpiglo, 1-kextj:ipj+kextj)       ,       &
+     &            znorthloc_e(jpimax, 1-kextj:ipj+kextj)       ,       &
+     &          znorthgloio_e(jpimax, 1-kextj:ipj+kextj,jpni)    )
+      !
+      ztab_e(:,:)      = 0._wp
+      znorthloc_e(:,:) = 0._wp
+      !
+      ij = 1 - kextj
+      ! put the last ipj+2*kextj lines of pt2d into znorthloc_e 
+      DO jj = jpj - ipj + 1 - kextj , jpj + kextj
+         znorthloc_e(1:jpi,ij)=pt2d(1:jpi,jj)
+         ij = ij + 1
+      END DO
+      !
+      itaille = jpimax * ( ipj + 2*kextj )
+      !
+      IF( ln_timing ) CALL tic_tac(.TRUE.)
+      CALL MPI_ALLGATHER( znorthloc_e(1,1-kextj)    , itaille, MPI_DOUBLE_PRECISION,    &
+         &                znorthgloio_e(1,1-kextj,1), itaille, MPI_DOUBLE_PRECISION,    &
+         &                ncomm_north, ierr )
+      !
+      IF( ln_timing ) CALL tic_tac(.FALSE.)
+      !
+      DO jr = 1, ndim_rank_north            ! recover the global north array
+         iproc = nrank_north(jr) + 1
+         ildi = nldit (iproc)
+         ilei = nleit (iproc)
+         iilb = nimppt(iproc)
+         DO jj = 1-kextj, ipj+kextj
+            DO ji = ildi, ilei
+               ztab_e(ji+iilb-1,jj) = znorthgloio_e(ji,jj,jr)
+            END DO
+         END DO
+      END DO
+
+      ! 2. North-Fold boundary conditions
+      ! ----------------------------------
+      CALL lbc_nfd( ztab_e(:,1-kextj:ipj+kextj), cd_type, psgn, kextj )
+
+      ij = 1 - kextj
+      !! Scatter back to pt2d
+      DO jj = jpj - ipj + 1 - kextj , jpj + kextj
+         DO ji= 1, jpi
+            pt2d(ji,jj) = ztab_e(ji+nimpp-1,ij)
+         END DO
+         ij  = ij +1
+      END DO
+      !
+      DEALLOCATE( ztab_e, znorthloc_e, znorthgloio_e )
+      !
+#endif
+   END SUBROUTINE mpp_lbc_north_icb
+
+
+   SUBROUTINE mpp_lnk_2d_icb( cdname, pt2d, cd_type, psgn, kexti, kextj )
+      !!----------------------------------------------------------------------
+      !!                  ***  routine mpp_lnk_2d_icb  ***
+      !!
+      !! ** Purpose :   Message passing management for 2d array (with extra halo for icebergs)
+      !!                This routine receives a (1-kexti:jpi+kexti,1-kexti:jpj+kextj)
+      !!                array (usually (0:jpi+1, 0:jpj+1)) from lbc_lnk_icb calls.
+      !!
+      !! ** Method  :   Use mppsend and mpprecv function for passing mask
+      !!      between processors following neighboring subdomains.
+      !!            domain parameters
+      !!                    jpi    : first dimension of the local subdomain
+      !!                    jpj    : second dimension of the local subdomain
+      !!                    kexti  : number of columns for extra outer halo
+      !!                    kextj  : number of rows for extra outer halo
+      !!                    nbondi : mark for "east-west local boundary"
+      !!                    nbondj : mark for "north-south local boundary"
+      !!                    noea   : number for local neighboring processors
+      !!                    nowe   : number for local neighboring processors
+      !!                    noso   : number for local neighboring processors
+      !!                    nono   : number for local neighboring processors
+      !!----------------------------------------------------------------------
+      CHARACTER(len=*)                                        , INTENT(in   ) ::   cdname      ! name of the calling subroutine
+      REAL(wp), DIMENSION(1-kexti:jpi+kexti,1-kextj:jpj+kextj), INTENT(inout) ::   pt2d     ! 2D array with extra halo
+      CHARACTER(len=1)                                        , INTENT(in   ) ::   cd_type  ! nature of ptab array grid-points
+      REAL(wp)                                                , INTENT(in   ) ::   psgn     ! sign used across the north fold
+      INTEGER                                                 , INTENT(in   ) ::   kexti    ! extra i-halo width
+      INTEGER                                                 , INTENT(in   ) ::   kextj    ! extra j-halo width
+      !
+      INTEGER  ::   jl   ! dummy loop indices
+      INTEGER  ::   imigr, iihom, ijhom        ! local integers
+      INTEGER  ::   ipreci, iprecj             !   -       -
+      INTEGER  ::   ml_req1, ml_req2, ml_err   ! for key_mpi_isend
+      INTEGER, DIMENSION(MPI_STATUS_SIZE) ::   ml_stat   ! for key_mpi_isend
+      !!
+      REAL(wp), DIMENSION(1-kexti:jpi+kexti,nn_hls+kextj,2) ::   r2dns, r2dsn
+      REAL(wp), DIMENSION(1-kextj:jpj+kextj,nn_hls+kexti,2) ::   r2dwe, r2dew
+      !!----------------------------------------------------------------------
+
+      ipreci = nn_hls + kexti      ! take into account outer extra 2D overlap area
+      iprecj = nn_hls + kextj
+
+      IF( narea == 1 .AND. numcom == -1 ) CALL mpp_report( cdname, 1, 1, 1, ld_lbc = .TRUE. )
+
+      ! 1. standard boundary treatment
+      ! ------------------------------
+      ! Order matters Here !!!!
+      !
+      !                                      ! East-West boundaries
+      !                                           !* Cyclic east-west
+      IF( l_Iperio ) THEN
+         pt2d(1-kexti:     1   ,:) = pt2d(jpim1-kexti: jpim1 ,:)       ! east
+         pt2d(  jpi  :jpi+kexti,:) = pt2d(     2     :2+kexti,:)       ! west
+         !
+      ELSE                                        !* closed
+         IF( .NOT. cd_type == 'F' )   pt2d(  1-kexti   :nn_hls   ,:) = 0._wp    ! east except at F-point
+                                      pt2d(jpi-nn_hls+1:jpi+kexti,:) = 0._wp    ! west
+      ENDIF
+      !                                      ! North-South boundaries
+      IF( l_Jperio ) THEN                         !* cyclic (only with no mpp j-split)
+         pt2d(:,1-kextj:     1   ) = pt2d(:,jpjm1-kextj:  jpjm1)       ! north
+         pt2d(:,  jpj  :jpj+kextj) = pt2d(:,     2     :2+kextj)       ! south
+      ELSE                                        !* closed
+         IF( .NOT. cd_type == 'F' )   pt2d(:,  1-kextj   :nn_hls   ) = 0._wp    ! north except at F-point
+                                      pt2d(:,jpj-nn_hls+1:jpj+kextj) = 0._wp    ! south
+      ENDIF
+      !
+
+      ! north fold treatment
+      ! -----------------------
+      IF( npolj /= 0 ) THEN
+         !
+         SELECT CASE ( jpni )
+                   CASE ( 1 )     ;   CALL lbc_nfd          ( pt2d(1:jpi,1:jpj+kextj), cd_type, psgn, kextj )
+                   CASE DEFAULT   ;   CALL mpp_lbc_north_icb( pt2d(1:jpi,1:jpj+kextj), cd_type, psgn, kextj )
+         END SELECT
+         !
+      ENDIF
+
+      ! 2. East and west directions exchange
+      ! ------------------------------------
+      ! we play with the neigbours AND the row number because of the periodicity
+      !
+      SELECT CASE ( nbondi )      ! Read Dirichlet lateral conditions
+      CASE ( -1, 0, 1 )                ! all exept 2 (i.e. close case)
+         iihom = jpi-nreci-kexti
+         DO jl = 1, ipreci
+            r2dew(:,jl,1) = pt2d(nn_hls+jl,:)
+            r2dwe(:,jl,1) = pt2d(iihom +jl,:)
+         END DO
+      END SELECT
+      !
+      !                           ! Migrations
+      imigr = ipreci * ( jpj + 2*kextj )
+      !
+      IF( ln_timing ) CALL tic_tac(.TRUE.)
+      !
+      SELECT CASE ( nbondi )
+      CASE ( -1 )
+         CALL mppsend( 2, r2dwe(1-kextj,1,1), imigr, noea, ml_req1 )
+         CALL mpprecv( 1, r2dew(1-kextj,1,2), imigr, noea )
+         CALL mpi_wait(ml_req1,ml_stat,ml_err)
+      CASE ( 0 )
+         CALL mppsend( 1, r2dew(1-kextj,1,1), imigr, nowe, ml_req1 )
+         CALL mppsend( 2, r2dwe(1-kextj,1,1), imigr, noea, ml_req2 )
+         CALL mpprecv( 1, r2dew(1-kextj,1,2), imigr, noea )
+         CALL mpprecv( 2, r2dwe(1-kextj,1,2), imigr, nowe )
+         CALL mpi_wait(ml_req1,ml_stat,ml_err)
+         CALL mpi_wait(ml_req2,ml_stat,ml_err)
+      CASE ( 1 )
+         CALL mppsend( 1, r2dew(1-kextj,1,1), imigr, nowe, ml_req1 )
+         CALL mpprecv( 2, r2dwe(1-kextj,1,2), imigr, nowe )
+         CALL mpi_wait(ml_req1,ml_stat,ml_err)
+      END SELECT
+      !
+      IF( ln_timing ) CALL tic_tac(.FALSE.)
+      !
+      !                           ! Write Dirichlet lateral conditions
+      iihom = jpi - nn_hls
+      !
+      SELECT CASE ( nbondi )
+      CASE ( -1 )
+         DO jl = 1, ipreci
+            pt2d(iihom+jl,:) = r2dew(:,jl,2)
+         END DO
+      CASE ( 0 )
+         DO jl = 1, ipreci
+            pt2d(jl-kexti,:) = r2dwe(:,jl,2)
+            pt2d(iihom+jl,:) = r2dew(:,jl,2)
+         END DO
+      CASE ( 1 )
+         DO jl = 1, ipreci
+            pt2d(jl-kexti,:) = r2dwe(:,jl,2)
+         END DO
+      END SELECT
+
+
+      ! 3. North and south directions
+      ! -----------------------------
+      ! always closed : we play only with the neigbours
+      !
+      IF( nbondj /= 2 ) THEN      ! Read Dirichlet lateral conditions
+         ijhom = jpj-nrecj-kextj
+         DO jl = 1, iprecj
+            r2dsn(:,jl,1) = pt2d(:,ijhom +jl)
+            r2dns(:,jl,1) = pt2d(:,nn_hls+jl)
+         END DO
+      ENDIF
+      !
+      !                           ! Migrations
+      imigr = iprecj * ( jpi + 2*kexti )
+      !
+      IF( ln_timing ) CALL tic_tac(.TRUE.)
+      !
+      SELECT CASE ( nbondj )
+      CASE ( -1 )
+         CALL mppsend( 4, r2dsn(1-kexti,1,1), imigr, nono, ml_req1 )
+         CALL mpprecv( 3, r2dns(1-kexti,1,2), imigr, nono )
+         CALL mpi_wait(ml_req1,ml_stat,ml_err)
+      CASE ( 0 )
+         CALL mppsend( 3, r2dns(1-kexti,1,1), imigr, noso, ml_req1 )
+         CALL mppsend( 4, r2dsn(1-kexti,1,1), imigr, nono, ml_req2 )
+         CALL mpprecv( 3, r2dns(1-kexti,1,2), imigr, nono )
+         CALL mpprecv( 4, r2dsn(1-kexti,1,2), imigr, noso )
+         CALL mpi_wait(ml_req1,ml_stat,ml_err)
+         CALL mpi_wait(ml_req2,ml_stat,ml_err)
+      CASE ( 1 )
+         CALL mppsend( 3, r2dns(1-kexti,1,1), imigr, noso, ml_req1 )
+         CALL mpprecv( 4, r2dsn(1-kexti,1,2), imigr, noso )
+         CALL mpi_wait(ml_req1,ml_stat,ml_err)
+      END SELECT
+      !
+      IF( ln_timing ) CALL tic_tac(.FALSE.)
+      !
+      !                           ! Write Dirichlet lateral conditions
+      ijhom = jpj - nn_hls
+      !
+      SELECT CASE ( nbondj )
+      CASE ( -1 )
+         DO jl = 1, iprecj
+            pt2d(:,ijhom+jl) = r2dns(:,jl,2)
+         END DO
+      CASE ( 0 )
+         DO jl = 1, iprecj
+            pt2d(:,jl-kextj) = r2dsn(:,jl,2)
+            pt2d(:,ijhom+jl) = r2dns(:,jl,2)
+         END DO
+      CASE ( 1 )
+         DO jl = 1, iprecj
+            pt2d(:,jl-kextj) = r2dsn(:,jl,2)
+         END DO
+      END SELECT
+      !
+   END SUBROUTINE mpp_lnk_2d_icb
+   
 END MODULE lbclnk
 
