Index: /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/BDY/bdy_oce.F90
===================================================================
--- /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/BDY/bdy_oce.F90	(revision 11066)
+++ /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/BDY/bdy_oce.F90	(revision 11067)
@@ -139,4 +139,6 @@
    TYPE(OBC_DATA) , DIMENSION(jp_bdy), TARGET      ::   dta_bdy           !: bdy external data (local process)
 !$AGRIF_END_DO_NOT_TREAT
+   LOGICAL, ALLOCATABLE, DIMENSION(:,:,:) ::   lsend_bdy !: mark needed communication for given boundary, grid and direction
+   LOGICAL, ALLOCATABLE, DIMENSION(:,:,:) ::   lrecv_bdy !: mark needed communication for given boundary, grid and direction
    !!----------------------------------------------------------------------
    !! NEMO/OCE 4.0 , NEMO Consortium (2018)
Index: /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/BDY/bdydyn2d.F90
===================================================================
--- /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/BDY/bdydyn2d.F90	(revision 11066)
+++ /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/BDY/bdydyn2d.F90	(revision 11067)
@@ -50,8 +50,8 @@
       REAL(wp), DIMENSION(jpi,jpj), INTENT(in   ) :: pssh
       !!
-      INTEGER                                  ::   ib_bdy ! Loop counter
-
+      INTEGER                                  ::   ib_bdy     ! Loop counter
+      LOGICAL, DIMENSION(4) :: lsend2, lrecv2, lsend3, lrecv3  ! indicate how communications are to be carried out
+      
       DO ib_bdy=1, nb_bdy
-
          SELECT CASE( cn_dyn2d(ib_bdy) )
          CASE('none')
@@ -71,5 +71,35 @@
          END SELECT
       ENDDO
-
+      !
+      lsend2(:) = .false.
+      lrecv2(:) = .false.
+      lsend3(:) = .false.
+      lrecv3(:) = .false.
+      DO ib_bdy=1, nb_bdy
+         SELECT CASE( cn_dyn2d(ib_bdy) )
+         CASE('flather')
+            lsend2(:) = lsend2(:) .OR. lsend_bdy(ib_bdy,2,:)   ! to   every bdy neighbour, U points
+            lrecv2(:) = lrecv2(:) .OR. lrecv_bdy(ib_bdy,2,:)   ! from every bdy neighbour, U points
+            lsend3(:) = lsend3(:) .OR. lsend_bdy(ib_bdy,3,:)   ! to   every bdy neighbour, V points
+            lrecv3(:) = lrecv3(:) .OR. lrecv_bdy(ib_bdy,3,:)   ! from every bdy neighbour, V points
+         CASE('orlanski')
+            lsend2(:) = lsend2(:) .OR. lsend_bdy(ib_bdy,2,:)   ! to   every bdy neighbour, U points
+            lrecv2(:) = lrecv2(:) .OR. lrecv_bdy(ib_bdy,2,:)   ! from every bdy neighbour, U points
+            lsend3(:) = lsend3(:) .OR. lsend_bdy(ib_bdy,3,:)   ! to   every bdy neighbour, V points
+            lrecv3(:) = lrecv3(:) .OR. lrecv_bdy(ib_bdy,3,:)   ! from every bdy neighbour, V points
+         CASE('orlanski_npo')
+            lsend2(:) = lsend2(:) .OR. lsend_bdy(ib_bdy,2,:)   ! to   every bdy neighbour, U points
+            lrecv2(:) = lrecv2(:) .OR. lrecv_bdy(ib_bdy,2,:)   ! from every bdy neighbour, U points
+            lsend3(:) = lsend3(:) .OR. lsend_bdy(ib_bdy,3,:)   ! to   every bdy neighbour, V points
+            lrecv3(:) = lrecv3(:) .OR. lrecv_bdy(ib_bdy,3,:)   ! from every bdy neighbour, V points
+         END SELECT
+      END DO
+      IF( ANY(lsend2) .OR. ANY(lrecv2) ) THEN   ! if need to send/recv in at least one direction
+         CALL lbc_bdy_lnk( 'bdydyn2d', lsend2, lrecv2, pua2d, 'U', -1. )
+      END IF
+      IF( ANY(lsend3) .OR. ANY(lrecv3) ) THEN   ! if need to send/recv in at least one direction
+         CALL lbc_bdy_lnk( 'bdydyn2d', lsend3, lrecv3, pva2d, 'V', -1. )
+      END IF
+      !
    END SUBROUTINE bdy_dyn2d
 
@@ -110,6 +140,4 @@
          pva2d(ii,ij) = ( pva2d(ii,ij) + zwgt * ( dta%v2d(jb) - pva2d(ii,ij) ) ) * vmask(ii,ij,1)
       END DO 
-      CALL lbc_bdy_lnk( 'bdydyn2d', pua2d, 'U', -1., ib_bdy ) 
-      CALL lbc_bdy_lnk( 'bdydyn2d', pva2d, 'V', -1., ib_bdy)   ! Boundary points should be updated
       !
    END SUBROUTINE bdy_dyn2d_frs
@@ -170,5 +198,4 @@
       END DO
 
-      CALL lbc_bdy_lnk( 'bdydyn2d', spgu(:,:), 'T', 1., ib_bdy )
       !
       igrd = 2      ! Flather bc on u-velocity; 
@@ -210,6 +237,4 @@
          pva2d(ii,ij) = zforc + (1._wp - z1_2*zflag) * zcorr * vmask(ii,ij,1)
       END DO
-      CALL lbc_bdy_lnk( 'bdydyn2d', pua2d, 'U', -1., ib_bdy )   ! Boundary points should be updated
-      CALL lbc_bdy_lnk( 'bdydyn2d', pva2d, 'V', -1., ib_bdy )   !
       !
    END SUBROUTINE bdy_dyn2d_fla
@@ -246,7 +271,4 @@
       CALL bdy_orlanski_2d( idx, igrd, pvb2d, pva2d, dta%v2d, ll_npo )
       !
-      CALL lbc_bdy_lnk( 'bdydyn2d', pua2d, 'U', -1., ib_bdy )   ! Boundary points should be updated
-      CALL lbc_bdy_lnk( 'bdydyn2d', pva2d, 'V', -1., ib_bdy )   !
-      !
    END SUBROUTINE bdy_dyn2d_orlanski
 
@@ -262,9 +284,16 @@
       !!
       INTEGER  ::   ib_bdy          ! bdy index
-      !!----------------------------------------------------------------------
+      LOGICAL, DIMENSION(4) :: lsend1, lrecv1  ! indicate how communications are to be carried out
+      !!----------------------------------------------------------------------
+      lsend1(:) = .false.
+      lrecv1(:) = .false.
       DO ib_bdy = 1, nb_bdy
          CALL bdy_nmn( idx_bdy(ib_bdy), 1, zssh )   ! zssh is masked
-         CALL lbc_bdy_lnk( 'bdydyn2d', zssh(:,:,1), 'T', 1., ib_bdy )
-      END DO
+         lsend1(:) = lsend1(:) .OR. lsend_bdy(ib_bdy,1,:)   ! to   every bdy neighbour, T points
+         lrecv1(:) = lrecv1(:) .OR. lrecv_bdy(ib_bdy,1,:)   ! from every bdy neighbour, T points
+      END DO
+      IF( ANY(lsend1) .OR. ANY(lrecv1) ) THEN   ! if need to send/recv in at least one direction
+         CALL lbc_bdy_lnk( 'bdydyn2d', lsend1, lrecv1, zssh(:,:,1), 'T',  1. )
+      END IF
       !
    END SUBROUTINE bdy_ssh
Index: /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/BDY/bdydyn3d.F90
===================================================================
--- /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/BDY/bdydyn3d.F90	(revision 11066)
+++ /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/BDY/bdydyn3d.F90	(revision 11067)
@@ -43,6 +43,7 @@
       !
       INTEGER ::   ib_bdy   ! loop index
-      !!----------------------------------------------------------------------
-      !
+      LOGICAL, DIMENSION(4) :: lsend2, lrecv2, lsend3, lrecv3  ! indicate how communications are to be carried out
+
+      !!----------------------------------------------------------------------
       DO ib_bdy=1, nb_bdy
          !
@@ -60,4 +61,40 @@
       END DO
       !
+      lsend2(:) = .false.
+      lrecv2(:) = .false.
+      lsend3(:) = .false.
+      lrecv3(:) = .false.
+      DO ib_bdy=1, nb_bdy
+         SELECT CASE( cn_dyn3d(ib_bdy) )
+         CASE('orlanski')
+            lsend2(:) = lsend2(:) .OR. lsend_bdy(ib_bdy,2,:)   ! to   every bdy neighbour, U points
+            lrecv2(:) = lrecv2(:) .OR. lrecv_bdy(ib_bdy,2,:)   ! from every bdy neighbour, U points
+            lsend3(:) = lsend3(:) .OR. lsend_bdy(ib_bdy,3,:)   ! to   every bdy neighbour, V points
+            lrecv3(:) = lrecv3(:) .OR. lrecv_bdy(ib_bdy,3,:)   ! from every bdy neighbour, V points
+         CASE('orlanski_npo')
+            lsend2(:) = lsend2(:) .OR. lsend_bdy(ib_bdy,2,:)   ! to   every bdy neighbour, U points
+            lrecv2(:) = lrecv2(:) .OR. lrecv_bdy(ib_bdy,2,:)   ! from every bdy neighbour, U points
+            lsend3(:) = lsend3(:) .OR. lsend_bdy(ib_bdy,3,:)   ! to   every bdy neighbour, V points
+            lrecv3(:) = lrecv3(:) .OR. lrecv_bdy(ib_bdy,3,:)   ! from every bdy neighbour, V points
+         CASE('zerograd')
+            lsend2(:) = lsend2(:) .OR. lsend_bdy(ib_bdy,2,:)   ! to   every bdy neighbour, U points
+            lrecv2(:) = lrecv2(:) .OR. lrecv_bdy(ib_bdy,2,:)   ! from every bdy neighbour, U points
+            lsend3(:) = lsend3(:) .OR. lsend_bdy(ib_bdy,3,:)   ! to   every bdy neighbour, V points
+            lrecv3(:) = lrecv3(:) .OR. lrecv_bdy(ib_bdy,3,:)   ! from every bdy neighbour, V points
+         CASE('neumann')
+            lsend2(:) = lsend2(:) .OR. lsend_bdy(ib_bdy,2,:)   ! to   every bdy neighbour, U points
+            lrecv2(:) = lrecv2(:) .OR. lrecv_bdy(ib_bdy,2,:)   ! from every bdy neighbour, U points
+            lsend3(:) = lsend3(:) .OR. lsend_bdy(ib_bdy,3,:)   ! to   every bdy neighbour, V points
+            lrecv3(:) = lrecv3(:) .OR. lrecv_bdy(ib_bdy,3,:)   ! from every bdy neighbour, V points
+         END SELECT
+      END DO
+      !
+      IF( ANY(lsend2) .OR. ANY(lrecv2) ) THEN   ! if need to send/recv in at least one direction
+         CALL lbc_bdy_lnk( 'bdydyn2d', lsend2, lrecv2, ua, 'U', -1. )
+      END IF
+      IF( ANY(lsend3) .OR. ANY(lrecv3) ) THEN   ! if need to send/recv in at least one direction
+         CALL lbc_bdy_lnk( 'bdydyn2d', lsend3, lrecv3, va, 'V', -1. )
+      END IF
+      !
    END SUBROUTINE bdy_dyn3d
 
@@ -78,5 +115,4 @@
       INTEGER  ::   jb, jk         ! dummy loop indices
       INTEGER  ::   ii, ij, igrd   ! local integers
-      REAL(wp) ::   zwgt           ! boundary weight
       !!----------------------------------------------------------------------
       !
@@ -98,7 +134,4 @@
          END DO
       END DO
-      !
-      CALL lbc_bdy_lnk( 'bdydyn3d', ua, 'U', -1., ib_bdy )   ! Boundary points should be updated  
-      CALL lbc_bdy_lnk( 'bdydyn3d', va, 'V', -1., ib_bdy )
       !
    END SUBROUTINE bdy_dyn3d_spe
@@ -156,7 +189,4 @@
       END DO
       !
-      CALL lbc_bdy_lnk( 'bdydyn3d', ua, 'U', -1., ib_bdy )   ! Boundary points should be updated  
-      CALL lbc_bdy_lnk( 'bdydyn3d', va, 'V', -1., ib_bdy )   
-      !
    END SUBROUTINE bdy_dyn3d_zgrad
 
@@ -176,5 +206,4 @@
       INTEGER  ::   ib, ik         ! dummy loop indices
       INTEGER  ::   ii, ij, igrd   ! local integers
-      REAL(wp) ::   zwgt           ! boundary weight
       !!----------------------------------------------------------------------
       !
@@ -187,5 +216,5 @@
          END DO
       END DO
-
+      !
       igrd = 3                       ! Everything is at T-points here
       DO ib = 1, idx%nblenrim(igrd)
@@ -196,6 +225,4 @@
          END DO
       END DO
-      !
-      CALL lbc_bdy_lnk( 'bdydyn3d', ua, 'U', -1., ib_bdy )   ;   CALL lbc_bdy_lnk( 'bdydyn3d', va, 'V', -1.,ib_bdy )   ! Boundary points should be updated
       !
    END SUBROUTINE bdy_dyn3d_zro
@@ -241,8 +268,5 @@
             va(ii,ij,jk) = ( va(ii,ij,jk) + zwgt * ( dta%v3d(jb,jk) - va(ii,ij,jk) ) ) * vmask(ii,ij,jk)
          END DO
-      END DO 
-      !
-      CALL lbc_bdy_lnk( 'bdydyn3d', ua, 'U', -1., ib_bdy )    ! Boundary points should be updated
-      CALL lbc_bdy_lnk( 'bdydyn3d', va, 'V', -1., ib_bdy )   
+      END DO   
       !
    END SUBROUTINE bdy_dyn3d_frs
@@ -276,7 +300,4 @@
       !  
       CALL bdy_orlanski_3d( idx, igrd, vb, va, dta%v3d, ll_npo )
-      !
-      CALL lbc_bdy_lnk( 'bdydyn3d', ua, 'U', -1., ib_bdy )    ! Boundary points should be updated
-      CALL lbc_bdy_lnk( 'bdydyn3d', va, 'V', -1., ib_bdy )   
       !
    END SUBROUTINE bdy_dyn3d_orlanski
@@ -326,6 +347,4 @@
       END DO
       !
-      CALL lbc_lnk_multi( 'bdydyn3d', ua, 'U', -1.,  va, 'V', -1. )   ! Boundary points should be updated
-      !
       IF( ln_timing )   CALL timing_stop('bdy_dyn3d_dmp')
       !
@@ -346,4 +365,5 @@
 
       INTEGER  ::   jb, igrd                               ! dummy loop indices
+      LOGICAL, DIMENSION(4) :: lsend2, lrecv2, lsend3, lrecv3  ! indicate how communications are to be carried out
       !!----------------------------------------------------------------------
       !
@@ -358,7 +378,4 @@
       CALL bdy_nmn( idx, igrd, va )   ! va is masked
       !
-      CALL lbc_bdy_lnk( 'bdydyn3d', ua, 'U', -1., ib_bdy )    ! Boundary points should be updated
-      CALL lbc_bdy_lnk( 'bdydyn3d', va, 'V', -1., ib_bdy )
-      !
    END SUBROUTINE bdy_dyn3d_nmn
 
Index: /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/BDY/bdyice.F90
===================================================================
--- /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/BDY/bdyice.F90	(revision 11066)
+++ /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/BDY/bdyice.F90	(revision 11067)
@@ -55,5 +55,6 @@
       INTEGER, INTENT(in) ::   kt   ! Main time step counter
       !
-      INTEGER ::   jbdy   ! BDY set index
+      INTEGER ::   jbdy                               ! BDY set index
+      LOGICAL, DIMENSION(4)       :: lsend1, lrecv1   ! indicate how communications are to be carried out
       !!----------------------------------------------------------------------
       ! controls
@@ -73,4 +74,24 @@
          !
       END DO
+      !
+      ! Update bdy points
+      lsend1(:) = .false.
+      lrecv1(:) = .false.
+      DO jbdy = 1, nb_bdy
+         IF( cn_ice(jbdy) == 'frs' ) THEN
+            lsend1(:) = lsend1(:) .OR. lsend_bdy(jbdy,1,:)   ! to   every neighbour, T points
+            lrecv1(:) = lrecv1(:) .OR. lrecv_bdy(jbdy,1,:)   ! from every neighbour, T points
+         END IF
+      END DO
+      IF( ANY(lsend1) .OR. ANY(lrecv1) ) THEN   ! if need to send/recv in at least one direction
+         ! exchange 3d arrays
+         CALL lbc_bdy_lnk_multi( 'bdyice', lsend1, lrecv1, a_i , 'T', 1., h_i , 'T', 1., h_s , 'T', 1. &
+              &                                          , oa_i, 'T', 1., a_ip, 'T', 1., v_ip, 'T', 1. &
+              &                                          , s_i , 'T', 1., t_su, 'T', 1., v_i , 'T', 1. &
+              &                                          , v_s , 'T', 1., sv_i, 'T', 1.                )
+         ! exchange 4d arrays
+         CALL lbc_bdy_lnk_multi( 'bdyice', lsend1, lrecv1, t_s , 'T', 1., e_s , 'T', 1. )   ! third dimension = 1
+         CALL lbc_bdy_lnk_multi( 'bdyice', lsend1, lrecv1, t_i , 'T', 1., e_i , 'T', 1. )   ! third dimension = 2
+      END IF
       !
       CALL ice_cor( kt , 0 )      ! -- In case categories are out of bounds, do a remapping
@@ -139,7 +160,4 @@
          ENDDO
       ENDDO
-      CALL lbc_bdy_lnk( 'bdyice', a_i(:,:,:), 'T', 1., jbdy )
-      CALL lbc_bdy_lnk( 'bdyice', h_i(:,:,:), 'T', 1., jbdy )
-      CALL lbc_bdy_lnk( 'bdyice', h_s(:,:,:), 'T', 1., jbdy )
 
       DO jl = 1, jpl
@@ -260,20 +278,4 @@
          !
       END DO ! jl
-
-      CALL lbc_bdy_lnk( 'bdyice', a_i (:,:,:)  , 'T', 1., jbdy )
-      CALL lbc_bdy_lnk( 'bdyice', h_i (:,:,:)  , 'T', 1., jbdy )
-      CALL lbc_bdy_lnk( 'bdyice', h_s (:,:,:)  , 'T', 1., jbdy )
-      CALL lbc_bdy_lnk( 'bdyice', oa_i(:,:,:)  , 'T', 1., jbdy )
-      CALL lbc_bdy_lnk( 'bdyice', a_ip(:,:,:)  , 'T', 1., jbdy )
-      CALL lbc_bdy_lnk( 'bdyice', v_ip(:,:,:)  , 'T', 1., jbdy )
-      CALL lbc_bdy_lnk( 'bdyice', s_i (:,:,:)  , 'T', 1., jbdy )
-      CALL lbc_bdy_lnk( 'bdyice', t_su(:,:,:)  , 'T', 1., jbdy )
-      CALL lbc_bdy_lnk( 'bdyice', v_i (:,:,:)  , 'T', 1., jbdy )
-      CALL lbc_bdy_lnk( 'bdyice', v_s (:,:,:)  , 'T', 1., jbdy )
-      CALL lbc_bdy_lnk( 'bdyice', sv_i(:,:,:)  , 'T', 1., jbdy )
-      CALL lbc_bdy_lnk( 'bdyice', t_s (:,:,:,:), 'T', 1., jbdy )
-      CALL lbc_bdy_lnk( 'bdyice', e_s (:,:,:,:), 'T', 1., jbdy )
-      CALL lbc_bdy_lnk( 'bdyice', t_i (:,:,:,:), 'T', 1., jbdy )
-      CALL lbc_bdy_lnk( 'bdyice', e_i (:,:,:,:), 'T', 1., jbdy )
       !      
    END SUBROUTINE bdy_ice_frs
@@ -297,4 +299,5 @@
       INTEGER  ::   jbdy             ! BDY set index
       REAL(wp) ::   zmsk1, zmsk2, zflag
+      LOGICAL, DIMENSION(4) :: lsend2, lrecv2, lsend3, lrecv3  ! indicate how communications are to be carried out
       !!------------------------------------------------------------------------------
       IF( ln_timing )   CALL timing_start('bdy_ice_dyn')
@@ -339,5 +342,4 @@
                   !
                END DO
-               CALL lbc_bdy_lnk( 'bdyice', u_ice(:,:), 'U', -1., jbdy )
                !
             CASE ( 'V' )
@@ -371,5 +373,4 @@
                   !
                END DO
-               CALL lbc_bdy_lnk( 'bdyice', v_ice(:,:), 'V', -1., jbdy )
                !
             END SELECT
@@ -379,5 +380,30 @@
          END SELECT
          !
-      END DO
+      END DO   ! jbdy
+      !
+      SELECT CASE ( cd_type )        
+      CASE ( 'U' ) 
+         lsend2(:) = .false.   ;   lrecv2(:) = .false.
+         DO jbdy = 1, nb_bdy
+            IF( cn_ice(jbdy) == 'frs' .AND. nn_ice_dta(jbdy) /= 0 ) THEN
+               lsend2(:) = lsend2(:) .OR. lsend_bdy(jbdy,2,:)   ! to   every bdy neighbour, U points
+               lrecv2(:) = lrecv2(:) .OR. lrecv_bdy(jbdy,2,:)   ! from every bdy neighbour, U points
+            END IF
+         END DO
+         IF( ANY(lsend2) .OR. ANY(lrecv2) ) THEN   ! if need to send/recv in at least one direction
+            CALL lbc_bdy_lnk( 'bdyice', lsend2, lrecv2, u_ice, 'U', -1. )
+         END IF
+      CASE ( 'V' )
+         lsend3(:) = .false.   ;   lrecv3(:) = .false.
+         DO jbdy = 1, nb_bdy
+            IF( cn_ice(jbdy) == 'frs' .AND. nn_ice_dta(jbdy) /= 0 ) THEN
+               lsend3(:) = lsend3(:) .OR. lsend_bdy(jbdy,3,:)   ! to   every bdy neighbour, V points
+               lrecv3(:) = lrecv3(:) .OR. lrecv_bdy(jbdy,3,:)   ! from every bdy neighbour, V points
+            END IF
+         END DO
+         IF( ANY(lsend3) .OR. ANY(lrecv3) ) THEN   ! if need to send/recv in at least one direction
+            CALL lbc_bdy_lnk( 'bdyice', lsend3, lrecv3, v_ice, 'V', -1. )
+         END IF
+      END SELECT
       !
       IF( ln_timing )   CALL timing_stop('bdy_ice_dyn')
Index: /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/BDY/bdyini.F90
===================================================================
--- /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/BDY/bdyini.F90	(revision 11066)
+++ /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/BDY/bdyini.F90	(revision 11067)
@@ -37,5 +37,4 @@
    INTEGER, PARAMETER ::   jp_nseg = 100   ! 
    INTEGER, PARAMETER ::   nrimmax =  20   ! maximum rimwidth in structured
-   INTEGER  :: nde = 1 ! domain extended in the halo to deal with bondaries 
                                                ! open boundary data files
    ! Straight open boundary segment parameters:
@@ -1177,4 +1176,46 @@
       END DO
 
+
+      ALLOCATE( lsend_bdy(nb_bdy,jpbgrd,4), lrecv_bdy(nb_bdy,jpbgrd,4) )
+      lsend_bdy(:,:,:) = .false.
+      lrecv_bdy(:,:,:) = .false. 
+      !
+      ! Check which boundaries might need communication
+      DO igrd = 1, jpbgrd
+         DO ib_bdy = 1, nb_bdy
+            IF     ( nbondi_bdy  (ib_bdy) ==  0 )   THEN 
+               lsend_bdy(ib_bdy,igrd,1) = .true.
+               lsend_bdy(ib_bdy,igrd,2) = .true.
+            ELSE IF( nbondi_bdy  (ib_bdy) ==  1 )   THEN
+               lsend_bdy(ib_bdy,igrd,1) = .true.
+            ELSE IF( nbondi_bdy  (ib_bdy) == -1 )   THEN
+               lsend_bdy(ib_bdy,igrd,2) = .true.
+            END IF
+            IF     ( nbondi_bdy_b(ib_bdy) ==  0 )   THEN 
+               lrecv_bdy(ib_bdy,igrd,1) = .true.
+               lrecv_bdy(ib_bdy,igrd,2) = .true.
+            ELSE IF( nbondi_bdy_b(ib_bdy) ==  1 )   THEN
+               lrecv_bdy(ib_bdy,igrd,1) = .true.
+            ELSE IF( nbondi_bdy_b(ib_bdy) == -1 )   THEN
+               lrecv_bdy(ib_bdy,igrd,2) = .true.
+            END IF
+            IF(      nbondj_bdy  (ib_bdy) ==  0 )   THEN 
+               lsend_bdy(ib_bdy,igrd,3) = .true.
+               lsend_bdy(ib_bdy,igrd,4) = .true.
+            ELSE IF( nbondj_bdy  (ib_bdy) ==  1 )   THEN
+               lsend_bdy(ib_bdy,igrd,3) = .true.
+            ELSE IF( nbondj_bdy  (ib_bdy) == -1 )   THEN
+               lsend_bdy(ib_bdy,igrd,4) = .true.
+            END IF
+            IF(      nbondj_bdy_b(ib_bdy) ==  0 )   THEN 
+               lrecv_bdy(ib_bdy,igrd,3) = .true.
+               lrecv_bdy(ib_bdy,igrd,4) = .true.
+            ELSE IF( nbondj_bdy_b(ib_bdy) ==  1 )   THEN
+               lrecv_bdy(ib_bdy,igrd,3) = .true.
+            ELSE IF( nbondj_bdy_b(ib_bdy) == -1 )   THEN
+               lrecv_bdy(ib_bdy,igrd,4) = .true.
+            END IF
+         END DO
+      END DO
       !
       ! Tidy up
Index: /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/BDY/bdytra.F90
===================================================================
--- /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/BDY/bdytra.F90	(revision 11066)
+++ /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/BDY/bdytra.F90	(revision 11067)
@@ -51,4 +51,5 @@
       INTEGER                        :: ib_bdy, jn, igrd   ! Loop indeces
       TYPE(ztrabdy), DIMENSION(jpts) :: zdta               ! Temporary data structure
+      LOGICAL, DIMENSION(4)          :: lsend1, lrecv1     ! indicate how communications are to be carried out
       !!----------------------------------------------------------------------
       igrd = 1 
@@ -71,9 +72,29 @@
             CASE DEFAULT           ;   CALL ctl_stop( 'bdy_tra : unrecognised option for open boundaries for T and S' )
             END SELECT
-            ! Boundary points should be updated
-            CALL lbc_bdy_lnk( 'bdytra', tsa(:,:,:,jn), 'T', 1., ib_bdy )
             ! 
          END DO
       END DO
+      !
+      lsend1(:) = .false.
+      lrecv1(:) = .false.
+      DO ib_bdy=1, nb_bdy
+         SELECT CASE( TRIM(cn_tra(ib_bdy)) )
+         CASE('neumann')
+            lsend1(:) = lsend1(:) .OR. lsend_bdy(ib_bdy,1,:)   ! to   every bdy neighbour, T points
+            lrecv1(:) = lrecv1(:) .OR. lrecv_bdy(ib_bdy,1,:)   ! from every bdy neighbour, T points
+         CASE('orlanski')
+            lsend1(:) = lsend1(:) .OR. lsend_bdy(ib_bdy,1,:)   ! to   every bdy neighbour, T points
+            lrecv1(:) = lrecv1(:) .OR. lrecv_bdy(ib_bdy,1,:)   ! from every bdy neighbour, T points
+         CASE('orlanski_npo')
+            lsend1(:) = lsend1(:) .OR. lsend_bdy(ib_bdy,1,:)   ! to   every bdy neighbour, T points
+            lrecv1(:) = lrecv1(:) .OR. lrecv_bdy(ib_bdy,1,:)   ! from every bdy neighbour, T points
+         CASE('runoff')
+            lsend1(:) = lsend1(:) .OR. lsend_bdy(ib_bdy,1,:)   ! to   every bdy neighbour, T points
+            lrecv1(:) = lrecv1(:) .OR. lrecv_bdy(ib_bdy,1,:)   ! from every bdy neighbour, T points
+         END SELECT
+      END DO
+      IF( ANY(lsend1) .OR. ANY(lrecv1) ) THEN   ! if need to send/recv in at least one direction
+         CALL lbc_bdy_lnk( 'bdytra', lsend1, lrecv1, tsa, 'T',  1. )
+      END IF
       !
    END SUBROUTINE bdy_tra
Index: /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/DYN/dynkeg.F90
===================================================================
--- /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/DYN/dynkeg.F90	(revision 11066)
+++ /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/DYN/dynkeg.F90	(revision 11067)
@@ -80,4 +80,5 @@
       REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) ::   ztrdu, ztrdv 
       REAL(wp)  :: zweightu, zweightv
+      LOGICAL, DIMENSION(4) :: lsend1, lrecv1  ! indicate how bdy communications are to be carried out
       !!----------------------------------------------------------------------
       !
@@ -134,6 +135,15 @@
                   END DO
                END IF
-               CALL lbc_bdy_lnk( 'dynkeg', zhke, 'T', 1., ib_bdy )   ! send 2 and recv jpi, jpj used in the computation of the speed tendencies
-            END DO
+            END DO
+            ! send 2 and recv jpi, jpj used in the computation of the speed tendencies
+            lsend1(:) = .false.
+            lrecv1(:) = .false.
+            DO ib_bdy = 1, nb_bdy
+               lsend1(:) = lsend1(:) .OR. lsend_bdy(ib_bdy,1,:)   ! to   every bdy neighbour, T points
+               lrecv1(:) = lrecv1(:) .OR. lrecv_bdy(ib_bdy,1,:)   ! from every bdy neighbour, T points
+            END DO
+            IF( COUNT(lsend1) > 0 .OR. COUNT(lrecv1) > 0 ) THEN   ! if need to send/recv in at least one direction
+               CALL lbc_bdy_lnk( 'bdydyn2d', lsend1, lrecv1, zhke, 'T',  1. )
+            END IF
          END IF
          !
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 11066)
+++ /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/LBC/lbc_lnk_multi_generic.h90	(revision 11067)
@@ -14,23 +14,34 @@
 #   define PTR_ptab              pt4d
 #endif
-   SUBROUTINE ROUTINE_MULTI( cdname                                                    &
-      &                    , pt1, cdna1, psgn1, pt2, cdna2, psgn2, pt3, cdna3, psgn3   &
-      &                    , pt4, cdna4, psgn4, pt5, cdna5, psgn5, pt6, cdna6, psgn6   &
-      &                    , pt7, cdna7, psgn7, pt8, cdna8, psgn8, pt9, cdna9, psgn9, cd_mpp, pval)
+
+#if defined IS_BDY
+   SUBROUTINE ROUTINE_MULTI( cdname, lsend, lrecv                                                               &
+      &                    , pt1, cdna1, psgn1, pt2 , cdna2 , psgn2 , pt3 , cdna3 , psgn3 , pt4, cdna4, psgn4   &
+      &                    , pt5, cdna5, psgn5, pt6 , cdna6 , psgn6 , pt7 , cdna7 , psgn7 , pt8, cdna8, psgn8   &
+      &                    , pt9, cdna9, psgn9, pt10, cdna10, psgn10, pt11, cdna11, psgn11                      &
+      &                    , cd_mpp, pval )
+      LOGICAL, DIMENSION(4)        , INTENT(in   ) ::   lsend, lrecv   ! indicate how communications are to be carried out
+#else
+   SUBROUTINE ROUTINE_MULTI( cdname                                                                             &
+      &                    , pt1, cdna1, psgn1, pt2 , cdna2 , psgn2 , pt3 , cdna3 , psgn3 , pt4, cdna4, psgn4   &
+      &                    , pt5, cdna5, psgn5, pt6 , cdna6 , psgn6 , pt7 , cdna7 , psgn7 , pt8, cdna8, psgn8   &
+      &                    , pt9, cdna9, psgn9, pt10, cdna10, psgn10, pt11, cdna11, psgn11                      &
+      &                    , cd_mpp, pval )
+#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
-      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
-      REAL(wp)                             , INTENT(in   ) ::   psgn1   ! sign used across the north fold
-      REAL(wp)           , OPTIONAL        , INTENT(in   ) ::   psgn2,  psgn3, psgn4, psgn5, psgn6, psgn7, psgn8, psgn9   
-      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
+      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                         ::   kfld        ! number of elements that will be attributed
-      PTR_TYPE         , DIMENSION(9) ::   ptab_ptr    ! pointer array
-      CHARACTER(len=1) , DIMENSION(9) ::   cdna_ptr    ! nature of ptab_ptr grid-points
-      REAL(wp)         , DIMENSION(9) ::   psgn_ptr    ! sign used across the north fold boundary
+      INTEGER                          ::   kfld        ! number of elements that will be attributed
+      PTR_TYPE         , DIMENSION(11) ::   ptab_ptr    ! pointer array
+      CHARACTER(len=1) , DIMENSION(11) ::   cdna_ptr    ! nature of ptab_ptr grid-points
+      REAL(wp)         , DIMENSION(11) ::   psgn_ptr    ! sign used across the north fold boundary
       !!---------------------------------------------------------------------
       !
@@ -41,14 +52,20 @@
       !
       !                 ! Look if more arrays are added
-      IF( PRESENT(psgn2) )   CALL ROUTINE_LOAD( pt2, cdna2, psgn2, ptab_ptr, cdna_ptr, psgn_ptr, kfld )
-      IF( PRESENT(psgn3) )   CALL ROUTINE_LOAD( pt3, cdna3, psgn3, ptab_ptr, cdna_ptr, psgn_ptr, kfld )
-      IF( PRESENT(psgn4) )   CALL ROUTINE_LOAD( pt4, cdna4, psgn4, ptab_ptr, cdna_ptr, psgn_ptr, kfld )
-      IF( PRESENT(psgn5) )   CALL ROUTINE_LOAD( pt5, cdna5, psgn5, ptab_ptr, cdna_ptr, psgn_ptr, kfld )
-      IF( PRESENT(psgn6) )   CALL ROUTINE_LOAD( pt6, cdna6, psgn6, ptab_ptr, cdna_ptr, psgn_ptr, kfld )
-      IF( PRESENT(psgn7) )   CALL ROUTINE_LOAD( pt7, cdna7, psgn7, ptab_ptr, cdna_ptr, psgn_ptr, kfld )
-      IF( PRESENT(psgn8) )   CALL ROUTINE_LOAD( pt8, cdna8, psgn8, ptab_ptr, cdna_ptr, psgn_ptr, kfld )
-      IF( PRESENT(psgn9) )   CALL ROUTINE_LOAD( pt9, cdna9, psgn9, ptab_ptr, cdna_ptr, psgn_ptr, kfld )
+      IF( PRESENT(psgn2 ) )   CALL ROUTINE_LOAD( pt2 , cdna2 , psgn2 , ptab_ptr, cdna_ptr, psgn_ptr, kfld )
+      IF( PRESENT(psgn3 ) )   CALL ROUTINE_LOAD( pt3 , cdna3 , psgn3 , ptab_ptr, cdna_ptr, psgn_ptr, kfld )
+      IF( PRESENT(psgn4 ) )   CALL ROUTINE_LOAD( pt4 , cdna4 , psgn4 , ptab_ptr, cdna_ptr, psgn_ptr, kfld )
+      IF( PRESENT(psgn5 ) )   CALL ROUTINE_LOAD( pt5 , cdna5 , psgn5 , ptab_ptr, cdna_ptr, psgn_ptr, kfld )
+      IF( PRESENT(psgn6 ) )   CALL ROUTINE_LOAD( pt6 , cdna6 , psgn6 , ptab_ptr, cdna_ptr, psgn_ptr, kfld )
+      IF( PRESENT(psgn7 ) )   CALL ROUTINE_LOAD( pt7 , cdna7 , psgn7 , ptab_ptr, cdna_ptr, psgn_ptr, kfld )
+      IF( PRESENT(psgn8 ) )   CALL ROUTINE_LOAD( pt8 , cdna8 , psgn8 , ptab_ptr, cdna_ptr, psgn_ptr, kfld )
+      IF( PRESENT(psgn9 ) )   CALL ROUTINE_LOAD( pt9 , cdna9 , psgn9 , ptab_ptr, cdna_ptr, psgn_ptr, kfld )
+      IF( PRESENT(psgn10) )   CALL ROUTINE_LOAD( pt10, cdna10, psgn10, ptab_ptr, cdna_ptr, psgn_ptr, kfld )
+      IF( PRESENT(psgn11) )   CALL ROUTINE_LOAD( pt11, cdna11, psgn11, ptab_ptr, cdna_ptr, psgn_ptr, kfld )
       !
-      CALL lbc_lnk_ptr( cdname, ptab_ptr, cdna_ptr, psgn_ptr, kfld, cd_mpp, pval )
+#if defined IS_BDY
+      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 )
+#endif
       !
    END SUBROUTINE ROUTINE_MULTI
@@ -72,4 +89,5 @@
       !
    END SUBROUTINE ROUTINE_LOAD
+
 #undef ARRAY_TYPE
 #undef PTR_TYPE
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 11066)
+++ /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/LBC/lbclnk.F90	(revision 11067)
@@ -38,5 +38,11 @@
    !
    INTERFACE lbc_bdy_lnk
-      MODULE PROCEDURE mpp_lnk_bdy_2d, mpp_lnk_bdy_3d, mpp_lnk_bdy_4d
+      MODULE PROCEDURE   mpp_lnk_bdy_2d      , mpp_lnk_bdy_3d      , mpp_lnk_bdy_4d
+   END INTERFACE
+   INTERFACE lbc_bdy_lnk_ptr
+      MODULE PROCEDURE   mpp_lnk_bdy_2d_ptr  , mpp_lnk_bdy_3d_ptr  , mpp_lnk_bdy_4d_ptr
+   END INTERFACE
+   INTERFACE lbc_bdy_lnk_multi
+      MODULE PROCEDURE   lbc_lnk_bdy_2d_multi, lbc_lnk_bdy_3d_multi, lbc_lnk_bdy_4d_multi
    END INTERFACE
    !
@@ -45,8 +51,9 @@
    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
+   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
 
    !!----------------------------------------------------------------------
@@ -256,29 +263,49 @@
 
 #  define DIM_2d
+#     define ROUTINE_LOAD           load_ptr_2d
 #     define ROUTINE_MULTI          lbc_lnk_2d_multi
-#     define ROUTINE_LOAD           load_ptr_2d
-#     include "lbc_lnk_multi_generic.h90"
-#     undef ROUTINE_MULTI
+#     include "lbc_lnk_multi_generic.h90"
+#     undef ROUTINE_MULTI
+#     undef ROUTINE_LOAD
+#     define IS_BDY
+#     define ROUTINE_LOAD           load_ptr_bdy_2d
+#     define ROUTINE_MULTI          lbc_lnk_bdy_2d_multi
+#     include "lbc_lnk_multi_generic.h90"
+#     undef ROUTINE_MULTI
+#     undef IS_BDY
 #     undef ROUTINE_LOAD
 #  undef DIM_2d
 
-
 #  define DIM_3d
+#     define ROUTINE_LOAD           load_ptr_3d
 #     define ROUTINE_MULTI          lbc_lnk_3d_multi
-#     define ROUTINE_LOAD           load_ptr_3d
-#     include "lbc_lnk_multi_generic.h90"
-#     undef ROUTINE_MULTI
+#     include "lbc_lnk_multi_generic.h90"
+#     undef ROUTINE_MULTI
+#     undef ROUTINE_LOAD
+#     define IS_BDY
+#     define ROUTINE_LOAD           load_ptr_bdy_3d
+#     define ROUTINE_MULTI          lbc_lnk_bdy_3d_multi
+#     include "lbc_lnk_multi_generic.h90"
+#     undef ROUTINE_MULTI
+#     undef IS_BDY
 #     undef ROUTINE_LOAD
 #  undef DIM_3d
 
-
 #  define DIM_4d
+#     define ROUTINE_LOAD           load_ptr_4d
 #     define ROUTINE_MULTI          lbc_lnk_4d_multi
-#     define ROUTINE_LOAD           load_ptr_4d
-#     include "lbc_lnk_multi_generic.h90"
-#     undef ROUTINE_MULTI
+#     include "lbc_lnk_multi_generic.h90"
+#     undef ROUTINE_MULTI
+#     undef ROUTINE_LOAD
+#     define IS_BDY
+#     define ROUTINE_LOAD           load_ptr_bdy_4d
+#     define ROUTINE_MULTI          lbc_lnk_bdy_4d_multi
+#     include "lbc_lnk_multi_generic.h90"
+#     undef ROUTINE_MULTI
+#     undef IS_BDY
 #     undef ROUTINE_LOAD
 #  undef DIM_4d
 
+
    !!======================================================================
 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 11066)
+++ /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/LBC/lib_mpp.F90	(revision 11067)
@@ -69,6 +69,8 @@
 
    ! 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_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
@@ -87,5 +89,4 @@
    PUBLIC   mpp_ini_znl
    PUBLIC   mppsend, mpprecv                          ! needed by TAM and ICB routines
-   PUBLIC   mpp_lnk_bdy_2d, mpp_lnk_bdy_3d, mpp_lnk_bdy_4d
    
    !! * Interfaces
@@ -451,4 +452,9 @@
 #     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
    !
@@ -459,4 +465,9 @@
 #     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
    !
@@ -467,4 +478,9 @@
 #     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
 
Index: /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/LBC/mpp_bdy_generic.h90
===================================================================
--- /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/LBC/mpp_bdy_generic.h90	(revision 11066)
+++ /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/OCE/LBC/mpp_bdy_generic.h90	(revision 11067)
@@ -1,6 +1,29 @@
+#if defined MULTI
+#   define NAT_IN(k)                cd_nat(k)   
+#   define SGN_IN(k)                psgn(k)
+#   define F_SIZE(ptab)             kfld
+#   define OPT_K(k)                 ,ipf
+#   if defined DIM_2d
+#      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_2D)                , INTENT(inout) ::   ptab(f)
+#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt2d(i,j)
+#      define K_SIZE(ptab)             1
+#      define L_SIZE(ptab)             1
+#   endif
+#   if defined DIM_3d
+#      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_3D)                , INTENT(inout) ::   ptab(f)
+#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt3d(i,j,k)
+#      define K_SIZE(ptab)             SIZE(ptab(1)%pt3d,3)
+#      define L_SIZE(ptab)             1
+#   endif
+#   if defined DIM_4d
+#      define ARRAY_TYPE(i,j,k,l,f)    TYPE(PTR_4D)                , INTENT(inout) ::   ptab(f)
+#      define ARRAY_IN(i,j,k,l,f)      ptab(f)%pt4d(i,j,k,l)
+#      define K_SIZE(ptab)             SIZE(ptab(1)%pt4d,3)
+#      define L_SIZE(ptab)             SIZE(ptab(1)%pt4d,4)
+#   endif
+#else
 #   define ARRAY_TYPE(i,j,k,l,f)    REAL(wp)                    , INTENT(inout) ::   ARRAY_IN(i,j,k,l,f)
 #   define NAT_IN(k)                cd_nat
 #   define SGN_IN(k)                psgn
-#   define IBD_IN(k)                kb_bdy
 #   define F_SIZE(ptab)             1
 #   define OPT_K(k)                 
@@ -20,8 +43,7 @@
 #      define L_SIZE(ptab)          SIZE(ptab,4)
 #   endif
-
-   SUBROUTINE ROUTINE_BDY( cdname, ptab, cd_nat, psgn      , kb_bdy )
+#endif
       !!----------------------------------------------------------------------
-      !!                  ***  routine mpp_lnk_bdy_3d  ***
+      !!                  ***  routine mpp_lnk_bdy  ***
       !!
       !! ** Purpose :   Message passing management
@@ -32,6 +54,4 @@
       !!                    nlci   : first dimension of the local subdomain
       !!                    nlcj   : second dimension of the local subdomain
-      !!                    nbondi_bdy : mark for "east-west local boundary"
-      !!                    nbondj_bdy : mark for "north-south local boundary"
       !!                    noea   : number for local neighboring processors 
       !!                    nowe   : number for local neighboring processors
@@ -42,9 +62,15 @@
       !!
       !!----------------------------------------------------------------------
-      CHARACTER(len=*)            , INTENT(in   ) ::   cdname      ! name of the calling subroutine
+#if defined MULTI
+   SUBROUTINE ROUTINE_BDY( cdname, lsend, lrecv, ptab, cd_nat, psgn, kfld )
+      INTEGER                     , INTENT(in   ) ::   kfld        ! number of pt3d arrays
+#else
+   SUBROUTINE ROUTINE_BDY( cdname, lsend, lrecv, ptab, cd_nat, psgn       )
+#endif
+      CHARACTER(len=*)            , INTENT(in   ) ::   cdname        ! name of the calling subroutine
       ARRAY_TYPE(:,:,:,:,:)   ! array or pointer of arrays on which the boundary condition is applied
-      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                     , INTENT(in   ) ::   IBD_IN(:)   ! BDY boundary set
+      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
+      LOGICAL, DIMENSION(4)       , INTENT(in   ) ::   lsend, lrecv  ! communication with other 4 proc
       !
       INTEGER  ::   ji, jj, jk, jl, jh, jf     ! dummy loop indices
@@ -52,9 +78,12 @@
       INTEGER  ::   imigr, iihom, ijhom        ! local integers
       INTEGER  ::   ml_req1, ml_req2, ml_err   ! for key_mpi_isend
-      REAL(wp) ::   zland                      ! local scalar
       INTEGER, DIMENSION(MPI_STATUS_SIZE) ::   ml_stat   ! for key_mpi_isend
-      !
-      REAL(wp), DIMENSION(:,:,:,:,:,:), ALLOCATABLE ::   zt3ns, zt3sn   ! 3d for north-south & south-north
-      REAL(wp), DIMENSION(:,:,:,:,:,:), ALLOCATABLE ::   zt3ew, zt3we   ! 3d for east-west & west-east
+      LOGICAL  ::   llsend_we, llsend_ea, llsend_no, llsend_so       ! communication send
+      LOGICAL  ::   llrecv_we, llrecv_ea, llrecv_no, llrecv_so       ! communication receive 
+      !
+      REAL(wp), DIMENSION(:,:,:,:,:), ALLOCATABLE ::   zsend_no, zsend_so   ! 3d for north-south & south-north send
+      REAL(wp), DIMENSION(:,:,:,:,:), ALLOCATABLE ::   zsend_ea, zsend_we   ! 3d for east-west   & west-east   send
+      REAL(wp), DIMENSION(:,:,:,:,:), ALLOCATABLE ::   zrecv_no, zrecv_so   ! 3d for north-south & south-north receive
+      REAL(wp), DIMENSION(:,:,:,:,:), ALLOCATABLE ::   zrecv_ea, zrecv_we   ! 3d for east-west   & west-east   receive
       !!----------------------------------------------------------------------
       !
@@ -62,53 +91,30 @@
       ipl = L_SIZE(ptab)   ! 4th    -
       ipf = F_SIZE(ptab)   ! 5th    -      use in "multi" case (array of pointers)
+      llsend_we = lsend(1);  llsend_ea = lsend(2);  llsend_so = lsend(3);  llsend_no = lsend(4);
+      llrecv_we = lrecv(1);  llrecv_ea = lrecv(2);  llrecv_so = lrecv(3);  llrecv_no = lrecv(4);
       !
       IF( narea == 1 .AND. numcom == -1 ) CALL mpp_report( cdname, ipk, ipl, ipf, ld_lbc = .TRUE. )
-      !      
-      ALLOCATE( zt3ns(jpi,nn_hls,ipk,ipl,ipf,2), zt3sn(jpi,nn_hls,ipk,ipl,ipf,2),   &
-         &      zt3ew(jpj,nn_hls,ipk,ipl,ipf,2), zt3we(jpj,nn_hls,ipk,ipl,ipf,2)  )
-
-      zland = 0._wp
+
 
       ! 1. standard boundary treatment
       ! ------------------------------
-      !
+      ! Bdy treatment does not update land points
       DO jf = 1, ipf                   ! number of arrays to be treated
-         !
-         !                                ! East-West boundaries
-         !                    
-         IF( nbondi == 2) THEN                  ! neither subdomain to the east nor to the west
-            !                                      !* Cyclic
+         IF( nbondi == 2 ) THEN                  ! neither subdomain to the east nor to the west
+            !                                      !* Cyclic East-West boundaries
             IF( l_Iperio ) THEN
                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
-         ELSEIF(nbondi == -1) THEN              ! subdomain to the east only
-            IF( .NOT. NAT_IN(jf) == 'F' )   ARRAY_IN(1:nn_hls,:,:,:,jf) = zland     ! south except F-point
-            !
-         ELSEIF(nbondi ==  1) THEN              ! subdomain to the west only
-            ARRAY_IN(nlci-nn_hls+1:jpi,:,:,:,jf) = zland    ! north
-         ENDIF
-         !                                ! North-South boundaries
-         !
+            END IF
+         END IF
          IF( nbondj == 2) THEN                  ! neither subdomain to the north nor to the south
-            !                                      !* Cyclic
+            !                                      !* Cyclic North-South boundaries
             IF( l_Jperio ) THEN
                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  ! east except F-point
-                                               ARRAY_IN(:,nlcj-nn_hls+1:jpj   ,:,:,jf) = zland  ! west
-            ENDIF
-         ELSEIF(nbondj == -1) THEN              ! subdomain to the east only
-            IF( .NOT. NAT_IN(jf) == 'F' )   ARRAY_IN(:,1:nn_hls,:,:,jf) = zland     ! south except F-point
-            !
-         ELSEIF(nbondj ==  1) THEN              ! subdomain to the west only
-            ARRAY_IN(:,nlcj-nn_hls+1:jpj,:,:,jf) = zland    ! north
-         ENDIF
-         !
+            END IF
+         END IF
       END DO
+
 
       ! 2. East and west directions exchange
@@ -116,90 +122,83 @@
       ! we play with the neigbours AND the row number because of the periodicity 
       !
-      !
-      DO jf = 1, ipf
-         SELECT CASE ( nbondi_bdy(IBD_IN(jf)) )      ! Read Dirichlet lateral conditions
-         CASE ( -1, 0, 1 )                ! all exept 2 (i.e. close case)
-            iihom = nlci-nreci
-               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 SELECT
-         !
-         !                           ! Migrations
-!!gm      imigr = nn_hls * jpj * ipk * ipl * ipf
-         imigr = nn_hls * jpj * ipk * ipl
-         !
-         IF( ln_timing ) CALL tic_tac(.TRUE.)
-         !
-         SELECT CASE ( nbondi_bdy(IBD_IN(jf)) )
-         CASE ( -1 )
-            CALL mppsend( 2, zt3we(1,1,1,1,1,1), imigr, noea, ml_req1 )
-         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 )
-         CASE ( 1 )
-            CALL mppsend( 1, zt3ew(1,1,1,1,1,1), imigr, nowe, ml_req1 )
-         END SELECT
-         !
-         SELECT CASE ( nbondi_bdy_b(IBD_IN(jf)) )
-         CASE ( -1 )
-            CALL mpprecv( 1, zt3ew(1,1,1,1,1,2), imigr, noea )
-         CASE ( 0 )
-            CALL mpprecv( 1, zt3ew(1,1,1,1,1,2), imigr, noea )
-            CALL mpprecv( 2, zt3we(1,1,1,1,1,2), imigr, nowe )
-         CASE ( 1 )
-            CALL mpprecv( 2, zt3we(1,1,1,1,1,2), imigr, nowe )
-         END SELECT
-         !
-         SELECT CASE ( nbondi_bdy(IBD_IN(jf)) )
-         CASE ( -1 )
-            IF(l_isend) CALL mpi_wait(ml_req1, ml_stat, ml_err)
-         CASE ( 0 )
-            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 )
-            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
+      IF( llsend_we )   ALLOCATE( zsend_we(jpj,nn_hls,ipk,ipl,ipf) )
+      IF( llsend_ea )   ALLOCATE( zsend_ea(jpj,nn_hls,ipk,ipl,ipf) )
+      IF( llrecv_we )   ALLOCATE( zrecv_we(jpj,nn_hls,ipk,ipl,ipf) )
+      IF( llrecv_ea )   ALLOCATE( zrecv_ea(jpj,nn_hls,ipk,ipl,ipf) )
+      !
+      ! Load arrays to the east and to the west to be sent
+      IF( llsend_we )   THEN   ! Read Dirichlet lateral conditions
+         DO jf = 1, ipf
+            DO jl = 1, ipl
+               DO jk = 1, ipk
+                  DO jh = 1, nn_hls
+                     zsend_we(:,jh,jk,jl,jf) = ARRAY_IN(nn_hls+jh,:,jk,jl,jf)
+                  END DO
+               END DO
+            END DO
+         END DO
+      END IF
+      !
+      IF( llsend_ea )   THEN   ! Read Dirichlet lateral conditions
+         iihom = nlci-nreci
+         DO jf = 1, ipf
+            DO jl = 1, ipl
+               DO jk = 1, ipk
+                  DO jh = 1, nn_hls
+                     zsend_ea(:,jh,jk,jl,jf) = ARRAY_IN(iihom +jh,:,jk,jl,jf)
+                  END DO
+               END DO
+            END DO
+         END DO
+      END IF
+      !
+      ! Send/receive arrays to the east and to the west                            
+      imigr = nn_hls * jpj * ipk * ipl * ipf   ! Migrations
+      !
+      IF( ln_timing ) CALL tic_tac(.TRUE.)
+      !
+      IF( llsend_ea )   CALL mppsend( 2, zsend_ea(1,1,1,1,1), imigr, noea, ml_req1 )
+      IF( llsend_we )   CALL mppsend( 1, zsend_we(1,1,1,1,1), imigr, nowe, ml_req2 )
+      !
+      IF( llrecv_ea )   CALL mpprecv( 1, zrecv_ea(1,1,1,1,1), imigr, noea )
+      IF( llrecv_we )   CALL mpprecv( 2, zrecv_we(1,1,1,1,1), imigr, nowe )
+      !
+      IF( l_isend .AND. llsend_ea ) CALL mpi_wait(ml_req1, ml_stat, ml_err)
+      IF( l_isend .AND. llsend_we ) CALL mpi_wait(ml_req2, ml_stat, ml_err)
+      !
+      IF( ln_timing ) CALL tic_tac(.FALSE.)
+      !
+      !                           ! Write Dirichlet lateral conditions
+      ! Update with the received arrays 
+      IF( llrecv_we )   THEN
+         DO jf = 1, ipf
+            DO jl = 1, ipl
+               DO jk = 1, ipk
+                  DO jh = 1, nn_hls
+                     ARRAY_IN(      jh,:,jk,jl,jf) = zrecv_we(:,jh,jk,jl,jf)
+                  END DO
+               END DO
+            END DO
+         END DO
+      END IF
+      !
+      IF( llrecv_ea )   THEN
          iihom = nlci-nn_hls
-         !
-         !
-         SELECT CASE ( nbondi_bdy_b(IBD_IN(jf)) )
-         CASE ( -1 )
-            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,2)
-                  END DO
-               END DO
-            END DO
-         CASE ( 0 )
-            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
-         CASE ( 1 )
-            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)
-                  END DO
-               END DO
-            END DO
-         END SELECT
-         !
-      END DO
+         DO jf = 1, ipf
+            DO jl = 1, ipl
+               DO jk = 1, ipk
+                  DO jh = 1, nn_hls
+                     ARRAY_IN(iihom+jh,:,jk,jl,jf) = zrecv_ea(:,jh,jk,jl,jf)
+                  END DO
+               END DO
+            END DO
+         END DO
+      END IF
+      !
+      ! Clean up
+      IF( llsend_we )   DEALLOCATE( zsend_we )
+      IF( llsend_ea )   DEALLOCATE( zsend_ea )
+      IF( llrecv_we )   DEALLOCATE( zrecv_we )
+      IF( llrecv_ea )   DEALLOCATE( zrecv_ea )
 
       ! 3. north fold treatment
@@ -220,88 +219,82 @@
       ! always closed : we play only with the neigbours
       !
-      DO jf = 1, ipf
-         IF( nbondj_bdy(IBD_IN(jf)) /= 2 ) THEN      ! Read Dirichlet lateral conditions
-            ijhom = nlcj-nrecj
-            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
-         ENDIF
-         !
-         !                           ! Migrations
-!!gm      imigr = nn_hls * jpi * ipk * ipl * ipf
-         imigr = nn_hls * jpi * ipk * ipl
-         !
-         IF( ln_timing ) CALL tic_tac(.TRUE.)
-         ! 
-         SELECT CASE ( nbondj_bdy(IBD_IN(jf)) )
-         CASE ( -1 )
-            CALL mppsend( 4, zt3sn(1,1,1,1,1,1), imigr, nono, ml_req1 )
-         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 )
-         CASE ( 1 )
-            CALL mppsend( 3, zt3ns(1,1,1,1,1,1), imigr, noso, ml_req1 )
-         END SELECT
-         ! 
-         SELECT CASE ( nbondj_bdy_b(IBD_IN(jf)) )
-         CASE ( -1 )
-            CALL mpprecv( 3, zt3ns(1,1,1,1,1,2), imigr, nono )
-         CASE ( 0 )
-            CALL mpprecv( 3, zt3ns(1,1,1,1,1,2), imigr, nono )
-            CALL mpprecv( 4, zt3sn(1,1,1,1,1,2), imigr, noso )
-         CASE ( 1 )
-            CALL mpprecv( 4, zt3sn(1,1,1,1,1,2), imigr, noso )
-         END SELECT
-         ! 
-         SELECT CASE ( nbondj_bdy(IBD_IN(jf)) )
-         CASE ( -1 )
-            IF(l_isend) CALL mpi_wait(ml_req1, ml_stat, ml_err)
-         CASE ( 0 )
-            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 )
-            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
+      IF( llsend_so )   ALLOCATE( zsend_so(jpi,nn_hls,ipk,ipl,ipf) )
+      IF( llsend_no )   ALLOCATE( zsend_no(jpi,nn_hls,ipk,ipl,ipf) )
+      IF( llrecv_so )   ALLOCATE( zrecv_so(jpi,nn_hls,ipk,ipl,ipf) )
+      IF( llrecv_no )   ALLOCATE( zrecv_no(jpi,nn_hls,ipk,ipl,ipf) )
+      !
+      ! Load arrays to the south and to the north to be sent
+      IF( llsend_so )   THEN   ! Read Dirichlet lateral conditions
+         DO jf = 1, ipf
+            DO jl = 1, ipl
+               DO jk = 1, ipk
+                  DO jh = 1, nn_hls
+                     zsend_so(:,jh,jk,jl,jf) = ARRAY_IN(:,nn_hls+jh,jk,jl,jf)
+                  END DO
+               END DO
+            END DO
+         END DO
+      END IF
+      !
+      IF( llsend_no )   THEN   ! Read Dirichlet lateral conditions
+         ijhom = nlcj-nrecj
+         DO jf = 1, ipf
+            DO jl = 1, ipl
+               DO jk = 1, ipk
+                  DO jh = 1, nn_hls
+                     zsend_no(:,jh,jk,jl,jf) = ARRAY_IN(:,ijhom +jh,jk,jl,jf)
+                  END DO
+               END DO
+            END DO
+         END DO
+      END IF
+      !
+      ! Send/receive arrays to the south and to the north
+      imigr = nn_hls * jpi * ipk * ipl * ipf   ! Migrations
+      !
+      IF( ln_timing ) CALL tic_tac(.TRUE.)
+      ! 
+      IF( llsend_no )   CALL mppsend( 4, zsend_no(1,1,1,1,1), imigr, nono, ml_req1 )
+      IF( llsend_so )   CALL mppsend( 3, zsend_so(1,1,1,1,1), imigr, noso, ml_req2 )
+      !
+      IF( llrecv_no )   CALL mpprecv( 3, zrecv_no(1,1,1,1,1), imigr, nono )
+      IF( llrecv_so )   CALL mpprecv( 4, zrecv_so(1,1,1,1,1), imigr, noso )
+      !
+      IF( l_isend .AND. llsend_no ) CALL mpi_wait(ml_req1, ml_stat, ml_err)
+      IF( l_isend .AND. llsend_so ) CALL mpi_wait(ml_req2, ml_stat, ml_err)
+      !
+      IF( ln_timing ) CALL tic_tac(.FALSE.)
+      !
+      !                           ! Write Dirichlet lateral conditions
+      ! Update with the received arrays 
+      IF( llrecv_so )   THEN
+         DO jf = 1, ipf
+            DO jl = 1, ipl
+               DO jk = 1, ipk
+                  DO jh = 1, nn_hls
+                     ARRAY_IN(:,      jh,jk,jl,jf) = zrecv_so(:,jh,jk,jl,jf)
+                  END DO
+               END DO
+            END DO
+         END DO
+      END IF
+      IF( llrecv_no )   THEN
          ijhom = nlcj-nn_hls
-         !
-         SELECT CASE ( nbondj_bdy_b(IBD_IN(jf)) )
-         CASE ( -1 )
-            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,2)
-                  END DO
-               END DO
-            END DO
-         CASE ( 0 )
-            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
-         CASE ( 1 )
-            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)
-                  END DO
-               END DO
-            END DO
-         END SELECT
-      END DO
-      !
-      DEALLOCATE( zt3ns, zt3sn, zt3ew, zt3we  )
+         DO jf = 1, ipf
+            DO jl = 1, ipl
+               DO jk = 1, ipk
+                  DO jh = 1, nn_hls
+                     ARRAY_IN(:,ijhom+jh,jk,jl,jf) = zrecv_no(:,jh,jk,jl,jf)
+                  END DO
+               END DO
+            END DO
+         END DO
+      END IF
+      !
+      ! Clean up
+      IF( llsend_so )   DEALLOCATE( zsend_so )
+      IF( llsend_no )   DEALLOCATE( zsend_no )
+      IF( llrecv_so )   DEALLOCATE( zrecv_so )
+      IF( llrecv_no )   DEALLOCATE( zrecv_no )
       !
    END SUBROUTINE ROUTINE_BDY
@@ -310,5 +303,4 @@
 #undef NAT_IN
 #undef SGN_IN
-#undef IBD_IN
 #undef ARRAY_IN
 #undef K_SIZE
@@ -316,2 +308,3 @@
 #undef F_SIZE
 #undef OPT_K
+
Index: /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/TOP/trcbdy.F90
===================================================================
--- /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/TOP/trcbdy.F90	(revision 11066)
+++ /NEMO/branches/2019/dev_r10984_HPC-13_IRRMANN_BDY_optimization/src/TOP/trcbdy.F90	(revision 11067)
@@ -49,4 +49,5 @@
       REAL(wp), POINTER, DIMENSION(:,:) ::  ztrc
       REAL(wp), POINTER                 ::  zfac
+      LOGICAL, DIMENSION(4)             :: lsend1, lrecv1     ! indicate how communications are to be carried out
       !!----------------------------------------------------------------------
       !
@@ -70,12 +71,29 @@
             CASE DEFAULT           ;   CALL ctl_stop( 'trc_bdy : unrecognised option for open boundaries for passive tracers' )
             END SELECT
-            ! Boundary points should be updated
-            CALL lbc_bdy_lnk( 'trcbdy', tra(:,:,:,jn), 'T', 1., ib_bdy )
             !
          END DO
       END DO
       !
+      lsend1(:) = .false.
+      lrecv1(:) = .false.
+      DO ib_bdy=1, nb_bdy
+         SELECT CASE( TRIM(cn_tra(ib_bdy)) )
+         CASE('neumann')
+            lsend1(:) = lsend1(:) .OR. lsend_bdy(ib_bdy,1,:)   ! to   every bdy neighbour, T points
+            lrecv1(:) = lrecv1(:) .OR. lrecv_bdy(ib_bdy,1,:)   ! from every bdy neighbour, T points
+         CASE('orlanski')
+            lsend1(:) = lsend1(:) .OR. lsend_bdy(ib_bdy,1,:)   ! to   every bdy neighbour, T points
+            lrecv1(:) = lrecv1(:) .OR. lrecv_bdy(ib_bdy,1,:)   ! from every bdy neighbour, T points
+         CASE('orlanski_npo')
+            lsend1(:) = lsend1(:) .OR. lsend_bdy(ib_bdy,1,:)   ! to   every bdy neighbour, T points
+            lrecv1(:) = lrecv1(:) .OR. lrecv_bdy(ib_bdy,1,:)   ! from every bdy neighbour, T points
+         END SELECT
+      END DO
+      IF( ANY(lsend1) .OR. ANY(lrecv1) ) THEN   ! if need to send/recv in at least one direction
+         CALL lbc_bdy_lnk( 'bdytra', lsend1, lrecv1, tsa, 'T',  1. )
+      END IF
+      !
       IF( ln_timing )   CALL timing_stop('trc_bdy')
-
+      !
    END SUBROUTINE trc_bdy
 
