New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
trabbl_adv.h90 in trunk/NEMO/OPA_SRC/TRA – NEMO

source: trunk/NEMO/OPA_SRC/TRA/trabbl_adv.h90 @ 480

Last change on this file since 480 was 474, checked in by opalod, 18 years ago

nemo_v1_update_061: SM: end of ctl_stop + mpi optimization in _bilap

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.6 KB
Line 
1   !!----------------------------------------------------------------------
2   !!                     ***  trabbl_adv.h90  ***
3   !!----------------------------------------------------------------------
4
5   !!----------------------------------------------------------------------
6   !!   OPA 9.0 , LOCEAN-IPSL (2005)
7   !! $Header$
8   !! This software is governed by the CeCILL licence see modipsl/doc/NEMO_CeCILL.txt
9   !!----------------------------------------------------------------------
10
11   SUBROUTINE tra_bbl_adv( kt )
12      !!----------------------------------------------------------------------
13      !!                  ***  ROUTINE tra_bbl_adv  ***
14      !!                   
15      !! ** Purpose :   Compute the before tracer (t & s) trend associated
16      !!     with the bottom boundary layer and add it to the general trend
17      !!     of tracer equations. The bottom boundary layer is supposed to be
18      !!     both an advective and diffusive bottom boundary layer.
19      !!
20      !! ** Method  :   Computes the bottom boundary horizontal and vertical
21      !!      advection terms. Add it to the general trend : ta =ta + adv_bbl.
22      !!        When the product grad( rho) * grad(h) < 0 (where grad is a
23      !!      along bottom slope gradient) an additional lateral 2nd order
24      !!      diffusion along the bottom slope is added to the general
25      !!      tracer trend, otherwise the additional trend is set to 0.
26      !!      Second order operator (laplacian type) with variable coefficient
27      !!      computed as follow for temperature (idem on s):
28      !!         difft = 1/(e1t*e2t*e3t) { di-1[ ahbt e2u*e3u/e1u di[ztb] ]
29      !!                                 + dj-1[ ahbt e1v*e3v/e2v dj[ztb] ] }
30      !!      where ztb is a 2D array: the bottom ocean te;perature and ahtb
31      !!      is a time and space varying diffusive coefficient defined by:
32      !!         ahbt = zahbp    if grad(rho).grad(h) < 0
33      !!              = 0.       otherwise.
34      !!      Note that grad(.) is the along bottom slope gradient. grad(rho)
35      !!      is evaluated using the local density (i.e. referenced at the
36      !!      local depth). Typical value of ahbt is 2000 m2/s (equivalent to
37      !!      a downslope velocity of 20 cm/s if the condition for slope
38      !!      convection is satified)
39      !!        Add this before trend to the general trend (ta,sa) of the
40      !!      botton ocean tracer point:
41      !!              ta = ta + difft
42      !!
43      !! ** Action  : - update (ta,sa) at the bottom level with the bottom
44      !!                boundary layer trend
45      !!              - save the lateral diffusion trends in tldfbbl/sldfbbl ('key_trdtra')
46      !!              - save the horizontal advection trends in tladbbl/sladbbl ('key_trdtra')
47      !!
48      !! References :
49      !!     Beckmann, A., and R. Doscher, 1997, J. Phys.Oceanogr., 581-591.
50      !!
51      !! History :
52      !!   8.5  !  02-12  (A. de Miranda, G. Madec)  Original Code
53      !!   9.0  !  04-01  (A. de Miranda, G. Madec, J.M. Molines )
54      !!   9.0  !  04-08  (C. Talandier) New trends organization
55      !!----------------------------------------------------------------------     
56      !! * Modules used
57      USE eosbn2
58      USE flxrnf
59      USE ocfzpt
60      USE lbclnk
61      USE oce, ONLY :    ztdta => ua,    & ! use ua as 3D workspace   
62                         ztdsa => va       ! use va as 3D workspace   
63
64      !! * Arguments
65      INTEGER, INTENT( in ) ::   kt        ! ocean time-step
66     
67      !! * Local declarations
68      INTEGER :: ji, jj, jk                ! dummy loop indices
69      INTEGER :: ik, iku, ikv              ! temporary integers
70
71      REAL(wp) ::   &
72         zsign, zt, zs, zh, zalbet,     &  ! temporary scalars
73         zgdrho, zbtr, zta, zsa            !    "         "
74      REAL(wp), DIMENSION(jpi,jpj) ::   &
75         ztnb, zsnb, zdep, ztbb, zsbb,  &  !    "                  "
76         zahu, zahv                        !    "                  "
77      REAL(wp), DIMENSION(jpi,jpj) ::   &  ! temporary workspace arrays
78         zalphax, zwu, zunb,            &  !    "                  "
79         zalphay, zwv, zvnb,            &  !    "                  "
80         zwx, zwy, zww, zwz                !    "                  "
81      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   &
82         zhdivn                            ! temporary workspace arrays
83      REAL(wp) ::   &
84         zfui, zfvj, zbt, zsigna           ! temporary scalars
85      REAL(wp) ::   &
86         fsalbt, pft, pfs, pfh             ! statement function
87      !!----------------------------------------------------------------------
88      ! ratio alpha/beta
89      ! ================
90      !  fsalbt: ratio of thermal over saline expension coefficients
91      !       pft :  potential temperature in degrees celcius
92      !       pfs :  salinity anomaly (s-35) in psu
93      !       pfh :  depth in meters
94
95      fsalbt( pft, pfs, pfh ) =                                              &
96         ( ( ( -0.255019e-07 * pft + 0.298357e-05 ) * pft                    &
97                                   - 0.203814e-03 ) * pft                    &
98                                   + 0.170907e-01 ) * pft                    &
99                                   + 0.665157e-01                            &
100         +(-0.678662e-05 * pfs - 0.846960e-04 * pft + 0.378110e-02 ) * pfs   &
101         +  ( ( - 0.302285e-13 * pfh                                         &
102                - 0.251520e-11 * pfs                                         &
103                + 0.512857e-12 * pft * pft          ) * pfh                  &
104                                     - 0.164759e-06   * pfs                  &
105             +(   0.791325e-08 * pft - 0.933746e-06 ) * pft                  &
106                                     + 0.380374e-04 ) * pfh
107      !!----------------------------------------------------------------------
108
109
110      IF( kt == nit000 )   CALL tra_bbl_init    ! initialization at first time-step
111
112      ! Save ta and sa trends
113      IF( l_trdtra )   THEN
114         ztdta(:,:,:) = ta(:,:,:)
115         ztdsa(:,:,:) = sa(:,:,:)
116      ENDIF
117
118      ! 1. 2D fields of bottom temperature and salinity, and bottom slope
119      ! -----------------------------------------------------------------
120      ! mbathy= number of w-level, minimum value=1 (cf dommsk.F)
121
122#if defined key_vectopt_loop   &&   ! defined key_mpp_omp
123      jj = 1
124      DO ji = 1, jpij   ! vector opt. (forced unrolling)
125#else
126      DO jj = 1, jpj
127         DO ji = 1, jpi
128#endif
129            ik = mbkt(ji,jj)                               ! index of the bottom ocean T-level
130            ztnb(ji,jj) = tn(ji,jj,ik) * tmask(ji,jj,1)    ! masked now T at the ocean bottom
131            zsnb(ji,jj) = sn(ji,jj,ik) * tmask(ji,jj,1)    ! masked now S at the ocean bottom
132            ztbb(ji,jj) = tb(ji,jj,ik) * tmask(ji,jj,1)    ! masked before T at the ocean bottom
133            zsbb(ji,jj) = sb(ji,jj,ik) * tmask(ji,jj,1)    ! masked before S at the ocean bottom
134            zdep(ji,jj) = fsdept(ji,jj,ik)                 ! depth of the ocean bottom T-level
135#if ! defined key_vectopt_loop   ||   defined key_mpp_omp
136         END DO
137#endif
138      END DO
139#if defined key_vectopt_loop   &&   ! defined key_mpp_omp
140      jj = 1
141      DO ji = 1, jpij-jpi   ! vector opt. (forced unrolling)
142            zunb(ji,jj) = un(ji,jj,mbku(ji,jj)) * umask(ji,jj,1)
143            zvnb(ji,jj) = vn(ji,jj,mbkv(ji,jj)) * vmask(ji,jj,1)   ! retirer le mask en u, v et t !
144      END DO
145#else
146      DO jj = 1, jpjm1
147         DO ji = 1, jpim1
148            zunb(ji,jj) = un(ji,jj,mbku(ji,jj)) * umask(ji,jj,1)
149            zvnb(ji,jj) = vn(ji,jj,mbkv(ji,jj)) * vmask(ji,jj,1)
150         END DO
151      END DO
152#endif
153 
154      ! boundary conditions on zunb and zvnb   (changed sign)
155       CALL lbc_lnk( zunb, 'U', -1. )   ;   CALL lbc_lnk( zvnb, 'V', -1. )
156      ! boundary condition on ztnb and znbb
157       CALL lbc_lnk( ztnb, 'T', 1. )    ;   CALL lbc_lnk( ztbb, 'T', 1. )
158      ! boundary condition on zsnb and zsbb
159       CALL lbc_lnk( zsnb, 'T', 1. )    ;   CALL lbc_lnk( zsbb, 'T', 1. )
160
161      ! 2. Criteria of additional bottom diffusivity: grad(rho).grad(h)<0
162      ! --------------------------------------------
163      ! Sign of the local density gradient along the i- and j-slopes
164      ! multiplied by the slope of the ocean bottom
165
166      SELECT CASE ( neos )
167
168      CASE ( 0 )               ! Jackett and McDougall (1994) formulation
169
170      DO jj = 1, jpjm1
171        DO ji = 1, fs_jpim1   ! vector opt.
172      !   ... temperature, salinity anomalie and depth
173          zt = 0.5 * ( ztnb(ji,jj) + ztnb(ji+1,jj) )
174          zs = 0.5 * ( zsnb(ji,jj) + zsnb(ji+1,jj) ) - 35.0
175          zh = 0.5 * ( zdep(ji,jj) + zdep(ji+1,jj) )
176      !   ... masked ratio alpha/beta
177          zalbet = fsalbt( zt, zs, zh )*umask(ji,jj,1)
178      !   ... local density gradient along i-bathymetric slope
179          zgdrho = zalbet*( ztnb(ji+1,jj) - ztnb(ji,jj) )   &
180                     -    ( zsnb(ji+1,jj) - zsnb(ji,jj) )
181          zgdrho = zgdrho * umask(ji,jj,1)
182      !   ... sign of local i-gradient of density multiplied by the i-slope
183          zsign = sign( 0.5, -zgdrho * ( zdep(ji+1,jj) - zdep(ji,jj) ) )
184
185          zsigna= sign(0.5, zunb(ji,jj)*(  zdep(ji+1,jj) - zdep(ji,jj) ))
186          zalphax(ji,jj)=(0.5+zsigna)*(0.5-zsign)*umask(ji,jj,1)
187        END DO
188      END DO
189
190      DO jj = 1, jpjm1
191        DO ji = 1, fs_jpim1   ! vector opt.
192      !   ... temperature, salinity anomalie and depth
193          zt = 0.5 * ( ztnb(ji,jj+1) + ztnb(ji,jj) )
194          zs = 0.5 * ( zsnb(ji,jj+1) + zsnb(ji,jj) ) - 35.0
195          zh = 0.5 * ( zdep(ji,jj+1) + zdep(ji,jj) )
196      !   ... masked ratio alpha/beta
197          zalbet = fsalbt( zt, zs, zh )*vmask(ji,jj,1)
198      !   ... local density gradient along j-bathymetric slope
199          zgdrho = zalbet*( ztnb(ji,jj+1) - ztnb(ji,jj) )   &
200                     -    ( zsnb(ji,jj+1) - zsnb(ji,jj) )
201          zgdrho = zgdrho*vmask(ji,jj,1)
202      !   ... sign of local j-gradient of density multiplied by the j-slope
203          zsign = sign( 0.5, -zgdrho * ( zdep(ji,jj+1) - zdep(ji,jj) ) )
204
205          zsigna= sign(0.5, zvnb(ji,jj)*(zdep(ji,jj+1) - zdep(ji,jj) ) )
206          zalphay(ji,jj)=(0.5+zsigna)*(0.5-zsign)*vmask(ji,jj,1)
207        END DO
208      END DO
209
210
211      CASE ( 1 )               ! Linear formulation function of temperature only
212                               !
213      DO jj = 1, jpjm1
214         DO ji = 1, jpim1
215            ! local 'density/temperature' gradient along i-bathymetric slope
216            zgdrho =  ztnb(ji+1,jj) - ztnb(ji,jj)
217            ! sign of local i-gradient of density multiplied by the i-slope
218            zsign = SIGN( 0.5, - zgdrho * ( zdep(ji+1,jj) - zdep(ji,jj) ) )
219
220            zsigna= sign(0.5, zunb(ji,jj)*(  zdep(ji+1,jj) - zdep(ji,jj) ))
221            zalphax(ji,jj)=(0.5+zsigna)*(0.5-zsign)*umask(ji,jj,1)
222         END DO
223      END DO
224
225      DO jj = 1, jpjm1
226         DO ji = 1, jpim1
227            ! local density gradient along j-bathymetric slope
228            zgdrho =  ztnb(ji,jj+1) - ztnb(ji,jj)
229            ! sign of local j-gradient of density multiplied by the j-slope
230            zsign = sign( 0.5, -zgdrho * ( zdep(ji,jj+1) - zdep(ji,jj) ) )
231
232            zsigna= sign(0.5, zvnb(ji,jj)*(zdep(ji,jj+1) - zdep(ji,jj) ) )
233            zalphay(ji,jj)=(0.5+zsigna)*(0.5-zsign)*vmask(ji,jj,1)
234         END DO
235      END DO
236
237      CASE ( 2 )               ! Linear formulation function of temperature and salinity
238
239         CALL ctl_stop( '          use of linear eos rho(T,S) = rau0 * ( rbeta * S - ralpha * T )', &
240              &         '          bbl not implented: easy to do it ' )
241
242      CASE DEFAULT
243
244         WRITE(ctmp1,*) '          bad flag value for neos = ', neos
245         CALL ctl_stop( ctmp1 )
246
247      END SELECT
248
249      ! lateral boundary conditions on zalphax and zalphay   (unchanged sign)
250       CALL lbc_lnk( zalphax, 'U', 1. )   ;   CALL lbc_lnk( zalphay, 'V', 1. )
251
252
253      ! 3. Velocities that are exchanged between ajacent bottom boxes.
254      !---------------------------------------------------------------
255
256      ! ... is equal to zero but where bbl will work.
257          u_bbl(:,:,:) = 0.e0
258          v_bbl(:,:,:) = 0.e0
259# if defined key_vectopt_loop   &&   ! defined key_mpp_omp
260      jj = 1
261      DO ji = 1, jpij-jpi   ! vector opt. (forced unrolling)
262# else
263      DO jj = 1, jpjm1
264         DO ji = 1, jpim1
265# endif
266            iku = mbku(ji,jj)
267            ikv = mbkv(ji,jj)
268            IF( MAX(iku,ikv) >  1 ) THEN
269               u_bbl(ji,jj,iku) = zalphax(ji,jj) * un(ji,jj,iku) * umask(ji,jj,1)
270               v_bbl(ji,jj,ikv) = zalphay(ji,jj) * vn(ji,jj,ikv) * vmask(ji,jj,1)
271            ENDIF
272# if ! defined key_vectopt_loop   ||   defined key_mpp_omp
273         END DO
274# endif
275          END DO
276
277      ! lateral boundary conditions on u_bbl and v_bbl   (changed sign)
278       CALL lbc_lnk( u_bbl, 'U', -1. )   ;   CALL lbc_lnk( v_bbl, 'V', -1. )
279
280      ! 5. Along sigma advective trend
281      ! -------------------------------
282      ! ... Second order centered tracer flux at u and v-points
283
284# if defined key_vectopt_loop   &&   ! defined key_mpp_omp
285      jj = 1
286      DO ji = 1, jpij-jpi   ! vector opt. (forced unrolling)
287# else
288      DO jj = 1, jpjm1
289         DO ji = 1, jpim1
290# endif
291            iku = mbku(ji,jj)
292            ikv = mbkv(ji,jj)
293            zfui = zalphax(ji,jj) *e2u(ji,jj) * fse3u(ji,jj,iku) * zunb(ji,jj)
294            zfvj = zalphay(ji,jj) *e1v(ji,jj) * fse3v(ji,jj,ikv) * zvnb(ji,jj)
295            ! centered scheme
296!           zwx(ji,jj) = 0.5* zfui * ( ztnb(ji,jj) + ztnb(ji+1,jj) )
297!           zwy(ji,jj) = 0.5* zfvj * ( ztnb(ji,jj) + ztnb(ji,jj+1) )
298!           zww(ji,jj) = 0.5* zfui * ( zsnb(ji,jj) + zsnb(ji+1,jj) )
299!           zwz(ji,jj) = 0.5* zfvj * ( zsnb(ji,jj) + zsnb(ji,jj+1) )
300            ! upstream scheme
301            zwx(ji,jj) = ( ( zfui + ABS( zfui ) ) * ztbb(ji  ,jj  )   &
302               &          +( zfui - ABS( zfui ) ) * ztbb(ji+1,jj  ) ) * 0.5
303            zwy(ji,jj) = ( ( zfvj + ABS( zfvj ) ) * ztbb(ji  ,jj  )   &
304               &          +( zfvj - ABS( zfvj ) ) * ztbb(ji  ,jj+1) ) * 0.5
305            zww(ji,jj) = ( ( zfui + ABS( zfui ) ) * zsbb(ji  ,jj  )   &
306               &          +( zfui - ABS( zfui ) ) * zsbb(ji+1,jj  ) ) * 0.5
307            zwz(ji,jj) = ( ( zfvj + ABS( zfvj ) ) * zsbb(ji  ,jj  )   &
308               &          +( zfvj - ABS( zfvj ) ) * zsbb(ji  ,jj+1) ) * 0.5
309#if ! defined key_vectopt_loop   ||   defined key_mpp_omp
310         END DO
311#endif
312        END DO
313# if defined key_vectopt_loop   &&   ! defined key_mpp_omp
314      jj = 1
315      DO ji = jpi+2, jpij-jpi-1   ! vector opt. (forced unrolling)
316# else
317      DO jj = 2, jpjm1
318         DO ji = 2, jpim1
319# endif
320            ik = mbkt(ji,jj)
321            zbtr = 1. / ( e1t(ji,jj)*e2t(ji,jj)*fse3t(ji,jj,ik) )
322            ! horizontal advective trends
323            zta = - zbtr * (  zwx(ji,jj) - zwx(ji-1,jj  )   &
324               &            + zwy(ji,jj) - zwy(ji  ,jj-1)  )
325            zsa = - zbtr * (  zww(ji,jj) - zww(ji-1,jj  )   &
326               &            + zwz(ji,jj) - zwz(ji  ,jj-1)  )
327
328            ! add it to the general tracer trends
329            ta(ji,jj,ik) = ta(ji,jj,ik) + zta
330            sa(ji,jj,ik) = sa(ji,jj,ik) + zsa
331#if ! defined key_vectopt_loop   ||   defined key_mpp_omp
332         END DO
333#endif
334      END DO
335
336      ! save the trends for diagnostic
337      ! BBL lateral advection tracers trends
338      IF( l_trdtra )   THEN
339#  if defined key_vectopt_loop   &&   ! defined key_mpp_omp
340         jj = 1
341         DO ji = jpi+2, jpij-jpi-1   ! vector opt. (forced unrolling)
342#  else
343         DO jj = 2, jpjm1
344            DO ji = 2, jpim1
345#  endif
346            ik = mbkt(ji,jj)
347            tladbbl(ji,jj) = ta(ji,jj,ik) - ztdta(ji,jj,ik)
348            sladbbl(ji,jj) = sa(ji,jj,ik) - ztdsa(ji,jj,ik)
349#  if ! defined key_vectopt_loop   ||   defined key_mpp_omp
350            END DO
351#  endif
352         END DO
353
354      ENDIF
355
356      IF(ln_ctl) THEN
357         CALL prt_ctl(tab3d_1=ta, clinfo1=' bbl  - Ta: ', mask1=tmask, &
358            &         tab3d_2=sa, clinfo2=' Sa: ', mask2=tmask, clinfo3='tra')
359      ENDIF
360
361
362      ! 6. Vertical advection velocities
363      ! --------------------------------
364      ! ... computes divergence perturbation (velocties to be removed from upper t boxes :
365      DO jk= 1, jpkm1
366         DO jj=1, jpjm1
367            DO ji = 1, fs_jpim1   ! vector opt.
368               zwu(ji,jj) = -e2u(ji,jj) * u_bbl(ji,jj,jk) * fse3u(ji,jj,jk)
369               zwv(ji,jj) = -e1v(ji,jj) * v_bbl(ji,jj,jk) * fse3v(ji,jj,jk)
370            END DO
371         END DO
372
373      ! ... horizontal divergence
374         DO jj = 2, jpjm1
375            DO ji = fs_2, fs_jpim1   ! vector opt.
376               zbt = e1t(ji,jj) * e2t(ji,jj) * fse3t(ji,jj,jk)
377               zhdivn(ji,jj,jk) = (  zwu(ji,jj) - zwu(ji-1,jj  )   &
378                                   + zwv(ji,jj) - zwv(ji  ,jj-1)  ) / zbt
379            END DO
380         END DO
381      END DO
382
383
384      ! ... horizontal bottom divergence
385# if defined key_vectopt_loop   &&   ! defined key_mpp_omp
386      jj = 1
387      DO ji = 1, jpij-jpi   ! vector opt. (forced unrolling)
388# else
389      DO jj = 1, jpjm1
390         DO ji = 1, jpim1
391# endif
392            iku = mbku(ji,jj)
393            ikv = mbkv(ji,jj)
394            zwu(ji,jj) = zalphax(ji,jj) * e2u(ji,jj) * fse3u(ji,jj,iku)
395            zwv(ji,jj) = zalphay(ji,jj) * e1v(ji,jj) * fse3v(ji,jj,ikv)
396#if ! defined key_vectopt_loop   ||   defined key_mpp_omp
397         END DO
398#endif
399        END DO
400
401# if defined key_vectopt_loop   &&   ! defined key_mpp_omp
402      jj = 1
403      DO ji = jpi+2, jpij-jpi-1   ! vector opt. (forced unrolling)
404# else
405      DO jj = 2, jpjm1
406         DO ji = 2, jpim1
407# endif
408            ik = mbkt(ji,jj)
409            zbt = e1t(ji,jj) * e2t(ji,jj) * fse3t(ji,jj,ik)
410            zhdivn(ji,jj,ik) =   &
411               &   (  zwu(ji  ,jj  ) * ( zunb(ji  ,jj  ) - un(ji  ,jj  ,ik) *umask(ji  ,jj  ,1) )   &
412               &    - zwu(ji-1,jj  ) * ( zunb(ji-1,jj  ) - un(ji-1,jj  ,ik) *umask(ji-1,jj  ,1) )   &
413               &    + zwv(ji  ,jj  ) * ( zvnb(ji  ,jj  ) - vn(ji  ,jj  ,ik) *vmask(ji  ,jj  ,1) )   &
414               &    - zwv(ji  ,jj-1) * ( zvnb(ji  ,jj-1) - vn(ji  ,jj-1,ik) *vmask(ji  ,jj-1,1) )   &
415               &   ) / zbt
416
417# if ! defined key_vectopt_loop   ||   defined key_mpp_omp
418         END DO
419# endif
420        END DO
421
422      ! 7. compute additional vertical velocity to be used in t boxes
423      ! -------------------------------------------------------------
424
425      ! ... Computation from the bottom
426      ! Note that w_bbl(:,:,jpk) has been set to 0 in tra_bbl_init
427      DO jk = jpkm1, 1, -1
428         DO jj= 2, jpjm1
429            DO ji = fs_2, fs_jpim1   ! vector opt.
430               w_bbl(ji,jj,jk) = w_bbl(ji,jj,jk+1) - fse3t(ji,jj,jk)*zhdivn(ji,jj,jk)
431            END DO
432         END DO
433      END DO
434
435      ! Boundary condition on w_bbl   (unchanged sign)
436      CALL lbc_lnk( w_bbl, 'W', 1. )
437
438   END SUBROUTINE tra_bbl_adv
Note: See TracBrowser for help on using the repository browser.