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

source: trunk/NEMO/OPA_SRC/TRA/tranxt.F90 @ 1110

Last change on this file since 1110 was 1110, checked in by ctlod, 16 years ago

trunk: remove a bug related to the combination of key_vvl and ln_trazdf_exp options, see ticket: #202

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.7 KB
Line 
1MODULE tranxt
2   !!======================================================================
3   !!                       ***  MODULE  tranxt  ***
4   !! Ocean active tracers:  time stepping on temperature and salinity
5   !!======================================================================
6   !! History :  OPA  !  1991-11  (G. Madec)  Original code
7   !!            7.0  !  1993-03  (M. Guyon)  symetrical conditions
8   !!            8.0  !  1996-02  (G. Madec & M. Imbard)  opa release 8.0
9   !!             -   !  1996-04  (A. Weaver)  Euler forward step
10   !!            8.2  !  1999-02  (G. Madec, N. Grima)  semi-implicit pressure grad.
11   !!  NEMO      1.0  !  2002-08  (G. Madec)  F90: Free form and module
12   !!             -   !  2002-11  (C. Talandier, A-M Treguier) Open boundaries
13   !!             -   !  2005-04  (C. Deltel) Add Asselin trend in the ML budget
14   !!            2.0  !  2006-02  (L. Debreu, C. Mazauric) Agrif implementation
15   !!            3.0  !  2008-06  (G. Madec)  time stepping always done in trazdf
16   !!----------------------------------------------------------------------
17
18   !!----------------------------------------------------------------------
19   !!   tra_nxt       : time stepping on temperature and salinity
20   !!----------------------------------------------------------------------
21   USE oce             ! ocean dynamics and tracers variables
22   USE dom_oce         ! ocean space and time domain variables
23   USE zdf_oce         ! ???
24   USE dynspg_oce      ! surface pressure gradient variables
25   USE trdmod_oce      ! ocean variables trends
26   USE trdmod          ! ocean active tracers trends
27   USE phycst
28   USE obctra          ! open boundary condition (obc_tra routine)
29   USE bdytra          ! Unstructured open boundary condition (bdy_tra routine)
30   USE in_out_manager  ! I/O manager
31   USE lbclnk          ! ocean lateral boundary conditions (or mpp link)
32   USE prtctl          ! Print control
33   USE agrif_opa_update
34   USE agrif_opa_interp
35
36   IMPLICIT NONE
37   PRIVATE
38
39   PUBLIC   tra_nxt    ! routine called by step.F90
40
41   !! * Substitutions
42#  include "domzgr_substitute.h90"
43   !!----------------------------------------------------------------------
44   !! NEMO/OPA 3.0 , LOCEAN-IPSL (2008)
45   !! $Id:$
46   !! Software governed by the CeCILL licence (modipsl/doc/NEMO_CeCILL.txt)
47   !!----------------------------------------------------------------------
48
49CONTAINS
50
51   SUBROUTINE tra_nxt( kt )
52      !!----------------------------------------------------------------------
53      !!                   ***  ROUTINE tranxt  ***
54      !!
55      !! ** Purpose :   Apply the boundary condition on the after temperature 
56      !!             and salinity fields, achieved the time stepping by adding
57      !!             the Asselin filter on now fields and swapping the fields.
58      !!
59      !! ** Method  :   At this stage of the computation, ta and sa are the
60      !!             after temperature and salinity as the time stepping has
61      !!             been performed in trazdf_imp or trazdf_exp module.
62      !!
63      !!              - Apply lateral boundary conditions on (ta,sa)
64      !!             at the local domain   boundaries through lbc_lnk call,
65      !!             at the radiative open boundaries (lk_obc=T),
66      !!             at the relaxed   open boundaries (lk_bdy=T), and
67      !!             at the AGRIF zoom     boundaries (lk_agrif=T)
68      !!
69      !!              - Apply the Asselin time filter on now fields,
70      !!             save in (ta,sa) an average over the three time levels
71      !!             which will be used to compute rdn and thus the semi-implicit
72      !!             hydrostatic pressure gradient (ln_dynhpg_imp = T), and
73      !!             swap tracer fields to prepare the next time_step.
74      !!                This can be summurized for tempearture as:
75      !!                    zt = (ta+2tn+tb)/4       ln_dynhpg_imp = T
76      !!                    zt = 0                   otherwise
77      !!                    tb = tn + atfp*[ tb - 2 tn + ta ]
78      !!                    tn = ta
79      !!                    ta = zt        (NB: reset to 0 after eos_bn2 call)
80      !!
81      !! ** Action  : - (tb,sb) and (tn,sn) ready for the next time step
82      !!              - (ta,sa) time averaged (t,s)   (ln_dynhpg_imp = T)
83      !!----------------------------------------------------------------------
84      USE oce, ONLY :    ztrdt => ua   ! use ua as 3D workspace   
85      USE oce, ONLY :    ztrds => va   ! use va as 3D workspace   
86      !!
87      INTEGER, INTENT(in) ::   kt    ! ocean time-step index
88      !!
89      INTEGER  ::   ji, jj, jk    ! dummy loop indices
90      REAL(wp) ::   zt, zs, zfact ! temporary scalars
91      !!----------------------------------------------------------------------
92
93      IF( kt == nit000 ) THEN
94         IF(lwp) WRITE(numout,*)
95         IF(lwp) WRITE(numout,*) 'tra_nxt : achieve the time stepping by Asselin filter and array swap'
96         IF(lwp) WRITE(numout,*) '~~~~~~~'
97      ENDIF
98
99      ! Update after tracer on domain lateral boundaries
100      !
101      CALL lbc_lnk( ta, 'T', 1. )      ! local domain boundaries  (T-point, unchanged sign)
102      CALL lbc_lnk( sa, 'T', 1. )
103      !
104#if defined key_obc
105      CALL obc_tra( kt )               ! OBC open boundaries
106#endif
107#if defined key_bdy
108      CALL bdy_tra( kt )               ! BDY open boundaries
109#endif
110#if defined key_agrif
111      CALL Agrif_tra                   ! AGRIF zoom boundaries
112#endif
113
114      ! trends computation initialisation
115      IF( l_trdtra ) THEN              ! store now fields before applying the Asselin filter
116         ztrdt(:,:,:) = tn(:,:,:)     
117         ztrds(:,:,:) = sn(:,:,:)
118      ENDIF
119
120      ! Asselin time filter and swap of arrays
121      !                                             
122      IF( neuler == 0 .AND. kt == nit000 ) THEN      ! Euler 1st time step : swap only
123         DO jk = 1, jpkm1
124            tb(:,:,jk) = tn(:,:,jk)                       ! ta, sa remain at their values which
125            sb(:,:,jk) = sn(:,:,jk)                       ! correspond to tn, sn after the sawp
126            tn(:,:,jk) = ta(:,:,jk)                     
127            sn(:,:,jk) = sa(:,:,jk)
128         END DO
129         !                                           
130      ELSE                                           ! Leap-Frog : filter + swap
131         !                                           
132         IF( ln_dynhpg_imp ) THEN                         ! semi-implicite hpg case
133            DO jk = 1, jpkm1                              ! (save the averaged of the 3 time steps
134               DO jj = 1, jpj                             !                   in the after fields)
135                  DO ji = 1, jpi
136                     zt = ( ta(ji,jj,jk) + 2. * tn(ji,jj,jk) + tb(ji,jj,jk) ) * 0.25
137                     zs = ( sa(ji,jj,jk) + 2. * sn(ji,jj,jk) + sb(ji,jj,jk) ) * 0.25
138                     tb(ji,jj,jk) = atfp * ( tb(ji,jj,jk) + ta(ji,jj,jk) ) + atfp1 * tn(ji,jj,jk)
139                     sb(ji,jj,jk) = atfp * ( sb(ji,jj,jk) + sa(ji,jj,jk) ) + atfp1 * sn(ji,jj,jk)
140                     tn(ji,jj,jk) = ta(ji,jj,jk)
141                     sn(ji,jj,jk) = sa(ji,jj,jk)
142                     ta(ji,jj,jk) = zt
143                     sa(ji,jj,jk) = zs
144                  END DO
145               END DO
146            END DO
147         ELSE                                            ! explicit hpg case
148            DO jk = 1, jpkm1
149               DO jj = 1, jpj
150                  DO ji = 1, jpi
151                     tb(ji,jj,jk) = atfp * ( tb(ji,jj,jk) + ta(ji,jj,jk) ) + atfp1 * tn(ji,jj,jk)
152                     sb(ji,jj,jk) = atfp * ( sb(ji,jj,jk) + sa(ji,jj,jk) ) + atfp1 * sn(ji,jj,jk)
153                     tn(ji,jj,jk) = ta(ji,jj,jk)
154                     sn(ji,jj,jk) = sa(ji,jj,jk)
155                  END DO
156               END DO
157            END DO
158         ENDIF
159         !
160      ENDIF
161
162#if defined key_agrif
163      ! Update tracer at AGRIF zoom boundaries
164      IF( .NOT.Agrif_Root() )    CALL Agrif_Update_Tra( kt )      ! children only
165#endif     
166
167      ! trends diagnostics :  Asselin filter trend : (tb filtered - tb)/2dt
168      IF( l_trdtra ) THEN     
169         DO jk = 1, jpkm1
170            zfact = 1.e0 / ( 2.*rdttra(jk) )             ! NB: euler case, (tb filtered - tb)=0 so 2dt always OK
171            ztrdt(:,:,jk) = ( tb(:,:,jk) - ztrdt(:,:,jk) ) * zfact
172            ztrds(:,:,jk) = ( sb(:,:,jk) - ztrds(:,:,jk) ) * zfact
173         END DO
174         CALL trd_mod( ztrdt, ztrds, jptra_trd_atf, 'TRA', kt )
175      END IF
176      !                        ! control print
177      IF(ln_ctl)   CALL prt_ctl( tab3d_1=tn, clinfo1=' nxt  - Tn: ', mask1=tmask,   &
178         &                       tab3d_2=sn, clinfo2=       ' Sn: ', mask2=tmask )
179      !
180   END SUBROUTINE tra_nxt
181
182   !!======================================================================
183END MODULE tranxt
Note: See TracBrowser for help on using the repository browser.