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.
traldf_triad.F90 in branches/2015/dev_r5803_NOC_WAD/NEMOGCM/NEMO/OPA_SRC/TRA – NEMO

source: branches/2015/dev_r5803_NOC_WAD/NEMOGCM/NEMO/OPA_SRC/TRA/traldf_triad.F90 @ 5870

Last change on this file since 5870 was 5870, checked in by acc, 8 years ago

Branch 2015/dev_r5803_NOC_WAD. Merge in trunk changes from 5803 to 5869 in preparation for merge. Also tidied and reorganised some wetting and drying code. Renamed wadlmt.F90 to wetdry.F90. Wetting drying code changes restricted to domzgr.F90, domvvl.F90 nemogcm.F90 sshwzv.F90, dynspg_ts.F90, wetdry.F90 and dynhpg.F90. Code passes full SETTE tests with ln_wd=.false.. Still awaiting test case for checking with ln_wd=.false.

  • Property svn:keywords set to Id
File size: 24.8 KB
Line 
1MODULE traldf_triad
2   !!======================================================================
3   !!                   ***  MODULE  traldf_triad  ***
4   !! Ocean  tracers:  horizontal component of the lateral tracer mixing trend
5   !!======================================================================
6   !! History :  3.3  ! 2010-10  (G. Nurser, C. Harris, G. Madec)  Griffies operator (original code)
7   !!            3.7  ! 2013-12  (F. Lemarie, G. Madec)  triad operator (Griffies) + Method of Stabilizing Correction
8   !!----------------------------------------------------------------------
9
10   !!----------------------------------------------------------------------
11   !!   tra_ldf_triad : update the tracer trend with the iso-neutral laplacian triad-operator
12   !!----------------------------------------------------------------------
13   USE oce             ! ocean dynamics and active tracers
14   USE dom_oce         ! ocean space and time domain
15   USE phycst          ! physical constants
16   USE trc_oce         ! share passive tracers/Ocean variables
17   USE zdf_oce         ! ocean vertical physics
18   USE ldftra          ! lateral physics: eddy diffusivity
19   USE ldfslp          ! lateral physics: iso-neutral slopes
20   USE traldf_iso      ! lateral diffusion (Madec operator)         (tra_ldf_iso routine)
21   USE diaptr          ! poleward transport diagnostics
22   USE zpshde          ! partial step: hor. derivative     (zps_hde routine)
23   !
24   USE in_out_manager  ! I/O manager
25   USE iom             ! I/O library
26   USE lbclnk          ! ocean lateral boundary conditions (or mpp link)
27   USE lib_mpp         ! MPP library
28   USE wrk_nemo        ! Memory Allocation
29   USE timing          ! Timing
30
31   IMPLICIT NONE
32   PRIVATE
33
34   PUBLIC   tra_ldf_triad   ! routine called by traldf.F90
35
36   REAL(wp), DIMENSION(:,:,:), ALLOCATABLE, SAVE ::   zdkt3d   !: vertical tracer gradient at 2 levels
37
38   !! * Substitutions
39#  include "domzgr_substitute.h90"
40#  include "vectopt_loop_substitute.h90"
41   !!----------------------------------------------------------------------
42   !! NEMO/OPA 3.7 , NEMO Consortium (2015)
43   !! $Id$
44   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
45   !!----------------------------------------------------------------------
46CONTAINS
47
48  SUBROUTINE tra_ldf_triad( kt, kit000, cdtype, pahu, pahv, pgu , pgv ,   &
49      &                                                     pgui, pgvi,   &
50      &                                         ptb , ptbb, pta , kjpt, kpass )
51      !!----------------------------------------------------------------------
52      !!                  ***  ROUTINE tra_ldf_triad  ***
53      !!
54      !! ** Purpose :   Compute the before horizontal tracer (t & s) diffusive
55      !!      trend for a laplacian tensor (ezxcept the dz[ dz[.] ] term) and
56      !!      add it to the general trend of tracer equation.
57      !!
58      !! ** Method  :   The horizontal component of the lateral diffusive trends
59      !!      is provided by a 2nd order operator rotated along neural or geopo-
60      !!      tential surfaces to which an eddy induced advection can be added
61      !!      It is computed using before fields (forward in time) and isopyc-
62      !!      nal or geopotential slopes computed in routine ldfslp.
63      !!
64      !!      see documentation for the desciption
65      !!
66      !! ** Action :   pta   updated with the before rotated diffusion
67      !!               ah_wslp2 ....
68      !!               akz   stabilizing vertical diffusivity coefficient (used in trazdf_imp)
69      !!----------------------------------------------------------------------
70      INTEGER                              , INTENT(in   ) ::   kt         ! ocean time-step index
71      INTEGER                              , INTENT(in   ) ::   kit000     ! first time step index
72      CHARACTER(len=3)                     , INTENT(in   ) ::   cdtype     ! =TRA or TRC (tracer indicator)
73      INTEGER                              , INTENT(in   ) ::   kjpt       ! number of tracers
74      INTEGER                              , INTENT(in   ) ::   kpass      ! =1/2 first or second passage
75      REAL(wp), DIMENSION(jpi,jpj,jpk)     , INTENT(in   ) ::   pahu, pahv ! eddy diffusivity at u- and v-points  [m2/s]
76      REAL(wp), DIMENSION(jpi,jpj    ,kjpt), INTENT(in   ) ::   pgu , pgv  ! tracer gradient at pstep levels
77      REAL(wp), DIMENSION(jpi,jpj,    kjpt), INTENT(in   ) ::   pgui, pgvi ! tracer gradient at top   levels
78      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(in   ) ::   ptb        ! tracer (kpass=1) or laplacian of tracer (kpass=2)
79      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(in   ) ::   ptbb       ! tracer (only used in kpass=2)
80      REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(inout) ::   pta        ! tracer trend
81      !
82      INTEGER  ::  ji, jj, jk, jn   ! dummy loop indices
83      INTEGER  ::  ip,jp,kp         ! dummy loop indices
84      INTEGER  ::  ierr            ! local integer
85      REAL(wp) ::  zmsku, zabe1, zcof1, zcoef3          ! local scalars
86      REAL(wp) ::  zmskv, zabe2, zcof2, zcoef4          !   -      -
87      REAL(wp) ::  zcoef0, ze3w_2, zsign, z2dt, z1_2dt  !   -      -
88      !
89      REAL(wp) ::   zslope_skew, zslope_iso, zslope2, zbu, zbv
90      REAL(wp) ::   ze1ur, ze2vr, ze3wr, zdxt, zdyt, zdzt
91      REAL(wp) ::   zah, zah_slp, zaei_slp
92#if defined key_diaar5
93      REAL(wp) ::   zztmp              ! local scalar
94#endif
95      REAL(wp), POINTER, DIMENSION(:,:  ) :: z2d                                            ! 2D workspace
96      REAL(wp), POINTER, DIMENSION(:,:,:) :: zdit, zdjt, zftu, zftv, ztfw, zpsi_uw, zpsi_vw   ! 3D     -
97      !!----------------------------------------------------------------------
98      !
99      IF( nn_timing == 1 )  CALL timing_start('tra_ldf_triad')
100      !
101      CALL wrk_alloc( jpi,jpj,       z2d ) 
102      CALL wrk_alloc( jpi,jpj,jpk,   zdit, zdjt, zftu, zftv, ztfw, zpsi_uw, zpsi_vw  ) 
103      !
104      IF( .NOT.ALLOCATED(zdkt3d) )  THEN
105         ALLOCATE( zdkt3d(jpi,jpj,0:1) , STAT=ierr )
106         IF( lk_mpp   )   CALL mpp_sum ( ierr )
107         IF( ierr > 0 )   CALL ctl_stop('STOP', 'tra_ldf_triad: unable to allocate arrays')
108      ENDIF
109     !
110      IF( kpass == 1 .AND. kt == kit000 )  THEN
111         IF(lwp) WRITE(numout,*)
112         IF(lwp) WRITE(numout,*) 'tra_ldf_triad : rotated laplacian diffusion operator on ', cdtype
113         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~~'
114      ENDIF
115      !
116      !                                               ! set time step size (Euler/Leapfrog)
117      IF( neuler == 0 .AND. kt == kit000 ) THEN   ;   z2dt =     rdttra(1)      ! at nit000   (Euler)
118      ELSE                                        ;   z2dt = 2.* rdttra(1)      !             (Leapfrog)
119      ENDIF
120      z1_2dt = 1._wp / z2dt
121      !
122      IF( kpass == 1 ) THEN   ;   zsign =  1._wp      ! bilaplacian operator require a minus sign (eddy diffusivity >0)
123      ELSE                    ;   zsign = -1._wp
124      ENDIF
125                 
126      !!----------------------------------------------------------------------
127      !!   0 - calculate  ah_wslp2, akz, and optionally zpsi_uw, zpsi_vw
128      !!----------------------------------------------------------------------
129      !
130      IF( kpass == 1 ) THEN         !==  first pass only  and whatever the tracer is  ==!
131         !
132         akz     (:,:,:) = 0._wp     
133         ah_wslp2(:,:,:) = 0._wp
134         IF( ln_ldfeiv_dia ) THEN
135            zpsi_uw(:,:,:) = 0._wp
136            zpsi_vw(:,:,:) = 0._wp
137         ENDIF
138         !
139         DO ip = 0, 1                            ! i-k triads
140            DO kp = 0, 1
141               DO jk = 1, jpkm1
142                  DO jj = 1, jpjm1
143                     DO ji = 1, fs_jpim1
144                        ze3wr = 1._wp / fse3w(ji+ip,jj,jk+kp)
145                        zbu   = e1e2u(ji,jj) * fse3u(ji,jj,jk)
146                        zah   = 0.25_wp * pahu(ji,jj,jk)
147                        zslope_skew = triadi_g(ji+ip,jj,jk,1-ip,kp)
148                        ! Subtract s-coordinate slope at t-points to give slope rel to s-surfaces (do this by *adding* gradient of depth)
149                        zslope2 = zslope_skew + ( fsdept(ji+1,jj,jk) - fsdept(ji,jj,jk) ) * r1_e1u(ji,jj) * umask(ji,jj,jk+kp)
150                        zslope2 = zslope2 *zslope2
151                        ah_wslp2(ji+ip,jj,jk+kp) = ah_wslp2(ji+ip,jj,jk+kp) + zah * zbu * ze3wr * r1_e1e2t(ji+ip,jj) * zslope2
152                        akz     (ji+ip,jj,jk+kp) = akz     (ji+ip,jj,jk+kp) + zah * r1_e1u(ji,jj)       &
153                           &                                                      * r1_e1u(ji,jj) * umask(ji,jj,jk+kp)
154                        !
155                       IF( ln_ldfeiv_dia )   zpsi_uw(ji,jj,jk+kp) = zpsi_uw(ji,jj,jk+kp)   &
156                           &                                       + 0.25_wp * aeiu(ji,jj,jk) * e2u(ji,jj) * zslope_skew
157                     END DO
158                  END DO
159               END DO
160            END DO
161         END DO
162         !
163         DO jp = 0, 1                            ! j-k triads
164            DO kp = 0, 1
165               DO jk = 1, jpkm1
166                  DO jj = 1, jpjm1
167                     DO ji = 1, fs_jpim1
168                        ze3wr = 1.0_wp / fse3w(ji,jj+jp,jk+kp)
169                        zbv   = e1e2v(ji,jj) * fse3v(ji,jj,jk)
170                        zah   = 0.25_wp * pahv(ji,jj,jk)
171                        zslope_skew = triadj_g(ji,jj+jp,jk,1-jp,kp)
172                        ! Subtract s-coordinate slope at t-points to give slope rel to s surfaces
173                        !    (do this by *adding* gradient of depth)
174                        zslope2 = zslope_skew + ( fsdept(ji,jj+1,jk) - fsdept(ji,jj,jk) ) * r1_e2v(ji,jj) * vmask(ji,jj,jk+kp)
175                        zslope2 = zslope2 * zslope2
176                        ah_wslp2(ji,jj+jp,jk+kp) = ah_wslp2(ji,jj+jp,jk+kp) + zah * zbv * ze3wr * r1_e1e2t(ji,jj+jp) * zslope2
177                        akz     (ji,jj+jp,jk+kp) = akz     (ji,jj+jp,jk+kp) + zah * r1_e2v(ji,jj)     &
178                           &                                                      * r1_e2v(ji,jj) * vmask(ji,jj,jk+kp)
179                        !
180                        IF( ln_ldfeiv_dia )   zpsi_vw(ji,jj,jk+kp) = zpsi_vw(ji,jj,jk+kp)   &
181                           &                                       + 0.25 * aeiv(ji,jj,jk) * e1v(ji,jj) * zslope_skew
182                     END DO
183                  END DO
184               END DO
185            END DO
186         END DO
187         !
188         IF( ln_traldf_msc ) THEN                ! stabilizing vertical diffusivity coefficient
189            !
190            IF( ln_traldf_blp ) THEN                ! bilaplacian operator
191               DO jk = 2, jpkm1
192                  DO jj = 1, jpjm1
193                     DO ji = 1, fs_jpim1
194                        akz(ji,jj,jk) = 16._wp * ah_wslp2(ji,jj,jk)   &
195                           &          * (  akz(ji,jj,jk) + ah_wslp2(ji,jj,jk) / ( fse3w(ji,jj,jk) * fse3w(ji,jj,jk) )  )
196                     END DO
197                  END DO
198               END DO
199            ELSEIF( ln_traldf_lap ) THEN              ! laplacian operator
200               DO jk = 2, jpkm1
201                  DO jj = 1, jpjm1
202                     DO ji = 1, fs_jpim1
203                        ze3w_2 = fse3w(ji,jj,jk) * fse3w(ji,jj,jk)
204                        zcoef0 = z2dt * (  akz(ji,jj,jk) + ah_wslp2(ji,jj,jk) / ze3w_2  )
205                        akz(ji,jj,jk) = MAX( zcoef0 - 0.5_wp , 0._wp ) * ze3w_2 * z1_2dt
206                     END DO
207                  END DO
208               END DO
209           ENDIF
210           !
211         ELSE                                    ! 33 flux set to zero with akz=ah_wslp2 ==>> computed in full implicit
212            akz(:,:,:) = ah_wslp2(:,:,:)     
213         ENDIF
214         !
215         IF( ln_ldfeiv_dia .AND. cdtype == 'TRA' )   CALL ldf_eiv_dia( zpsi_uw, zpsi_vw )
216         !
217      ENDIF                                  !==  end 1st pass only  ==!
218      !
219      !                                                           ! ===========
220      DO jn = 1, kjpt                                             ! tracer loop
221         !                                                        ! ===========
222         ! Zero fluxes for each tracer
223!!gm  this should probably be done outside the jn loop
224         ztfw(:,:,:) = 0._wp
225         zftu(:,:,:) = 0._wp
226         zftv(:,:,:) = 0._wp
227         !
228         DO jk = 1, jpkm1        !==  before lateral T & S gradients at T-level jk  ==!
229            DO jj = 1, jpjm1
230               DO ji = 1, fs_jpim1   ! vector opt.
231                  zdit(ji,jj,jk) = ( ptb(ji+1,jj  ,jk,jn) - ptb(ji,jj,jk,jn) ) * umask(ji,jj,jk)
232                  zdjt(ji,jj,jk) = ( ptb(ji  ,jj+1,jk,jn) - ptb(ji,jj,jk,jn) ) * vmask(ji,jj,jk)
233               END DO
234            END DO
235         END DO
236         IF( ln_zps .AND. l_grad_zps ) THEN    ! partial steps: correction at top/bottom ocean level
237            DO jj = 1, jpjm1                       ! bottom level
238               DO ji = 1, fs_jpim1   ! vector opt.
239                  zdit(ji,jj,mbku(ji,jj)) = pgu(ji,jj,jn)
240                  zdjt(ji,jj,mbkv(ji,jj)) = pgv(ji,jj,jn)
241               END DO
242            END DO
243            IF( ln_isfcav ) THEN                   ! top level (ocean cavities only)
244               DO jj = 1, jpjm1
245                  DO ji = 1, fs_jpim1   ! vector opt.
246                     IF( miku(ji,jj)  > 1 )   zdit(ji,jj,miku(ji,jj) ) = pgui(ji,jj,jn) 
247                     IF( mikv(ji,jj)  > 1 )   zdjt(ji,jj,mikv(ji,jj) ) = pgvi(ji,jj,jn) 
248                  END DO
249               END DO
250            ENDIF
251         ENDIF
252
253         !!----------------------------------------------------------------------
254         !!   II - horizontal trend  (full)
255         !!----------------------------------------------------------------------
256         !
257         DO jk = 1, jpkm1
258            !
259            !                    !==  Vertical tracer gradient at level jk and jk+1
260            zdkt3d(:,:,1) = ( ptb(:,:,jk,jn) - ptb(:,:,jk+1,jn) ) * tmask(:,:,jk+1)
261            !
262            !                    ! surface boundary condition: zdkt3d(jk=0)=zdkt3d(jk=1)
263            IF( jk == 1 ) THEN   ;   zdkt3d(:,:,0) = zdkt3d(:,:,1)
264            ELSE                 ;   zdkt3d(:,:,0) = ( ptb(:,:,jk-1,jn) - ptb(:,:,jk,jn) ) * tmask(:,:,jk)
265            ENDIF
266            !
267            zaei_slp = 0._wp
268            !
269            IF( ln_botmix_triad ) THEN
270               DO ip = 0, 1              !==  Horizontal & vertical fluxes
271                  DO kp = 0, 1
272                     DO jj = 1, jpjm1
273                        DO ji = 1, fs_jpim1
274                           ze1ur = r1_e1u(ji,jj)
275                           zdxt  = zdit(ji,jj,jk) * ze1ur
276                           ze3wr = 1._wp / fse3w(ji+ip,jj,jk+kp)
277                           zdzt  = zdkt3d(ji+ip,jj,kp) * ze3wr
278                           zslope_skew = triadi_g(ji+ip,jj,jk,1-ip,kp)
279                           zslope_iso  = triadi  (ji+ip,jj,jk,1-ip,kp)
280
281                           zbu = 0.25_wp * e1e2u(ji,jj) * fse3u(ji,jj,jk)
282                           ! ln_botmix_triad is .T. don't mask zah for bottom half cells    !!gm ?????   ahu is masked....
283                           zah = pahu(ji,jj,jk)
284                           zah_slp  = zah * zslope_iso
285                           IF( ln_ldfeiv )   zaei_slp = aeiu(ji,jj,jk) * zslope_skew
286                           zftu(ji   ,jj,jk   ) = zftu(ji   ,jj,jk   ) - ( zah * zdxt + (zah_slp - zaei_slp) * zdzt ) * zbu * ze1ur
287                           ztfw(ji+ip,jj,jk+kp) = ztfw(ji+ip,jj,jk+kp) - ( zah_slp + zaei_slp) * zdxt                 * zbu * ze3wr
288                        END DO
289                     END DO
290                  END DO
291               END DO
292
293               DO jp = 0, 1
294                  DO kp = 0, 1
295                     DO jj = 1, jpjm1
296                        DO ji = 1, fs_jpim1
297                           ze2vr = r1_e2v(ji,jj)
298                           zdyt  = zdjt(ji,jj,jk) * ze2vr
299                           ze3wr = 1._wp / fse3w(ji,jj+jp,jk+kp)
300                           zdzt  = zdkt3d(ji,jj+jp,kp) * ze3wr
301                           zslope_skew = triadj_g(ji,jj+jp,jk,1-jp,kp)
302                           zslope_iso  = triadj(ji,jj+jp,jk,1-jp,kp)
303                           zbv = 0.25_wp * e1e2v(ji,jj) * fse3v(ji,jj,jk)
304                           ! ln_botmix_triad is .T. don't mask zah for bottom half cells    !!gm ?????  ahv is masked...
305                           zah = pahv(ji,jj,jk)
306                           zah_slp = zah * zslope_iso
307                           IF( ln_ldfeiv )   zaei_slp = aeiv(ji,jj,jk) * zslope_skew
308                           zftv(ji,jj   ,jk   ) = zftv(ji,jj   ,jk   ) - ( zah * zdyt + (zah_slp - zaei_slp) * zdzt ) * zbv * ze2vr
309                           ztfw(ji,jj+jp,jk+kp) = ztfw(ji,jj+jp,jk+kp) - ( zah_slp + zaei_slp ) * zdyt                * zbv * ze3wr
310                        END DO
311                     END DO
312                  END DO
313               END DO
314
315            ELSE
316
317               DO ip = 0, 1               !==  Horizontal & vertical fluxes
318                  DO kp = 0, 1
319                     DO jj = 1, jpjm1
320                        DO ji = 1, fs_jpim1
321                           ze1ur = r1_e1u(ji,jj)
322                           zdxt  = zdit(ji,jj,jk) * ze1ur
323                           ze3wr = 1._wp / fse3w(ji+ip,jj,jk+kp)
324                           zdzt  = zdkt3d(ji+ip,jj,kp) * ze3wr
325                           zslope_skew = triadi_g(ji+ip,jj,jk,1-ip,kp)
326                           zslope_iso  = triadi(ji+ip,jj,jk,1-ip,kp)
327
328                           zbu = 0.25_wp * e1e2u(ji,jj) * fse3u(ji,jj,jk)
329                           ! ln_botmix_triad is .F. mask zah for bottom half cells
330                           zah = pahu(ji,jj,jk) * umask(ji,jj,jk+kp)         ! pahu(ji+ip,jj,jk)   ===>>  ????
331                           zah_slp  = zah * zslope_iso
332                           IF( ln_ldfeiv )   zaei_slp = aeiu(ji,jj,jk) * zslope_skew        ! fsaeit(ji+ip,jj,jk)*zslope_skew
333                           zftu(ji   ,jj,jk   ) = zftu(ji   ,jj,jk   ) - ( zah * zdxt + (zah_slp - zaei_slp) * zdzt ) * zbu * ze1ur
334                           ztfw(ji+ip,jj,jk+kp) = ztfw(ji+ip,jj,jk+kp) - (zah_slp + zaei_slp) * zdxt * zbu * ze3wr
335                        END DO
336                     END DO
337                  END DO
338               END DO
339
340               DO jp = 0, 1
341                  DO kp = 0, 1
342                     DO jj = 1, jpjm1
343                        DO ji = 1, fs_jpim1
344                           ze2vr = r1_e2v(ji,jj)
345                           zdyt  = zdjt(ji,jj,jk) * ze2vr
346                           ze3wr = 1._wp / fse3w(ji,jj+jp,jk+kp)
347                           zdzt  = zdkt3d(ji,jj+jp,kp) * ze3wr
348                           zslope_skew = triadj_g(ji,jj+jp,jk,1-jp,kp)
349                           zslope_iso  = triadj(ji,jj+jp,jk,1-jp,kp)
350                           zbv = 0.25_wp * e1e2v(ji,jj) * fse3v(ji,jj,jk)
351                           ! ln_botmix_triad is .F. mask zah for bottom half cells
352                           zah = pahv(ji,jj,jk) * vmask(ji,jj,jk+kp)         ! pahv(ji,jj+jp,jk)  ????
353                           zah_slp = zah * zslope_iso
354                           IF( ln_ldfeiv )   zaei_slp = aeiv(ji,jj,jk) * zslope_skew        ! fsaeit(ji,jj+jp,jk)*zslope_skew
355                           zftv(ji,jj,jk) = zftv(ji,jj,jk) - ( zah * zdyt + (zah_slp - zaei_slp) * zdzt ) * zbv * ze2vr
356                           ztfw(ji,jj+jp,jk+kp) = ztfw(ji,jj+jp,jk+kp) - (zah_slp + zaei_slp) * zdyt * zbv * ze3wr
357                        END DO
358                     END DO
359                  END DO
360               END DO
361            ENDIF
362            !                             !==  horizontal divergence and add to the general trend  ==!
363            DO jj = 2 , jpjm1
364               DO ji = fs_2, fs_jpim1  ! vector opt.
365                  pta(ji,jj,jk,jn) = pta(ji,jj,jk,jn) + zsign * (  zftu(ji-1,jj,jk) - zftu(ji,jj,jk)       &
366                     &                                           + zftv(ji,jj-1,jk) - zftv(ji,jj,jk)   )   &
367                     &                                        / (  e1e2t(ji,jj) * fse3t(ji,jj,jk)  )
368               END DO
369            END DO
370            !
371         END DO
372         !
373         !                                !==  add the vertical 33 flux  ==!
374         IF( ln_traldf_lap ) THEN               ! laplacian case: eddy coef = ah_wslp2 - akz
375            DO jk = 2, jpkm1       
376               DO jj = 1, jpjm1
377                  DO ji = fs_2, fs_jpim1
378                     ztfw(ji,jj,jk) = ztfw(ji,jj,jk) - e1e2t(ji,jj) / fse3w(ji,jj,jk) * tmask(ji,jj,jk)   &
379                        &                            * ( ah_wslp2(ji,jj,jk) - akz(ji,jj,jk) )             &
380                        &                            * ( ptb(ji,jj,jk-1,jn) - ptb(ji,jj,jk,jn) )
381                  END DO
382               END DO
383            END DO
384         ELSE                                   ! bilaplacian
385            SELECT CASE( kpass )
386            CASE(  1  )                            ! 1st pass : eddy coef = ah_wslp2
387               DO jk = 2, jpkm1 
388                  DO jj = 1, jpjm1
389                     DO ji = fs_2, fs_jpim1
390                        ztfw(ji,jj,jk) = ztfw(ji,jj,jk) - e1e2t(ji,jj) / fse3w(ji,jj,jk) * tmask(ji,jj,jk)             &
391                           &                            * ah_wslp2(ji,jj,jk) * ( ptb(ji,jj,jk-1,jn) - ptb(ji,jj,jk,jn) )
392                     END DO
393                  END DO
394               END DO
395            CASE(  2  )                            ! 2nd pass : eddy flux = ah_wslp2 and akz applied on ptb  and ptbb gradients, resp.
396               DO jk = 2, jpkm1 
397                  DO jj = 1, jpjm1
398                     DO ji = fs_2, fs_jpim1
399                        ztfw(ji,jj,jk) = ztfw(ji,jj,jk) - e1e2t(ji,jj) / fse3w(ji,jj,jk) * tmask(ji,jj,jk)                      &
400                           &                            * (  ah_wslp2(ji,jj,jk) * ( ptb (ji,jj,jk-1,jn) - ptb (ji,jj,jk,jn) )   &
401                           &                               + akz     (ji,jj,jk) * ( ptbb(ji,jj,jk-1,jn) - ptbb(ji,jj,jk,jn) )   )
402                     END DO
403                  END DO
404               END DO
405            END SELECT
406         ENDIF
407         !
408         DO jk = 1, jpkm1                 !==  Divergence of vertical fluxes added to pta  ==!
409            DO jj = 2, jpjm1
410               DO ji = fs_2, fs_jpim1  ! vector opt.
411                  pta(ji,jj,jk,jn) = pta(ji,jj,jk,jn) + zsign * (  ztfw(ji,jj,jk+1) - ztfw(ji,jj,jk)  )   &
412                     &                                        / ( e1e2t(ji,jj) * fse3t(ji,jj,jk) )
413               END DO
414            END DO
415         END DO
416         !
417         IF( ( kpass == 1 .AND. ln_traldf_lap ) .OR.  &     !==  first pass only (  laplacian)  ==!
418             ( kpass == 2 .AND. ln_traldf_blp ) ) THEN      !==  2nd   pass      (bilaplacian)  ==!
419            !
420            !                          ! "Poleward" diffusive heat or salt transports (T-S case only)
421            IF( cdtype == 'TRA' .AND. ln_diaptr ) THEN
422               IF( jn == jp_tem)   htr_ldf(:) = ptr_sj( zftv(:,:,:) )        ! 3.3  names
423               IF( jn == jp_sal)   str_ldf(:) = ptr_sj( zftv(:,:,:) )
424            ENDIF
425            !
426            IF( iom_use("udiff_heattr") .OR. iom_use("vdiff_heattr") ) THEN
427              !
428              IF( cdtype == 'TRA' .AND. jn == jp_tem  ) THEN
429                  z2d(:,:) = zftu(ji,jj,1) 
430                  DO jk = 2, jpkm1
431                     DO jj = 2, jpjm1
432                        DO ji = fs_2, fs_jpim1   ! vector opt.
433                           z2d(ji,jj) = z2d(ji,jj) + zftu(ji,jj,jk) 
434                        END DO
435                     END DO
436                  END DO
437                  z2d(:,:) = rau0_rcp * z2d(:,:) 
438                  CALL lbc_lnk( z2d, 'U', -1. )
439                  CALL iom_put( "udiff_heattr", z2d )                  ! heat i-transport
440                  !
441                  z2d(:,:) = zftv(ji,jj,1) 
442                  DO jk = 2, jpkm1
443                     DO jj = 2, jpjm1
444                        DO ji = fs_2, fs_jpim1   ! vector opt.
445                           z2d(ji,jj) = z2d(ji,jj) + zftv(ji,jj,jk) 
446                        END DO
447                     END DO
448                  END DO
449                  z2d(:,:) = rau0_rcp * z2d(:,:)     
450                  CALL lbc_lnk( z2d, 'V', -1. )
451                  CALL iom_put( "vdiff_heattr", z2d )                  !  heat j-transport
452               ENDIF
453               !
454            ENDIF
455            !
456         ENDIF                                                    !== end pass selection  ==!
457         !
458         !                                                        ! ===============
459      END DO                                                      ! end tracer loop
460      !                                                           ! ===============
461      !
462      CALL wrk_dealloc( jpi,jpj,       z2d ) 
463      CALL wrk_dealloc( jpi,jpj,jpk,   zdit, zdjt, zftu, zftv, ztfw, zpsi_uw, zpsi_vw  ) 
464      !
465      IF( nn_timing == 1 )  CALL timing_stop('tra_ldf_triad')
466      !
467   END SUBROUTINE tra_ldf_triad
468
469   !!==============================================================================
470END MODULE traldf_triad
Note: See TracBrowser for help on using the repository browser.