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 NEMO/trunk/src/OCE/TRA – NEMO

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

Last change on this file was 14978, checked in by hadcv, 3 years ago

#2640: correct tra_adv_qck results on the north fold

  • Property svn:keywords set to Id
File size: 22.2 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   USE iom
24   !
25   USE in_out_manager  ! I/O manager
26   USE lib_mpp         ! distribued memory computing
27   USE lbclnk          ! ocean lateral boundary condition (or mpp link)
28   USE lib_fortran     ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined)
29#if defined key_loop_fusion
30   USE traadv_qck_lf   ! QCK    scheme            (tra_adv_qck  routine - loop fusion version)
31#endif
32
33   IMPLICIT NONE
34   PRIVATE
35
36   PUBLIC   tra_adv_qck   ! routine called by step.F90
37
38   REAL(wp) :: r1_6 = 1./ 6.   ! 1/6 ratio
39
40   LOGICAL  ::   l_trd   ! flag to compute trends
41   LOGICAL  ::   l_ptr   ! flag to compute poleward transport
42
43
44   !! * Substitutions
45#  include "do_loop_substitute.h90"
46#  include "domzgr_substitute.h90"
47   !!----------------------------------------------------------------------
48   !! NEMO/OCE 4.0 , NEMO Consortium (2018)
49   !! $Id$
50   !! Software governed by the CeCILL license (see ./LICENSE)
51   !!----------------------------------------------------------------------
52CONTAINS
53
54   SUBROUTINE tra_adv_qck ( kt, kit000, cdtype, p2dt, pU, pV, pW, Kbb, Kmm, pt, kjpt, Krhs )
55      !!----------------------------------------------------------------------
56      !!                  ***  ROUTINE tra_adv_qck  ***
57      !!
58      !! ** Purpose :   Compute the now trend due to the advection of tracers
59      !!      and add it to the general trend of passive tracer equations.
60      !!
61      !! ** Method :   The advection is evaluated by a third order scheme
62      !!             For a positive velocity u :              u(i)>0
63      !!                                          |--FU--|--FC--|--FD--|------|
64      !!                                             i-1    i      i+1   i+2
65      !!
66      !!             For a negative velocity u :              u(i)<0
67      !!                                          |------|--FD--|--FC--|--FU--|
68      !!                                             i-1    i      i+1   i+2
69      !!             where  FU is the second upwind point
70      !!                    FD is the first douwning point
71      !!                    FC is the central point (or the first upwind point)
72      !!
73      !!      Flux(i) = u(i) * { 0.5(FC+FD)  -0.5C(i)(FD-FC)  -((1-C(i))/6)(FU+FD-2FC) }
74      !!                with C(i)=|u(i)|dx(i)/dt (=Courant number)
75      !!
76      !!         dt = 2*rdtra and the scalar values are tb and sb
77      !!
78      !!       On the vertical, the simple centered scheme used pt(:,:,:,:,Kmm)
79      !!
80      !!               The fluxes are bounded by the ULTIMATE limiter to
81      !!             guarantee the monotonicity of the solution and to
82      !!            prevent the appearance of spurious numerical oscillations
83      !!
84      !! ** Action : - update pt(:,:,:,:,Krhs)  with the now advective tracer trends
85      !!             - send trends to trdtra module for further diagnostcs (l_trdtra=T)
86      !!             - poleward advective heat and salt transport (ln_diaptr=T)
87      !!
88      !! ** Reference : Leonard (1979, 1991)
89      !!----------------------------------------------------------------------
90      INTEGER                                  , INTENT(in   ) ::   kt              ! ocean time-step index
91      INTEGER                                  , INTENT(in   ) ::   Kbb, Kmm, Krhs  ! ocean time level indices
92      INTEGER                                  , INTENT(in   ) ::   kit000          ! first time step index
93      CHARACTER(len=3)                         , INTENT(in   ) ::   cdtype          ! =TRA or TRC (tracer indicator)
94      INTEGER                                  , INTENT(in   ) ::   kjpt            ! number of tracers
95      REAL(wp)                                 , INTENT(in   ) ::   p2dt            ! tracer time-step
96      ! TEMP: [tiling] This can be A2D(nn_hls) after all lbc_lnks removed in the nn_hls = 2 case in tra_adv_fct
97      REAL(wp), DIMENSION(jpi,jpj,jpk         ), INTENT(in   ) ::   pU, pV, pW      ! 3 ocean volume transport components
98      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt,jpt), INTENT(inout) ::   pt              ! tracers and RHS of tracer equation
99      !!----------------------------------------------------------------------
100      !
101#if defined key_loop_fusion
102      CALL tra_adv_qck_lf ( kt, kit000, cdtype, p2dt, pU, pV, pW, Kbb, Kmm, pt, kjpt, Krhs )
103#else
104      IF( .NOT. l_istiled .OR. ntile == 1 )  THEN                       ! Do only on the first tile
105         IF( kt == kit000 )  THEN
106            IF(lwp) WRITE(numout,*)
107            IF(lwp) WRITE(numout,*) 'tra_adv_qck : 3rd order quickest advection scheme on ', cdtype
108            IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~'
109            IF(lwp) WRITE(numout,*)
110         ENDIF
111         !
112         l_trd = .FALSE.
113         l_ptr = .FALSE.
114         IF( ( cdtype == 'TRA' .AND. l_trdtra ) .OR. ( cdtype == 'TRC' .AND. l_trdtrc ) )   l_trd = .TRUE.
115         IF(   cdtype == 'TRA' .AND. ( iom_use( 'sophtadv' ) .OR. iom_use( 'sophtadv' ) ) ) l_ptr = .TRUE.
116      ENDIF
117      !
118      !        ! horizontal fluxes are computed with the QUICKEST + ULTIMATE scheme
119      CALL tra_adv_qck_i( kt, cdtype, p2dt, pU, Kbb, Kmm, pt, kjpt, Krhs )
120      CALL tra_adv_qck_j( kt, cdtype, p2dt, pV, Kbb, Kmm, pt, kjpt, Krhs )
121
122      !        ! vertical fluxes are computed with the 2nd order centered scheme
123      CALL tra_adv_cen2_k( kt, cdtype, pW, Kmm, pt, kjpt, Krhs )
124      !
125#endif
126   END SUBROUTINE tra_adv_qck
127
128
129   SUBROUTINE tra_adv_qck_i( kt, cdtype, p2dt, pU, Kbb, Kmm, pt, kjpt, Krhs )
130      !!----------------------------------------------------------------------
131      !!
132      !!----------------------------------------------------------------------
133      INTEGER                                  , INTENT(in   ) ::   kt         ! ocean time-step index
134      INTEGER                                  , INTENT(in   ) ::   Kbb, Kmm, Krhs  ! ocean time level indices
135      CHARACTER(len=3)                         , INTENT(in   ) ::   cdtype     ! =TRA or TRC (tracer indicator)
136      INTEGER                                  , INTENT(in   ) ::   kjpt       ! number of tracers
137      REAL(wp)                                 , INTENT(in   ) ::   p2dt       ! tracer time-step
138      ! TEMP: [tiling] This can be A2D(nn_hls) after all lbc_lnks removed in the nn_hls = 2 case in tra_adv_fct
139      REAL(wp), DIMENSION(jpi,jpj,jpk         ), INTENT(in   ) ::   pU        ! i-velocity components
140      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt,jpt), INTENT(inout) ::   pt              ! active tracers and RHS of tracer equation
141      !!
142      INTEGER  ::   ji, jj, jk, jn   ! dummy loop indices
143      REAL(wp) ::   ztra, zbtr, zdir, zdx, zmsk   ! local scalars
144      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zwx, zfu, zfc, zfd
145      !----------------------------------------------------------------------
146      !
147      !                                                          ! ===========
148      DO jn = 1, kjpt                                            ! tracer loop
149         !                                                       ! ===========
150         zfu(:,:,:) = 0._wp     ;   zfc(:,:,:) = 0._wp
151         zfd(:,:,:) = 0._wp     ;   zwx(:,:,:) = 0._wp
152         !
153!!gm why not using a SHIFT instruction...
154         DO_3D( nn_hls-1, nn_hls-1, 0, 0, 1, jpkm1 )     !--- Computation of the ustream and downstream value of the tracer and the mask
155            zfc(ji,jj,jk) = pt(ji-1,jj,jk,jn,Kbb)        ! Upstream   in the x-direction for the tracer
156            zfd(ji,jj,jk) = pt(ji+1,jj,jk,jn,Kbb)        ! Downstream in the x-direction for the tracer
157         END_3D
158         IF (nn_hls==1) CALL lbc_lnk( 'traadv_qck', zfc(:,:,:), 'T', 1.0_wp , zfd(:,:,:), 'T', 1.0_wp, ld4only= .TRUE. )   ! Lateral boundary conditions
159
160         !
161         ! Horizontal advective fluxes
162         ! ---------------------------
163         DO_3D( nn_hls-1, 0, 0, 0, 1, jpkm1 )
164            zdir = 0.5 + SIGN( 0.5_wp, pU(ji,jj,jk) )   ! if pU > 0 : zdir = 1 otherwise zdir = 0
165            zfu(ji,jj,jk) = zdir * zfc(ji,jj,jk ) + ( 1. - zdir ) * zfd(ji+1,jj,jk)  ! FU in the x-direction for T
166         END_3D
167         !
168         DO_3D( nn_hls-1, 0, 0, 0, 1, jpkm1 )
169            zdir = 0.5 + SIGN( 0.5_wp, pU(ji,jj,jk) )   ! if pU > 0 : zdir = 1 otherwise zdir = 0
170            zdx = ( zdir * e1t(ji,jj) + ( 1. - zdir ) * e1t(ji+1,jj) ) * e2u(ji,jj) * e3u(ji,jj,jk,Kmm)
171            zwx(ji,jj,jk)  = ABS( pU(ji,jj,jk) ) * p2dt / zdx    ! (0<zc_cfl<1 : Courant number on x-direction)
172            zfc(ji,jj,jk)  = zdir * pt(ji  ,jj,jk,jn,Kbb) + ( 1. - zdir ) * pt(ji+1,jj,jk,jn,Kbb)  ! FC in the x-direction for T
173            zfd(ji,jj,jk)  = zdir * pt(ji+1,jj,jk,jn,Kbb) + ( 1. - zdir ) * pt(ji  ,jj,jk,jn,Kbb)  ! FD in the x-direction for T
174         END_3D
175         !--- Lateral boundary conditions
176         IF (nn_hls==1) CALL lbc_lnk( 'traadv_qck', zfu(:,:,:), 'T', 1.0_wp , zfd(:,:,:), 'T', 1.0_wp, zfc(:,:,:), 'T', 1.0_wp,  zwx(:,:,:), 'T', 1.0_wp )
177
178         !--- QUICKEST scheme
179         CALL quickest( zfu, zfd, zfc, zwx )
180         !
181         ! Mask at the T-points in the x-direction (mask=0 or mask=1)
182         DO_3D( nn_hls-1, nn_hls-1, 0, 0, 1, jpkm1 )
183            zfu(ji,jj,jk) = tmask(ji-1,jj,jk) + tmask(ji,jj,jk) + tmask(ji+1,jj,jk) - 2.
184         END_3D
185         IF (nn_hls==1) CALL lbc_lnk( 'traadv_qck', zfu(:,:,:), 'T', 1.0_wp, ld4only= .TRUE. )      ! Lateral boundary conditions
186
187         !
188         ! Tracer flux on the x-direction
189         DO_3D( 1, 0, 0, 0, 1, jpkm1 )
190            zdir = 0.5 + SIGN( 0.5_wp, pU(ji,jj,jk) )   ! if pU > 0 : zdir = 1 otherwise zdir = 0
191            !--- If the second ustream point is a land point
192            !--- the flux is computed by the 1st order UPWIND scheme
193            zmsk = zdir * zfu(ji,jj,jk) + ( 1. - zdir ) * zfu(ji+1,jj,jk)
194            zwx(ji,jj,jk) = zmsk * zwx(ji,jj,jk) + ( 1. - zmsk ) * zfc(ji,jj,jk)
195            zwx(ji,jj,jk) = zwx(ji,jj,jk) * pU(ji,jj,jk)
196         END_3D
197         !
198         ! Computation of the trend
199         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
200            zbtr = r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
201            ! horizontal advective trends
202            ztra = - zbtr * ( zwx(ji,jj,jk) - zwx(ji-1,jj,jk) )
203            !--- add it to the general tracer trends
204            pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) + ztra
205         END_3D
206         !                                 ! trend diagnostics
207         IF( l_trd )   CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_xad, zwx, pU, pt(:,:,:,jn,Kmm) )
208         !
209      END DO
210      !
211   END SUBROUTINE tra_adv_qck_i
212
213
214   SUBROUTINE tra_adv_qck_j( kt, cdtype, p2dt, pV, Kbb, Kmm, pt, kjpt, Krhs )
215      !!----------------------------------------------------------------------
216      !!
217      !!----------------------------------------------------------------------
218      INTEGER                                  , INTENT(in   ) ::   kt         ! ocean time-step index
219      INTEGER                                  , INTENT(in   ) ::   Kbb, Kmm, Krhs  ! ocean time level indices
220      CHARACTER(len=3)                         , INTENT(in   ) ::   cdtype     ! =TRA or TRC (tracer indicator)
221      INTEGER                                  , INTENT(in   ) ::   kjpt       ! number of tracers
222      REAL(wp)                                 , INTENT(in   ) ::   p2dt       ! tracer time-step
223      ! TEMP: [tiling] This can be A2D(nn_hls) after all lbc_lnks removed in the nn_hls = 2 case in tra_adv_fct
224      REAL(wp), DIMENSION(jpi,jpj,jpk         ), INTENT(in   ) ::   pV        ! j-velocity components
225      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt,jpt), INTENT(inout) ::   pt              ! active tracers and RHS of tracer equation
226      !!
227      INTEGER  :: ji, jj, jk, jn                ! dummy loop indices
228      REAL(wp) :: ztra, zbtr, zdir, zdx, zmsk   ! local scalars
229      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zwy, zfu, zfc, zfd   ! 3D workspace
230      !----------------------------------------------------------------------
231      !
232      !                                                          ! ===========
233      DO jn = 1, kjpt                                            ! tracer loop
234         !                                                       ! ===========
235         zfu(:,:,:) = 0.0     ;   zfc(:,:,:) = 0.0
236         zfd(:,:,:) = 0.0     ;   zwy(:,:,:) = 0.0
237         !
238         !--- Computation of the ustream and downstream value of the tracer and the mask
239         DO_3D( 0, 0, nn_hls-1, nn_hls-1, 1, jpkm1 )
240            ! Upstream in the x-direction for the tracer
241            zfc(ji,jj,jk) = pt(ji,jj-1,jk,jn,Kbb)
242            ! Downstream in the x-direction for the tracer
243            zfd(ji,jj,jk) = pt(ji,jj+1,jk,jn,Kbb)
244         END_3D
245
246         IF (nn_hls==1) CALL lbc_lnk( 'traadv_qck', zfc(:,:,:), 'T', 1.0_wp , zfd(:,:,:), 'T', 1.0_wp, ld4only= .TRUE. )   ! Lateral boundary conditions
247
248         ! Correct zfd on northfold after lbc_lnk; see #2640
249         IF( nn_hls == 1 .AND. l_IdoNFold .AND. ntej == Nje0 ) THEN
250            DO jk = 1, jpkm1
251               WHERE( tmask_i(ntsi:ntei,ntej:jpj) == 0._wp ) zfd(ntsi:ntei,ntej:jpj,jk) = zfc(ntsi:ntei,ntej:jpj,jk)
252            END DO
253         ENDIF
254         !
255         ! Horizontal advective fluxes
256         ! ---------------------------
257         !
258         DO_3D( 0, 0, nn_hls-1, 0, 1, jpkm1 )
259            zdir = 0.5 + SIGN( 0.5_wp, pV(ji,jj,jk) )   ! if pU > 0 : zdir = 1 otherwise zdir = 0
260            zfu(ji,jj,jk) = zdir * zfc(ji,jj,jk ) + ( 1. - zdir ) * zfd(ji,jj+1,jk)  ! FU in the x-direction for T
261         END_3D
262         !
263         DO_3D( 0, 0, nn_hls-1, 0, 1, jpkm1 )
264            zdir = 0.5 + SIGN( 0.5_wp, pV(ji,jj,jk) )   ! if pU > 0 : zdir = 1 otherwise zdir = 0
265            zdx = ( zdir * e2t(ji,jj) + ( 1. - zdir ) * e2t(ji,jj+1) ) * e1v(ji,jj) * e3v(ji,jj,jk,Kmm)
266            zwy(ji,jj,jk)  = ABS( pV(ji,jj,jk) ) * p2dt / zdx    ! (0<zc_cfl<1 : Courant number on x-direction)
267            zfc(ji,jj,jk)  = zdir * pt(ji,jj  ,jk,jn,Kbb) + ( 1. - zdir ) * pt(ji,jj+1,jk,jn,Kbb)  ! FC in the x-direction for T
268            zfd(ji,jj,jk)  = zdir * pt(ji,jj+1,jk,jn,Kbb) + ( 1. - zdir ) * pt(ji,jj  ,jk,jn,Kbb)  ! FD in the x-direction for T
269         END_3D
270
271         !--- Lateral boundary conditions
272         IF (nn_hls==1) CALL lbc_lnk( 'traadv_qck', zfu(:,:,:), 'T', 1.0_wp , zfd(:,:,:), 'T', 1.0_wp, zfc(:,:,:), 'T', 1.0_wp, zwy(:,:,:), 'T', 1.0_wp )
273
274         !--- QUICKEST scheme
275         CALL quickest( zfu, zfd, zfc, zwy )
276         !
277         ! Mask at the T-points in the x-direction (mask=0 or mask=1)
278         DO_3D( 0, 0, nn_hls-1, nn_hls-1, 1, jpkm1 )
279            zfu(ji,jj,jk) = tmask(ji,jj-1,jk) + tmask(ji,jj,jk) + tmask(ji,jj+1,jk) - 2.
280         END_3D
281         IF (nn_hls==1) CALL lbc_lnk( 'traadv_qck', zfu(:,:,:), 'T', 1.0_wp, ld4only= .TRUE. )    !--- Lateral boundary conditions
282         !
283         ! Tracer flux on the x-direction
284         DO_3D( 0, 0, 1, 0, 1, jpkm1 )
285            zdir = 0.5 + SIGN( 0.5_wp, pV(ji,jj,jk) )   ! if pU > 0 : zdir = 1 otherwise zdir = 0
286            !--- If the second ustream point is a land point
287            !--- the flux is computed by the 1st order UPWIND scheme
288            zmsk = zdir * zfu(ji,jj,jk) + ( 1. - zdir ) * zfu(ji,jj+1,jk)
289            zwy(ji,jj,jk) = zmsk * zwy(ji,jj,jk) + ( 1. - zmsk ) * zfc(ji,jj,jk)
290            zwy(ji,jj,jk) = zwy(ji,jj,jk) * pV(ji,jj,jk)
291         END_3D
292         !
293         ! Computation of the trend
294         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
295            zbtr = r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
296            ! horizontal advective trends
297            ztra = - zbtr * ( zwy(ji,jj,jk) - zwy(ji,jj-1,jk) )
298            !--- add it to the general tracer trends
299            pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) + ztra
300         END_3D
301         !                                 ! trend diagnostics
302         IF( l_trd )   CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_yad, zwy, pV, pt(:,:,:,jn,Kmm) )
303         !                                 ! "Poleward" heat and salt transports (contribution of upstream fluxes)
304         IF( l_ptr )   CALL dia_ptr_hst( jn, 'adv', zwy(:,:,:) )
305         !
306      END DO
307      !
308   END SUBROUTINE tra_adv_qck_j
309
310
311   SUBROUTINE tra_adv_cen2_k( kt, cdtype, pW, Kmm, pt, kjpt, Krhs )
312      !!----------------------------------------------------------------------
313      !!
314      !!----------------------------------------------------------------------
315      INTEGER                                  , INTENT(in   ) ::   kt       ! ocean time-step index
316      INTEGER                                  , INTENT(in   ) ::   Kmm, Krhs  ! ocean time level indices
317      CHARACTER(len=3)                         , INTENT(in   ) ::   cdtype   ! =TRA or TRC (tracer indicator)
318      INTEGER                                  , INTENT(in   ) ::   kjpt     ! number of tracers
319      ! TEMP: [tiling] This can be A2D(nn_hls) after all lbc_lnks removed in the nn_hls = 2 case in tra_adv_fct
320      REAL(wp), DIMENSION(jpi,jpj,jpk         ), INTENT(in   ) ::   pW      ! vertical velocity
321      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt,jpt), INTENT(inout) ::   pt              ! active tracers and RHS of tracer equation
322      !
323      INTEGER  ::   ji, jj, jk, jn   ! dummy loop indices
324      REAL(wp), DIMENSION(A2D(nn_hls),jpk) ::   zwz   ! 3D workspace
325      !!----------------------------------------------------------------------
326      !
327      zwz(:,:, 1 ) = 0._wp       ! surface & bottom values set to zero for all tracers
328      zwz(:,:,jpk) = 0._wp
329      !
330      !                                                          ! ===========
331      DO jn = 1, kjpt                                            ! tracer loop
332         !                                                       ! ===========
333         !
334         DO_3D( 0, 0, 0, 0, 2, jpkm1 )       !* Interior point   (w-masked 2nd order centered flux)
335            zwz(ji,jj,jk) = 0.5 * pW(ji,jj,jk) * ( pt(ji,jj,jk-1,jn,Kmm) + pt(ji,jj,jk,jn,Kmm) ) * wmask(ji,jj,jk)
336         END_3D
337         IF( ln_linssh ) THEN                !* top value   (only in linear free surf. as zwz is multiplied by wmask)
338            IF( ln_isfcav ) THEN                  ! ice-shelf cavities (top of the ocean)
339               DO_2D( 0, 0, 0, 0 )
340                  zwz(ji,jj, mikt(ji,jj) ) = pW(ji,jj,mikt(ji,jj)) * pt(ji,jj,mikt(ji,jj),jn,Kmm)   ! linear free surface
341               END_2D
342            ELSE                                   ! no ocean cavities (only ocean surface)
343               DO_2D( 0, 0, 0, 0 )
344                  zwz(ji,jj,1) = pW(ji,jj,1) * pt(ji,jj,1,jn,Kmm)
345               END_2D
346            ENDIF
347         ENDIF
348         !
349         DO_3D( 0, 0, 0, 0, 1, jpkm1 )   !==  Tracer flux divergence added to the general trend  ==!
350            pt(ji,jj,jk,jn,Krhs) = pt(ji,jj,jk,jn,Krhs) - ( zwz(ji,jj,jk) - zwz(ji,jj,jk+1) )   &
351               &                                * r1_e1e2t(ji,jj) / e3t(ji,jj,jk,Kmm)
352         END_3D
353         !                                 ! Send trends for diagnostic
354         IF( l_trd )  CALL trd_tra( kt, Kmm, Krhs, cdtype, jn, jptra_zad, zwz, pW, pt(:,:,:,jn,Kmm) )
355         !
356      END DO
357      !
358   END SUBROUTINE tra_adv_cen2_k
359
360
361   SUBROUTINE quickest( pfu, pfd, pfc, puc )
362      !!----------------------------------------------------------------------
363      !!
364      !! ** Purpose :  Computation of advective flux with Quickest scheme
365      !!
366      !! ** Method :
367      !!----------------------------------------------------------------------
368      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(in   ) ::   pfu   ! second upwind point
369      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(in   ) ::   pfd   ! first douwning point
370      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(in   ) ::   pfc   ! the central point (or the first upwind point)
371      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(inout) ::   puc   ! input as Courant number ; output as flux
372      !!
373      INTEGER  ::  ji, jj, jk               ! dummy loop indices
374      REAL(wp) ::  zcoef1, zcoef2, zcoef3   ! local scalars
375      REAL(wp) ::  zc, zcurv, zfho          !   -      -
376      !----------------------------------------------------------------------
377      !
378      DO_3D( 1, 0, 1, 0, 1, jpkm1 )
379         zc     = puc(ji,jj,jk)                         ! Courant number
380         zcurv  = pfd(ji,jj,jk) + pfu(ji,jj,jk) - 2. * pfc(ji,jj,jk)
381         zcoef1 = 0.5 *      ( pfc(ji,jj,jk) + pfd(ji,jj,jk) )
382         zcoef2 = 0.5 * zc * ( pfd(ji,jj,jk) - pfc(ji,jj,jk) )
383         zcoef3 = ( 1. - ( zc * zc ) ) * r1_6 * zcurv
384         zfho   = zcoef1 - zcoef2 - zcoef3              !  phi_f QUICKEST
385         !
386         zcoef1 = pfd(ji,jj,jk) - pfu(ji,jj,jk)
387         zcoef2 = ABS( zcoef1 )
388         zcoef3 = ABS( zcurv )
389         IF( zcoef3 >= zcoef2 ) THEN
390            zfho = pfc(ji,jj,jk)
391         ELSE
392            zcoef3 = pfu(ji,jj,jk) + ( ( pfc(ji,jj,jk) - pfu(ji,jj,jk) ) / MAX( zc, 1.e-9 ) )    ! phi_REF
393            IF( zcoef1 >= 0. ) THEN
394               zfho = MAX( pfc(ji,jj,jk), zfho )
395               zfho = MIN( zfho, MIN( zcoef3, pfd(ji,jj,jk) ) )
396            ELSE
397               zfho = MIN( pfc(ji,jj,jk), zfho )
398               zfho = MAX( zfho, MAX( zcoef3, pfd(ji,jj,jk) ) )
399            ENDIF
400         ENDIF
401         puc(ji,jj,jk) = zfho
402      END_3D
403      !
404   END SUBROUTINE quickest
405
406   !!======================================================================
407END MODULE traadv_qck
Note: See TracBrowser for help on using the repository browser.