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.
dynzdf.F90 in branches/2017/dev_CNRS_2017/NEMOGCM/NEMO/OPA_SRC/DYN – NEMO

source: branches/2017/dev_CNRS_2017/NEMOGCM/NEMO/OPA_SRC/DYN/dynzdf.F90 @ 8882

Last change on this file since 8882 was 8882, checked in by flavoni, 6 years ago

dev_CNRS_2017 branch: merged dev_r7881_ENHANCE09_RK3 with trunk r8864

  • Property svn:keywords set to Id
File size: 19.8 KB
Line 
1MODULE dynzdf
2   !!==============================================================================
3   !!                 ***  MODULE  dynzdf  ***
4   !! Ocean dynamics :  vertical component of the momentum mixing trend
5   !!==============================================================================
6   !! History :  1.0  !  2005-11  (G. Madec)  Original code
7   !!            3.3  !  2010-10  (C. Ethe, G. Madec) reorganisation of initialisation phase
8   !!            4.0  !  2017-06  (G. Madec) remove the explicit time-stepping option + avm at t-point
9   !!----------------------------------------------------------------------
10
11   !!----------------------------------------------------------------------
12   !!   dyn_zdf       : compute the after velocity through implicit calculation of vertical mixing
13   !!----------------------------------------------------------------------
14   USE oce            ! ocean dynamics and tracers variables
15   USE phycst         ! physical constants
16   USE dom_oce        ! ocean space and time domain variables
17   USE sbc_oce        ! surface boundary condition: ocean
18   USE zdf_oce        ! ocean vertical physics variables
19   USE zdfdrg         ! vertical physics: top/bottom drag coef.
20   USE dynadv    ,ONLY: ln_dynadv_vec    ! dynamics: advection form
21   USE dynldf    ,ONLY: nldf, np_lap_i   ! dynamics: type of lateral mixing
22   USE dynldf_iso,ONLY: akzu, akzv       ! dynamics: vertical component of rotated lateral mixing
23   USE ldfdyn         ! lateral diffusion: eddy viscosity coef.
24   USE trd_oce        ! trends: ocean variables
25   USE trddyn         ! trend manager: dynamics
26   !
27   USE in_out_manager ! I/O manager
28   USE lib_mpp        ! MPP library
29   USE prtctl         ! Print control
30   USE timing         ! Timing
31
32   IMPLICIT NONE
33   PRIVATE
34
35   PUBLIC   dyn_zdf   !  routine called by step.F90
36
37   REAL(wp) ::  r_vvl     ! non-linear free surface indicator: =0 if ln_linssh=T, =1 otherwise
38
39   !! * Substitutions
40#  include "vectopt_loop_substitute.h90"
41   !!----------------------------------------------------------------------
42   !! NEMO/OPA 4.0 , NEMO Consortium (2017)
43   !! $Id$
44   !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
45   !!----------------------------------------------------------------------
46CONTAINS
47   
48   SUBROUTINE dyn_zdf( kt )
49      !!----------------------------------------------------------------------
50      !!                  ***  ROUTINE dyn_zdf  ***
51      !!
52      !! ** Purpose :   compute the trend due to the vert. momentum diffusion
53      !!              together with the Leap-Frog time stepping using an
54      !!              implicit scheme.
55      !!
56      !! ** Method  :  - Leap-Frog time stepping on all trends but the vertical mixing
57      !!         ua =         ub + 2*dt *       ua             vector form or linear free surf.
58      !!         ua = ( e3u_b*ub + 2*dt * e3u_n*ua ) / e3u_a   otherwise
59      !!               - update the after velocity with the implicit vertical mixing.
60      !!      This requires to solver the following system:
61      !!         ua = ua + 1/e3u_a dk+1[ mi(avm) / e3uw_a dk[ua] ]
62      !!      with the following surface/top/bottom boundary condition:
63      !!      surface: wind stress input (averaged over kt-1/2 & kt+1/2)
64      !!      top & bottom : top stress (iceshelf-ocean) & bottom stress (cf zdfdrg.F90)
65      !!
66      !! ** Action :   (ua,va)   after velocity
67      !!---------------------------------------------------------------------
68      INTEGER, INTENT(in) ::   kt   ! ocean time-step index
69      !
70      INTEGER  ::   ji, jj, jk         ! dummy loop indices
71      INTEGER  ::   iku, ikv           ! local integers
72      REAL(wp) ::   zzwi, ze3ua, zdt   ! local scalars
73      REAL(wp) ::   zzws, ze3va        !   -      -
74      REAL(wp), DIMENSION(jpi,jpj,jpk)        ::  zwi, zwd, zws   ! 3D workspace
75      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::   ztrdu, ztrdv   !  -      -
76      !!---------------------------------------------------------------------
77      !
78      IF( ln_timing )   CALL timing_start('dyn_zdf')
79      !
80      IF( kt == nit000 ) THEN       !* initialization
81         IF(lwp) WRITE(numout,*)
82         IF(lwp) WRITE(numout,*) 'dyn_zdf_imp : vertical momentum diffusion implicit operator'
83         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~ '
84         !
85         If( ln_linssh ) THEN   ;    r_vvl = 0._wp    ! non-linear free surface indicator
86         ELSE                   ;    r_vvl = 1._wp
87         ENDIF
88      ENDIF
89      !                             !* set time step
90      IF( neuler == 0 .AND. kt == nit000     ) THEN   ;   r2dt =      rdt   ! = rdt (restart with Euler time stepping)
91      ELSEIF(               kt <= nit000 + 1 ) THEN   ;   r2dt = 2. * rdt   ! = 2 rdt (leapfrog)
92      ENDIF
93
94      IF( l_trddyn )   THEN         !* temporary save of ta and sa trends
95         ALLOCATE( ztrdu(jpi,jpj,jpk), ztrdv(jpi,jpj,jpk) ) 
96         ztrdu(:,:,:) = ua(:,:,:)
97         ztrdv(:,:,:) = va(:,:,:)
98      ENDIF
99      !
100      !              !==  RHS: Leap-Frog time stepping on all trends but the vertical mixing  ==!   (put in ua,va)
101      !
102      !                    ! time stepping except vertical diffusion
103      IF( ln_dynadv_vec .OR. ln_linssh ) THEN   ! applied on velocity
104         DO jk = 1, jpkm1
105            ua(:,:,jk) = ( ub(:,:,jk) + r2dt * ua(:,:,jk) ) * umask(:,:,jk)
106            va(:,:,jk) = ( vb(:,:,jk) + r2dt * va(:,:,jk) ) * vmask(:,:,jk)
107         END DO
108      ELSE                                      ! applied on thickness weighted velocity
109         DO jk = 1, jpkm1
110            ua(:,:,jk) = (         e3u_b(:,:,jk) * ub(:,:,jk)  &
111               &          + r2dt * e3u_n(:,:,jk) * ua(:,:,jk)  ) / e3u_a(:,:,jk) * umask(:,:,jk)
112            va(:,:,jk) = (         e3v_b(:,:,jk) * vb(:,:,jk)  &
113               &          + r2dt * e3v_n(:,:,jk) * va(:,:,jk)  ) / e3v_a(:,:,jk) * vmask(:,:,jk)
114         END DO
115      ENDIF
116      !                    ! add top/bottom friction
117      !     With split-explicit free surface, barotropic stress is treated explicitly Update velocities at the bottom.
118      !     J. Chanut: The bottom stress is computed considering after barotropic velocities, which does
119      !                not lead to the effective stress seen over the whole barotropic loop.
120      !     G. Madec : in linear free surface, e3u_a = e3u_n = e3u_0, so systematic use of e3u_a
121      IF( ln_drgimp .AND. ln_dynspg_ts ) THEN
122         DO jk = 1, jpkm1        ! remove barotropic velocities
123            ua(:,:,jk) = ( ua(:,:,jk) - ua_b(:,:) ) * umask(:,:,jk)
124            va(:,:,jk) = ( va(:,:,jk) - va_b(:,:) ) * vmask(:,:,jk)
125         END DO
126         DO jj = 2, jpjm1        ! Add bottom/top stress due to barotropic component only
127            DO ji = fs_2, fs_jpim1   ! vector opt.
128               iku = mbku(ji,jj)         ! ocean bottom level at u- and v-points
129               ikv = mbkv(ji,jj)         ! (deepest ocean u- and v-points)
130               ze3ua =  ( 1._wp - r_vvl ) * e3u_n(ji,jj,iku) + r_vvl * e3u_a(ji,jj,iku)
131               ze3va =  ( 1._wp - r_vvl ) * e3v_n(ji,jj,ikv) + r_vvl * e3v_a(ji,jj,ikv)
132               ua(ji,jj,iku) = ua(ji,jj,iku) + r2dt * 0.5*( rCdU_bot(ji+1,jj)+rCdU_bot(ji,jj) ) * ua_b(ji,jj) / ze3ua
133               va(ji,jj,ikv) = va(ji,jj,ikv) + r2dt * 0.5*( rCdU_bot(ji,jj+1)+rCdU_bot(ji,jj) ) * va_b(ji,jj) / ze3va
134            END DO
135         END DO
136         IF( ln_isfcav ) THEN    ! Ocean cavities (ISF)
137            DO jj = 2, jpjm1       
138               DO ji = fs_2, fs_jpim1   ! vector opt.
139                  iku = miku(ji,jj)         ! top ocean level at u- and v-points
140                  ikv = mikv(ji,jj)         ! (first wet ocean u- and v-points)
141                  ze3ua =  ( 1._wp - r_vvl ) * e3u_n(ji,jj,iku) + r_vvl * e3u_a(ji,jj,iku)
142                  ze3va =  ( 1._wp - r_vvl ) * e3v_n(ji,jj,ikv) + r_vvl * e3v_a(ji,jj,ikv)
143                  ua(ji,jj,iku) = ua(ji,jj,iku) + r2dt * 0.5*( rCdU_top(ji+1,jj)+rCdU_top(ji,jj) ) * ua_b(ji,jj) / ze3ua
144                  va(ji,jj,ikv) = va(ji,jj,ikv) + r2dt * 0.5*( rCdU_top(ji+1,jj)+rCdU_top(ji,jj) ) * va_b(ji,jj) / ze3va
145               END DO
146            END DO
147         END IF
148      ENDIF
149      !
150      !              !==  Vertical diffusion on u  ==!
151      !
152      !                    !* Matrix construction
153      zdt = r2dt * 0.5
154      IF( nldf == np_lap_i ) THEN   ! rotated lateral mixing: add its vertical mixing (akzu)
155         DO jk = 1, jpkm1
156            DO jj = 2, jpjm1 
157               DO ji = fs_2, fs_jpim1   ! vector opt.
158                  ze3ua =  ( 1._wp - r_vvl ) * e3u_n(ji,jj,jk) + r_vvl * e3u_a(ji,jj,jk)   ! after scale factor at T-point
159                  zzwi = - zdt * ( avm(ji+1,jj,jk  ) + avm(ji,jj,jk  ) + akzu(ji,jj,jk  ) )   &
160                     &         / ( ze3ua * e3uw_n(ji,jj,jk  ) ) * wumask(ji,jj,jk  )
161                  zzws = - zdt * ( avm(ji+1,jj,jk+1) + avm(ji,jj,jk+1) + akzu(ji,jj,jk+1) )   &
162                     &         / ( ze3ua * e3uw_n(ji,jj,jk+1) ) * wumask(ji,jj,jk+1)
163                  zwi(ji,jj,jk) = zzwi
164                  zws(ji,jj,jk) = zzws
165                  zwd(ji,jj,jk) = 1._wp - zzwi - zzws
166               END DO
167            END DO
168         END DO
169      ELSE                          ! standard case
170         DO jk = 1, jpkm1
171            DO jj = 2, jpjm1 
172               DO ji = fs_2, fs_jpim1   ! vector opt.
173                  ze3ua =  ( 1._wp - r_vvl ) * e3u_n(ji,jj,jk) + r_vvl * e3u_a(ji,jj,jk)   ! after scale factor at T-point
174                  zzwi = - zdt * ( avm(ji+1,jj,jk  ) + avm(ji,jj,jk  ) ) / ( ze3ua * e3uw_n(ji,jj,jk  ) ) * wumask(ji,jj,jk  )
175                  zzws = - zdt * ( avm(ji+1,jj,jk+1) + avm(ji,jj,jk+1) ) / ( ze3ua * e3uw_n(ji,jj,jk+1) ) * wumask(ji,jj,jk+1)
176                  zwi(ji,jj,jk) = zzwi
177                  zws(ji,jj,jk) = zzws
178                  zwd(ji,jj,jk) = 1._wp - zzwi - zzws
179               END DO
180            END DO
181         END DO
182      ENDIF
183      !
184      DO jj = 2, jpjm1     !* Surface boundary conditions
185         DO ji = fs_2, fs_jpim1   ! vector opt.
186            zwi(ji,jj,1) = 0._wp
187            zwd(ji,jj,1) = 1._wp - zws(ji,jj,1)
188         END DO
189      END DO
190      !
191      !              !==  Apply semi-implicit bottom friction  ==!
192      !
193      !     Only needed for semi-implicit bottom friction setup. The explicit
194      !     bottom friction has been included in "u(v)a" which act as the R.H.S
195      !     column vector of the tri-diagonal matrix equation
196      !
197      IF ( ln_drgimp ) THEN      ! implicit bottom friction
198         DO jj = 2, jpjm1
199            DO ji = 2, jpim1
200               iku = mbku(ji,jj)       ! ocean bottom level at u- and v-points
201               ze3ua =  ( 1._wp - r_vvl ) * e3u_n(ji,jj,iku) + r_vvl * e3u_a(ji,jj,iku)   ! after scale factor at T-point
202               zwd(ji,jj,iku) = zwd(ji,jj,iku) - r2dt * 0.5*( rCdU_bot(ji+1,jj)+rCdU_bot(ji,jj) ) / ze3ua
203            END DO
204         END DO
205         IF ( ln_isfcav ) THEN   ! top friction (always implicit)
206            DO jj = 2, jpjm1
207               DO ji = 2, jpim1
208                  !!gm   top Cd is masked (=0 outside cavities) no need of test on mik>=2  ==>> it has been suppressed
209                  iku = miku(ji,jj)       ! ocean top level at u- and v-points
210                  ze3ua =  ( 1._wp - r_vvl ) * e3u_n(ji,jj,iku) + r_vvl * e3u_a(ji,jj,iku)   ! after scale factor at T-point
211                  zwd(ji,jj,iku) = zwd(ji,jj,iku) - r2dt * 0.5*( rCdU_top(ji+1,jj)+rCdU_top(ji,jj) ) / ze3ua
212               END DO
213            END DO
214         END IF
215      ENDIF
216      !
217      ! Matrix inversion starting from the first level
218      !-----------------------------------------------------------------------
219      !   solve m.x = y  where m is a tri diagonal matrix ( jpk*jpk )
220      !
221      !        ( zwd1 zws1   0    0    0  )( zwx1 ) ( zwy1 )
222      !        ( zwi2 zwd2 zws2   0    0  )( zwx2 ) ( zwy2 )
223      !        (  0   zwi3 zwd3 zws3   0  )( zwx3 )=( zwy3 )
224      !        (        ...               )( ...  ) ( ...  )
225      !        (  0    0    0   zwik zwdk )( zwxk ) ( zwyk )
226      !
227      !   m is decomposed in the product of an upper and a lower triangular matrix
228      !   The 3 diagonal terms are in 2d arrays: zwd, zws, zwi
229      !   The solution (the after velocity) is in ua
230      !-----------------------------------------------------------------------
231      !
232      DO jk = 2, jpkm1        !==  First recurrence : Dk = Dk - Lk * Uk-1 / Dk-1   (increasing k)  ==
233         DO jj = 2, jpjm1   
234            DO ji = fs_2, fs_jpim1   ! vector opt.
235               zwd(ji,jj,jk) = zwd(ji,jj,jk) - zwi(ji,jj,jk) * zws(ji,jj,jk-1) / zwd(ji,jj,jk-1)
236            END DO
237         END DO
238      END DO
239      !
240      DO jj = 2, jpjm1        !==  second recurrence:    SOLk = RHSk - Lk / Dk-1  Lk-1  ==!
241         DO ji = fs_2, fs_jpim1   ! vector opt.
242            ze3ua =  ( 1._wp - r_vvl ) * e3u_n(ji,jj,1) + r_vvl * e3u_a(ji,jj,1) 
243            ua(ji,jj,1) = ua(ji,jj,1) + r2dt * 0.5_wp * ( utau_b(ji,jj) + utau(ji,jj) )   &
244               &                                      / ( ze3ua * rau0 ) * umask(ji,jj,1) 
245         END DO
246      END DO
247      DO jk = 2, jpkm1
248         DO jj = 2, jpjm1
249            DO ji = fs_2, fs_jpim1
250               ua(ji,jj,jk) = ua(ji,jj,jk) - zwi(ji,jj,jk) / zwd(ji,jj,jk-1) * ua(ji,jj,jk-1)
251            END DO
252         END DO
253      END DO
254      !
255      DO jj = 2, jpjm1        !==  thrid recurrence : SOLk = ( Lk - Uk * Ek+1 ) / Dk  ==!
256         DO ji = fs_2, fs_jpim1   ! vector opt.
257            ua(ji,jj,jpkm1) = ua(ji,jj,jpkm1) / zwd(ji,jj,jpkm1)
258         END DO
259      END DO
260      DO jk = jpk-2, 1, -1
261         DO jj = 2, jpjm1
262            DO ji = fs_2, fs_jpim1
263               ua(ji,jj,jk) = ( ua(ji,jj,jk) - zws(ji,jj,jk) * ua(ji,jj,jk+1) ) / zwd(ji,jj,jk)
264            END DO
265         END DO
266      END DO
267      !
268      !              !==  Vertical diffusion on v  ==!
269      !
270      !                       !* Matrix construction
271      zdt = r2dt * 0.5
272      IF( nldf == np_lap_i ) THEN   ! rotated lateral mixing: add its vertical mixing (akzu)
273         DO jk = 1, jpkm1
274            DO jj = 2, jpjm1   
275               DO ji = fs_2, fs_jpim1   ! vector opt.
276                  ze3va =  ( 1._wp - r_vvl ) * e3v_n(ji,jj,jk) + r_vvl * e3v_a(ji,jj,jk)   ! after scale factor at T-point
277                  zzwi = - zdt * ( avm(ji,jj+1,jk  )+ avm(ji,jj,jk  ) + akzv(ji,jj,jk  ) )   &
278                     &         / ( ze3va * e3vw_n(ji,jj,jk  ) ) * wvmask(ji,jj,jk  )
279                  zzws = - zdt * ( avm(ji,jj+1,jk+1)+ avm(ji,jj,jk+1) + akzv(ji,jj,jk+1) )   &
280                     &         / ( ze3va * e3vw_n(ji,jj,jk+1) ) * wvmask(ji,jj,jk+1)
281                  zwi(ji,jj,jk) = zzwi * wvmask(ji,jj,jk  )
282                  zws(ji,jj,jk) = zzws * wvmask(ji,jj,jk+1)
283                  zwd(ji,jj,jk) = 1._wp - zzwi - zzws
284               END DO
285            END DO
286         END DO
287      ELSE                          ! standard case
288         DO jk = 1, jpkm1
289            DO jj = 2, jpjm1   
290               DO ji = fs_2, fs_jpim1   ! vector opt.
291                  ze3va =  ( 1._wp - r_vvl ) * e3v_n(ji,jj,jk) + r_vvl * e3v_a(ji,jj,jk)   ! after scale factor at T-point
292                  zzwi = - zdt * ( avm(ji,jj+1,jk  )+ avm(ji,jj,jk  ) ) / ( ze3va * e3vw_n(ji,jj,jk  ) ) * wvmask(ji,jj,jk  )
293                  zzws = - zdt * ( avm(ji,jj+1,jk+1)+ avm(ji,jj,jk+1) ) / ( ze3va * e3vw_n(ji,jj,jk+1) ) * wvmask(ji,jj,jk+1)
294                  zwi(ji,jj,jk) = zzwi * wvmask(ji,jj,jk  )
295                  zws(ji,jj,jk) = zzws * wvmask(ji,jj,jk+1)
296                  zwd(ji,jj,jk) = 1._wp - zzwi - zzws
297               END DO
298            END DO
299         END DO
300      ENDIF
301      !
302      DO jj = 2, jpjm1        !* Surface boundary conditions
303         DO ji = fs_2, fs_jpim1   ! vector opt.
304            zwi(ji,jj,1) = 0._wp
305            zwd(ji,jj,1) = 1._wp - zws(ji,jj,1)
306         END DO
307      END DO
308      !              !==  Apply semi-implicit top/bottom friction  ==!
309      !
310      !     Only needed for semi-implicit bottom friction setup. The explicit
311      !     bottom friction has been included in "u(v)a" which act as the R.H.S
312      !     column vector of the tri-diagonal matrix equation
313      !
314      IF( ln_drgimp ) THEN
315         DO jj = 2, jpjm1
316            DO ji = 2, jpim1
317               ikv = mbkv(ji,jj)       ! (deepest ocean u- and v-points)
318               ze3va =  ( 1._wp - r_vvl ) * e3v_n(ji,jj,ikv) + r_vvl * e3v_a(ji,jj,ikv)   ! after scale factor at T-point
319               zwd(ji,jj,ikv) = zwd(ji,jj,ikv) - r2dt * 0.5*( rCdU_bot(ji,jj+1)+rCdU_bot(ji,jj) ) / ze3va           
320            END DO
321         END DO
322         IF ( ln_isfcav ) THEN
323            DO jj = 2, jpjm1
324               DO ji = 2, jpim1
325                  ikv = mikv(ji,jj)       ! (first wet ocean u- and v-points)
326                  ze3va =  ( 1._wp - r_vvl ) * e3v_n(ji,jj,ikv) + r_vvl * e3v_a(ji,jj,ikv)   ! after scale factor at T-point
327                  zwd(ji,jj,iku) = zwd(ji,jj,iku) - r2dt * 0.5*( rCdU_top(ji+1,jj)+rCdU_top(ji,jj) ) / ze3va
328               END DO
329            END DO
330         ENDIF
331      ENDIF
332
333      ! Matrix inversion
334      !-----------------------------------------------------------------------
335      !   solve m.x = y  where m is a tri diagonal matrix ( jpk*jpk )
336      !
337      !        ( zwd1 zws1   0    0    0  )( zwx1 ) ( zwy1 )
338      !        ( zwi2 zwd2 zws2   0    0  )( zwx2 ) ( zwy2 )
339      !        (  0   zwi3 zwd3 zws3   0  )( zwx3 )=( zwy3 )
340      !        (        ...               )( ...  ) ( ...  )
341      !        (  0    0    0   zwik zwdk )( zwxk ) ( zwyk )
342      !
343      !   m is decomposed in the product of an upper and lower triangular matrix
344      !   The 3 diagonal terms are in 2d arrays: zwd, zws, zwi
345      !   The solution (after velocity) is in 2d array va
346      !-----------------------------------------------------------------------
347      !
348      DO jk = 2, jpkm1        !==  First recurrence : Dk = Dk - Lk * Uk-1 / Dk-1   (increasing k)  ==
349         DO jj = 2, jpjm1   
350            DO ji = fs_2, fs_jpim1   ! vector opt.
351               zwd(ji,jj,jk) = zwd(ji,jj,jk) - zwi(ji,jj,jk) * zws(ji,jj,jk-1) / zwd(ji,jj,jk-1)
352            END DO
353         END DO
354      END DO
355      !
356      DO jj = 2, jpjm1        !==  second recurrence:    SOLk = RHSk - Lk / Dk-1  Lk-1  ==!
357         DO ji = fs_2, fs_jpim1   ! vector opt.         
358            ze3va =  ( 1._wp - r_vvl ) * e3v_n(ji,jj,1) + r_vvl * e3v_a(ji,jj,1) 
359            va(ji,jj,1) = va(ji,jj,1) + r2dt * 0.5_wp * ( vtau_b(ji,jj) + vtau(ji,jj) )   &
360               &                                      / ( ze3va * rau0 ) * vmask(ji,jj,1) 
361         END DO
362      END DO
363      DO jk = 2, jpkm1
364         DO jj = 2, jpjm1
365            DO ji = fs_2, fs_jpim1   ! vector opt.
366               va(ji,jj,jk) = va(ji,jj,jk) - zwi(ji,jj,jk) / zwd(ji,jj,jk-1) * va(ji,jj,jk-1)
367            END DO
368         END DO
369      END DO
370      !
371      DO jj = 2, jpjm1        !==  third recurrence : SOLk = ( Lk - Uk * SOLk+1 ) / Dk  ==!
372         DO ji = fs_2, fs_jpim1   ! vector opt.
373            va(ji,jj,jpkm1) = va(ji,jj,jpkm1) / zwd(ji,jj,jpkm1)
374         END DO
375      END DO
376      DO jk = jpk-2, 1, -1
377         DO jj = 2, jpjm1
378            DO ji = fs_2, fs_jpim1
379               va(ji,jj,jk) = ( va(ji,jj,jk) - zws(ji,jj,jk) * va(ji,jj,jk+1) ) / zwd(ji,jj,jk)
380            END DO
381         END DO
382      END DO
383      !
384      IF( l_trddyn )   THEN                      ! save the vertical diffusive trends for further diagnostics
385         ztrdu(:,:,:) = ( ua(:,:,:) - ub(:,:,:) ) / r2dt - ztrdu(:,:,:)
386         ztrdv(:,:,:) = ( va(:,:,:) - vb(:,:,:) ) / r2dt - ztrdv(:,:,:)
387         CALL trd_dyn( ztrdu, ztrdv, jpdyn_zdf, kt )
388         DEALLOCATE( ztrdu, ztrdv ) 
389      ENDIF
390      !                                          ! print mean trends (used for debugging)
391      IF(ln_ctl)   CALL prt_ctl( tab3d_1=ua, clinfo1=' zdf  - Ua: ', mask1=umask,               &
392         &                       tab3d_2=va, clinfo2=       ' Va: ', mask2=vmask, clinfo3='dyn' )
393         !
394      IF( ln_timing )   CALL timing_stop('dyn_zdf')
395      !
396   END SUBROUTINE dyn_zdf
397
398   !!==============================================================================
399END MODULE dynzdf
Note: See TracBrowser for help on using the repository browser.