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/branches/2021/dev_r14116_HPC-10_mcastril_Mixed_Precision_implementation/src/OCE/TRA – NEMO

source: NEMO/branches/2021/dev_r14116_HPC-10_mcastril_Mixed_Precision_implementation/src/OCE/TRA/traadv_qck.F90 @ 15540

Last change on this file since 15540 was 15540, checked in by sparonuz, 3 years ago

Mixed precision version, tested up to 30 years on ORCA2.

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