Index: branches/2016/dev_r6522_SIMPLIF_3/NEMOGCM/NEMO/OPA_SRC/BDY/bdylib.F90
===================================================================
--- branches/2016/dev_r6522_SIMPLIF_3/NEMOGCM/NEMO/OPA_SRC/BDY/bdylib.F90	(revision 6884)
+++ branches/2016/dev_r6522_SIMPLIF_3/NEMOGCM/NEMO/OPA_SRC/BDY/bdylib.F90	(revision 7058)
@@ -5,4 +5,5 @@
    !!======================================================================
    !! History :  3.6  !  2013     (D. Storkey) original code
+   !!            4.0  !  2014     (T. Lovato) Generalize OBC structure
    !!----------------------------------------------------------------------
    !!----------------------------------------------------------------------
@@ -22,13 +23,150 @@
    PRIVATE
 
-   PUBLIC   bdy_orlanski_2d     ! routine called where?
-   PUBLIC   bdy_orlanski_3d     ! routine called where?
+   PUBLIC   bdy_frs, bdy_spe, bdy_nmn, bdy_orl
+   PUBLIC   bdy_orlanski_2d
+   PUBLIC   bdy_orlanski_3d
 
    !!----------------------------------------------------------------------
-   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
+   !! NEMO/OPA 4.0 , NEMO Consortium (2016)
    !! $Id$ 
    !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
    !!----------------------------------------------------------------------
 CONTAINS
+
+   SUBROUTINE bdy_frs( idx, pta, dta )
+      !!----------------------------------------------------------------------
+      !!                 ***  SUBROUTINE bdy_frs  ***
+      !!
+      !! ** Purpose : Apply the Flow Relaxation Scheme for tracers at open boundaries.
+      !!
+      !! Reference : Engedahl H., 1995, Tellus, 365-382.
+      !!----------------------------------------------------------------------
+      TYPE(OBC_INDEX),                     INTENT(in) ::   idx  ! OBC indices
+      REAL(wp), DIMENSION(:,:),            INTENT(in) ::   dta  ! OBC external data
+      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   pta  ! tracer trend
+      !!
+      REAL(wp) ::   zwgt           ! boundary weight
+      INTEGER  ::   ib, ik, igrd   ! dummy loop indices
+      INTEGER  ::   ii, ij         ! 2D addresses
+      !!----------------------------------------------------------------------
+      !
+      IF( nn_timing == 1 ) CALL timing_start('bdy_frs')
+      ! 
+      igrd = 1                       ! Everything is at T-points here
+      DO ib = 1, idx%nblen(igrd)
+         DO ik = 1, jpkm1
+            ii = idx%nbi(ib,igrd) 
+            ij = idx%nbj(ib,igrd)
+            zwgt = idx%nbw(ib,igrd)
+            pta(ii,ij,ik) = ( pta(ii,ij,ik) + zwgt * (dta(ib,ik) - pta(ii,ij,ik) ) ) * tmask(ii,ij,ik)
+         END DO
+      END DO
+      !
+      IF( nn_timing == 1 ) CALL timing_stop('bdy_frs')
+      !
+   END SUBROUTINE bdy_frs
+
+   SUBROUTINE bdy_spe( idx, pta, dta )
+      !!----------------------------------------------------------------------
+      !!                 ***  SUBROUTINE bdy_spe  ***
+      !!
+      !! ** Purpose : Apply a specified value for tracers at open boundaries.
+      !!
+      !!----------------------------------------------------------------------
+      TYPE(OBC_INDEX),                     INTENT(in) ::   idx  ! OBC indices
+      REAL(wp), DIMENSION(:,:),            INTENT(in) ::   dta  ! OBC external data
+      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   pta  ! tracer trend
+      !!
+      REAL(wp) ::   zwgt           ! boundary weight
+      INTEGER  ::   ib, ik, igrd   ! dummy loop indices
+      INTEGER  ::   ii, ij         ! 2D addresses
+      !!----------------------------------------------------------------------
+      !
+      IF( nn_timing == 1 ) CALL timing_start('bdy_spe')
+      !
+      igrd = 1                       ! Everything is at T-points here
+      DO ib = 1, idx%nblenrim(igrd)
+         ii = idx%nbi(ib,igrd)
+         ij = idx%nbj(ib,igrd)
+         DO ik = 1, jpkm1
+            pta(ii,ij,ik) = dta(ib,ik) * tmask(ii,ij,ik)
+         END DO
+      END DO
+      !
+      IF( nn_timing == 1 ) CALL timing_stop('bdy_spe')
+      !
+   END SUBROUTINE bdy_spe
+
+   SUBROUTINE bdy_nmn( idx, pta )
+      !!----------------------------------------------------------------------
+      !!                 ***  SUBROUTINE bdy_nmn  ***
+      !!
+      !! ** Purpose : Duplicate the value for tracers at open boundaries.
+      !!
+      !!----------------------------------------------------------------------
+      TYPE(OBC_INDEX),                     INTENT(in) ::   idx  ! OBC indices
+      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   pta  ! tracer trend
+      !!
+      REAL(wp) ::   zwgt           ! boundary weight
+      INTEGER  ::   ib, ik, igrd   ! dummy loop indices
+      INTEGER  ::   ii, ij, zcoef, zcoef1, zcoef2, ip, jp   ! 2D addresses
+      !!----------------------------------------------------------------------
+      !
+      IF( nn_timing == 1 ) CALL timing_start('bdy_nmn')
+      !
+      igrd = 1                       ! Everything is at T-points here
+      DO ib = 1, idx%nblenrim(igrd)
+         ii = idx%nbi(ib,igrd)
+         ij = idx%nbj(ib,igrd)
+         DO ik = 1, jpkm1
+            ! search the sense of the gradient
+            zcoef1 = bdytmask(ii-1,ij  ) +  bdytmask(ii+1,ij  )
+            zcoef2 = bdytmask(ii  ,ij-1) +  bdytmask(ii  ,ij+1)
+            IF ( zcoef1+zcoef2 == 0) THEN
+               ! corner
+               zcoef = tmask(ii-1,ij,ik) + tmask(ii+1,ij,ik) +  tmask(ii,ij-1,ik) +  tmask(ii,ij+1,ik)
+               pta(ii,ij,ik) = pta(ii-1,ij  ,ik) * tmask(ii-1,ij  ,ik) + &
+                 &             pta(ii+1,ij  ,ik) * tmask(ii+1,ij  ,ik) + &
+                 &             pta(ii  ,ij-1,ik) * tmask(ii  ,ij-1,ik) + &
+                 &             pta(ii  ,ij+1,ik) * tmask(ii  ,ij+1,ik)
+               pta(ii,ij,ik) = ( pta(ii,ij,ik) / MAX( 1, zcoef) ) * tmask(ii,ij,ik)
+            ELSE
+               ip = bdytmask(ii+1,ij  ) - bdytmask(ii-1,ij  )
+               jp = bdytmask(ii  ,ij+1) - bdytmask(ii  ,ij-1)
+               pta(ii,ij,ik) = pta(ii+ip,ij+jp,ik) * tmask(ii+ip,ij+jp,ik)
+            ENDIF
+         END DO
+      END DO
+      !
+      IF( nn_timing == 1 ) CALL timing_stop('bdy_nmn')
+      !
+   END SUBROUTINE bdy_nmn
+
+   SUBROUTINE bdy_orl( idx, ptb, pta, dta, ll_npo )
+      !!----------------------------------------------------------------------
+      !!                 ***  SUBROUTINE bdy_orl  ***
+      !!
+      !! ** Purpose : Apply Orlanski radiation for tracers at open boundaries.
+      !!              This is a wrapper routine for bdy_orlanski_3d below
+      !!
+      !!----------------------------------------------------------------------
+      TYPE(OBC_INDEX),                     INTENT(in) ::   idx  ! OBC indices
+      REAL(wp), DIMENSION(:,:),            INTENT(in) ::   dta  ! OBC external data
+      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   ptb  ! before tracer field
+      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   pta  ! tracer trend
+      LOGICAL,                             INTENT(in) ::   ll_npo  ! switch for NPO version
+      !!
+      INTEGER  ::   igrd                                    ! grid index
+      !!----------------------------------------------------------------------
+      !
+      IF( nn_timing == 1 ) CALL timing_start('bdy_orl')
+      !
+      igrd = 1                       ! Everything is at T-points here
+      !
+      CALL bdy_orlanski_3d( idx, igrd, ptb(:,:,:), pta(:,:,:), dta, ll_npo )
+      !
+      IF( nn_timing == 1 ) CALL timing_stop('bdy_orl')
+      !
+   END SUBROUTINE bdy_orl
 
    SUBROUTINE bdy_orlanski_2d( idx, igrd, phib, phia, phi_ext, ll_npo )
Index: branches/2016/dev_r6522_SIMPLIF_3/NEMOGCM/NEMO/OPA_SRC/BDY/bdytra.F90
===================================================================
--- branches/2016/dev_r6522_SIMPLIF_3/NEMOGCM/NEMO/OPA_SRC/BDY/bdytra.F90	(revision 6884)
+++ branches/2016/dev_r6522_SIMPLIF_3/NEMOGCM/NEMO/OPA_SRC/BDY/bdytra.F90	(revision 7058)
@@ -8,7 +8,7 @@
    !!            3.4  !  2011     (D. Storkey) rewrite in preparation for OBC-BDY merge
    !!            3.5  !  2012     (S. Mocavero, I. Epicoco) Optimization of BDY communications
+   !!            4.0  !  2016     (T. Lovato) Generalize OBC structure
    !!----------------------------------------------------------------------
-   !!   bdy_tra            : Apply open boundary conditions to T and S
-   !!   bdy_tra_frs        : Apply Flow Relaxation Scheme
+   !!   bdy_tra       : Apply open boundary conditions & damping to T and S
    !!----------------------------------------------------------------------
    USE oce            ! ocean dynamics and tracers variables
@@ -16,5 +16,4 @@
    USE bdy_oce        ! ocean open boundary conditions
    USE bdylib         ! for orlanski library routines
-   USE bdydta   , ONLY:   bf   ! 
    !
    USE in_out_manager ! I/O manager
@@ -25,9 +24,14 @@
    PRIVATE
 
+   ! Local structure to rearrange tracers data
+   TYPE, PUBLIC ::   ztrabdy
+      REAL(wp), POINTER, DIMENSION(:,:) ::  tra
+   END TYPE
+
    PUBLIC   bdy_tra      ! called in tranxt.F90 
    PUBLIC   bdy_tra_dmp  ! called in step.F90 
 
    !!----------------------------------------------------------------------
-   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
+   !! NEMO/OPA 4.0, NEMO Consortium (2016)
    !! $Id$ 
    !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
@@ -44,198 +48,45 @@
       INTEGER, INTENT(in) ::   kt   ! Main time step counter
       !
-      INTEGER ::   ib_bdy   ! Loop index
+      INTEGER                        :: ib_bdy, jn   ! Loop indeces
+      TYPE(ztrabdy), DIMENSION(jpts) :: zdta         ! Temporary data structure
       !!----------------------------------------------------------------------
 
       DO ib_bdy=1, nb_bdy
          !
-         SELECT CASE( cn_tra(ib_bdy) )
-         CASE('none'        )   ;   CYCLE
-         CASE('frs'         )   ;   CALL bdy_tra_frs     ( idx_bdy(ib_bdy), dta_bdy(ib_bdy), kt )
-         CASE('specified'   )   ;   CALL bdy_tra_spe     ( idx_bdy(ib_bdy), dta_bdy(ib_bdy), kt )
-         CASE('neumann'     )   ;   CALL bdy_tra_nmn     ( idx_bdy(ib_bdy), dta_bdy(ib_bdy), kt )
-         CASE('orlanski'    )   ;   CALL bdy_tra_orlanski( idx_bdy(ib_bdy), dta_bdy(ib_bdy), ll_npo=.false. )
-         CASE('orlanski_npo')   ;   CALL bdy_tra_orlanski( idx_bdy(ib_bdy), dta_bdy(ib_bdy), ll_npo=.true. )
-         CASE('runoff'      )   ;   CALL bdy_tra_rnf     ( idx_bdy(ib_bdy), dta_bdy(ib_bdy), kt )
-         CASE DEFAULT           ;   CALL ctl_stop( 'bdy_tra : unrecognised option for open boundaries for T and S' )
-         END SELECT
-         ! Boundary points should be updated
-         CALL lbc_bdy_lnk( tsa(:,:,:,jp_tem), 'T', 1., ib_bdy )
-         CALL lbc_bdy_lnk( tsa(:,:,:,jp_sal), 'T', 1., ib_bdy )
+         zdta(1)%tra => dta_bdy(ib_bdy)%tem
+         zdta(2)%tra => dta_bdy(ib_bdy)%sal
+         !
+         DO jn = 1, jpts
+            !
+            SELECT CASE( cn_tra(ib_bdy) )
+            CASE('none'        )   ;   CYCLE
+            CASE('frs'         )   ;   CALL bdy_frs ( idx_bdy(ib_bdy),                tsa(:,:,:,jn), zdta(jn)%tra )
+            CASE('specified'   )   ;   CALL bdy_spe ( idx_bdy(ib_bdy),                tsa(:,:,:,jn), zdta(jn)%tra )
+            CASE('neumann'     )   ;   CALL bdy_nmn ( idx_bdy(ib_bdy),                tsa(:,:,:,jn)               )
+            CASE('orlanski'    )   ;   CALL bdy_orl ( idx_bdy(ib_bdy), tsb(:,:,:,jn), tsa(:,:,:,jn), zdta(jn)%tra, ll_npo=.false. )
+            CASE('orlanski_npo')   ;   CALL bdy_orl ( idx_bdy(ib_bdy), tsb(:,:,:,jn), tsa(:,:,:,jn), zdta(jn)%tra, ll_npo=.true. )
+            CASE('runoff'      )   ;   CALL bdy_rnf ( idx_bdy(ib_bdy),                tsa(:,:,:,jn),               jn )
+            CASE DEFAULT           ;   CALL ctl_stop( 'bdy_tra : unrecognised option for open boundaries for T and S' )
+            END SELECT
+            ! Boundary points should be updated
+            CALL lbc_bdy_lnk( tsa(:,:,:,jn), 'T', 1., ib_bdy )
+            ! 
+         END DO
       END DO
       !
    END SUBROUTINE bdy_tra
 
-
-   SUBROUTINE bdy_tra_frs( idx, dta, kt )
+   SUBROUTINE bdy_rnf( idx, pta, jpa )
       !!----------------------------------------------------------------------
-      !!                 ***  SUBROUTINE bdy_tra_frs  ***
+      !!                 ***  SUBROUTINE bdy_rnf  ***
       !!                    
-      !! ** Purpose : Apply the Flow Relaxation Scheme for tracers at open boundaries.
-      !! 
-      !! Reference : Engedahl H., 1995, Tellus, 365-382.
-      !!----------------------------------------------------------------------
-      INTEGER,         INTENT(in) ::   kt    !
-      TYPE(OBC_INDEX), INTENT(in) ::   idx   ! OBC indices
-      TYPE(OBC_DATA),  INTENT(in) ::   dta   ! OBC external data
-      !
-      REAL(wp) ::   zwgt           ! boundary weight
-      INTEGER  ::   ib, ik, igrd   ! dummy loop indices
-      INTEGER  ::   ii, ij         ! 2D addresses
-      !!----------------------------------------------------------------------
-      !
-      IF( nn_timing == 1 )   CALL timing_start('bdy_tra_frs')
-      !
-      igrd = 1                       ! Everything is at T-points here
-      DO ib = 1, idx%nblen(igrd)
-         DO ik = 1, jpkm1
-            ii = idx%nbi(ib,igrd)
-            ij = idx%nbj(ib,igrd)
-            zwgt = idx%nbw(ib,igrd)
-            tsa(ii,ij,ik,jp_tem) = ( tsa(ii,ij,ik,jp_tem) + zwgt * ( dta%tem(ib,ik) - tsa(ii,ij,ik,jp_tem) ) ) * tmask(ii,ij,ik)         
-            tsa(ii,ij,ik,jp_sal) = ( tsa(ii,ij,ik,jp_sal) + zwgt * ( dta%sal(ib,ik) - tsa(ii,ij,ik,jp_sal) ) ) * tmask(ii,ij,ik)
-         END DO
-      END DO 
-      !
-      IF( kt .eq. nit000 )   CLOSE( unit = 102 )
-      !
-      IF( nn_timing == 1 )   CALL timing_stop('bdy_tra_frs')
-      !
-   END SUBROUTINE bdy_tra_frs
-
-
-   SUBROUTINE bdy_tra_spe( idx, dta, kt )
-      !!----------------------------------------------------------------------
-      !!                 ***  SUBROUTINE bdy_tra_frs  ***
-      !!                    
-      !! ** Purpose : Apply a specified value for tracers at open boundaries.
+      !! ** Purpose : Specialized routine to apply TRA runoff values at OBs:
+      !!                  - duplicate the neighbour value for the temperature
+      !!                  - specified to 0.1 PSU for the salinity
       !! 
       !!----------------------------------------------------------------------
-      INTEGER,         INTENT(in) ::   kt    !
-      TYPE(OBC_INDEX), INTENT(in) ::   idx   ! OBC indices
-      TYPE(OBC_DATA),  INTENT(in) ::   dta   ! OBC external data
-      !
-      REAL(wp) ::   zwgt           ! boundary weight
-      INTEGER  ::   ib, ik, igrd   ! dummy loop indices
-      INTEGER  ::   ii, ij         ! 2D addresses
-      !!----------------------------------------------------------------------
-      !
-      IF( nn_timing == 1 ) CALL timing_start('bdy_tra_spe')
-      !
-      igrd = 1                       ! Everything is at T-points here
-      DO ib = 1, idx%nblenrim(igrd)
-         ii = idx%nbi(ib,igrd)
-         ij = idx%nbj(ib,igrd)
-         DO ik = 1, jpkm1
-            tsa(ii,ij,ik,jp_tem) = dta%tem(ib,ik) * tmask(ii,ij,ik)
-            tsa(ii,ij,ik,jp_sal) = dta%sal(ib,ik) * tmask(ii,ij,ik)
-         END DO
-      END DO
-      !
-      IF( kt == nit000 )   CLOSE( unit = 102 )
-      !
-      IF( nn_timing == 1 )   CALL timing_stop('bdy_tra_spe')
-      !
-   END SUBROUTINE bdy_tra_spe
-
-
-   SUBROUTINE bdy_tra_nmn( idx, dta, kt )
-      !!----------------------------------------------------------------------
-      !!                 ***  SUBROUTINE bdy_tra_nmn  ***
-      !!                    
-      !! ** Purpose : Duplicate the value for tracers at open boundaries.
-      !! 
-      !!----------------------------------------------------------------------
-      INTEGER,         INTENT(in) ::   kt    ! 
-      TYPE(OBC_INDEX), INTENT(in) ::   idx   ! OBC indices
-      TYPE(OBC_DATA) , INTENT(in) ::   dta   ! OBC external data
-      !
-      REAL(wp) ::   zwgt           ! boundary weight
-      INTEGER  ::   ib, ik, igrd   ! dummy loop indices
-      INTEGER  ::   ii, ij,zcoef, zcoef1,zcoef2, ip, jp   ! 2D addresses
-      !!----------------------------------------------------------------------
-      !
-      IF( nn_timing == 1 )   CALL timing_start('bdy_tra_nmn')
-      !
-      igrd = 1                       ! Everything is at T-points here
-      DO ib = 1, idx%nblenrim(igrd)
-         ii = idx%nbi(ib,igrd)
-         ij = idx%nbj(ib,igrd)
-         DO ik = 1, jpkm1
-            ! search the sense of the gradient
-            zcoef1 = bdytmask(ii-1,ij  ) +  bdytmask(ii+1,ij  )
-            zcoef2 = bdytmask(ii  ,ij-1) +  bdytmask(ii  ,ij+1)
-            IF ( zcoef1+zcoef2 == 0) THEN
-               ! corner
-               zcoef = tmask(ii-1,ij,ik) + tmask(ii+1,ij,ik) +  tmask(ii,ij-1,ik) +  tmask(ii,ij+1,ik)
-               tsa(ii,ij,ik,jp_tem) = tsa(ii-1,ij  ,ik,jp_tem) * tmask(ii-1,ij  ,ik) + &
-                 &                    tsa(ii+1,ij  ,ik,jp_tem) * tmask(ii+1,ij  ,ik) + &
-                 &                    tsa(ii  ,ij-1,ik,jp_tem) * tmask(ii  ,ij-1,ik) + &
-                 &                    tsa(ii  ,ij+1,ik,jp_tem) * tmask(ii  ,ij+1,ik)
-               tsa(ii,ij,ik,jp_tem) = ( tsa(ii,ij,ik,jp_tem) / MAX( 1, zcoef) ) * tmask(ii,ij,ik)
-               tsa(ii,ij,ik,jp_sal) = tsa(ii-1,ij  ,ik,jp_sal) * tmask(ii-1,ij  ,ik) + &
-                 &                    tsa(ii+1,ij  ,ik,jp_sal) * tmask(ii+1,ij  ,ik) + &
-                 &                    tsa(ii  ,ij-1,ik,jp_sal) * tmask(ii  ,ij-1,ik) + &
-                 &                    tsa(ii  ,ij+1,ik,jp_sal) * tmask(ii  ,ij+1,ik)
-               tsa(ii,ij,ik,jp_sal) = ( tsa(ii,ij,ik,jp_sal) / MAX( 1, zcoef) ) * tmask(ii,ij,ik)
-            ELSE
-               ip = bdytmask(ii+1,ij  ) - bdytmask(ii-1,ij  )
-               jp = bdytmask(ii  ,ij+1) - bdytmask(ii  ,ij-1)
-               tsa(ii,ij,ik,jp_tem) = tsa(ii+ip,ij+jp,ik,jp_tem) * tmask(ii+ip,ij+jp,ik)
-               tsa(ii,ij,ik,jp_sal) = tsa(ii+ip,ij+jp,ik,jp_sal) * tmask(ii+ip,ij+jp,ik)
-            ENDIF
-         END DO
-      END DO
-      !
-      IF( kt == nit000 )   CLOSE( unit = 102 )
-      !
-      IF( nn_timing == 1 )   CALL timing_stop('bdy_tra_nmn')
-      !
-   END SUBROUTINE bdy_tra_nmn
- 
-
-   SUBROUTINE bdy_tra_orlanski( idx, dta, ll_npo )
-      !!----------------------------------------------------------------------
-      !!                 ***  SUBROUTINE bdy_tra_orlanski  ***
-      !!             
-      !!              - Apply Orlanski radiation to temperature and salinity. 
-      !!              - Wrapper routine for bdy_orlanski_3d
-      !! 
-      !!
-      !! References:  Marchesiello, McWilliams and Shchepetkin, Ocean Modelling vol. 3 (2001)    
-      !!----------------------------------------------------------------------
-      TYPE(OBC_INDEX), INTENT(in) ::   idx     ! OBC indices
-      TYPE(OBC_DATA) , INTENT(in) ::   dta     ! OBC external data
-      LOGICAL        , INTENT(in) ::   ll_npo  ! switch for NPO version
-      !
-      INTEGER  ::   igrd                                    ! grid index
-      !!----------------------------------------------------------------------
-      !
-      IF( nn_timing == 1 ) CALL timing_start('bdy_tra_orlanski')
-      !
-      igrd = 1      ! Orlanski bc on temperature; 
-      !            
-      CALL bdy_orlanski_3d( idx, igrd, tsb(:,:,:,jp_tem), tsa(:,:,:,jp_tem), dta%tem, ll_npo )
-
-      igrd = 1      ! Orlanski bc on salinity;
-      !  
-      CALL bdy_orlanski_3d( idx, igrd, tsb(:,:,:,jp_sal), tsa(:,:,:,jp_sal), dta%sal, ll_npo )
-      !
-      IF( nn_timing == 1 )   CALL timing_stop('bdy_tra_orlanski')
-      !
-   END SUBROUTINE bdy_tra_orlanski
-
-
-   SUBROUTINE bdy_tra_rnf( idx, dta, kt )
-      !!----------------------------------------------------------------------
-      !!                 ***  SUBROUTINE bdy_tra_rnf  ***
-      !!                    
-      !! ** Purpose : Apply the runoff values for tracers at open boundaries:
-      !!                  - specified to 0.1 PSU for the salinity
-      !!                  - duplicate the value for the temperature
-      !! 
-      !!----------------------------------------------------------------------
-      INTEGER        , INTENT(in) ::   kt    ! 
-      TYPE(OBC_INDEX), INTENT(in) ::   idx   ! OBC indices
-      TYPE(OBC_DATA) , INTENT(in) ::   dta   ! OBC external data
+      TYPE(OBC_INDEX),                     INTENT(in) ::   idx  ! OBC indices
+      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   pta  ! tracer trend
+      INTEGER,                             INTENT(in) ::   jpa  ! TRA index
       !
       REAL(wp) ::   zwgt           ! boundary weight
@@ -244,5 +95,5 @@
       !!----------------------------------------------------------------------
       !
-      IF( nn_timing == 1 )   CALL timing_start('bdy_tra_rnf')
+      IF( nn_timing == 1 )   CALL timing_start('bdy_rnf')
       !
       igrd = 1                       ! Everything is at T-points here
@@ -253,15 +104,12 @@
             ip = bdytmask(ii+1,ij  ) - bdytmask(ii-1,ij  )
             jp = bdytmask(ii  ,ij+1) - bdytmask(ii  ,ij-1)
-            tsa(ii,ij,ik,jp_tem) = tsa(ii+ip,ij+jp,ik,jp_tem) * tmask(ii,ij,ik)
-            tsa(ii,ij,ik,jp_sal) =                        0.1 * tmask(ii,ij,ik)
+            if (jpa == jp_tem) pta(ii,ij,ik) = pta(ii+ip,ij+jp,ik) * tmask(ii,ij,ik)
+            if (jpa == jp_sal) pta(ii,ij,ik) =                 0.1 * tmask(ii,ij,ik)
          END DO
       END DO
       !
-      IF( kt == nit000 )   CLOSE( unit = 102 )
+      IF( nn_timing == 1 )   CALL timing_stop('bdy_rnf')
       !
-      IF( nn_timing == 1 )   CALL timing_stop('bdy_tra_rnf')
-      !
-   END SUBROUTINE bdy_tra_rnf
-
+   END SUBROUTINE bdy_rnf
 
    SUBROUTINE bdy_tra_dmp( kt )
Index: branches/2016/dev_r6522_SIMPLIF_3/NEMOGCM/NEMO/OPA_SRC/ZDF/zdfric.F90
===================================================================
--- branches/2016/dev_r6522_SIMPLIF_3/NEMOGCM/NEMO/OPA_SRC/ZDF/zdfric.F90	(revision 6884)
+++ branches/2016/dev_r6522_SIMPLIF_3/NEMOGCM/NEMO/OPA_SRC/ZDF/zdfric.F90	(revision 7058)
@@ -202,5 +202,5 @@
          DO jj = 2, jpjm1
             DO ji = fs_2, fs_jpim1
-               IF( fsdept(ji,jj,jk) < ekm_dep(ji,jj) ) THEN
+               IF( gdept_n(ji,jj,jk) < ekm_dep(ji,jj) ) THEN
                   avmv(ji,jj,jk) = MAX( avmv(ji,jj,jk), rn_wvmix )
                   avmu(ji,jj,jk) = MAX( avmu(ji,jj,jk), rn_wvmix )
Index: branches/2016/dev_r6522_SIMPLIF_3/NEMOGCM/NEMO/TOP_SRC/trcbdy.F90
===================================================================
--- branches/2016/dev_r6522_SIMPLIF_3/NEMOGCM/NEMO/TOP_SRC/trcbdy.F90	(revision 6884)
+++ branches/2016/dev_r6522_SIMPLIF_3/NEMOGCM/NEMO/TOP_SRC/trcbdy.F90	(revision 7058)
@@ -9,9 +9,9 @@
    !!            3.5  !  2012     (S. Mocavero, I. Epicoco) Optimization of BDY communications
    !!            3.6  !  2015     (T. Lovato) Adapt BDY for tracers in TOP component
+   !!            4.0  !  2016     (T. Lovato) Generalize OBC structure
    !!----------------------------------------------------------------------
 #if defined key_top
    !!----------------------------------------------------------------------
-   !!   trc_bdy            : Apply open boundary conditions to T and S
-   !!   trc_bdy_frs        : Apply Flow Relaxation Scheme
+   !!   trc_bdy       : Apply open boundary conditions & damping to tracers
    !!----------------------------------------------------------------------
    USE timing                       ! Timing
@@ -22,8 +22,14 @@
    USE lbclnk                       ! ocean lateral boundary conditions (or mpp link)
    USE in_out_manager               ! I/O manager
-   USE bdy_oce, only: idx_bdy, OBC_INDEX, BDYTMASK, ln_bdy       ! ocean open boundary conditions
+   USE bdy_oce, only: idx_bdy       ! ocean open boundary conditions
 
    IMPLICIT NONE
    PRIVATE
+
+   ! Local structure to rearrange tracers data
+   TYPE, PUBLIC ::   ztrcbdy
+      REAL(wp), POINTER, DIMENSION(:,:) ::  trc
+      REAL(wp), POINTER                 ::  fac
+   END TYPE
 
    PUBLIC trc_bdy      ! routine called in trcnxt.F90 
@@ -31,5 +37,5 @@
 
    !!----------------------------------------------------------------------
-   !! NEMO/OPA 3.6 , NEMO Consortium (2015)
+   !! NEMO/OPA 4.0 , NEMO Consortium (2016)
    !! $Id$ 
    !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
@@ -41,6 +47,5 @@
       !!                  ***  SUBROUTINE trc_bdy  ***
       !!
-      !! ** Purpose : - Apply open boundary conditions for tracers in TOP component
-      !!                and scale the tracer data
+      !! ** Purpose : - Apply open boundary conditions for TOP tracers
       !!
       !!----------------------------------------------------------------------
@@ -48,187 +53,33 @@
       !!
       INTEGER               :: ib_bdy, jn ! Loop indeces
+      TYPE(ztrcbdy)         :: zdta       ! Temporary data structure
       !!----------------------------------------------------------------------
       !
       IF( nn_timing == 1 ) CALL timing_start('trc_bdy')
       !
-      DO jn = 1, jptra
-         DO ib_bdy=1, nb_bdy
-
-            SELECT CASE( trcdta_bdy(jn,ib_bdy)%cn_obc )
-            CASE('none')
-               CYCLE
-            CASE('frs')
-               CALL bdy_trc_frs( jn, idx_bdy(ib_bdy), trcdta_bdy(jn,ib_bdy), kt )
-            CASE('specified')
-               CALL bdy_trc_spe( jn, idx_bdy(ib_bdy), trcdta_bdy(jn,ib_bdy), kt )
-            CASE('neumann')
-               CALL bdy_trc_nmn( jn, idx_bdy(ib_bdy), trcdta_bdy(jn,ib_bdy), kt )
-            CASE('orlanski')
-               CALL bdy_trc_orlanski( jn, idx_bdy(ib_bdy), trcdta_bdy(jn,ib_bdy), ll_npo=.false. )
-            CASE('orlanski_npo')
-               CALL bdy_trc_orlanski( jn, idx_bdy(ib_bdy), trcdta_bdy(jn,ib_bdy), ll_npo=.true. )
-            CASE DEFAULT
-               CALL ctl_stop( 'trc_bdy : unrecognised option for open boundaries for passive tracers' )
+      DO ib_bdy=1, nb_bdy
+         DO jn = 1, jptra
+            !
+            zdta%trc => trcdta_bdy(jn,ib_bdy)%trc 
+            zdta%fac => trcdta_bdy(jn,ib_bdy)%rn_fac
+            !
+            SELECT CASE( TRIM(trcdta_bdy(jn,ib_bdy)%cn_obc) )
+            CASE('none'        )   ;   CYCLE
+            CASE('frs'         )   ;   CALL bdy_frs( idx_bdy(ib_bdy),                tra(:,:,:,jn), zdta%trc*zdta%fac )
+            CASE('specified'   )   ;   CALL bdy_spe( idx_bdy(ib_bdy),                tra(:,:,:,jn), zdta%trc*zdta%fac )
+            CASE('neumann'     )   ;   CALL bdy_nmn( idx_bdy(ib_bdy),                tra(:,:,:,jn) )
+            CASE('orlanski'    )   ;   CALL bdy_orl( idx_bdy(ib_bdy), trb(:,:,:,jn), tra(:,:,:,jn), zdta%trc*zdta%fac, ll_npo=.false. )
+            CASE('orlanski_npo')   ;   CALL bdy_orl( idx_bdy(ib_bdy), trb(:,:,:,jn), tra(:,:,:,jn), zdta%trc*zdta%fac, ll_npo=.true. )
+            CASE DEFAULT           ;   CALL ctl_stop( 'trc_bdy : unrecognised option for open boundaries for passive tracers' )
             END SELECT
-
             ! Boundary points should be updated
             CALL lbc_bdy_lnk( tra(:,:,:,jn), 'T', 1., ib_bdy )
-
-         ENDDO
-      ENDDO
+            !
+         END DO
+      END DO
       !
       IF( nn_timing == 1 ) CALL timing_stop('trc_bdy')
 
    END SUBROUTINE trc_bdy
-
-   SUBROUTINE bdy_trc_frs( jn, idx, dta, kt )
-      !!----------------------------------------------------------------------
-      !!                 ***  SUBROUTINE bdy_trc_frs  ***
-      !!                    
-      !! ** Purpose : Apply the Flow Relaxation Scheme for tracers at open boundaries.
-      !! 
-      !! Reference : Engedahl H., 1995, Tellus, 365-382.
-      !!----------------------------------------------------------------------
-      INTEGER,         INTENT(in) ::   kt
-      INTEGER,         INTENT(in) ::   jn   ! Tracer index
-      TYPE(OBC_INDEX), INTENT(in) ::   idx  ! OBC indices
-      TYPE(OBC_DATA),  INTENT(in) ::   dta  ! OBC external data
-      !! 
-      REAL(wp) ::   zwgt           ! boundary weight
-      INTEGER  ::   ib, ik, igrd   ! dummy loop indices
-      INTEGER  ::   ii, ij         ! 2D addresses
-      !!----------------------------------------------------------------------
-      !
-      IF( nn_timing == 1 ) CALL timing_start('bdy_trc_frs')
-      ! 
-      igrd = 1                       ! Everything is at T-points here
-      DO ib = 1, idx%nblen(igrd)
-         DO ik = 1, jpkm1
-            ii = idx%nbi(ib,igrd)
-            ij = idx%nbj(ib,igrd)
-            zwgt = idx%nbw(ib,igrd)
-            tra(ii,ij,ik,jn) = ( tra(ii,ij,ik,jn) + zwgt * ( ( dta%trc(ib,ik) * dta%rn_fac)  & 
-                        &  - tra(ii,ij,ik,jn) ) ) * tmask(ii,ij,ik)
-         END DO
-      END DO 
-      !
-      IF( kt .eq. nit000 ) CLOSE( unit = 102 )
-      !
-      IF( nn_timing == 1 ) CALL timing_stop('bdy_trc_frs')
-      !
-   END SUBROUTINE bdy_trc_frs
-  
-   SUBROUTINE bdy_trc_spe( jn, idx, dta, kt )
-      !!----------------------------------------------------------------------
-      !!                 ***  SUBROUTINE bdy_trc_frs  ***
-      !!                    
-      !! ** Purpose : Apply a specified value for tracers at open boundaries.
-      !! 
-      !!----------------------------------------------------------------------
-      INTEGER,         INTENT(in) ::   kt
-      INTEGER,         INTENT(in) ::   jn   ! Tracer index
-      TYPE(OBC_INDEX), INTENT(in) ::   idx  ! OBC indices
-      TYPE(OBC_DATA),  INTENT(in) ::   dta  ! OBC external data
-      !! 
-      REAL(wp) ::   zwgt           ! boundary weight
-      INTEGER  ::   ib, ik, igrd   ! dummy loop indices
-      INTEGER  ::   ii, ij         ! 2D addresses
-      !!----------------------------------------------------------------------
-      !
-      IF( nn_timing == 1 ) CALL timing_start('bdy_trc_spe')
-      !
-      igrd = 1                       ! Everything is at T-points here
-      DO ib = 1, idx%nblenrim(igrd)
-         ii = idx%nbi(ib,igrd)
-         ij = idx%nbj(ib,igrd)
-         DO ik = 1, jpkm1
-            tra(ii,ij,ik,jn) = dta%trc(ib,ik) * dta%rn_fac * tmask(ii,ij,ik)
-         END DO
-      END DO
-      !
-      IF( kt .eq. nit000 ) CLOSE( unit = 102 )
-      !
-      IF( nn_timing == 1 ) CALL timing_stop('bdy_trc_spe')
-      !
-   END SUBROUTINE bdy_trc_spe
-
-   SUBROUTINE bdy_trc_nmn( jn, idx, dta, kt )
-      !!----------------------------------------------------------------------
-      !!                 ***  SUBROUTINE bdy_trc_nmn  ***
-      !!                    
-      !! ** Purpose : Duplicate the value for tracers at open boundaries.
-      !! 
-      !!----------------------------------------------------------------------
-      INTEGER,         INTENT(in) ::   kt
-      INTEGER,         INTENT(in) ::   jn   ! Tracer index
-      TYPE(OBC_INDEX), INTENT(in) ::   idx  ! OBC indices
-      TYPE(OBC_DATA),  INTENT(in) ::   dta  ! OBC external data
-      !! 
-      REAL(wp) ::   zwgt           ! boundary weight
-      INTEGER  ::   ib, ik, igrd   ! dummy loop indices
-      INTEGER  ::   ii, ij, zcoef, zcoef1, zcoef2, ip, jp   ! 2D addresses
-      !!----------------------------------------------------------------------
-      !
-      IF( nn_timing == 1 ) CALL timing_start('bdy_trc_nmn')
-      !
-      igrd = 1                       ! Everything is at T-points here
-      DO ib = 1, idx%nblenrim(igrd)
-         ii = idx%nbi(ib,igrd)
-         ij = idx%nbj(ib,igrd)
-         DO ik = 1, jpkm1
-            ! search the sense of the gradient
-            zcoef1 = bdytmask(ii-1,ij  ) +  bdytmask(ii+1,ij  )
-            zcoef2 = bdytmask(ii  ,ij-1) +  bdytmask(ii  ,ij+1)
-            IF ( zcoef1+zcoef2 == 0) THEN
-               ! corner
-               zcoef = tmask(ii-1,ij,ik) + tmask(ii+1,ij,ik) +  tmask(ii,ij-1,ik) +  tmask(ii,ij+1,ik)
-               tra(ii,ij,ik,jn) = tra(ii-1,ij  ,ik,jn) * tmask(ii-1,ij  ,ik) + &
-                 &                tra(ii+1,ij  ,ik,jn) * tmask(ii+1,ij  ,ik) + &
-                 &                tra(ii  ,ij-1,ik,jn) * tmask(ii  ,ij-1,ik) + &
-                 &                tra(ii  ,ij+1,ik,jn) * tmask(ii  ,ij+1,ik)
-               tra(ii,ij,ik,jn) = ( tra(ii,ij,ik,jn) / MAX( 1, zcoef) ) * tmask(ii,ij,ik)
-            ELSE
-               ip = bdytmask(ii+1,ij  ) - bdytmask(ii-1,ij  )
-               jp = bdytmask(ii  ,ij+1) - bdytmask(ii  ,ij-1)
-               tra(ii,ij,ik,jn) = tra(ii+ip,ij+jp,ik,jn) * tmask(ii+ip,ij+jp,ik)
-            ENDIF
-         END DO
-      END DO
-      !
-      IF( kt .eq. nit000 ) CLOSE( unit = 102 )
-      !
-      IF( nn_timing == 1 ) CALL timing_stop('bdy_trc_nmn')
-      !
-   END SUBROUTINE bdy_trc_nmn
- 
-
-   SUBROUTINE bdy_trc_orlanski( jn, idx, dta, ll_npo )
-      !!----------------------------------------------------------------------
-      !!                 ***  SUBROUTINE bdy_trc_orlanski  ***
-      !!             
-      !!              - Apply Orlanski radiation to tracers of TOP component. 
-      !!              - Wrapper routine for bdy_orlanski_3d
-      !! 
-      !!
-      !! References:  Marchesiello, McWilliams and Shchepetkin, Ocean Modelling vol. 3 (2001)    
-      !!----------------------------------------------------------------------
-      INTEGER,                      INTENT(in) ::   jn      ! Tracer index
-      TYPE(OBC_INDEX),              INTENT(in) ::   idx     ! OBC indices
-      TYPE(OBC_DATA),               INTENT(in) ::   dta     ! OBC external data
-      LOGICAL,                      INTENT(in) ::   ll_npo  ! switch for NPO version
-
-      INTEGER  ::   igrd                                    ! grid index
-      !!----------------------------------------------------------------------
-
-      IF( nn_timing == 1 ) CALL timing_start('bdy_trc_orlanski')
-      !
-      igrd = 1      ! Orlanski bc on tracers; 
-      !            
-      CALL bdy_orlanski_3d( idx, igrd, trb(:,:,:,jn), tra(:,:,:,jn), (dta%trc * dta%rn_fac), ll_npo )
-      !
-      IF( nn_timing == 1 ) CALL timing_stop('bdy_trc_orlanski')
-      !
-
-   END SUBROUTINE bdy_trc_orlanski
 
    SUBROUTINE trc_bdy_dmp( kt )
Index: branches/2016/dev_r6522_SIMPLIF_3/NEMOGCM/NEMO/TOP_SRC/trcsub.F90
===================================================================
--- branches/2016/dev_r6522_SIMPLIF_3/NEMOGCM/NEMO/TOP_SRC/trcsub.F90	(revision 6884)
+++ branches/2016/dev_r6522_SIMPLIF_3/NEMOGCM/NEMO/TOP_SRC/trcsub.F90	(revision 7058)
@@ -499,5 +499,6 @@
       z1_rau0 = 0.5 / rau0
       ssha(:,:) = (  sshb(:,:) - z2dt * ( z1_rau0 * ( emp_b(:,:) + emp(:,:) ) + zhdiv(:,:) )  ) * tmask(:,:,1)
-#if ! defined key_dynspg_ts
+
+      IF( .NOT.ln_dynspg_ts ) THEN
       ! These lines are not necessary with time splitting since
       ! boundary condition on sea level is set during ts loop
@@ -505,9 +506,9 @@
       CALL agrif_ssh( kt )
 #endif
-      IF( ln_bdy ) THEN
-         ssha(:,:) = ssha(:,:) * bdytmask(:,:)
-         CALL lbc_lnk( ssha, 'T', 1. ) 
-      ENDIF
-#endif
+         IF( ln_bdy ) THEN
+            ssha(:,:) = ssha(:,:) * bdytmask(:,:)
+            CALL lbc_lnk( ssha, 'T', 1. ) 
+         ENDIF
+      ENDIF
       !
       !                                           !------------------------------!
