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.
trcadv_muscl.F90 in trunk/NEMO/TOP_SRC/TRP – NEMO

source: trunk/NEMO/TOP_SRC/TRP/trcadv_muscl.F90 @ 724

Last change on this file since 724 was 724, checked in by cetlod, 17 years ago

Update modules for passive tracers transport trends computation, see ticket:13

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 13.7 KB
Line 
1MODULE trcadv_muscl
2   !!==============================================================================
3   !!                       ***  MODULE  trcadv_muscl  ***
4   !! Ocean passive tracers:  horizontal & vertical advective trend
5   !!==============================================================================
6#if defined key_passivetrc
7   !!----------------------------------------------------------------------
8   !!   trc_adv_muscl : update the tracer trend with the horizontal
9   !!                   and vertical advection trends using MUSCL scheme
10   !!----------------------------------------------------------------------
11   !! * Modules used
12   USE oce_trc         ! ocean dynamics and active tracers variables
13   USE trc             ! ocean passive tracers variables
14   USE lbclnk          ! ocean lateral boundary conditions (or mpp link)
15   USE trcbbl          ! advective passive tracers in the BBL
16   USE lib_mpp
17   USE prtctl_trc      ! Print control for debbuging
18
19   IMPLICIT NONE
20   PRIVATE
21
22   !! * Accessibility
23   PUBLIC trc_adv_muscl  ! routine called by trcstp.F90
24
25   !! * Substitutions
26#  include "passivetrc_substitute.h90"
27   !!----------------------------------------------------------------------
28   !!   TOP 1.0 , LOCEAN-IPSL (2005)
29   !! $Header: /home/opalod/NEMOCVSROOT/NEMO/TOP_SRC/TRP/trcadv_muscl.F90,v 1.13 2007/10/12 09:26:30 opalod Exp $
30   !! This software is governed by the CeCILL licence see modipsl/doc/NEMO_CeCILL.txt
31   !!----------------------------------------------------------------------
32
33CONTAINS
34
35   SUBROUTINE trc_adv_muscl( kt )
36      !!----------------------------------------------------------------------
37      !!                    ***  ROUTINE trc_adv_muscl  ***
38      !!         
39      !! ** Purpose :   Compute the now trend due to total advection of any pas-
40      !!      sive tracer using a MUSCL scheme (Monotone Upstream-centered Scheme
41      !!      for Conservation Laws) and add it to the general tracer trend.
42      !!
43      !! ** Method  :
44      !!
45      !! ** Action  : - update tra with the now advective tracer trends
46      !!              - save trends in trtrd ('key_trc_diatrd')
47      !!
48      !! References :               
49      !!      Estubier, A., and M. Levy, Notes Techn. Pole de Modelisation
50      !! IPSL, Sept. 2000 (http://www.lodyc.jussieu.fr/opa)
51      !!
52      !! History :
53      !!        !  06-00  (A.Estublier)  for passive tracers
54      !!   9.0  !  03-04  (C. Ethe, G. Madec)  F90: Free form and module
55      !!----------------------------------------------------------------------
56      !! * modules used
57#if defined key_trcbbl_adv
58      USE oce_trc            , zun => ua,  &  ! use ua as workspace
59         &                     zvn => va      ! use va as workspace
60      REAL(wp), DIMENSION(jpi,jpj,jpk) :: zwn
61#else
62      USE oce_trc            , zun => un,  &  ! When no bbl, zun == un
63                               zvn => vn,  &  !              zvn == vn
64                               zwn => wn      !              zwn == wn
65#endif
66
67      !! * Arguments
68      INTEGER, INTENT( in ) ::   kt         ! ocean time-step
69
70      !! * Local declarations
71      INTEGER ::   ji, jj, jk,jn            ! dummy loop indices
72      REAL(wp), DIMENSION (jpi,jpj,jpk) ::   &
73         zt1, zt2, ztp1, ztp2
74
75      REAL(wp) ::   zu, zv, zw, zeu, zev, zew, zbtr, ztra
76      REAL(wp) ::   z0u, z0v, z0w
77      REAL(wp) ::   zzt1, zzt2, zalpha, z2dtt
78#if defined key_trc_diatrd
79      REAL(wp) ::   ztai, ztaj
80      REAL(wp) ::   zfui, zfvj
81#endif
82      CHARACTER (len=22) :: charout
83      !!----------------------------------------------------------------------
84
85
86      IF( kt == nittrc000 .AND. lwp ) THEN
87         WRITE(numout,*)
88         WRITE(numout,*) 'trc_adv : MUSCL advection scheme'
89         WRITE(numout,*) '~~~~~~~'
90      ENDIF
91
92 
93
94#if defined key_trcbbl_adv
95      ! Advective bottom boundary layer
96      ! -------------------------------
97      zun(:,:,:) = un (:,:,:) - u_trc_bbl(:,:,:)
98      zvn(:,:,:) = vn (:,:,:) - v_trc_bbl(:,:,:)
99      zwn(:,:,:) = wn (:,:,:) + w_trc_bbl(:,:,:)
100#endif
101
102 
103
104      DO jn = 1, jptra
105#if defined key_trc_diatrd
106        DO jk = 1,jpk
107           DO jj = 1,jpj
108              DO ji = 1,jpi
109                 IF (luttrd(jn)) trtrd(ji,jj,jk,ikeep(jn),1) = 0.
110                 IF (luttrd(jn)) trtrd(ji,jj,jk,ikeep(jn),2) = 0.
111                 IF (luttrd(jn)) trtrd(ji,jj,jk,ikeep(jn),3) = 0.
112              END DO
113            END DO
114          END DO
115#endif
116         ! I. Horizontal advective fluxes
117         ! ------------------------------
118
119         ! first guess of the slopes
120         ! interior values
121         DO jk = 1, jpkm1
122            DO jj = 1, jpjm1     
123               DO ji = 1, fs_jpim1   ! vector opt.
124                  zt1(ji,jj,jk) = umask(ji,jj,jk) * ( trb(ji+1,jj,jk,jn) - trb(ji,jj,jk,jn) )
125                  zt2(ji,jj,jk) = vmask(ji,jj,jk) * ( trb(ji,jj+1,jk,jn) - trb(ji,jj,jk,jn) )
126               END DO
127            END DO
128         END DO
129         ! bottom values
130         zt1(:,:,jpk) = 0.e0
131         zt2(:,:,jpk) = 0.e0
132
133         ! lateral boundary conditions on zt1, zt2
134         CALL lbc_lnk( zt1, 'U', -1. )   
135         CALL lbc_lnk( zt2, 'V', -1. ) 
136
137
138         ! Slopes
139         ! interior values
140         DO jk = 1, jpkm1
141            DO jj = 2, jpj
142               DO ji = fs_2, jpi   ! vector opt.
143                  ztp1(ji,jj,jk) =                    ( zt1(ji,jj,jk) + zt1(ji-1,jj  ,jk) )   &
144                     &           * ( 0.25 + SIGN( 0.25, zt1(ji,jj,jk) * zt1(ji-1,jj  ,jk) ) )
145                  ztp2(ji,jj,jk) =                    ( zt2(ji,jj,jk) + zt2(ji  ,jj-1,jk) )   &
146                     &           * ( 0.25 + SIGN( 0.25, zt2(ji,jj,jk) * zt2(ji  ,jj-1,jk) ) )
147               END DO
148            END DO
149         END DO
150         ! bottom values
151         ztp1(:,:,jpk) = 0.e0
152         ztp2(:,:,jpk) = 0.e0
153
154         ! Slopes limitation
155         DO jk = 1, jpkm1
156            DO jj = 2, jpj
157               DO ji = fs_2, jpi   ! vector opt.
158                  ztp1(ji,jj,jk) = SIGN( 1., ztp1(ji,jj,jk) )   &
159                     &           * MIN(    ABS( ztp1(ji  ,jj,jk) ),   &
160                     &                  2.*ABS( zt1 (ji-1,jj,jk) ),   &
161                     &                  2.*ABS( zt1 (ji  ,jj,jk) ) )
162
163                  ztp2(ji,jj,jk) = SIGN( 1., ztp2(ji,jj,jk) )   &
164                     &           * MIN(    ABS( ztp2(ji,jj  ,jk) ),   &
165                     &                  2.*ABS( zt2 (ji,jj-1,jk) ),   &
166                     &                  2.*ABS( zt2 (ji,jj  ,jk) ) )
167
168               END DO
169            END DO
170         END DO
171
172         ! Advection terms
173         ! interior values
174         DO jk = 1, jpkm1
175            DO jj = 2, jpjm1     
176               DO ji = fs_2, fs_jpim1   ! vector opt.
177                  ! volume fluxes
178#if ! defined key_zco
179                  zeu = e2u(ji,jj) * fse3u(ji,jj,jk) * zun(ji,jj,jk)
180                  zev = e1v(ji,jj) * fse3v(ji,jj,jk) * zvn(ji,jj,jk)
181#else
182                  zeu = e2u(ji,jj) * zun(ji,jj,jk)
183                  zev = e1v(ji,jj) * zvn(ji,jj,jk)
184#endif
185                  ! MUSCL fluxes
186                  z2dtt = rdttra(jk) * FLOAT(ndttrc)
187                  z0u = SIGN( 0.5, zun(ji,jj,jk) )           
188                  zalpha = 0.5 - z0u
189                  zu  = z0u - 0.5 * zun(ji,jj,jk) * z2dtt / e1u(ji,jj)
190                  zzt1 = trb(ji+1,jj,jk,jn) + zu*ztp1(ji+1,jj,jk)
191                  zzt2 = trb(ji  ,jj,jk,jn) + zu*ztp1(ji  ,jj,jk)
192                  zt1(ji,jj,jk) = zeu * ( zalpha * zzt1 + (1.-zalpha) * zzt2 )
193                  z0v = SIGN( 0.5, zvn(ji,jj,jk) )           
194                  zalpha = 0.5 - z0v
195                  zv  = z0v - 0.5 * zvn(ji,jj,jk) * z2dtt / e2v(ji,jj)
196                  zzt1 = trb(ji,jj+1,jk,jn) + zv*ztp2(ji,jj+1,jk)
197                  zzt2 = trb(ji,jj  ,jk,jn) + zv*ztp2(ji,jj  ,jk)
198                  zt2(ji,jj,jk) = zev * ( zalpha * zzt1 + (1.-zalpha) * zzt2 )
199               END DO
200            END DO
201         END DO
202
203         ! lateral boundary conditions on zt1, zt2 (changed sign)
204         CALL lbc_lnk( zt1, 'U', -1. ) 
205         CALL lbc_lnk( zt2, 'V', -1. ) 
206
207         ! Compute and add the horizontal advective trend
208
209         DO jk = 1, jpkm1
210            DO jj = 2, jpjm1     
211               DO ji = fs_2, fs_jpim1   ! vector opt.
212#if ! defined key_zco
213                  zbtr = 1. / ( e1t(ji,jj)*e2t(ji,jj)*fse3t(ji,jj,jk) )
214#else
215                  zbtr = 1. / ( e1t(ji,jj)*e2t(ji,jj) )
216#endif
217                  ! horizontal advective trends
218                  ztra = - zbtr * ( zt1(ji,jj,jk) - zt1(ji-1,jj  ,jk  )   &
219                     &            + zt2(ji,jj,jk) - zt2(ji  ,jj-1,jk  ) )
220                  ! add it to the general tracer trends
221                  tra(ji,jj,jk,jn) = tra(ji,jj,jk,jn) + ztra
222#if defined key_trc_diatrd
223                  ! recompute the trends in i- and j-direction as Uh gradh(T)
224#if ! defined key_zco
225                  zfui =  e2u(ji  ,jj) * fse3u(ji,  jj,jk) * un(ji,  jj,jk)   &
226                     & -  e2u(ji-1,jj) * fse3u(ji-1,jj,jk) * un(ji-1,jj,jk)
227                  zfvj =  e1v(ji,jj  ) * fse3v(ji,jj  ,jk) * vn(ji,jj  ,jk)   &
228                     & -  e1v(ji,jj-1) * fse3v(ji,jj-1,jk) * vn(ji,jj-1,jk)
229#   else
230                  zfui = e2u(ji  ,jj) * un(ji,  jj,jk)   &
231                     & - e2u(ji-1,jj) * un(ji-1,jj,jk)
232                  zfvj = e1v(ji,jj  ) * vn(ji,jj  ,jk)   &
233                     & - e1v(ji,jj-1) * vn(ji,jj-1,jk)
234#   endif
235                  ztai =-zbtr * (  zt1(ji,jj,jk) - zt1(ji-1,jj  ,jk) - trn(ji,jj,jk,jn) * zfui  )
236                  ztaj =-zbtr * (  zt2(ji,jj,jk) - zt2(ji  ,jj-1,jk) - trn(ji,jj,jk,jn) * zfvj  )
237                  ! save i- and j- advective trends computed as Uh gradh(T)
238                  IF (luttrd(jn)) trtrd(ji,jj,jk,ikeep(jn),1) = ztai
239                  IF (luttrd(jn)) trtrd(ji,jj,jk,ikeep(jn),2) = ztaj
240#endif
241               END DO
242            END DO
243         END DO
244      ENDDO
245
246      IF(ln_ctl)   THEN  ! print mean trends (used for debugging)
247         WRITE(charout, FMT="('muscl - had')")
248         CALL prt_ctl_trc_info(charout)
249         CALL prt_ctl_trc(tab4d=tra, mask=tmask, clinfo=ctrcnm,clinfo2='trd')
250      ENDIF
251
252         ! II. Vertical advective fluxes
253         ! -----------------------------
254
255      DO jn = 1, jptra
256         ! First guess of the slope
257         ! interior values
258         DO jk = 2, jpkm1
259            zt1(:,:,jk) = tmask(:,:,jk) * ( trb(:,:,jk-1,jn) - trb(:,:,jk,jn) )
260         END DO
261         ! surface and bottom boundary conditions
262         zt1 (:,:, 1 ) = 0.e0 
263         zt1 (:,:,jpk) = 0.e0
264         ! Slopes
265         DO jk = 2, jpkm1
266            DO jj = 1, jpj
267               DO ji = 1, jpi
268                  ztp1(ji,jj,jk) =                    ( zt1(ji,jj,jk) + zt1(ji,jj,jk+1) )   &
269                     &           * ( 0.25 + SIGN( 0.25, zt1(ji,jj,jk) * zt1(ji,jj,jk+1) ) )
270               END DO
271            END DO
272         END DO
273
274         ! Slopes limitation
275         ! interior values
276         DO jk = 2, jpkm1
277            DO jj = 1, jpj
278               DO ji = 1, jpi
279                  ztp1(ji,jj,jk) = SIGN( 1., ztp1(ji,jj,jk) )   &
280                     &           * MIN(    ABS( ztp1(ji,jj,jk  ) ),   &
281                     &                  2.*ABS( zt1 (ji,jj,jk+1) ),   &
282                     &                  2.*ABS( zt1 (ji,jj,jk  ) ) )
283               END DO
284            END DO
285         END DO
286         ! surface values
287         ztp1(:,:,1) = 0. 
288         ! vertical advective flux
289         ! interior values
290         DO jk = 1, jpkm1
291            DO jj = 2, jpjm1     
292               DO ji = fs_2, fs_jpim1   ! vector opt.
293                  z2dtt = rdttra(jk) * FLOAT(ndttrc)
294                  zew = zwn(ji,jj,jk+1)
295                  z0w = SIGN( 0.5, zwn(ji,jj,jk+1) )
296                  zalpha = 0.5 + z0w
297                  zw  = z0w - 0.5 * zwn(ji,jj,jk+1)*z2dtt / fse3w(ji,jj,jk+1)
298                  zzt1 = trb(ji,jj,jk+1,jn) + zw*ztp1(ji,jj,jk+1)
299                  zzt2 = trb(ji,jj,jk  ,jn) + zw*ztp1(ji,jj,jk  )
300                  zt1(ji,jj,jk+1) = zew * ( zalpha * zzt1 + (1.-zalpha)*zzt2 )
301               END DO
302            END DO
303         END DO
304         ! surface values
305         IF( lk_dynspg_rl ) THEN        ! rigid lid : flux set to zero
306            zt1(:,:, 1 ) = 0.e0
307         ELSE                           ! free surface
308            zt1(:,:, 1 ) = zwn(:,:,1) * trb(:,:,1,jn)
309         ENDIF
310
311         ! bottom values
312         zt1(:,:,jpk) = 0.e0
313
314         ! Compute & add the vertical advective trend
315
316         DO jk = 1, jpkm1
317            DO jj = 2, jpjm1     
318               DO ji = fs_2, fs_jpim1   ! vector opt.
319                  zbtr = 1. / fse3t(ji,jj,jk)
320                  ! horizontal advective trends
321                  ztra = - zbtr * ( zt1(ji,jj,jk) - zt1(ji,jj,jk+1) )
322                  ! add it to the general tracer trends
323                  tra(ji,jj,jk,jn) =  tra(ji,jj,jk,jn) + ztra
324#if defined key_trc_diatrd
325                  ! save the vertical advective trends computed as w gradz(T)
326                  IF (luttrd(jn)) trtrd(ji,jj,jk,ikeep(jn),3) = ztra - trn(ji,jj,jk,jn) * hdivn(ji,jj,jk)
327#endif
328               END DO
329            END DO
330         END DO
331
332      END DO
333
334      IF(ln_ctl)   THEN  ! print mean trends (used for debugging)
335         WRITE(charout, FMT="('muscl - zad')")
336         CALL prt_ctl_trc_info(charout)
337         CALL prt_ctl_trc(tab4d=tra, mask=tmask, clinfo=ctrcnm,clinfo2='trd')
338      ENDIF
339
340END SUBROUTINE trc_adv_muscl
341
342#else
343   !!----------------------------------------------------------------------
344   !!   Default option                                         Empty module
345   !!----------------------------------------------------------------------
346CONTAINS
347   SUBROUTINE trc_adv_muscl( kt ) 
348      INTEGER, INTENT(in) :: kt
349      WRITE(*,*) 'trc_adv_muscl: You should not have seen this print! error?', kt
350   END SUBROUTINE trc_adv_muscl
351#endif
352
353   !!======================================================================
354END MODULE trcadv_muscl
Note: See TracBrowser for help on using the repository browser.