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.
dynnxt.F90 in branches/DEV_r1784_mid_year_merge_2010/NEMO/OPA_SRC/DYN – NEMO

source: branches/DEV_r1784_mid_year_merge_2010/NEMO/OPA_SRC/DYN/dynnxt.F90 @ 1970

Last change on this file since 1970 was 1970, checked in by acc, 14 years ago

ticket #684 step 5: Add in changes from the trunk between revisions 1821 and 1879.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 12.6 KB
Line 
1MODULE dynnxt
2   !!=========================================================================
3   !!                       ***  MODULE  dynnxt  ***
4   !! Ocean dynamics: time stepping
5   !!=========================================================================
6   !! History :  OPA  !  1987-02  (P. Andrich, D. L Hostis)  Original code
7   !!                 !  1990-10  (C. Levy, G. Madec)
8   !!            7.0  !  1993-03  (M. Guyon)  symetrical conditions
9   !!            8.0  !  1997-02  (G. Madec & M. Imbard)  opa, release 8.0
10   !!            8.2  !  1997-04  (A. Weaver)  Euler forward step
11   !!             -   !  1997-06  (G. Madec)  lateral boudary cond., lbc routine
12   !!    NEMO    1.0  !  2002-08  (G. Madec)  F90: Free form and module
13   !!             -   !  2002-10  (C. Talandier, A-M. Treguier) Open boundary cond.
14   !!            2.0  !  2005-11  (V. Garnier) Surface pressure gradient organization
15   !!            2.3  !  2007-07  (D. Storkey) Calls to BDY routines.
16   !!            3.2  !  2009-06  (G. Madec, R.Benshila)  re-introduce the vvl option
17   !!-------------------------------------------------------------------------
18 
19   !!-------------------------------------------------------------------------
20   !!   dyn_nxt      : obtain the next (after) horizontal velocity
21   !!-------------------------------------------------------------------------
22   USE oce             ! ocean dynamics and tracers
23   USE dom_oce         ! ocean space and time domain
24   USE dynspg_oce      ! type of surface pressure gradient
25   USE dynadv          ! dynamics: vector invariant versus flux form
26   USE domvvl          ! variable volume
27   USE obc_oce         ! ocean open boundary conditions
28   USE obcdyn          ! open boundary condition for momentum (obc_dyn routine)
29   USE obcdyn_bt       ! 2D open boundary condition for momentum (obc_dyn_bt routine)
30   USE obcvol          ! ocean open boundary condition (obc_vol routines)
31   USE bdy_oce         ! unstructured open boundary conditions
32   USE bdydta          ! unstructured open boundary conditions
33   USE bdydyn          ! unstructured open boundary conditions
34   USE agrif_opa_update
35   USE agrif_opa_interp
36   USE in_out_manager  ! I/O manager
37   USE lbclnk          ! lateral boundary condition (or mpp link)
38   USE prtctl          ! Print control
39
40   IMPLICIT NONE
41   PRIVATE
42
43   PUBLIC    dyn_nxt   ! routine called by step.F90
44
45   !! * Substitutions
46#  include "domzgr_substitute.h90"
47   !!-------------------------------------------------------------------------
48   !! NEMO/OPA 3.2 , LOCEAN-IPSL (2009)
49   !! $Id$
50   !! Software is governed by the CeCILL licence (modipsl/doc/NEMO_CeCILL.txt)
51   !!-------------------------------------------------------------------------
52
53CONTAINS
54
55   SUBROUTINE dyn_nxt ( kt )
56      !!----------------------------------------------------------------------
57      !!                  ***  ROUTINE dyn_nxt  ***
58      !!                   
59      !! ** Purpose :   Compute the after horizontal velocity. Apply the boundary
60      !!             condition on the after velocity, achieved the time stepping
61      !!             by applying the Asselin filter on now fields and swapping
62      !!             the fields.
63      !!
64      !! ** Method  : * After velocity is compute using a leap-frog scheme:
65      !!                       (ua,va) = (ub,vb) + 2 rdt (ua,va)
66      !!             Note that with flux form advection and variable volume layer
67      !!             (lk_vvl=T), the leap-frog is applied on thickness weighted
68      !!             velocity.
69      !!             Note also that in filtered free surface (lk_dynspg_flt=T),
70      !!             the time stepping has already been done in dynspg module
71      !!
72      !!              * Apply lateral boundary conditions on after velocity
73      !!             at the local domain boundaries through lbc_lnk call,
74      !!             at the radiative open boundaries (lk_obc=T),
75      !!             at the relaxed   open boundaries (lk_bdy=T), and
76      !!             at the AGRIF zoom     boundaries (lk_agrif=T)
77      !!
78      !!              * Apply the time filter applied and swap of the dynamics
79      !!             arrays to start the next time step:
80      !!                (ub,vb) = (un,vn) + atfp [ (ub,vb) + (ua,va) - 2 (un,vn) ]
81      !!                (un,vn) = (ua,va).
82      !!             Note that with flux form advection and variable volume layer
83      !!             (lk_vvl=T), the time filter is applied on thickness weighted
84      !!             velocity.
85      !!
86      !! ** Action :   ub,vb   filtered before horizontal velocity of next time-step
87      !!               un,vn   now horizontal velocity of next time-step
88      !!----------------------------------------------------------------------
89      INTEGER, INTENT( in ) ::   kt      ! ocean time-step index
90      !!
91      INTEGER  ::   ji, jj, jk   ! dummy loop indices
92#if ! defined key_dynspg_flt
93      REAL(wp) ::   z2dt         ! temporary scalar
94#endif
95      REAL(wp) ::   zue3a , zue3n , zue3b    ! temporary scalar
96      REAL(wp) ::   zve3a , zve3n , zve3b    !    -         -
97      REAL(wp) ::   ze3u_b, ze3u_n, ze3u_a   !    -         -
98      REAL(wp) ::   ze3v_b, ze3v_n, ze3v_a   !    -         -
99      REAL(wp) ::   zuf   , zvf              !    -         -
100      !!----------------------------------------------------------------------
101
102      IF( kt == nit000 ) THEN
103         IF(lwp) WRITE(numout,*)
104         IF(lwp) WRITE(numout,*) 'dyn_nxt : time stepping'
105         IF(lwp) WRITE(numout,*) '~~~~~~~'
106      ENDIF
107
108#if defined key_dynspg_flt
109      !
110      ! Next velocity :   Leap-frog time stepping already done in dynspg_flt.F routine
111      ! -------------
112
113      ! Update after velocity on domain lateral boundaries      (only local domain required)
114      ! --------------------------------------------------
115      CALL lbc_lnk( ua, 'U', -1. )         ! local domain boundaries
116      CALL lbc_lnk( va, 'V', -1. ) 
117      !
118#else
119      ! Next velocity :   Leap-frog time stepping
120      ! -------------
121      z2dt = 2. * rdt                                 ! Euler or leap-frog time step
122      IF( neuler == 0 .AND. kt == nit000 )  z2dt = rdt
123      !
124      IF( ln_dynadv_vec .OR. .NOT. lk_vvl ) THEN      ! applied on velocity
125         DO jk = 1, jpkm1
126            ua(:,:,jk) = ( ub(:,:,jk) + z2dt * ua(:,:,jk) ) * umask(:,:,jk)
127            va(:,:,jk) = ( vb(:,:,jk) + z2dt * va(:,:,jk) ) * vmask(:,:,jk)
128         END DO
129      ELSE                                            ! applied on thickness weighted velocity
130         DO jk = 1, jpkm1
131            ua(:,:,jk) = (          ub(:,:,jk) * fse3u_b(:,:,jk)      &
132               &           + z2dt * ua(:,:,jk) * fse3u_n(:,:,jk)  )   &
133               &         / fse3u_a(:,:,jk) * umask(:,:,jk)
134            va(:,:,jk) = (          vb(:,:,jk) * fse3v_b(:,:,jk)      &
135               &           + z2dt * va(:,:,jk) * fse3v_n(:,:,jk)  )   &
136               &         / fse3v_a(:,:,jk) * vmask(:,:,jk)
137         END DO
138      ENDIF
139
140
141      ! Update after velocity on domain lateral boundaries
142      ! --------------------------------------------------     
143      CALL lbc_lnk( ua, 'U', -1. )     !* local domain boundaries
144      CALL lbc_lnk( va, 'V', -1. ) 
145      !
146# if defined key_obc
147      !                                !* OBC open boundaries
148      IF( lk_obc )   CALL obc_dyn( kt )
149      !
150      IF ( lk_dynspg_exp .OR. lk_dynspg_ts ) THEN
151         ! Flather boundary condition : - Update sea surface height on each open boundary
152         !                                       sshn   (= after ssh   ) for explicit case
153         !                                       sshn_b (= after ssha_b) for time-splitting case
154         !                              - Correct the barotropic velocities
155         CALL obc_dyn_bt( kt )
156         !
157!!gm ERROR - potential BUG: sshn should not be modified at this stage !!   ssh_nxt not alrady called
158         CALL lbc_lnk( sshn, 'T', 1. )         ! Boundary conditions on sshn
159         !
160         IF( ln_vol_cst )   CALL obc_vol( kt )
161         !
162         IF(ln_ctl)   CALL prt_ctl( tab2d_1=sshn, clinfo1=' ssh      : ', mask1=tmask )
163      ENDIF
164      !
165# elif defined key_bdy 
166      !                                !* BDY open boundaries
167      !RB all this part should be in a specific routine
168      IF( lk_dynspg_exp .OR. lk_dynspg_ts ) THEN       ! except for filtered option
169         !
170         CALL bdy_dyn_frs( kt )
171         !
172         IF( ln_bdy_dyn_fla ) THEN
173            ua_e(:,:) = 0.e0
174            va_e(:,:) = 0.e0
175            ! Set these variables for use in bdy_dyn_fla
176            hur_e(:,:) = hur(:,:)
177            hvr_e(:,:) = hvr(:,:)
178            DO jk = 1, jpkm1   !! Vertically integrated momentum trends
179               ua_e(:,:) = ua_e(:,:) + fse3u(:,:,jk) * umask(:,:,jk) * ua(:,:,jk)
180               va_e(:,:) = va_e(:,:) + fse3v(:,:,jk) * vmask(:,:,jk) * va(:,:,jk)
181            END DO
182            ua_e(:,:) = ua_e(:,:) * hur(:,:)
183            va_e(:,:) = va_e(:,:) * hvr(:,:)
184            DO jk = 1 , jpkm1
185               ua(:,:,jk) = ua(:,:,jk) - ua_e(:,:)
186               va(:,:,jk) = va(:,:,jk) - va_e(:,:)
187            END DO
188            CALL bdy_dta_bt( kt+1, 0)
189            CALL bdy_dyn_fla( sshn_b )
190            CALL lbc_lnk( ua_e, 'U', -1. )   ! Boundary points should be updated
191            CALL lbc_lnk( va_e, 'V', -1. )   !
192            DO jk = 1 , jpkm1
193               ua(:,:,jk) = ( ua(:,:,jk) + ua_e(:,:) ) * umask(:,:,jk)
194               va(:,:,jk) = ( va(:,:,jk) + va_e(:,:) ) * vmask(:,:,jk)
195            END DO
196         ENDIF
197         !
198      ENDIF
199# endif
200      !
201# if defined key_agrif
202      CALL Agrif_dyn( kt )             !* AGRIF zoom boundaries
203# endif
204#endif
205
206      ! Time filter and swap of dynamics arrays
207      ! ------------------------------------------
208      IF( neuler == 0 .AND. kt == nit000 ) THEN        !* Euler at first time-step: only swap
209         DO jk = 1, jpkm1
210            un(:,:,jk) = ua(:,:,jk)                          ! un <-- ua
211            vn(:,:,jk) = va(:,:,jk)
212         END DO
213      ELSE                                             !* Leap-Frog : Asselin filter and swap
214         IF( ln_dynadv_vec .OR. .NOT. lk_vvl ) THEN          ! applied on velocity
215            DO jk = 1, jpkm1                             
216               DO jj = 1, jpj
217                  DO ji = 1, jpi   
218                     zuf = atfp * ( ub(ji,jj,jk) + ua(ji,jj,jk) ) + atfp1 * un(ji,jj,jk)
219                     zvf = atfp * ( vb(ji,jj,jk) + va(ji,jj,jk) ) + atfp1 * vn(ji,jj,jk)
220                     !
221                     ub(ji,jj,jk) = zuf                      ! ub <-- filtered velocity
222                     vb(ji,jj,jk) = zvf
223                     un(ji,jj,jk) = ua(ji,jj,jk)             ! un <-- ua
224                     vn(ji,jj,jk) = va(ji,jj,jk)
225                  END DO
226               END DO
227            END DO
228         ELSE                                                ! applied on thickness weighted velocity
229            DO jk = 1, jpkm1
230               DO jj = 1, jpj
231                  DO ji = 1, jpi
232                     ze3u_a = fse3u_a(ji,jj,jk)
233                     ze3v_a = fse3v_a(ji,jj,jk)
234                     ze3u_n = fse3u_n(ji,jj,jk)
235                     ze3v_n = fse3v_n(ji,jj,jk)
236                     ze3u_b = fse3u_b(ji,jj,jk)
237                     ze3v_b = fse3v_b(ji,jj,jk)
238                     !
239                     zue3a = ua(ji,jj,jk) * ze3u_a
240                     zve3a = va(ji,jj,jk) * ze3v_a
241                     zue3n = un(ji,jj,jk) * ze3u_n
242                     zve3n = vn(ji,jj,jk) * ze3v_n
243                     zue3b = ub(ji,jj,jk) * ze3u_b
244                     zve3b = vb(ji,jj,jk) * ze3v_b
245                     !
246                     zuf  = ( atfp  * ( zue3b  + zue3a  ) + atfp1 * zue3n  )   &
247                        & / ( atfp  * ( ze3u_b + ze3u_a ) + atfp1 * ze3u_n ) * umask(ji,jj,jk)
248                     zvf  = ( atfp  * ( zve3b  + zve3a  ) + atfp1 * zve3n  )   &
249                        & / ( atfp  * ( ze3v_b + ze3v_a ) + atfp1 * ze3v_n ) * vmask(ji,jj,jk)
250                     !
251                     ub(ji,jj,jk) = zuf                      ! ub <-- filtered velocity
252                     vb(ji,jj,jk) = zvf
253                     un(ji,jj,jk) = ua(ji,jj,jk)             ! un <-- ua
254                     vn(ji,jj,jk) = va(ji,jj,jk)
255                  END DO
256               END DO
257            END DO
258         ENDIF
259      ENDIF
260
261#if defined key_agrif
262      ! Update velocity at AGRIF zoom boundaries
263      IF (.NOT.Agrif_Root())    CALL Agrif_Update_Dyn( kt )
264#endif     
265
266      IF(ln_ctl)   CALL prt_ctl( tab3d_1=un, clinfo1=' nxt  - Un: ', mask1=umask,   &
267         &                       tab3d_2=vn, clinfo2=' Vn: '       , mask2=vmask )
268      !
269   END SUBROUTINE dyn_nxt
270
271   !!=========================================================================
272END MODULE dynnxt
Note: See TracBrowser for help on using the repository browser.