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 branches/DEV_r2006_merge_TRA_TRC/NEMO/OPA_SRC/TRA – NEMO

source: branches/DEV_r2006_merge_TRA_TRC/NEMO/OPA_SRC/TRA/trazdf_exp.F90 @ 2082

Last change on this file since 2082 was 2082, checked in by cetlod, 14 years ago

Improve the merge of TRA-TRC, see ticket #717

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 8.3 KB
Line 
1MODULE trazdf_exp
2   !!==============================================================================
3   !!                    ***  MODULE  trazdf_exp  ***
4   !! Ocean  tracers:  vertical component of the tracer mixing trend using
5   !!                  a split-explicit time-stepping
6   !!==============================================================================
7   !! History :  OPA  !  1990-10  (B. Blanke)  Original code
8   !!            7.0  !  1991-11  (G. Madec)
9   !!                 !  1992-06  (M. Imbard)  correction on tracer trend loops
10   !!                 !  1996-01  (G. Madec)  statement function for e3
11   !!                 !  1997-05  (G. Madec)  vertical component of isopycnal
12   !!                 !  1997-07  (G. Madec)  geopotential diffusion in s-coord
13   !!                 !  2000-08  (G. Madec)  double diffusive mixing
14   !!   NEMO     1.0  !  2002-08  (G. Madec)  F90: Free form and module
15   !!             -   !  2004-08  (C. Talandier) New trends organisation
16   !!             -   !  2005-11  (G. Madec)  New organisation
17   !!            3.0  !  2008-04  (G. Madec)  leap-frog time stepping done in trazdf
18   !!            3.3  !  2010-06  (C. Ethe, G. Madec) Merge TRA-TRC
19   !!----------------------------------------------------------------------
20
21   !!----------------------------------------------------------------------
22   !!   tra_zdf_exp  : compute the tracer the vertical diffusion trend using a
23   !!                  split-explicit time stepping and provide the after tracer
24   !!----------------------------------------------------------------------
25   USE oce             ! ocean dynamics and active tracers
26   USE dom_oce         ! ocean space and time domain
27   USE domvvl          ! variable volume levels
28   USE zdf_oce         ! ocean vertical physics
29   USE zdfddm          ! ocean vertical physics: double diffusion
30   USE in_out_manager  ! I/O manager
31   USE trc_oce         ! share passive tracers/Ocean variables
32
33   IMPLICIT NONE
34   PRIVATE
35
36   PUBLIC   tra_zdf_exp   ! routine called by step.F90
37
38   !! * Substitutions
39#  include "domzgr_substitute.h90"
40#  include "zdfddm_substitute.h90"
41#  include "vectopt_loop_substitute.h90"
42   !!----------------------------------------------------------------------
43   !! NEMO/OPA  3.3 , LOCEAN-IPSL (2010)
44   !! $Id$
45   !! Software governed by the CeCILL licence (modipsl/doc/NEMO_CeCILL.txt)
46   !!----------------------------------------------------------------------
47
48CONTAINS
49
50   SUBROUTINE tra_zdf_exp( kt, cdtype, p2dt, kn_zdfexp,  &
51      &                                ptb , pta      , kjpt )
52      !!----------------------------------------------------------------------
53      !!                  ***  ROUTINE tra_zdf_exp  ***
54      !!                   
55      !! ** Purpose :   Compute the after tracer fields due to the vertical
56      !!      tracer mixing alone, and then due to the whole tracer trend.
57      !!
58      !! ** Method  : - The after tracer fields due to the vertical diffusion
59      !!      of tracers alone is given by:
60      !!                zwx = ptb + p2dt difft
61      !!      where difft = dz( avt dz(ptb) ) = 1/e3t dk+1( avt/e3w dk(ptb) )
62      !!           (if lk_zdfddm=T use avs on salinity and passive tracers instead of avt)
63      !!      difft is evaluated with an Euler split-explit scheme using a
64      !!      no flux boundary condition at both surface and bottomi boundaries.
65      !!      (N.B. bottom condition is applied through the masked field avt).
66      !!              - the after tracer fields due to the whole trend is
67      !!      obtained in leap-frog environment by :
68      !!          pta = zwx + p2dt pta
69      !!              - in case of variable level thickness (lk_vvl=T) the
70      !!     the leap-frog is applied on thickness weighted tracer. That is:
71      !!          pta = [ ptb*e3tb + e3tn*( zwx - ptb + p2dt pta ) ] / e3tn
72      !!
73      !! ** Action : - after tracer fields pta
74      !!---------------------------------------------------------------------
75      !!
76      INTEGER         , INTENT(in   )                                ::   kt          ! ocean time-step index
77      CHARACTER(len=3), INTENT(in   )                                ::   cdtype      ! =TRA or TRC (tracer indicator)
78      INTEGER         , INTENT(in   )                                ::   kjpt        ! number of tracers
79      INTEGER         , INTENT(in   )                                ::   kn_zdfexp   ! number of sub-time step
80      REAL(wp)        , INTENT(in   ), DIMENSION(jpk)                ::   p2dt        ! vertical profile of tracer time-step
81      REAL(wp)        , INTENT(in   ), DIMENSION(jpi,jpj,jpk,kjpt)   ::   ptb       ! before and now tracer fields
82      REAL(wp)        , INTENT(inout), DIMENSION(jpi,jpj,jpk,kjpt)   ::   pta       ! tracer trend
83      !!
84      INTEGER  ::  ji, jj, jk, jn, jl        ! dummy loop indices
85      REAL(wp) ::  zlavmr, zave3r, ze3tr     ! temporary scalars
86      REAL(wp) ::  ztra, ze3tb               ! temporary scalars
87      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zwx, zwy   ! 3D workspace
88      !!---------------------------------------------------------------------
89
90      IF( ( cdtype == 'TRA' .AND. kt == nit000 ) .OR. ( cdtype == 'TRC' .AND. kt == nittrc000 ) )  THEN
91         IF(lwp) WRITE(numout,*)
92         IF(lwp) WRITE(numout,*) 'tra_zdf_exp : explicit vertical mixing on ', cdtype
93         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~'
94      ENDIF
95
96      ! Initializations
97      ! ---------------
98      zlavmr = 1. / float( kn_zdfexp )                           ! Local constant
99      !
100      !
101      DO jn = 1, kjpt
102         !
103         zwy(:,:, 1 ) = 0.e0     ! surface boundary conditions: no flux
104         zwy(:,:,jpk) = 0.e0     ! bottom  boundary conditions: no flux
105         !
106         zwx(:,:,:)   = ptb(:,:,:,jn)  ! zwx array set to before tracer values
107
108         ! Split-explicit loop  (after tracer due to the vertical diffusion alone)
109         ! -------------------
110         !
111         DO jl = 1, kn_zdfexp
112            !                     ! first vertical derivative
113            DO jk = 2, jpk
114               DO jj = 2, jpjm1 
115                  DO ji = fs_2, fs_jpim1   ! vector opt.
116                     zave3r = 1.e0 / fse3w_n(ji,jj,jk) 
117                     IF( cdtype == 'TRA' .AND. jn == jp_tem ) THEN  ! temperature : use of avt
118                        zwy(ji,jj,jk) =   avt(ji,jj,jk) * ( zwx(ji,jj,jk-1) - zwx(ji,jj,jk) ) * zave3r
119                     ELSE                                           ! salinity or pass. tracer : use of avs
120                        zwy(ji,jj,jk) = fsavs(ji,jj,jk) * ( zwx(ji,jj,jk-1) - zwx(ji,jj,jk) ) * zave3r
121                     END IF
122                  END DO
123               END DO
124            END DO
125            !
126            DO jk = 1, jpkm1      ! second vertical derivative   ==> tracer at kt+l*2*rdt/nn_zdfexp
127               DO jj = 2, jpjm1 
128                  DO ji = fs_2, fs_jpim1   ! vector opt.
129                     ze3tr = zlavmr / fse3t_n(ji,jj,jk)
130                     zwx(ji,jj,jk) = zwx(ji,jj,jk) + p2dt(jk) * ( zwy(ji,jj,jk) - zwy(ji,jj,jk+1) ) * ze3tr
131                  END DO
132               END DO
133            END DO
134            !
135         END DO
136
137         ! After tracer due to all trends
138         ! ------------------------------
139         IF( lk_vvl ) THEN          ! variable level thickness : leap-frog on tracer*e3t
140            DO jk = 1, jpkm1
141               DO jj = 2, jpjm1 
142                  DO ji = fs_2, fs_jpim1   ! vector opt.
143                     ze3tb = fse3t_b(ji,jj,jk) / fse3t(ji,jj,jk)                          ! before e3t
144                     ztra  = zwx(ji,jj,jk) - ptb(ji,jj,jk,jn) + p2dt(jk) * pta(ji,jj,jk,jn)       ! total trends * 2*rdt
145                     pta(ji,jj,jk,jn) = ( ze3tb * ptb(ji,jj,jk,jn) + ztra ) * tmask(ji,jj,jk)
146                  END DO
147               END DO
148            END DO
149         ELSE                       ! fixed level thickness : leap-frog on tracers
150            DO jk = 1, jpkm1
151               DO jj = 2, jpjm1 
152                  DO ji = fs_2, fs_jpim1   ! vector opt.
153                     pta(ji,jj,jk,jn) = ( zwx(ji,jj,jk) + p2dt(jk) * pta(ji,jj,jk,jn) ) * tmask(ji,jj,jk)
154                  END DO
155               END DO
156            END DO
157         ENDIF
158         !
159      END DO
160      !
161   END SUBROUTINE tra_zdf_exp
162
163   !!==============================================================================
164END MODULE trazdf_exp
Note: See TracBrowser for help on using the repository browser.