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 NEMO/branches/UKMO/r14075_India_uncoupled/src/OCE/DYN – NEMO

source: NEMO/branches/UKMO/r14075_India_uncoupled/src/OCE/DYN/dynnxt.F90 @ 15422

Last change on this file since 15422 was 15422, checked in by jcastill, 3 years ago

Changes tested so that they can merged with the CO9 Met Office branch - jpmax_harmo should be 34 with FES14 tides, but the last components are not used anyway

File size: 22.7 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
[2528]17   !!            3.3  !  2010-09  (D. Storkey, E.O'Dea) Bug fix for BDY module
[2723]18   !!            3.3  !  2011-03  (P. Oddo) Bug fix for time-splitting+(BDY-OBC) and not VVL
[4292]19   !!            3.5  !  2013-07  (J. Chanut) Compliant with time splitting changes
[6140]20   !!            3.6  !  2014-04  (G. Madec) add the diagnostic of the time filter trends
[5930]21   !!            3.7  !  2015-11  (J. Chanut) Free surface simplification
[1502]22   !!-------------------------------------------------------------------------
[1438]23 
[1502]24   !!-------------------------------------------------------------------------
[6140]25   !!   dyn_nxt       : obtain the next (after) horizontal velocity
[1502]26   !!-------------------------------------------------------------------------
[6140]27   USE oce            ! ocean dynamics and tracers
28   USE dom_oce        ! ocean space and time domain
29   USE sbc_oce        ! Surface boundary condition: ocean fields
[9023]30   USE sbcrnf         ! river runoffs
[9361]31   USE sbcisf         ! ice shelf
[6140]32   USE phycst         ! physical constants
33   USE dynadv         ! dynamics: vector invariant versus flux form
34   USE dynspg_ts      ! surface pressure gradient: split-explicit scheme
[15422]35   USE dynspg
[6140]36   USE domvvl         ! variable volume
[13284]37   USE bdy_oce , ONLY : ln_bdy
[6140]38   USE bdydta         ! ocean open boundary conditions
39   USE bdydyn         ! ocean open boundary conditions
40   USE bdyvol         ! ocean open boundary condition (bdy_vol routines)
41   USE trd_oce        ! trends: ocean variables
42   USE trddyn         ! trend manager: dynamics
43   USE trdken         ! trend manager: kinetic energy
[4990]44   !
[6140]45   USE in_out_manager ! I/O manager
46   USE iom            ! I/O manager library
47   USE lbclnk         ! lateral boundary condition (or mpp link)
48   USE lib_mpp        ! MPP library
49   USE prtctl         ! Print control
50   USE timing         ! Timing
[13284]51   USE zdfdrg ,  ONLY : ln_drgice_imp, rCdU_top
[2528]52#if defined key_agrif
[9570]53   USE agrif_oce_interp
[2528]54#endif
[3]55
56   IMPLICIT NONE
57   PRIVATE
58
[1438]59   PUBLIC    dyn_nxt   ! routine called by step.F90
60
[15422]61   !! Substitution
62#  include "vectopt_loop_substitute.h90"
[2715]63   !!----------------------------------------------------------------------
[9598]64   !! NEMO/OCE 4.0 , NEMO Consortium (2018)
[14075]65   !! $Id$
[10068]66   !! Software governed by the CeCILL license (see ./LICENSE)
[2715]67   !!----------------------------------------------------------------------
[3]68CONTAINS
69
70   SUBROUTINE dyn_nxt ( kt )
71      !!----------------------------------------------------------------------
72      !!                  ***  ROUTINE dyn_nxt  ***
73      !!                   
[5930]74      !! ** Purpose :   Finalize after horizontal velocity. Apply the boundary
75      !!             condition on the after velocity, achieve the time stepping
[1502]76      !!             by applying the Asselin filter on now fields and swapping
77      !!             the fields.
[3]78      !!
[5930]79      !! ** Method  : * Ensure after velocities transport matches time splitting
80      !!             estimate (ln_dynspg_ts=T)
[3]81      !!
[1502]82      !!              * Apply lateral boundary conditions on after velocity
83      !!             at the local domain boundaries through lbc_lnk call,
[7646]84      !!             at the one-way open boundaries (ln_bdy=T),
[4990]85      !!             at the AGRIF zoom   boundaries (lk_agrif=T)
[3]86      !!
[1502]87      !!              * Apply the time filter applied and swap of the dynamics
88      !!             arrays to start the next time step:
89      !!                (ub,vb) = (un,vn) + atfp [ (ub,vb) + (ua,va) - 2 (un,vn) ]
90      !!                (un,vn) = (ua,va).
[6140]91      !!             Note that with flux form advection and non linear free surface,
92      !!             the time filter is applied on thickness weighted velocity.
93      !!             As a result, dyn_nxt MUST be called after tra_nxt.
[1502]94      !!
95      !! ** Action :   ub,vb   filtered before horizontal velocity of next time-step
96      !!               un,vn   now horizontal velocity of next time-step
[3]97      !!----------------------------------------------------------------------
98      INTEGER, INTENT( in ) ::   kt      ! ocean time-step index
[2715]99      !
[3]100      INTEGER  ::   ji, jj, jk   ! dummy loop indices
[6140]101      INTEGER  ::   ikt          ! local integers
102      REAL(wp) ::   zue3a, zue3n, zue3b, zuf, zcoef    ! local scalars
[4990]103      REAL(wp) ::   zve3a, zve3n, zve3b, zvf, z1_2dt   !   -      -
[9019]104      REAL(wp), ALLOCATABLE, DIMENSION(:,:)   ::   zue, zve
[13284]105      REAL(wp), ALLOCATABLE, DIMENSION(:,:)   ::   zutau, zvtau
[9019]106      REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) ::   ze3u_f, ze3v_f, zua, zva 
[1502]107      !!----------------------------------------------------------------------
[3294]108      !
[9019]109      IF( ln_timing    )   CALL timing_start('dyn_nxt')
110      IF( ln_dynspg_ts )   ALLOCATE( zue(jpi,jpj)     , zve(jpi,jpj)     )
111      IF( l_trddyn     )   ALLOCATE( zua(jpi,jpj,jpk) , zva(jpi,jpj,jpk) )
[3294]112      !
[3]113      IF( kt == nit000 ) THEN
114         IF(lwp) WRITE(numout,*)
115         IF(lwp) WRITE(numout,*) 'dyn_nxt : time stepping'
116         IF(lwp) WRITE(numout,*) '~~~~~~~'
117      ENDIF
118
[5930]119      IF ( ln_dynspg_ts ) THEN
120         ! Ensure below that barotropic velocities match time splitting estimate
121         ! Compute actual transport and replace it with ts estimate at "after" time step
[7753]122         zue(:,:) = e3u_a(:,:,1) * ua(:,:,1) * umask(:,:,1)
123         zve(:,:) = e3v_a(:,:,1) * va(:,:,1) * vmask(:,:,1)
[5930]124         DO jk = 2, jpkm1
[7753]125            zue(:,:) = zue(:,:) + e3u_a(:,:,jk) * ua(:,:,jk) * umask(:,:,jk)
126            zve(:,:) = zve(:,:) + e3v_a(:,:,jk) * va(:,:,jk) * vmask(:,:,jk)
[1502]127         END DO
128         DO jk = 1, jpkm1
[7753]129            ua(:,:,jk) = ( ua(:,:,jk) - zue(:,:) * r1_hu_a(:,:) + ua_b(:,:) ) * umask(:,:,jk)
130            va(:,:,jk) = ( va(:,:,jk) - zve(:,:) * r1_hv_a(:,:) + va_b(:,:) ) * vmask(:,:,jk)
[592]131         END DO
[6140]132         !
133         IF( .NOT.ln_bt_fw ) THEN
[5930]134            ! Remove advective velocity from "now velocities"
135            ! prior to asselin filtering     
136            ! In the forward case, this is done below after asselin filtering   
137            ! so that asselin contribution is removed at the same time
138            DO jk = 1, jpkm1
[9023]139               un(:,:,jk) = ( un(:,:,jk) - un_adv(:,:)*r1_hu_n(:,:) + un_b(:,:) )*umask(:,:,jk)
140               vn(:,:,jk) = ( vn(:,:,jk) - vn_adv(:,:)*r1_hv_n(:,:) + vn_b(:,:) )*vmask(:,:,jk)
[7753]141            END DO 
[5930]142         ENDIF
[4292]143      ENDIF
144
[1502]145      ! Update after velocity on domain lateral boundaries
146      ! --------------------------------------------------     
[5930]147# if defined key_agrif
148      CALL Agrif_dyn( kt )             !* AGRIF zoom boundaries
149# endif
150      !
[10425]151      CALL lbc_lnk_multi( 'dynnxt', ua, 'U', -1., va, 'V', -1. )     !* local domain boundaries
[1502]152      !
153      !                                !* BDY open boundaries
[7646]154      IF( ln_bdy .AND. ln_dynspg_exp )   CALL bdy_dyn( kt )
155      IF( ln_bdy .AND. ln_dynspg_ts  )   CALL bdy_dyn( kt, dyn3d_only=.true. )
[3294]156
157!!$   Do we need a call to bdy_vol here??
158      !
[4990]159      IF( l_trddyn ) THEN             ! prepare the atf trend computation + some diagnostics
160         z1_2dt = 1._wp / (2. * rdt)        ! Euler or leap-frog time step
161         IF( neuler == 0 .AND. kt == nit000 )   z1_2dt = 1._wp / rdt
162         !
163         !                                  ! Kinetic energy and Conversion
164         IF( ln_KE_trd  )   CALL trd_dyn( ua, va, jpdyn_ken, kt )
165         !
166         IF( ln_dyn_trd ) THEN              ! 3D output: total momentum trends
[7753]167            zua(:,:,:) = ( ua(:,:,:) - ub(:,:,:) ) * z1_2dt
168            zva(:,:,:) = ( va(:,:,:) - vb(:,:,:) ) * z1_2dt
[4990]169            CALL iom_put( "utrd_tot", zua )        ! total momentum trends, except the asselin time filter
170            CALL iom_put( "vtrd_tot", zva )
171         ENDIF
172         !
[7753]173         zua(:,:,:) = un(:,:,:)             ! save the now velocity before the asselin filter
174         zva(:,:,:) = vn(:,:,:)             ! (caution: there will be a shift by 1 timestep in the
175         !                                  !  computation of the asselin filter trends)
[4990]176      ENDIF
177
[1438]178      ! Time filter and swap of dynamics arrays
179      ! ------------------------------------------
[1502]180      IF( neuler == 0 .AND. kt == nit000 ) THEN        !* Euler at first time-step: only swap
181         DO jk = 1, jpkm1
[12026]182            ub(:,:,jk) = un(:,:,jk)                         ! ub <-- un
183            vb(:,:,jk) = vn(:,:,jk)
[9226]184            un(:,:,jk) = ua(:,:,jk)                         ! un <-- ua
[7753]185            vn(:,:,jk) = va(:,:,jk)
[1438]186         END DO
[15422]187         ! limit velocities 
188         IF (ln_ulimit) THEN 
189            call dyn_limit_velocity (kt) 
190         ENDIF
[9226]191         IF( .NOT.ln_linssh ) THEN                          ! e3._b <-- e3._n
192!!gm BUG ????    I don't understand why it is not : e3._n <-- e3._a 
[4292]193            DO jk = 1, jpkm1
[9226]194!               e3t_b(:,:,jk) = e3t_n(:,:,jk)
195!               e3u_b(:,:,jk) = e3u_n(:,:,jk)
196!               e3v_b(:,:,jk) = e3v_n(:,:,jk)
197               !
198               e3t_n(:,:,jk) = e3t_a(:,:,jk)
199               e3u_n(:,:,jk) = e3u_a(:,:,jk)
200               e3v_n(:,:,jk) = e3v_a(:,:,jk)
[6140]201            END DO
[9226]202!!gm BUG end
[4292]203         ENDIF
[9226]204                                                            !
205         
[1502]206      ELSE                                             !* Leap-Frog : Asselin filter and swap
[2528]207         !                                ! =============!
[6140]208         IF( ln_linssh ) THEN             ! Fixed volume !
[2528]209            !                             ! =============!
[1502]210            DO jk = 1, jpkm1                             
[592]211               DO jj = 1, jpj
[1502]212                  DO ji = 1, jpi   
[4990]213                     zuf = un(ji,jj,jk) + atfp * ( ub(ji,jj,jk) - 2._wp * un(ji,jj,jk) + ua(ji,jj,jk) )
214                     zvf = vn(ji,jj,jk) + atfp * ( vb(ji,jj,jk) - 2._wp * vn(ji,jj,jk) + va(ji,jj,jk) )
[1502]215                     !
216                     ub(ji,jj,jk) = zuf                      ! ub <-- filtered velocity
217                     vb(ji,jj,jk) = zvf
218                     un(ji,jj,jk) = ua(ji,jj,jk)             ! un <-- ua
219                     vn(ji,jj,jk) = va(ji,jj,jk)
220                  END DO
221               END DO
222            END DO
[15422]223            ! limit velocities 
224            IF (ln_ulimit) THEN 
225               call dyn_limit_velocity (kt) 
226            ENDIF
[2528]227            !                             ! ================!
228         ELSE                             ! Variable volume !
229            !                             ! ================!
[4292]230            ! Before scale factor at t-points
231            ! (used as a now filtered scale factor until the swap)
232            ! ----------------------------------------------------
[9023]233            DO jk = 1, jpkm1
234               e3t_b(:,:,jk) = e3t_n(:,:,jk) + atfp * ( e3t_b(:,:,jk) - 2._wp * e3t_n(:,:,jk) + e3t_a(:,:,jk) )
235            END DO
236            ! Add volume filter correction: compatibility with tracer advection scheme
237            ! => time filter + conservation correction (only at the first level)
238            zcoef = atfp * rdt * r1_rau0
[9361]239
[12279]240            DO jk = 1, jpkm1
241               e3t_b(:,:,jk) = e3t_b(:,:,jk) - zcoef * ( emp_b(:,:) - emp(:,:) ) * tmask(:,:,jk) & 
242                             &                       * e3t_n(:,:,jk) /  ( ht_n(:,:) + 1._wp - ssmask(:,:) )
243            END DO
[9361]244
245            IF ( ln_rnf ) THEN
[12279]246               DO jk = 1, jpkm1
[12366]247                  e3t_b(:,:,jk) = e3t_b(:,:,jk) + zcoef * ( rnf_b(:,:) - rnf(:,:) ) * tmask(:,:,jk) & 
[12279]248                                &                       * e3t_n(:,:,jk) /  ( ht_n(:,:) + 1._wp - ssmask(:,:) )
249               END DO
250            ENDIF
[9361]251
[12279]252            IF ( ln_isf ) THEN
253               DO jk = 1, jpkm1
254                  e3t_b(:,:,jk) = e3t_b(:,:,jk) - zcoef * ( fwfisf_b(:,:) - fwfisf(:,:) ) * tmask(:,:,jk) & 
255                                &                       * e3t_n(:,:,jk) /  ( ht_n(:,:) + 1._wp - ssmask(:,:) )
[9361]256               END DO
[12279]257            ENDIF
[2528]258            !
[6140]259            IF( ln_dynadv_vec ) THEN      ! Asselin filter applied on velocity
260               ! Before filtered scale factor at (u/v)-points
261               CALL dom_vvl_interpol( e3t_b(:,:,:), e3u_b(:,:,:), 'U' )
262               CALL dom_vvl_interpol( e3t_b(:,:,:), e3v_b(:,:,:), 'V' )
[4292]263               DO jk = 1, jpkm1
264                  DO jj = 1, jpj
[2528]265                     DO ji = 1, jpi
[4292]266                        zuf = un(ji,jj,jk) + atfp * ( ub(ji,jj,jk) - 2._wp * un(ji,jj,jk) + ua(ji,jj,jk) )
267                        zvf = vn(ji,jj,jk) + atfp * ( vb(ji,jj,jk) - 2._wp * vn(ji,jj,jk) + va(ji,jj,jk) )
[2528]268                        !
269                        ub(ji,jj,jk) = zuf                      ! ub <-- filtered velocity
270                        vb(ji,jj,jk) = zvf
271                        un(ji,jj,jk) = ua(ji,jj,jk)             ! un <-- ua
272                        vn(ji,jj,jk) = va(ji,jj,jk)
273                     END DO
274                  END DO
275               END DO
[15422]276               ! limit velocities 
277               IF (ln_ulimit) THEN 
278                  call dyn_limit_velocity (kt) 
279               ENDIF
[2528]280               !
[6140]281            ELSE                          ! Asselin filter applied on thickness weighted velocity
282               !
[9019]283               ALLOCATE( ze3u_f(jpi,jpj,jpk) , ze3v_f(jpi,jpj,jpk) )
[6140]284               ! Before filtered scale factor at (u/v)-points stored in ze3u_f, ze3v_f
285               CALL dom_vvl_interpol( e3t_b(:,:,:), ze3u_f, 'U' )
286               CALL dom_vvl_interpol( e3t_b(:,:,:), ze3v_f, 'V' )
[4292]287               DO jk = 1, jpkm1
288                  DO jj = 1, jpj
[4312]289                     DO ji = 1, jpi                 
[6140]290                        zue3a = e3u_a(ji,jj,jk) * ua(ji,jj,jk)
291                        zve3a = e3v_a(ji,jj,jk) * va(ji,jj,jk)
292                        zue3n = e3u_n(ji,jj,jk) * un(ji,jj,jk)
293                        zve3n = e3v_n(ji,jj,jk) * vn(ji,jj,jk)
294                        zue3b = e3u_b(ji,jj,jk) * ub(ji,jj,jk)
295                        zve3b = e3v_b(ji,jj,jk) * vb(ji,jj,jk)
[2528]296                        !
[3294]297                        zuf = ( zue3n + atfp * ( zue3b - 2._wp * zue3n  + zue3a ) ) / ze3u_f(ji,jj,jk)
298                        zvf = ( zve3n + atfp * ( zve3b - 2._wp * zve3n  + zve3a ) ) / ze3v_f(ji,jj,jk)
[2528]299                        !
[3294]300                        ub(ji,jj,jk) = zuf                     ! ub <-- filtered velocity
[2528]301                        vb(ji,jj,jk) = zvf
[3294]302                        un(ji,jj,jk) = ua(ji,jj,jk)            ! un <-- ua
[2528]303                        vn(ji,jj,jk) = va(ji,jj,jk)
304                     END DO
305                  END DO
306               END DO
[15422]307               ! limit velocities 
308               IF (ln_ulimit) THEN 
309                  call dyn_limit_velocity (kt) 
310               ENDIF
[7753]311               e3u_b(:,:,1:jpkm1) = ze3u_f(:,:,1:jpkm1)        ! e3u_b <-- filtered scale factor
312               e3v_b(:,:,1:jpkm1) = ze3v_f(:,:,1:jpkm1)
[6140]313               !
[9019]314               DEALLOCATE( ze3u_f , ze3v_f )
[2528]315            ENDIF
316            !
[3]317         ENDIF
[2528]318         !
[6140]319         IF( ln_dynspg_ts .AND. ln_bt_fw ) THEN
[4312]320            ! Revert "before" velocities to time split estimate
321            ! Doing it here also means that asselin filter contribution is removed 
[7753]322            zue(:,:) = e3u_b(:,:,1) * ub(:,:,1) * umask(:,:,1)
323            zve(:,:) = e3v_b(:,:,1) * vb(:,:,1) * vmask(:,:,1)   
[4990]324            DO jk = 2, jpkm1
[7753]325               zue(:,:) = zue(:,:) + e3u_b(:,:,jk) * ub(:,:,jk) * umask(:,:,jk)
326               zve(:,:) = zve(:,:) + e3v_b(:,:,jk) * vb(:,:,jk) * vmask(:,:,jk)   
[4370]327            END DO
328            DO jk = 1, jpkm1
[7753]329               ub(:,:,jk) = ub(:,:,jk) - (zue(:,:) * r1_hu_n(:,:) - un_b(:,:)) * umask(:,:,jk)
330               vb(:,:,jk) = vb(:,:,jk) - (zve(:,:) * r1_hv_n(:,:) - vn_b(:,:)) * vmask(:,:,jk)
[4292]331            END DO
332         ENDIF
333         !
334      ENDIF ! neuler =/0
[4354]335      !
336      ! Set "now" and "before" barotropic velocities for next time step:
337      ! JC: Would be more clever to swap variables than to make a full vertical
338      ! integration
339      !
[4370]340      !
[6140]341      IF(.NOT.ln_linssh ) THEN
[7753]342         hu_b(:,:) = e3u_b(:,:,1) * umask(:,:,1)
343         hv_b(:,:) = e3v_b(:,:,1) * vmask(:,:,1)
[6140]344         DO jk = 2, jpkm1
[7753]345            hu_b(:,:) = hu_b(:,:) + e3u_b(:,:,jk) * umask(:,:,jk)
346            hv_b(:,:) = hv_b(:,:) + e3v_b(:,:,jk) * vmask(:,:,jk)
[4354]347         END DO
[7753]348         r1_hu_b(:,:) = ssumask(:,:) / ( hu_b(:,:) + 1._wp - ssumask(:,:) )
349         r1_hv_b(:,:) = ssvmask(:,:) / ( hv_b(:,:) + 1._wp - ssvmask(:,:) )
[4354]350      ENDIF
351      !
[7753]352      un_b(:,:) = e3u_a(:,:,1) * un(:,:,1) * umask(:,:,1)
353      ub_b(:,:) = e3u_b(:,:,1) * ub(:,:,1) * umask(:,:,1)
354      vn_b(:,:) = e3v_a(:,:,1) * vn(:,:,1) * vmask(:,:,1)
355      vb_b(:,:) = e3v_b(:,:,1) * vb(:,:,1) * vmask(:,:,1)
[6140]356      DO jk = 2, jpkm1
[7753]357         un_b(:,:) = un_b(:,:) + e3u_a(:,:,jk) * un(:,:,jk) * umask(:,:,jk)
358         ub_b(:,:) = ub_b(:,:) + e3u_b(:,:,jk) * ub(:,:,jk) * umask(:,:,jk)
359         vn_b(:,:) = vn_b(:,:) + e3v_a(:,:,jk) * vn(:,:,jk) * vmask(:,:,jk)
360         vb_b(:,:) = vb_b(:,:) + e3v_b(:,:,jk) * vb(:,:,jk) * vmask(:,:,jk)
[4354]361      END DO
[7753]362      un_b(:,:) = un_b(:,:) * r1_hu_a(:,:)
363      vn_b(:,:) = vn_b(:,:) * r1_hv_a(:,:)
364      ub_b(:,:) = ub_b(:,:) * r1_hu_b(:,:)
365      vb_b(:,:) = vb_b(:,:) * r1_hv_b(:,:)
[4354]366      !
[6140]367      IF( .NOT.ln_dynspg_ts ) THEN        ! output the barotropic currents
368         CALL iom_put(  "ubar", un_b(:,:) )
369         CALL iom_put(  "vbar", vn_b(:,:) )
370      ENDIF
[4990]371      IF( l_trddyn ) THEN                ! 3D output: asselin filter trends on momentum
[7753]372         zua(:,:,:) = ( ub(:,:,:) - zua(:,:,:) ) * z1_2dt
373         zva(:,:,:) = ( vb(:,:,:) - zva(:,:,:) ) * z1_2dt
[4990]374         CALL trd_dyn( zua, zva, jpdyn_atf, kt )
375      ENDIF
376      !
[13284]377      IF ( iom_use("utau") ) THEN
378         IF ( ln_drgice_imp.OR.ln_isfcav ) THEN
379            ALLOCATE(zutau(jpi,jpj)) 
380            DO jj = 2, jpjm1
381               DO ji = 2, jpim1
382                  jk = miku(ji,jj) 
383                  zutau(ji,jj) = utau(ji,jj) & 
384                  &  + 0.5_wp * rau0 * (rCdU_top(ji+1,jj)+rCdU_top(ji,jj)) * ua(ji,jj,jk) 
385               END DO
386            END DO
387            CALL lbc_lnk( 'dynnxt' , zutau, 'U', -1.)
388            CALL iom_put(  "utau", zutau(:,:) )
389            DEALLOCATE(zutau)
390         ELSE
391            CALL iom_put(  "utau", utau(:,:) )
392         ENDIF
393      ENDIF
394      !
395      IF ( iom_use("vtau") ) THEN
396         IF ( ln_drgice_imp.OR.ln_isfcav ) THEN
397            ALLOCATE(zvtau(jpi,jpj))
398            DO jj = 2, jpjm1
399               DO ji = 2, jpim1
400                  jk = mikv(ji,jj)
401                  zvtau(ji,jj) = vtau(ji,jj) &
402                  &  + 0.5_wp * rau0 * (rCdU_top(ji,jj+1)+rCdU_top(ji,jj)) * va(ji,jj,jk)
403               END DO
404            END DO
405            CALL lbc_lnk( 'dynnxt' , zvtau, 'V', -1.)
406            CALL iom_put(  "vtau", zvtau(:,:) )
407            DEALLOCATE(zvtau)
408         ELSE
409            CALL iom_put(  "vtau", vtau(:,:) )
410         ENDIF
411      ENDIF
412      !
[1438]413      IF(ln_ctl)   CALL prt_ctl( tab3d_1=un, clinfo1=' nxt  - Un: ', mask1=umask,   &
414         &                       tab3d_2=vn, clinfo2=' Vn: '       , mask2=vmask )
[6140]415      !
[9019]416      IF( ln_dynspg_ts )   DEALLOCATE( zue, zve )
417      IF( l_trddyn     )   DEALLOCATE( zua, zva )
418      IF( ln_timing    )   CALL timing_stop('dyn_nxt')
[2715]419      !
[3]420   END SUBROUTINE dyn_nxt
421
[15422]422   SUBROUTINE dyn_limit_velocity (kt) 
423      ! limits maximum values of un and vn by volume courant number 
424      INTEGER, INTENT( in ) ::   kt      ! ocean time-step index 
425     
426      INTEGER  ::   ji, jj, jk   ! dummy loop indices 
427      REAL(wp) ::   zzu,zplim,zmlim,isp,ism,zcn,ze3e1,zzcn,zcnn,idivp,idivm 
428   
429      ! limit fluxes 
430      zcn =cn_ulimit !0.9 ! maximum velocity inverse courant number 
431      zcnn = cnn_ulimit !0.54 ! how much to reduce cn by in divergen flow 
432   
433      DO jk = 1, jpkm1 
434         DO jj = 2, jpjm1 
435            DO ji = fs_2, fs_jpim1   ! vect. opt.
436               ! U direction 
437               zzu = un(ji,jj,jk) 
438               ze3e1 = e3u_n(ji  ,jj,jk) * e2u(ji  ,jj) 
439               ! ips is 1 if flow is positive othersize zero 
440               isp =  0.5 * (sign(1.0_wp,zzu) + 1.0_wp ) 
441               ism = -0.5 * (sign(1.0_wp,zzu) - 1.0_wp ) 
442               ! idev is 1 if divergent flow otherwise zero 
443               idivp = -isp * 0.5 * (sign(1.0_wp, un(ji-1,jj,jk)) - 1.0_wp ) 
444               idivm =  ism * 0.5 * (sign(1.0_wp, un(ji+1,jj,jk)) + 1.0_wp ) 
445               zzcn = (idivp+idivm)*(zcnn-1.0_wp)+1.0_wp 
446               zzcn = zzcn * zcn 
447               zplim =  zzcn * (e3t_n(ji  ,jj,jk) * e1t(ji  ,jj) * e2t(ji  ,jj)) / & 
448                                               (2.0*rdt * ze3e1)*umask(ji,jj,jk) 
449               zmlim = -zzcn * (e3t_n(ji+1,jj,jk) * e1t(ji+1,jj) * e2t(ji+1,jj)) / & 
450                                               (2.0*rdt * ze3e1)*umask(ji,jj,jk) 
451               ! limit currents 
452               un(ji,jj,jk) = min ( zzu,zplim) * isp + max(zzu,zmlim) *ism 
453   
454               ! V  direction 
455               zzu = vn(ji,jj,jk) 
456               ze3e1 = e3v_n(ji  ,jj,jk) * e1v(ji  ,jj) 
457               isp =  0.5 * (sign(1.0_wp,zzu) + 1.0_wp ) 
458               ism = -0.5 * (sign(1.0_wp,zzu) - 1.0_wp ) 
459               ! idev is 1 if divergent flow otherwise zero 
460               idivp = -isp * 0.5 * (sign(1.0_wp, vn(ji,jj-1,jk)) - 1.0_wp ) 
461               idivm =  ism * 0.5 * (sign(1.0_wp, vn(ji,jj+1,jk)) + 1.0_wp ) 
462               zzcn = (idivp+idivm)*(zcnn-1.0_wp)+1.0_wp 
463               zzcn = zzcn * zcn 
464               zplim =  zzcn * (e3t_n(ji,jj  ,jk) * e1t(ji,jj  ) * e2t(ji,jj  )) / & 
465                                               (2.0*rdt * ze3e1)*vmask(ji,jj,jk) 
466               zmlim = -zzcn * (e3t_n(ji,jj+1,jk) * e1t(ji,jj+1) * e2t(ji,jj+1)) / & 
467                                               (2.0*rdt * ze3e1)*vmask(ji,jj,jk) 
468               ! limit currents 
469               vn(ji,jj,jk) = min ( zzu,zplim) * isp + max(zzu,zmlim) *ism 
470            ENDDO 
471         ENDDO 
472      ENDDO 
473       CALL lbc_lnk_multi( 'dynnxt', un(:,:,:), 'U',  -1., vn(:,:,:), 'V',  -1. ) 
474   
475    END SUBROUTINE dyn_limit_velocity
476
[1502]477   !!=========================================================================
[3]478END MODULE dynnxt
Note: See TracBrowser for help on using the repository browser.