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.
dynadv_ubs.F90 in NEMO/branches/2021/dev_r14393_HPC-03_Mele_Comm_Cleanup/src/OCE/DYN – NEMO

source: NEMO/branches/2021/dev_r14393_HPC-03_Mele_Comm_Cleanup/src/OCE/DYN/dynadv_ubs.F90 @ 14757

Last change on this file since 14757 was 14757, checked in by francesca, 3 years ago

Fortran 77 '.EQ.' operator replacement in conditional statements; [comm_cleanup] tags removal - ticket #2607

  • Property svn:keywords set to Id
File size: 15.0 KB
Line 
1MODULE dynadv_ubs
2   !!======================================================================
3   !!                       ***  MODULE  dynadv_ubs  ***
4   !! Ocean dynamics: Update the momentum trend with the flux form advection
5   !!                 trend using a 3rd order upstream biased scheme
6   !!======================================================================
7   !! History :  2.0  ! 2006-08  (R. Benshila, L. Debreu)  Original code
8   !!            3.2  ! 2009-07  (R. Benshila)  Suppression of rigid-lid option
9   !!----------------------------------------------------------------------
10
11   !!----------------------------------------------------------------------
12   !!   dyn_adv_ubs   : flux form momentum advection using    (ln_dynadv=T)
13   !!                   an 3rd order Upstream Biased Scheme or Quick scheme
14   !!                   combined with 2nd or 4th order finite differences
15   !!----------------------------------------------------------------------
16   USE oce            ! ocean dynamics and tracers
17   USE dom_oce        ! ocean space and time domain
18   USE trd_oce        ! trends: ocean variables
19   USE trddyn         ! trend manager: dynamics
20   !
21   USE in_out_manager ! I/O manager
22   USE prtctl         ! Print control
23   USE lbclnk         ! ocean lateral boundary conditions (or mpp link)
24   USE lib_mpp        ! MPP library
25
26   IMPLICIT NONE
27   PRIVATE
28
29   REAL(wp), PARAMETER :: gamma1 = 1._wp/3._wp  ! =1/4 quick      ; =1/3  3rd order UBS
30   REAL(wp), PARAMETER :: gamma2 = 1._wp/32._wp ! =0   2nd order  ; =1/32 4th order centred
31
32   PUBLIC   dyn_adv_ubs   ! routine called by step.F90
33
34   !! * Substitutions
35#  include "do_loop_substitute.h90"
36#  include "domzgr_substitute.h90"
37   !!----------------------------------------------------------------------
38   !! NEMO/OCE 4.0 , NEMO Consortium (2018)
39   !! $Id$
40   !! Software governed by the CeCILL license (see ./LICENSE)
41   !!----------------------------------------------------------------------
42CONTAINS
43
44   SUBROUTINE dyn_adv_ubs( kt, Kbb, Kmm, puu, pvv, Krhs )
45      !!----------------------------------------------------------------------
46      !!                  ***  ROUTINE dyn_adv_ubs  ***
47      !!
48      !! ** Purpose :   Compute the now momentum advection trend in flux form
49      !!              and the general trend of the momentum equation.
50      !!
51      !! ** Method  :   The scheme is the one implemeted in ROMS. It depends
52      !!      on two parameter gamma1 and gamma2. The former control the
53      !!      upstream baised part of the scheme and the later the centred
54      !!      part:     gamma1 = 0    pure centered  (no diffusive part)
55      !!                       = 1/4  Quick scheme
56      !!                       = 1/3  3rd order Upstream biased scheme
57      !!                gamma2 = 0    2nd order finite differencing
58      !!                       = 1/32 4th order finite differencing
59      !!      For stability reasons, the first term of the fluxes which cor-
60      !!      responds to a second order centered scheme is evaluated using 
61      !!      the now velocity (centered in time) while the second term which 
62      !!      is the diffusive part of the scheme, is evaluated using the
63      !!      before velocity (forward in time).
64      !!      Default value (hard coded in the begining of the module) are
65      !!      gamma1=1/3 and gamma2=1/32.
66      !!
67      !! ** Action : - (puu(:,:,:,Krhs),pvv(:,:,:,Krhs)) updated with the 3D advective momentum trends
68      !!
69      !! Reference : Shchepetkin & McWilliams, 2005, Ocean Modelling.
70      !!----------------------------------------------------------------------
71      INTEGER                             , INTENT( in )  ::  kt              ! ocean time-step index
72      INTEGER                             , INTENT( in )  ::  Kbb, Kmm, Krhs  ! ocean time level indices
73      REAL(wp), DIMENSION(jpi,jpj,jpk,jpt), INTENT(inout) ::  puu, pvv        ! ocean velocities and RHS of momentum equation
74      !
75      INTEGER  ::   ji, jj, jk   ! dummy loop indices
76      REAL(wp) ::   zui, zvj, zfuj, zfvi, zl_u, zl_v   ! local scalars
77      REAL(wp), DIMENSION(jpi,jpj,jpk)   ::   zfu_t, zfu_f, zfu_uw, zfu
78      REAL(wp), DIMENSION(jpi,jpj,jpk)   ::   zfv_t, zfv_f, zfv_vw, zfv, zfw
79      REAL(wp), DIMENSION(jpi,jpj,jpk,2) ::   zlu_uu, zlu_uv
80      REAL(wp), DIMENSION(jpi,jpj,jpk,2) ::   zlv_vv, zlv_vu
81      !!----------------------------------------------------------------------
82      !
83      IF( kt == nit000 ) THEN
84         IF(lwp) WRITE(numout,*)
85         IF(lwp) WRITE(numout,*) 'dyn_adv_ubs : UBS flux form momentum advection'
86         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~'
87      ENDIF
88      !
89      zfu_t(:,:,:) = 0._wp
90      zfv_t(:,:,:) = 0._wp
91      zfu_f(:,:,:) = 0._wp
92      zfv_f(:,:,:) = 0._wp
93      !
94      zlu_uu(:,:,:,:) = 0._wp
95      zlv_vv(:,:,:,:) = 0._wp 
96      zlu_uv(:,:,:,:) = 0._wp 
97      zlv_vu(:,:,:,:) = 0._wp 
98      !
99      IF( l_trddyn ) THEN           ! trends: store the input trends
100         zfu_uw(:,:,:) = puu(:,:,:,Krhs)
101         zfv_vw(:,:,:) = pvv(:,:,:,Krhs)
102      ENDIF
103      !                                      ! =========================== !
104      DO jk = 1, jpkm1                       !  Laplacian of the velocity  !
105         !                                   ! =========================== !
106         !                                         ! horizontal volume fluxes
107         zfu(:,:,jk) = e2u(:,:) * e3u(:,:,jk,Kmm) * puu(:,:,jk,Kmm)
108         zfv(:,:,jk) = e1v(:,:) * e3v(:,:,jk,Kmm) * pvv(:,:,jk,Kmm)
109         !           
110         DO_2D( nn_hls-1, nn_hls-1, nn_hls-1, nn_hls-1 )                       ! laplacia
111            ! round brackets added to fix the order of floating point operations
112            ! needed to ensure halo 1 - halo 2 compatibility
113            zlu_uu(ji,jj,jk,1) = ( ( puu (ji+1,jj  ,jk,Kbb) - puu (ji  ,jj  ,jk,Kbb) &
114               &                   )                                                 & ! bracket for halo 1 - halo 2 compatibility
115               &                 + ( puu (ji-1,jj  ,jk,Kbb) - puu (ji  ,jj  ,jk,Kbb) &
116               &                   )                                                 & ! bracket for halo 1 - halo 2 compatibility
117               &                 ) * umask(ji  ,jj  ,jk)
118            zlv_vv(ji,jj,jk,1) = ( ( pvv (ji  ,jj+1,jk,Kbb) - pvv (ji  ,jj  ,jk,Kbb) & 
119               &                   )                                                 & ! bracket for halo 1 - halo 2 compatibility
120               &                 + ( pvv (ji  ,jj-1,jk,Kbb) - pvv (ji  ,jj  ,jk,Kbb) &
121               &                   )                                                 & ! bracket for halo 1 - halo 2 compatibility
122               &                 ) * vmask(ji  ,jj  ,jk)
123            zlu_uv(ji,jj,jk,1) = (  puu (ji  ,jj+1,jk,Kbb) - puu (ji  ,jj  ,jk,Kbb)  ) * fmask(ji  ,jj  ,jk)   &
124               &               - (  puu (ji  ,jj  ,jk,Kbb) - puu (ji  ,jj-1,jk,Kbb)  ) * fmask(ji  ,jj-1,jk)
125            zlv_vu(ji,jj,jk,1) = (  pvv (ji+1,jj  ,jk,Kbb) - pvv (ji  ,jj  ,jk,Kbb)  ) * fmask(ji  ,jj  ,jk)   &
126               &               - (  pvv (ji  ,jj  ,jk,Kbb) - pvv (ji-1,jj  ,jk,Kbb)  ) * fmask(ji-1,jj  ,jk)
127            !
128            ! round brackets added to fix the order of floating point operations
129            ! needed to ensure halo 1 - halo 2 compatibility
130            zlu_uu(ji,jj,jk,2) = ( ( zfu(ji+1,jj  ,jk) - zfu(ji  ,jj  ,jk)           &
131               &                   )                                                 & ! bracket for halo 1 - halo 2 compatibility
132               &                 + ( zfu(ji-1,jj  ,jk) - zfu(ji  ,jj  ,jk)           &
133               &                   )                                                 & ! bracket for halo 1 - halo 2 compatibility
134               &                 ) * umask(ji  ,jj  ,jk)
135            zlv_vv(ji,jj,jk,2) = ( ( zfv(ji  ,jj+1,jk) - zfv(ji  ,jj  ,jk)           &
136               &                   )                                                 & ! bracket for halo 1 - halo 2 compatibility
137               &                 + ( zfv(ji  ,jj-1,jk) - zfv(ji  ,jj  ,jk)           & 
138               &                   )                                                 & ! bracket for halo 1 - halo 2 compatibility
139               &                 ) * vmask(ji  ,jj  ,jk)
140            zlu_uv(ji,jj,jk,2) = (  zfu(ji  ,jj+1,jk) - zfu(ji  ,jj  ,jk)  ) * fmask(ji  ,jj  ,jk)             &
141               &               - (  zfu(ji  ,jj  ,jk) - zfu(ji  ,jj-1,jk)  ) * fmask(ji  ,jj-1,jk)
142            zlv_vu(ji,jj,jk,2) = (  zfv(ji+1,jj  ,jk) - zfv(ji  ,jj  ,jk)  ) * fmask(ji  ,jj  ,jk)             &
143               &               - (  zfv(ji  ,jj  ,jk) - zfv(ji-1,jj  ,jk)  ) * fmask(ji-1,jj  ,jk)
144         END_2D
145      END DO
146      ! NOTE: [tiling] sign reversal necessary for results to be independent of nn_hls (bug in trunk)
147      IF( nn_hls==1 ) CALL lbc_lnk( 'dynadv_ubs', zlu_uu(:,:,:,1), 'U', -1.0_wp , zlu_uv(:,:,:,1), 'U', -1.0_wp,  &
148                                              &   zlu_uu(:,:,:,2), 'U', -1.0_wp , zlu_uv(:,:,:,2), 'U', -1.0_wp,  &
149                                              &   zlv_vv(:,:,:,1), 'V', -1.0_wp , zlv_vu(:,:,:,1), 'V', -1.0_wp,  &
150                                              &   zlv_vv(:,:,:,2), 'V', -1.0_wp , zlv_vu(:,:,:,2), 'V', -1.0_wp   )
151      !
152      !                                      ! ====================== !
153      !                                      !  Horizontal advection  !
154      DO jk = 1, jpkm1                       ! ====================== !
155         !                                         ! horizontal volume fluxes
156         zfu(:,:,jk) = 0.25_wp * e2u(:,:) * e3u(:,:,jk,Kmm) * puu(:,:,jk,Kmm)
157         zfv(:,:,jk) = 0.25_wp * e1v(:,:) * e3v(:,:,jk,Kmm) * pvv(:,:,jk,Kmm)
158         !
159         DO_2D( 1, 0, 1, 0 )                       ! horizontal momentum fluxes at T- and F-point
160            zui = ( puu(ji,jj,jk,Kmm) + puu(ji+1,jj  ,jk,Kmm) )
161            zvj = ( pvv(ji,jj,jk,Kmm) + pvv(ji  ,jj+1,jk,Kmm) )
162            !
163            IF( zui > 0 ) THEN   ;   zl_u = zlu_uu(ji  ,jj,jk,1)
164            ELSE                 ;   zl_u = zlu_uu(ji+1,jj,jk,1)
165            ENDIF
166            IF( zvj > 0 ) THEN   ;   zl_v = zlv_vv(ji,jj  ,jk,1)
167            ELSE                 ;   zl_v = zlv_vv(ji,jj+1,jk,1)
168            ENDIF
169            !
170            zfu_t(ji+1,jj  ,jk) = ( zfu(ji,jj,jk) + zfu(ji+1,jj  ,jk)                               &
171               &                    - gamma2 * ( zlu_uu(ji,jj,jk,2) + zlu_uu(ji+1,jj  ,jk,2) )  )   &
172               &                * ( zui - gamma1 * zl_u)
173            zfv_t(ji  ,jj+1,jk) = ( zfv(ji,jj,jk) + zfv(ji  ,jj+1,jk)                               &
174               &                    - gamma2 * ( zlv_vv(ji,jj,jk,2) + zlv_vv(ji  ,jj+1,jk,2) )  )   &
175               &                * ( zvj - gamma1 * zl_v)
176            !
177            zfuj = ( zfu(ji,jj,jk) + zfu(ji  ,jj+1,jk) )
178            zfvi = ( zfv(ji,jj,jk) + zfv(ji+1,jj  ,jk) )
179            IF( zfuj > 0 ) THEN   ;    zl_v = zlv_vu( ji  ,jj  ,jk,1)
180            ELSE                  ;    zl_v = zlv_vu( ji+1,jj,jk,1)
181            ENDIF
182            IF( zfvi > 0 ) THEN   ;    zl_u = zlu_uv( ji,jj  ,jk,1)
183            ELSE                  ;    zl_u = zlu_uv( ji,jj+1,jk,1)
184            ENDIF
185            !
186            zfv_f(ji  ,jj  ,jk) = ( zfvi - gamma2 * ( zlv_vu(ji,jj,jk,2) + zlv_vu(ji+1,jj  ,jk,2) )  )   &
187               &                * ( puu(ji,jj,jk,Kmm) + puu(ji  ,jj+1,jk,Kmm) - gamma1 * zl_u )
188            zfu_f(ji  ,jj  ,jk) = ( zfuj - gamma2 * ( zlu_uv(ji,jj,jk,2) + zlu_uv(ji  ,jj+1,jk,2) )  )   &
189               &                * ( pvv(ji,jj,jk,Kmm) + pvv(ji+1,jj  ,jk,Kmm) - gamma1 * zl_v )
190         END_2D
191         DO_2D( 0, 0, 0, 0 )                       ! divergence of horizontal momentum fluxes
192            puu(ji,jj,jk,Krhs) = puu(ji,jj,jk,Krhs) - (  zfu_t(ji+1,jj,jk) - zfu_t(ji,jj  ,jk)    &
193               &                           + zfv_f(ji  ,jj,jk) - zfv_f(ji,jj-1,jk)  ) * r1_e1e2u(ji,jj)   &
194               &                           / e3u(ji,jj,jk,Kmm)
195            pvv(ji,jj,jk,Krhs) = pvv(ji,jj,jk,Krhs) - (  zfu_f(ji,jj  ,jk) - zfu_f(ji-1,jj,jk)    &
196               &                           + zfv_t(ji,jj+1,jk) - zfv_t(ji  ,jj,jk)  ) * r1_e1e2v(ji,jj)   &
197               &                           / e3v(ji,jj,jk,Kmm)
198         END_2D
199      END DO
200      IF( l_trddyn ) THEN                          ! trends: send trends to trddyn for diagnostic
201         zfu_uw(:,:,:) = puu(:,:,:,Krhs) - zfu_uw(:,:,:)
202         zfv_vw(:,:,:) = pvv(:,:,:,Krhs) - zfv_vw(:,:,:)
203         CALL trd_dyn( zfu_uw, zfv_vw, jpdyn_keg, kt, Kmm )
204         zfu_t(:,:,:) = puu(:,:,:,Krhs)
205         zfv_t(:,:,:) = pvv(:,:,:,Krhs)
206      ENDIF
207      !                                      ! ==================== !
208      !                                      !  Vertical advection  !
209      !                                      ! ==================== !
210      DO_2D( 0, 0, 0, 0 )                          ! surface/bottom advective fluxes set to zero
211         zfu_uw(ji,jj,jpk) = 0._wp
212         zfv_vw(ji,jj,jpk) = 0._wp
213         zfu_uw(ji,jj, 1 ) = 0._wp
214         zfv_vw(ji,jj, 1 ) = 0._wp
215      END_2D
216      IF( ln_linssh ) THEN                         ! constant volume : advection through the surface
217         DO_2D( 0, 0, 0, 0 )
218            zfu_uw(ji,jj,1) = 0.5_wp * ( e1e2t(ji,jj) * ww(ji,jj,1) + e1e2t(ji+1,jj) * ww(ji+1,jj,1) ) * puu(ji,jj,1,Kmm)
219            zfv_vw(ji,jj,1) = 0.5_wp * ( e1e2t(ji,jj) * ww(ji,jj,1) + e1e2t(ji,jj+1) * ww(ji,jj+1,1) ) * pvv(ji,jj,1,Kmm)
220         END_2D
221      ENDIF
222      DO jk = 2, jpkm1                          ! interior fluxes
223         DO_2D( 0, 1, 0, 1 )
224            zfw(ji,jj,jk) = 0.25_wp * e1e2t(ji,jj) * ww(ji,jj,jk)
225         END_2D
226         DO_2D( 0, 0, 0, 0 )
227            zfu_uw(ji,jj,jk) = ( zfw(ji,jj,jk)+ zfw(ji+1,jj,jk) ) * ( puu(ji,jj,jk,Kmm) + puu(ji,jj,jk-1,Kmm) )
228            zfv_vw(ji,jj,jk) = ( zfw(ji,jj,jk)+ zfw(ji,jj+1,jk) ) * ( pvv(ji,jj,jk,Kmm) + pvv(ji,jj,jk-1,Kmm) )
229         END_2D
230      END DO
231      DO_3D( 0, 0, 0, 0, 1, jpkm1 )             ! divergence of vertical momentum flux divergence
232         puu(ji,jj,jk,Krhs) =  puu(ji,jj,jk,Krhs) - ( zfu_uw(ji,jj,jk) - zfu_uw(ji,jj,jk+1) ) * r1_e1e2u(ji,jj)   &
233            &                                       / e3u(ji,jj,jk,Kmm)
234         pvv(ji,jj,jk,Krhs) =  pvv(ji,jj,jk,Krhs) - ( zfv_vw(ji,jj,jk) - zfv_vw(ji,jj,jk+1) ) * r1_e1e2v(ji,jj)   &
235            &                                       / e3v(ji,jj,jk,Kmm)
236      END_3D
237      !
238      IF( l_trddyn ) THEN                       ! save the vertical advection trend for diagnostic
239         zfu_t(:,:,:) = puu(:,:,:,Krhs) - zfu_t(:,:,:)
240         zfv_t(:,:,:) = pvv(:,:,:,Krhs) - zfv_t(:,:,:)
241         CALL trd_dyn( zfu_t, zfv_t, jpdyn_zad, kt, Kmm )
242      ENDIF
243      !                                         ! Control print
244      IF(sn_cfctl%l_prtctl)   CALL prt_ctl( tab3d_1=puu(:,:,:,Krhs), clinfo1=' ubs2 adv - Ua: ', mask1=umask,   &
245         &                                  tab3d_2=pvv(:,:,:,Krhs), clinfo2=           ' Va: ', mask2=vmask, clinfo3='dyn' )
246      !
247   END SUBROUTINE dyn_adv_ubs
248
249   !!==============================================================================
250END MODULE dynadv_ubs
Note: See TracBrowser for help on using the repository browser.