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 @ 409

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

nemo_v1_bugfix_028 : CT : bug correction for the BBL advection

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.8 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,  &  ! temporary workspace arrays
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_autotasking
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_autotasking
136         END DO
137#endif
138      END DO
139#if defined key_vectopt_loop   &&   ! defined key_autotasking
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         IF(lwp) WRITE(numout,cform_err)
240         IF(lwp) WRITE(numout,*) '          use of linear eos rho(T,S) = rau0 * ( rbeta * S - ralpha * T )'
241         IF(lwp) WRITE(numout,*) '          bbl not implented: easy to do it '
242         nstop = nstop + 1
243
244      CASE DEFAULT
245
246         IF(lwp) WRITE(numout,cform_err)
247         IF(lwp) WRITE(numout,*) '          bad flag value for neos = ', neos
248         nstop = nstop + 1
249
250      END SELECT
251
252      ! lateral boundary conditions on zalphax and zalphay   (unchanged sign)
253       CALL lbc_lnk( zalphax, 'U', 1. )   ;   CALL lbc_lnk( zalphay, 'V', 1. )
254
255
256      ! 3. Velocities that are exchanged between ajacent bottom boxes.
257      !---------------------------------------------------------------
258
259      ! ... is equal to zero but where bbl will work.
260          u_bbl(:,:,:) = 0.e0
261          v_bbl(:,:,:) = 0.e0
262# if defined key_vectopt_loop   &&   ! defined key_autotasking
263      jj = 1
264      DO ji = 1, jpij-jpi   ! vector opt. (forced unrolling)
265# else
266      DO jj = 1, jpjm1
267         DO ji = 1, jpim1
268# endif
269            iku = mbku(ji,jj)
270            ikv = mbkv(ji,jj)
271            IF( MAX(iku,ikv) >  1 ) THEN
272               u_bbl(ji,jj,iku) = zalphax(ji,jj) * un(ji,jj,iku) * umask(ji,jj,1)
273               v_bbl(ji,jj,ikv) = zalphay(ji,jj) * vn(ji,jj,ikv) * vmask(ji,jj,1)
274            ENDIF
275# if ! defined key_vectopt_loop   ||   defined key_autotasking
276         END DO
277# endif
278          END DO
279
280      ! lateral boundary conditions on u_bbl and v_bbl   (changed sign)
281       CALL lbc_lnk( u_bbl, 'U', -1. )   ;   CALL lbc_lnk( v_bbl, 'V', -1. )
282
283      ! 5. Along sigma advective trend
284      ! -------------------------------
285      ! ... Second order centered tracer flux at u and v-points
286
287# if defined key_vectopt_loop   &&   ! defined key_autotasking
288      jj = 1
289      DO ji = 1, jpij-jpi   ! vector opt. (forced unrolling)
290# else
291      DO jj = 1, jpjm1
292         DO ji = 1, jpim1
293# endif
294            iku = mbku(ji,jj)
295            ikv = mbkv(ji,jj)
296            zfui = zalphax(ji,jj) *e2u(ji,jj) * fse3u(ji,jj,iku) * zunb(ji,jj)
297            zfvj = zalphay(ji,jj) *e1v(ji,jj) * fse3v(ji,jj,ikv) * zvnb(ji,jj)
298            ! centered scheme
299!           zwx(ji,jj) = 0.5* zfui * ( ztnb(ji,jj) + ztnb(ji+1,jj) )
300!           zwy(ji,jj) = 0.5* zfvj * ( ztnb(ji,jj) + ztnb(ji,jj+1) )
301!           zww(ji,jj) = 0.5* zfui * ( zsnb(ji,jj) + zsnb(ji+1,jj) )
302!           zwz(ji,jj) = 0.5* zfvj * ( zsnb(ji,jj) + zsnb(ji,jj+1) )
303            ! upstream scheme
304            zwx(ji,jj) = ( ( zfui + ABS( zfui ) ) * ztbb(ji  ,jj  )   &
305               &          +( zfui - ABS( zfui ) ) * ztbb(ji+1,jj  ) ) * 0.5
306            zwy(ji,jj) = ( ( zfvj + ABS( zfvj ) ) * ztbb(ji  ,jj  )   &
307               &          +( zfvj - ABS( zfvj ) ) * ztbb(ji  ,jj+1) ) * 0.5
308            zww(ji,jj) = ( ( zfui + ABS( zfui ) ) * zsbb(ji  ,jj  )   &
309               &          +( zfui - ABS( zfui ) ) * zsbb(ji+1,jj  ) ) * 0.5
310            zwz(ji,jj) = ( ( zfvj + ABS( zfvj ) ) * zsbb(ji  ,jj  )   &
311               &          +( zfvj - ABS( zfvj ) ) * zsbb(ji  ,jj+1) ) * 0.5
312#if ! defined key_vectopt_loop   ||   defined key_autotasking
313         END DO
314#endif
315        END DO
316# if defined key_vectopt_loop   &&   ! defined key_autotasking
317      jj = 1
318      DO ji = jpi+2, jpij-jpi-1   ! vector opt. (forced unrolling)
319# else
320      DO jj = 2, jpjm1
321         DO ji = 2, jpim1
322# endif
323            ik = mbkt(ji,jj)
324            zbtr = 1. / ( e1t(ji,jj)*e2t(ji,jj)*fse3t(ji,jj,ik) )
325            ! horizontal advective trends
326            zta = - zbtr * (  zwx(ji,jj) - zwx(ji-1,jj  )   &
327               &            + zwy(ji,jj) - zwy(ji  ,jj-1)  )
328            zsa = - zbtr * (  zww(ji,jj) - zww(ji-1,jj  )   &
329               &            + zwz(ji,jj) - zwz(ji  ,jj-1)  )
330
331            ! add it to the general tracer trends
332            ta(ji,jj,ik) = ta(ji,jj,ik) + zta
333            sa(ji,jj,ik) = sa(ji,jj,ik) + zsa
334#if ! defined key_vectopt_loop   ||   defined key_autotasking
335         END DO
336#endif
337      END DO
338
339      ! save the trends for diagnostic
340      ! BBL lateral advection tracers trends
341      IF( l_trdtra )   THEN
342#  if defined key_vectopt_loop   &&   ! defined key_autotasking
343         jj = 1
344         DO ji = jpi+2, jpij-jpi-1   ! vector opt. (forced unrolling)
345#  else
346         DO jj = 2, jpjm1
347            DO ji = 2, jpim1
348#  endif
349            ik = mbkt(ji,jj)
350            tladbbl(ji,jj) = ta(ji,jj,ik) - ztdta(ji,jj,ik)
351            sladbbl(ji,jj) = sa(ji,jj,ik) - ztdsa(ji,jj,ik)
352#  if ! defined key_vectopt_loop   ||   defined key_autotasking
353            END DO
354#  endif
355         END DO
356
357      ENDIF
358
359      IF(ln_ctl) THEN
360         CALL prt_ctl(tab3d_1=ta, clinfo1=' bbl  - Ta: ', mask1=tmask, &
361            &         tab3d_2=sa, clinfo2=' Sa: ', mask2=tmask, clinfo3='tra')
362      ENDIF
363
364
365      ! 6. Vertical advection velocities
366      ! --------------------------------
367      ! ... computes divergence perturbation (velocties to be removed from upper t boxes :
368      DO jk= 1, jpkm1
369         DO jj=1, jpjm1
370            DO ji = 1, fs_jpim1   ! vector opt.
371               zwu(ji,jj) = -e2u(ji,jj) * u_bbl(ji,jj,jk) * fse3u(ji,jj,jk)
372               zwv(ji,jj) = -e1v(ji,jj) * v_bbl(ji,jj,jk) * fse3v(ji,jj,jk)
373            END DO
374         END DO
375
376      ! ... horizontal divergence
377         DO jj = 2, jpjm1
378            DO ji = fs_2, fs_jpim1   ! vector opt.
379               zbt = e1t(ji,jj) * e2t(ji,jj) * fse3t(ji,jj,jk)
380               zhdivn(ji,jj,jk) = (  zwu(ji,jj) - zwu(ji-1,jj  )   &
381                                   + zwv(ji,jj) - zwv(ji  ,jj-1)  ) / zbt
382            END DO
383         END DO
384      END DO
385
386
387      ! ... horizontal bottom divergence
388# if defined key_vectopt_loop   &&   ! defined key_autotasking
389      jj = 1
390      DO ji = 1, jpij-jpi   ! vector opt. (forced unrolling)
391# else
392      DO jj = 1, jpjm1
393         DO ji = 1, jpim1
394# endif
395            iku = mbku(ji,jj)
396            ikv = mbkv(ji,jj)
397            zwu(ji,jj) = zalphax(ji,jj) * e2u(ji,jj) * fse3u(ji,jj,iku)
398            zwv(ji,jj) = zalphay(ji,jj) * e1v(ji,jj) * fse3v(ji,jj,ikv)
399#if ! defined key_vectopt_loop   ||   defined key_autotasking
400         END DO
401#endif
402        END DO
403
404# if defined key_vectopt_loop   &&   ! defined key_autotasking
405      jj = 1
406      DO ji = jpi+2, jpij-jpi-1   ! vector opt. (forced unrolling)
407# else
408      DO jj = 2, jpjm1
409         DO ji = 2, jpim1
410# endif
411            ik = mbkt(ji,jj)
412            zbt = e1t(ji,jj) * e2t(ji,jj) * fse3t(ji,jj,ik)
413            zhdivn(ji,jj,ik) =   &
414               &   (  zwu(ji  ,jj  ) * ( zunb(ji  ,jj  ) - un(ji  ,jj  ,ik) *umask(ji  ,jj  ,1) )   &
415               &    - zwu(ji-1,jj  ) * ( zunb(ji-1,jj  ) - un(ji-1,jj  ,ik) *umask(ji-1,jj  ,1) )   &
416               &    + zwv(ji  ,jj  ) * ( zvnb(ji  ,jj  ) - vn(ji  ,jj  ,ik) *vmask(ji  ,jj  ,1) )   &
417               &    - zwv(ji  ,jj-1) * ( zvnb(ji  ,jj-1) - vn(ji  ,jj-1,ik) *vmask(ji  ,jj-1,1) )   &
418               &   ) / zbt
419
420# if ! defined key_vectopt_loop   ||   defined key_autotasking
421         END DO
422# endif
423        END DO
424
425      ! 7. compute additional vertical velocity to be used in t boxes
426      ! -------------------------------------------------------------
427
428      ! ... Computation from the bottom
429      ! Note that w_bbl(:,:,jpk) has been set to 0 in tra_bbl_init
430      DO jk = jpkm1, 1, -1
431         DO jj= 2, jpjm1
432            DO ji = fs_2, fs_jpim1   ! vector opt.
433               w_bbl(ji,jj,jk) = w_bbl(ji,jj,jk+1) - fse3t(ji,jj,jk)*zhdivn(ji,jj,jk)
434            END DO
435         END DO
436      END DO
437
438      ! Boundary condition on w_bbl   (unchanged sign)
439      CALL lbc_lnk( w_bbl, 'W', 1. )
440
441   END SUBROUTINE tra_bbl_adv
Note: See TracBrowser for help on using the repository browser.