source: branches/2015/nemo_v3_6_STABLE/NEMOGCM/NEMO/OPA_SRC/DYN/dynldf_bilap.F90 @ 8627

Last change on this file since 8627 was 8627, checked in by gm, 3 years ago

#1963 : Correct implementation of CMIP6 KE dissipation + move EKE⇔PE diag in traadv_eiv (in both cases, no more need of ln_trd_KE=T)

  • Property svn:keywords set to Id
File size: 10.6 KB
Line 
1MODULE dynldf_bilap
2   !!======================================================================
3   !!                     ***  MODULE  dynldf_bilap  ***
4   !! Ocean dynamics:  lateral viscosity trend
5   !!======================================================================
6   !! History :  OPA  ! 1990-09  (G. Madec)  Original code
7   !!            4.0  ! 1993-03  (M. Guyon)  symetrical conditions (M. Guyon)
8   !!            6.0  ! 1996-01  (G. Madec)  statement function for e3
9   !!            8.0  ! 1997-07  (G. Madec)  lbc calls
10   !!   NEMO     1.0  ! 2002-08  (G. Madec)  F90: Free form and module
11   !!            2.0  ! 2004-08  (C. Talandier) New trends organization
12   !!----------------------------------------------------------------------
13
14   !!----------------------------------------------------------------------
15   !!   dyn_ldf_bilap : update the momentum trend with the lateral diffusion
16   !!                   using an iso-level bilaplacian operator
17   !!----------------------------------------------------------------------
18   USE oce             ! ocean dynamics and tracers
19   USE dom_oce         ! ocean space and time domain
20   USE phycst          ! physical constants
21   USE ldfdyn_oce      ! ocean dynamics: lateral physics
22   !
23   USE in_out_manager  ! I/O manager
24   USE iom             ! I/O library
25   USE lbclnk          ! ocean lateral boundary conditions (or mpp link)
26   USE wrk_nemo        ! Memory Allocation
27   USE timing          ! Timing
28
29   IMPLICIT NONE
30   PRIVATE
31
32   PUBLIC   dyn_ldf_bilap   ! called by step.F90
33
34   !! * Substitutions
35#  include "domzgr_substitute.h90"
36#  include "ldfdyn_substitute.h90"
37#  include "vectopt_loop_substitute.h90"
38   !!----------------------------------------------------------------------
39   !! NEMO/OPA 3.3 , NEMO Consortium (2010)
40   !! $Id$
41   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
42   !!----------------------------------------------------------------------
43CONTAINS
44
45   SUBROUTINE dyn_ldf_bilap( kt )
46      !!----------------------------------------------------------------------
47      !!                     ***  ROUTINE dyn_ldf_bilap  ***
48      !!
49      !! ** Purpose :   Compute the before trend of the lateral momentum
50      !!      diffusion and add it to the general trend of momentum equation.
51      !!
52      !! ** Method  :   The before horizontal momentum diffusion trend is a
53      !!      bi-harmonic operator (bilaplacian type) which separates the
54      !!      divergent and rotational parts of the flow.
55      !!      Its horizontal components are computed as follow:
56      !!      laplacian:
57      !!          zlu = 1/e1u di[ hdivb ] - 1/(e2u*e3u) dj-1[ e3f rotb ]
58      !!          zlv = 1/e2v dj[ hdivb ] + 1/(e1v*e3v) di-1[ e3f rotb ]
59      !!      third derivative:
60      !!       * multiply by the eddy viscosity coef. at u-, v-point, resp.
61      !!          zlu = ahmu * zlu
62      !!          zlv = ahmv * zlv
63      !!       * curl and divergence of the laplacian
64      !!          zuf = 1/(e1f*e2f) ( di[e2v zlv] - dj[e1u zlu] )
65      !!          zut = 1/(e1t*e2t*e3t) ( di[e2u*e3u zlu] + dj[e1v*e3v zlv] )
66      !!      bilaplacian:
67      !!              diffu = 1/e1u di[ zut ] - 1/(e2u*e3u) dj-1[ e3f zuf ]
68      !!              diffv = 1/e2v dj[ zut ] + 1/(e1v*e3v) di-1[ e3f zuf ]
69      !!      If ln_sco=F and ln_zps=F, the vertical scale factors in the
70      !!      rotational part of the diffusion are simplified
71      !!      Add this before trend to the general trend (ua,va):
72      !!            (ua,va) = (ua,va) + (diffu,diffv)
73      !!
74      !! ** Action : - Update (ua,va) with the before iso-level biharmonic
75      !!               mixing trend.
76      !!----------------------------------------------------------------------
77      INTEGER, INTENT(in) ::   kt   ! ocean time-step index
78      !
79      INTEGER  ::   ji, jj, jk                       ! dummy loop indices
80      REAL(wp) ::   zua, zva, zbt, ze2u, ze2v, zzz   ! local scalar
81      REAL(wp), POINTER, DIMENSION(:,:  ) ::   zcu, zcv
82      REAL(wp), POINTER, DIMENSION(:,:,:) ::   zuf, zut, zlu, zlv
83      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   z2d   ! 2D workspace
84      !!----------------------------------------------------------------------
85      !
86      IF( nn_timing == 1 )  CALL timing_start('dyn_ldf_bilap')
87      !
88      CALL wrk_alloc( jpi, jpj,      zcu, zcv           )
89      CALL wrk_alloc( jpi, jpj, jpk, zuf, zut, zlu, zlv ) 
90      !
91      IF( kt == nit000 .AND. lwp ) THEN
92         WRITE(numout,*)
93         WRITE(numout,*) 'dyn_ldf_bilap : iso-level bilaplacian operator'
94         WRITE(numout,*) '~~~~~~~~~~~~~'
95      ENDIF
96
97!!bug gm this should be enough
98!!$      zuf(:,:,jpk) = 0.e0
99!!$      zut(:,:,jpk) = 0.e0
100!!$      zlu(:,:,jpk) = 0.e0
101!!$      zlv(:,:,jpk) = 0.e0
102      zuf(:,:,:) = 0._wp
103      zut(:,:,:) = 0._wp
104      zlu(:,:,:) = 0._wp
105      zlv(:,:,:) = 0._wp
106
107      !                                                ! ===============
108      DO jk = 1, jpkm1                                 ! Horizontal slab
109         !                                             ! ===============
110         ! Laplacian
111         ! ---------
112
113         IF( ln_sco .OR. ln_zps ) THEN   ! s-coordinate or z-coordinate with partial steps
114            zuf(:,:,jk) = rotb(:,:,jk) * fse3f(:,:,jk)
115            DO jj = 2, jpjm1
116               DO ji = fs_2, fs_jpim1   ! vector opt.
117                  zlu(ji,jj,jk) = - (   zuf(ji  ,jj,jk) -   zuf(ji,jj-1,jk) ) / ( e2u(ji,jj) * fse3u(ji,jj,jk) )   &
118                     &            + ( hdivb(ji+1,jj,jk) - hdivb(ji,jj  ,jk) ) /   e1u(ji,jj)
119   
120                  zlv(ji,jj,jk) = + (   zuf(ji,jj  ,jk) -   zuf(ji-1,jj,jk) ) / ( e1v(ji,jj) * fse3v(ji,jj,jk) )   &
121                     &            + ( hdivb(ji,jj+1,jk) - hdivb(ji  ,jj,jk) ) /   e2v(ji,jj)
122               END DO
123            END DO
124         ELSE                            ! z-coordinate - full step
125            DO jj = 2, jpjm1
126               DO ji = fs_2, fs_jpim1   ! vector opt.
127                  zlu(ji,jj,jk) = - ( rotb (ji  ,jj,jk) - rotb (ji,jj-1,jk) ) / e2u(ji,jj)   &
128                     &            + ( hdivb(ji+1,jj,jk) - hdivb(ji,jj  ,jk) ) / e1u(ji,jj)
129   
130                  zlv(ji,jj,jk) = + ( rotb (ji,jj  ,jk) - rotb (ji-1,jj,jk) ) / e1v(ji,jj)   &
131                     &            + ( hdivb(ji,jj+1,jk) - hdivb(ji  ,jj,jk) ) / e2v(ji,jj)
132               END DO 
133            END DO 
134         ENDIF
135      END DO
136      CALL lbc_lnk( zlu, 'U', -1. )   ;   CALL lbc_lnk( zlv, 'V', -1. )   ! Boundary conditions
137
138      IF( iom_use('dispkexyfo') ) THEN   ! ocean kinetic energy dissipation per unit area
139         !                               ! due to xy friction (xy=lateral)
140         !   see NEMO_book appendix C, §C.7.2 (N.B. here averaged at t-points)
141         !   local dissipation of KE at t-point due to bilaplacian operator is given by :
142         !      + ahmu mi( zlu**2 ) + mj( ahmv zlv**2 )
143         !   Note that a sign + is used as in v3.6 ahm is negative for bilaplacian viscosity
144         !
145         ! NB: ahm is negative when bilaplacian is used
146         ALLOCATE( z2d(jpi,jpj) )
147         z2d(:,:) = 0._wp
148         DO jk = 1, jpkm1
149            DO jj = 2, jpjm1
150               DO ji = 2, jpim1
151                  z2d(ji,jj) = z2d(ji,jj)                                                                  &
152                     &  +  (  fsahmu(ji,jj,jk)*zlu(ji,jj,jk)**2 + fsahmu(ji-1,jj,jk)*zlu(ji-1,jj,jk)**2    &
153                     &      + fsahmv(ji,jj,jk)*zlv(ji,jj,jk)**2 + fsahmv(ji,jj-1,jk)*zlv(ji,jj-1,jk)**2  ) * tmask(ji,jj,jk)
154               END DO
155            END DO
156         END DO
157         zzz = 0.5_wp * rau0
158         z2d(:,:) = zzz * z2d(:,:) 
159         CALL lbc_lnk( z2d,'T', 1. )
160         CALL iom_put( 'dispkexyfo', z2d )
161         DEALLOCATE( z2d )
162      ENDIF
163     
164   
165      ! Third derivative
166      ! ----------------
167      !
168      DO jk = 1, jpkm1
169         !
170         ! Multiply by the eddy viscosity coef. (at u- and v-points)
171         zlu(:,:,jk) = zlu(:,:,jk) * fsahmu(:,:,jk) 
172         zlv(:,:,jk) = zlv(:,:,jk) * fsahmv(:,:,jk)
173         !         
174         ! Contravariant "laplacian"
175         zcu(:,:) = e1u(:,:) * zlu(:,:,jk)
176         zcv(:,:) = e2v(:,:) * zlv(:,:,jk)
177         
178         ! Laplacian curl ( * e3f if s-coordinates or z-coordinate with partial steps)
179         DO jj = 1, jpjm1
180            DO ji = 1, fs_jpim1   ! vector opt.
181               zuf(ji,jj,jk) = fmask(ji,jj,jk) * (  zcv(ji+1,jj  ) - zcv(ji,jj)      &
182                  &                               - zcu(ji  ,jj+1) + zcu(ji,jj)  )   &
183                  &       * fse3f(ji,jj,jk) * r1_e12f(ji,jj)
184            END DO 
185         END DO 
186
187         ! Laplacian Horizontal fluxes
188         DO jj = 1, jpjm1
189            DO ji = 1, fs_jpim1   ! vector opt.
190               zlu(ji,jj,jk) = e2u(ji,jj) * fse3u(ji,jj,jk) * zlu(ji,jj,jk)
191               zlv(ji,jj,jk) = e1v(ji,jj) * fse3v(ji,jj,jk) * zlv(ji,jj,jk)
192            END DO
193         END DO
194
195         ! Laplacian divergence
196         DO jj = 2, jpj
197            DO ji = fs_2, jpi   ! vector opt.
198               zbt = e1t(ji,jj) * e2t(ji,jj) * fse3t(ji,jj,jk)
199               zut(ji,jj,jk) = (  zlu(ji,jj,jk) - zlu(ji-1,jj  ,jk)   &
200                  &             + zlv(ji,jj,jk) - zlv(ji  ,jj-1,jk) ) / zbt
201            END DO
202         END DO
203      END DO
204
205      ! boundary conditions on the laplacian curl and div (zuf,zut)
206!!bug gm no need to do this 2 following lbc...
207      CALL lbc_lnk( zuf, 'F', 1. )
208      CALL lbc_lnk( zut, 'T', 1. )
209
210      DO jk = 1, jpkm1               ! Bilaplacian
211         DO jj = 2, jpjm1
212            DO ji = fs_2, fs_jpim1   ! vector opt.
213               ze2u = e2u(ji,jj) * fse3u(ji,jj,jk)
214               ze2v = e1v(ji,jj) * fse3v(ji,jj,jk)
215               ! horizontal biharmonic diffusive trends
216               zua = - ( zuf(ji  ,jj,jk) - zuf(ji,jj-1,jk) ) / ze2u   &
217                  &  + ( zut(ji+1,jj,jk) - zut(ji,jj  ,jk) ) / e1u(ji,jj)
218
219               zva = + ( zuf(ji,jj  ,jk) - zuf(ji-1,jj,jk) ) / ze2v   &
220                  &  + ( zut(ji,jj+1,jk) - zut(ji  ,jj,jk) ) / e2v(ji,jj)
221               ! add it to the general momentum trends
222               ua(ji,jj,jk) = ua(ji,jj,jk) + zua
223               va(ji,jj,jk) = va(ji,jj,jk) + zva
224            END DO
225         END DO
226         !                                             ! ===============
227      END DO                                           !   End of slab
228      !                                                ! ===============
229      CALL wrk_dealloc( jpi, jpj,      zcu, zcv           )
230      CALL wrk_dealloc( jpi, jpj, jpk, zuf, zut, zlu, zlv ) 
231      !
232      IF( nn_timing == 1 )  CALL timing_stop('dyn_ldf_bilap')
233      !
234   END SUBROUTINE dyn_ldf_bilap
235
236   !!======================================================================
237END MODULE dynldf_bilap
Note: See TracBrowser for help on using the repository browser.