dynldf_bilapg.F90 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. MODULE dynldf_bilapg
  2. !!======================================================================
  3. !! *** MODULE dynldf_bilapg ***
  4. !! Ocean dynamics: lateral viscosity trend
  5. !!======================================================================
  6. !! History : OPA ! 1997-07 (G. Madec) Original code
  7. !! NEMO 1.0 ! 2002-08 (G. Madec) F90: Free form and module
  8. !! 2.0 ! 2004-08 (C. Talandier) New trends organization
  9. !!----------------------------------------------------------------------
  10. #if defined key_ldfslp || defined key_esopa
  11. !!----------------------------------------------------------------------
  12. !! 'key_ldfslp' Rotation of mixing tensor
  13. !!----------------------------------------------------------------------
  14. !! dyn_ldf_bilapg : update the momentum trend with the horizontal part
  15. !! of the horizontal s-coord. bilaplacian diffusion
  16. !! ldfguv :
  17. !!----------------------------------------------------------------------
  18. USE oce ! ocean dynamics and tracers
  19. USE dom_oce ! ocean space and time domain
  20. USE ldfdyn_oce ! ocean dynamics lateral physics
  21. USE zdf_oce ! ocean vertical physics
  22. USE ldfslp ! iso-neutral slopes available
  23. USE ldftra_oce, ONLY: ln_traldf_iso
  24. !
  25. USE in_out_manager ! I/O manager
  26. USE lib_mpp ! MPP library
  27. USE lbclnk ! ocean lateral boundary conditions (or mpp link)
  28. USE prtctl ! Print control
  29. USE wrk_nemo ! Memory Allocation
  30. USE timing ! Timing
  31. IMPLICIT NONE
  32. PRIVATE
  33. PUBLIC dyn_ldf_bilapg ! called by step.F90
  34. REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) :: zfuw, zfvw , zdiu, zdiv ! 2D workspace (ldfguv)
  35. REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) :: zdju, zdj1u, zdjv, zdj1v ! 2D workspace (ldfguv)
  36. !! * Substitutions
  37. # include "domzgr_substitute.h90"
  38. # include "ldfdyn_substitute.h90"
  39. !!----------------------------------------------------------------------
  40. !! NEMO/OPA 3.3 , NEMO Consortium (2010)
  41. !! $Id: dynldf_bilapg.F90 4990 2014-12-15 16:42:49Z timgraham $
  42. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  43. !!----------------------------------------------------------------------
  44. CONTAINS
  45. INTEGER FUNCTION dyn_ldf_bilapg_alloc()
  46. !!----------------------------------------------------------------------
  47. !! *** ROUTINE dyn_ldf_bilapg_alloc ***
  48. !!----------------------------------------------------------------------
  49. ALLOCATE( zfuw(jpi,jpk) , zfvw (jpi,jpk) , zdiu(jpi,jpk) , zdiv (jpi,jpk) , &
  50. & zdju(jpi,jpk) , zdj1u(jpi,jpk) , zdjv(jpi,jpk) , zdj1v(jpi,jpk) , STAT=dyn_ldf_bilapg_alloc )
  51. !
  52. IF( dyn_ldf_bilapg_alloc /= 0 ) CALL ctl_warn('dyn_ldf_bilapg_alloc: failed to allocate arrays')
  53. END FUNCTION dyn_ldf_bilapg_alloc
  54. SUBROUTINE dyn_ldf_bilapg( kt )
  55. !!----------------------------------------------------------------------
  56. !! *** ROUTINE dyn_ldf_bilapg ***
  57. !!
  58. !! ** Purpose : Compute the before trend of the horizontal momentum
  59. !! diffusion and add it to the general trend of momentum equation.
  60. !!
  61. !! ** Method : The lateral momentum diffusive trends is provided by a
  62. !! a 4th order operator rotated along geopotential surfaces. It is
  63. !! computed using before fields (forward in time) and geopotential
  64. !! slopes computed in routine inildf.
  65. !! -1- compute the geopotential harmonic operator applied to
  66. !! (ub,vb) and multiply it by the eddy diffusivity coefficient
  67. !! (done by a call to ldfgpu and ldfgpv routines) The result is in
  68. !! (zwk1,zwk2) arrays. Applied the domain lateral boundary conditions
  69. !! by call to lbc_lnk.
  70. !! -2- applied to (zwk1,zwk2) the geopotential harmonic operator
  71. !! by a second call to ldfgpu and ldfgpv routines respectively. The
  72. !! result is in (zwk3,zwk4) arrays.
  73. !! -3- Add this trend to the general trend (ta,sa):
  74. !! (ua,va) = (ua,va) + (zwk3,zwk4)
  75. !!
  76. !! ** Action : - Update (ua,va) arrays with the before geopotential
  77. !! biharmonic mixing trend.
  78. !!----------------------------------------------------------------------
  79. INTEGER, INTENT( in ) :: kt ! ocean time-step index
  80. !
  81. INTEGER :: ji, jj, jk ! dummy loop indices
  82. REAL(wp), POINTER, DIMENSION(:,:,:) :: zwk1, zwk2, zwk3, zwk4
  83. !!----------------------------------------------------------------------
  84. !
  85. IF( nn_timing == 1 ) CALL timing_start('dyn_ldf_bilapg')
  86. !
  87. CALL wrk_alloc( jpi, jpj, jpk, zwk1, zwk2, zwk3, zwk4 )
  88. !
  89. IF( kt == nit000 ) THEN
  90. IF(lwp) WRITE(numout,*)
  91. IF(lwp) WRITE(numout,*) 'dyn_ldf_bilapg : horizontal biharmonic operator in s-coordinate'
  92. IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~~~'
  93. ! ! allocate dyn_ldf_bilapg arrays
  94. IF( dyn_ldf_bilapg_alloc() /= 0 ) CALL ctl_stop('STOP', 'dyn_ldf_bilapg: failed to allocate arrays')
  95. ENDIF
  96. ! s-coordinate: Iso-level diffusion on tracer, but geopotential level diffusion on momentum
  97. IF( ln_dynldf_hor .AND. ln_traldf_iso ) THEN
  98. !
  99. DO jk = 1, jpk ! set the slopes of iso-level
  100. DO jj = 2, jpjm1
  101. DO ji = 2, jpim1
  102. uslp (ji,jj,jk) = -1./e1u(ji,jj) * ( fsdept_b(ji+1,jj,jk) - fsdept_b(ji ,jj ,jk) ) * umask(ji,jj,jk)
  103. vslp (ji,jj,jk) = -1./e2v(ji,jj) * ( fsdept_b(ji,jj+1,jk) - fsdept_b(ji ,jj ,jk) ) * vmask(ji,jj,jk)
  104. wslpi(ji,jj,jk) = -1./e1t(ji,jj) * ( fsdepw_b(ji+1,jj,jk) - fsdepw_b(ji-1,jj,jk) ) * tmask(ji,jj,jk) * 0.5
  105. wslpj(ji,jj,jk) = -1./e2t(ji,jj) * ( fsdepw_b(ji,jj+1,jk) - fsdepw_b(ji,jj-1,jk) ) * tmask(ji,jj,jk) * 0.5
  106. END DO
  107. END DO
  108. END DO
  109. ! Lateral boundary conditions on the slopes
  110. CALL lbc_lnk( uslp , 'U', -1. ) ; CALL lbc_lnk( vslp , 'V', -1. )
  111. CALL lbc_lnk( wslpi, 'W', -1. ) ; CALL lbc_lnk( wslpj, 'W', -1. )
  112. !!bug
  113. IF( kt == nit000 ) then
  114. IF(lwp) WRITE(numout,*) ' max slop: u', SQRT( MAXVAL(uslp*uslp)), ' v ', SQRT(MAXVAL(vslp)), &
  115. & ' wi', sqrt(MAXVAL(wslpi)) , ' wj', sqrt(MAXVAL(wslpj))
  116. endif
  117. !!end
  118. ENDIF
  119. zwk1(:,:,:) = 0.e0 ; zwk3(:,:,:) = 0.e0
  120. zwk2(:,:,:) = 0.e0 ; zwk4(:,:,:) = 0.e0
  121. ! Laplacian of (ub,vb) multiplied by ahm
  122. ! --------------------------------------
  123. CALL ldfguv( ub, vb, zwk1, zwk2, 1 ) ! rotated harmonic operator applied to (ub,vb)
  124. ! ! and multiply by ahmu, ahmv (output in (zwk1,zwk2) )
  125. CALL lbc_lnk( zwk1, 'U', -1. ) ; CALL lbc_lnk( zwk2, 'V', -1. ) ! Lateral boundary conditions
  126. ! Bilaplacian of (ub,vb)
  127. ! ----------------------
  128. CALL ldfguv( zwk1, zwk2, zwk3, zwk4, 2 ) ! rotated harmonic operator applied to (zwk1,zwk2)
  129. ! ! (output in (zwk3,zwk4) )
  130. ! Update the momentum trends
  131. ! --------------------------
  132. DO jj = 2, jpjm1 ! add the diffusive trend to the general momentum trends
  133. DO jk = 1, jpkm1
  134. DO ji = 2, jpim1
  135. ua(ji,jj,jk) = ua(ji,jj,jk) + zwk3(ji,jj,jk)
  136. va(ji,jj,jk) = va(ji,jj,jk) + zwk4(ji,jj,jk)
  137. END DO
  138. END DO
  139. END DO
  140. !
  141. CALL wrk_dealloc( jpi, jpj, jpk, zwk1, zwk2, zwk3, zwk4 )
  142. !
  143. IF( nn_timing == 1 ) CALL timing_stop('dyn_ldf_bilapg')
  144. !
  145. END SUBROUTINE dyn_ldf_bilapg
  146. SUBROUTINE ldfguv( pu, pv, plu, plv, kahm )
  147. !!----------------------------------------------------------------------
  148. !! *** ROUTINE ldfguv ***
  149. !!
  150. !! ** Purpose : Apply a geopotential harmonic operator to (pu,pv)
  151. !! (defined at u- and v-points) and multiply it by the eddy
  152. !! viscosity coefficient (if kahm=1).
  153. !!
  154. !! ** Method : The harmonic operator rotated along geopotential
  155. !! surfaces is applied to (pu,pv) using the slopes of geopotential
  156. !! surfaces computed in inildf routine. The result is provided in
  157. !! (plu,plv) arrays. It is computed in 2 stepv:
  158. !!
  159. !! First step: horizontal part of the operator. It is computed on
  160. !! ========== pu as follows (idem on pv)
  161. !! horizontal fluxes :
  162. !! zftu = e2u*e3u/e1u di[ pu ] - e2u*uslp dk[ mi(mk(pu)) ]
  163. !! zftv = e1v*e3v/e2v dj[ pu ] - e1v*vslp dk[ mj(mk(pu)) ]
  164. !! take the horizontal divergence of the fluxes (no divided by
  165. !! the volume element :
  166. !! plu = di-1[ zftu ] + dj-1[ zftv ]
  167. !!
  168. !! Second step: vertical part of the operator. It is computed on
  169. !! =========== pu as follows (idem on pv)
  170. !! vertical fluxes :
  171. !! zftw = e1t*e2t/e3w * (wslpi^2+wslpj^2) dk-1[ pu ]
  172. !! - e2t * wslpi di[ mi(mk(pu)) ]
  173. !! - e1t * wslpj dj[ mj(mk(pu)) ]
  174. !! take the vertical divergence of the fluxes add it to the hori-
  175. !! zontal component, divide the result by the volume element and
  176. !! if kahm=1, multiply by the eddy diffusivity coefficient:
  177. !! plu = aht / (e1t*e2t*e3t) { plu + dk[ zftw ] }
  178. !! else:
  179. !! plu = 1 / (e1t*e2t*e3t) { plu + dk[ zftw ] }
  180. !!
  181. !! ** Action :
  182. !! plu, plv : partial harmonic operator applied to
  183. !! pu and pv (all the components except
  184. !! second order vertical derivative term)
  185. !!----------------------------------------------------------------------
  186. REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(in ) :: pu , pv ! 1st call: before horizontal velocity
  187. ! ! 2nd call: ahm x these fields
  188. REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT( out) :: plu, plv ! partial harmonic operator applied to
  189. ! ! pu and pv (all the components except
  190. ! ! second order vertical derivative term)
  191. INTEGER , INTENT(in ) :: kahm ! =1 1st call ; =2 2nd call
  192. !
  193. INTEGER :: ji, jj, jk ! dummy loop indices
  194. REAL(wp) :: zabe1 , zabe2 , zcof1 , zcof2 ! local scalar
  195. REAL(wp) :: zcoef0, zcoef3, zcoef4 ! - -
  196. REAL(wp) :: zbur, zbvr, zmkt, zmkf, zuav, zvav ! - -
  197. REAL(wp) :: zuwslpi, zuwslpj, zvwslpi, zvwslpj ! - -
  198. !
  199. REAL(wp), POINTER, DIMENSION(:,:) :: ziut, zjuf, zjvt, zivf, zdku, zdk1u, zdkv, zdk1v
  200. !!----------------------------------------------------------------------
  201. !
  202. IF( nn_timing == 1 ) CALL timing_start('ldfguv')
  203. !
  204. CALL wrk_alloc( jpi, jpj, ziut, zjuf, zjvt, zivf, zdku, zdk1u, zdkv, zdk1v )
  205. !
  206. ! ! ********** ! ! ===============
  207. DO jk = 1, jpkm1 ! First step ! ! Horizontal slab
  208. ! ! ********** ! ! ===============
  209. ! I.1 Vertical gradient of pu and pv at level jk and jk+1
  210. ! -------------------------------------------------------
  211. ! surface boundary condition: zdku(jk=1)=zdku(jk=2)
  212. ! zdkv(jk=1)=zdkv(jk=2)
  213. zdk1u(:,:) = ( pu(:,:,jk) - pu(:,:,jk+1) ) * umask(:,:,jk+1)
  214. zdk1v(:,:) = ( pv(:,:,jk) - pv(:,:,jk+1) ) * vmask(:,:,jk+1)
  215. IF( jk == 1 ) THEN
  216. zdku(:,:) = zdk1u(:,:)
  217. zdkv(:,:) = zdk1v(:,:)
  218. ELSE
  219. zdku(:,:) = ( pu(:,:,jk-1) - pu(:,:,jk) ) * umask(:,:,jk)
  220. zdkv(:,:) = ( pv(:,:,jk-1) - pv(:,:,jk) ) * vmask(:,:,jk)
  221. ENDIF
  222. ! -----f-----
  223. ! I.2 Horizontal fluxes on U |
  224. ! ------------------------=== t u t
  225. ! |
  226. ! i-flux at t-point -----f-----
  227. DO jj = 1, jpjm1
  228. DO ji = 2, jpi
  229. zabe1 = e2t(ji,jj) * fse3t(ji,jj,jk) / e1t(ji,jj)
  230. zmkt = 1./MAX( umask(ji-1,jj,jk )+umask(ji,jj,jk+1) &
  231. + umask(ji-1,jj,jk+1)+umask(ji,jj,jk ), 1. )
  232. zcof1 = -e2t(ji,jj) * zmkt &
  233. * 0.5 * ( uslp(ji-1,jj,jk) + uslp(ji,jj,jk) )
  234. ziut(ji,jj) = tmask(ji,jj,jk) * &
  235. ( zabe1 * ( pu(ji,jj,jk) - pu(ji-1,jj,jk) ) &
  236. + zcof1 * ( zdku (ji,jj) + zdk1u(ji-1,jj) &
  237. +zdk1u(ji,jj) + zdku (ji-1,jj) ) )
  238. END DO
  239. END DO
  240. ! j-flux at f-point
  241. DO jj = 1, jpjm1
  242. DO ji = 1, jpim1
  243. zabe2 = e1f(ji,jj) * fse3f(ji,jj,jk) / e2f(ji,jj)
  244. zmkf = 1./MAX( umask(ji,jj+1,jk )+umask(ji,jj,jk+1) &
  245. + umask(ji,jj+1,jk+1)+umask(ji,jj,jk ), 1. )
  246. zcof2 = -e1f(ji,jj) * zmkf &
  247. * 0.5 * ( vslp(ji+1,jj,jk) + vslp(ji,jj,jk) )
  248. zjuf(ji,jj) = fmask(ji,jj,jk) * &
  249. ( zabe2 * ( pu(ji,jj+1,jk) - pu(ji,jj,jk) ) &
  250. + zcof2 * ( zdku (ji,jj+1) + zdk1u(ji,jj) &
  251. +zdk1u(ji,jj+1) + zdku (ji,jj) ) )
  252. END DO
  253. END DO
  254. ! | t |
  255. ! I.3 Horizontal fluxes on V | |
  256. ! ------------------------=== f---v---f
  257. ! | |
  258. ! i-flux at f-point | t |
  259. DO jj = 1, jpjm1
  260. DO ji = 1, jpim1
  261. zabe1 = e2f(ji,jj) * fse3f(ji,jj,jk) / e1f(ji,jj)
  262. zmkf = 1./MAX( vmask(ji+1,jj,jk )+vmask(ji,jj,jk+1) &
  263. + vmask(ji+1,jj,jk+1)+vmask(ji,jj,jk ), 1. )
  264. zcof1 = -e2f(ji,jj) * zmkf &
  265. * 0.5 * ( uslp(ji,jj+1,jk) + uslp(ji,jj,jk) )
  266. zivf(ji,jj) = fmask(ji,jj,jk) * &
  267. ( zabe1 * ( pu(ji+1,jj,jk) - pu(ji,jj,jk) ) &
  268. + zcof1 * ( zdku (ji,jj) + zdk1u(ji+1,jj) &
  269. +zdk1u(ji,jj) + zdku (ji+1,jj) ) )
  270. END DO
  271. END DO
  272. ! j-flux at t-point
  273. DO jj = 2, jpj
  274. DO ji = 1, jpim1
  275. zabe2 = e1t(ji,jj) * fse3t(ji,jj,jk) / e2t(ji,jj)
  276. zmkt = 1./MAX( vmask(ji,jj-1,jk )+vmask(ji,jj,jk+1) &
  277. + vmask(ji,jj-1,jk+1)+vmask(ji,jj,jk ), 1. )
  278. zcof2 = -e1t(ji,jj) * zmkt &
  279. * 0.5 * ( vslp(ji,jj-1,jk) + vslp(ji,jj,jk) )
  280. zjvt(ji,jj) = tmask(ji,jj,jk) * &
  281. ( zabe2 * ( pu(ji,jj,jk) - pu(ji,jj-1,jk) ) &
  282. + zcof2 * ( zdku (ji,jj-1) + zdk1u(ji,jj) &
  283. +zdk1u(ji,jj-1) + zdku (ji,jj) ) )
  284. END DO
  285. END DO
  286. ! I.4 Second derivative (divergence) (not divided by the volume)
  287. ! ---------------------
  288. DO jj = 2, jpjm1
  289. DO ji = 2, jpim1
  290. plu(ji,jj,jk) = ziut (ji+1,jj) - ziut (ji,jj ) &
  291. + zjuf (ji ,jj) - zjuf (ji,jj-1)
  292. plv(ji,jj,jk) = zivf (ji,jj ) - zivf (ji-1,jj) &
  293. + zjvt (ji,jj+1) - zjvt (ji,jj )
  294. END DO
  295. END DO
  296. ! ! ===============
  297. END DO ! End of slab
  298. ! ! ===============
  299. !,,,,,,,,,,,,,,,,,,,,,,,,,,,,,synchro,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
  300. ! ! ************ ! ! ===============
  301. DO jj = 2, jpjm1 ! Second step ! ! Horizontal slab
  302. ! ! ************ ! ! ===============
  303. ! II.1 horizontal (pu,pv) gradients
  304. ! ---------------------------------
  305. DO jk = 1, jpk
  306. DO ji = 2, jpi
  307. ! i-gradient of u at jj
  308. zdiu (ji,jk) = tmask(ji,jj ,jk) * ( pu(ji,jj ,jk) - pu(ji-1,jj ,jk) )
  309. ! j-gradient of u and v at jj
  310. zdju (ji,jk) = fmask(ji,jj ,jk) * ( pu(ji,jj+1,jk) - pu(ji ,jj ,jk) )
  311. zdjv (ji,jk) = tmask(ji,jj ,jk) * ( pv(ji,jj ,jk) - pv(ji ,jj-1,jk) )
  312. ! j-gradient of u and v at jj+1
  313. zdj1u(ji,jk) = fmask(ji,jj-1,jk) * ( pu(ji,jj ,jk) - pu(ji ,jj-1,jk) )
  314. zdj1v(ji,jk) = tmask(ji,jj+1,jk) * ( pv(ji,jj+1,jk) - pv(ji ,jj ,jk) )
  315. END DO
  316. END DO
  317. DO jk = 1, jpk
  318. DO ji = 1, jpim1
  319. ! i-gradient of v at jj
  320. zdiv (ji,jk) = fmask(ji,jj ,jk) * ( pv(ji+1,jj,jk) - pv(ji ,jj ,jk) )
  321. END DO
  322. END DO
  323. ! II.2 Vertical fluxes
  324. ! --------------------
  325. ! Surface and bottom vertical fluxes set to zero
  326. zfuw(:, 1 ) = 0.e0
  327. zfvw(:, 1 ) = 0.e0
  328. zfuw(:,jpk) = 0.e0
  329. zfvw(:,jpk) = 0.e0
  330. ! interior (2=<jk=<jpk-1) on pu field
  331. DO jk = 2, jpkm1
  332. DO ji = 2, jpim1
  333. ! i- and j-slopes at uw-point
  334. zuwslpi = 0.5 * ( wslpi(ji+1,jj,jk) + wslpi(ji,jj,jk) )
  335. zuwslpj = 0.5 * ( wslpj(ji+1,jj,jk) + wslpj(ji,jj,jk) )
  336. ! coef. for the vertical dirative
  337. zcoef0 = e1u(ji,jj) * e2u(ji,jj) / fse3u(ji,jj,jk) &
  338. * ( zuwslpi * zuwslpi + zuwslpj * zuwslpj )
  339. ! weights for the i-k, j-k averaging at t- and f-points, resp.
  340. zmkt = 1./MAX( tmask(ji,jj,jk-1)+tmask(ji+1,jj,jk-1) &
  341. + tmask(ji,jj,jk )+tmask(ji+1,jj,jk ), 1. )
  342. zmkf = 1./MAX( fmask(ji,jj-1,jk-1)+fmask(ji,jj,jk-1) &
  343. + fmask(ji,jj-1,jk )+fmask(ji,jj,jk ), 1. )
  344. ! coef. for the horitontal derivative
  345. zcoef3 = - e2u(ji,jj) * zmkt * zuwslpi
  346. zcoef4 = - e1u(ji,jj) * zmkf * zuwslpj
  347. ! vertical flux on u field
  348. zfuw(ji,jk) = umask(ji,jj,jk) * &
  349. ( zcoef0 * ( pu (ji,jj,jk-1) - pu (ji,jj,jk) ) &
  350. + zcoef3 * ( zdiu (ji,jk-1) + zdiu (ji+1,jk-1) &
  351. +zdiu (ji,jk ) + zdiu (ji+1,jk ) ) &
  352. + zcoef4 * ( zdj1u(ji,jk-1) + zdju (ji ,jk-1) &
  353. +zdj1u(ji,jk ) + zdju (ji ,jk ) ) )
  354. END DO
  355. END DO
  356. ! interior (2=<jk=<jpk-1) on pv field
  357. DO jk = 2, jpkm1
  358. DO ji = 2, jpim1
  359. ! i- and j-slopes at vw-point
  360. zvwslpi = 0.5 * ( wslpi(ji,jj+1,jk) + wslpi(ji,jj,jk) )
  361. zvwslpj = 0.5 * ( wslpj(ji,jj+1,jk) + wslpj(ji,jj,jk) )
  362. ! coef. for the vertical derivative
  363. zcoef0 = e1v(ji,jj) * e2v(ji,jj) / fse3v(ji,jj,jk) &
  364. * ( zvwslpi * zvwslpi + zvwslpj * zvwslpj )
  365. ! weights for the i-k, j-k averaging at f- and t-points, resp.
  366. zmkf = 1./MAX( fmask(ji-1,jj,jk-1)+fmask(ji,jj,jk-1) &
  367. + fmask(ji-1,jj,jk )+fmask(ji,jj,jk ), 1. )
  368. zmkt = 1./MAX( tmask(ji,jj,jk-1)+tmask(ji,jj+1,jk-1) &
  369. + tmask(ji,jj,jk )+tmask(ji,jj+1,jk ), 1. )
  370. ! coef. for the horizontal derivatives
  371. zcoef3 = - e2v(ji,jj) * zmkf * zvwslpi
  372. zcoef4 = - e1v(ji,jj) * zmkt * zvwslpj
  373. ! vertical flux on pv field
  374. zfvw(ji,jk) = vmask(ji,jj,jk) * &
  375. ( zcoef0 * ( pv (ji,jj,jk-1) - pv (ji,jj,jk) ) &
  376. + zcoef3 * ( zdiv (ji,jk-1) + zdiv (ji-1,jk-1) &
  377. +zdiv (ji,jk ) + zdiv (ji-1,jk ) ) &
  378. + zcoef4 * ( zdjv (ji,jk-1) + zdj1v(ji ,jk-1) &
  379. +zdjv (ji,jk ) + zdj1v(ji ,jk ) ) )
  380. END DO
  381. END DO
  382. ! II.3 Divergence of vertical fluxes added to the horizontal divergence
  383. ! ---------------------------------------------------------------------
  384. IF( (kahm -nkahm_smag) ==1 ) THEN
  385. ! multiply the laplacian by the eddy viscosity coefficient
  386. DO jk = 1, jpkm1
  387. DO ji = 2, jpim1
  388. ! eddy coef. divided by the volume element
  389. zbur = fsahmu(ji,jj,jk) / ( e1u(ji,jj)*e2u(ji,jj)*fse3u(ji,jj,jk) )
  390. zbvr = fsahmv(ji,jj,jk) / ( e1v(ji,jj)*e2v(ji,jj)*fse3v(ji,jj,jk) )
  391. ! vertical divergence
  392. zuav = zfuw(ji,jk) - zfuw(ji,jk+1)
  393. zvav = zfvw(ji,jk) - zfvw(ji,jk+1)
  394. ! harmonic operator applied to (pu,pv) and multiply by ahm
  395. plu(ji,jj,jk) = ( plu(ji,jj,jk) + zuav ) * zbur
  396. plv(ji,jj,jk) = ( plv(ji,jj,jk) + zvav ) * zbvr
  397. END DO
  398. END DO
  399. ELSEIF( (kahm +nkahm_smag ) == 2 ) THEN
  400. ! second call, no multiplication
  401. DO jk = 1, jpkm1
  402. DO ji = 2, jpim1
  403. ! inverse of the volume element
  404. zbur = 1. / ( e1u(ji,jj)*e2u(ji,jj)*fse3u(ji,jj,jk) )
  405. zbvr = 1. / ( e1v(ji,jj)*e2v(ji,jj)*fse3v(ji,jj,jk) )
  406. ! vertical divergence
  407. zuav = zfuw(ji,jk) - zfuw(ji,jk+1)
  408. zvav = zfvw(ji,jk) - zfvw(ji,jk+1)
  409. ! harmonic operator applied to (pu,pv)
  410. plu(ji,jj,jk) = ( plu(ji,jj,jk) + zuav ) * zbur
  411. plv(ji,jj,jk) = ( plv(ji,jj,jk) + zvav ) * zbvr
  412. END DO
  413. END DO
  414. ELSE
  415. IF(lwp)WRITE(numout,*) ' ldfguv: kahm= 1 or 2, here =', kahm
  416. IF(lwp)WRITE(numout,*) ' We stop'
  417. STOP 'ldfguv'
  418. ENDIF
  419. ! ! ===============
  420. END DO ! End of slab
  421. ! ! ===============
  422. CALL wrk_dealloc( jpi, jpj, ziut, zjuf, zjvt, zivf, zdku, zdk1u, zdkv, zdk1v )
  423. !
  424. IF( nn_timing == 1 ) CALL timing_stop('ldfguv')
  425. !
  426. END SUBROUTINE ldfguv
  427. #else
  428. !!----------------------------------------------------------------------
  429. !! Dummy module : NO rotation of mixing tensor
  430. !!----------------------------------------------------------------------
  431. CONTAINS
  432. SUBROUTINE dyn_ldf_bilapg( kt ) ! Dummy routine
  433. INTEGER, INTENT(in) :: kt
  434. WRITE(*,*) 'dyn_ldf_bilapg: You should not have seen this print! error?', kt
  435. END SUBROUTINE dyn_ldf_bilapg
  436. #endif
  437. !!======================================================================
  438. END MODULE dynldf_bilapg