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_qck.F90 in branches/2017/dev_r7881_no_wrk_alloc/NEMOGCM/NEMO/OPA_SRC/TRA – NEMO

source: branches/2017/dev_r7881_no_wrk_alloc/NEMOGCM/NEMO/OPA_SRC/TRA/traadv_qck.F90 @ 7910

Last change on this file since 7910 was 7910, checked in by timgraham, 7 years ago

All wrk_alloc removed

  • Property svn:keywords set to Id
File size: 23.6 KB
Line 
1MODULE traadv_qck
2   !!==============================================================================
3   !!                       ***  MODULE  traadv_qck  ***
4   !! Ocean tracers:  horizontal & vertical advective trend
5   !!==============================================================================
6   !! History :  3.0  !  2008-07  (G. Reffray)  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_qck    : update the tracer trend with the horizontal advection
12   !!                    trends using a 3rd order finite difference scheme
13   !!   tra_adv_qck_i  : apply QUICK scheme in i-direction
14   !!   tra_adv_qck_j  : apply QUICK scheme in j-direction
15   !!   tra_adv_cen2_k : 2nd centered scheme for the vertical advection
16   !!----------------------------------------------------------------------
17   USE oce             ! ocean dynamics and active tracers
18   USE dom_oce         ! ocean space and time domain
19   USE trc_oce         ! share passive tracers/Ocean variables
20   USE trd_oce         ! trends: ocean variables
21   USE trdtra          ! trends manager: tracers
22   USE diaptr          ! poleward transport diagnostics
23   !
24   USE lib_mpp         ! distribued memory computing
25   USE lbclnk          ! ocean lateral boundary condition (or mpp link)
26   USE in_out_manager  ! I/O manager
27   USE timing          ! Timing
28   USE lib_fortran     ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 
29
30   IMPLICIT NONE
31   PRIVATE
32
33   PUBLIC   tra_adv_qck   ! routine called by step.F90
34
35   REAL(wp) :: r1_6 = 1./ 6.   ! 1/6 ratio
36
37   LOGICAL  ::   l_trd   ! flag to compute trends
38   LOGICAL  ::   l_ptr   ! flag to compute poleward transport
39
40
41   !! * Substitutions
42#  include "vectopt_loop_substitute.h90"
43   !!----------------------------------------------------------------------
44   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
45   !! $Id$
46   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
47   !!----------------------------------------------------------------------
48CONTAINS
49
50   SUBROUTINE tra_adv_qck ( kt, kit000, cdtype, p2dt, pun, pvn, pwn,      &
51      &                                       ptb, ptn, pta, kjpt )
52      !!----------------------------------------------------------------------
53      !!                  ***  ROUTINE tra_adv_qck  ***
54      !!
55      !! ** Purpose :   Compute the now trend due to the advection of tracers
56      !!      and add it to the general trend of passive tracer equations.
57      !!
58      !! ** Method :   The advection is evaluated by a third order scheme
59      !!             For a positive velocity u :              u(i)>0
60      !!                                          |--FU--|--FC--|--FD--|------|
61      !!                                             i-1    i      i+1   i+2
62      !!
63      !!             For a negative velocity u :              u(i)<0
64      !!                                          |------|--FD--|--FC--|--FU--|
65      !!                                             i-1    i      i+1   i+2
66      !!             where  FU is the second upwind point
67      !!                    FD is the first douwning point
68      !!                    FC is the central point (or the first upwind point)
69      !!
70      !!      Flux(i) = u(i) * { 0.5(FC+FD)  -0.5C(i)(FD-FC)  -((1-C(i))/6)(FU+FD-2FC) }
71      !!                with C(i)=|u(i)|dx(i)/dt (=Courant number)
72      !!
73      !!         dt = 2*rdtra and the scalar values are tb and sb
74      !!
75      !!       On the vertical, the simple centered scheme used ptn
76      !!
77      !!               The fluxes are bounded by the ULTIMATE limiter to
78      !!             guarantee the monotonicity of the solution and to
79      !!            prevent the appearance of spurious numerical oscillations
80      !!
81      !! ** Action : - update pta  with the now advective tracer trends
82      !!             - send trends to trdtra module for further diagnostcs (l_trdtra=T)
83      !!             - htr_adv, str_adv : poleward advective heat and salt transport (ln_diaptr=T)
84      !!
85      !! ** Reference : Leonard (1979, 1991)
86      !!----------------------------------------------------------------------
87      INTEGER                              , INTENT(in   ) ::   kt              ! ocean time-step index
88      INTEGER                              , INTENT(in   ) ::   kit000          ! first time step index
89      CHARACTER(len=3)                     , INTENT(in   ) ::   cdtype          ! =TRA or TRC (tracer indicator)
90      INTEGER                              , INTENT(in   ) ::   kjpt            ! number of tracers
91      REAL(wp)                             , INTENT(in   ) ::   p2dt            ! tracer time-step
92      REAL(wp), DIMENSION(jpi,jpj,jpk     ), INTENT(in   ) ::   pun, pvn, pwn   ! 3 ocean velocity components
93      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(in   ) ::   ptb, ptn        ! before and now tracer fields
94      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(inout) ::   pta             ! tracer trend
95      !!----------------------------------------------------------------------
96      !
97      IF( nn_timing == 1 )  CALL timing_start('tra_adv_qck')
98      !
99      IF( kt == kit000 )  THEN
100         IF(lwp) WRITE(numout,*)
101         IF(lwp) WRITE(numout,*) 'tra_adv_qck : 3rd order quickest advection scheme on ', cdtype
102         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~'
103         IF(lwp) WRITE(numout,*)
104      ENDIF
105      !
106      l_trd = .FALSE.
107      l_ptr = .FALSE.
108      IF( ( cdtype == 'TRA' .AND. l_trdtra ) .OR. ( cdtype == 'TRC' .AND. l_trdtrc ) )      l_trd = .TRUE.
109      IF(   cdtype == 'TRA' .AND. ln_diaptr )                                               l_ptr = .TRUE. 
110      !
111      !
112      !        ! horizontal fluxes are computed with the QUICKEST + ULTIMATE scheme
113      CALL tra_adv_qck_i( kt, cdtype, p2dt, pun, ptb, ptn, pta, kjpt ) 
114      CALL tra_adv_qck_j( kt, cdtype, p2dt, pvn, ptb, ptn, pta, kjpt ) 
115
116      !        ! vertical fluxes are computed with the 2nd order centered scheme
117      CALL tra_adv_cen2_k( kt, cdtype, pwn,         ptn, pta, kjpt )
118      !
119      IF( nn_timing == 1 )  CALL timing_stop('tra_adv_qck')
120      !
121   END SUBROUTINE tra_adv_qck
122
123
124   SUBROUTINE tra_adv_qck_i( kt, cdtype, p2dt, pun,                  &
125      &                                        ptb, ptn, pta, kjpt   )
126      !!----------------------------------------------------------------------
127      !!
128      !!----------------------------------------------------------------------
129      INTEGER                              , INTENT(in   ) ::   kt         ! ocean time-step index
130      CHARACTER(len=3)                     , INTENT(in   ) ::   cdtype     ! =TRA or TRC (tracer indicator)
131      INTEGER                              , INTENT(in   ) ::   kjpt       ! number of tracers
132      REAL(wp)                             , INTENT(in   ) ::   p2dt       ! tracer time-step
133      REAL(wp), DIMENSION(jpi,jpj,jpk     ), INTENT(in   ) ::   pun        ! i-velocity components
134      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(in   ) ::   ptb, ptn   ! before and now tracer fields
135      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(inout) ::   pta        ! tracer trend
136      !!
137      INTEGER  ::   ji, jj, jk, jn   ! dummy loop indices
138      REAL(wp) ::   ztra, zbtr, zdir, zdx, zmsk   ! local scalars
139      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zwx, zfu, zfc, zfd
140      !----------------------------------------------------------------------
141      !
142      !                                                          ! ===========
143      DO jn = 1, kjpt                                            ! tracer loop
144         !                                                       ! ===========
145         zfu(:,:,:) = 0._wp     ;   zfc(:,:,:) = 0._wp 
146         zfd(:,:,:) = 0._wp     ;   zwx(:,:,:) = 0._wp   
147         !
148!!gm why not using a SHIFT instruction...
149         DO jk = 1, jpkm1     !--- Computation of the ustream and downstream value of the tracer and the mask
150            DO jj = 2, jpjm1
151               DO ji = fs_2, fs_jpim1   ! vector opt.
152                  zfc(ji,jj,jk) = ptb(ji-1,jj,jk,jn)        ! Upstream   in the x-direction for the tracer
153                  zfd(ji,jj,jk) = ptb(ji+1,jj,jk,jn)        ! Downstream in the x-direction for the tracer
154               END DO
155            END DO
156         END DO
157         CALL lbc_lnk( zfc(:,:,:), 'T', 1. )   ;   CALL lbc_lnk( zfd(:,:,:), 'T', 1. )   ! Lateral boundary conditions
158         
159         !
160         ! Horizontal advective fluxes
161         ! ---------------------------
162         DO jk = 1, jpkm1                             
163            DO jj = 2, jpjm1
164               DO ji = fs_2, fs_jpim1   ! vector opt.         
165                  zdir = 0.5 + SIGN( 0.5, pun(ji,jj,jk) )   ! if pun > 0 : zdir = 1 otherwise zdir = 0
166                  zfu(ji,jj,jk) = zdir * zfc(ji,jj,jk ) + ( 1. - zdir ) * zfd(ji+1,jj,jk)  ! FU in the x-direction for T
167               END DO
168            END DO
169         END DO
170         !
171         DO jk = 1, jpkm1 
172            DO jj = 2, jpjm1
173               DO ji = fs_2, fs_jpim1   ! vector opt.   
174                  zdir = 0.5 + SIGN( 0.5, pun(ji,jj,jk) )   ! if pun > 0 : zdir = 1 otherwise zdir = 0
175                  zdx = ( zdir * e1t(ji,jj) + ( 1. - zdir ) * e1t(ji+1,jj) ) * e2u(ji,jj) * e3u_n(ji,jj,jk)
176                  zwx(ji,jj,jk)  = ABS( pun(ji,jj,jk) ) * p2dt / zdx    ! (0<zc_cfl<1 : Courant number on x-direction)
177                  zfc(ji,jj,jk)  = zdir * ptb(ji  ,jj,jk,jn) + ( 1. - zdir ) * ptb(ji+1,jj,jk,jn)  ! FC in the x-direction for T
178                  zfd(ji,jj,jk)  = zdir * ptb(ji+1,jj,jk,jn) + ( 1. - zdir ) * ptb(ji  ,jj,jk,jn)  ! FD in the x-direction for T
179               END DO
180            END DO
181         END DO 
182         !--- Lateral boundary conditions
183         CALL lbc_lnk( zfu(:,:,:), 'T', 1. )   ;   CALL lbc_lnk( zfd(:,:,:), 'T', 1. )
184         CALL lbc_lnk( zfc(:,:,:), 'T', 1. )   ;   CALL lbc_lnk( zwx(:,:,:), 'T', 1. )
185
186         !--- QUICKEST scheme
187         CALL quickest( zfu, zfd, zfc, zwx )
188         !
189         ! Mask at the T-points in the x-direction (mask=0 or mask=1)
190         DO jk = 1, jpkm1 
191            DO jj = 2, jpjm1
192               DO ji = fs_2, fs_jpim1   ! vector opt.               
193                  zfu(ji,jj,jk) = tmask(ji-1,jj,jk) + tmask(ji,jj,jk) + tmask(ji+1,jj,jk) - 2.
194               END DO
195            END DO
196         END DO
197         CALL lbc_lnk( zfu(:,:,:), 'T', 1. )      ! Lateral boundary conditions
198
199         !
200         ! Tracer flux on the x-direction
201         DO jk = 1, jpkm1 
202            !
203            DO jj = 2, jpjm1
204               DO ji = fs_2, fs_jpim1   ! vector opt.               
205                  zdir = 0.5 + SIGN( 0.5, pun(ji,jj,jk) )   ! if pun > 0 : zdir = 1 otherwise zdir = 0
206                  !--- If the second ustream point is a land point
207                  !--- the flux is computed by the 1st order UPWIND scheme
208                  zmsk = zdir * zfu(ji,jj,jk) + ( 1. - zdir ) * zfu(ji+1,jj,jk)
209                  zwx(ji,jj,jk) = zmsk * zwx(ji,jj,jk) + ( 1. - zmsk ) * zfc(ji,jj,jk)
210                  zwx(ji,jj,jk) = zwx(ji,jj,jk) * pun(ji,jj,jk)
211               END DO
212            END DO
213         END DO
214         !
215         CALL lbc_lnk( zwx(:,:,:), 'T', 1. ) ! Lateral boundary conditions
216         !
217         ! Computation of the trend
218         DO jk = 1, jpkm1 
219            DO jj = 2, jpjm1
220               DO ji = fs_2, fs_jpim1   ! vector opt. 
221                  zbtr = r1_e1e2t(ji,jj) / e3t_n(ji,jj,jk)
222                  ! horizontal advective trends
223                  ztra = - zbtr * ( zwx(ji,jj,jk) - zwx(ji-1,jj,jk) )
224                  !--- add it to the general tracer trends
225                  pta(ji,jj,jk,jn) = pta(ji,jj,jk,jn) + ztra
226               END DO
227            END DO
228         END DO
229         !                                 ! trend diagnostics
230         IF( l_trd )                     CALL trd_tra( kt, cdtype, jn, jptra_xad, zwx, pun, ptn(:,:,:,jn) )
231         !
232      END DO
233      !
234      !
235   END SUBROUTINE tra_adv_qck_i
236
237
238   SUBROUTINE tra_adv_qck_j( kt, cdtype, p2dt, pvn,                &
239      &                                        ptb, ptn, pta, kjpt )
240      !!----------------------------------------------------------------------
241      !!
242      !!----------------------------------------------------------------------
243      INTEGER                              , INTENT(in   ) ::   kt         ! ocean time-step index
244      CHARACTER(len=3)                     , INTENT(in   ) ::   cdtype     ! =TRA or TRC (tracer indicator)
245      INTEGER                              , INTENT(in   ) ::   kjpt       ! number of tracers
246      REAL(wp)                             , INTENT(in   ) ::   p2dt       ! tracer time-step
247      REAL(wp), DIMENSION(jpi,jpj,jpk     ), INTENT(in   ) ::   pvn        ! j-velocity components
248      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(in   ) ::   ptb, ptn   ! before and now tracer fields
249      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(inout) ::   pta        ! tracer trend
250      !!
251      INTEGER  :: ji, jj, jk, jn   ! dummy loop indices
252      REAL(wp) :: ztra, zbtr, zdir, zdx, zmsk   ! local scalars
253      REAL(wp), DIMENSION(jpi,jpj,jpk) :: zwy, zfu, zfc, zfd
254      !----------------------------------------------------------------------
255      !
256      !
257      !                                                          ! ===========
258      DO jn = 1, kjpt                                            ! tracer loop
259         !                                                       ! ===========
260         zfu(:,:,:) = 0.0     ;   zfc(:,:,:) = 0.0 
261         zfd(:,:,:) = 0.0     ;   zwy(:,:,:) = 0.0     
262         !                                                 
263         DO jk = 1, jpkm1                               
264            !                                             
265            !--- Computation of the ustream and downstream value of the tracer and the mask
266            DO jj = 2, jpjm1
267               DO ji = fs_2, fs_jpim1   ! vector opt.
268                  ! Upstream in the x-direction for the tracer
269                  zfc(ji,jj,jk) = ptb(ji,jj-1,jk,jn)
270                  ! Downstream in the x-direction for the tracer
271                  zfd(ji,jj,jk) = ptb(ji,jj+1,jk,jn)
272               END DO
273            END DO
274         END DO
275         CALL lbc_lnk( zfc(:,:,:), 'T', 1. )   ;   CALL lbc_lnk( zfd(:,:,:), 'T', 1. )   ! Lateral boundary conditions
276
277         
278         !
279         ! Horizontal advective fluxes
280         ! ---------------------------
281         !
282         DO jk = 1, jpkm1                             
283            DO jj = 2, jpjm1
284               DO ji = fs_2, fs_jpim1   ! vector opt.         
285                  zdir = 0.5 + SIGN( 0.5, pvn(ji,jj,jk) )   ! if pun > 0 : zdir = 1 otherwise zdir = 0
286                  zfu(ji,jj,jk) = zdir * zfc(ji,jj,jk ) + ( 1. - zdir ) * zfd(ji,jj+1,jk)  ! FU in the x-direction for T
287               END DO
288            END DO
289         END DO
290         !
291         DO jk = 1, jpkm1 
292            DO jj = 2, jpjm1
293               DO ji = fs_2, fs_jpim1   ! vector opt.   
294                  zdir = 0.5 + SIGN( 0.5, pvn(ji,jj,jk) )   ! if pun > 0 : zdir = 1 otherwise zdir = 0
295                  zdx = ( zdir * e2t(ji,jj) + ( 1. - zdir ) * e2t(ji,jj+1) ) * e1v(ji,jj) * e3v_n(ji,jj,jk)
296                  zwy(ji,jj,jk)  = ABS( pvn(ji,jj,jk) ) * p2dt / zdx    ! (0<zc_cfl<1 : Courant number on x-direction)
297                  zfc(ji,jj,jk)  = zdir * ptb(ji,jj  ,jk,jn) + ( 1. - zdir ) * ptb(ji,jj+1,jk,jn)  ! FC in the x-direction for T
298                  zfd(ji,jj,jk)  = zdir * ptb(ji,jj+1,jk,jn) + ( 1. - zdir ) * ptb(ji,jj  ,jk,jn)  ! FD in the x-direction for T
299               END DO
300            END DO
301         END DO
302
303         !--- Lateral boundary conditions
304         CALL lbc_lnk( zfu(:,:,:), 'T', 1. )      ;     CALL lbc_lnk( zfd(:,:,:), 'T', 1. )
305         CALL lbc_lnk( zfc(:,:,:), 'T', 1. )      ;     CALL lbc_lnk( zwy(:,:,:), 'T', 1. )
306
307         !--- QUICKEST scheme
308         CALL quickest( zfu, zfd, zfc, zwy )
309         !
310         ! Mask at the T-points in the x-direction (mask=0 or mask=1)
311         DO jk = 1, jpkm1 
312            DO jj = 2, jpjm1
313               DO ji = fs_2, fs_jpim1   ! vector opt.               
314                  zfu(ji,jj,jk) = tmask(ji,jj-1,jk) + tmask(ji,jj,jk) + tmask(ji,jj+1,jk) - 2.
315               END DO
316            END DO
317         END DO
318         !--- Lateral boundary conditions
319         CALL lbc_lnk( zfu(:,:,:), 'T', 1. ) 
320         !
321         ! Tracer flux on the x-direction
322         DO jk = 1, jpkm1 
323            !
324            DO jj = 2, jpjm1
325               DO ji = fs_2, fs_jpim1   ! vector opt.               
326                  zdir = 0.5 + SIGN( 0.5, pvn(ji,jj,jk) )   ! if pun > 0 : zdir = 1 otherwise zdir = 0
327                  !--- If the second ustream point is a land point
328                  !--- the flux is computed by the 1st order UPWIND scheme
329                  zmsk = zdir * zfu(ji,jj,jk) + ( 1. - zdir ) * zfu(ji,jj+1,jk)
330                  zwy(ji,jj,jk) = zmsk * zwy(ji,jj,jk) + ( 1. - zmsk ) * zfc(ji,jj,jk)
331                  zwy(ji,jj,jk) = zwy(ji,jj,jk) * pvn(ji,jj,jk)
332               END DO
333            END DO
334         END DO
335         !
336         CALL lbc_lnk( zwy(:,:,:), 'T', 1. ) ! Lateral boundary conditions
337         !
338         ! Computation of the trend
339         DO jk = 1, jpkm1 
340            DO jj = 2, jpjm1
341               DO ji = fs_2, fs_jpim1   ! vector opt. 
342                  zbtr = r1_e1e2t(ji,jj) / e3t_n(ji,jj,jk)
343                  ! horizontal advective trends
344                  ztra = - zbtr * ( zwy(ji,jj,jk) - zwy(ji,jj-1,jk) )
345                  !--- add it to the general tracer trends
346                  pta(ji,jj,jk,jn) = pta(ji,jj,jk,jn) + ztra
347               END DO
348            END DO
349         END DO
350         !                                 ! trend diagnostics
351         IF( l_trd )                     CALL trd_tra( kt, cdtype, jn, jptra_yad, zwy, pvn, ptn(:,:,:,jn) )
352         !                                 ! "Poleward" heat and salt transports (contribution of upstream fluxes)
353         IF( l_ptr )                     CALL dia_ptr_hst( jn, 'adv', zwy(:,:,:) )
354         !
355      END DO
356      !
357      !
358   END SUBROUTINE tra_adv_qck_j
359
360
361   SUBROUTINE tra_adv_cen2_k( kt, cdtype, pwn,           &
362     &                                    ptn, pta, kjpt )
363      !!----------------------------------------------------------------------
364      !!
365      !!----------------------------------------------------------------------
366      INTEGER                              , INTENT(in   ) ::   kt       ! ocean time-step index
367      CHARACTER(len=3)                     , INTENT(in   ) ::   cdtype   ! =TRA or TRC (tracer indicator)
368      INTEGER                              , INTENT(in   ) ::   kjpt     ! number of tracers
369      REAL(wp), DIMENSION(jpi,jpj,jpk     ), INTENT(in   ) ::   pwn      ! vertical velocity
370      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(in   ) ::   ptn      ! before and now tracer fields
371      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(inout) ::   pta      ! tracer trend
372      !
373      INTEGER  ::   ji, jj, jk, jn   ! dummy loop indices
374      REAL(wp), DIMENSION(jpi,jpj,jpk) :: zwz
375      !!----------------------------------------------------------------------
376      !
377      !
378      zwz(:,:, 1 ) = 0._wp       ! surface & bottom values set to zero for all tracers
379      zwz(:,:,jpk) = 0._wp
380      !
381      !                                                          ! ===========
382      DO jn = 1, kjpt                                            ! tracer loop
383         !                                                       ! ===========
384         !
385         DO jk = 2, jpkm1                    !* Interior point   (w-masked 2nd order centered flux)
386            DO jj = 2, jpjm1
387               DO ji = fs_2, fs_jpim1   ! vector opt.
388                  zwz(ji,jj,jk) = 0.5 * pwn(ji,jj,jk) * ( ptn(ji,jj,jk-1,jn) + ptn(ji,jj,jk,jn) ) * wmask(ji,jj,jk)
389               END DO
390            END DO
391         END DO
392         IF( ln_linssh ) THEN                !* top value   (only in linear free surf. as zwz is multiplied by wmask)
393            IF( ln_isfcav ) THEN                  ! ice-shelf cavities (top of the ocean)
394               DO jj = 1, jpj
395                  DO ji = 1, jpi
396                     zwz(ji,jj, mikt(ji,jj) ) = pwn(ji,jj,mikt(ji,jj)) * ptn(ji,jj,mikt(ji,jj),jn)   ! linear free surface
397                  END DO
398               END DO   
399            ELSE                                   ! no ocean cavities (only ocean surface)
400               zwz(:,:,1) = pwn(:,:,1) * ptn(:,:,1,jn)
401            ENDIF
402         ENDIF
403         !
404         DO jk = 1, jpkm1          !==  Tracer flux divergence added to the general trend  ==!
405            DO jj = 2, jpjm1
406               DO ji = fs_2, fs_jpim1   ! vector opt.
407                  pta(ji,jj,jk,jn) = pta(ji,jj,jk,jn) - ( zwz(ji,jj,jk) - zwz(ji,jj,jk+1) )   &
408                     &                                * r1_e1e2t(ji,jj) / e3t_n(ji,jj,jk)
409               END DO
410            END DO
411         END DO
412         !                                 ! Send trends for diagnostic
413         IF( l_trd )  CALL trd_tra( kt, cdtype, jn, jptra_zad, zwz, pwn, ptn(:,:,:,jn) )
414         !
415      END DO
416      !
417      !
418   END SUBROUTINE tra_adv_cen2_k
419
420
421   SUBROUTINE quickest( pfu, pfd, pfc, puc )
422      !!----------------------------------------------------------------------
423      !!
424      !! ** Purpose :  Computation of advective flux with Quickest scheme
425      !!
426      !! ** Method :   
427      !!----------------------------------------------------------------------
428      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(in   ) ::   pfu   ! second upwind point
429      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(in   ) ::   pfd   ! first douwning point
430      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(in   ) ::   pfc   ! the central point (or the first upwind point)
431      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   puc   ! input as Courant number ; output as flux
432      !!
433      INTEGER  ::  ji, jj, jk               ! dummy loop indices
434      REAL(wp) ::  zcoef1, zcoef2, zcoef3   ! local scalars         
435      REAL(wp) ::  zc, zcurv, zfho          !   -      -
436      !----------------------------------------------------------------------
437      !
438      IF( nn_timing == 1 )  CALL timing_start('quickest')
439      !
440      DO jk = 1, jpkm1
441         DO jj = 1, jpj
442            DO ji = 1, jpi
443               zc     = puc(ji,jj,jk)                         ! Courant number
444               zcurv  = pfd(ji,jj,jk) + pfu(ji,jj,jk) - 2. * pfc(ji,jj,jk)
445               zcoef1 = 0.5 *      ( pfc(ji,jj,jk) + pfd(ji,jj,jk) )
446               zcoef2 = 0.5 * zc * ( pfd(ji,jj,jk) - pfc(ji,jj,jk) )
447               zcoef3 = ( 1. - ( zc * zc ) ) * r1_6 * zcurv
448               zfho   = zcoef1 - zcoef2 - zcoef3              !  phi_f QUICKEST
449               !
450               zcoef1 = pfd(ji,jj,jk) - pfu(ji,jj,jk)
451               zcoef2 = ABS( zcoef1 )
452               zcoef3 = ABS( zcurv )
453               IF( zcoef3 >= zcoef2 ) THEN
454                  zfho = pfc(ji,jj,jk) 
455               ELSE
456                  zcoef3 = pfu(ji,jj,jk) + ( ( pfc(ji,jj,jk) - pfu(ji,jj,jk) ) / MAX( zc, 1.e-9 ) )    ! phi_REF
457                  IF( zcoef1 >= 0. ) THEN
458                     zfho = MAX( pfc(ji,jj,jk), zfho ) 
459                     zfho = MIN( zfho, MIN( zcoef3, pfd(ji,jj,jk) ) ) 
460                  ELSE
461                     zfho = MIN( pfc(ji,jj,jk), zfho ) 
462                     zfho = MAX( zfho, MAX( zcoef3, pfd(ji,jj,jk) ) ) 
463                  ENDIF
464               ENDIF
465               puc(ji,jj,jk) = zfho
466            END DO
467         END DO
468      END DO
469      !
470      IF( nn_timing == 1 )  CALL timing_stop('quickest')
471      !
472   END SUBROUTINE quickest
473
474   !!======================================================================
475END MODULE traadv_qck
Note: See TracBrowser for help on using the repository browser.