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 trunk/NEMO/OPA_SRC/DYN – NEMO

source: trunk/NEMO/OPA_SRC/DYN/dynnxt.F90 @ 1566

Last change on this file since 1566 was 1566, checked in by rblod, 15 years ago

Cosmetic changes: suppress useless variables and code review of the code changed when suppressing rigid-lid, see ticket #508

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 12.5 KB
RevLine 
[3]1MODULE dynnxt
[1502]2   !!=========================================================================
[3]3   !!                       ***  MODULE  dynnxt  ***
4   !! Ocean dynamics: time stepping
[1502]5   !!=========================================================================
[1438]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.
[1502]16   !!            3.2  !  2009-06  (G. Madec, R.Benshila)  re-introduce the vvl option
17   !!-------------------------------------------------------------------------
[1438]18 
[1502]19   !!-------------------------------------------------------------------------
20   !!   dyn_nxt      : obtain the next (after) horizontal velocity
21   !!-------------------------------------------------------------------------
[3]22   USE oce             ! ocean dynamics and tracers
23   USE dom_oce         ! ocean space and time domain
[1502]24   USE dynspg_oce      ! type of surface pressure gradient
25   USE dynadv          ! dynamics: vector invariant versus flux form
26   USE domvvl          ! variable volume
[367]27   USE obc_oce         ! ocean open boundary conditions
[3]28   USE obcdyn          ! open boundary condition for momentum (obc_dyn routine)
[367]29   USE obcdyn_bt       ! 2D open boundary condition for momentum (obc_dyn_bt routine)
30   USE obcvol          ! ocean open boundary condition (obc_vol routines)
[911]31   USE bdy_oce         ! unstructured open boundary conditions
32   USE bdydta          ! unstructured open boundary conditions
33   USE bdydyn          ! unstructured open boundary conditions
[1502]34   USE agrif_opa_update
35   USE agrif_opa_interp
36   USE in_out_manager  ! I/O manager
[3]37   USE lbclnk          ! lateral boundary condition (or mpp link)
[258]38   USE prtctl          ! Print control
[3]39
40   IMPLICIT NONE
41   PRIVATE
42
[1438]43   PUBLIC    dyn_nxt   ! routine called by step.F90
44
[592]45   !! * Substitutions
46#  include "domzgr_substitute.h90"
[1438]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   !!-------------------------------------------------------------------------
[3]52
53CONTAINS
54
55   SUBROUTINE dyn_nxt ( kt )
56      !!----------------------------------------------------------------------
57      !!                  ***  ROUTINE dyn_nxt  ***
58      !!                   
[1502]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.
[3]63      !!
[1502]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
[3]71      !!
[1502]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)
[3]77      !!
[1502]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
[3]88      !!----------------------------------------------------------------------
89      INTEGER, INTENT( in ) ::   kt      ! ocean time-step index
[1438]90      !!
[3]91      INTEGER  ::   ji, jj, jk   ! dummy loop indices
[1566]92#if ! defined key_dynspg_flt
[3]93      REAL(wp) ::   z2dt         ! temporary scalar
[1566]94#endif
[1438]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              !    -         -
[1502]100      !!----------------------------------------------------------------------
[3]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
[1502]108#if defined key_dynspg_flt
109      !
110      ! Next velocity :   Leap-frog time stepping already done in dynspg_flt.F routine
111      ! -------------
[3]112
[1502]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
[1438]120      ! -------------
[1502]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
[1438]125         DO jk = 1, jpkm1
[1502]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)  )   &
[1438]133               &         / fse3u_a(:,:,jk) * umask(:,:,jk)
[1502]134            va(:,:,jk) = (          vb(:,:,jk) * fse3v_b(:,:,jk)      &
135               &           + z2dt * va(:,:,jk) * fse3v_n(:,:,jk)  )   &
[1438]136               &         / fse3v_a(:,:,jk) * vmask(:,:,jk)
[592]137         END DO
138      ENDIF
139
[1502]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      !
[3]146# if defined key_obc
[1502]147      !                                !* OBC open boundaries
[3]148      CALL obc_dyn( kt )
[1502]149      !
[367]150      IF ( lk_dynspg_exp .OR. lk_dynspg_ts ) THEN
[1502]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
[367]155         CALL obc_dyn_bt( kt )
[1438]156         !
[1502]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
[1438]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 )
[367]163      ENDIF
[1502]164      !
[1125]165# elif defined key_bdy 
[1502]166      !                                !* BDY open boundaries
167      IF( lk_dynspg_exp .OR. lk_dynspg_ts ) THEN       ! except for filtered option
[1438]168         !
[911]169         CALL bdy_dyn_frs( kt )
[1438]170         !
[1502]171         IF( ln_bdy_dyn_fla ) THEN
[1438]172            ua_e(:,:) = 0.e0
173            va_e(:,:) = 0.e0
[911]174            ! Set these variables for use in bdy_dyn_fla
[1502]175            hur_e(:,:) = hur(:,:)
176            hvr_e(:,:) = hvr(:,:)
[1438]177            DO jk = 1, jpkm1   !! Vertically integrated momentum trends
[911]178               ua_e(:,:) = ua_e(:,:) + fse3u(:,:,jk) * umask(:,:,jk) * ua(:,:,jk)
179               va_e(:,:) = va_e(:,:) + fse3v(:,:,jk) * vmask(:,:,jk) * va(:,:,jk)
180            END DO
[1502]181            ua_e(:,:) = ua_e(:,:) * hur(:,:)
182            va_e(:,:) = va_e(:,:) * hvr(:,:)
[911]183            DO jk = 1 , jpkm1
[1502]184               ua(:,:,jk) = ua(:,:,jk) - ua_e(:,:)
185               va(:,:,jk) = va(:,:,jk) - va_e(:,:)
[911]186            END DO
187            CALL bdy_dta_bt( kt+1, 0)
[1502]188            CALL bdy_dyn_fla( sshn_b )
189            DO jk = 1 , jpkm1
190               ua(:,:,jk) = ( ua(:,:,jk) + ua_e(:,:) ) * umask(:,:,jk)
191               va(:,:,jk) = ( va(:,:,jk) + va_e(:,:) ) * vmask(:,:,jk)
192            END DO
[911]193         ENDIF
[1438]194         !
[911]195      ENDIF
[1438]196# endif
[1502]197      !
[392]198# if defined key_agrif
[1502]199      CALL Agrif_dyn( kt )             !* AGRIF zoom boundaries
[389]200# endif
[3]201#endif
[592]202
[1438]203      ! Time filter and swap of dynamics arrays
204      ! ------------------------------------------
[1502]205      IF( neuler == 0 .AND. kt == nit000 ) THEN        !* Euler at first time-step: only swap
206         DO jk = 1, jpkm1
207            un(:,:,jk) = ua(:,:,jk)                          ! un <-- ua
[1438]208            vn(:,:,jk) = va(:,:,jk)
209         END DO
[1502]210      ELSE                                             !* Leap-Frog : Asselin filter and swap
211         IF( ln_dynadv_vec .OR. .NOT. lk_vvl ) THEN          ! applied on velocity
212            DO jk = 1, jpkm1                             
[592]213               DO jj = 1, jpj
[1502]214                  DO ji = 1, jpi   
215                     zuf = atfp * ( ub(ji,jj,jk) + ua(ji,jj,jk) ) + atfp1 * un(ji,jj,jk)
216                     zvf = atfp * ( vb(ji,jj,jk) + va(ji,jj,jk) ) + atfp1 * vn(ji,jj,jk)
217                     !
218                     ub(ji,jj,jk) = zuf                      ! ub <-- filtered velocity
219                     vb(ji,jj,jk) = zvf
220                     un(ji,jj,jk) = ua(ji,jj,jk)             ! un <-- ua
221                     vn(ji,jj,jk) = va(ji,jj,jk)
222                  END DO
223               END DO
224            END DO
225         ELSE                                                ! applied on thickness weighted velocity
226            DO jk = 1, jpkm1
227               DO jj = 1, jpj
[592]228                  DO ji = 1, jpi
[1438]229                     ze3u_a = fse3u_a(ji,jj,jk)
230                     ze3v_a = fse3v_a(ji,jj,jk)
231                     ze3u_n = fse3u_n(ji,jj,jk)
232                     ze3v_n = fse3v_n(ji,jj,jk)
233                     ze3u_b = fse3u_b(ji,jj,jk)
234                     ze3v_b = fse3v_b(ji,jj,jk)
235                     !
236                     zue3a = ua(ji,jj,jk) * ze3u_a
237                     zve3a = va(ji,jj,jk) * ze3v_a
238                     zue3n = un(ji,jj,jk) * ze3u_n
239                     zve3n = vn(ji,jj,jk) * ze3v_n
240                     zue3b = ub(ji,jj,jk) * ze3u_b
241                     zve3b = vb(ji,jj,jk) * ze3v_b
242                     !
[1502]243                     zuf  = ( atfp  * ( zue3b  + zue3a  ) + atfp1 * zue3n  )   &
244                        & / ( atfp  * ( ze3u_b + ze3u_a ) + atfp1 * ze3u_n ) * umask(ji,jj,jk)
245                     zvf  = ( atfp  * ( zve3b  + zve3a  ) + atfp1 * zve3n  )   &
246                        & / ( atfp  * ( ze3v_b + ze3v_a ) + atfp1 * ze3v_n ) * vmask(ji,jj,jk)
247                     !
248                     ub(ji,jj,jk) = zuf                      ! ub <-- filtered velocity
[1438]249                     vb(ji,jj,jk) = zvf
[1502]250                     un(ji,jj,jk) = ua(ji,jj,jk)             ! un <-- ua
[592]251                     vn(ji,jj,jk) = va(ji,jj,jk)
252                  END DO
253               END DO
[1438]254            END DO
[3]255         ENDIF
[258]256      ENDIF
[3]257
[392]258#if defined key_agrif
[1502]259      ! Update velocity at AGRIF zoom boundaries
[389]260      IF (.NOT.Agrif_Root())    CALL Agrif_Update_Dyn( kt )
261#endif     
262
[1438]263      IF(ln_ctl)   CALL prt_ctl( tab3d_1=un, clinfo1=' nxt  - Un: ', mask1=umask,   &
264         &                       tab3d_2=vn, clinfo2=' Vn: '       , mask2=vmask )
265      !
[3]266   END SUBROUTINE dyn_nxt
267
[1502]268   !!=========================================================================
[3]269END MODULE dynnxt
Note: See TracBrowser for help on using the repository browser.