Index: NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/CRS/crsdom.F90
===================================================================
--- NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/CRS/crsdom.F90	(revision 11191)
+++ NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/CRS/crsdom.F90	(revision 11192)
@@ -296,6 +296,6 @@
       ENDDO
 
-      CALL crs_lbc_lnk( p_e1_crs, cd_type, 1.0, pval=1.0 )
-      CALL crs_lbc_lnk( p_e2_crs, cd_type, 1.0, pval=1.0 )
+      CALL crs_lbc_lnk( p_e1_crs, cd_type, 1.0, pfillval=1.0 )
+      CALL crs_lbc_lnk( p_e2_crs, cd_type, 1.0, pfillval=1.0 )
 
    END SUBROUTINE crs_dom_hgr
@@ -1748,6 +1748,6 @@
        ENDDO
                   
-       CALL crs_lbc_lnk( p_e3_crs    , cd_type, 1.0, pval=1.0 )  
-       CALL crs_lbc_lnk( p_e3_max_crs, cd_type, 1.0, pval=1.0 )  
+       CALL crs_lbc_lnk( p_e3_crs    , cd_type, 1.0, pfillval=1.0 )  
+       CALL crs_lbc_lnk( p_e3_max_crs, cd_type, 1.0, pfillval=1.0 )  
        !              
        !
@@ -1857,6 +1857,6 @@
       ENDDO   
 
-      CALL crs_lbc_lnk( p_surf_crs    , cd_type, 1.0, pval=1.0 )
-      CALL crs_lbc_lnk( p_surf_crs_msk, cd_type, 1.0, pval=1.0 )
+      CALL crs_lbc_lnk( p_surf_crs    , cd_type, 1.0, pfillval=1.0 )
+      CALL crs_lbc_lnk( p_surf_crs_msk, cd_type, 1.0, pfillval=1.0 )
 
    END SUBROUTINE crs_dom_sfc
Index: NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/CRS/crslbclnk.F90
===================================================================
--- NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/CRS/crslbclnk.F90	(revision 11191)
+++ NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/CRS/crslbclnk.F90	(revision 11192)
@@ -27,5 +27,5 @@
 CONTAINS
 
-   SUBROUTINE crs_lbc_lnk_3d( pt3d1, cd_type1, psgn, cd_mpp, pval )
+   SUBROUTINE crs_lbc_lnk_3d( pt3d1, cd_type1, psgn, kfillmode, pfillval  )
       !!---------------------------------------------------------------------
       !!                  ***  SUBROUTINE crs_lbc_lnk  ***
@@ -40,22 +40,15 @@
       REAL(wp)                                , INTENT(in   ) ::   psgn     ! control of the sign
       REAL(wp), DIMENSION(jpi_crs,jpj_crs,jpk), INTENT(inout) ::   pt3d1    ! 3D array on which the lbc is applied
-      REAL(wp)                      , OPTIONAL, INTENT(in   ) ::   pval     ! valeur sur les halo
-      CHARACTER(len=3)              , OPTIONAL, INTENT(in   ) ::   cd_mpp   ! MPP only (here do nothing)
+      INTEGER                     , OPTIONAL  , INTENT(in   ) ::   kfillmode   ! filling method for halo over land (default = cst)
+      REAL(wp)                    , OPTIONAL  , INTENT(in   ) ::   pfillval    ! background value (used at closed boundaries)
       !
       LOGICAL  ::   ll_grid_crs
-      REAL(wp) ::   zval   ! valeur sur les halo
       !!----------------------------------------------------------------------
       !
       ll_grid_crs = ( jpi == jpi_crs )
       !
-      IF( PRESENT(pval) ) THEN   ;   zval = pval
-      ELSE                       ;   zval = 0._wp
-      ENDIF
-      !
       IF( .NOT.ll_grid_crs )   CALL dom_grid_crs   ! Save the parent grid information  & Switch to coarse grid domain
       !
-      IF( PRESENT( cd_mpp ) ) THEN   ;   CALL lbc_lnk( 'crslbclnk', pt3d1, cd_type1, psgn, cd_mpp, pval=zval  )
-      ELSE                           ;   CALL lbc_lnk( 'crslbclnk', pt3d1, cd_type1, psgn        , pval=zval  )
-      ENDIF
+      CALL lbc_lnk( 'crslbclnk', pt3d1, cd_type1, psgn, kfillmode, pfillval )
       !
       IF( .NOT.ll_grid_crs )   CALL dom_grid_glo   ! Return to parent grid domain
@@ -64,5 +57,5 @@
    
    
-   SUBROUTINE crs_lbc_lnk_2d(pt2d, cd_type, psgn, cd_mpp, pval)
+   SUBROUTINE crs_lbc_lnk_2d(pt2d, cd_type, psgn, kfillmode, pfillval )
       !!---------------------------------------------------------------------
       !!                  ***  SUBROUTINE crs_lbc_lnk  ***
@@ -77,22 +70,15 @@
       REAL(wp)                            , INTENT(in   ) ::   psgn     ! control of the sign
       REAL(wp), DIMENSION(jpi_crs,jpj_crs), INTENT(inout) ::   pt2d     ! 2D array on which the lbc is applied
-      REAL(wp)                  , OPTIONAL, INTENT(in   ) ::   pval     ! valeur sur les halo
-      CHARACTER(len=3)          , OPTIONAL, INTENT(in   ) ::   cd_mpp   ! MPP only (here do nothing)
+      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  ::   ll_grid_crs
-      REAL(wp) ::   zval     ! valeur sur les halo
       !!----------------------------------------------------------------------
       !
       ll_grid_crs = ( jpi == jpi_crs )
       !
-      IF( PRESENT(pval) ) THEN   ;   zval = pval
-      ELSE                       ;   zval = 0._wp
-      ENDIF
-      !
       IF( .NOT.ll_grid_crs )   CALL dom_grid_crs   ! Save the parent grid information  & Switch to coarse grid domain
       !
-      IF( PRESENT( cd_mpp ) ) THEN   ;   CALL lbc_lnk( 'crslbclnk', pt2d, cd_type, psgn, cd_mpp, pval=zval  )
-      ELSE                           ;   CALL lbc_lnk( 'crslbclnk', pt2d, cd_type, psgn        , pval=zval  )
-      ENDIF
+      CALL lbc_lnk( 'crslbclnk', pt2d, cd_type, psgn, kfillmode, pfillval )
       !
       IF( .NOT.ll_grid_crs )   CALL dom_grid_glo   ! Return to parent grid domain
Index: NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/IOM/iom.F90
===================================================================
--- NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/IOM/iom.F90	(revision 11191)
+++ NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/IOM/iom.F90	(revision 11192)
@@ -1270,9 +1270,9 @@
                !--- overlap areas and extra hallows (mpp)
                IF(     PRESENT(pv_r2d) .AND. idom /= jpdom_unknown ) THEN
-                  CALL lbc_lnk( 'iom', pv_r2d,'Z',-999.,'no0' )
+                  CALL lbc_lnk( 'iom', pv_r2d,'Z', -999., kfillmode = jpfillnothing )
                ELSEIF( PRESENT(pv_r3d) .AND. idom /= jpdom_unknown ) THEN
                   ! this if could be simplified with the new lbc_lnk that works with any size of the 3rd dimension
                   IF( icnt(3) == inlev ) THEN
-                     CALL lbc_lnk( 'iom', pv_r3d,'Z',-999.,'no0' )
+                     CALL lbc_lnk( 'iom', pv_r3d,'Z', -999., kfillmode = jpfillnothing )
                   ELSE   ! put some arbitrary value (a call to lbc_lnk will be done later...)
                      DO jj = nlcj+1, jpj   ;   pv_r3d(1:nlci, jj, :) = pv_r3d(1:nlci, nlej, :)   ;   END DO
@@ -1299,5 +1299,5 @@
             CALL xios_recv_field( trim(cdvar), pv_r3d)
             IF(idom /= jpdom_unknown ) then
-                CALL lbc_lnk( 'iom', pv_r3d,'Z',-999.,'no0' )
+                CALL lbc_lnk( 'iom', pv_r3d,'Z', -999., kfillmode = jpfillnothing)
             ENDIF
          ELSEIF( PRESENT(pv_r2d) ) THEN
@@ -1306,5 +1306,5 @@
             CALL xios_recv_field( trim(cdvar), pv_r2d)
             IF(idom /= jpdom_unknown ) THEN
-                CALL lbc_lnk('iom', pv_r2d,'Z',-999.,'no0')
+                CALL lbc_lnk('iom', pv_r2d,'Z',-999., kfillmode = jpfillnothing)
             ENDIF
          ELSEIF( PRESENT(pv_r1d) ) THEN
Index: NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/LBC/lbc_lnk_generic.h90
===================================================================
--- NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/LBC/lbc_lnk_generic.h90	(revision 11191)
+++ NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/LBC/lbc_lnk_generic.h90	(revision 11192)
@@ -46,8 +46,8 @@
 
 #if defined MULTI
-   SUBROUTINE ROUTINE_LNK( cdname, ptab, cd_nat, psgn, kfld, cd_mpp, pval )
+   SUBROUTINE ROUTINE_LNK( cdname, ptab, cd_nat, psgn, kfld, kfillmode, pfillval )
       INTEGER                     , INTENT(in   ) ::   kfld        ! number of pt3d arrays
 #else
-   SUBROUTINE ROUTINE_LNK( cdname, ptab, cd_nat, psgn      , cd_mpp, pval )
+   SUBROUTINE ROUTINE_LNK( cdname, ptab, cd_nat, psgn      , kfillmode, pfillval )
 #endif
       CHARACTER(len=*)            , INTENT(in   ) ::   cdname      ! name of the calling subroutine
@@ -55,6 +55,6 @@
       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
-      CHARACTER(len=3), OPTIONAL  , INTENT(in   ) ::   cd_mpp      ! fill the overlap area only
-      REAL(wp)        , OPTIONAL  , INTENT(in   ) ::   pval        ! background value (used at closed boundaries)
+      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)
       !
       INTEGER  ::    ji,  jj,  jk,  jl, jh, jf   ! dummy loop indices
Index: NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/LBC/lbc_lnk_multi_generic.h90
===================================================================
--- NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/LBC/lbc_lnk_multi_generic.h90	(revision 11191)
+++ NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/LBC/lbc_lnk_multi_generic.h90	(revision 11192)
@@ -20,5 +20,5 @@
       &                    , pt5, cdna5, psgn5, pt6 , cdna6 , psgn6 , pt7 , cdna7 , psgn7 , pt8, cdna8, psgn8   &
       &                    , pt9, cdna9, psgn9, pt10, cdna10, psgn10, pt11, cdna11, psgn11                      &
-      &                    , cd_mpp, pval )
+      &                    , kfillmode, pfillval )
       LOGICAL, DIMENSION(4)        , INTENT(in   ) ::   lsend, lrecv   ! indicate how communications are to be carried out
 #else
@@ -27,16 +27,16 @@
       &                    , pt5, cdna5, psgn5, pt6 , cdna6 , psgn6 , pt7 , cdna7 , psgn7 , pt8, cdna8, psgn8   &
       &                    , pt9, cdna9, psgn9, pt10, cdna10, psgn10, pt11, cdna11, psgn11                      &
-      &                    , cd_mpp, pval )
+      &                    , kfillmode, pfillval )
 #endif
       !!---------------------------------------------------------------------
-      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
-      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
-      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
-      CHARACTER(len=3)   , OPTIONAL        , INTENT(in   ) ::  cd_mpp  ! fill the overlap area only
-      REAL(wp)           , OPTIONAL        , INTENT(in   ) ::  pval    ! background value (used at closed boundaries)
+      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
+      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
+      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
+      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)
       !!
       INTEGER                          ::   kfld        ! number of elements that will be attributed
@@ -64,7 +64,7 @@
       !
 #if defined IS_BDY
-      CALL lbc_bdy_lnk_ptr( cdname, lsend, lrecv, ptab_ptr, cdna_ptr, psgn_ptr, kfld               )
+      CALL lbc_bdy_lnk_ptr( cdname, lsend, lrecv, ptab_ptr, cdna_ptr, psgn_ptr, kfld                      )
 #else 
-      CALL lbc_lnk_ptr    ( cdname,               ptab_ptr, cdna_ptr, psgn_ptr, kfld, cd_mpp, pval )
+      CALL lbc_lnk_ptr    ( cdname,               ptab_ptr, cdna_ptr, psgn_ptr, kfld, kfillmode, pfillval )
 #endif
       !
Index: NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/LBC/lbclnk.F90
===================================================================
--- NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/LBC/lbclnk.F90	(revision 11191)
+++ NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/LBC/lbclnk.F90	(revision 11192)
@@ -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
@@ -51,10 +51,20 @@
    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
+   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_bdy_lnk_multi ! modified ocean lateral BDY boundary conditions
-   PUBLIC   lbc_lnk_icb       ! iceberg lateral 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
    !!----------------------------------------------------------------------
    !! NEMO/OCE 4.0 , NEMO Consortium (2018)
@@ -63,181 +73,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
-   !!======================================================================
 
    !!----------------------------------------------------------------------
@@ -307,6 +140,443 @@
 #  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
+   !!                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           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
+   !!                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_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
+
+   !!----------------------------------------------------------------------
+   !!                   ***  routine mpp_lnk_bdy_(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
+   !!                kb_bdy :   BDY boundary set
+   !!                kfld   :   optional, number of pt3d arrays
+   !!----------------------------------------------------------------------
+   !
+   !                       !==  2D array and array of 2D pointer  ==!
+   !
+#  define DIM_2d
+#     define ROUTINE_BDY           mpp_lnk_bdy_2d
+#     include "mpp_bdy_generic.h90"
+#     undef ROUTINE_BDY
+#     define MULTI
+#     define ROUTINE_BDY           mpp_lnk_bdy_2d_ptr
+#     include "mpp_bdy_generic.h90"
+#     undef ROUTINE_BDY
+#     undef MULTI
+#  undef DIM_2d
+   !
+   !                       !==  3D array and array of 3D pointer  ==!
+   !
+#  define DIM_3d
+#     define ROUTINE_BDY           mpp_lnk_bdy_3d
+#     include "mpp_bdy_generic.h90"
+#     undef ROUTINE_BDY
+#     define MULTI
+#     define ROUTINE_BDY           mpp_lnk_bdy_3d_ptr
+#     include "mpp_bdy_generic.h90"
+#     undef ROUTINE_BDY
+#     undef MULTI
+#  undef DIM_3d
+   !
+   !                       !==  4D array and array of 4D pointer  ==!
+   !
+#  define DIM_4d
+#     define ROUTINE_BDY           mpp_lnk_bdy_4d
+#     include "mpp_bdy_generic.h90"
+#     undef ROUTINE_BDY
+#     define MULTI
+#     define ROUTINE_BDY           mpp_lnk_bdy_4d_ptr
+#     include "mpp_bdy_generic.h90"
+#     undef ROUTINE_BDY
+#     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 )
+         IF(l_isend) 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 )
+         IF(l_isend) CALL mpi_wait(ml_req1,ml_stat,ml_err)
+         IF(l_isend) 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 )
+         IF(l_isend) 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 )
+         IF(l_isend) 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 )
+         IF(l_isend) CALL mpi_wait(ml_req1,ml_stat,ml_err)
+         IF(l_isend) 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 )
+         IF(l_isend) 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
 
Index: NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/LBC/lib_mpp.F90
===================================================================
--- NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/LBC/lib_mpp.F90	(revision 11191)
+++ NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/LBC/lib_mpp.F90	(revision 11192)
@@ -34,9 +34,5 @@
    !!   get_unit      : give the index of an unused logical unit
    !!----------------------------------------------------------------------
-#if   defined key_mpp_mpi
-   !!----------------------------------------------------------------------
-   !!   'key_mpp_mpi'             MPI massively parallel processing library
-   !!----------------------------------------------------------------------
-   !!   lib_mpp_alloc : allocate mpp arrays
+   !!----------------------------------------------------------------------
    !!   mynode        : indentify the processor unit
    !!   mpp_lnk       : interface (defined in lbclnk) for message passing of 2d or 3d arrays (mpp_lnk_2d, mpp_lnk_3d)
@@ -57,31 +53,12 @@
    !!----------------------------------------------------------------------
    USE dom_oce        ! ocean space and time domain
-   USE lbcnfd         ! north fold treatment
    USE in_out_manager ! I/O manager
 
    IMPLICIT NONE
    PRIVATE
-
-   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
-
-   ! Interface associated to the mpp_lnk_... routines is defined in lbclnk
-   PUBLIC   mpp_lnk_2d        , mpp_lnk_3d        , mpp_lnk_4d
-   PUBLIC   mpp_lnk_2d_ptr    , mpp_lnk_3d_ptr    , mpp_lnk_4d_ptr
-   PUBLIC   mpp_lnk_bdy_2d    , mpp_lnk_bdy_3d    , mpp_lnk_bdy_4d
-   PUBLIC   mpp_lnk_bdy_2d_ptr, mpp_lnk_bdy_3d_ptr, mpp_lnk_bdy_4d_ptr
-   !
-!!gm  this should be useless
-   PUBLIC   mpp_nfd_2d    , mpp_nfd_3d    , mpp_nfd_4d
-   PUBLIC   mpp_nfd_2d_ptr, mpp_nfd_3d_ptr, mpp_nfd_4d_ptr
-!!gm end
    !
    PUBLIC   ctl_stop, ctl_warn, get_unit, ctl_opn, ctl_nam
    PUBLIC   mynode, mppstop, mppsync, mpp_comm_free
    PUBLIC   mpp_ini_north
-   PUBLIC   mpp_lnk_2d_icb
-   PUBLIC   mpp_lbc_north_icb
    PUBLIC   mpp_min, mpp_max, mpp_sum, mpp_minloc, mpp_maxloc
    PUBLIC   mpp_delay_max, mpp_delay_sum, mpp_delay_rcv
@@ -89,4 +66,6 @@
    PUBLIC   mpp_ini_znl
    PUBLIC   mppsend, mpprecv                          ! needed by TAM and ICB routines
+   PUBLIC   mpp_report
+   PUBLIC   tic_tac
    
    !! * Interfaces
@@ -114,9 +93,14 @@
    !!  MPI  variable definition !!
    !! ========================= !!
+#if   defined key_mpp_mpi
 !$AGRIF_DO_NOT_TREAT
    INCLUDE 'mpif.h'
 !$AGRIF_END_DO_NOT_TREAT
-
    LOGICAL, PUBLIC, PARAMETER ::   lk_mpp = .TRUE.    !: mpp flag
+#else   
+   INTEGER, PUBLIC, PARAMETER ::   MPI_STATUS_SIZE = 1
+   INTEGER, PUBLIC, PARAMETER ::   MPI_DOUBLE_PRECISION = 8
+   LOGICAL, PUBLIC, PARAMETER ::   lk_mpp = .FALSE.    !: mpp flag
+#endif
 
    INTEGER, PARAMETER         ::   nprocmax = 2**10   ! maximun dimension (required to be a power of 2)
@@ -189,4 +173,10 @@
    LOGICAL, PUBLIC ::   l_north_nogather = .FALSE.  !: internal control of northfold comms
 
+   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
+   
    !!----------------------------------------------------------------------
    !! NEMO/OCE 4.0 , NEMO Consortium (2018)
@@ -215,4 +205,5 @@
       NAMELIST/nammpp/ cn_mpi_send, nn_buffer, jpni, jpnj, ln_nnogather
       !!----------------------------------------------------------------------
+#if defined key_mpp_mpi
       !
       ii = 1
@@ -311,5 +302,5 @@
       ENDIF
 
-#if defined key_agrif
+# if defined key_agrif
       IF( Agrif_Root() ) THEN
          CALL Agrif_MPI_Init(mpi_comm_oce)
@@ -317,5 +308,5 @@
          CALL Agrif_MPI_set_grid_comm(mpi_comm_oce)
       ENDIF
-#endif
+# endif
 
       CALL mpi_comm_rank( mpi_comm_oce, mpprank, ierr )
@@ -330,169 +321,10 @@
       CALL MPI_OP_CREATE(DDPDD_MPI, .TRUE., MPI_SUMDD, ierr)
       !
+#else
+      IF( PRESENT( localComm ) ) mpi_comm_oce = localComm
+      mynode = 0
+      CALL ctl_opn( kumond, TRIM(ldname), 'UNKNOWN', 'FORMATTED', 'SEQUENTIAL', -1, 6, .FALSE. , 1 )
+#endif
    END FUNCTION mynode
-
-   !!----------------------------------------------------------------------
-   !!                   ***  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
-   !!                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           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
-   !!                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_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
-
-
-   !!----------------------------------------------------------------------
-   !!                   ***  routine mpp_lnk_bdy_(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
-   !!                kb_bdy :   BDY boundary set
-   !!                kfld   :   optional, number of pt3d arrays
-   !!----------------------------------------------------------------------
-   !
-   !                       !==  2D array and array of 2D pointer  ==!
-   !
-#  define DIM_2d
-#     define ROUTINE_BDY           mpp_lnk_bdy_2d
-#     include "mpp_bdy_generic.h90"
-#     undef ROUTINE_BDY
-#     define MULTI
-#     define ROUTINE_BDY           mpp_lnk_bdy_2d_ptr
-#     include "mpp_bdy_generic.h90"
-#     undef ROUTINE_BDY
-#     undef MULTI
-#  undef DIM_2d
-   !
-   !                       !==  3D array and array of 3D pointer  ==!
-   !
-#  define DIM_3d
-#     define ROUTINE_BDY           mpp_lnk_bdy_3d
-#     include "mpp_bdy_generic.h90"
-#     undef ROUTINE_BDY
-#     define MULTI
-#     define ROUTINE_BDY           mpp_lnk_bdy_3d_ptr
-#     include "mpp_bdy_generic.h90"
-#     undef ROUTINE_BDY
-#     undef MULTI
-#  undef DIM_3d
-   !
-   !                       !==  4D array and array of 4D pointer  ==!
-   !
-#  define DIM_4d
-#     define ROUTINE_BDY           mpp_lnk_bdy_4d
-#     include "mpp_bdy_generic.h90"
-#     undef ROUTINE_BDY
-#     define MULTI
-#     define ROUTINE_BDY           mpp_lnk_bdy_4d_ptr
-#     include "mpp_bdy_generic.h90"
-#     undef ROUTINE_BDY
-#     undef MULTI
-#  undef DIM_4d
-
-   !!----------------------------------------------------------------------
-   !!
-   !!   load_array  &   mpp_lnk_2d_9    à generaliser a 3D et 4D
-   
-   
-   !!    mpp_lnk_sum_2d et 3D   ====>>>>>>   à virer du code !!!!
-   
-   
-   !!----------------------------------------------------------------------
-
 
 
@@ -513,4 +345,5 @@
       !!----------------------------------------------------------------------
       !
+#if defined key_mpp_mpi
       SELECT CASE ( cn_mpi_send )
       CASE ( 'S' )                ! Standard mpi send (blocking)
@@ -522,4 +355,5 @@
          CALL mpi_isend( pmess, kbytes, mpi_double_precision, kdest , ktyp, mpi_comm_oce, md_req, iflag )
       END SELECT
+#endif
       !
    END SUBROUTINE mppsend
@@ -543,4 +377,5 @@
       !!----------------------------------------------------------------------
       !
+#if defined key_mpp_mpi
       ! If a specific process number has been passed to the receive call,
       ! use that one. Default is to use mpi_any_source
@@ -549,4 +384,5 @@
       !
       CALL mpi_recv( pmess, kbytes, mpi_double_precision, use_source, ktyp, mpi_comm_oce, istatus, iflag )
+#endif
       !
    END SUBROUTINE mpprecv
@@ -569,6 +405,10 @@
       !
       itaille = jpi * jpj
+#if defined key_mpp_mpi
       CALL mpi_gather( ptab, itaille, mpi_double_precision, pio, itaille     ,   &
          &                            mpi_double_precision, kp , mpi_comm_oce, ierror )
+#else
+      pio(:,:,1) = ptab(:,:)
+#endif
       !
    END SUBROUTINE mppgather
@@ -592,6 +432,10 @@
       itaille = jpi * jpj
       !
+#if defined key_mpp_mpi
       CALL mpi_scatter( pio, itaille, mpi_double_precision, ptab, itaille     ,   &
          &                            mpi_double_precision, kp  , mpi_comm_oce, ierror )
+#else
+      ptab(:,:) = pio(:,:,1)
+#endif
       !
    END SUBROUTINE mppscatter
@@ -617,4 +461,5 @@
       COMPLEX(wp), ALLOCATABLE, DIMENSION(:) ::   ytmp
       !!----------------------------------------------------------------------
+#if defined key_mpp_mpi
       ilocalcomm = mpi_comm_oce
       IF( PRESENT(kcom) )   ilocalcomm = kcom
@@ -655,10 +500,13 @@
 
       ! send y_in into todelay(idvar)%y1d with a non-blocking communication
-#if defined key_mpi2
+# if defined key_mpi2
       IF( ln_timing ) CALL tic_tac( .TRUE., ld_global = .TRUE.)
       CALL  mpi_allreduce( y_in(:), todelay(idvar)%y1d(:), isz, MPI_DOUBLE_COMPLEX, mpi_sumdd, ilocalcomm, ndelayid(idvar), ierr )
       IF( ln_timing ) CALL tic_tac(.FALSE., ld_global = .TRUE.)
+# else
+      CALL mpi_iallreduce( y_in(:), todelay(idvar)%y1d(:), isz, MPI_DOUBLE_COMPLEX, mpi_sumdd, ilocalcomm, ndelayid(idvar), ierr )
+# endif
 #else
-      CALL mpi_iallreduce( y_in(:), todelay(idvar)%y1d(:), isz, MPI_DOUBLE_COMPLEX, mpi_sumdd, ilocalcomm, ndelayid(idvar), ierr )
+      pout(:) = REAL(y_in(:), wp)
 #endif
 
@@ -684,4 +532,5 @@
       INTEGER ::   ierr, ilocalcomm
       !!----------------------------------------------------------------------
+#if defined key_mpp_mpi
       ilocalcomm = mpi_comm_oce
       IF( PRESENT(kcom) )   ilocalcomm = kcom
@@ -718,10 +567,13 @@
 
       ! send p_in into todelay(idvar)%z1d with a non-blocking communication
-#if defined key_mpi2
+# if defined key_mpi2
       IF( ln_timing ) CALL tic_tac( .TRUE., ld_global = .TRUE.)
       CALL  mpi_allreduce( p_in(:), todelay(idvar)%z1d(:), isz, MPI_DOUBLE_PRECISION, mpi_max, ilocalcomm, ndelayid(idvar), ierr )
       IF( ln_timing ) CALL tic_tac(.FALSE., ld_global = .TRUE.)
+# else
+      CALL mpi_iallreduce( p_in(:), todelay(idvar)%z1d(:), isz, MPI_DOUBLE_PRECISION, mpi_max, ilocalcomm, ndelayid(idvar), ierr )
+# endif
 #else
-      CALL mpi_iallreduce( p_in(:), todelay(idvar)%z1d(:), isz, MPI_DOUBLE_PRECISION, mpi_max, ilocalcomm, ndelayid(idvar), ierr )
+      pout(:) = p_in(:)
 #endif
 
@@ -739,4 +591,5 @@
       INTEGER ::   ierr
       !!----------------------------------------------------------------------
+#if defined key_mpp_mpi
       IF( ndelayid(kid) /= -2 ) THEN  
 #if ! defined key_mpi2
@@ -748,4 +601,5 @@
          ndelayid(kid) = -2   ! add flag to know that mpi_wait was already called on kid
       ENDIF
+#endif
    END SUBROUTINE mpp_delay_rcv
 
@@ -906,5 +760,7 @@
       !!-----------------------------------------------------------------------
       !
+#if defined key_mpp_mpi
       CALL mpi_barrier( mpi_comm_oce, ierror )
+#endif
       !
    END SUBROUTINE mppsync
@@ -928,4 +784,5 @@
       IF( PRESENT(ld_force_abort) ) ll_force_abort = ld_force_abort
       !
+#if defined key_mpp_mpi
       IF(ll_force_abort) THEN
          CALL mpi_abort( MPI_COMM_WORLD )
@@ -934,4 +791,5 @@
          CALL mpi_finalize( info )
       ENDIF
+#endif
       IF( .NOT. llfinal ) STOP 123
       !
@@ -946,5 +804,7 @@
       !!----------------------------------------------------------------------
       !
+#if defined key_mpp_mpi
       CALL MPI_COMM_FREE(kcom, ierr)
+#endif
       !
    END SUBROUTINE mpp_comm_free
@@ -976,4 +836,5 @@
       INTEGER, ALLOCATABLE, DIMENSION(:) ::   kwork
       !!----------------------------------------------------------------------
+#if defined key_mpp_mpi
       !-$$     WRITE (numout,*) 'mpp_ini_znl ', nproc, ' - ngrp_world     : ', ngrp_world
       !-$$     WRITE (numout,*) 'mpp_ini_znl ', nproc, ' - mpi_comm_world : ', mpi_comm_world
@@ -1047,4 +908,5 @@
 
       DEALLOCATE(kwork)
+#endif
 
    END SUBROUTINE mpp_ini_znl
@@ -1078,4 +940,5 @@
       !!----------------------------------------------------------------------
       !
+#if defined key_mpp_mpi
       njmppmax = MAXVAL( njmppt )
       !
@@ -1109,4 +972,5 @@
       CALL MPI_COMM_CREATE( mpi_comm_oce, ngrp_north, ncomm_north, ierr )
       !
+#endif
    END SUBROUTINE mpp_ini_north
 
@@ -1130,4 +994,5 @@
       LOGICAL                                      ::   mpi_was_called
       !!---------------------------------------------------------------------
+#if defined key_mpp_mpi
       !
       CALL mpi_initialized( mpi_was_called, code )      ! MPI initialization
@@ -1169,4 +1034,5 @@
       ENDIF
       !
+#endif
    END SUBROUTINE mpi_init_oce
 
@@ -1203,286 +1069,4 @@
 
 
-   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
-      !!----------------------------------------------------------------------
-      !
-      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 )
-      !
-   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 )
-         IF(l_isend) 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 )
-         IF(l_isend) CALL mpi_wait(ml_req1,ml_stat,ml_err)
-         IF(l_isend) 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 )
-         IF(l_isend) 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 )
-         IF(l_isend) 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 )
-         IF(l_isend) CALL mpi_wait(ml_req1,ml_stat,ml_err)
-         IF(l_isend) 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 )
-         IF(l_isend) 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
-
-
    SUBROUTINE mpp_report( cdname, kpk, kpl, kpf, ld_lbc, ld_glb, ld_dlg )
       !!----------------------------------------------------------------------
@@ -1500,4 +1084,5 @@
       INTEGER ::    ji,  jj,  jk,  jh, jf, jcount   ! dummy loop indices
       !!----------------------------------------------------------------------
+#if defined key_mpp_mpi
       !
       ll_lbc = .FALSE.
@@ -1610,4 +1195,5 @@
          DEALLOCATE(crname_lbc)
       ENDIF
+#endif
    END SUBROUTINE mpp_report
 
@@ -1620,4 +1206,5 @@
     REAL(wp),               SAVE :: tic_ct = 0._wp
     INTEGER :: ii
+#if defined key_mpp_mpi
 
     IF( ncom_stp <= nit000 ) RETURN
@@ -1635,258 +1222,18 @@
        tic_ct = MPI_Wtime()                                                        ! start count tac->tic (waiting time)
     ENDIF
+#endif
     
    END SUBROUTINE tic_tac
 
-   
-#else
-   !!----------------------------------------------------------------------
-   !!   Default case:            Dummy module        share memory computing
-   !!----------------------------------------------------------------------
-   USE in_out_manager
-
-   INTERFACE mpp_sum
-      MODULE PROCEDURE mppsum_int, mppsum_a_int, mppsum_real, mppsum_a_real, mppsum_realdd, mppsum_a_realdd
-   END INTERFACE
-   INTERFACE mpp_max
-      MODULE PROCEDURE mppmax_a_int, mppmax_int, mppmax_a_real, mppmax_real
-   END INTERFACE
-   INTERFACE mpp_min
-      MODULE PROCEDURE mppmin_a_int, mppmin_int, mppmin_a_real, mppmin_real
-   END INTERFACE
-   INTERFACE mpp_minloc
-      MODULE PROCEDURE mpp_minloc2d ,mpp_minloc3d
-   END INTERFACE
-   INTERFACE mpp_maxloc
-      MODULE PROCEDURE mpp_maxloc2d ,mpp_maxloc3d
-   END INTERFACE
-
-   LOGICAL, PUBLIC, PARAMETER ::   lk_mpp = .FALSE.      !: mpp flag
-   LOGICAL, PUBLIC            ::   ln_nnogather          !: namelist control of northfold comms (needed here in case "key_mpp_mpi" is not used)
-   INTEGER, PUBLIC            ::   mpi_comm_oce          ! opa local communicator
-
-   INTEGER, PARAMETER, PUBLIC               ::   nbdelay = 0   ! make sure we don't enter loops: DO ji = 1, nbdelay
-   CHARACTER(len=32), DIMENSION(1), PUBLIC  ::   c_delaylist = 'empty'
-   CHARACTER(len=32), DIMENSION(1), PUBLIC  ::   c_delaycpnt = 'empty'
-   LOGICAL, PUBLIC                          ::   l_full_nf_update = .TRUE.
-   TYPE ::   DELAYARR
-      REAL(   wp), POINTER, DIMENSION(:) ::  z1d => NULL()
-      COMPLEX(wp), POINTER, DIMENSION(:) ::  y1d => NULL()
-   END TYPE DELAYARR
-   TYPE( DELAYARR ), DIMENSION(1), PUBLIC  ::   todelay              
-   INTEGER,  PUBLIC, DIMENSION(1)           ::   ndelayid = -1
-   !!----------------------------------------------------------------------
-CONTAINS
-
-   INTEGER FUNCTION lib_mpp_alloc(kumout)          ! Dummy function
-      INTEGER, INTENT(in) ::   kumout
-      lib_mpp_alloc = 0
-   END FUNCTION lib_mpp_alloc
-
-   FUNCTION mynode( ldtxt, ldname, kumnam_ref, knumnam_cfg,  kumond , kstop, localComm ) RESULT (function_value)
-      INTEGER, OPTIONAL            , INTENT(in   ) ::   localComm
-      CHARACTER(len=*),DIMENSION(:) ::   ldtxt
-      CHARACTER(len=*) ::   ldname
-      INTEGER ::   kumnam_ref, knumnam_cfg , kumond , kstop
-      IF( PRESENT( localComm ) ) mpi_comm_oce = localComm
-      function_value = 0
-      IF( .FALSE. )   ldtxt(:) = 'never done'
-      CALL ctl_opn( kumond, TRIM(ldname), 'UNKNOWN', 'FORMATTED', 'SEQUENTIAL', -1, 6, .FALSE. , 1 )
-   END FUNCTION mynode
-
-   SUBROUTINE mppsync                       ! Dummy routine
-   END SUBROUTINE mppsync
-
-   !!----------------------------------------------------------------------
-   !!    ***  mppmax_a_int, mppmax_int, mppmax_a_real, mppmax_real  ***
-   !!   
-   !!----------------------------------------------------------------------
-   !!
-#  define OPERATION_MAX
-#  define INTEGER_TYPE
-#  define DIM_0d
-#     define ROUTINE_ALLREDUCE           mppmax_int
-#     include "mpp_allreduce_generic.h90"
-#     undef ROUTINE_ALLREDUCE
-#  undef DIM_0d
-#  define DIM_1d
-#     define ROUTINE_ALLREDUCE           mppmax_a_int
-#     include "mpp_allreduce_generic.h90"
-#     undef ROUTINE_ALLREDUCE
-#  undef DIM_1d
-#  undef INTEGER_TYPE
-!
-#  define REAL_TYPE
-#  define DIM_0d
-#     define ROUTINE_ALLREDUCE           mppmax_real
-#     include "mpp_allreduce_generic.h90"
-#     undef ROUTINE_ALLREDUCE
-#  undef DIM_0d
-#  define DIM_1d
-#     define ROUTINE_ALLREDUCE           mppmax_a_real
-#     include "mpp_allreduce_generic.h90"
-#     undef ROUTINE_ALLREDUCE
-#  undef DIM_1d
-#  undef REAL_TYPE
-#  undef OPERATION_MAX
-   !!----------------------------------------------------------------------
-   !!    ***  mppmin_a_int, mppmin_int, mppmin_a_real, mppmin_real  ***
-   !!   
-   !!----------------------------------------------------------------------
-   !!
-#  define OPERATION_MIN
-#  define INTEGER_TYPE
-#  define DIM_0d
-#     define ROUTINE_ALLREDUCE           mppmin_int
-#     include "mpp_allreduce_generic.h90"
-#     undef ROUTINE_ALLREDUCE
-#  undef DIM_0d
-#  define DIM_1d
-#     define ROUTINE_ALLREDUCE           mppmin_a_int
-#     include "mpp_allreduce_generic.h90"
-#     undef ROUTINE_ALLREDUCE
-#  undef DIM_1d
-#  undef INTEGER_TYPE
-!
-#  define REAL_TYPE
-#  define DIM_0d
-#     define ROUTINE_ALLREDUCE           mppmin_real
-#     include "mpp_allreduce_generic.h90"
-#     undef ROUTINE_ALLREDUCE
-#  undef DIM_0d
-#  define DIM_1d
-#     define ROUTINE_ALLREDUCE           mppmin_a_real
-#     include "mpp_allreduce_generic.h90"
-#     undef ROUTINE_ALLREDUCE
-#  undef DIM_1d
-#  undef REAL_TYPE
-#  undef OPERATION_MIN
-
-   !!----------------------------------------------------------------------
-   !!    ***  mppsum_a_int, mppsum_int, mppsum_a_real, mppsum_real  ***
-   !!   
-   !!   Global sum of 1D array or a variable (integer, real or complex)
-   !!----------------------------------------------------------------------
-   !!
-#  define OPERATION_SUM
-#  define INTEGER_TYPE
-#  define DIM_0d
-#     define ROUTINE_ALLREDUCE           mppsum_int
-#     include "mpp_allreduce_generic.h90"
-#     undef ROUTINE_ALLREDUCE
-#  undef DIM_0d
-#  define DIM_1d
-#     define ROUTINE_ALLREDUCE           mppsum_a_int
-#     include "mpp_allreduce_generic.h90"
-#     undef ROUTINE_ALLREDUCE
-#  undef DIM_1d
-#  undef INTEGER_TYPE
-!
-#  define REAL_TYPE
-#  define DIM_0d
-#     define ROUTINE_ALLREDUCE           mppsum_real
-#     include "mpp_allreduce_generic.h90"
-#     undef ROUTINE_ALLREDUCE
-#  undef DIM_0d
-#  define DIM_1d
-#     define ROUTINE_ALLREDUCE           mppsum_a_real
-#     include "mpp_allreduce_generic.h90"
-#     undef ROUTINE_ALLREDUCE
-#  undef DIM_1d
-#  undef REAL_TYPE
-#  undef OPERATION_SUM
-
-#  define OPERATION_SUM_DD
-#  define COMPLEX_TYPE
-#  define DIM_0d
-#     define ROUTINE_ALLREDUCE           mppsum_realdd
-#     include "mpp_allreduce_generic.h90"
-#     undef ROUTINE_ALLREDUCE
-#  undef DIM_0d
-#  define DIM_1d
-#     define ROUTINE_ALLREDUCE           mppsum_a_realdd
-#     include "mpp_allreduce_generic.h90"
-#     undef ROUTINE_ALLREDUCE
-#  undef DIM_1d
-#  undef COMPLEX_TYPE
-#  undef OPERATION_SUM_DD
-
-   !!----------------------------------------------------------------------
-   !!    ***  mpp_minloc2d, mpp_minloc3d, mpp_maxloc2d, mpp_maxloc3d
-   !!   
-   !!----------------------------------------------------------------------
-   !!
-#  define OPERATION_MINLOC
-#  define DIM_2d
-#     define ROUTINE_LOC           mpp_minloc2d
-#     include "mpp_loc_generic.h90"
-#     undef ROUTINE_LOC
-#  undef DIM_2d
-#  define DIM_3d
-#     define ROUTINE_LOC           mpp_minloc3d
-#     include "mpp_loc_generic.h90"
-#     undef ROUTINE_LOC
-#  undef DIM_3d
-#  undef OPERATION_MINLOC
-
-#  define OPERATION_MAXLOC
-#  define DIM_2d
-#     define ROUTINE_LOC           mpp_maxloc2d
-#     include "mpp_loc_generic.h90"
-#     undef ROUTINE_LOC
-#  undef DIM_2d
-#  define DIM_3d
-#     define ROUTINE_LOC           mpp_maxloc3d
-#     include "mpp_loc_generic.h90"
-#     undef ROUTINE_LOC
-#  undef DIM_3d
-#  undef OPERATION_MAXLOC
-
-   SUBROUTINE mpp_delay_sum( cdname, cdelay, y_in, pout, ldlast, kcom )
-      CHARACTER(len=*), INTENT(in   )               ::   cdname  ! name of the calling subroutine
-      CHARACTER(len=*), INTENT(in   )               ::   cdelay  ! name (used as id) of the delayed operation
-      COMPLEX(wp),      INTENT(in   ), DIMENSION(:) ::   y_in
-      REAL(wp),         INTENT(  out), DIMENSION(:) ::   pout
-      LOGICAL,          INTENT(in   )               ::   ldlast  ! true if this is the last time we call this routine
-      INTEGER,          INTENT(in   ), OPTIONAL     ::   kcom
-      !
-      pout(:) = REAL(y_in(:), wp)
-   END SUBROUTINE mpp_delay_sum
-
-   SUBROUTINE mpp_delay_max( cdname, cdelay, p_in, pout, ldlast, kcom )
-      CHARACTER(len=*), INTENT(in   )               ::   cdname  ! name of the calling subroutine
-      CHARACTER(len=*), INTENT(in   )               ::   cdelay  ! name (used as id) of the delayed operation
-      REAL(wp),         INTENT(in   ), DIMENSION(:) ::   p_in
-      REAL(wp),         INTENT(  out), DIMENSION(:) ::   pout
-      LOGICAL,          INTENT(in   )               ::   ldlast  ! true if this is the last time we call this routine
-      INTEGER,          INTENT(in   ), OPTIONAL     ::   kcom
-      !
-      pout(:) = p_in(:)
-   END SUBROUTINE mpp_delay_max
-
-   SUBROUTINE mpp_delay_rcv( kid )
-      INTEGER,INTENT(in   )      ::  kid 
-      WRITE(*,*) 'mpp_delay_rcv: You should not have seen this print! error?', kid
-   END SUBROUTINE mpp_delay_rcv
-   
-   SUBROUTINE mppstop( ldfinal, ld_force_abort )
-      LOGICAL, OPTIONAL, INTENT(in) :: ldfinal    ! source process number
-      LOGICAL, OPTIONAL, INTENT(in) :: ld_force_abort    ! source process number
-      STOP      ! non MPP case, just stop the run
-   END SUBROUTINE mppstop
-
-   SUBROUTINE mpp_ini_znl( knum )
-      INTEGER :: knum
-      WRITE(*,*) 'mpp_ini_znl: You should not have seen this print! error?', knum
-   END SUBROUTINE mpp_ini_znl
-
-   SUBROUTINE mpp_comm_free( kcom )
-      INTEGER :: kcom
-      WRITE(*,*) 'mpp_comm_free: You should not have seen this print! error?', kcom
-   END SUBROUTINE mpp_comm_free
-   
-#endif
-
-   !!----------------------------------------------------------------------
-   !!   All cases:         ctl_stop, ctl_warn, get_unit, ctl_opn, ctl_nam   routines
+#if ! defined key_mpp_mpi
+   SUBROUTINE mpi_wait(request, status, ierror)
+      INTEGER                            , INTENT(in   ) ::   request
+      INTEGER, DIMENSION(MPI_STATUS_SIZE), INTENT(  out) ::   status
+      INTEGER                            , INTENT(  out) ::   ierror
+   END SUBROUTINE mpi_wait
+#endif
+
+   !!----------------------------------------------------------------------
+   !!   ctl_stop, ctl_warn, get_unit, ctl_opn, ctl_nam   routines
    !!----------------------------------------------------------------------
 
Index: NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/LBC/mpp_lnk_generic.h90
===================================================================
--- NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/LBC/mpp_lnk_generic.h90	(revision 11191)
+++ NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/LBC/mpp_lnk_generic.h90	(revision 11192)
@@ -46,26 +46,33 @@
 
 #if defined MULTI
-   SUBROUTINE ROUTINE_LNK( cdname, ptab, cd_nat, psgn, kfld, cd_mpp, pval )
-      INTEGER                     , INTENT(in   ) ::   kfld        ! number of pt3d arrays
+   SUBROUTINE ROUTINE_LNK( cdname, ptab, cd_nat, psgn, kfld, kfillmode, pfillval )
+      INTEGER             , INTENT(in   ) ::   kfld        ! number of pt3d arrays
 #else
-   SUBROUTINE ROUTINE_LNK( cdname, ptab, cd_nat, psgn      , cd_mpp, pval )
+   SUBROUTINE ROUTINE_LNK( cdname, ptab, cd_nat, psgn      , kfillmode, pfillval )
 #endif
       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
-      CHARACTER(len=3), OPTIONAL  , INTENT(in   ) ::   cd_mpp      ! fill the overlap area only
-      REAL(wp)        , OPTIONAL  , INTENT(in   ) ::   pval        ! background value (used at closed boundaries)
-      !
-      INTEGER  ::    ji,  jj,  jk,  jl, jh, jf   ! dummy loop indices
+      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)
+      !
+      INTEGER  ::    ji,  jj,  jk,  jl,  jf      ! dummy loop indices
       INTEGER  ::   ipi, ipj, ipk, ipl, ipf      ! dimension of the input array
-      INTEGER  ::   imigr, iihom, ijhom          ! local integers
-      INTEGER  ::   ml_req1, ml_req2, ml_err     ! for key_mpi_isend
+      INTEGER  ::   isize, ishift, ishift2       ! local integers
+      INTEGER  ::   ireq_we, ireq_ea, ireq_so, ireq_no     ! mpi_request id
       INTEGER  ::   ierr
+      INTEGER  ::   ifill_we, ifill_ea, ifill_so, ifill_no   
       REAL(wp) ::   zland
-      INTEGER , DIMENSION(MPI_STATUS_SIZE)      ::   ml_stat        ! for key_mpi_isend
-      REAL(wp), DIMENSION(:,:,:,:,:,:), ALLOCATABLE ::   zt3ns, zt3sn   ! north-south & south-north  halos
-      REAL(wp), DIMENSION(:,:,:,:,:,:), ALLOCATABLE ::   zt3ew, zt3we   ! east -west  & west - east  halos
+      INTEGER , DIMENSION(MPI_STATUS_SIZE)        ::   istat          ! for mpi_isend
+      REAL(wp), DIMENSION(:,:,:,:,:), ALLOCATABLE ::   zsnd_we, zrcv_we, zsnd_ea, zrcv_ea   ! east -west  & west - east  halos
+      REAL(wp), DIMENSION(:,:,:,:,:), ALLOCATABLE ::   zsnd_so, zrcv_so, zsnd_no, zrcv_no   ! north-south & south-north  halos
+      LOGICAL  ::   llcom_we, llcom_ea, llcom_no, llcom_so       ! communication done or not
+      LOGICAL  ::   lldo_nfd                                     ! do north pole folding
       !!----------------------------------------------------------------------
+      !
+      ! ----------------------------------------- !
+      !     0. local variables initialization     !
+      ! ----------------------------------------- !
       !
       ipk = K_SIZE(ptab)   ! 3rd dimension
@@ -75,149 +82,148 @@
       IF( narea == 1 .AND. numcom == -1 ) CALL mpp_report( cdname, ipk, ipl, ipf, ld_lbc = .TRUE. )
       !
-      IF( PRESENT( pval ) ) THEN   ;   zland = pval      ! set land value
-      ELSE                         ;   zland = 0._wp     ! zero by default
-      ENDIF
-
-      ! ------------------------------- !
-      !   standard boundary treatment   !    ! CAUTION: semi-column notation is often impossible
-      ! ------------------------------- !
-      !
-      IF( .NOT. PRESENT( cd_mpp ) ) THEN     !==  standard close or cyclic treatment  ==!
-         !
-         DO jf = 1, ipf                      ! number of arrays to be treated
-            !
-            !                                ! East-West boundaries
-            IF( l_Iperio ) THEN                    !* cyclic
-               ARRAY_IN( 1 ,:,:,:,jf) = ARRAY_IN(jpim1,:,:,:,jf)
-               ARRAY_IN(jpi,:,:,:,jf) = ARRAY_IN(  2  ,:,:,:,jf)
-            ELSE                                   !* closed
-               IF( .NOT. NAT_IN(jf) == 'F' )   ARRAY_IN(     1       :nn_hls,:,:,:,jf) = zland    ! east except F-point
-                                               ARRAY_IN(nlci-nn_hls+1:jpi   ,:,:,:,jf) = zland    ! west
-            ENDIF
-            !                                ! North-South boundaries
-            IF( l_Jperio ) THEN                    !* cyclic (only with no mpp j-split)
-               ARRAY_IN(:, 1 ,:,:,jf) = ARRAY_IN(:, jpjm1,:,:,jf)
-               ARRAY_IN(:,jpj,:,:,jf) = ARRAY_IN(:,   2  ,:,:,jf)
-            ELSE                                   !* closed
-               IF( .NOT. NAT_IN(jf) == 'F' )   ARRAY_IN(:,     1       :nn_hls,:,:,jf) = zland    ! south except F-point
-                                               ARRAY_IN(:,nlcj-nn_hls+1:jpj   ,:,:,jf) = zland    ! north
+      llcom_we = nbondi ==  1 .OR. nbondi == 0   ! keep for compatibility, should be defined in mppini
+      llcom_ea = nbondi == -1 .OR. nbondi == 0   ! keep for compatibility, should be defined in mppini
+      llcom_so = nbondj ==  1 .OR. nbondj == 0   ! keep for compatibility, should be defined in mppini
+      llcom_no = nbondj == -1 .OR. nbondj == 0   ! keep for compatibility, should be defined in mppini
+      
+      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(               llcom_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(               llcom_ea ) THEN   ;   ifill_ea = jpfillmpi
+      ELSE                                ;   ifill_ea = ifill_we
+      END IF
+      !
+      IF(               llcom_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(               llcom_no ) THEN   ;   ifill_no = jpfillmpi
+      ELSE                                ;   ifill_no = ifill_so   ! warning will be potentially changed if lldo_nfd = T
+      END IF
+      !
+#if defined PRINT_CAUTION
+      !
+      ! ================================================================================== !
+      ! CAUTION: semi-column notation is often impossible because of the cpp preprocessing !
+      ! ================================================================================== !
+      !
+#endif
+      !
+      ! -------------------------------------------------- !
+      !     1. Do east and west MPI exchange if needed     !
+      ! -------------------------------------------------- !
+      !
+      ! these echanges are made for jj = nn_hls+1 to jpj-nn_hls
+      isize = nn_hls * ( jpj - 2*nn_hls ) * ipk * ipl * ipf      
+
+      ! Allocate local temporary arrays to be sent/received. Fill arrays to be sent
+      IF( ifill_we == jpfillmpi ) THEN   ! copy western side of the inner mpi domain in local temporary array to be sent by MPI
+         !
+         ALLOCATE( zsnd_we(nn_hls,jpj-2*nn_hls,ipk,ipl,ipf), zrcv_we(nn_hls,jpj-2*nn_hls,ipk,ipl,ipf) )
+         ishift = 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_we(ji,jj-nn_hls,jk,jl,jf) = ARRAY_IN(ishift+ji,jj,jk,jl,jf)   ! nn_hls + 1 -> 2*nn_hls
+         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+      ENDIF
+      !
+      IF( ifill_ea == jpfillmpi ) THEN   ! copy eastern side of the inner mpi domain in local temporary array to be sent by MPI
+         !
+         ALLOCATE( zsnd_ea(nn_hls,jpj-2*nn_hls,ipk,ipl,ipf), zrcv_ea(nn_hls,jpj-2*nn_hls,ipk,ipl,ipf) )
+         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_ea(ji,jj-nn_hls,jk,jl,jf) = ARRAY_IN(ishift+ji,jj,jk,jl,jf)   ! jpi - 2*nn_hls + 1 -> jpi - nn_hls
+         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+      ENDIF
+      !
+      IF( ln_timing ) CALL tic_tac(.TRUE.)
+      !
+      ! non-blocking send of the western/eastern side using local temporary arrays
+      IF( ifill_we == jpfillmpi )   CALL mppsend( 1, zsnd_we(1,1,1,1,1), isize, nowe, ireq_we )
+      IF( ifill_ea == jpfillmpi )   CALL mppsend( 2, zsnd_ea(1,1,1,1,1), isize, noea, ireq_ea )
+      ! blocking receive of the western/eastern halo in local temporary arrays
+      IF( ifill_we == jpfillmpi )   CALL mpprecv( 2, zrcv_we(1,1,1,1,1), isize, nowe )
+      IF( ifill_ea == jpfillmpi )   CALL mpprecv( 1, zrcv_ea(1,1,1,1,1), isize, noea )
+      !
+      IF( ln_timing ) CALL tic_tac(.FALSE.)
+      !
+      !
+      ! ----------------------------------- !
+      !     2. Fill east and west halos     !
+      ! ----------------------------------- !
+      !
+      ! 2.1 fill weastern halo
+      ! ----------------------
+      ! ishift = 0                         ! fill halo from ji = 1 to nn_hls
+      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_we(ji,jj-nn_hls,jk,jl,jf)   ! 1 -> nn_hls
+         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 = nn_hls+1, jpj-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  )                 ! filling with inner domain values
+         DO jf = 1, ipf                               ! number of arrays to be treated
+            IF( .NOT. NAT_IN(jf) == 'F' ) THEN        ! do nothing for F point
+               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) = ARRAY_IN(nn_hls+1,jj,jk,jl,jf)
+               END DO   ;   END DO   ;   END DO   ;   END DO
             ENDIF
          END DO
-         !
-      ENDIF
-
-      ! ------------------------------- !
-      !      East and west exchange     !
-      ! ------------------------------- !
-      ! we play with the neigbours AND the row number because of the periodicity
-      !
-      IF( ABS(nbondi) == 1 ) ALLOCATE( zt3ew(jpj,nn_hls,ipk,ipl,ipf,1), zt3we(jpj,nn_hls,ipk,ipl,ipf,1) )
-      IF(     nbondi  == 0 ) ALLOCATE( zt3ew(jpj,nn_hls,ipk,ipl,ipf,2), zt3we(jpj,nn_hls,ipk,ipl,ipf,2) )
-      !
-      SELECT CASE ( nbondi )      ! Read Dirichlet lateral conditions
-      CASE ( -1 )
-         iihom = nlci-nreci
-         DO jf = 1, ipf
-            DO jl = 1, ipl
-               DO jk = 1, ipk
-                  DO jh = 1, nn_hls
-                     zt3we(:,jh,jk,jl,jf,1) = ARRAY_IN(iihom +jh,:,jk,jl,jf)
-                  END DO
-               END DO
-            END DO
-         END DO
-      CASE ( 0 )
-         iihom = nlci-nreci
-         DO jf = 1, ipf
-            DO jl = 1, ipl
-               DO jk = 1, ipk
-                  DO jh = 1, nn_hls
-                     zt3ew(:,jh,jk,jl,jf,1) = ARRAY_IN(nn_hls+jh,:,jk,jl,jf)
-                     zt3we(:,jh,jk,jl,jf,1) = ARRAY_IN(iihom +jh,:,jk,jl,jf)
-                  END DO
-               END DO
-            END DO
-         END DO
-      CASE ( 1 )
-         iihom = nlci-nreci
-         DO jf = 1, ipf
-            DO jl = 1, ipl
-               DO jk = 1, ipk
-                  DO jh = 1, nn_hls
-                     zt3ew(:,jh,jk,jl,jf,1) = ARRAY_IN(nn_hls+jh,:,jk,jl,jf)
-                  END DO
-               END DO
-            END DO
+      CASE ( jpfillcst   )                 ! filling with constant value
+         DO jf = 1, ipf                               ! number of arrays to be treated
+            IF( .NOT. NAT_IN(jf) == 'F' ) THEN        ! do nothing for F point
+               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) = zland
+               END DO;   END DO   ;   END DO   ;   END DO
+            ENDIF
          END DO
       END SELECT
-      !                           ! Migrations
-      imigr = nn_hls * jpj * ipk * ipl * ipf      
-      !
-      IF( ln_timing ) CALL tic_tac(.TRUE.)
-      !
-      SELECT CASE ( nbondi )
-      CASE ( -1 )
-         CALL mppsend( 2, zt3we(1,1,1,1,1,1), imigr, noea, ml_req1 )
-         CALL mpprecv( 1, zt3ew(1,1,1,1,1,1), imigr, noea )
-         IF(l_isend)   CALL mpi_wait(ml_req1, ml_stat, ml_err)
-      CASE ( 0 )
-         CALL mppsend( 1, zt3ew(1,1,1,1,1,1), imigr, nowe, ml_req1 )
-         CALL mppsend( 2, zt3we(1,1,1,1,1,1), imigr, noea, ml_req2 )
-         CALL mpprecv( 1, zt3ew(1,1,1,1,1,2), imigr, noea )
-         CALL mpprecv( 2, zt3we(1,1,1,1,1,2), imigr, nowe )
-         IF(l_isend)   CALL mpi_wait(ml_req1, ml_stat, ml_err)
-         IF(l_isend)   CALL mpi_wait(ml_req2, ml_stat, ml_err)
-      CASE ( 1 )
-         CALL mppsend( 1, zt3ew(1,1,1,1,1,1), imigr, nowe, ml_req1 )
-         CALL mpprecv( 2, zt3we(1,1,1,1,1,1), imigr, nowe )
-         IF(l_isend)   CALL mpi_wait(ml_req1, ml_stat, ml_err )
+      !
+      ! 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_ea(ji,jj-nn_hls,jk,jl,jf)   ! jpi - nn_hls + 1 -> jpi
+         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 = nn_hls+1, jpj-nn_hls   ;   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 = nn_hls+1, jpj-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   )                 ! filling with constant value
+         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) = zland
+         END DO;   END DO   ;   END DO   ;   END DO   ;   END DO
       END SELECT
-      !
-      IF( ln_timing ) CALL tic_tac(.FALSE.)
-      !
-      !                           ! Write Dirichlet lateral conditions
-      iihom = nlci-nn_hls
-      !
-      SELECT CASE ( nbondi )
-      CASE ( -1 )
-         DO jf = 1, ipf
-            DO jl = 1, ipl
-               DO jk = 1, ipk
-                  DO jh = 1, nn_hls
-                     ARRAY_IN(iihom+jh,:,jk,jl,jf) = zt3ew(:,jh,jk,jl,jf,1)
-                  END DO
-               END DO
-            END DO
-         END DO
-      CASE ( 0 )
-         DO jf = 1, ipf
-            DO jl = 1, ipl
-               DO jk = 1, ipk
-                  DO jh = 1, nn_hls
-                     ARRAY_IN(jh      ,:,jk,jl,jf) = zt3we(:,jh,jk,jl,jf,2)
-                     ARRAY_IN(iihom+jh,:,jk,jl,jf) = zt3ew(:,jh,jk,jl,jf,2)
-                  END DO
-               END DO
-            END DO
-         END DO
-      CASE ( 1 )
-         DO jf = 1, ipf
-            DO jl = 1, ipl
-               DO jk = 1, ipk
-                  DO jh = 1, nn_hls
-                     ARRAY_IN(jh      ,:,jk,jl,jf) = zt3we(:,jh,jk,jl,jf,1)
-                  END DO
-               END DO
-            END DO
-         END DO
-      END SELECT
-      !
-      IF( nbondi /= 2 ) DEALLOCATE( zt3ew, zt3we )
       !
       ! ------------------------------- !
       !     3. north fold treatment     !
       ! ------------------------------- !
+      !
       ! do it before south directions so concerned processes can do it without waiting for the comm with the sourthern neighbor
-      IF( npolj /= 0 .AND. .NOT. PRESENT(cd_mpp) ) THEN
+      !
+      IF( lldo_nfd .AND. ifill_no /= jpfillnothing ) THEN
          !
          SELECT CASE ( jpni )
@@ -226,113 +232,124 @@
          END SELECT
          !
-      ENDIF
-      !
-      ! ------------------------------- !
-      !  4. North and south directions  !
-      ! ------------------------------- !
-      ! always closed : we play only with the neigbours
-      !
-      IF( ABS(nbondj) == 1 ) ALLOCATE( zt3ns(jpi,nn_hls,ipk,ipl,ipf,1), zt3sn(jpi,nn_hls,ipk,ipl,ipf,1) )
-      IF(     nbondj  == 0 ) ALLOCATE( zt3ns(jpi,nn_hls,ipk,ipl,ipf,2), zt3sn(jpi,nn_hls,ipk,ipl,ipf,2) )
-      !
-      SELECT CASE ( nbondj )
-      CASE ( -1 )
-         ijhom = nlcj-nrecj
-         DO jf = 1, ipf
-            DO jl = 1, ipl
-               DO jk = 1, ipk
-                  DO jh = 1, nn_hls
-                     zt3sn(:,jh,jk,jl,jf,1) = ARRAY_IN(:,ijhom +jh,jk,jl,jf)
-                  END DO
-               END DO
-            END DO
+         ifill_no = jpfillnothing  ! force to do nothing for the northern halo as we just done the north pole folding
+         !
+      ENDIF
+      !
+      ! ---------------------------------------------------- !
+      !     4. Do north and south MPI exchange if needed     !
+      ! ---------------------------------------------------- !
+      !
+      isize = jpi * nn_hls * ipk * ipl * ipf      
+
+      ! allocate local temporary arrays to be sent/received. Fill arrays to be sent
+      IF( ifill_so == jpfillmpi ) THEN   ! copy sourhern side of the inner mpi domain in local temporary array to be sent by MPI
+         !
+         ALLOCATE( zsnd_so(jpi,nn_hls,ipk,ipl,ipf), zrcv_so(jpi,nn_hls,ipk,ipl,ipf) )
+         ishift = nn_hls
+         DO jf = 1, ipf   ;   DO jl = 1, ipl   ;   DO jk = 1, ipk   ;   DO jj = 1, nn_hls   ;   DO ji = 1, jpi
+            zsnd_so(ji,jj,jk,jl,jf) = ARRAY_IN(ji,ishift+jj,jk,jl,jf)   ! nn_hls+1 -> 2*nn_hls
+         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+      ENDIF
+      !
+      IF( ifill_no == jpfillmpi ) THEN   ! copy eastern side of the inner mpi domain in local temporary array to be sent by MPI
+         !
+         ALLOCATE( zsnd_no(jpi,nn_hls,ipk,ipl,ipf), zrcv_no(jpi,nn_hls,ipk,ipl,ipf) )
+         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, jpi
+            zsnd_no(ji,jj,jk,jl,jf) = ARRAY_IN(ji,ishift+jj,jk,jl,jf)   ! jpj-2*nn_hls+1 -> jpj-nn_hls
+         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+      ENDIF
+      !
+      IF( ln_timing ) CALL tic_tac(.TRUE.)
+      !
+      ! non-blocking send of the southern/northern side
+      IF( ifill_so == jpfillmpi )   CALL mppsend( 3, zsnd_so(1,1,1,1,1), isize, noso, ireq_so )
+      IF( ifill_no == jpfillmpi )   CALL mppsend( 4, zsnd_no(1,1,1,1,1), isize, nono, ireq_no )
+      ! blocking receive of the southern/northern halo
+      IF( ifill_so == jpfillmpi )   CALL mpprecv( 4, zrcv_so(1,1,1,1,1), isize, noso )
+      IF( ifill_no == jpfillmpi )   CALL mpprecv( 3, zrcv_no(1,1,1,1,1), isize, nono )
+      !
+      IF( ln_timing ) CALL tic_tac(.FALSE.)
+      !
+      ! ------------------------------------- !
+      !     5. Fill south and north halos     !
+      ! ------------------------------------- !
+      !
+      ! 5.1 fill southern halo
+      ! ----------------------
+      ! ishift = 0                         ! fill halo from jj = 1 to nn_hls
+      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 = 1, jpi
+            ARRAY_IN(ji,jj,jk,jl,jf) = zrcv_so(ji,jj,jk,jl,jf)   ! 1 -> nn_hls
+         END DO;   END DO   ;   END DO   ;   END DO   ;   END DO
+      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                               ! number of arrays to be treated
+            IF( .NOT. NAT_IN(jf) == 'F' ) THEN        ! do nothing for F point
+               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
+            ENDIF
          END DO
-      CASE ( 0 )
-         ijhom = nlcj-nrecj
-         DO jf = 1, ipf
-            DO jl = 1, ipl
-               DO jk = 1, ipk
-                  DO jh = 1, nn_hls
-                     zt3sn(:,jh,jk,jl,jf,1) = ARRAY_IN(:,ijhom +jh,jk,jl,jf)
-                     zt3ns(:,jh,jk,jl,jf,1) = ARRAY_IN(:,nn_hls+jh,jk,jl,jf)
-                  END DO
-               END DO
-            END DO
-         END DO
-      CASE ( 1 )
-         ijhom = nlcj-nrecj
-         DO jf = 1, ipf
-            DO jl = 1, ipl
-               DO jk = 1, ipk
-                  DO jh = 1, nn_hls
-                     zt3ns(:,jh,jk,jl,jf,1) = ARRAY_IN(:,nn_hls+jh,jk,jl,jf)
-                  END DO
-               END DO
-            END DO
+      CASE ( jpfillcst   )                 ! filling with constant value
+         DO jf = 1, ipf                               ! number of arrays to be treated
+            IF( .NOT. NAT_IN(jf) == 'F' ) THEN        ! do nothing for F point
+               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
+            ENDIF
          END DO
       END SELECT
       !
-      !                           ! Migrations
-      imigr = nn_hls * jpi * ipk * ipl * ipf
-      !
-      IF( ln_timing ) CALL tic_tac(.TRUE.)
-      ! 
-      SELECT CASE ( nbondj )
-      CASE ( -1 )
-         CALL mppsend( 4, zt3sn(1,1,1,1,1,1), imigr, nono, ml_req1 )
-         CALL mpprecv( 3, zt3ns(1,1,1,1,1,1), imigr, nono )
-         IF(l_isend) CALL mpi_wait(ml_req1, ml_stat, ml_err )
-      CASE ( 0 )
-         CALL mppsend( 3, zt3ns(1,1,1,1,1,1), imigr, noso, ml_req1 )
-         CALL mppsend( 4, zt3sn(1,1,1,1,1,1), imigr, nono, ml_req2 )
-         CALL mpprecv( 3, zt3ns(1,1,1,1,1,2), imigr, nono )
-         CALL mpprecv( 4, zt3sn(1,1,1,1,1,2), imigr, noso )
-         IF(l_isend)   CALL mpi_wait(ml_req1, ml_stat, ml_err )
-         IF(l_isend)   CALL mpi_wait(ml_req2, ml_stat, ml_err )
-      CASE ( 1 )
-         CALL mppsend( 3, zt3ns(1,1,1,1,1,1), imigr, noso, ml_req1 )
-         CALL mpprecv( 4, zt3sn(1,1,1,1,1,1), imigr, noso )
-         IF(l_isend)   CALL mpi_wait(ml_req1, ml_stat, ml_err )
+      ! 5.2 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 = 1, jpi
+            ARRAY_IN(ji,ishift+jj,jk,jl,jf) = zrcv_no(ji,jj,jk,jl,jf)   ! jpj-nn_hls+1 -> jpj
+         END DO   ;   END DO   ;   END DO   ;   END DO   ;   END DO
+      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
       !
-      IF( ln_timing ) CALL tic_tac(.FALSE.)
-      !                           ! Write Dirichlet lateral conditions
-      ijhom = nlcj-nn_hls
-      !
-      SELECT CASE ( nbondj )
-      CASE ( -1 )
-         DO jf = 1, ipf
-            DO jl = 1, ipl
-               DO jk = 1, ipk
-                  DO jh = 1, nn_hls
-                     ARRAY_IN(:,ijhom+jh,jk,jl,jf) = zt3ns(:,jh,jk,jl,jf,1)
-                  END DO
-               END DO
-            END DO
-         END DO
-      CASE ( 0 )
-         DO jf = 1, ipf
-            DO jl = 1, ipl
-               DO jk = 1, ipk
-                  DO jh = 1, nn_hls
-                     ARRAY_IN(:,      jh,jk,jl,jf) = zt3sn(:,jh,jk,jl,jf,2)
-                     ARRAY_IN(:,ijhom+jh,jk,jl,jf) = zt3ns(:,jh,jk,jl,jf,2)
-                  END DO
-               END DO
-            END DO
-         END DO
-      CASE ( 1 )
-         DO jf = 1, ipf
-            DO jl = 1, ipl
-               DO jk = 1, ipk
-                  DO jh = 1, nn_hls
-                     ARRAY_IN(:,jh,jk,jl,jf) = zt3sn(:,jh,jk,jl,jf,1)
-                  END DO
-               END DO
-            END DO
-         END DO
-      END SELECT
-      !
-      IF( nbondj /= 2 ) DEALLOCATE( zt3ns, zt3sn )
+      ! -------------------------------------------- !
+      !     6. deallocate local temporary arrays     !
+      ! -------------------------------------------- !
+      !
+      IF( ifill_we == jpfillmpi ) THEN
+         CALL mpi_wait(ireq_we, istat, ierr )
+         DEALLOCATE( zsnd_we, zrcv_we )
+      ENDIF
+      IF( ifill_ea == jpfillmpi )  THEN
+         CALL mpi_wait(ireq_ea, istat, ierr )
+         DEALLOCATE( zsnd_ea, zrcv_ea )
+      ENDIF
+      IF( ifill_so == jpfillmpi ) THEN
+         CALL mpi_wait(ireq_so, istat, ierr )
+         DEALLOCATE( zsnd_so, zrcv_so )
+      ENDIF
+      IF( ifill_no == jpfillmpi ) THEN
+         CALL mpi_wait(ireq_no, istat, ierr )
+         DEALLOCATE( zsnd_no, zrcv_no )
+      ENDIF
       !
    END SUBROUTINE ROUTINE_LNK
Index: NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/LBC/mppini.F90
===================================================================
--- NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/LBC/mppini.F90	(revision 11191)
+++ NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/LBC/mppini.F90	(revision 11192)
@@ -84,5 +84,7 @@
       nbondj = 2
       nidom  = FLIO_DOM_NONE
-      npolj = jperio
+      npolj = 0
+      IF( jperio == 3 .OR. jperio == 4 )   npolj = 3
+      IF( jperio == 5 .OR. jperio == 6 )   npolj = 5
       l_Iperio = jpni == 1 .AND. (jperio == 1 .OR. jperio == 4 .OR. jperio == 6 .OR. jperio == 7)
       l_Jperio = jpnj == 1 .AND. (jperio == 2 .OR. jperio == 7)
