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.
sshwzv.F90 in branches/2013/dev_MERGE_2013/NEMOGCM/NEMO/OPA_SRC/DYN – NEMO

source: branches/2013/dev_MERGE_2013/NEMOGCM/NEMO/OPA_SRC/DYN/sshwzv.F90 @ 4328

Last change on this file since 4328 was 4328, checked in by davestorkey, 10 years ago

Remove OBC module at NEMO 3.6. See ticket #1189.

  • Property svn:keywords set to Id
File size: 14.1 KB
RevLine 
[1565]1MODULE sshwzv   
[3]2   !!==============================================================================
[1438]3   !!                       ***  MODULE  sshwzv  ***
4   !! Ocean dynamics : sea surface height and vertical velocity
[3]5   !!==============================================================================
[1438]6   !! History :  3.1  !  2009-02  (G. Madec, M. Leclair)  Original code
[2528]7   !!            3.3  !  2010-04  (M. Leclair, G. Madec)  modified LF-RA
8   !!             -   !  2010-05  (K. Mogensen, A. Weaver, M. Martin, D. Lea) Assimilation interface
9   !!             -   !  2010-09  (D.Storkey and E.O'Dea) bug fixes for BDY module
[4292]10   !!            3.3  !  2011-10  (M. Leclair) split former ssh_wzv routine and remove all vvl related work
[3]11   !!----------------------------------------------------------------------
[1438]12
[3]13   !!----------------------------------------------------------------------
[4292]14   !!   ssh_nxt        : after ssh
15   !!   ssh_swp        : filter ans swap the ssh arrays
16   !!   wzv            : compute now vertical velocity
[1438]17   !!----------------------------------------------------------------------
[3]18   USE oce             ! ocean dynamics and tracers variables
19   USE dom_oce         ! ocean space and time domain variables
[888]20   USE sbc_oce         ! surface boundary condition: ocean
21   USE domvvl          ! Variable volume
[1565]22   USE divcur          ! hor. divergence and curl      (div & cur routines)
[1438]23   USE iom             ! I/O library
[4292]24   USE restart         ! only for lrst_oce
[3]25   USE in_out_manager  ! I/O manager
[258]26   USE prtctl          ! Print control
[592]27   USE phycst
28   USE lbclnk          ! ocean lateral boundary condition (or mpp link)
[2715]29   USE lib_mpp         ! MPP library
[2528]30   USE bdy_oce
[4292]31   USE bdy_par         
32   USE bdydyn2d        ! bdy_ssh routine
[2715]33   USE diaar5, ONLY:   lk_diaar5
[1482]34   USE iom
[4292]35   USE sbcrnf, ONLY: h_rnf, nk_rnf, sbc_rnf_div   ! River runoff
36   USE dynspg_ts,   ONLY: ln_bt_fw
37   USE dynspg_oce, ONLY: lk_dynspg_ts
[2528]38#if defined key_agrif
39   USE agrif_opa_update
[2486]40   USE agrif_opa_interp
[2528]41#endif
42#if defined key_asminc   
43   USE asminc          ! Assimilation increment
44#endif
[3294]45   USE wrk_nemo        ! Memory Allocation
46   USE timing          ! Timing
[592]47
[3]48   IMPLICIT NONE
49   PRIVATE
50
[1438]51   PUBLIC   ssh_nxt    ! called by step.F90
[4292]52   PUBLIC   wzv        ! called by step.F90
53   PUBLIC   ssh_swp    ! called by step.F90
[3]54
55   !! * Substitutions
56#  include "domzgr_substitute.h90"
[1438]57#  include "vectopt_loop_substitute.h90"
[3]58   !!----------------------------------------------------------------------
[2528]59   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
[888]60   !! $Id$
[2715]61   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
[592]62   !!----------------------------------------------------------------------
[3]63CONTAINS
64
[4292]65   SUBROUTINE ssh_nxt( kt )
[3]66      !!----------------------------------------------------------------------
[4292]67      !!                ***  ROUTINE ssh_nxt  ***
[1438]68      !!                   
[4292]69      !! ** Purpose :   compute the after ssh (ssha)
[3]70      !!
[4292]71      !! ** Method  : - Using the incompressibility hypothesis, the ssh increment
72      !!      is computed by integrating the horizontal divergence and multiply by
73      !!      by the time step.
[3]74      !!
[1438]75      !! ** action  :   ssha    : after sea surface height
[2528]76      !!
77      !! Reference  : Leclair, M., and G. Madec, 2009, Ocean Modelling.
[3]78      !!----------------------------------------------------------------------
[2715]79      !
[4292]80      REAL(wp), POINTER, DIMENSION(:,:  ) ::  zhdiv
81      INTEGER, INTENT(in) ::   kt                      ! time step
82      !
83      INTEGER             ::   jk                      ! dummy loop indice
84      REAL(wp)            ::   z2dt, z1_rau0           ! local scalars
[3]85      !!----------------------------------------------------------------------
[3294]86      !
[4292]87      IF( nn_timing == 1 )  CALL timing_start('ssh_nxt')
[3294]88      !
[4292]89      CALL wrk_alloc( jpi, jpj, zhdiv ) 
[3294]90      !
[3]91      IF( kt == nit000 ) THEN
[2528]92         !
[3]93         IF(lwp) WRITE(numout,*)
[4292]94         IF(lwp) WRITE(numout,*) 'ssh_nxt : after sea surface height'
[1438]95         IF(lwp) WRITE(numout,*) '~~~~~~~ '
96         !
[3]97      ENDIF
[2528]98      !
99      CALL div_cur( kt )                              ! Horizontal divergence & Relative vorticity
100      !
[2715]101      z2dt = 2._wp * rdt                              ! set time step size (Euler/Leapfrog)
102      IF( neuler == 0 .AND. kt == nit000 )   z2dt = rdt
[3]103
[1438]104      !                                           !------------------------------!
105      !                                           !   After Sea Surface Height   !
106      !                                           !------------------------------!
[2715]107      zhdiv(:,:) = 0._wp
[1438]108      DO jk = 1, jpkm1                                 ! Horizontal divergence of barotropic transports
[4292]109        zhdiv(:,:) = zhdiv(:,:) + fse3t_n(:,:,jk) * hdivn(:,:,jk)
[1438]110      END DO
111      !                                                ! Sea surface elevation time stepping
[2528]112      ! In forward Euler time stepping case, the same formulation as in the leap-frog case can be used
113      ! because emp_b field is initialized with the vlaues of emp field. Hence, 0.5 * ( emp + emp_b ) = emp
[4292]114      z1_rau0 = 0.5_wp * r1_rau0
[2715]115      ssha(:,:) = (  sshb(:,:) - z2dt * ( z1_rau0 * ( emp_b(:,:) + emp(:,:) ) + zhdiv(:,:) )  ) * tmask(:,:,1)
[1438]116
[2486]117#if defined key_agrif
[2715]118      CALL agrif_ssh( kt )
[2486]119#endif
[2528]120#if defined key_bdy
[4292]121      ! bg jchanut tschanges
122      ! These lines are not necessary with time splitting since
123      ! boundary condition on sea level is set during ts loop
124      IF (lk_bdy) THEN
125         CALL lbc_lnk( ssha, 'T', 1. ) ! Not sure that's necessary
126         CALL bdy_ssh( ssha ) ! Duplicate sea level across open boundaries
127      ENDIF
[2528]128#endif
[4292]129      ! end jchanut tschanges
[3764]130#if defined key_asminc
131      !                                                ! Include the IAU weighted SSH increment
132      IF( lk_asminc .AND. ln_sshinc .AND. ln_asmiau ) THEN
133         CALL ssh_asm_inc( kt )
134         ssha(:,:) = ssha(:,:) + z2dt * ssh_iau(:,:)
135      ENDIF
136#endif
[4292]137
138      !                                           !------------------------------!
139      !                                           !           outputs            !
140      !                                           !------------------------------!
141      CALL iom_put( "ssh" , sshn                  )   ! sea surface height
142      CALL iom_put( "ssh2", sshn(:,:) * sshn(:,:) )   ! square of sea surface height
143      !
144      IF(ln_ctl)   CALL prt_ctl( tab2d_1=ssha, clinfo1=' ssha  - : ', mask1=tmask, ovlap=1 )
145      !
146      CALL wrk_dealloc( jpi, jpj, zhdiv ) 
147      !
148      IF( nn_timing == 1 )  CALL timing_stop('ssh_nxt')
149      !
150   END SUBROUTINE ssh_nxt
151
152   
153   SUBROUTINE wzv( kt )
154      !!----------------------------------------------------------------------
155      !!                ***  ROUTINE wzv  ***
156      !!                   
157      !! ** Purpose :   compute the now vertical velocity
158      !!
159      !! ** Method  : - Using the incompressibility hypothesis, the vertical
160      !!      velocity is computed by integrating the horizontal divergence 
161      !!      from the bottom to the surface minus the scale factor evolution.
162      !!        The boundary conditions are w=0 at the bottom (no flux) and.
163      !!
164      !! ** action  :   wn      : now vertical velocity
165      !!
166      !! Reference  : Leclair, M., and G. Madec, 2009, Ocean Modelling.
167      !!----------------------------------------------------------------------
168      !
169      INTEGER, INTENT(in) ::   kt           ! time step
170      REAL(wp), POINTER, DIMENSION(:,:  ) ::  z2d
171      REAL(wp), POINTER, DIMENSION(:,:,:) ::  z3d, zhdiv
172      !
173      INTEGER             ::   ji, jj, jk   ! dummy loop indices
174      REAL(wp)            ::   z1_2dt       ! local scalars
175      !!----------------------------------------------------------------------
176     
177      IF( nn_timing == 1 )  CALL timing_start('wzv')
178      !
179      IF( kt == nit000 ) THEN
180         !
181         IF(lwp) WRITE(numout,*)
182         IF(lwp) WRITE(numout,*) 'wzv : now vertical velocity '
183         IF(lwp) WRITE(numout,*) '~~~~~ '
184         !
185         wn(:,:,jpk) = 0._wp                  ! bottom boundary condition: w=0 (set once for all)
186         !
187      ENDIF
188      !                                           !------------------------------!
189      !                                           !     Now Vertical Velocity    !
190      !                                           !------------------------------!
191      z1_2dt = 1. / ( 2. * rdt )                         ! set time step size (Euler/Leapfrog)
192      IF( neuler == 0 .AND. kt == nit000 )   z1_2dt = 1. / rdt
193      !
194      IF( ln_vvl_ztilde .OR. ln_vvl_layer ) THEN      ! z_tilde and layer cases
195         CALL wrk_alloc( jpi, jpj, jpk, zhdiv ) 
196         !
197         DO jk = 1, jpkm1
198            ! horizontal divergence of thickness diffusion transport ( velocity multiplied by e3t)
199            ! - ML - note: computation allready done in dom_vvl_sf_nxt. Could be optimized (not critical and clearer this way)
200            DO jj = 2, jpjm1
201               DO ji = fs_2, fs_jpim1   ! vector opt.
202                  zhdiv(ji,jj,jk) = r1_e12t(ji,jj) * ( un_td(ji,jj,jk) - un_td(ji-1,jj,jk) + vn_td(ji,jj,jk) - vn_td(ji,jj-1,jk) )
203               END DO
[592]204            END DO
205         END DO
[4292]206         CALL lbc_lnk(zhdiv, 'T', 1.)  ! - ML - Perhaps not necessary: not used for horizontal "connexions"
207         !                             ! Is it problematic to have a wrong vertical velocity in boundary cells?
208         !                             ! Same question holds for hdivn. Perhaps just for security
209         DO jk = jpkm1, 1, -1                       ! integrate from the bottom the hor. divergence
210            ! computation of w
211            wn(:,:,jk) = wn(:,:,jk+1) - (   fse3t_n(:,:,jk) * hdivn(:,:,jk) + zhdiv(:,:,jk)                    &
212               &                          + z1_2dt * ( fse3t_a(:,:,jk) - fse3t_b(:,:,jk) ) ) * tmask(:,:,jk)
213         END DO
214         !          IF( ln_vvl_layer ) wn(:,:,:) = 0.e0
215         CALL wrk_dealloc( jpi, jpj, jpk, zhdiv ) 
216      ELSE   ! z_star and linear free surface cases
217         DO jk = jpkm1, 1, -1                       ! integrate from the bottom the hor. divergence
218            ! computation of w
219            wn(:,:,jk) = wn(:,:,jk+1) - (   fse3t_n(:,:,jk) * hdivn(:,:,jk)                                   &
220               &                          + z1_2dt * ( fse3t_a(:,:,jk) - fse3t_b(:,:,jk) ) ) * tmask(:,:,jk)
221         END DO
[1438]222      ENDIF
[592]223
[2528]224#if defined key_bdy
[4327]225      IF (lk_bdy) THEN
226         DO jk = 1, jpkm1
227            wn(:,:,jk) = wn(:,:,jk) * bdytmask(:,:)
228         END DO
229      ENDIF
[2528]230#endif
[4292]231      !
[2528]232      !                                           !------------------------------!
233      !                                           !           outputs            !
234      !                                           !------------------------------!
[4292]235      CALL iom_put( "woce", wn )   ! vertical velocity
[2528]236      IF( lk_diaar5 ) THEN                            ! vertical mass transport & its square value
[4292]237         CALL wrk_alloc( jpi, jpj, z2d ) 
238         CALL wrk_alloc( jpi, jpj, jpk, z3d ) 
[2528]239         ! Caution: in the VVL case, it only correponds to the baroclinic mass transport.
[4292]240         z2d(:,:) = rau0 * e12t(:,:)
[1756]241         DO jk = 1, jpk
242            z3d(:,:,jk) = wn(:,:,jk) * z2d(:,:)
243         END DO
[2528]244         CALL iom_put( "w_masstr" , z3d                     ) 
245         CALL iom_put( "w_masstr2", z3d(:,:,:) * z3d(:,:,:) )
[4292]246         CALL wrk_dealloc( jpi, jpj, z2d  ) 
247         CALL wrk_dealloc( jpi, jpj, jpk, z3d ) 
[1756]248      ENDIF
[1438]249      !
[4292]250      IF( nn_timing == 1 )  CALL timing_stop('wzv')
[592]251
252
[4292]253   END SUBROUTINE wzv
254
255   SUBROUTINE ssh_swp( kt )
[1438]256      !!----------------------------------------------------------------------
257      !!                    ***  ROUTINE ssh_nxt  ***
258      !!
259      !! ** Purpose :   achieve the sea surface  height time stepping by
260      !!              applying Asselin time filter and swapping the arrays
[4292]261      !!              ssha  already computed in ssh_nxt 
[1438]262      !!
[2528]263      !! ** Method  : - apply Asselin time fiter to now ssh (excluding the forcing
264      !!              from the filter, see Leclair and Madec 2010) and swap :
265      !!                sshn = ssha + atfp * ( sshb -2 sshn + ssha )
266      !!                            - atfp * rdt * ( emp_b - emp ) / rau0
267      !!                sshn = ssha
[1438]268      !!
269      !! ** action  : - sshb, sshn   : before & now sea surface height
270      !!                               ready for the next time step
[2528]271      !!
272      !! Reference  : Leclair, M., and G. Madec, 2009, Ocean Modelling.
[1438]273      !!----------------------------------------------------------------------
[2528]274      INTEGER, INTENT(in) ::   kt   ! ocean time-step index
[1438]275      !!----------------------------------------------------------------------
[3294]276      !
[4292]277      IF( nn_timing == 1 )  CALL timing_start('ssh_swp')
[3294]278      !
[1438]279      IF( kt == nit000 ) THEN
280         IF(lwp) WRITE(numout,*)
[4292]281         IF(lwp) WRITE(numout,*) 'ssh_swp : Asselin time filter and swap of sea surface height'
[1438]282         IF(lwp) WRITE(numout,*) '~~~~~~~ '
283      ENDIF
[592]284
[4292]285# if defined key_dynspg_ts
286      IF( ( neuler == 0 .AND. kt == nit000 ) .OR. ln_bt_fw ) THEN    !** Euler time-stepping: no filter
287# else
288      IF ( neuler == 0 .AND. kt == nit000 ) THEN   !** Euler time-stepping at first time-step : no filter
289#endif
290         sshb(:,:) = sshn(:,:)                           ! before <-- now
291         sshn(:,:) = ssha(:,:)                           ! now    <-- after  (before already = now)
292      ELSE                                         !** Leap-Frog time-stepping: Asselin filter + swap
293         sshb(:,:) = sshn(:,:) + atfp * ( sshb(:,:) - 2 * sshn(:,:) + ssha(:,:) )     ! before <-- now filtered
294         IF( lk_vvl ) sshb(:,:) = sshb(:,:) - atfp * rdt / rau0 * ( emp_b(:,:) - emp(:,:) ) * tmask(:,:,1)
295         sshn(:,:) = ssha(:,:)                           ! now <-- after
[1438]296      ENDIF
297      !
[2528]298      ! Update velocity at AGRIF zoom boundaries
[2486]299#if defined key_agrif
[2528]300      IF ( .NOT.Agrif_Root() ) CALL Agrif_Update_Dyn( kt )
[2486]301#endif
[1438]302      !
[2528]303      IF(ln_ctl)   CALL prt_ctl( tab2d_1=sshb, clinfo1=' sshb  - : ', mask1=tmask, ovlap=1 )
304      !
[4292]305      IF( nn_timing == 1 )  CALL timing_stop('ssh_swp')
[3294]306      !
[4292]307   END SUBROUTINE ssh_swp
[3]308
309   !!======================================================================
[1565]310END MODULE sshwzv
Note: See TracBrowser for help on using the repository browser.