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.
traadv_ubs_lf.F90 in NEMO/trunk/src/OCE/TRA – NEMO

source: NEMO/trunk/src/OCE/TRA/traadv_ubs_lf.F90

Last change on this file was 15074, checked in by clem, 3 years ago

loop fusion: debug ubs

File size: 20.5 KB
Line 
1MODULE traadv_ubs_lf
2   !!==============================================================================
3   !!                       ***  MODULE  traadv_ubs  ***
4   !! Ocean active tracers:  horizontal & vertical advective trend
5   !!==============================================================================
6   !! History :  1.0  !  2006-08  (L. Debreu, R. Benshila)  Original code
7   !!            3.3  !  2010-05  (C. Ethe, G. Madec)  merge TRC-TRA + switch from velocity to transport
8   !!----------------------------------------------------------------------
9
10   !!----------------------------------------------------------------------
11   !!   tra_adv_ubs : update the tracer trend with the horizontal
12   !!                 advection trends using a third order biaised scheme
13   !!----------------------------------------------------------------------
14   USE oce            ! ocean dynamics and active tracers
15   USE dom_oce        ! ocean space and time domain
16   USE trc_oce        ! share passive tracers/Ocean variables
17   USE trd_oce        ! trends: ocean variables
18   USE traadv_fct      ! acces to routine interp_4th_cpt
19   USE trdtra         ! trends manager: tracers
20   USE diaptr         ! poleward transport diagnostics
21   USE diaar5         ! AR5 diagnostics
22   !
23   USE iom            ! I/O library
24   USE in_out_manager ! I/O manager
25   USE lib_mpp        ! massively parallel library
26   USE lbclnk         ! ocean lateral boundary condition (or mpp link)
27   USE lib_fortran    ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined)
28
29   IMPLICIT NONE
30   PRIVATE
31
32   PUBLIC   tra_adv_ubs_lf   ! routine called by traadv module
33
34   LOGICAL :: l_trd   ! flag to compute trends
35   LOGICAL :: l_ptr   ! flag to compute poleward transport
36   LOGICAL :: l_hst   ! flag to compute heat transport
37
38
39   !! * Substitutions
40#  include "do_loop_substitute.h90"
41#  include "domzgr_substitute.h90"
42   !!----------------------------------------------------------------------
43   !! NEMO/OCE 4.0 , NEMO Consortium (2018)
44   !! $Id: traadv_ubs.F90 14776 2021-04-30 12:33:41Z mocavero $
45   !! Software governed by the CeCILL license (see ./LICENSE)
46   !!----------------------------------------------------------------------
47CONTAINS
48
49   SUBROUTINE tra_adv_ubs_lf( kt, kit000, cdtype, p2dt, pU, pV, pW,          &
50      &                    Kbb, Kmm, pt, kjpt, Krhs, kn_ubs_v )
51      !!----------------------------------------------------------------------
52      !!                  ***  ROUTINE tra_adv_ubs  ***
53      !!
54      !! ** Purpose :   Compute the now trend due to the advection of tracers
55      !!      and add it to the general trend of passive tracer equations.
56      !!
57      !! ** Method  :   The 3rd order Upstream Biased Scheme (UBS) is based on an
58      !!      upstream-biased parabolic interpolation (Shchepetkin and McWilliams 2005)
59      !!      It is only used in the horizontal direction.
60      !!      For example the i-component of the advective fluxes are given by :
61      !!                !  e2u e3u un ( mi(Tn) - zltu(i  ) )   if un(i) >= 0
62      !!          ztu = !  or
63      !!                !  e2u e3u un ( mi(Tn) - zltu(i+1) )   if un(i) < 0
64      !!      where zltu is the second derivative of the before temperature field:
65      !!          zltu = 1/e3t di[ e2u e3u / e1u di[Tb] ]
66      !!        This results in a dissipatively dominant (i.e. hyper-diffusive)
67      !!      truncation error. The overall performance of the advection scheme
68      !!      is similar to that reported in (Farrow and Stevens, 1995).
69      !!        For stability reasons, the first term of the fluxes which corresponds
70      !!      to a second order centered scheme is evaluated using the now velocity
71      !!      (centered in time) while the second term which is the diffusive part
72      !!      of the scheme, is evaluated using the before velocity (forward in time).
73      !!      Note that UBS is not positive. Do not use it on passive tracers.
74      !!                On the vertical, the advection is evaluated using a FCT scheme,
75      !!      as the UBS have been found to be too diffusive.
76      !!                kn_ubs_v argument controles whether the FCT is based on
77      !!      a 2nd order centrered scheme (kn_ubs_v=2) or on a 4th order compact
78      !!      scheme (kn_ubs_v=4).
79      !!
80      !! ** Action : - update pt(:,:,:,:,Krhs)  with the now advective tracer trends
81      !!             - send trends to trdtra module for further diagnostcs (l_trdtra=T)
82      !!             - poleward advective heat and salt transport (ln_diaptr=T)
83      !!
84      !! Reference : Shchepetkin, A. F., J. C. McWilliams, 2005, Ocean Modelling, 9, 347-404.
85      !!             Farrow, D.E., Stevens, D.P., 1995, J. Phys. Ocean. 25, 1731�1741.
86      !!----------------------------------------------------------------------
87      INTEGER                                  , INTENT(in   ) ::   kt              ! ocean time-step index
88      INTEGER                                  , INTENT(in   ) ::   Kbb, Kmm, Krhs  ! ocean time level indices
89      INTEGER                                  , INTENT(in   ) ::   kit000          ! first time step index
90      CHARACTER(len=3)                         , INTENT(in   ) ::   cdtype          ! =TRA or TRC (tracer indicator)
91      INTEGER                                  , INTENT(in   ) ::   kjpt            ! number of tracers
92      INTEGER                                  , INTENT(in   ) ::   kn_ubs_v        ! number of tracers
93      REAL(wp)                                 , INTENT(in   ) ::   p2dt            ! tracer time-step
94      ! TEMP: [tiling] This can be A2D(nn_hls) if using XIOS (subdomain support)
95      REAL(wp), DIMENSION(jpi,jpj,jpk         ), INTENT(in   ) ::   pU, pV, pW      ! 3 ocean volume transport components
96      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt,jpt), INTENT(inout) ::   pt              ! tracers and RHS of tracer equation
97      !
98      INTEGER  ::   ji, jj, jk, jn   ! dummy loop indices
99      REAL(wp) ::   ztra, zbtr, zcoef, zcoef_ip1, zcoef_jp1        ! local scalars
100      REAL(wp) ::   zfp_ui, zfm_ui, zcenut, ztak, zfp_wk, zfm_wk   !   -      -
101      REAL(wp) ::   zfp_vj, zfm_vj, zcenvt, zeeu, zeev, z_hdivn    !   -      -
102      REAL(wp) ::   zeeu_im1, zeeu_ip1, zeev_jm1, zeev_jp1
103      REAL(wp) ::   zztu, zztu_im1, zztu_ip1
104      REAL(wp) ::   zztv, zztv_jm1, zztv_jp1
105      REAL(wp) ::   zzltu, zzltu_ip1, zzltv, zzltv_jp1
106      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   ztu, ztv, zltu, zltv, zti, ztw     ! 3D workspace
107      !!----------------------------------------------------------------------
108      !
109      IF( ntile == 0 .OR. ntile == 1 )  THEN                       ! Do only on the first tile
110         IF( kt == kit000 )  THEN
111            IF(lwp) WRITE(numout,*)
112            IF(lwp) WRITE(numout,*) 'tra_adv_ubs :  horizontal UBS advection scheme on ', cdtype
113            IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~'
114         ENDIF
115         !
116         l_trd = .FALSE.
117         l_hst = .FALSE.
118         l_ptr = .FALSE.
119         IF( ( cdtype == 'TRA' .AND. l_trdtra ) .OR. ( cdtype == 'TRC' .AND. l_trdtrc ) )      l_trd = .TRUE.
120         IF(   cdtype == 'TRA' .AND. ( iom_use( 'sophtadv' ) .OR. iom_use( 'sophtadv' ) )  )   l_ptr = .TRUE.
121         IF(   cdtype == 'TRA' .AND. ( iom_use("uadv_heattr") .OR. iom_use("vadv_heattr") .OR. &
122            &                          iom_use("uadv_salttr") .OR. iom_use("vadv_salttr")  ) ) l_hst = .TRUE.
123      ENDIF
124      !
125      ztw (:,:, 1 ) = 0._wp      ! surface & bottom value : set to zero for all tracers
126      zltu(:,:,jpk) = 0._wp   ;   zltv(:,:,jpk) = 0._wp
127      ztw (:,:,jpk) = 0._wp   ;   zti (:,:,jpk) = 0._wp
128      !                                                          ! ===========
129      DO jn = 1, kjpt                                            ! tracer loop
130         !                                                       ! ===========
131         !                        !==  horizontal laplacian of before tracer ==!
132         DO_3D( 1, 0, 1, 0, 1, jpkm1 )                   ! Second derivative (divergence)
133            ! First derivative (masked gradient)
134            zeeu_im1 = e2_e1u(ji-1,jj  ) * e3u(ji-1,jj  ,jk,Kmm) * umask(ji-1,jj  ,jk)
135            zeeu     = e2_e1u(ji  ,jj  ) * e3u(ji  ,jj  ,jk,Kmm) * umask(ji  ,jj  ,jk)
136            zeeu_ip1 = e2_e1u(ji+1,jj  ) * e3u(ji+1,jj  ,jk,Kmm) * umask(ji+1,jj  ,jk)
137            zeev_jm1 = e1_e2v(ji  ,jj-1) * e3v(ji  ,jj-1,jk,Kmm) * vmask(ji  ,jj-1,jk)
138            zeev     = e1_e2v(ji  ,jj  ) * e3v(ji  ,jj  ,jk,Kmm) * vmask(ji  ,jj  ,jk)
139            zeev_jp1 = e1_e2v(ji  ,jj+1) * e3v(ji  ,jj+1,jk,Kmm) * vmask(ji  ,jj+1,jk)
140            !
141            zztu_im1 = zeeu_im1 * ( pt(ji  ,jj,jk,jn,Kbb) - pt(ji-1,jj,jk,jn,Kbb) )
142            zztu     = zeeu     * ( pt(ji+1,jj,jk,jn,Kbb) - pt(ji  ,jj,jk,jn,Kbb) )
143            zztu_ip1 = zeeu_ip1 * ( pt(ji+2,jj,jk,jn,Kbb) - pt(ji+1,jj,jk,jn,Kbb) )
144            !
145            zztv_jm1 = zeev_jm1 * ( pt(ji,jj  ,jk,jn,Kbb) - pt(ji,jj-1,jk,jn,Kbb) )
146            zztv     = zeev     * ( pt(ji,jj+1,jk,jn,Kbb) - pt(ji,jj  ,jk,jn,Kbb) )
147            zztv_jp1 = zeev_jp1 * ( pt(ji,jj+2,jk,jn,Kbb) - pt(ji,jj+1,jk,jn,Kbb) )
148            ! Second derivative (divergence)
149            zcoef     = 1._wp / ( 6._wp * e3t(ji  ,jj  ,jk,Kmm) )
150            zcoef_ip1 = 1._wp / ( 6._wp * e3t(ji+1,jj  ,jk,Kmm) )
151            zcoef_jp1 = 1._wp / ( 6._wp * e3t(ji  ,jj+1,jk,Kmm) )
152            !
153            zzltu     = (  zztu     - zztu_im1  ) * zcoef
154            zzltu_ip1 = (  zztu_ip1 - zztu      ) * zcoef_ip1
155            zzltv     = (  zztv     - zztv_jm1  ) * zcoef
156            zzltv_jp1 = (  zztv_jp1 - zztv      ) * zcoef_jp1
157            !
158            !                     !==  Horizontal advective fluxes  ==!     (UBS)
159            zfp_ui = pU(ji,jj,jk) + ABS( pU(ji,jj,jk) )        ! upstream transport (x2)
160            zfm_ui = pU(ji,jj,jk) - ABS( pU(ji,jj,jk) )
161            zfp_vj = pV(ji,jj,jk) + ABS( pV(ji,jj,jk) )
162            zfm_vj = pV(ji,jj,jk) - ABS( pV(ji,jj,jk) )
163            !                                                  ! 2nd order centered advective fluxes (x2)
164            zcenut = pU(ji,jj,jk) * ( pt(ji,jj,jk,jn,Kmm) + pt(ji+1,jj  ,jk,jn,Kmm) )
165            zcenvt = pV(ji,jj,jk) * ( pt(ji,jj,jk,jn,Kmm) + pt(ji  ,jj+1,jk,jn,Kmm) )
166            !                                                  ! UBS advective fluxes
167            ztu(ji,jj,jk) = 0.5 * ( zcenut - zfp_ui * zzltu - zfm_ui * zzltu_ip1 )
168            ztv(ji,jj,jk) = 0.5 * ( zcenvt - zfp_vj * zzltv - zfm_vj * zzltv_jp1 )
169         END_3D
170         !
171         DO_3D( 0, 0, 0, 0, 1, jpk )
172            zltu(ji,jj,jk) = pt(ji,jj,jk,jn,Krhs)      ! store the initial trends before its update
173         END_3D
174         !
175         !                           !==  add the horizontal advective trend  ==!
176         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
177            pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs)                &
178               &             - (  ztu(ji,jj,jk) - ztu(ji-1,jj  ,jk)    &
179               &                + ztv(ji,jj,jk) - ztv(ji  ,jj-1,jk)  ) &
180               &                * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
181         END_3D
182         !
183         DO_3D( 0, 0, 0, 0, 1, jpk )
184            zltu(ji,jj,jk) = pt(ji,jj,jk,jn,Krhs) - zltu(ji,jj,jk)  ! Horizontal advective trend used in vertical 2nd order FCT case
185         END_3D                                                     ! and/or in trend diagnostic (l_trd=T)
186         !
187         IF( l_trd ) THEN                  ! trend diagnostics
188             CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_xad, ztu, pU, pt(:,:,:,jn,Kmm) )
189             CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_yad, ztv, pV, pt(:,:,:,jn,Kmm) )
190         END IF
191         !
192         !                                ! "Poleward" heat and salt transports (contribution of upstream fluxes)
193         IF( l_ptr )  CALL dia_ptr_hst( jn, 'adv', ztv(:,:,:) )
194         !                                !  heati/salt transport
195         IF( l_hst )  CALL dia_ar5_hst( jn, 'adv', ztu(:,:,:), ztv(:,:,:) )
196         !
197         !
198         !                       !== vertical advective trend  ==!
199         !
200         SELECT CASE( kn_ubs_v )       ! select the vertical advection scheme
201         !
202         CASE(  2  )                   ! 2nd order FCT
203            !
204            IF( l_trd ) THEN
205               DO_3D( 0, 0, 0, 0, 1, jpkm1 )
206                  zltv(ji,jj,jk) = pt(ji,jj,jk,jn,Krhs)          ! store pt(:,:,:,:,Krhs) if trend diag.
207               END_3D
208            ENDIF
209            !
210            !                               !*  upstream advection with initial mass fluxes & intermediate update  ==!
211            DO_3D( 1, 1, 1, 1, 2, jpkm1 )
212               zfp_wk = pW(ji,jj,jk) + ABS( pW(ji,jj,jk) )
213               zfm_wk = pW(ji,jj,jk) - ABS( pW(ji,jj,jk) )
214               ztw(ji,jj,jk) = 0.5_wp * (  zfp_wk * pt(ji,jj,jk,jn,Kbb) + zfm_wk * pt(ji,jj,jk-1,jn,Kbb)  ) * wmask(ji,jj,jk)
215            END_3D
216            IF( ln_linssh ) THEN                ! top ocean value (only in linear free surface as ztw has been w-masked)
217               IF( ln_isfcav ) THEN                   ! top of the ice-shelf cavities and at the ocean surface
218                  DO_2D( 1, 1, 1, 1 )
219                     ztw(ji,jj, mikt(ji,jj) ) = pW(ji,jj,mikt(ji,jj)) * pt(ji,jj,mikt(ji,jj),jn,Kbb)   ! linear free surface
220                  END_2D
221               ELSE                                   ! no cavities: only at the ocean surface
222                  DO_2D( 1, 1, 1, 1 )
223                     ztw(ji,jj,1) = pW(ji,jj,1) * pt(ji,jj,1,jn,Kbb)
224                  END_2D
225               ENDIF
226            ENDIF
227            !
228            DO_3D( 0, 0, 0, 0, 1, jpkm1 )   !* trend and after field with monotonic scheme
229               ztak = - ( ztw(ji,jj,jk) - ztw(ji,jj,jk+1) )    &
230                  &     * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
231               pt(ji,jj,jk,jn,Krhs) =   pt(ji,jj,jk,jn,Krhs) +  ztak
232               zti(ji,jj,jk)    = ( pt(ji,jj,jk,jn,Kbb) + p2dt * ( ztak + zltu(ji,jj,jk) ) ) * tmask(ji,jj,jk)
233            END_3D
234            !
235            !                          !*  anti-diffusive flux : high order minus low order
236            DO_3D( 1, 1, 1, 1, 2, jpkm1 )
237               ztw(ji,jj,jk) = (   0.5_wp * pW(ji,jj,jk) * ( pt(ji,jj,jk,jn,Kmm) + pt(ji,jj,jk-1,jn,Kmm) )   &
238                  &              - ztw(ji,jj,jk)   ) * wmask(ji,jj,jk)
239            END_3D
240            !                                            ! top ocean value: high order == upstream  ==>>  zwz=0
241            IF( ln_linssh )   ztw(:,:, 1 ) = 0._wp       ! only ocean surface as interior zwz values have been w-masked
242            !
243            CALL nonosc_z( Kmm, pt(:,:,:,jn,Kbb), ztw, zti, p2dt )      !  monotonicity algorithm
244            !
245         CASE(  4  )                               ! 4th order COMPACT
246            CALL interp_4th_cpt( pt(:,:,:,jn,Kmm) , ztw )         ! 4th order compact interpolation of T at w-point
247            DO_3D( 0, 0, 0, 0, 2, jpkm1 )
248               ztw(ji,jj,jk) = pW(ji,jj,jk) * ztw(ji,jj,jk) * wmask(ji,jj,jk)
249            END_3D
250            IF( ln_linssh ) THEN
251               DO_2D( 1, 1, 1, 1 )
252                  ztw(ji,jj,1) = pW(ji,jj,1) * pt(ji,jj,1,jn,Kmm)     !!gm ISF & 4th COMPACT doesn't work
253               END_2D
254            ENDIF
255            !
256         END SELECT
257         !
258         DO_3D( 0, 0, 0, 0, 1, jpkm1 )   !  final trend with corrected fluxes
259            pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) - ( ztw(ji,jj,jk) - ztw(ji,jj,jk+1) )    &
260               &                                        * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
261         END_3D
262         !
263         IF( l_trd )  THEN               ! vertical advective trend diagnostics
264            DO_3D( 0, 0, 0, 0, 1, jpkm1 )                 ! (compute -w.dk[ptn]= -dk[w.ptn] + ptn.dk[w])
265               zltv(ji,jj,jk) = pt(ji,jj,jk,jn,Krhs) - zltv(ji,jj,jk)                          &
266                  &           + pt(ji,jj,jk,jn,Kmm) * (  pW(ji,jj,jk) - pW(ji,jj,jk+1)  )   &
267                  &                              * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
268            END_3D
269            CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_zad, zltv )
270         ENDIF
271         !
272      END DO
273      !
274   END SUBROUTINE tra_adv_ubs_lf
275
276
277   SUBROUTINE nonosc_z( Kmm, pbef, pcc, paft, p2dt )
278      !!---------------------------------------------------------------------
279      !!                    ***  ROUTINE nonosc_z  ***
280      !!
281      !! **  Purpose :   compute monotonic tracer fluxes from the upstream
282      !!       scheme and the before field by a nonoscillatory algorithm
283      !!
284      !! **  Method  :   ... ???
285      !!       warning : pbef and paft must be masked, but the boundaries
286      !!       conditions on the fluxes are not necessary zalezak (1979)
287      !!       drange (1995) multi-dimensional forward-in-time and upstream-
288      !!       in-space based differencing for fluid
289      !!----------------------------------------------------------------------
290      INTEGER , INTENT(in   )                         ::   Kmm    ! time level index
291      REAL(wp), INTENT(in   )                         ::   p2dt   ! tracer time-step
292      REAL(wp),                DIMENSION(jpi,jpj,jpk) ::   pbef   ! before field
293      REAL(wp), INTENT(inout), DIMENSION(A2D(nn_hls)    ,jpk) ::   paft   ! after field
294      REAL(wp), INTENT(inout), DIMENSION(A2D(nn_hls)    ,jpk) ::   pcc    ! monotonic flux in the k direction
295      !
296      INTEGER  ::   ji, jj, jk   ! dummy loop indices
297      INTEGER  ::   ikm1         ! local integer
298      REAL(wp) ::   zpos, zneg, zbt, za, zb, zc, zbig, zrtrn   ! local scalars
299      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zbetup, zbetdo         ! 3D workspace
300      !!----------------------------------------------------------------------
301      !
302      zbig  = 1.e+38_wp
303      zrtrn = 1.e-15_wp
304      zbetup(:,:,:) = 0._wp   ;   zbetdo(:,:,:) = 0._wp
305      !
306      ! Search local extrema
307      ! --------------------
308      !                    ! large negative value (-zbig) inside land
309      DO_3D( 0, 0, 0, 0, 1, jpk )
310         pbef(ji,jj,jk) = pbef(ji,jj,jk) * tmask(ji,jj,jk) - zbig * ( 1.e0 - tmask(ji,jj,jk) )
311         paft(ji,jj,jk) = paft(ji,jj,jk) * tmask(ji,jj,jk) - zbig * ( 1.e0 - tmask(ji,jj,jk) )
312      END_3D
313      !
314      DO jk = 1, jpkm1     ! search maximum in neighbourhood
315         ikm1 = MAX(jk-1,1)
316         DO_2D( 0, 0, 0, 0 )
317            zbetup(ji,jj,jk) = MAX(  pbef(ji  ,jj  ,jk  ), paft(ji  ,jj  ,jk  ),   &
318               &                     pbef(ji  ,jj  ,ikm1), pbef(ji  ,jj  ,jk+1),   &
319               &                     paft(ji  ,jj  ,ikm1), paft(ji  ,jj  ,jk+1)  )
320         END_2D
321      END DO
322      !                    ! large positive value (+zbig) inside land
323      DO_3D( 0, 0, 0, 0, 1, jpk )
324         pbef(ji,jj,jk) = pbef(ji,jj,jk) * tmask(ji,jj,jk) + zbig * ( 1.e0 - tmask(ji,jj,jk) )
325         paft(ji,jj,jk) = paft(ji,jj,jk) * tmask(ji,jj,jk) + zbig * ( 1.e0 - tmask(ji,jj,jk) )
326      END_3D
327      !
328      DO jk = 1, jpkm1     ! search minimum in neighbourhood
329         ikm1 = MAX(jk-1,1)
330         DO_2D( 0, 0, 0, 0 )
331            zbetdo(ji,jj,jk) = MIN(  pbef(ji  ,jj  ,jk  ), paft(ji  ,jj  ,jk  ),   &
332               &                     pbef(ji  ,jj  ,ikm1), pbef(ji  ,jj  ,jk+1),   &
333               &                     paft(ji  ,jj  ,ikm1), paft(ji  ,jj  ,jk+1)  )
334         END_2D
335      END DO
336      !                    ! restore masked values to zero
337      DO_3D( 0, 0, 0, 0, 1, jpk )
338         pbef(ji,jj,jk) = pbef(ji,jj,jk) * tmask(ji,jj,jk)
339         paft(ji,jj,jk) = paft(ji,jj,jk) * tmask(ji,jj,jk)
340      END_3D
341      !
342      ! Positive and negative part of fluxes and beta terms
343      ! ---------------------------------------------------
344      DO_3D( 0, 0, 0, 0, 1, jpkm1 )
345         ! positive & negative part of the flux
346         zpos = MAX( 0., pcc(ji  ,jj  ,jk+1) ) - MIN( 0., pcc(ji  ,jj  ,jk  ) )
347         zneg = MAX( 0., pcc(ji  ,jj  ,jk  ) ) - MIN( 0., pcc(ji  ,jj  ,jk+1) )
348         ! up & down beta terms
349         zbt = e1e2t(ji,jj) * e3t(ji,jj,jk,Kmm) / p2dt
350         zbetup(ji,jj,jk) = ( zbetup(ji,jj,jk) - paft(ji,jj,jk) ) / (zpos+zrtrn) * zbt
351         zbetdo(ji,jj,jk) = ( paft(ji,jj,jk) - zbetdo(ji,jj,jk) ) / (zneg+zrtrn) * zbt
352      END_3D
353      !
354      ! monotonic flux in the k direction, i.e. pcc
355      ! -------------------------------------------
356      DO_3D( 0, 0, 0, 0, 2, jpkm1 )
357         za = MIN( 1., zbetdo(ji,jj,jk), zbetup(ji,jj,jk-1) )
358         zb = MIN( 1., zbetup(ji,jj,jk), zbetdo(ji,jj,jk-1) )
359         zc = 0.5 * ( 1.e0 + SIGN( 1.0_wp, pcc(ji,jj,jk) ) )
360         pcc(ji,jj,jk) = pcc(ji,jj,jk) * ( zc * za + ( 1.e0 - zc) * zb )
361      END_3D
362      !
363   END SUBROUTINE nonosc_z
364
365   !!======================================================================
366END MODULE traadv_ubs_lf
Note: See TracBrowser for help on using the repository browser.