Index: branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/BDY/bdydyn2d.F90
===================================================================
--- branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/BDY/bdydyn2d.F90	(revision 3664)
+++ branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/BDY/bdydyn2d.F90	(revision 3666)
@@ -5,4 +5,5 @@
    !!======================================================================
    !! History :  3.4  !  2011     (D. Storkey) new module as part of BDY rewrite
+   !!            3.5  !  2012     (S. Mocavero, I. Epicoco) Optimization of BDY communications
    !!----------------------------------------------------------------------
 #if defined key_bdy 
@@ -51,7 +52,7 @@
             CYCLE
          CASE(jp_frs)
-            CALL bdy_dyn2d_frs( idx_bdy(ib_bdy), dta_bdy(ib_bdy) )
+            CALL bdy_dyn2d_frs( idx_bdy(ib_bdy), dta_bdy(ib_bdy), ib_bdy )
          CASE(jp_flather)
-            CALL bdy_dyn2d_fla( idx_bdy(ib_bdy), dta_bdy(ib_bdy) )
+            CALL bdy_dyn2d_fla( idx_bdy(ib_bdy), dta_bdy(ib_bdy), ib_bdy )
          CASE DEFAULT
             CALL ctl_stop( 'bdy_dyn2d : unrecognised option for open boundaries for barotropic variables' )
@@ -61,5 +62,5 @@
    END SUBROUTINE bdy_dyn2d
 
-   SUBROUTINE bdy_dyn2d_frs( idx, dta )
+   SUBROUTINE bdy_dyn2d_frs( idx, dta, ib_bdy )
       !!----------------------------------------------------------------------
       !!                  ***  SUBROUTINE bdy_dyn2d_frs  ***
@@ -74,4 +75,5 @@
       TYPE(OBC_INDEX), INTENT(in) ::   idx  ! OBC indices
       TYPE(OBC_DATA),  INTENT(in) ::   dta  ! OBC external data
+      INTEGER,         INTENT(in) ::   ib_bdy  ! BDY set index
       !!
       INTEGER  ::   jb, jk         ! dummy loop indices
@@ -97,6 +99,6 @@
          pv2d(ii,ij) = ( pv2d(ii,ij) + zwgt * ( dta%v2d(jb) - pv2d(ii,ij) ) ) * vmask(ii,ij,1)
       END DO 
-      CALL lbc_lnk( pu2d, 'U', -1. ) 
-      CALL lbc_lnk( pv2d, 'V', -1. )   ! Boundary points should be updated
+      CALL lbc_bdy_lnk( pu2d, 'U', -1., ib_bdy ) 
+      CALL lbc_bdy_lnk( pv2d, 'V', -1., ib_bdy)   ! Boundary points should be updated
       !
       IF( nn_timing == 1 ) CALL timing_stop('bdy_dyn2d_frs')
@@ -106,5 +108,5 @@
 
 
-   SUBROUTINE bdy_dyn2d_fla( idx, dta )
+   SUBROUTINE bdy_dyn2d_fla( idx, dta, ib_bdy )
       !!----------------------------------------------------------------------
       !!                 ***  SUBROUTINE bdy_dyn2d_fla  ***
@@ -127,4 +129,5 @@
       TYPE(OBC_INDEX),              INTENT(in) ::   idx  ! OBC indices
       TYPE(OBC_DATA),               INTENT(in) ::   dta  ! OBC external data
+      INTEGER,                      INTENT(in) ::   ib_bdy  ! BDY set index
 
       INTEGER  ::   jb, igrd                         ! dummy loop indices
@@ -177,6 +180,6 @@
          pv2d(ii,ij) = zforc + zcorr * vmask(ii,ij,1)
       END DO
-      CALL lbc_lnk( pu2d, 'U', -1. )   ! Boundary points should be updated
-      CALL lbc_lnk( pv2d, 'V', -1. )   !
+      CALL lbc_bdy_lnk( pu2d, 'U', -1., ib_bdy )   ! Boundary points should be updated
+      CALL lbc_bdy_lnk( pv2d, 'V', -1., ib_bdy )   !
       !
       IF( nn_timing == 1 ) CALL timing_stop('bdy_dyn2d_fla')
Index: branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/BDY/bdydyn3d.F90
===================================================================
--- branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/BDY/bdydyn3d.F90	(revision 3664)
+++ branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/BDY/bdydyn3d.F90	(revision 3666)
@@ -5,4 +5,5 @@
    !!======================================================================
    !! History :  3.4  !  2011     (D. Storkey) new module as part of BDY rewrite 
+   !!            3.5  !  2012     (S. Mocavero, I. Epicoco) Optimization of BDY communications
    !!----------------------------------------------------------------------
 #if defined key_bdy 
@@ -54,5 +55,5 @@
             CYCLE
          CASE(jp_frs)
-            CALL bdy_dyn3d_frs( idx_bdy(ib_bdy), dta_bdy(ib_bdy), kt )
+            CALL bdy_dyn3d_frs( idx_bdy(ib_bdy), dta_bdy(ib_bdy), kt, ib_bdy )
          CASE DEFAULT
             CALL ctl_stop( 'bdy_dyn3d : unrecognised option for open boundaries for baroclinic velocities' )
@@ -62,5 +63,5 @@
    END SUBROUTINE bdy_dyn3d
 
-   SUBROUTINE bdy_dyn3d_frs( idx, dta, kt )
+   SUBROUTINE bdy_dyn3d_frs( idx, dta, kt, ib_bdy )
       !!----------------------------------------------------------------------
       !!                  ***  SUBROUTINE bdy_dyn3d_frs  ***
@@ -76,4 +77,5 @@
       TYPE(OBC_INDEX), INTENT(in) ::   idx  ! OBC indices
       TYPE(OBC_DATA),  INTENT(in) ::   dta  ! OBC external data
+      INTEGER,         INTENT(in) ::   ib_bdy  ! BDY set index
       !!
       INTEGER  ::   jb, jk         ! dummy loop indices
@@ -103,5 +105,5 @@
          END DO
       END DO 
-      CALL lbc_lnk( ua, 'U', -1. )   ;   CALL lbc_lnk( va, 'V', -1. )   ! Boundary points should be updated
+      CALL lbc_bdy_lnk( ua, 'U', -1., ib_bdy )   ;   CALL lbc_bdy_lnk( va, 'V', -1.,ib_bdy )   ! Boundary points should be updated
       !
       IF( kt .eq. nit000 ) CLOSE( unit = 102 )
Index: branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/BDY/bdyice_lim2.F90
===================================================================
--- branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/BDY/bdyice_lim2.F90	(revision 3664)
+++ branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/BDY/bdyice_lim2.F90	(revision 3666)
@@ -6,4 +6,5 @@
    !!  History :  3.3  !  2010-09 (D. Storkey)  Original code
    !!             3.4  !  2011    (D. Storkey) rewrite in preparation for OBC-BDY merge
+   !!             3.5  !  2012    (S. Mocavero, I. Epicoco) Optimization of BDY communications
    !!----------------------------------------------------------------------
 #if defined   key_bdy   &&   defined key_lim2
@@ -53,5 +54,5 @@
             CYCLE
          CASE(jp_frs)
-            CALL bdy_ice_frs( idx_bdy(ib_bdy), dta_bdy(ib_bdy) )
+            CALL bdy_ice_frs( idx_bdy(ib_bdy), dta_bdy(ib_bdy), ib_bdy )
          CASE DEFAULT
             CALL ctl_stop( 'bdy_ice_lim_2 : unrecognised option for open boundaries for ice fields' )
@@ -61,5 +62,5 @@
    END SUBROUTINE bdy_ice_lim_2
 
-   SUBROUTINE bdy_ice_frs( idx, dta )
+   SUBROUTINE bdy_ice_frs( idx, dta, ib_bdy )
       !!------------------------------------------------------------------------------
       !!                 ***  SUBROUTINE bdy_ice_frs  ***
@@ -73,4 +74,5 @@
       TYPE(OBC_INDEX), INTENT(in) ::   idx  ! OBC indices
       TYPE(OBC_DATA),  INTENT(in) ::   dta  ! OBC external data
+      INTEGER,         INTENT(in) ::   ib_bdy  ! BDY set index
       !!
       INTEGER  ::   jb, jk, jgrd   ! dummy loop indices
@@ -94,6 +96,6 @@
          END DO
       END DO 
-      CALL lbc_lnk( frld, 'T', 1. )                                         ! lateral boundary conditions
-      CALL lbc_lnk( hicif, 'T', 1. )   ;   CALL lbc_lnk( hsnif, 'T', 1. )
+      CALL lbc_bdy_lnk( frld, 'T', 1., ib_bdy )                                         ! lateral boundary conditions
+      CALL lbc_bdy_lnk( hicif, 'T', 1., ib_bdy )   ;   CALL lbc_bdy_lnk( hsnif, 'T', 1., ib_bdy )
       !      
       IF( nn_timing == 1 ) CALL timing_stop('bdy_ice_frs')
Index: branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/BDY/bdyini.F90
===================================================================
--- branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/BDY/bdyini.F90	(revision 3664)
+++ branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/BDY/bdyini.F90	(revision 3666)
@@ -11,4 +11,6 @@
    !!            3.3  !  2010-09  (D.Storkey) add ice boundary conditions
    !!            3.4  !  2011     (D. Storkey) rewrite in preparation for OBC-BDY merge
+   !!            3.5  !  2012     (S. Mocavero, I. Epicoco) Updates for the 
+   !!                             optimization of BDY communications
    !!----------------------------------------------------------------------
 #if defined key_bdy
@@ -76,4 +78,8 @@
       CHARACTER(LEN=80),DIMENSION(jpbgrd)  ::   clfile
       CHARACTER(LEN=1),DIMENSION(jpbgrd)   ::   cgrid
+      INTEGER :: com_east, com_west, com_south, com_north          ! Flags for boundaries sending
+      INTEGER :: com_east_b, com_west_b, com_south_b, com_north_b  ! Flags for boundaries receiving
+      INTEGER :: iw_b(4), ie_b(4), is_b(4), in_b(4)                ! Arrays for neighbours coordinates
+
       !!
       NAMELIST/nambdy/ nb_bdy, ln_coords_file, cn_coords_file,             &
@@ -543,4 +549,58 @@
       in = mjg(1) + nlcj-1 - 1   ! if monotasking and no zoom, in=jpjm1
 
+      ALLOCATE( nbondi_bdy(nb_bdy))
+      ALLOCATE( nbondj_bdy(nb_bdy))
+      nbondi_bdy(:)=2
+      nbondj_bdy(:)=2
+      ALLOCATE( nbondi_bdy_b(nb_bdy))
+      ALLOCATE( nbondj_bdy_b(nb_bdy))
+      nbondi_bdy_b(:)=2
+      nbondj_bdy_b(:)=2
+
+      ! Work out dimensions of boundary data on each neighbour process
+      IF(nbondi .eq. 0) THEN
+         iw_b(1) = jpizoom + nimppt(nowe+1)
+         ie_b(1) = jpizoom + nimppt(nowe+1)+nlcit(nowe+1)-3
+         is_b(1) = jpjzoom + njmppt(nowe+1)
+         in_b(1) = jpjzoom + njmppt(nowe+1)+nlcjt(nowe+1)-3
+
+         iw_b(2) = jpizoom + nimppt(noea+1)
+         ie_b(2) = jpizoom + nimppt(noea+1)+nlcit(noea+1)-3
+         is_b(2) = jpjzoom + njmppt(noea+1)
+         in_b(2) = jpjzoom + njmppt(noea+1)+nlcjt(noea+1)-3
+      ELSEIF(nbondi .eq. 1) THEN
+         iw_b(1) = jpizoom + nimppt(nowe+1)
+         ie_b(1) = jpizoom + nimppt(nowe+1)+nlcit(nowe+1)-3
+         is_b(1) = jpjzoom + njmppt(nowe+1)
+         in_b(1) = jpjzoom + njmppt(nowe+1)+nlcjt(nowe+1)-3
+      ELSEIF(nbondi .eq. -1) THEN
+         iw_b(2) = jpizoom + nimppt(noea+1)
+         ie_b(2) = jpizoom + nimppt(noea+1)+nlcit(noea+1)-3
+         is_b(2) = jpjzoom + njmppt(noea+1)
+         in_b(2) = jpjzoom + njmppt(noea+1)+nlcjt(noea+1)-3
+      ENDIF
+
+      IF(nbondj .eq. 0) THEN
+         iw_b(3) = jpizoom + nimppt(noso+1)
+         ie_b(3) = jpizoom + nimppt(noso+1)+nlcit(noso+1)-3
+         is_b(3) = jpjzoom + njmppt(noso+1)
+         in_b(3) = jpjzoom + njmppt(noso+1)+nlcjt(noso+1)-3
+
+         iw_b(4) = jpizoom + nimppt(nono+1)
+         ie_b(4) = jpizoom + nimppt(nono+1)+nlcit(nono+1)-3
+         is_b(4) = jpjzoom + njmppt(nono+1)
+         in_b(4) = jpjzoom + njmppt(nono+1)+nlcjt(nono+1)-3
+      ELSEIF(nbondj .eq. 1) THEN
+         iw_b(3) = jpizoom + nimppt(noso+1)
+         ie_b(3) = jpizoom + nimppt(noso+1)+nlcit(noso+1)-3
+         is_b(3) = jpjzoom + njmppt(noso+1)
+         in_b(3) = jpjzoom + njmppt(noso+1)+nlcjt(noso+1)-3
+      ELSEIF(nbondj .eq. -1) THEN
+         iw_b(4) = jpizoom + nimppt(nono+1)
+         ie_b(4) = jpizoom + nimppt(nono+1)+nlcit(nono+1)-3
+         is_b(4) = jpjzoom + njmppt(nono+1)
+         in_b(4) = jpjzoom + njmppt(nono+1)+nlcjt(nono+1)-3
+      ENDIF
+
       DO ib_bdy = 1, nb_bdy
          DO igrd = 1, jpbgrd
@@ -585,4 +645,13 @@
          ! -----------------------------------------------------------------
 
+         com_east = 0
+         com_west = 0
+         com_south = 0
+         com_north = 0
+
+         com_east_b = 0
+         com_west_b = 0
+         com_south_b = 0
+         com_north_b = 0
          DO igrd = 1, jpbgrd
             icount  = 0
@@ -598,10 +667,171 @@
                      idx_bdy(ib_bdy)%nbi(icount,igrd)   = nbidta(ib,igrd,ib_bdy)- mig(1)+1
                      idx_bdy(ib_bdy)%nbj(icount,igrd)   = nbjdta(ib,igrd,ib_bdy)- mjg(1)+1
+                     ! check if point has to be sent
+                     ii = idx_bdy(ib_bdy)%nbi(icount,igrd)
+                     ij = idx_bdy(ib_bdy)%nbj(icount,igrd)
+                     if((com_east .ne. 1) .and. (ii .eq. (nlci-1)) .and. (nbondi .le. 0)) then
+                        com_east = 1
+                     elseif((com_west .ne. 1) .and. (ii .eq. 2) .and. (nbondi .ge. 0) .and. (nbondi .ne. 2)) then
+                        com_west = 1
+                     endif 
+                     if((com_south .ne. 1) .and. (ij .eq. 2) .and. (nbondj .ge. 0) .and. (nbondj .ne. 2)) then
+                        com_south = 1
+                     elseif((com_north .ne. 1) .and. (ij .eq. (nlcj-1)) .and. (nbondj .le. 0)) then
+                        com_north = 1
+                     endif 
                      idx_bdy(ib_bdy)%nbr(icount,igrd)   = nbrdta(ib,igrd,ib_bdy)
                      idx_bdy(ib_bdy)%nbmap(icount,igrd) = ib
                   ENDIF
+                  ! check if point has to be received from a neighbour
+                  IF(nbondi .eq. 0) THEN
+                     IF( nbidta(ib,igrd,ib_bdy) >= iw_b(1) .AND. nbidta(ib,igrd,ib_bdy) <= ie_b(1) .AND.   &
+                       & nbjdta(ib,igrd,ib_bdy) >= is_b(1) .AND. nbjdta(ib,igrd,ib_bdy) <= in_b(1) .AND.   &
+                       & nbrdta(ib,igrd,ib_bdy) == ir  ) THEN
+                       ii = nbidta(ib,igrd,ib_bdy)- iw_b(1)+2
+                       if((com_west_b .ne. 1) .and. (ii .eq. (nlcit(nowe+1)-1))) then
+                          ij = nbjdta(ib,igrd,ib_bdy) - is_b(1)+2
+                          if((ij .eq. 2) .and. (nbondj .eq. 0 .or. nbondj .eq. 1)) then
+                            com_south = 1
+                          elseif((ij .eq. nlcjt(nowe+1)-1) .and. (nbondj .eq. 0 .or. nbondj .eq. -1)) then
+                            com_north = 1
+                          endif
+                          com_west_b = 1
+                       endif 
+                     ENDIF
+                     IF( nbidta(ib,igrd,ib_bdy) >= iw_b(2) .AND. nbidta(ib,igrd,ib_bdy) <= ie_b(2) .AND.   &
+                       & nbjdta(ib,igrd,ib_bdy) >= is_b(2) .AND. nbjdta(ib,igrd,ib_bdy) <= in_b(2) .AND.   &
+                       & nbrdta(ib,igrd,ib_bdy) == ir  ) THEN
+                       ii = nbidta(ib,igrd,ib_bdy)- iw_b(2)+2
+                       if((com_east_b .ne. 1) .and. (ii .eq. 2)) then
+                          ij = nbjdta(ib,igrd,ib_bdy) - is_b(2)+2
+                          if((ij .eq. 2) .and. (nbondj .eq. 0 .or. nbondj .eq. 1)) then
+                            com_south = 1
+                          elseif((ij .eq. nlcjt(noea+1)-1) .and. (nbondj .eq. 0 .or. nbondj .eq. -1)) then
+                            com_north = 1
+                          endif
+                          com_east_b = 1
+                       endif 
+                     ENDIF
+                  ELSEIF(nbondi .eq. 1) THEN
+                     IF( nbidta(ib,igrd,ib_bdy) >= iw_b(1) .AND. nbidta(ib,igrd,ib_bdy) <= ie_b(1) .AND.   &
+                       & nbjdta(ib,igrd,ib_bdy) >= is_b(1) .AND. nbjdta(ib,igrd,ib_bdy) <= in_b(1) .AND.   &
+                       & nbrdta(ib,igrd,ib_bdy) == ir  ) THEN
+                       ii = nbidta(ib,igrd,ib_bdy)- iw_b(1)+2
+                       if((com_west_b .ne. 1) .and. (ii .eq. (nlcit(nowe+1)-1))) then
+                          ij = nbjdta(ib,igrd,ib_bdy) - is_b(1)+2
+                          if((ij .eq. 2) .and. (nbondj .eq. 0 .or. nbondj .eq. 1)) then
+                            com_south = 1
+                          elseif((ij .eq. nlcjt(nowe+1)-1) .and. (nbondj .eq. 0 .or. nbondj .eq. -1)) then
+                            com_north = 1
+                          endif
+                          com_west_b = 1
+                       endif 
+                     ENDIF
+                  ELSEIF(nbondi .eq. -1) THEN
+                     IF( nbidta(ib,igrd,ib_bdy) >= iw_b(2) .AND. nbidta(ib,igrd,ib_bdy) <= ie_b(2) .AND.   &
+                       & nbjdta(ib,igrd,ib_bdy) >= is_b(2) .AND. nbjdta(ib,igrd,ib_bdy) <= in_b(2) .AND.   &
+                       & nbrdta(ib,igrd,ib_bdy) == ir  ) THEN
+                       ii = nbidta(ib,igrd,ib_bdy)- iw_b(2)+2
+                       if((com_east_b .ne. 1) .and. (ii .eq. 2)) then
+                          ij = nbjdta(ib,igrd,ib_bdy) - is_b(2)+2
+                          if((ij .eq. 2) .and. (nbondj .eq. 0 .or. nbondj .eq. 1)) then
+                            com_south = 1
+                          elseif((ij .eq. nlcjt(noea+1)-1) .and. (nbondj .eq. 0 .or. nbondj .eq. -1)) then
+                            com_north = 1
+                          endif
+                          com_east_b = 1
+                       endif 
+                     ENDIF
+                  ENDIF
+                  IF(nbondj .eq. 0) THEN
+                     IF(com_north_b .ne. 1 .AND. (nbidta(ib,igrd,ib_bdy) == iw_b(4)-1 .OR. nbidta(ib,igrd,ib_bdy) == ie_b(4)+1) .AND. &
+                       & nbjdta(ib,igrd,ib_bdy) == is_b(4) .AND. nbrdta(ib,igrd,ib_bdy) == ir) THEN
+                       com_north_b = 1 
+                     ENDIF
+                     IF(com_south_b .ne. 1 .AND. (nbidta(ib,igrd,ib_bdy) == iw_b(3)-1 .OR. nbidta(ib,igrd,ib_bdy) == ie_b(3)+1) .AND. &
+                       & nbjdta(ib,igrd,ib_bdy) == in_b(3) .AND. nbrdta(ib,igrd,ib_bdy) == ir) THEN
+                       com_south_b = 1 
+                     ENDIF
+                     IF( nbidta(ib,igrd,ib_bdy) >= iw_b(3) .AND. nbidta(ib,igrd,ib_bdy) <= ie_b(3) .AND.   &
+                       & nbjdta(ib,igrd,ib_bdy) >= is_b(3) .AND. nbjdta(ib,igrd,ib_bdy) <= in_b(3) .AND.   &
+                       & nbrdta(ib,igrd,ib_bdy) == ir  ) THEN
+                       ij = nbjdta(ib,igrd,ib_bdy)- is_b(3)+2
+                       if((com_south_b .ne. 1) .and. (ij .eq. (nlcjt(noso+1)-1))) then
+                          com_south_b = 1
+                       endif 
+                     ENDIF
+                     IF( nbidta(ib,igrd,ib_bdy) >= iw_b(4) .AND. nbidta(ib,igrd,ib_bdy) <= ie_b(4) .AND.   &
+                       & nbjdta(ib,igrd,ib_bdy) >= is_b(4) .AND. nbjdta(ib,igrd,ib_bdy) <= in_b(4) .AND.   &
+                       & nbrdta(ib,igrd,ib_bdy) == ir  ) THEN
+                       ij = nbjdta(ib,igrd,ib_bdy)- is_b(4)+2
+                       if((com_north_b .ne. 1) .and. (ij .eq. 2)) then
+                          com_north_b = 1
+                       endif 
+                     ENDIF
+                  ELSEIF(nbondj .eq. 1) THEN
+                     IF(com_south_b .ne. 1 .AND. (nbidta(ib,igrd,ib_bdy) == iw_b(3)-1 .OR. nbidta(ib,igrd,ib_bdy) == ie_b(3)+1) .AND. &
+                       & nbjdta(ib,igrd,ib_bdy) == in_b(3) .AND. nbrdta(ib,igrd,ib_bdy) == ir) THEN
+                       com_south_b = 1 
+                     ENDIF
+                     IF( nbidta(ib,igrd,ib_bdy) >= iw_b(3) .AND. nbidta(ib,igrd,ib_bdy) <= ie_b(3) .AND.   &
+                       & nbjdta(ib,igrd,ib_bdy) >= is_b(3) .AND. nbjdta(ib,igrd,ib_bdy) <= in_b(3) .AND.   &
+                       & nbrdta(ib,igrd,ib_bdy) == ir  ) THEN
+                       ij = nbjdta(ib,igrd,ib_bdy)- is_b(3)+2
+                       if((com_south_b .ne. 1) .and. (ij .eq. (nlcjt(noso+1)-1))) then
+                          com_south_b = 1
+                       endif 
+                     ENDIF
+                  ELSEIF(nbondj .eq. -1) THEN
+                     IF(com_north_b .ne. 1 .AND. (nbidta(ib,igrd,ib_bdy) == iw_b(4)-1 .OR. nbidta(ib,igrd,ib_bdy) == ie_b(4)+1) .AND. &
+                       & nbjdta(ib,igrd,ib_bdy) == is_b(4) .AND. nbrdta(ib,igrd,ib_bdy) == ir) THEN
+                       com_north_b = 1 
+                     ENDIF
+                     IF( nbidta(ib,igrd,ib_bdy) >= iw_b(4) .AND. nbidta(ib,igrd,ib_bdy) <= ie_b(4) .AND.   &
+                       & nbjdta(ib,igrd,ib_bdy) >= is_b(4) .AND. nbjdta(ib,igrd,ib_bdy) <= in_b(4) .AND.   &
+                       & nbrdta(ib,igrd,ib_bdy) == ir  ) THEN
+                       ij = nbjdta(ib,igrd,ib_bdy)- is_b(4)+2
+                       if((com_north_b .ne. 1) .and. (ij .eq. 2)) then
+                          com_north_b = 1
+                       endif 
+                     ENDIF
+                  ENDIF
                ENDDO
             ENDDO
          ENDDO 
+         ! definition of the i- and j- direction local boundaries arrays
+         ! used for sending the boudaries
+         IF((com_east .eq. 1) .and. (com_west .eq. 1)) THEN
+            nbondi_bdy(ib_bdy) = 0
+         ELSEIF ((com_east .eq. 1) .and. (com_west .eq. 0)) THEN
+            nbondi_bdy(ib_bdy) = -1
+         ELSEIF ((com_east .eq. 0) .and. (com_west .eq. 1)) THEN
+            nbondi_bdy(ib_bdy) = 1
+         ENDIF
+
+         IF((com_north .eq. 1) .and. (com_south .eq. 1)) THEN
+            nbondj_bdy(ib_bdy) = 0
+         ELSEIF ((com_north .eq. 1) .and. (com_south .eq. 0)) THEN
+            nbondj_bdy(ib_bdy) = -1
+         ELSEIF ((com_north .eq. 0) .and. (com_south .eq. 1)) THEN
+            nbondj_bdy(ib_bdy) = 1
+         ENDIF
+
+         ! definition of the i- and j- direction local boundaries arrays
+         ! used for receiving the boudaries
+         IF((com_east_b .eq. 1) .and. (com_west_b .eq. 1)) THEN
+            nbondi_bdy_b(ib_bdy) = 0
+         ELSEIF ((com_east_b .eq. 1) .and. (com_west_b .eq. 0)) THEN
+            nbondi_bdy_b(ib_bdy) = -1
+         ELSEIF ((com_east_b .eq. 0) .and. (com_west_b .eq. 1)) THEN
+            nbondi_bdy_b(ib_bdy) = 1
+         ENDIF
+
+         IF((com_north_b .eq. 1) .and. (com_south_b .eq. 1)) THEN
+            nbondj_bdy_b(ib_bdy) = 0
+         ELSEIF ((com_north_b .eq. 1) .and. (com_south_b .eq. 0)) THEN
+            nbondj_bdy_b(ib_bdy) = -1
+         ELSEIF ((com_north_b .eq. 0) .and. (com_south_b .eq. 1)) THEN
+            nbondj_bdy_b(ib_bdy) = 1
+         ENDIF
 
          ! Compute rim weights for FRS scheme
Index: branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/BDY/bdytra.F90
===================================================================
--- branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/BDY/bdytra.F90	(revision 3664)
+++ branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/BDY/bdytra.F90	(revision 3666)
@@ -7,4 +7,5 @@
    !!            3.0  !  2008-04  (NEMO team)  add in the reference version
    !!            3.4  !  2011     (D. Storkey) rewrite in preparation for OBC-BDY merge
+   !!            3.5  !  2012     (S. Mocavero, I. Epicoco) Optimization of BDY communications
    !!----------------------------------------------------------------------
 #if defined key_bdy
@@ -52,5 +53,5 @@
             CYCLE
          CASE(jp_frs)
-            CALL bdy_tra_frs( idx_bdy(ib_bdy), dta_bdy(ib_bdy), kt )
+            CALL bdy_tra_frs( idx_bdy(ib_bdy), dta_bdy(ib_bdy), kt, ib_bdy )
          CASE DEFAULT
             CALL ctl_stop( 'bdy_tra : unrecognised option for open boundaries for T and S' )
@@ -60,5 +61,5 @@
    END SUBROUTINE bdy_tra
 
-   SUBROUTINE bdy_tra_frs( idx, dta, kt )
+   SUBROUTINE bdy_tra_frs( idx, dta, kt, ib_bdy )
       !!----------------------------------------------------------------------
       !!                 ***  SUBROUTINE bdy_tra_frs  ***
@@ -71,4 +72,5 @@
       TYPE(OBC_INDEX), INTENT(in) ::   idx  ! OBC indices
       TYPE(OBC_DATA),  INTENT(in) ::   dta  ! OBC external data
+      INTEGER,         INTENT(in) ::   ib_bdy  ! BDY set index
       !! 
       REAL(wp) ::   zwgt           ! boundary weight
@@ -89,6 +91,5 @@
          END DO
       END DO 
-      !
-      CALL lbc_lnk( tsa(:,:,:,jp_tem), 'T', 1. )   ; CALL lbc_lnk( tsa(:,:,:,jp_sal), 'T', 1. )    ! Boundary points should be updated
+      CALL lbc_bdy_lnk( tsa(:,:,:,jp_tem), 'T', 1., ib_bdy )   ; CALL lbc_bdy_lnk( tsa(:,:,:,jp_sal), 'T', 1., ib_bdy )    ! Boundary points should be updated
       !
       IF( kt .eq. nit000 ) CLOSE( unit = 102 )
Index: branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/DOM/dom_oce.F90
===================================================================
--- branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/DOM/dom_oce.F90	(revision 3664)
+++ branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/DOM/dom_oce.F90	(revision 3666)
@@ -8,4 +8,6 @@
    !!            3.3  ! 2010-11  (G. Madec) add mbk. arrays associated to the deepest ocean level
    !!            4.0  ! 2011-01  (A. R. Porter, STFC Daresbury) dynamical allocation
+   !!            3.5  ! 2012     (S. Mocavero, I. Epicoco) Add arrays associated
+   !!                             to the optimization of BDY communications
    !!----------------------------------------------------------------------
 
@@ -80,4 +82,9 @@
    INTEGER, PUBLIC ::   narea             !: number for local area
    INTEGER, PUBLIC ::   nbondi, nbondj    !: mark of i- and j-direction local boundaries
+   INTEGER, ALLOCATABLE, PUBLIC ::   nbondi_bdy(:)    !: mark i-direction local boundaries for BDY open boundaries
+   INTEGER, ALLOCATABLE, PUBLIC ::   nbondj_bdy(:)    !: mark j-direction local boundaries for BDY open boundaries
+   INTEGER, ALLOCATABLE, PUBLIC ::   nbondi_bdy_b(:)  !: mark i-direction of neighbours local boundaries for BDY open boundaries  
+   INTEGER, ALLOCATABLE, PUBLIC ::   nbondj_bdy_b(:)  !: mark j-direction of neighbours local boundaries for BDY open boundaries  
+
    INTEGER, PUBLIC ::   npolj             !: north fold mark (0, 3 or 4)
    INTEGER, PUBLIC ::   nlci, nldi, nlei  !: i-dimensions of the local subdomain and its first and last indoor indices
Index: branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/LBC/lbclnk.F90
===================================================================
--- branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/LBC/lbclnk.F90	(revision 3664)
+++ branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/LBC/lbclnk.F90	(revision 3666)
@@ -7,4 +7,7 @@
    !!   NEMO     1.0  ! 2002-09  (G. Madec)     F90: Free form and module
    !!            3.2  ! 2009-03  (R. Benshila)  External north fold treatment  
+   !!            3.5  ! 2012     (S.Mocavero, I. Epicoco) Add 'lbc_bdy_lnk' 
+   !!                            and lbc_obc_lnk' routine to optimize  
+   !!                            the BDY/OBC communications
    !!----------------------------------------------------------------------
 #if   defined key_mpp_mpi
@@ -14,4 +17,6 @@
    !!   lbc_lnk      : generic interface for mpp_lnk_3d and mpp_lnk_2d routines defined in lib_mpp
    !!   lbc_lnk_e    : generic interface for mpp_lnk_2d_e routine defined in lib_mpp
+   !!   lbc_bdy_lnk  : generic interface for mpp_lnk_bdy_2d and mpp_lnk_bdy_3d routines defined in lib_mpp
+   !!   lbc_obc_lnk  : generic interface for mpp_lnk_obc_2d and mpp_lnk_obc_3d routines defined in lib_mpp
    !!----------------------------------------------------------------------
    USE lib_mpp          ! distributed memory computing library
@@ -21,4 +26,11 @@
    END INTERFACE
 
+   INTERFACE lbc_bdy_lnk
+      MODULE PROCEDURE mpp_lnk_bdy_2d, mpp_lnk_bdy_3d
+   END INTERFACE
+   INTERFACE lbc_obc_lnk
+      MODULE PROCEDURE mpp_lnk_obc_2d, mpp_lnk_obc_3d
+   END INTERFACE
+
    INTERFACE lbc_lnk_e
       MODULE PROCEDURE mpp_lnk_2d_e
@@ -27,4 +39,6 @@
    PUBLIC lbc_lnk       ! ocean lateral boundary conditions
    PUBLIC lbc_lnk_e
+   PUBLIC lbc_bdy_lnk   ! ocean lateral BDY boundary conditions
+   PUBLIC lbc_obc_lnk   ! ocean lateral BDY boundary conditions
 
    !!----------------------------------------------------------------------
@@ -41,4 +55,6 @@
    !!   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
+   !!   lbc_obc_lnk  : set the lateral OBC boundary condition
    !!----------------------------------------------------------------------
    USE oce             ! ocean dynamics and tracers   
@@ -58,6 +74,15 @@
    END INTERFACE
 
+   INTERFACE lbc_bdy_lnk
+      MODULE PROCEDURE lbc_bdy_lnk_2d, lbc_bdy_lnk_3d
+   END INTERFACE
+   INTERFACE lbc_obc_lnk
+      MODULE PROCEDURE lbc_lnk_2d, lbc_lnk_3d
+   END INTERFACE
+
    PUBLIC   lbc_lnk       ! ocean/ice  lateral boundary conditions
    PUBLIC   lbc_lnk_e 
+   PUBLIC   lbc_bdy_lnk   ! ocean lateral BDY boundary conditions
+   PUBLIC   lbc_obc_lnk   ! ocean lateral OBC boundary conditions
    
    !!----------------------------------------------------------------------
@@ -180,4 +205,37 @@
    END SUBROUTINE lbc_lnk_3d
 
+   SUBROUTINE lbc_bdy_lnk_3d( pt3d, cd_type, psgn, ib_bdy )
+      !!---------------------------------------------------------------------
+      !!                  ***  ROUTINE lbc_bdy_lnk  ***
+      !!
+      !! ** Purpose :   wrapper rountine to 'lbc_lnk_3d'. This wrapper is used
+      !!                to maintain the same interface with regards to the mpp case
+      !!
+      !!----------------------------------------------------------------------
+      CHARACTER(len=1)                , INTENT(in   )           ::   cd_type   ! nature of pt3d grid-points
+      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout)           ::   pt3d      ! 3D array on which the lbc is applied
+      REAL(wp)                        , INTENT(in   )           ::   psgn      ! control of the sign 
+      INTEGER                                                   ::   ib_bdy    ! BDY boundary set
+      !!
+      CALL lbc_lnk_3d( pt3d, cd_type, psgn)
+
+   END SUBROUTINE lbc_bdy_lnk_3d
+
+   SUBROUTINE lbc_bdy_lnk_2d( pt2d, cd_type, psgn, ib_bdy )
+      !!---------------------------------------------------------------------
+      !!                  ***  ROUTINE lbc_bdy_lnk  ***
+      !!
+      !! ** Purpose :   wrapper rountine to 'lbc_lnk_3d'. This wrapper is used
+      !!                to maintain the same interface with regards to the mpp case
+      !!
+      !!----------------------------------------------------------------------
+      CHARACTER(len=1)                , INTENT(in   )           ::   cd_type   ! nature of pt3d grid-points
+      REAL(wp), DIMENSION(jpi,jpj),     INTENT(inout)           ::   pt2d      ! 3D array on which the lbc is applied
+      REAL(wp)                        , INTENT(in   )           ::   psgn      ! control of the sign 
+      INTEGER                                                   ::   ib_bdy    ! BDY boundary set
+      !!
+      CALL lbc_lnk_2d( pt2d, cd_type, psgn)
+
+   END SUBROUTINE lbc_bdy_lnk_2d
 
    SUBROUTINE lbc_lnk_2d( pt2d, cd_type, psgn, cd_mpp, pval )
Index: branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/LBC/lib_mpp.F90
===================================================================
--- branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/LBC/lib_mpp.F90	(revision 3664)
+++ branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/LBC/lib_mpp.F90	(revision 3666)
@@ -19,4 +19,7 @@
    !!            3.2  !  2009  (O. Marti)    add mpp_ini_znl 
    !!            4.0  !  2011  (G. Madec)  move ctl_ routines from in_out_manager
+   !!            3.5  !  2012  (S.Mocavero, I. Epicoco) Add 'mpp_lnk_bdy_3d', 'mpp_lnk_obc_3d', 
+   !!                          'mpp_lnk_bdy_2d' and 'mpp_lnk_obc_2d' routines and update
+   !!                          the mppobc routine to optimize the BDY and OBC communications
    !!----------------------------------------------------------------------
 
@@ -68,4 +71,6 @@
    PUBLIC   mppsize
    PUBLIC   lib_mpp_alloc   ! Called in nemogcm.F90
+   PUBLIC   mpp_lnk_bdy_2d, mpp_lnk_bdy_3d
+   PUBLIC   mpp_lnk_obc_2d, mpp_lnk_obc_3d
 
    !! * Interfaces
@@ -354,12 +359,11 @@
    END FUNCTION mynode
 
-
-   SUBROUTINE mpp_lnk_3d( ptab, cd_type, psgn, cd_mpp, pval )
-      !!----------------------------------------------------------------------
-      !!                  ***  routine mpp_lnk_3d  ***
+   SUBROUTINE mpp_lnk_obc_3d( ptab, cd_type, psgn )
+      !!----------------------------------------------------------------------
+      !!                  ***  routine mpp_lnk_obc_3d  ***
       !!
       !! ** Purpose :   Message passing manadgement
       !!
-      !! ** Method  :   Use mppsend and mpprecv function for passing mask 
+      !! ** Method  :   Use mppsend and mpprecv function for passing OBC boundaries 
       !!      between processors following neighboring subdomains.
       !!            domain parameters
@@ -381,6 +385,4 @@
       REAL(wp)                        , INTENT(in   ) ::   psgn     ! =-1 the sign change across the north fold boundary
       !                                                             ! =  1. , the sign is kept
-      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             ! dummy loop indices
@@ -391,41 +393,26 @@
       !!----------------------------------------------------------------------
 
-      IF( PRESENT( pval ) ) THEN   ;   zland = pval      ! set land value
-      ELSE                         ;   zland = 0.e0      ! zero by default
-      ENDIF
+      zland = 0.e0      ! zero by default
 
       ! 1. standard boundary treatment
       ! ------------------------------
-      IF( PRESENT( cd_mpp ) ) THEN      ! only fill added line/raw with existing values
-         !
-         ! WARNING ptab is defined only between nld and nle
-         DO jk = 1, jpk
-            DO jj = nlcj+1, jpj                 ! added line(s)   (inner only)
-               ptab(nldi  :nlei  , jj          ,jk) = ptab(nldi:nlei,     nlej,jk)   
-               ptab(1     :nldi-1, jj          ,jk) = ptab(nldi     ,     nlej,jk)
-               ptab(nlei+1:nlci  , jj          ,jk) = ptab(     nlei,     nlej,jk)
-            END DO
-            DO ji = nlci+1, jpi                 ! added column(s) (full)
-               ptab(ji           ,nldj  :nlej  ,jk) = ptab(     nlei,nldj:nlej,jk)
-               ptab(ji           ,1     :nldj-1,jk) = ptab(     nlei,nldj     ,jk)
-               ptab(ji           ,nlej+1:jpj   ,jk) = ptab(     nlei,     nlej,jk)
-            END DO
-         END DO
-         !
-      ELSE                              ! standard close or cyclic treatment 
-         !
-         !                                   ! East-West boundaries
-         !                                        !* Cyclic east-west
-         IF( nbondi == 2 .AND. (nperio == 1 .OR. nperio == 4 .OR. nperio == 6) ) THEN
-            ptab( 1 ,:,:) = ptab(jpim1,:,:)
-            ptab(jpi,:,:) = ptab(  2  ,:,:)
-         ELSE                                     !* closed
-            IF( .NOT. cd_type == 'F' )   ptab(     1       :jpreci,:,:) = zland    ! south except F-point
-                                         ptab(nlci-jpreci+1:jpi   ,:,:) = zland    ! north
-         ENDIF
-         !                                   ! North-South boundaries (always closed)
-         IF( .NOT. cd_type == 'F' )   ptab(:,     1       :jprecj,:) = zland       ! south except F-point
-                                      ptab(:,nlcj-jprecj+1:jpj   ,:) = zland       ! north
-         !
+      IF( nbondi == 2) THEN
+        IF (nperio == 1 .OR. nperio == 4 .OR. nperio == 6) THEN
+          ptab( 1 ,:,:) = ptab(jpim1,:,:)
+          ptab(jpi,:,:) = ptab(  2  ,:,:)
+        ELSE
+          IF( .NOT. cd_type == 'F' )   ptab(     1       :jpreci,:,:) = zland    ! south except F-point
+          ptab(nlci-jpreci+1:jpi   ,:,:) = zland    ! north
+        ENDIF
+      ELSEIF(nbondi == -1) THEN
+        IF( .NOT. cd_type == 'F' )   ptab(     1       :jpreci,:,:) = zland    ! south except F-point
+      ELSEIF(nbondi == 1) THEN
+        ptab(nlci-jpreci+1:jpi   ,:,:) = zland    ! north
+      ENDIF                                     !* closed
+
+      IF (nbondj == 2 .OR. nbondj == -1) THEN
+        IF( .NOT. cd_type == 'F' )   ptab(:,     1       :jprecj,:) = zland       ! south except F-point
+      ELSEIF (nbondj == 2 .OR. nbondj == 1) THEN
+        ptab(:,nlcj-jprecj+1:jpj   ,:) = zland       ! north
       ENDIF
 
@@ -434,4 +421,5 @@
       ! we play with the neigbours AND the row number because of the periodicity 
       !
+      IF(nbondj .ne. 0) THEN
       SELECT CASE ( nbondi )      ! Read Dirichlet lateral conditions
       CASE ( -1, 0, 1 )                ! all exept 2 (i.e. close case)
@@ -472,5 +460,5 @@
             ptab(iihom+jl,:,:) = t3ew(:,jl,:,2)
          END DO
-      CASE ( 0 ) 
+      CASE ( 0 )
          DO jl = 1, jpreci
             ptab(jl      ,:,:) = t3we(:,jl,:,2)
@@ -482,4 +470,5 @@
          END DO
       END SELECT
+      ENDIF
 
 
@@ -488,4 +477,5 @@
       ! always closed : we play only with the neigbours
       !
+      IF(nbondi .ne. 0) THEN
       IF( nbondj /= 2 ) THEN      ! Read Dirichlet lateral conditions
          ijhom = nlcj-nrecj
@@ -525,5 +515,5 @@
             ptab(:,ijhom+jl,:) = t3ns(:,jl,:,2)
          END DO
-      CASE ( 0 ) 
+      CASE ( 0 )
          DO jl = 1, jprecj
             ptab(:,jl      ,:) = t3sn(:,jl,:,2)
@@ -535,4 +525,5 @@
          END DO
       END SELECT
+      ENDIF
 
 
@@ -540,5 +531,5 @@
       ! -----------------------
       !
-      IF( npolj /= 0 .AND. .NOT. PRESENT(cd_mpp) ) THEN
+      IF( npolj /= 0 ) THEN
          !
          SELECT CASE ( jpni )
@@ -549,14 +540,14 @@
       ENDIF
       !
-   END SUBROUTINE mpp_lnk_3d
-
-
-   SUBROUTINE mpp_lnk_2d( pt2d, cd_type, psgn, cd_mpp, pval )
-      !!----------------------------------------------------------------------
-      !!                  ***  routine mpp_lnk_2d  ***
+   END SUBROUTINE mpp_lnk_obc_3d
+
+
+   SUBROUTINE mpp_lnk_obc_2d( pt2d, cd_type, psgn )
+      !!----------------------------------------------------------------------
+      !!                  ***  routine mpp_lnk_obc_2d  ***
       !!                  
       !! ** Purpose :   Message passing manadgement for 2d array
       !!
-      !! ** Method  :   Use mppsend and mpprecv function for passing mask 
+      !! ** Method  :   Use mppsend and mpprecv function for passing OBC boundaries 
       !!      between processors following neighboring subdomains.
       !!            domain parameters
@@ -576,6 +567,4 @@
       REAL(wp)                    , INTENT(in   ) ::   psgn     ! =-1 the sign change across the north fold boundary
       !                                                         ! =  1. , the sign is kept
-      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, jl   ! dummy loop indices
@@ -586,40 +575,27 @@
       !!----------------------------------------------------------------------
 
-      IF( PRESENT( pval ) ) THEN   ;   zland = pval      ! set land value
-      ELSE                         ;   zland = 0.e0      ! zero by default
-      ENDIF
+      zland = 0.e0      ! zero by default
 
       ! 1. standard boundary treatment
       ! ------------------------------
       !
-      IF( PRESENT( cd_mpp ) ) THEN      ! only fill added line/raw with existing values
-         !
-         ! WARNING pt2d is defined only between nld and nle
-         DO jj = nlcj+1, jpj                 ! added line(s)   (inner only)
-            pt2d(nldi  :nlei  , jj          ) = pt2d(nldi:nlei,     nlej)   
-            pt2d(1     :nldi-1, jj          ) = pt2d(nldi     ,     nlej)
-            pt2d(nlei+1:nlci  , jj          ) = pt2d(     nlei,     nlej)
-         END DO
-         DO ji = nlci+1, jpi                 ! added column(s) (full)
-            pt2d(ji           ,nldj  :nlej  ) = pt2d(     nlei,nldj:nlej)
-            pt2d(ji           ,1     :nldj-1) = pt2d(     nlei,nldj     )
-            pt2d(ji           ,nlej+1:jpj   ) = pt2d(     nlei,     nlej)
-         END DO
-         !
-      ELSE                              ! standard close or cyclic treatment 
-         !
-         !                                   ! East-West boundaries
-         IF( nbondi == 2 .AND.   &                ! Cyclic east-west
-            &    (nperio == 1 .OR. nperio == 4 .OR. nperio == 6) ) THEN
-            pt2d( 1 ,:) = pt2d(jpim1,:)                                    ! west
-            pt2d(jpi,:) = pt2d(  2  ,:)                                    ! east
-         ELSE                                     ! closed
-            IF( .NOT. cd_type == 'F' )   pt2d(     1       :jpreci,:) = zland    ! south except F-point
-                                         pt2d(nlci-jpreci+1:jpi   ,:) = zland    ! north
-         ENDIF
-         !                                   ! North-South boundaries (always closed)
-            IF( .NOT. cd_type == 'F' )   pt2d(:,     1       :jprecj) = zland    !south except F-point
-                                         pt2d(:,nlcj-jprecj+1:jpj   ) = zland    ! north
-         !
+      IF( nbondi == 2) THEN
+        IF (nperio == 1 .OR. nperio == 4 .OR. nperio == 6) THEN
+          pt2d( 1 ,:) = pt2d(jpim1,:)
+          pt2d(jpi,:) = pt2d(  2  ,:)
+        ELSE
+          IF( .NOT. cd_type == 'F' )   pt2d(     1       :jpreci,:) = zland    ! south except F-point
+          pt2d(nlci-jpreci+1:jpi   ,:) = zland    ! north
+        ENDIF
+      ELSEIF(nbondi == -1) THEN
+        IF( .NOT. cd_type == 'F' )   pt2d(     1       :jpreci,:) = zland    ! south except F-point
+      ELSEIF(nbondi == 1) THEN
+        pt2d(nlci-jpreci+1:jpi   ,:) = zland    ! north
+      ENDIF                                     !* closed
+
+      IF (nbondj == 2 .OR. nbondj == -1) THEN
+        IF( .NOT. cd_type == 'F' )   pt2d(:,     1       :jprecj) = zland       ! south except F-point
+      ELSEIF (nbondj == 2 .OR. nbondj == 1) THEN
+        pt2d(:,nlcj-jprecj+1:jpj) = zland       ! north
       ENDIF
 
@@ -734,4 +710,394 @@
       ! -----------------------
       !
+      IF( npolj /= 0 ) THEN
+         !
+         SELECT CASE ( jpni )
+         CASE ( 1 )     ;   CALL lbc_nfd      ( pt2d, cd_type, psgn )   ! only 1 northern proc, no mpp
+         CASE DEFAULT   ;   CALL mpp_lbc_north( pt2d, cd_type, psgn )   ! for all northern procs.
+         END SELECT
+         !
+      ENDIF
+      !
+   END SUBROUTINE mpp_lnk_obc_2d
+
+   SUBROUTINE mpp_lnk_3d( ptab, cd_type, psgn, cd_mpp, pval )
+      !!----------------------------------------------------------------------
+      !!                  ***  routine mpp_lnk_3d  ***
+      !!
+      !! ** Purpose :   Message passing manadgement
+      !!
+      !! ** Method  :   Use mppsend and mpprecv function for passing mask 
+      !!      between processors following neighboring subdomains.
+      !!            domain parameters
+      !!                    nlci   : first dimension of the local subdomain
+      !!                    nlcj   : second dimension of the local subdomain
+      !!                    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
+      !!
+      !! ** Action  :   ptab with update value at its periphery
+      !!
+      !!----------------------------------------------------------------------
+      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   ptab     ! 3D array on which the boundary condition is applied
+      CHARACTER(len=1)                , INTENT(in   ) ::   cd_type  ! define the nature of ptab array grid-points
+      !                                                             ! = T , U , V , F , W points
+      REAL(wp)                        , INTENT(in   ) ::   psgn     ! =-1 the sign change across the north fold boundary
+      !                                                             ! =  1. , the sign is kept
+      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             ! dummy loop indices
+      INTEGER  ::   imigr, iihom, ijhom        ! temporary integers
+      INTEGER  ::   ml_req1, ml_req2, ml_err   ! for key_mpi_isend
+      REAL(wp) ::   zland
+      INTEGER, DIMENSION(MPI_STATUS_SIZE) ::   ml_stat   ! for key_mpi_isend
+      !!----------------------------------------------------------------------
+
+      IF( PRESENT( pval ) ) THEN   ;   zland = pval      ! set land value
+      ELSE                         ;   zland = 0.e0      ! zero by default
+      ENDIF
+
+      ! 1. standard boundary treatment
+      ! ------------------------------
+      IF( PRESENT( cd_mpp ) ) THEN      ! only fill added line/raw with existing values
+         !
+         ! WARNING ptab is defined only between nld and nle
+         DO jk = 1, jpk
+            DO jj = nlcj+1, jpj                 ! added line(s)   (inner only)
+               ptab(nldi  :nlei  , jj          ,jk) = ptab(nldi:nlei,     nlej,jk)   
+               ptab(1     :nldi-1, jj          ,jk) = ptab(nldi     ,     nlej,jk)
+               ptab(nlei+1:nlci  , jj          ,jk) = ptab(     nlei,     nlej,jk)
+            END DO
+            DO ji = nlci+1, jpi                 ! added column(s) (full)
+               ptab(ji           ,nldj  :nlej  ,jk) = ptab(     nlei,nldj:nlej,jk)
+               ptab(ji           ,1     :nldj-1,jk) = ptab(     nlei,nldj     ,jk)
+               ptab(ji           ,nlej+1:jpj   ,jk) = ptab(     nlei,     nlej,jk)
+            END DO
+         END DO
+         !
+      ELSE                              ! standard close or cyclic treatment 
+         !
+         !                                   ! East-West boundaries
+         !                                        !* Cyclic east-west
+         IF( nbondi == 2 .AND. (nperio == 1 .OR. nperio == 4 .OR. nperio == 6) ) THEN
+            ptab( 1 ,:,:) = ptab(jpim1,:,:)
+            ptab(jpi,:,:) = ptab(  2  ,:,:)
+         ELSE                                     !* closed
+            IF( .NOT. cd_type == 'F' )   ptab(     1       :jpreci,:,:) = zland    ! south except F-point
+                                         ptab(nlci-jpreci+1:jpi   ,:,:) = zland    ! north
+         ENDIF
+         !                                   ! North-South boundaries (always closed)
+         IF( .NOT. cd_type == 'F' )   ptab(:,     1       :jprecj,:) = zland       ! south except F-point
+                                      ptab(:,nlcj-jprecj+1:jpj   ,:) = zland       ! north
+         !
+      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 = nlci-nreci
+         DO jl = 1, jpreci
+            t3ew(:,jl,:,1) = ptab(jpreci+jl,:,:)
+            t3we(:,jl,:,1) = ptab(iihom +jl,:,:)
+         END DO
+      END SELECT  
+      !
+      !                           ! Migrations
+      imigr = jpreci * jpj * jpk
+      !
+      SELECT CASE ( nbondi ) 
+      CASE ( -1 )
+         CALL mppsend( 2, t3we(1,1,1,1), imigr, noea, ml_req1 )
+         CALL mpprecv( 1, t3ew(1,1,1,2), imigr, noea )
+         IF(l_isend) CALL mpi_wait(ml_req1, ml_stat, ml_err)
+      CASE ( 0 )
+         CALL mppsend( 1, t3ew(1,1,1,1), imigr, nowe, ml_req1 )
+         CALL mppsend( 2, t3we(1,1,1,1), imigr, noea, ml_req2 )
+         CALL mpprecv( 1, t3ew(1,1,1,2), imigr, noea )
+         CALL mpprecv( 2, t3we(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, t3ew(1,1,1,1), imigr, nowe, ml_req1 )
+         CALL mpprecv( 2, t3we(1,1,1,2), imigr, nowe )
+         IF(l_isend) CALL mpi_wait(ml_req1, ml_stat, ml_err)
+      END SELECT
+      !
+      !                           ! Write Dirichlet lateral conditions
+      iihom = nlci-jpreci
+      !
+      SELECT CASE ( nbondi )
+      CASE ( -1 )
+         DO jl = 1, jpreci
+            ptab(iihom+jl,:,:) = t3ew(:,jl,:,2)
+         END DO
+      CASE ( 0 ) 
+         DO jl = 1, jpreci
+            ptab(jl      ,:,:) = t3we(:,jl,:,2)
+            ptab(iihom+jl,:,:) = t3ew(:,jl,:,2)
+         END DO
+      CASE ( 1 )
+         DO jl = 1, jpreci
+            ptab(jl      ,:,:) = t3we(:,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 = nlcj-nrecj
+         DO jl = 1, jprecj
+            t3sn(:,jl,:,1) = ptab(:,ijhom +jl,:)
+            t3ns(:,jl,:,1) = ptab(:,jprecj+jl,:)
+         END DO
+      ENDIF
+      !
+      !                           ! Migrations
+      imigr = jprecj * jpi * jpk
+      !
+      SELECT CASE ( nbondj )     
+      CASE ( -1 )
+         CALL mppsend( 4, t3sn(1,1,1,1), imigr, nono, ml_req1 )
+         CALL mpprecv( 3, t3ns(1,1,1,2), imigr, nono )
+         IF(l_isend) CALL mpi_wait(ml_req1, ml_stat, ml_err)
+      CASE ( 0 )
+         CALL mppsend( 3, t3ns(1,1,1,1), imigr, noso, ml_req1 )
+         CALL mppsend( 4, t3sn(1,1,1,1), imigr, nono, ml_req2 )
+         CALL mpprecv( 3, t3ns(1,1,1,2), imigr, nono )
+         CALL mpprecv( 4, t3sn(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, t3ns(1,1,1,1), imigr, noso, ml_req1 )
+         CALL mpprecv( 4, t3sn(1,1,1,2), imigr, noso )
+         IF(l_isend) CALL mpi_wait(ml_req1, ml_stat, ml_err)
+      END SELECT
+      !
+      !                           ! Write Dirichlet lateral conditions
+      ijhom = nlcj-jprecj
+      !
+      SELECT CASE ( nbondj )
+      CASE ( -1 )
+         DO jl = 1, jprecj
+            ptab(:,ijhom+jl,:) = t3ns(:,jl,:,2)
+         END DO
+      CASE ( 0 ) 
+         DO jl = 1, jprecj
+            ptab(:,jl      ,:) = t3sn(:,jl,:,2)
+            ptab(:,ijhom+jl,:) = t3ns(:,jl,:,2)
+         END DO
+      CASE ( 1 )
+         DO jl = 1, jprecj
+            ptab(:,jl,:) = t3sn(:,jl,:,2)
+         END DO
+      END SELECT
+
+
+      ! 4. north fold treatment
+      ! -----------------------
+      !
+      IF( npolj /= 0 .AND. .NOT. PRESENT(cd_mpp) ) THEN
+         !
+         SELECT CASE ( jpni )
+         CASE ( 1 )     ;   CALL lbc_nfd      ( ptab, cd_type, psgn )   ! only 1 northern proc, no mpp
+         CASE DEFAULT   ;   CALL mpp_lbc_north( ptab, cd_type, psgn )   ! for all northern procs.
+         END SELECT
+         !
+      ENDIF
+      !
+   END SUBROUTINE mpp_lnk_3d
+
+
+   SUBROUTINE mpp_lnk_2d( pt2d, cd_type, psgn, cd_mpp, pval )
+      !!----------------------------------------------------------------------
+      !!                  ***  routine mpp_lnk_2d  ***
+      !!                  
+      !! ** Purpose :   Message passing manadgement for 2d array
+      !!
+      !! ** Method  :   Use mppsend and mpprecv function for passing mask 
+      !!      between processors following neighboring subdomains.
+      !!            domain parameters
+      !!                    nlci   : first dimension of the local subdomain
+      !!                    nlcj   : second dimension of the local subdomain
+      !!                    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
+      !!
+      !!----------------------------------------------------------------------
+      REAL(wp), DIMENSION(jpi,jpj), INTENT(inout) ::   pt2d     ! 2D array on which the boundary condition is applied
+      CHARACTER(len=1)            , INTENT(in   ) ::   cd_type  ! define the nature of ptab array grid-points
+      !                                                         ! = T , U , V , F , W and I points
+      REAL(wp)                    , INTENT(in   ) ::   psgn     ! =-1 the sign change across the north fold boundary
+      !                                                         ! =  1. , the sign is kept
+      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, jl   ! dummy loop indices
+      INTEGER  ::   imigr, iihom, ijhom        ! temporary integers
+      INTEGER  ::   ml_req1, ml_req2, ml_err   ! for key_mpi_isend
+      REAL(wp) ::   zland
+      INTEGER, DIMENSION(MPI_STATUS_SIZE) ::   ml_stat   ! for key_mpi_isend
+      !!----------------------------------------------------------------------
+
+      IF( PRESENT( pval ) ) THEN   ;   zland = pval      ! set land value
+      ELSE                         ;   zland = 0.e0      ! zero by default
+      ENDIF
+
+      ! 1. standard boundary treatment
+      ! ------------------------------
+      !
+      IF( PRESENT( cd_mpp ) ) THEN      ! only fill added line/raw with existing values
+         !
+         ! WARNING pt2d is defined only between nld and nle
+         DO jj = nlcj+1, jpj                 ! added line(s)   (inner only)
+            pt2d(nldi  :nlei  , jj          ) = pt2d(nldi:nlei,     nlej)   
+            pt2d(1     :nldi-1, jj          ) = pt2d(nldi     ,     nlej)
+            pt2d(nlei+1:nlci  , jj          ) = pt2d(     nlei,     nlej)
+         END DO
+         DO ji = nlci+1, jpi                 ! added column(s) (full)
+            pt2d(ji           ,nldj  :nlej  ) = pt2d(     nlei,nldj:nlej)
+            pt2d(ji           ,1     :nldj-1) = pt2d(     nlei,nldj     )
+            pt2d(ji           ,nlej+1:jpj   ) = pt2d(     nlei,     nlej)
+         END DO
+         !
+      ELSE                              ! standard close or cyclic treatment 
+         !
+         !                                   ! East-West boundaries
+         IF( nbondi == 2 .AND.   &                ! Cyclic east-west
+            &    (nperio == 1 .OR. nperio == 4 .OR. nperio == 6) ) THEN
+            pt2d( 1 ,:) = pt2d(jpim1,:)                                    ! west
+            pt2d(jpi,:) = pt2d(  2  ,:)                                    ! east
+         ELSE                                     ! closed
+            IF( .NOT. cd_type == 'F' )   pt2d(     1       :jpreci,:) = zland    ! south except F-point
+                                         pt2d(nlci-jpreci+1:jpi   ,:) = zland    ! north
+         ENDIF
+         !                                   ! North-South boundaries (always closed)
+            IF( .NOT. cd_type == 'F' )   pt2d(:,     1       :jprecj) = zland    !south except F-point
+                                         pt2d(:,nlcj-jprecj+1:jpj   ) = zland    ! north
+         !
+      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 = nlci-nreci
+         DO jl = 1, jpreci
+            t2ew(:,jl,1) = pt2d(jpreci+jl,:)
+            t2we(:,jl,1) = pt2d(iihom +jl,:)
+         END DO
+      END SELECT
+      !
+      !                           ! Migrations
+      imigr = jpreci * jpj
+      !
+      SELECT CASE ( nbondi )
+      CASE ( -1 )
+         CALL mppsend( 2, t2we(1,1,1), imigr, noea, ml_req1 )
+         CALL mpprecv( 1, t2ew(1,1,2), imigr, noea )
+         IF(l_isend) CALL mpi_wait(ml_req1,ml_stat,ml_err)
+      CASE ( 0 )
+         CALL mppsend( 1, t2ew(1,1,1), imigr, nowe, ml_req1 )
+         CALL mppsend( 2, t2we(1,1,1), imigr, noea, ml_req2 )
+         CALL mpprecv( 1, t2ew(1,1,2), imigr, noea )
+         CALL mpprecv( 2, t2we(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, t2ew(1,1,1), imigr, nowe, ml_req1 )
+         CALL mpprecv( 2, t2we(1,1,2), imigr, nowe )
+         IF(l_isend) CALL mpi_wait(ml_req1,ml_stat,ml_err)
+      END SELECT
+      !
+      !                           ! Write Dirichlet lateral conditions
+      iihom = nlci - jpreci
+      !
+      SELECT CASE ( nbondi )
+      CASE ( -1 )
+         DO jl = 1, jpreci
+            pt2d(iihom+jl,:) = t2ew(:,jl,2)
+         END DO
+      CASE ( 0 )
+         DO jl = 1, jpreci
+            pt2d(jl      ,:) = t2we(:,jl,2)
+            pt2d(iihom+jl,:) = t2ew(:,jl,2)
+         END DO
+      CASE ( 1 )
+         DO jl = 1, jpreci
+            pt2d(jl      ,:) = t2we(:,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 = nlcj-nrecj
+         DO jl = 1, jprecj
+            t2sn(:,jl,1) = pt2d(:,ijhom +jl)
+            t2ns(:,jl,1) = pt2d(:,jprecj+jl)
+         END DO
+      ENDIF
+      !
+      !                           ! Migrations
+      imigr = jprecj * jpi
+      !
+      SELECT CASE ( nbondj )
+      CASE ( -1 )
+         CALL mppsend( 4, t2sn(1,1,1), imigr, nono, ml_req1 )
+         CALL mpprecv( 3, t2ns(1,1,2), imigr, nono )
+         IF(l_isend) CALL mpi_wait(ml_req1,ml_stat,ml_err)
+      CASE ( 0 )
+         CALL mppsend( 3, t2ns(1,1,1), imigr, noso, ml_req1 )
+         CALL mppsend( 4, t2sn(1,1,1), imigr, nono, ml_req2 )
+         CALL mpprecv( 3, t2ns(1,1,2), imigr, nono )
+         CALL mpprecv( 4, t2sn(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, t2ns(1,1,1), imigr, noso, ml_req1 )
+         CALL mpprecv( 4, t2sn(1,1,2), imigr, noso )
+         IF(l_isend) CALL mpi_wait(ml_req1,ml_stat,ml_err)
+      END SELECT
+      !
+      !                           ! Write Dirichlet lateral conditions
+      ijhom = nlcj - jprecj
+      !
+      SELECT CASE ( nbondj )
+      CASE ( -1 )
+         DO jl = 1, jprecj
+            pt2d(:,ijhom+jl) = t2ns(:,jl,2)
+         END DO
+      CASE ( 0 )
+         DO jl = 1, jprecj
+            pt2d(:,jl      ) = t2sn(:,jl,2)
+            pt2d(:,ijhom+jl) = t2ns(:,jl,2)
+         END DO
+      CASE ( 1 ) 
+         DO jl = 1, jprecj
+            pt2d(:,jl      ) = t2sn(:,jl,2)
+         END DO
+      END SELECT
+
+
+      ! 4. north fold treatment
+      ! -----------------------
+      !
       IF( npolj /= 0 .AND. .NOT. PRESENT(cd_mpp) ) THEN
          !
@@ -1781,4 +2147,5 @@
       INTEGER ::   ml_stat(MPI_STATUS_SIZE)    ! for key_mpi_isend
       REAL(wp), POINTER, DIMENSION(:,:) ::   ztab   ! temporary workspace
+      LOGICAL :: lmigr ! is true for those processors that have to migrate the OB
       !!----------------------------------------------------------------------
 
@@ -1806,9 +2173,18 @@
          CALL mppstop
       ENDIF
-      
+
       ! Communication level by level
       ! ----------------------------
 !!gm Remark : this is very time consumming!!!
       !                                         ! ------------------------ !
+            IF( ijpt0 > ijpt1 .OR. iipt0 > iipt1 ) THEN
+            ! there is nothing to be migrated
+               lmigr = .FALSE.
+            ELSE
+              lmigr = .TRUE.
+            ENDIF
+
+      IF( lmigr ) THEN
+
       DO jk = 1, kk                             !   Loop over the levels   !
          !                                      ! ------------------------ !
@@ -1832,14 +2208,14 @@
          ! ---------------------------
          !
+       IF( ktype == 1 ) THEN
+
          IF( nbondi /= 2 ) THEN         ! Read Dirichlet lateral conditions
             iihom = nlci-nreci
-            DO jl = 1, jpreci
-               t2ew(:,jl,1) = ztab(jpreci+jl,:)
-               t2we(:,jl,1) = ztab(iihom +jl,:)
-            END DO
+            t2ew(1:jpreci,1,1) = ztab(jpreci+1:nreci, ijpt0)
+            t2we(1:jpreci,1,1) = ztab(iihom+1:iihom+jpreci, ijpt0)
          ENDIF
          !
          !                              ! Migrations
-         imigr=jpreci*jpj
+         imigr = jpreci
          !
          IF( nbondi == -1 ) THEN
@@ -1864,28 +2240,23 @@
          !
          IF( nbondi == 0 .OR. nbondi == 1 ) THEN
-            DO jl = 1, jpreci
-               ztab(jl,:) = t2we(:,jl,2)
-            END DO
+            ztab(1:jpreci, ijpt0) = t2we(1:jpreci,1,2)
          ENDIF
          IF( nbondi == -1 .OR. nbondi == 0 ) THEN
-            DO jl = 1, jpreci
-               ztab(iihom+jl,:) = t2ew(:,jl,2)
-            END DO
+            ztab(iihom+1:iihom+jpreci, ijpt0) = t2ew(1:jpreci,1,2)
          ENDIF
-
+       ENDIF  ! (ktype == 1)
 
          ! 2. North and south directions
          ! -----------------------------
          !
+       IF(ktype == 2 ) THEN
          IF( nbondj /= 2 ) THEN         ! Read Dirichlet lateral conditions
             ijhom = nlcj-nrecj
-            DO jl = 1, jprecj
-               t2sn(:,jl,1) = ztab(:,ijhom +jl)
-               t2ns(:,jl,1) = ztab(:,jprecj+jl)
-            END DO
+            t2sn(1:jprecj,1,1) = ztab(iipt0, ijhom+1:ijhom+jprecj)
+            t2ns(1:jprecj,1,1) = ztab(iipt0, jprecj+1:nrecj)
          ENDIF
          !
          !                              ! Migrations
-         imigr = jprecj * jpi
+         imigr = jprecj
          !
          IF( nbondj == -1 ) THEN
@@ -1909,17 +2280,14 @@
          ijhom = nlcj - jprecj
          IF( nbondj == 0 .OR. nbondj == 1 ) THEN
-            DO jl = 1, jprecj
-               ztab(:,jl) = t2sn(:,jl,2)
-            END DO
+            ztab(iipt0,1:jprecj) = t2sn(1:jprecj,1,2)
          ENDIF
          IF( nbondj == 0 .OR. nbondj == -1 ) THEN
-            DO jl = 1, jprecj
-               ztab(:,ijhom+jl) = t2ns(:,jl,2)
-            END DO
+            ztab(iipt0, ijhom+1:ijhom+jprecj) = t2ns(1:jprecj,1,2)
          ENDIF
+         ENDIF    ! (ktype == 2)
          IF( ktype==1 .AND. kd1 <= jpi+nimpp-1 .AND. nimpp <= kd2 ) THEN
             DO jj = ijpt0, ijpt1            ! north/south boundaries
                DO ji = iipt0,ilpt1
-                  ptab(ji,jk) = ztab(ji,jj)  
+                  ptab(ji,jk) = ztab(ji,jj)
                END DO
             END DO
@@ -1927,5 +2295,5 @@
             DO jj = ijpt0, ilpt1            ! east/west boundaries
                DO ji = iipt0,iipt1
-                  ptab(jj,jk) = ztab(ji,jj) 
+                  ptab(jj,jk) = ztab(ji,jj)
                END DO
             END DO
@@ -1934,4 +2302,5 @@
       END DO
       !
+      ENDIF ! ( lmigr )
       CALL wrk_dealloc( jpi,jpj, ztab )
       !
@@ -2533,4 +2902,431 @@
    END SUBROUTINE mpp_lbc_north_e
 
+      SUBROUTINE mpp_lnk_bdy_3d( ptab, cd_type, psgn, ib_bdy )
+      !!----------------------------------------------------------------------
+      !!                  ***  routine mpp_lnk_bdy_3d  ***
+      !!
+      !! ** Purpose :   Message passing management
+      !!
+      !! ** Method  :   Use mppsend and mpprecv function for passing BDY boundaries 
+      !!      between processors following neighboring subdomains.
+      !!            domain parameters
+      !!                    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
+      !!                    noso   : number for local neighboring processors
+      !!                    nono   : number for local neighboring processors
+      !!
+      !! ** Action  :   ptab with update value at its periphery
+      !!
+      !!----------------------------------------------------------------------
+
+      USE lbcnfd          ! north fold
+
+      INCLUDE 'mpif.h'
+
+      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   ptab     ! 3D array on which the boundary condition is applied
+      CHARACTER(len=1)                , INTENT(in   ) ::   cd_type  ! define the nature of ptab array grid-points
+      !                                                             ! = T , U , V , F , W points
+      REAL(wp)                        , INTENT(in   ) ::   psgn     ! =-1 the sign change across the north fold boundary
+      !                                                             ! =  1. , the sign is kept
+      INTEGER                         , INTENT(in   ) ::   ib_bdy   ! BDY boundary set
+      INTEGER  ::   ji, jj, jk, jl             ! dummy loop indices
+      INTEGER  ::   imigr, iihom, ijhom        ! temporary integers
+      INTEGER  ::   ml_req1, ml_req2, ml_err   ! for key_mpi_isend
+      REAL(wp) ::   zland
+      INTEGER, DIMENSION(MPI_STATUS_SIZE) ::   ml_stat   ! for key_mpi_isend
+      !!----------------------------------------------------------------------
+
+      zland = 0.e0
+
+      ! 1. standard boundary treatment
+      ! ------------------------------
+      
+      !                                   ! East-West boundaries
+      !                                        !* Cyclic east-west
+
+      IF( nbondi == 2) THEN
+        IF (nperio == 1 .OR. nperio == 4 .OR. nperio == 6) THEN
+          ptab( 1 ,:,:) = ptab(jpim1,:,:)
+          ptab(jpi,:,:) = ptab(  2  ,:,:)
+        ELSE
+          IF( .NOT. cd_type == 'F' )   ptab(     1       :jpreci,:,:) = zland    ! south except F-point
+          ptab(nlci-jpreci+1:jpi   ,:,:) = zland    ! north
+        ENDIF
+      ELSEIF(nbondi == -1) THEN
+        IF( .NOT. cd_type == 'F' )   ptab(     1       :jpreci,:,:) = zland    ! south except F-point
+      ELSEIF(nbondi == 1) THEN
+        ptab(nlci-jpreci+1:jpi   ,:,:) = zland    ! north
+      ENDIF                                     !* closed
+
+      IF (nbondj == 2 .OR. nbondj == -1) THEN
+        IF( .NOT. cd_type == 'F' )   ptab(:,     1       :jprecj,:) = zland       ! south except F-point
+      ELSEIF (nbondj == 2 .OR. nbondj == 1) THEN
+        ptab(:,nlcj-jprecj+1:jpj   ,:) = zland       ! north
+      ENDIF
+      
+      !
+
+      ! 2. East and west directions exchange
+      ! ------------------------------------
+      ! we play with the neigbours AND the row number because of the periodicity 
+      !
+      SELECT CASE ( nbondi_bdy(ib_bdy) )      ! Read Dirichlet lateral conditions
+      CASE ( -1, 0, 1 )                ! all exept 2 (i.e. close case)
+         iihom = nlci-nreci
+         DO jl = 1, jpreci
+            t3ew(:,jl,:,1) = ptab(jpreci+jl,:,:)
+            t3we(:,jl,:,1) = ptab(iihom +jl,:,:)
+         END DO
+      END SELECT
+      !
+      !                           ! Migrations
+      imigr = jpreci * jpj * jpk
+      !
+      SELECT CASE ( nbondi_bdy(ib_bdy) )
+      CASE ( -1 )
+         CALL mppsend( 2, t3we(1,1,1,1), imigr, noea, ml_req1 )
+      CASE ( 0 )
+         CALL mppsend( 1, t3ew(1,1,1,1), imigr, nowe, ml_req1 )
+         CALL mppsend( 2, t3we(1,1,1,1), imigr, noea, ml_req2 )
+      CASE ( 1 )
+         CALL mppsend( 1, t3ew(1,1,1,1), imigr, nowe, ml_req1 )
+      END SELECT
+      !
+      SELECT CASE ( nbondi_bdy_b(ib_bdy) )
+      CASE ( -1 )
+         CALL mpprecv( 1, t3ew(1,1,1,2), imigr, noea )
+      CASE ( 0 )
+         CALL mpprecv( 1, t3ew(1,1,1,2), imigr, noea )
+         CALL mpprecv( 2, t3we(1,1,1,2), imigr, nowe )
+      CASE ( 1 )
+         CALL mpprecv( 2, t3we(1,1,1,2), imigr, nowe )
+      END SELECT
+      !
+      SELECT CASE ( nbondi_bdy(ib_bdy) )
+      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
+      !
+      !                           ! Write Dirichlet lateral conditions
+      iihom = nlci-jpreci
+      !
+      SELECT CASE ( nbondi_bdy_b(ib_bdy) )
+      CASE ( -1 )
+         DO jl = 1, jpreci
+            ptab(iihom+jl,:,:) = t3ew(:,jl,:,2)
+         END DO
+      CASE ( 0 )
+         DO jl = 1, jpreci
+            ptab(jl      ,:,:) = t3we(:,jl,:,2)
+            ptab(iihom+jl,:,:) = t3ew(:,jl,:,2)
+         END DO
+      CASE ( 1 )
+         DO jl = 1, jpreci
+            ptab(jl      ,:,:) = t3we(:,jl,:,2)
+         END DO
+      END SELECT
+
+
+      ! 3. North and south directions
+      ! -----------------------------
+      ! always closed : we play only with the neigbours
+      !
+      IF( nbondj_bdy(ib_bdy) /= 2 ) THEN      ! Read Dirichlet lateral conditions
+         ijhom = nlcj-nrecj
+         DO jl = 1, jprecj
+            t3sn(:,jl,:,1) = ptab(:,ijhom +jl,:)
+            t3ns(:,jl,:,1) = ptab(:,jprecj+jl,:)
+         END DO
+      ENDIF
+      !
+      !                           ! Migrations
+      imigr = jprecj * jpi * jpk
+      !
+      SELECT CASE ( nbondj_bdy(ib_bdy) )
+      CASE ( -1 )
+         CALL mppsend( 4, t3sn(1,1,1,1), imigr, nono, ml_req1 )
+      CASE ( 0 )
+         CALL mppsend( 3, t3ns(1,1,1,1), imigr, noso, ml_req1 )
+         CALL mppsend( 4, t3sn(1,1,1,1), imigr, nono, ml_req2 )
+      CASE ( 1 )
+         CALL mppsend( 3, t3ns(1,1,1,1), imigr, noso, ml_req1 )
+      END SELECT
+      !
+      SELECT CASE ( nbondj_bdy_b(ib_bdy) )
+      CASE ( -1 )
+         CALL mpprecv( 3, t3ns(1,1,1,2), imigr, nono )
+      CASE ( 0 )
+         CALL mpprecv( 3, t3ns(1,1,1,2), imigr, nono )
+         CALL mpprecv( 4, t3sn(1,1,1,2), imigr, noso )
+      CASE ( 1 )
+         CALL mpprecv( 4, t3sn(1,1,1,2), imigr, noso )
+      END SELECT
+      !
+      SELECT CASE ( nbondj_bdy(ib_bdy) )
+      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
+      !
+      !                           ! Write Dirichlet lateral conditions
+      ijhom = nlcj-jprecj
+      !
+      SELECT CASE ( nbondj_bdy_b(ib_bdy) )
+      CASE ( -1 )
+         DO jl = 1, jprecj
+            ptab(:,ijhom+jl,:) = t3ns(:,jl,:,2)
+         END DO
+      CASE ( 0 )
+         DO jl = 1, jprecj
+            ptab(:,jl      ,:) = t3sn(:,jl,:,2)
+            ptab(:,ijhom+jl,:) = t3ns(:,jl,:,2)
+         END DO
+      CASE ( 1 )
+         DO jl = 1, jprecj
+            ptab(:,jl,:) = t3sn(:,jl,:,2)
+         END DO
+      END SELECT
+
+
+      ! 4. north fold treatment
+      ! -----------------------
+      !
+      IF( npolj /= 0) THEN
+         !
+         SELECT CASE ( jpni )
+         CASE ( 1 )     ;   CALL lbc_nfd      ( ptab, cd_type, psgn )   ! only 1 northern proc, no mpp
+         CASE DEFAULT   ;   CALL mpp_lbc_north( ptab, cd_type, psgn )   ! for all northern procs.
+         END SELECT
+         !
+      ENDIF
+      !
+   END SUBROUTINE mpp_lnk_bdy_3d
+
+      SUBROUTINE mpp_lnk_bdy_2d( ptab, cd_type, psgn, ib_bdy )
+      !!----------------------------------------------------------------------
+      !!                  ***  routine mpp_lnk_bdy_2d  ***
+      !!
+      !! ** Purpose :   Message passing management
+      !!
+      !! ** Method  :   Use mppsend and mpprecv function for passing BDY boundaries 
+      !!      between processors following neighboring subdomains.
+      !!            domain parameters
+      !!                    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
+      !!                    noso   : number for local neighboring processors
+      !!                    nono   : number for local neighboring processors
+      !!
+      !! ** Action  :   ptab with update value at its periphery
+      !!
+      !!----------------------------------------------------------------------
+
+      USE lbcnfd          ! north fold
+
+      INCLUDE 'mpif.h'
+
+      REAL(wp), DIMENSION(jpi,jpj)    , INTENT(inout) ::   ptab     ! 3D array on which the boundary condition is applied
+      CHARACTER(len=1)                , INTENT(in   ) ::   cd_type  ! define the nature of ptab array grid-points
+      !                                                             ! = T , U , V , F , W points
+      REAL(wp)                        , INTENT(in   ) ::   psgn     ! =-1 the sign change across the north fold boundary
+      !                                                             ! =  1. , the sign is kept
+      INTEGER                         , INTENT(in   ) ::   ib_bdy   ! BDY boundary set
+      INTEGER  ::   ji, jj, jl             ! dummy loop indices
+      INTEGER  ::   imigr, iihom, ijhom        ! temporary integers
+      INTEGER  ::   ml_req1, ml_req2, ml_err   ! for key_mpi_isend
+      REAL(wp) ::   zland
+      INTEGER, DIMENSION(MPI_STATUS_SIZE) ::   ml_stat   ! for key_mpi_isend
+      !!----------------------------------------------------------------------
+
+      zland = 0.e0
+
+      ! 1. standard boundary treatment
+      ! ------------------------------
+      
+      !                                   ! East-West boundaries
+      !                                        !* Cyclic east-west
+
+      IF( nbondi == 2) THEN
+        IF (nperio == 1 .OR. nperio == 4 .OR. nperio == 6) THEN
+          ptab( 1 ,:) = ptab(jpim1,:)
+          ptab(jpi,:) = ptab(  2  ,:)
+        ELSE
+          IF( .NOT. cd_type == 'F' )   ptab(     1       :jpreci,:) = zland    ! south except F-point
+          ptab(nlci-jpreci+1:jpi   ,:) = zland    ! north
+        ENDIF
+      ELSEIF(nbondi == -1) THEN
+        IF( .NOT. cd_type == 'F' )   ptab(     1       :jpreci,:) = zland    ! south except F-point
+      ELSEIF(nbondi == 1) THEN
+        ptab(nlci-jpreci+1:jpi   ,:) = zland    ! north
+      ENDIF                                     !* closed
+
+      IF (nbondj == 2 .OR. nbondj == -1) THEN
+        IF( .NOT. cd_type == 'F' )   ptab(:,     1       :jprecj) = zland       ! south except F-point
+      ELSEIF (nbondj == 2 .OR. nbondj == 1) THEN
+        ptab(:,nlcj-jprecj+1:jpj) = zland       ! north
+      ENDIF
+      
+      !
+
+      ! 2. East and west directions exchange
+      ! ------------------------------------
+      ! we play with the neigbours AND the row number because of the periodicity 
+      !
+      SELECT CASE ( nbondi_bdy(ib_bdy) )      ! Read Dirichlet lateral conditions
+      CASE ( -1, 0, 1 )                ! all exept 2 (i.e. close case)
+         iihom = nlci-nreci
+         DO jl = 1, jpreci
+            t2ew(:,jl,1) = ptab(jpreci+jl,:)
+            t2we(:,jl,1) = ptab(iihom +jl,:)
+         END DO
+      END SELECT
+      !
+      !                           ! Migrations
+      imigr = jpreci * jpj
+      !
+      SELECT CASE ( nbondi_bdy(ib_bdy) )
+      CASE ( -1 )
+         CALL mppsend( 2, t2we(1,1,1), imigr, noea, ml_req1 )
+      CASE ( 0 )
+         CALL mppsend( 1, t2ew(1,1,1), imigr, nowe, ml_req1 )
+         CALL mppsend( 2, t2we(1,1,1), imigr, noea, ml_req2 )
+      CASE ( 1 )
+         CALL mppsend( 1, t2ew(1,1,1), imigr, nowe, ml_req1 )
+      END SELECT
+      !
+      SELECT CASE ( nbondi_bdy_b(ib_bdy) )
+      CASE ( -1 )
+         CALL mpprecv( 1, t2ew(1,1,2), imigr, noea )
+      CASE ( 0 )
+         CALL mpprecv( 1, t2ew(1,1,2), imigr, noea )
+         CALL mpprecv( 2, t2we(1,1,2), imigr, nowe )
+      CASE ( 1 )
+         CALL mpprecv( 2, t2we(1,1,2), imigr, nowe )
+      END SELECT
+      !
+      SELECT CASE ( nbondi_bdy(ib_bdy) )
+      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
+      !
+      !                           ! Write Dirichlet lateral conditions
+      iihom = nlci-jpreci
+      !
+      SELECT CASE ( nbondi_bdy_b(ib_bdy) )
+      CASE ( -1 )
+         DO jl = 1, jpreci
+            ptab(iihom+jl,:) = t2ew(:,jl,2)
+         END DO
+      CASE ( 0 )
+         DO jl = 1, jpreci
+            ptab(jl      ,:) = t2we(:,jl,2)
+            ptab(iihom+jl,:) = t2ew(:,jl,2)
+         END DO
+      CASE ( 1 )
+         DO jl = 1, jpreci
+            ptab(jl      ,:) = t2we(:,jl,2)
+         END DO
+      END SELECT
+
+
+      ! 3. North and south directions
+      ! -----------------------------
+      ! always closed : we play only with the neigbours
+      !
+      IF( nbondj_bdy(ib_bdy) /= 2 ) THEN      ! Read Dirichlet lateral conditions
+         ijhom = nlcj-nrecj
+         DO jl = 1, jprecj
+            t2sn(:,jl,1) = ptab(:,ijhom +jl)
+            t2ns(:,jl,1) = ptab(:,jprecj+jl)
+         END DO
+      ENDIF
+      !
+      !                           ! Migrations
+      imigr = jprecj * jpi
+      !
+      SELECT CASE ( nbondj_bdy(ib_bdy) )
+      CASE ( -1 )
+         CALL mppsend( 4, t2sn(1,1,1), imigr, nono, ml_req1 )
+      CASE ( 0 )
+         CALL mppsend( 3, t2ns(1,1,1), imigr, noso, ml_req1 )
+         CALL mppsend( 4, t2sn(1,1,1), imigr, nono, ml_req2 )
+      CASE ( 1 )
+         CALL mppsend( 3, t2ns(1,1,1), imigr, noso, ml_req1 )
+      END SELECT
+      !
+      SELECT CASE ( nbondj_bdy_b(ib_bdy) )
+      CASE ( -1 )
+         CALL mpprecv( 3, t2ns(1,1,2), imigr, nono )
+      CASE ( 0 )
+         CALL mpprecv( 3, t2ns(1,1,2), imigr, nono )
+         CALL mpprecv( 4, t2sn(1,1,2), imigr, noso )
+      CASE ( 1 )
+         CALL mpprecv( 4, t2sn(1,1,2), imigr, noso )
+      END SELECT
+      !
+      SELECT CASE ( nbondj_bdy(ib_bdy) )
+      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
+      !
+      !                           ! Write Dirichlet lateral conditions
+      ijhom = nlcj-jprecj
+      !
+      SELECT CASE ( nbondj_bdy_b(ib_bdy) )
+      CASE ( -1 )
+         DO jl = 1, jprecj
+            ptab(:,ijhom+jl) = t2ns(:,jl,2)
+         END DO
+      CASE ( 0 )
+         DO jl = 1, jprecj
+            ptab(:,jl      ) = t2sn(:,jl,2)
+            ptab(:,ijhom+jl) = t2ns(:,jl,2)
+         END DO
+      CASE ( 1 )
+         DO jl = 1, jprecj
+            ptab(:,jl) = t2sn(:,jl,2)
+         END DO
+      END SELECT
+
+
+      ! 4. north fold treatment
+      ! -----------------------
+      !
+      IF( npolj /= 0) THEN
+         !
+         SELECT CASE ( jpni )
+         CASE ( 1 )     ;   CALL lbc_nfd      ( ptab, cd_type, psgn )   ! only 1 northern proc, no mpp
+         CASE DEFAULT   ;   CALL mpp_lbc_north( ptab, cd_type, psgn )   ! for all northern procs.
+         END SELECT
+         !
+      ENDIF
+      !
+   END SUBROUTINE mpp_lnk_bdy_2d
 
    SUBROUTINE mpi_init_opa( ldtxt, ksft, code )
Index: branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/OBC/obcdyn.F90
===================================================================
--- branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/OBC/obcdyn.F90	(revision 3664)
+++ branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/OBC/obcdyn.F90	(revision 3666)
@@ -5,5 +5,6 @@
    !! Ocean dynamics:   Radiation of velocities on each open boundary
    !!=================================================================================
-
+   !! History :  3.5  !  2012     (S. Mocavero, I. Epicoco) Updates for the 
+   !!                             optimization of OBC communications
    !!---------------------------------------------------------------------------------
    !!   obc_dyn        : call the subroutine for each open boundary
@@ -105,9 +106,9 @@
       IF( lk_mpp ) THEN
          IF( kt >= nit000+3 .AND. ln_rstart ) THEN
-            CALL lbc_lnk( ub, 'U', -1. )
-            CALL lbc_lnk( vb, 'V', -1. )
+            CALL lbc_obc_lnk( ub, 'U', -1. )
+            CALL lbc_obc_lnk( vb, 'V', -1. )
          END IF
-         CALL lbc_lnk( ua, 'U', -1. )
-         CALL lbc_lnk( va, 'V', -1. )
+         CALL lbc_obc_lnk( ua, 'U', -1. )
+         CALL lbc_obc_lnk( va, 'V', -1. )
       ENDIF
 
Index: branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/OBC/obcdyn_bt.F90
===================================================================
--- branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/OBC/obcdyn_bt.F90	(revision 3664)
+++ branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/OBC/obcdyn_bt.F90	(revision 3666)
@@ -5,4 +5,6 @@
    !!======================================================================
    !! History :  1.0  ! 2005-12  (V. Garnier) original code
+   !!            3.5  ! 2012     (S. Mocavero, I. Epicoco) Updates for the 
+   !!                             optimization of OBC communications
    !!----------------------------------------------------------------------
 #if ( defined key_dynspg_ts || defined key_dynspg_exp ) && defined key_obc
@@ -65,11 +67,11 @@
       IF( lk_mpp ) THEN
          IF( kt >= nit000+3 .AND. ln_rstart ) THEN
-            CALL lbc_lnk( sshb, 'T',  1. )
-            CALL lbc_lnk( ub  , 'U', -1. )
-            CALL lbc_lnk( vb  , 'V', -1. )
+            CALL lbc_obc_lnk( sshb, 'T',  1. )
+            CALL lbc_obc_lnk( ub  , 'U', -1. )
+            CALL lbc_obc_lnk( vb  , 'V', -1. )
          END IF
-         CALL lbc_lnk( sshn, 'T',  1. )
-         CALL lbc_lnk( ua  , 'U', -1. )
-         CALL lbc_lnk( va  , 'V', -1. )
+         CALL lbc_obc_lnk( sshn, 'T',  1. )
+         CALL lbc_obc_lnk( ua  , 'U', -1. )
+         CALL lbc_obc_lnk( va  , 'V', -1. )
       ENDIF
 
Index: branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/OBC/obctra.F90
===================================================================
--- branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/OBC/obctra.F90	(revision 3664)
+++ branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/OBC/obctra.F90	(revision 3666)
@@ -4,4 +4,6 @@
    !! Ocean tracers:   Radiation of tracers on each open boundary
    !!=================================================================================
+   !! History :  3.5  !  2012     (S. Mocavero, I. Epicoco) Updates for the 
+   !!                             optimization of OBC communications
 #if defined key_obc
    !!---------------------------------------------------------------------------------
@@ -101,9 +103,9 @@
       IF( lk_mpp ) THEN                  !!bug ???
          IF( kt >= nit000+3 .AND. ln_rstart ) THEN
-            CALL lbc_lnk( tsb(:,:,:,jp_tem), 'T', 1. )
-            CALL lbc_lnk( tsb(:,:,:,jp_sal), 'T', 1. )
+            CALL lbc_obc_lnk( tsb(:,:,:,jp_tem), 'T', 1. )
+            CALL lbc_obc_lnk( tsb(:,:,:,jp_sal), 'T', 1. )
          END IF
-         CALL lbc_lnk( tsa(:,:,:,jp_tem), 'T', 1. )
-         CALL lbc_lnk( tsa(:,:,:,jp_sal), 'T', 1. )
+         CALL lbc_obc_lnk( tsa(:,:,:,jp_tem), 'T', 1. )
+         CALL lbc_obc_lnk( tsa(:,:,:,jp_sal), 'T', 1. )
       ENDIF
 
Index: branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/SBC/fldread.F90
===================================================================
--- branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/SBC/fldread.F90	(revision 3664)
+++ branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/SBC/fldread.F90	(revision 3666)
@@ -835,4 +835,5 @@
          IF( LEN( TRIM(sdf_n(jf)%wname) ) > 0 )   sdf(jf)%wgtname = TRIM( cdir )//TRIM( sdf_n(jf)%wname )
          sdf(jf)%vcomp   = sdf_n(jf)%vcomp
+         sdf(jf)%rotn    = .FALSE.
       END DO
 
Index: branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/SBC/sbc_oce.F90
===================================================================
--- branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/SBC/sbc_oce.F90	(revision 3664)
+++ branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/SBC/sbc_oce.F90	(revision 3666)
@@ -44,5 +44,7 @@
    !                                             !:  = 1 global mean of e-p-r set to zero at each nn_fsbc time step
    !                                             !:  = 2 annual global mean of e-p-r set to zero
-   LOGICAL , PUBLIC ::   ln_cdgw     = .FALSE.   !: true if neutral drag coefficient read from wave model
+   LOGICAL , PUBLIC ::   ln_wave     = .FALSE.   !: true if some coupling with wave model
+   LOGICAL , PUBLIC ::   ln_cdgw     = .FALSE.   !: true if neutral drag coefficient from wave model
+   LOGICAL , PUBLIC ::   ln_sdw      = .FALSE.   !: true if 3d stokes drift from wave model
 
    !!----------------------------------------------------------------------
Index: branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/SBC/sbcmod.F90
===================================================================
--- branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/SBC/sbcmod.F90	(revision 3664)
+++ branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/SBC/sbcmod.F90	(revision 3666)
@@ -82,5 +82,6 @@
       !!
       NAMELIST/namsbc/ nn_fsbc   , ln_ana , ln_flx  , ln_blk_clio, ln_blk_core, ln_cpl,   &
-         &             ln_blk_mfs, ln_apr_dyn, nn_ice , ln_dm2dc, ln_rnf, ln_ssr     , nn_fwb, ln_cdgw
+         &             ln_blk_mfs, ln_apr_dyn, nn_ice , ln_dm2dc, ln_rnf, ln_ssr, nn_fwb, &
+         &             ln_wave, ln_cdgw, ln_sdw
       !!----------------------------------------------------------------------
 
@@ -91,6 +92,8 @@
       ENDIF
 
+      call flush(numout)
       REWIND( numnam )           ! Read Namelist namsbc
       READ  ( numnam, namsbc )
+      call flush(numout)
 
       !                          ! overwrite namelist parameter using CPP key information
@@ -165,7 +168,17 @@
          &   CALL ctl_warn( 'diurnal cycle for qsr: the sampling of the diurnal cycle is too small...' )
 
-       !drag coefficient read from wave model definable only with mfs bulk formulae and core 
-       IF(ln_cdgw .AND. .NOT.(ln_blk_mfs .OR. ln_blk_core) )              &
-          &   CALL ctl_stop( 'drag coefficient read from wave model definable only with mfs bulk formulae and core')
+      IF ( ln_wave ) THEN
+      !Activated wave module but neither drag nor stokes drift activated
+         IF ( .NOT.(ln_cdgw .OR. ln_sdw) )   THEN
+            CALL ctl_warn( 'Ask for wave coupling but nor drag coefficient (ln_cdgw=F) neither stokes drift activated (ln_sdw=F)' )
+      !drag coefficient read from wave model definable only with mfs bulk formulae and core 
+         ELSEIF (ln_cdgw .AND. .NOT.(ln_blk_mfs .OR. ln_blk_core) )       THEN       
+             CALL ctl_stop( 'drag coefficient read from wave model definable only with mfs bulk formulae and core')
+         ENDIF
+      ELSE
+      IF ( ln_cdgw .OR. ln_sdw  )                                         & 
+         &   CALL ctl_stop('Not Activated Wave Module (ln_wave=F) but     &
+         & asked coupling with drag coefficient (ln_cdgw =T) or Stokes drift (ln_sdw=T) ')
+      ENDIF 
       
       !                          ! Choice of the Surface Boudary Condition (set nsbc)
@@ -248,5 +261,5 @@
       !                                                  ! averaged over nf_sbc time-step
 
-      IF (ln_cdgw) CALL sbc_wave( kt )
+      IF (ln_wave) CALL sbc_wave( kt )
                                                    !==  sbc formulation  ==!
                                                             
Index: branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/SBC/sbcrnf.F90
===================================================================
--- branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/SBC/sbcrnf.F90	(revision 3664)
+++ branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/SBC/sbcrnf.F90	(revision 3666)
@@ -57,7 +57,7 @@
    REAL(wp) ::   r1_rau0   ! = 1 / rau0 
 
-   TYPE(FLD), ALLOCATABLE, DIMENSION(:) ::   sf_rnf       ! structure: river runoff (file information, fields read)
-   TYPE(FLD), ALLOCATABLE, DIMENSION(:) ::   sf_s_rnf     ! structure: river runoff salinity (file information, fields read)  
-   TYPE(FLD), ALLOCATABLE, DIMENSION(:) ::   sf_t_rnf     ! structure: river runoff temperature (file information, fields read)  
+   TYPE(FLD), PUBLIC, ALLOCATABLE, DIMENSION(:) ::   sf_rnf       ! structure: river runoff (file information, fields read)
+   TYPE(FLD), PUBLIC, ALLOCATABLE, DIMENSION(:) ::   sf_s_rnf     ! structure: river runoff salinity (file information, fields read)  
+   TYPE(FLD), PUBLIC, ALLOCATABLE, DIMENSION(:) ::   sf_t_rnf     ! structure: river runoff temperature (file information, fields read)  
  
    !! * Substitutions  
Index: branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/SBC/sbcwave.F90
===================================================================
--- branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/SBC/sbcwave.F90	(revision 3664)
+++ branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/SBC/sbcwave.F90	(revision 3666)
@@ -4,5 +4,6 @@
    !! Wave module 
    !!======================================================================
-   !! History :  3.3.1  !   2011-09  (Adani M)  Original code
+   !! History :  3.3.1  !   2011-09  (Adani M)  Original code: Drag Coefficient 
+   !!         :  3.4    !   2012-10  (Adani M)                 Stokes Drift 
    !!----------------------------------------------------------------------
    USE iom             ! I/O manager library
@@ -10,5 +11,7 @@
    USE lib_mpp         ! distribued memory computing library
    USE fldread	       ! read input fields
+   USE oce
    USE sbc_oce	       ! Surface boundary condition: ocean fields
+   USE domvvl
 
    
@@ -22,7 +25,16 @@
    PUBLIC   sbc_wave    ! routine called in sbc_blk_core or sbc_blk_mfs
    
-   TYPE(FLD), ALLOCATABLE, DIMENSION(:)  :: sf_wave	  ! structure of input fields (file informations, fields read)
+   INTEGER , PARAMETER ::   jpfld  = 3           ! maximum number of files to read for srokes drift
+   INTEGER , PARAMETER ::   jp_usd = 1           ! index of stokes drift  (i-component) (m/s)    at T-point
+   INTEGER , PARAMETER ::   jp_vsd = 2           ! index of stokes drift  (j-component) (m/s)    at T-point
+   INTEGER , PARAMETER ::   jp_wn  = 3           ! index of wave number                 (1/m)    at T-point
+   TYPE(FLD), ALLOCATABLE, DIMENSION(:)  :: sf_cd	  ! structure of input fields (file informations, fields read) Drag Coefficient
+   TYPE(FLD), ALLOCATABLE, DIMENSION(:)  :: sf_sd	  ! structure of input fields (file informations, fields read) Stokes Drift
    REAL(wp),PUBLIC,ALLOCATABLE,DIMENSION (:,:)       :: cdn_wave 
+   REAL(wp),ALLOCATABLE,DIMENSION (:,:)              :: usd2d,vsd2d,uwavenum,vwavenum 
+   REAL(wp),PUBLIC,ALLOCATABLE,DIMENSION (:,:,:)     :: usd3d,vsd3d,wsd3d 
 
+   !! * Substitutions
+#  include "domzgr_substitute.h90"
    !!----------------------------------------------------------------------
    !! NEMO/OPA 4.0 , NEMO Consortium (2011) 
@@ -40,13 +52,26 @@
       !! ** Method  : - Read namelist namsbc_wave
       !!              - Read Cd_n10 fields in netcdf files 
+      !!              - Read stokes drift 2d in netcdf files 
+      !!              - Read wave number      in netcdf files 
+      !!              - Compute 3d stokes drift using monochromatic
       !! ** action  :   
       !!               
       !!---------------------------------------------------------------------
-      INTEGER, INTENT( in  ) ::  kt   ! ocean time step
+      USE oce,  ONLY : un,vn,hdivn,rotn
+      USE divcur
+      USE wrk_nemo
+#if defined key_bdy
+      USE bdy_oce, ONLY : bdytmask
+#endif
+      INTEGER, INTENT( in  ) ::  kt       ! ocean time step
       INTEGER                ::  ierror   ! return error code
-      CHARACTER(len=100)     ::  cn_dir_cdg                       ! Root directory for location of drag coefficient files
-      TYPE(FLD_N)            ::  sn_cdg                          ! informations about the fields to be read
+      INTEGER                ::  ifpr, jj,ji,jk 
+      REAL(wp),DIMENSION(:,:,:),POINTER             ::  udummy,vdummy,hdivdummy,rotdummy
+      REAL                                          ::  z2dt,z1_2dt
+      TYPE(FLD_N), DIMENSION(jpfld) ::   slf_i     ! array of namelist informations on the fields to read
+      CHARACTER(len=100)     ::  cn_dir                          ! Root directory for location of drag coefficient files
+      TYPE(FLD_N)            ::  sn_cdg, sn_usd, sn_vsd, sn_wn   ! informations about the fields to be read
       !!---------------------------------------------------------------------
-      NAMELIST/namsbc_wave/  sn_cdg, cn_dir_cdg
+      NAMELIST/namsbc_wave/  sn_cdg, cn_dir, sn_usd, sn_vsd, sn_wn
       !!---------------------------------------------------------------------
 
@@ -62,5 +87,8 @@
          !              !   name   !  (hours)  !   name     !   (T/F)    !  (T/F)  !  'monthly'  ! filename ! pairs    !
          sn_cdg = FLD_N('cdg_wave'  ,    1     ,'drag_coeff',  .true.    , .false. ,   'daily'   , ''       , ''       )
-         cn_dir_cdg = './'          ! directory in which the Patm data are 
+         sn_usd = FLD_N('sdw_wave'  ,    1     ,'u_sd2d',      .true.    , .false. ,   'daily'   , ''       , ''       )
+         sn_vsd = FLD_N('sdw_wave'  ,    1     ,'v_sd2d',      .true.    , .false. ,   'daily'   , ''       , ''       )
+         sn_wn = FLD_N( 'sdw_wave'  ,    1     ,'wave_num',    .true.    , .false. ,   'daily'   , ''       , ''       )
+         cn_dir = './'          ! directory in which the wave data are 
          
 
@@ -69,18 +97,100 @@
          !
 
-         ALLOCATE( sf_wave(1), STAT=ierror )           !* allocate and fill sf_wave with sn_cdg
-         IF( ierror > 0 )   CALL ctl_stop( 'STOP', 'sbc_wave: unable to allocate sf_wave structure' )
-         !
-         CALL fld_fill( sf_wave, (/ sn_cdg /), cn_dir_cdg, 'sbc_wave', 'Wave module ', 'namsbc_wave' )
-                                ALLOCATE( sf_wave(1)%fnow(jpi,jpj,1)   )
-         IF( sn_cdg%ln_tint )   ALLOCATE( sf_wave(1)%fdta(jpi,jpj,1,2) )
-         ALLOCATE( cdn_wave(jpi,jpj) )
-         cdn_wave(:,:) = 0.0
+         IF ( ln_cdgw ) THEN
+            ALLOCATE( sf_cd(1), STAT=ierror )           !* allocate and fill sf_wave with sn_cdg
+            IF( ierror > 0 )   CALL ctl_stop( 'STOP', 'sbc_wave: unable to allocate sf_wave structure' )
+            !
+                                   ALLOCATE( sf_cd(1)%fnow(jpi,jpj,1)   )
+            IF( sn_cdg%ln_tint )   ALLOCATE( sf_cd(1)%fdta(jpi,jpj,1,2) )
+            CALL fld_fill( sf_cd, (/ sn_cdg /), cn_dir, 'sbc_wave', 'Wave module ', 'namsbc_wave' )
+            ALLOCATE( cdn_wave(jpi,jpj) )
+            cdn_wave(:,:) = 0.0
+        ENDIF
+         IF ( ln_sdw ) THEN
+            slf_i(jp_usd) = sn_usd ; slf_i(jp_vsd) = sn_vsd; slf_i(jp_wn) = sn_wn
+            ALLOCATE( sf_sd(3), STAT=ierror )           !* allocate and fill sf_wave with sn_cdg
+            IF( ierror > 0 )   CALL ctl_stop( 'STOP', 'sbc_wave: unable to allocate sf_wave structure' )
+            !
+            DO ifpr= 1, jpfld
+               ALLOCATE( sf_sd(ifpr)%fnow(jpi,jpj,1) )
+               IF( slf_i(ifpr)%ln_tint )   ALLOCATE( sf_sd(ifpr)%fdta(jpi,jpj,1,2) )
+            END DO
+            CALL fld_fill( sf_sd, slf_i, cn_dir, 'sbc_wave', 'Wave module ', 'namsbc_wave' )
+            ALLOCATE( usd2d(jpi,jpj),vsd2d(jpi,jpj),uwavenum(jpi,jpj),vwavenum(jpi,jpj) )
+            ALLOCATE( usd3d(jpi,jpj,jpk),vsd3d(jpi,jpj,jpk),wsd3d(jpi,jpj,jpk) )
+            usd2d(:,:) = 0.0 ;  vsd2d(:,:) = 0.0 ; uwavenum(:,:) = 0.0 ; vwavenum(:,:) = 0.0
+            usd3d(:,:,:) = 0.0 ;vsd3d(:,:,:) = 0.0 ; wsd3d(:,:,:) = 0.0
+         ENDIF
       ENDIF
          !
          !
-      CALL fld_read( kt, nn_fsbc, sf_wave )      !* read drag coefficient from external forcing
-      cdn_wave(:,:) = sf_wave(1)%fnow(:,:,1)
+      IF ( ln_cdgw ) THEN
+         CALL fld_read( kt, nn_fsbc, sf_cd )      !* read drag coefficient from external forcing
+         cdn_wave(:,:) = sf_cd(1)%fnow(:,:,1)
+      ENDIF
+      IF ( ln_sdw )  THEN
+          CALL fld_read( kt, nn_fsbc, sf_sd )      !* read drag coefficient from external forcing
 
+         ! Interpolate wavenumber, stokes drift into the grid_V and grid_V
+         !-------------------------------------------------
+
+         DO jj = 1, jpjm1
+            DO ji = 1, jpim1
+               uwavenum(ji,jj)=0.5 * ( 2. - umask(ji,jj,1) ) * ( sf_sd(3)%fnow(ji,jj,1) * tmask(ji,jj,1) &
+               &                                + sf_sd(3)%fnow(ji+1,jj,1) * tmask(ji+1,jj,1) )
+
+               vwavenum(ji,jj)=0.5 * ( 2. - vmask(ji,jj,1) ) * ( sf_sd(3)%fnow(ji,jj,1) * tmask(ji,jj,1) &
+               &                                + sf_sd(3)%fnow(ji,jj+1,1) * tmask(ji,jj+1,1) )
+
+               usd2d(ji,jj) = 0.5 * ( 2. - umask(ji,jj,1) ) * ( sf_sd(1)%fnow(ji,jj,1) * tmask(ji,jj,1) &
+               &                                + sf_sd(1)%fnow(ji+1,jj,1) * tmask(ji+1,jj,1) )
+
+               vsd2d(ji,jj) = 0.5 * ( 2. - vmask(ji,jj,1) ) * ( sf_sd(2)%fnow(ji,jj,1) * tmask(ji,jj,1) &
+               &                                + sf_sd(2)%fnow(ji,jj+1,1) * tmask(ji,jj+1,1) )
+            END DO
+         END DO
+
+          !Computation of the 3d Stokes Drift
+          DO jk = 1, jpk
+             DO jj = 1, jpj-1
+                DO ji = 1, jpi-1
+                   usd3d(ji,jj,jk) = usd2d(ji,jj)*exp(2.0*uwavenum(ji,jj)*(-MIN( gdept(ji,jj,jk) , gdept(ji+1,jj  ,jk))))
+                   vsd3d(ji,jj,jk) = vsd2d(ji,jj)*exp(2.0*vwavenum(ji,jj)*(-MIN( gdept(ji,jj,jk) , gdept(ji  ,jj+1,jk))))
+                END DO
+             END DO
+             usd3d(jpi,:,jk) = usd2d(jpi,:)*exp( 2.0*uwavenum(jpi,:)*(-gdept(jpi,:,jk)) )
+             vsd3d(:,jpj,jk) = vsd2d(:,jpj)*exp( 2.0*vwavenum(:,jpj)*(-gdept(:,jpj,jk)) )
+          END DO
+
+          CALL wrk_alloc( jpi,jpj,jpk,udummy,vdummy,hdivdummy,rotdummy)
+          
+          udummy(:,:,:)=un(:,:,:)
+          vdummy(:,:,:)=vn(:,:,:)
+          hdivdummy(:,:,:)=hdivn(:,:,:)
+          rotdummy(:,:,:)=rotn(:,:,:)
+          un(:,:,:)=usd3d(:,:,:)
+          vn(:,:,:)=vsd3d(:,:,:)
+          CALL div_cur(kt)
+      !                                           !------------------------------!
+      !                                           !     Now Vertical Velocity    !
+      !                                           !------------------------------!
+          z2dt = 2._wp * rdt                              ! set time step size (Euler/Leapfrog)
+
+          z1_2dt = 1.e0 / z2dt
+          DO jk = jpkm1, 1, -1                             ! integrate from the bottom the hor. divergence
+             ! - ML - need 3 lines here because replacement of fse3t by its expression yields too long lines otherwise
+             wsd3d(:,:,jk) = wsd3d(:,:,jk+1) -   fse3t_n(:,:,jk) * hdivn(:,:,jk)        &
+                &                      - ( fse3t_a(:,:,jk) - fse3t_b(:,:,jk) )    &
+                &                         * tmask(:,:,jk) * z1_2dt
+#if defined key_bdy
+             wsd3d(:,:,jk) = wsd3d(:,:,jk) * bdytmask(:,:)
+#endif
+          END DO
+          hdivn(:,:,:)=hdivdummy(:,:,:)
+          rotn(:,:,:)=rotdummy(:,:,:)
+          vn(:,:,:)=vdummy(:,:,:)
+          un(:,:,:)=udummy(:,:,:)
+          CALL wrk_dealloc( jpi,jpj,jpk,udummy,vdummy,hdivdummy,rotdummy)
+      ENDIF
    END SUBROUTINE sbc_wave
       
Index: branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/TRA/traadv_muscl.F90
===================================================================
--- branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/TRA/traadv_muscl.F90	(revision 3664)
+++ branches/2012/dev_LOCEAN_UKMO_CMCC_INGV_2012/NEMOGCM/NEMO/OPA_SRC/TRA/traadv_muscl.F90	(revision 3666)
@@ -8,4 +8,5 @@
    !!   NEMO     1.0  !  2002-06  (G. Madec)  F90: Free form and module
    !!            3.2  !  2010-05  (C. Ethe, G. Madec)  merge TRC-TRA + switch from velocity to transport
+   !!            3.4  !  2012-06  (P. Oddo) include the upstream where needed
    !!----------------------------------------------------------------------
 
@@ -18,7 +19,9 @@
    USE trdmod_oce      ! tracers trends 
    USE trdtra      ! tracers trends 
+   USE eosbn2          ! equation of state 
    USE in_out_manager  ! I/O manager
    USE dynspg_oce      ! choice/control of key cpp for surface pressure gradient
    USE trabbl          ! tracers: bottom boundary layer
+   USE sbcrnf          ! river runoffs
    USE lib_mpp         ! distribued memory computing
    USE lbclnk          ! ocean lateral boundary condition (or mpp link) 
@@ -27,4 +30,6 @@
    USE wrk_nemo        ! Memory Allocation
    USE timing          ! Timing
+   USE eosbn2          ! equation of state
+   USE sbcrnf          ! river runoffs
 
    IMPLICIT NONE
@@ -35,4 +40,6 @@
    LOGICAL  :: l_trd       ! flag to compute trends
 
+   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: upsmsk !: mixed upstream/centered scheme near some straits
+   !                                                             !  and in closed seas (orca 2 and 4 configurations)
    !! * Substitutions
 #  include "domzgr_substitute.h90"
@@ -78,4 +85,8 @@
       REAL(wp) ::   ztra, zbtr, zdt, zalpha   !   -      -
       REAL(wp), POINTER, DIMENSION(:,:,:) :: zslpx, zslpy
+      INTEGER  ::   ierr
+      REAL(wp) ::   zice                             ! temporary scalars
+      REAL(wp), POINTER, DIMENSION(:,:  ) :: ztfreez
+      REAL(wp), POINTER, DIMENSION(:,:,:) :: zind
       !!----------------------------------------------------------------------
       !
@@ -83,4 +94,6 @@
       !
       CALL wrk_alloc( jpi, jpj, jpk, zslpx, zslpy )
+      CALL wrk_alloc( jpi, jpj, ztfreez )
+      CALL wrk_alloc( jpi, jpj, jpk, zind )
       !
 
@@ -89,4 +102,13 @@
          IF(lwp) WRITE(numout,*) 'tra_adv : MUSCL advection scheme on ', cdtype
          IF(lwp) WRITE(numout,*) '~~~~~~~'
+         IF(lwp) WRITE(numout,*)
+         !
+         !
+         IF (.not. ALLOCATED(upsmsk))THEN
+             ALLOCATE( upsmsk(jpi,jpj), STAT=ierr )
+             IF( ierr /= 0 )   CALL ctl_stop('STOP', 'tra_adv_muscl: unable to allocate array')
+         ENDIF
+         !
+         upsmsk(:,:) = 0._wp                             ! not upstream by default
          !
          l_trd = .FALSE.
@@ -94,4 +116,24 @@
       ENDIF
 
+      !
+      ! Upstream / centered scheme indicator
+      ! ------------------------------------
+      ztfreez(:,:) = tfreez( tsn(:,:,1,jp_sal) )
+      DO jk = 1, jpk
+         DO jj = 1, jpj
+            DO ji = 1, jpi
+               !                                        ! below ice covered area (if tn < "freezing"+0.1 )
+               IF( tsn(ji,jj,jk,jp_tem) <= ztfreez(ji,jj) + 0.1_wp ) THEN   ;   zice = 1.e0
+               ELSE                                                         ;   zice = 0.e0
+               ENDIF
+               zind(ji,jj,jk) = MAX (   &
+                  rnfmsk(ji,jj) * rnfmsk_z(jk),      &  ! near runoff mouths (& closed sea outflows)
+                  upsmsk(ji,jj)               ,      &  ! some of some straits
+                  zice                               &  ! below ice covered area (if tn < "freezing"+0.1 )
+                  &                  ) * tmask(ji,jj,jk)
+               zind(ji,jj,jk) = 1 - zind(ji,jj,jk)
+            END DO
+         END DO
+      END DO
       !                                                     ! ===========
       DO jn = 1, kjpt                                       ! tracer loop
@@ -148,6 +190,6 @@
                   zalpha = 0.5 - z0u
                   zu  = z0u - 0.5 * pun(ji,jj,jk) * zdt / ( e1u(ji,jj) * e2u(ji,jj) * fse3u(ji,jj,jk) )
-                  zzwx = ptb(ji+1,jj,jk,jn) + zu * zslpx(ji+1,jj,jk)
-                  zzwy = ptb(ji  ,jj,jk,jn) + zu * zslpx(ji  ,jj,jk)
+                  zzwx = ptb(ji+1,jj,jk,jn) + zind(ji,jj,jk) * (zu * zslpx(ji+1,jj,jk))
+                  zzwy = ptb(ji  ,jj,jk,jn) + zind(ji,jj,jk) * (zu * zslpx(ji  ,jj,jk))
                   zwx(ji,jj,jk) = pun(ji,jj,jk) * ( zalpha * zzwx + (1.-zalpha) * zzwy )
                   !
@@ -155,6 +197,6 @@
                   zalpha = 0.5 - z0v
                   zv  = z0v - 0.5 * pvn(ji,jj,jk) * zdt / ( e1v(ji,jj) * e2v(ji,jj) * fse3v(ji,jj,jk) )
-                  zzwx = ptb(ji,jj+1,jk,jn) + zv * zslpy(ji,jj+1,jk)
-                  zzwy = ptb(ji,jj  ,jk,jn) + zv * zslpy(ji,jj  ,jk) 
+                  zzwx = ptb(ji,jj+1,jk,jn) + zind(ji,jj,jk) * (zv * zslpy(ji,jj+1,jk))
+                  zzwy = ptb(ji,jj  ,jk,jn) + zind(ji,jj,jk) * (zv * zslpy(ji,jj  ,jk))
                   zwy(ji,jj,jk) = pvn(ji,jj,jk) * ( zalpha * zzwx + (1.-zalpha) * zzwy )
                END DO
@@ -230,6 +272,6 @@
                   zalpha = 0.5 + z0w
                   zw  = z0w - 0.5 * pwn(ji,jj,jk+1) * zdt * zbtr 
-                  zzwx = ptb(ji,jj,jk+1,jn) + zw * zslpx(ji,jj,jk+1)
-                  zzwy = ptb(ji,jj,jk  ,jn) + zw * zslpx(ji,jj,jk  )
+                  zzwx = ptb(ji,jj,jk+1,jn) + zind(ji,jj,jk) * (zw * zslpx(ji,jj,jk+1))
+                  zzwy = ptb(ji,jj,jk  ,jn) + zind(ji,jj,jk) * (zw * zslpx(ji,jj,jk  ))
                   zwx(ji,jj,jk+1) = pwn(ji,jj,jk+1) * ( zalpha * zzwx + (1.-zalpha) * zzwy )
                END DO 
@@ -255,4 +297,6 @@
       !
       CALL wrk_dealloc( jpi, jpj, jpk, zslpx, zslpy )
+      CALL wrk_dealloc( jpi, jpj, ztfreez )
+      CALL wrk_dealloc( jpi, jpj, jpk, zind )
       !
       IF( nn_timing == 1 )  CALL timing_stop('tra_adv_muscl')
