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.
trazdf_exp.F90 in trunk/NEMO/OPA_SRC/TRA – NEMO

source: trunk/NEMO/OPA_SRC/TRA/trazdf_exp.F90 @ 216

Last change on this file since 216 was 216, checked in by opalod, 19 years ago

CT : UPDATE151 : New trends organization

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.9 KB
Line 
1MODULE trazdf_exp
2   !!==============================================================================
3   !!                    ***  MODULE  trazdf_exp  ***
4   !! Ocean active tracers:  vertical component of the tracer mixing trend using
5   !!                        an explicit time-stepping (time spllitting scheme)
6   !!==============================================================================
7
8   !!----------------------------------------------------------------------
9   !!   tra_zdf_exp  : update the tracer trend with the vertical diffusion
10   !!                  using an explicit time stepping
11   !!----------------------------------------------------------------------
12   !! * Modules used
13   USE oce             ! ocean dynamics and active tracers
14   USE dom_oce         ! ocean space and time domain
15   USE trdmod          ! ocean active tracers trends
16   USE trdmod_oce      ! ocean variables trends
17   USE zdf_oce         ! ocean vertical physics
18   USE zdfddm          ! ocean vertical physics: double diffusion
19   USE in_out_manager  ! I/O manager
20
21   IMPLICIT NONE
22   PRIVATE
23
24   !! * Routine accessibility
25   PUBLIC tra_zdf_exp          ! routine called by step.F90
26
27   !! * Module variable
28   REAL(wp), DIMENSION(jpk) ::   &
29      r2dt                     ! vertical profile of 2 x tracer time-step
30
31   !! * Substitutions
32#  include "domzgr_substitute.h90"
33#  include "zdfddm_substitute.h90"
34   !!----------------------------------------------------------------------
35   !!  OPA 9.0, LODYC-IPSL (2003)
36   !!----------------------------------------------------------------------
37
38CONTAINS
39
40   SUBROUTINE tra_zdf_exp( kt )
41      !!----------------------------------------------------------------------
42      !!                  ***  ROUTINE tra_zdf_exp  ***
43      !!                   
44      !! ** Purpose :   Compute the trend due to the vertical tracer mixing
45      !!      using an explicit time stepping and add it to the general trend
46      !!      of the tracer equations.
47      !!
48      !! ** Method  :   The vertical diffusion of tracers (t & s) is given by:
49      !!         difft = dz( avt dz(tb) ) = 1/e3t dk+1( avt/e3w dk(tb) )
50      !!      It is evaluated with an Euler scheme, using a time splitting
51      !!      technique.
52      !!      Surface and bottom boundary conditions: no diffusive flux on
53      !!      both tracers (bottom, applied through the masked field avt).
54      !!      Add this trend to the general trend ta,sa :
55      !!          ta = ta + dz( avt dz(t) )
56      !!         (sa = sa + dz( avs dz(t) ) if lk_zdfddm= T)
57      !!
58      !! ** Action : - Update (ta,sa) with the before vertical diffusion trend
59      !!             - Save the trends  in (ztdta,ztdsa) ('key_trdtra')
60      !!
61      !! History :
62      !!   6.0  !  90-10  (B. Blanke)  Original code
63      !!   7.0  !  91-11  (G. Madec)
64      !!        !  92-06  (M. Imbard)  correction on tracer trend loops
65      !!        !  96-01  (G. Madec)  statement function for e3
66      !!        !  97-05  (G. Madec)  vertical component of isopycnal
67      !!        !  97-07  (G. Madec)  geopotential diffusion in s-coord
68      !!        !  00-08  (G. Madec)  double diffusive mixing
69      !!   8.5  !  02-08  (G. Madec)  F90: Free form and module
70      !!   9.0  !  04-08  (C. Talandier) New trends organization
71      !!---------------------------------------------------------------------
72      !! * Modules used     
73      USE oce, ONLY :    ztdta => ua,       & ! use ua as 3D workspace   
74                         ztdsa => va          ! use va as 3D workspace   
75
76      !! * Arguments
77      INTEGER, INTENT( in ) ::   kt           ! ocean time-step index
78     
79      !! * Local declarations
80      INTEGER ::   ji, jj, jk, jl             ! dummy loop indices
81      REAL(wp) ::   &
82         zlavmr,                            & ! temporary scalars
83         zave3r, ze3tr,                     & !    "         "
84         zta, zsa                             !    "         "
85      REAL(wp), DIMENSION(jpi,jpk) ::   &
86         zwx, zwy, zwz, zww
87      !!---------------------------------------------------------------------
88
89
90      ! 0. Local constant initialization
91      ! --------------------------------
92      ! time step = 2 rdttra
93      IF( neuler == 0 .AND. kt == nit000 ) THEN
94         r2dt(:) =  rdttra(:)              ! restarting with Euler time stepping
95      ELSEIF( kt <= nit000 + 1) THEN
96         r2dt(:) = 2. * rdttra(:)          ! leapfrog
97      ENDIF
98      zlavmr = 1. / float( n_zdfexp )
99
100      ! Save ta and sa trends
101      IF( l_trdtra )   THEN
102         ztdta(:,:,:) = ta(:,:,:) 
103         ztdsa(:,:,:) = sa(:,:,:) 
104      ENDIF
105
106      !                                                ! ===============
107      DO jj = 2, jpjm1                                 !  Vertical slab
108         !                                             ! ===============
109         ! 1. Initializations
110         ! ------------------
111
112         ! Surface & bottom boundary conditions: no flux
113         DO ji = 2, jpim1
114            zwy(ji, 1 ) = 0.e0
115            zwy(ji,jpk) = 0.e0
116            zww(ji, 1 ) = 0.e0
117            zww(ji,jpk) = 0.e0
118         END DO
119
120         ! zwx and zwz arrays set to before tracer values
121         DO jk = 1, jpk
122            DO ji = 2, jpim1
123               zwx(ji,jk) = tb(ji,jj,jk)
124               zwz(ji,jk) = sb(ji,jj,jk)
125            END DO
126         END DO
127
128
129         ! 2. Time splitting loop
130         ! ----------------------
131
132         DO jl = 1, n_zdfexp
133
134            ! first vertical derivative
135            IF( lk_zdfddm ) THEN       ! double diffusion: avs /= avt
136               DO jk = 2, jpk
137                  DO ji = 2, jpim1
138                     zave3r = 1.e0 / fse3w(ji,jj,jk) 
139                     zwy(ji,jk) =   avt(ji,jj,jk) * ( zwx(ji,jk-1) - zwx(ji,jk) ) * zave3r
140                     zww(ji,jk) = fsavs(ji,jj,jk) * ( zwz(ji,jk-1) - zwz(ji,jk) ) * zave3r
141                  END DO
142               END DO
143            ELSE                      ! default : avs = avt
144               DO jk = 2, jpk
145                  DO ji = 2, jpim1
146                     zave3r = avt(ji,jj,jk) / fse3w(ji,jj,jk)
147                     zwy(ji,jk) = zave3r *(zwx(ji,jk-1) - zwx(ji,jk) )
148                     zww(ji,jk) = zave3r *(zwz(ji,jk-1) - zwz(ji,jk) )
149                  END DO
150               END DO
151            ENDIF
152
153            ! trend estimation at kt+l*2*rdt/n_zdfexp
154            DO jk = 1, jpkm1
155               DO ji = 2, jpim1
156                  ze3tr = zlavmr / fse3t(ji,jj,jk)
157                  ! 2nd vertical derivative
158                  zta = ( zwy(ji,jk) - zwy(ji,jk+1) ) * ze3tr
159                  zsa = ( zww(ji,jk) - zww(ji,jk+1) ) * ze3tr
160                  ! update the tracer trends
161                  ta(ji,jj,jk) = ta(ji,jj,jk) + zta
162                  sa(ji,jj,jk) = sa(ji,jj,jk) + zsa
163                  ! update tracer fields at kt+l*2*rdt/n_zdfexp
164                  zwx(ji,jk) = zwx(ji,jk) + r2dt(jk) * zta * tmask(ji,jj,jk)
165                  zwz(ji,jk) = zwz(ji,jk) + r2dt(jk) * zsa * tmask(ji,jj,jk)
166               END DO
167            END DO
168         END DO
169         !                                             ! ===============
170      END DO                                           !   End of slab
171      !                                                ! ===============
172      ! save the trends for diagnostic
173      ! vertical diffusive tracers trends
174      IF( l_trdtra )   THEN
175         ztdta(:,:,:) = ta(:,:,:) - ztdta(:,:,:)
176         ztdsa(:,:,:) = sa(:,:,:) - ztdsa(:,:,:)
177         CALL trd_mod(ztdta, ztdsa, jpttdzdf, 'TRA', kt)
178      ENDIF
179
180      IF(l_ctl) THEN         ! print mean trends (used for debugging)
181         zta = SUM( ta(2:nictl,2:njctl,1:jpkm1) * tmask(2:nictl,2:njctl,1:jpkm1) )
182         zsa = SUM( sa(2:nictl,2:njctl,1:jpkm1) * tmask(2:nictl,2:njctl,1:jpkm1) )
183         WRITE(numout,*) ' zdf  - Ta: ', zta-t_ctl, ' Sa: ', zsa-s_ctl
184         t_ctl = zta   ;   s_ctl = zsa
185      ENDIF
186
187   END SUBROUTINE tra_zdf_exp
188
189   !!==============================================================================
190END MODULE trazdf_exp
Note: See TracBrowser for help on using the repository browser.