zpshde.F90 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. MODULE zpshde
  2. !!======================================================================
  3. !! *** MODULE zpshde ***
  4. !! z-coordinate + partial step : Horizontal Derivative at ocean bottom level
  5. !!======================================================================
  6. !! History : OPA ! 2002-04 (A. Bozec) Original code
  7. !! NEMO 1.0 ! 2002-08 (G. Madec E. Durand) Optimization and Free form
  8. !! - ! 2004-03 (C. Ethe) adapted for passive tracers
  9. !! 3.3 ! 2010-05 (C. Ethe, G. Madec) merge TRC-TRA
  10. !! 3.6 ! 2014-11 (P. Mathiot) Add zps_hde_isf (needed to open a cavity)
  11. !!======================================================================
  12. !!----------------------------------------------------------------------
  13. !! zps_hde : Horizontal DErivative of T, S and rd at the last
  14. !! ocean level (Z-coord. with Partial Steps)
  15. !!----------------------------------------------------------------------
  16. USE oce ! ocean: dynamics and tracers variables
  17. USE dom_oce ! domain: ocean variables
  18. USE phycst ! physical constants
  19. USE eosbn2 ! ocean equation of state
  20. USE in_out_manager ! I/O manager
  21. USE lbclnk ! lateral boundary conditions (or mpp link)
  22. USE lib_mpp ! MPP library
  23. USE wrk_nemo ! Memory allocation
  24. USE timing ! Timing
  25. IMPLICIT NONE
  26. PRIVATE
  27. PUBLIC zps_hde ! routine called by step.F90
  28. PUBLIC zps_hde_isf ! routine called by step.F90
  29. !! * Substitutions
  30. # include "domzgr_substitute.h90"
  31. # include "vectopt_loop_substitute.h90"
  32. !!----------------------------------------------------------------------
  33. !! NEMO/OPA 3.3 , NEMO Consortium (2010)
  34. !! $Id: zpshde.F90 4990 2014-12-15 16:42:49Z timgraham $
  35. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  36. !!----------------------------------------------------------------------
  37. CONTAINS
  38. SUBROUTINE zps_hde( kt, kjpt, pta, pgtu, pgtv, &
  39. & prd, pgru, pgrv )
  40. !!----------------------------------------------------------------------
  41. !! *** ROUTINE zps_hde ***
  42. !!
  43. !! ** Purpose : Compute the horizontal derivative of T, S and rho
  44. !! at u- and v-points with a linear interpolation for z-coordinate
  45. !! with partial steps.
  46. !!
  47. !! ** Method : In z-coord with partial steps, scale factors on last
  48. !! levels are different for each grid point, so that T, S and rd
  49. !! points are not at the same depth as in z-coord. To have horizontal
  50. !! gradients again, we interpolate T and S at the good depth :
  51. !! Linear interpolation of T, S
  52. !! Computation of di(tb) and dj(tb) by vertical interpolation:
  53. !! di(t) = t~ - t(i,j,k) or t(i+1,j,k) - t~
  54. !! dj(t) = t~ - t(i,j,k) or t(i,j+1,k) - t~
  55. !! This formulation computes the two cases:
  56. !! CASE 1 CASE 2
  57. !! k-1 ___ ___________ k-1 ___ ___________
  58. !! Ti T~ T~ Ti+1
  59. !! _____ _____
  60. !! k | |Ti+1 k Ti | |
  61. !! | |____ ____| |
  62. !! ___ | | | ___ | | |
  63. !!
  64. !! case 1-> e3w(i+1) >= e3w(i) ( and e3w(j+1) >= e3w(j) ) then
  65. !! t~ = t(i+1,j ,k) + (e3w(i+1) - e3w(i)) * dk(Ti+1)/e3w(i+1)
  66. !! ( t~ = t(i ,j+1,k) + (e3w(j+1) - e3w(j)) * dk(Tj+1)/e3w(j+1) )
  67. !! or
  68. !! case 2-> e3w(i+1) <= e3w(i) ( and e3w(j+1) <= e3w(j) ) then
  69. !! t~ = t(i,j,k) + (e3w(i) - e3w(i+1)) * dk(Ti)/e3w(i )
  70. !! ( t~ = t(i,j,k) + (e3w(j) - e3w(j+1)) * dk(Tj)/e3w(j ) )
  71. !! Idem for di(s) and dj(s)
  72. !!
  73. !! For rho, we call eos which will compute rd~(t~,s~) at the right
  74. !! depth zh from interpolated T and S for the different formulations
  75. !! of the equation of state (eos).
  76. !! Gradient formulation for rho :
  77. !! di(rho) = rd~ - rd(i,j,k) or rd(i+1,j,k) - rd~
  78. !!
  79. !! ** Action : compute for top interfaces
  80. !! - pgtu, pgtv: horizontal gradient of tracer at u- & v-points
  81. !! - pgru, pgrv: horizontal gradient of rho (if present) at u- & v-points
  82. !!----------------------------------------------------------------------
  83. INTEGER , INTENT(in ) :: kt ! ocean time-step index
  84. INTEGER , INTENT(in ) :: kjpt ! number of tracers
  85. REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(in ) :: pta ! 4D tracers fields
  86. REAL(wp), DIMENSION(jpi,jpj, kjpt), INTENT( out) :: pgtu, pgtv ! hor. grad. of ptra at u- & v-pts
  87. REAL(wp), DIMENSION(jpi,jpj,jpk ), INTENT(in ), OPTIONAL :: prd ! 3D density anomaly fields
  88. REAL(wp), DIMENSION(jpi,jpj ), INTENT( out), OPTIONAL :: pgru, pgrv ! hor. grad of prd at u- & v-pts (bottom)
  89. !
  90. INTEGER :: ji, jj, jn ! Dummy loop indices
  91. INTEGER :: iku, ikv, ikum1, ikvm1 ! partial step level (ocean bottom level) at u- and v-points
  92. REAL(wp) :: ze3wu, ze3wv, zmaxu, zmaxv ! temporary scalars
  93. REAL(wp), DIMENSION(jpi,jpj) :: zri, zrj, zhi, zhj ! NB: 3rd dim=1 to use eos
  94. REAL(wp), DIMENSION(jpi,jpj,kjpt) :: zti, ztj !
  95. !!----------------------------------------------------------------------
  96. !
  97. IF( nn_timing == 1 ) CALL timing_start( 'zps_hde')
  98. !
  99. pgtu(:,:,:)=0.0_wp ; pgtv(:,:,:)=0.0_wp ;
  100. zti (:,:,:)=0.0_wp ; ztj (:,:,:)=0.0_wp ;
  101. zhi (:,: )=0.0_wp ; zhj (:,: )=0.0_wp ;
  102. !
  103. DO jn = 1, kjpt !== Interpolation of tracers at the last ocean level ==!
  104. !
  105. DO jj = 1, jpjm1
  106. DO ji = 1, jpim1
  107. iku = mbku(ji,jj) ; ikum1 = MAX( iku - 1 , 1 ) ! last and before last ocean level at u- & v-points
  108. ikv = mbkv(ji,jj) ; ikvm1 = MAX( ikv - 1 , 1 ) ! if level first is a p-step, ik.m1=1
  109. ze3wu = fse3w(ji+1,jj ,iku) - fse3w(ji,jj,iku)
  110. ze3wv = fse3w(ji ,jj+1,ikv) - fse3w(ji,jj,ikv)
  111. !
  112. ! i- direction
  113. IF( ze3wu >= 0._wp ) THEN ! case 1
  114. zmaxu = ze3wu / fse3w(ji+1,jj,iku)
  115. ! interpolated values of tracers
  116. zti (ji,jj,jn) = pta(ji+1,jj,iku,jn) + zmaxu * ( pta(ji+1,jj,ikum1,jn) - pta(ji+1,jj,iku,jn) )
  117. ! gradient of tracers
  118. pgtu(ji,jj,jn) = umask(ji,jj,1) * ( zti(ji,jj,jn) - pta(ji,jj,iku,jn) )
  119. ELSE ! case 2
  120. zmaxu = -ze3wu / fse3w(ji,jj,iku)
  121. ! interpolated values of tracers
  122. zti (ji,jj,jn) = pta(ji,jj,iku,jn) + zmaxu * ( pta(ji,jj,ikum1,jn) - pta(ji,jj,iku,jn) )
  123. ! gradient of tracers
  124. pgtu(ji,jj,jn) = umask(ji,jj,1) * ( pta(ji+1,jj,iku,jn) - zti(ji,jj,jn) )
  125. ENDIF
  126. !
  127. ! j- direction
  128. IF( ze3wv >= 0._wp ) THEN ! case 1
  129. zmaxv = ze3wv / fse3w(ji,jj+1,ikv)
  130. ! interpolated values of tracers
  131. ztj (ji,jj,jn) = pta(ji,jj+1,ikv,jn) + zmaxv * ( pta(ji,jj+1,ikvm1,jn) - pta(ji,jj+1,ikv,jn) )
  132. ! gradient of tracers
  133. pgtv(ji,jj,jn) = vmask(ji,jj,1) * ( ztj(ji,jj,jn) - pta(ji,jj,ikv,jn) )
  134. ELSE ! case 2
  135. zmaxv = -ze3wv / fse3w(ji,jj,ikv)
  136. ! interpolated values of tracers
  137. ztj (ji,jj,jn) = pta(ji,jj,ikv,jn) + zmaxv * ( pta(ji,jj,ikvm1,jn) - pta(ji,jj,ikv,jn) )
  138. ! gradient of tracers
  139. pgtv(ji,jj,jn) = vmask(ji,jj,1) * ( pta(ji,jj+1,ikv,jn) - ztj(ji,jj,jn) )
  140. ENDIF
  141. END DO
  142. END DO
  143. CALL lbc_lnk( pgtu(:,:,jn), 'U', -1. ) ; CALL lbc_lnk( pgtv(:,:,jn), 'V', -1. ) ! Lateral boundary cond.
  144. !
  145. END DO
  146. ! horizontal derivative of density anomalies (rd)
  147. IF( PRESENT( prd ) ) THEN ! depth of the partial step level
  148. pgru(:,:)=0.0_wp ; pgrv(:,:)=0.0_wp ;
  149. DO jj = 1, jpjm1
  150. DO ji = 1, jpim1
  151. iku = mbku(ji,jj)
  152. ikv = mbkv(ji,jj)
  153. ze3wu = fse3w(ji+1,jj ,iku) - fse3w(ji,jj,iku)
  154. ze3wv = fse3w(ji ,jj+1,ikv) - fse3w(ji,jj,ikv)
  155. IF( ze3wu >= 0._wp ) THEN ; zhi(ji,jj) = fsdept(ji ,jj,iku) ! i-direction: case 1
  156. ELSE ; zhi(ji,jj) = fsdept(ji+1,jj,iku) ! - - case 2
  157. ENDIF
  158. IF( ze3wv >= 0._wp ) THEN ; zhj(ji,jj) = fsdept(ji,jj ,ikv) ! j-direction: case 1
  159. ELSE ; zhj(ji,jj) = fsdept(ji,jj+1,ikv) ! - - case 2
  160. ENDIF
  161. END DO
  162. END DO
  163. ! Compute interpolated rd from zti, ztj for the 2 cases at the depth of the partial
  164. ! step and store it in zri, zrj for each case
  165. CALL eos( zti, zhi, zri )
  166. CALL eos( ztj, zhj, zrj )
  167. ! Gradient of density at the last level
  168. DO jj = 1, jpjm1
  169. DO ji = 1, jpim1
  170. iku = mbku(ji,jj)
  171. ikv = mbkv(ji,jj)
  172. ze3wu = fse3w(ji+1,jj ,iku) - fse3w(ji,jj,iku)
  173. ze3wv = fse3w(ji ,jj+1,ikv) - fse3w(ji,jj,ikv)
  174. IF( ze3wu >= 0._wp ) THEN ; pgru(ji,jj) = umask(ji,jj,1) * ( zri(ji ,jj ) - prd(ji,jj,iku) ) ! i: 1
  175. ELSE ; pgru(ji,jj) = umask(ji,jj,1) * ( prd(ji+1,jj,iku) - zri(ji,jj ) ) ! i: 2
  176. ENDIF
  177. IF( ze3wv >= 0._wp ) THEN ; pgrv(ji,jj) = vmask(ji,jj,1) * ( zrj(ji,jj ) - prd(ji,jj,ikv) ) ! j: 1
  178. ELSE ; pgrv(ji,jj) = vmask(ji,jj,1) * ( prd(ji,jj+1,ikv) - zrj(ji,jj ) ) ! j: 2
  179. ENDIF
  180. END DO
  181. END DO
  182. CALL lbc_lnk( pgru , 'U', -1. ) ; CALL lbc_lnk( pgrv , 'V', -1. ) ! Lateral boundary conditions
  183. !
  184. END IF
  185. !
  186. IF( nn_timing == 1 ) CALL timing_stop( 'zps_hde')
  187. !
  188. END SUBROUTINE zps_hde
  189. !
  190. SUBROUTINE zps_hde_isf( kt, kjpt, pta, pgtu, pgtv, &
  191. & prd, pgru, pgrv, pmru, pmrv, pgzu, pgzv, pge3ru, pge3rv, &
  192. & pgtui, pgtvi, pgrui, pgrvi, pmrui, pmrvi, pgzui, pgzvi, pge3rui, pge3rvi )
  193. !!----------------------------------------------------------------------
  194. !! *** ROUTINE zps_hde ***
  195. !!
  196. !! ** Purpose : Compute the horizontal derivative of T, S and rho
  197. !! at u- and v-points with a linear interpolation for z-coordinate
  198. !! with partial steps.
  199. !!
  200. !! ** Method : In z-coord with partial steps, scale factors on last
  201. !! levels are different for each grid point, so that T, S and rd
  202. !! points are not at the same depth as in z-coord. To have horizontal
  203. !! gradients again, we interpolate T and S at the good depth :
  204. !! Linear interpolation of T, S
  205. !! Computation of di(tb) and dj(tb) by vertical interpolation:
  206. !! di(t) = t~ - t(i,j,k) or t(i+1,j,k) - t~
  207. !! dj(t) = t~ - t(i,j,k) or t(i,j+1,k) - t~
  208. !! This formulation computes the two cases:
  209. !! CASE 1 CASE 2
  210. !! k-1 ___ ___________ k-1 ___ ___________
  211. !! Ti T~ T~ Ti+1
  212. !! _____ _____
  213. !! k | |Ti+1 k Ti | |
  214. !! | |____ ____| |
  215. !! ___ | | | ___ | | |
  216. !!
  217. !! case 1-> e3w(i+1) >= e3w(i) ( and e3w(j+1) >= e3w(j) ) then
  218. !! t~ = t(i+1,j ,k) + (e3w(i+1) - e3w(i)) * dk(Ti+1)/e3w(i+1)
  219. !! ( t~ = t(i ,j+1,k) + (e3w(j+1) - e3w(j)) * dk(Tj+1)/e3w(j+1) )
  220. !! or
  221. !! case 2-> e3w(i+1) <= e3w(i) ( and e3w(j+1) <= e3w(j) ) then
  222. !! t~ = t(i,j,k) + (e3w(i) - e3w(i+1)) * dk(Ti)/e3w(i )
  223. !! ( t~ = t(i,j,k) + (e3w(j) - e3w(j+1)) * dk(Tj)/e3w(j ) )
  224. !! Idem for di(s) and dj(s)
  225. !!
  226. !! For rho, we call eos which will compute rd~(t~,s~) at the right
  227. !! depth zh from interpolated T and S for the different formulations
  228. !! of the equation of state (eos).
  229. !! Gradient formulation for rho :
  230. !! di(rho) = rd~ - rd(i,j,k) or rd(i+1,j,k) - rd~
  231. !!
  232. !! ** Action : compute for top and bottom interfaces
  233. !! - pgtu, pgtv, pgtui, pgtvi: horizontal gradient of tracer at u- & v-points
  234. !! - pgru, pgrv, pgrui, pgtvi: horizontal gradient of rho (if present) at u- & v-points
  235. !! - pmru, pmrv, pmrui, pmrvi: horizontal sum of rho at u- & v- point (used in dynhpg with vvl)
  236. !! - pgzu, pgzv, pgzui, pgzvi: horizontal gradient of z at u- and v- point (used in dynhpg with vvl)
  237. !! - pge3ru, pge3rv, pge3rui, pge3rvi: horizontal gradient of rho weighted by local e3w at u- & v-points
  238. !!----------------------------------------------------------------------
  239. INTEGER , INTENT(in ) :: kt ! ocean time-step index
  240. INTEGER , INTENT(in ) :: kjpt ! number of tracers
  241. REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(in ) :: pta ! 4D tracers fields
  242. REAL(wp), DIMENSION(jpi,jpj, kjpt), INTENT( out) :: pgtu, pgtv ! hor. grad. of ptra at u- & v-pts
  243. REAL(wp), DIMENSION(jpi,jpj, kjpt), INTENT( out) :: pgtui, pgtvi ! hor. grad. of stra at u- & v-pts (ISF)
  244. REAL(wp), DIMENSION(jpi,jpj,jpk ), INTENT(in ), OPTIONAL :: prd ! 3D density anomaly fields
  245. REAL(wp), DIMENSION(jpi,jpj ), INTENT( out), OPTIONAL :: pgru, pgrv ! hor. grad of prd at u- & v-pts (bottom)
  246. REAL(wp), DIMENSION(jpi,jpj ), INTENT( out), OPTIONAL :: pmru, pmrv ! hor. sum of prd at u- & v-pts (bottom)
  247. REAL(wp), DIMENSION(jpi,jpj ), INTENT( out), OPTIONAL :: pgzu, pgzv ! hor. grad of z at u- & v-pts (bottom)
  248. REAL(wp), DIMENSION(jpi,jpj ), INTENT( out), OPTIONAL :: pge3ru, pge3rv ! hor. grad of prd weighted by local e3w at u- & v-pts (bottom)
  249. REAL(wp), DIMENSION(jpi,jpj ), INTENT( out), OPTIONAL :: pgrui, pgrvi ! hor. grad of prd at u- & v-pts (top)
  250. REAL(wp), DIMENSION(jpi,jpj ), INTENT( out), OPTIONAL :: pmrui, pmrvi ! hor. sum of prd at u- & v-pts (top)
  251. REAL(wp), DIMENSION(jpi,jpj ), INTENT( out), OPTIONAL :: pgzui, pgzvi ! hor. grad of z at u- & v-pts (top)
  252. REAL(wp), DIMENSION(jpi,jpj ), INTENT( out), OPTIONAL :: pge3rui, pge3rvi ! hor. grad of prd weighted by local e3w at u- & v-pts (top)
  253. !
  254. INTEGER :: ji, jj, jn ! Dummy loop indices
  255. INTEGER :: iku, ikv, ikum1, ikvm1,ikup1, ikvp1 ! partial step level (ocean bottom level) at u- and v-points
  256. REAL(wp) :: ze3wu, ze3wv, zmaxu, zmaxv, zdzwu, zdzwv, zdzwuip1, zdzwvjp1 ! temporary scalars
  257. REAL(wp), DIMENSION(jpi,jpj) :: zri, zrj, zhi, zhj ! NB: 3rd dim=1 to use eos
  258. REAL(wp), DIMENSION(jpi,jpj,kjpt) :: zti, ztj !
  259. !!----------------------------------------------------------------------
  260. !
  261. IF( nn_timing == 1 ) CALL timing_start( 'zps_hde_isf')
  262. !
  263. pgtu(:,:,:)=0.0_wp ; pgtv(:,:,:)=0.0_wp ;
  264. pgtui(:,:,:)=0.0_wp ; pgtvi(:,:,:)=0.0_wp ;
  265. zti (:,:,:)=0.0_wp ; ztj (:,:,:)=0.0_wp ;
  266. zhi (:,: )=0.0_wp ; zhj (:,: )=0.0_wp ;
  267. !
  268. DO jn = 1, kjpt !== Interpolation of tracers at the last ocean level ==!
  269. !
  270. DO jj = 1, jpjm1
  271. DO ji = 1, jpim1
  272. iku = mbku(ji,jj) ; ikum1 = MAX( iku - 1 , 1 ) ! last and before last ocean level at u- & v-points
  273. ikv = mbkv(ji,jj) ; ikvm1 = MAX( ikv - 1 , 1 ) ! if level first is a p-step, ik.m1=1
  274. ! (ISF) case partial step top and bottom in adjacent cell in vertical
  275. ! cannot used e3w because if 2 cell water column, we have ps at top and bottom
  276. ! in this case e3w(i,j) - e3w(i,j+1) is not the distance between Tj~ and Tj
  277. ! the only common depth between cells (i,j) and (i,j+1) is gdepw_0
  278. ze3wu = (gdept_0(ji+1,jj,iku) - gdepw_0(ji+1,jj,iku)) - (gdept_0(ji,jj,iku) - gdepw_0(ji,jj,iku))
  279. ze3wv = (gdept_0(ji,jj+1,ikv) - gdepw_0(ji,jj+1,ikv)) - (gdept_0(ji,jj,ikv) - gdepw_0(ji,jj,ikv))
  280. !
  281. ! i- direction
  282. IF( ze3wu >= 0._wp ) THEN ! case 1
  283. zmaxu = ze3wu / fse3w(ji+1,jj,iku)
  284. ! interpolated values of tracers
  285. zti (ji,jj,jn) = pta(ji+1,jj,iku,jn) + zmaxu * ( pta(ji+1,jj,ikum1,jn) - pta(ji+1,jj,iku,jn) )
  286. ! gradient of tracers
  287. pgtu(ji,jj,jn) = umask(ji,jj,iku) * ( zti(ji,jj,jn) - pta(ji,jj,iku,jn) )
  288. ELSE ! case 2
  289. zmaxu = -ze3wu / fse3w(ji,jj,iku)
  290. ! interpolated values of tracers
  291. zti (ji,jj,jn) = pta(ji,jj,iku,jn) + zmaxu * ( pta(ji,jj,ikum1,jn) - pta(ji,jj,iku,jn) )
  292. ! gradient of tracers
  293. pgtu(ji,jj,jn) = umask(ji,jj,iku) * ( pta(ji+1,jj,iku,jn) - zti(ji,jj,jn) )
  294. ENDIF
  295. !
  296. ! j- direction
  297. IF( ze3wv >= 0._wp ) THEN ! case 1
  298. zmaxv = ze3wv / fse3w(ji,jj+1,ikv)
  299. ! interpolated values of tracers
  300. ztj (ji,jj,jn) = pta(ji,jj+1,ikv,jn) + zmaxv * ( pta(ji,jj+1,ikvm1,jn) - pta(ji,jj+1,ikv,jn) )
  301. ! gradient of tracers
  302. pgtv(ji,jj,jn) = vmask(ji,jj,ikv) * ( ztj(ji,jj,jn) - pta(ji,jj,ikv,jn) )
  303. ELSE ! case 2
  304. zmaxv = -ze3wv / fse3w(ji,jj,ikv)
  305. ! interpolated values of tracers
  306. ztj (ji,jj,jn) = pta(ji,jj,ikv,jn) + zmaxv * ( pta(ji,jj,ikvm1,jn) - pta(ji,jj,ikv,jn) )
  307. ! gradient of tracers
  308. pgtv(ji,jj,jn) = vmask(ji,jj,ikv) * ( pta(ji,jj+1,ikv,jn) - ztj(ji,jj,jn) )
  309. ENDIF
  310. END DO
  311. END DO
  312. CALL lbc_lnk( pgtu(:,:,jn), 'U', -1. ) ; CALL lbc_lnk( pgtv(:,:,jn), 'V', -1. ) ! Lateral boundary cond.
  313. !
  314. END DO
  315. ! horizontal derivative of density anomalies (rd)
  316. IF( PRESENT( prd ) ) THEN ! depth of the partial step level
  317. pgru(:,:)=0.0_wp ; pgrv(:,:)=0.0_wp ;
  318. pgzu(:,:)=0.0_wp ; pgzv(:,:)=0.0_wp ;
  319. pmru(:,:)=0.0_wp ; pmru(:,:)=0.0_wp ;
  320. pge3ru(:,:)=0.0_wp ; pge3rv(:,:)=0.0_wp ;
  321. DO jj = 1, jpjm1
  322. DO ji = 1, jpim1
  323. iku = mbku(ji,jj)
  324. ikv = mbkv(ji,jj)
  325. ze3wu = (gdept_0(ji+1,jj,iku) - gdepw_0(ji+1,jj,iku)) - (gdept_0(ji,jj,iku) - gdepw_0(ji,jj,iku))
  326. ze3wv = (gdept_0(ji,jj+1,ikv) - gdepw_0(ji,jj+1,ikv)) - (gdept_0(ji,jj,ikv) - gdepw_0(ji,jj,ikv))
  327. IF( ze3wu >= 0._wp ) THEN ; zhi(ji,jj) = fsdept(ji+1,jj,iku) - ze3wu ! i-direction: case 1
  328. ELSE ; zhi(ji,jj) = fsdept(ji ,jj,iku) + ze3wu ! - - case 2
  329. ENDIF
  330. IF( ze3wv >= 0._wp ) THEN ; zhj(ji,jj) = fsdept(ji,jj+1,ikv) - ze3wv ! j-direction: case 1
  331. ELSE ; zhj(ji,jj) = fsdept(ji,jj ,ikv) + ze3wv ! - - case 2
  332. ENDIF
  333. END DO
  334. END DO
  335. ! Compute interpolated rd from zti, ztj for the 2 cases at the depth of the partial
  336. ! step and store it in zri, zrj for each case
  337. CALL eos( zti, zhi, zri )
  338. CALL eos( ztj, zhj, zrj )
  339. ! Gradient of density at the last level
  340. DO jj = 1, jpjm1
  341. DO ji = 1, jpim1
  342. iku = mbku(ji,jj) ; ikum1 = MAX( iku - 1 , 1 ) ! last and before last ocean level at u- & v-points
  343. ikv = mbkv(ji,jj) ; ikvm1 = MAX( ikv - 1 , 1 ) ! last and before last ocean level at u- & v-points
  344. ze3wu = (gdept_0(ji+1,jj,iku) - gdepw_0(ji+1,jj,iku)) - (gdept_0(ji,jj,iku) - gdepw_0(ji,jj,iku))
  345. ze3wv = (gdept_0(ji,jj+1,ikv) - gdepw_0(ji,jj+1,ikv)) - (gdept_0(ji,jj,ikv) - gdepw_0(ji,jj,ikv))
  346. IF( ze3wu >= 0._wp ) THEN
  347. pgzu(ji,jj) = (fsde3w(ji+1,jj,iku) - ze3wu) - fsde3w(ji,jj,iku)
  348. pgru(ji,jj) = umask(ji,jj,iku) * ( zri(ji ,jj) - prd(ji,jj,iku) ) ! i: 1
  349. pmru(ji,jj) = umask(ji,jj,iku) * ( zri(ji ,jj) + prd(ji,jj,iku) ) ! i: 1
  350. pge3ru(ji,jj) = umask(ji,jj,iku) &
  351. * ( (fse3w(ji+1,jj,iku) - ze3wu )* ( zri(ji ,jj ) + prd(ji+1,jj,ikum1) + 2._wp) &
  352. - fse3w(ji ,jj,iku) * ( prd(ji ,jj,iku) + prd(ji ,jj,ikum1) + 2._wp) ) ! j: 2
  353. ELSE
  354. pgzu(ji,jj) = fsde3w(ji+1,jj,iku) - (fsde3w(ji,jj,iku) + ze3wu)
  355. pgru(ji,jj) = umask(ji,jj,iku) * ( prd(ji+1,jj,iku) - zri(ji,jj) ) ! i: 2
  356. pmru(ji,jj) = umask(ji,jj,iku) * ( prd(ji+1,jj,iku) + zri(ji,jj) ) ! i: 2
  357. pge3ru(ji,jj) = umask(ji,jj,iku) &
  358. * ( fse3w(ji+1,jj,iku) * ( prd(ji+1,jj,iku) + prd(ji+1,jj,ikum1) + 2._wp) &
  359. -(fse3w(ji ,jj,iku) + ze3wu) * ( zri(ji ,jj ) + prd(ji ,jj,ikum1) + 2._wp) ) ! j: 2
  360. ENDIF
  361. IF( ze3wv >= 0._wp ) THEN
  362. pgzv(ji,jj) = (fsde3w(ji,jj+1,ikv) - ze3wv) - fsde3w(ji,jj,ikv)
  363. pgrv(ji,jj) = vmask(ji,jj,ikv) * ( zrj(ji,jj ) - prd(ji,jj,ikv) ) ! j: 1
  364. pmrv(ji,jj) = vmask(ji,jj,ikv) * ( zrj(ji,jj ) + prd(ji,jj,ikv) ) ! j: 1
  365. pge3rv(ji,jj) = vmask(ji,jj,ikv) &
  366. * ( (fse3w(ji,jj+1,ikv) - ze3wv )* ( zrj(ji,jj ) + prd(ji,jj+1,ikvm1) + 2._wp) &
  367. - fse3w(ji,jj ,ikv) * ( prd(ji,jj ,ikv) + prd(ji,jj ,ikvm1) + 2._wp) ) ! j: 2
  368. ELSE
  369. pgzv(ji,jj) = fsde3w(ji,jj+1,ikv) - (fsde3w(ji,jj,ikv) + ze3wv)
  370. pgrv(ji,jj) = vmask(ji,jj,ikv) * ( prd(ji,jj+1,ikv) - zrj(ji,jj) ) ! j: 2
  371. pmrv(ji,jj) = vmask(ji,jj,ikv) * ( prd(ji,jj+1,ikv) + zrj(ji,jj) ) ! j: 2
  372. pge3rv(ji,jj) = vmask(ji,jj,ikv) &
  373. * ( fse3w(ji,jj+1,ikv) * ( prd(ji,jj+1,ikv) + prd(ji,jj+1,ikvm1) + 2._wp) &
  374. -(fse3w(ji,jj ,ikv) + ze3wv) * ( zrj(ji,jj ) + prd(ji,jj ,ikvm1) + 2._wp) ) ! j: 2
  375. ENDIF
  376. END DO
  377. END DO
  378. CALL lbc_lnk( pgru , 'U', -1. ) ; CALL lbc_lnk( pgrv , 'V', -1. ) ! Lateral boundary conditions
  379. CALL lbc_lnk( pmru , 'U', 1. ) ; CALL lbc_lnk( pmrv , 'V', 1. ) ! Lateral boundary conditions
  380. CALL lbc_lnk( pgzu , 'U', -1. ) ; CALL lbc_lnk( pgzv , 'V', -1. ) ! Lateral boundary conditions
  381. CALL lbc_lnk( pge3ru , 'U', -1. ) ; CALL lbc_lnk( pge3rv , 'V', -1. ) ! Lateral boundary conditions
  382. !
  383. END IF
  384. ! (ISH) compute grui and gruvi
  385. DO jn = 1, kjpt !== Interpolation of tracers at the last ocean level ==! !
  386. DO jj = 1, jpjm1
  387. DO ji = 1, jpim1
  388. iku = miku(ji,jj) ; ikup1 = miku(ji,jj) + 1
  389. ikv = mikv(ji,jj) ; ikvp1 = mikv(ji,jj) + 1
  390. !
  391. ! (ISF) case partial step top and bottom in adjacent cell in vertical
  392. ! cannot used e3w because if 2 cell water column, we have ps at top and bottom
  393. ! in this case e3w(i,j) - e3w(i,j+1) is not the distance between Tj~ and Tj
  394. ! the only common depth between cells (i,j) and (i,j+1) is gdepw_0
  395. ze3wu = (gdepw_0(ji+1,jj,iku+1) - gdept_0(ji+1,jj,iku)) - (gdepw_0(ji,jj,iku+1) - gdept_0(ji,jj,iku))
  396. ze3wv = (gdepw_0(ji,jj+1,ikv+1) - gdept_0(ji,jj+1,ikv)) - (gdepw_0(ji,jj,ikv+1) - gdept_0(ji,jj,ikv))
  397. ! i- direction
  398. IF( ze3wu >= 0._wp ) THEN ! case 1
  399. zmaxu = ze3wu / fse3w(ji+1,jj,iku+1)
  400. ! interpolated values of tracers
  401. zti(ji,jj,jn) = pta(ji+1,jj,iku,jn) + zmaxu * ( pta(ji+1,jj,iku+1,jn) - pta(ji+1,jj,iku,jn) )
  402. ! gradient of tracers
  403. pgtui(ji,jj,jn) = umask(ji,jj,iku) * ( zti(ji,jj,jn) - pta(ji,jj,iku,jn) )
  404. ELSE ! case 2
  405. zmaxu = - ze3wu / fse3w(ji,jj,iku+1)
  406. ! interpolated values of tracers
  407. zti(ji,jj,jn) = pta(ji,jj,iku,jn) + zmaxu * ( pta(ji,jj,iku+1,jn) - pta(ji,jj,iku,jn) )
  408. ! gradient of tracers
  409. pgtui(ji,jj,jn) = umask(ji,jj,iku) * ( pta(ji+1,jj,iku,jn) - zti(ji,jj,jn) )
  410. ENDIF
  411. !
  412. ! j- direction
  413. IF( ze3wv >= 0._wp ) THEN ! case 1
  414. zmaxv = ze3wv / fse3w(ji,jj+1,ikv+1)
  415. ! interpolated values of tracers
  416. ztj(ji,jj,jn) = pta(ji,jj+1,ikv,jn) + zmaxv * ( pta(ji,jj+1,ikv+1,jn) - pta(ji,jj+1,ikv,jn) )
  417. ! gradient of tracers
  418. pgtvi(ji,jj,jn) = vmask(ji,jj,ikv) * ( ztj(ji,jj,jn) - pta(ji,jj,ikv,jn) )
  419. ELSE ! case 2
  420. zmaxv = - ze3wv / fse3w(ji,jj,ikv+1)
  421. ! interpolated values of tracers
  422. ztj(ji,jj,jn) = pta(ji,jj,ikv,jn) + zmaxv * ( pta(ji,jj,ikv+1,jn) - pta(ji,jj,ikv,jn) )
  423. ! gradient of tracers
  424. pgtvi(ji,jj,jn) = vmask(ji,jj,ikv) * ( pta(ji,jj+1,ikv,jn) - ztj(ji,jj,jn) )
  425. ENDIF
  426. END DO!!
  427. END DO!!
  428. CALL lbc_lnk( pgtui(:,:,jn), 'U', -1. ) ; CALL lbc_lnk( pgtvi(:,:,jn), 'V', -1. ) ! Lateral boundary cond.
  429. !
  430. END DO
  431. ! horizontal derivative of density anomalies (rd)
  432. IF( PRESENT( prd ) ) THEN ! depth of the partial step level
  433. pgrui(:,:) =0.0_wp ; pgrvi(:,:) =0.0_wp ;
  434. pgzui(:,:) =0.0_wp ; pgzvi(:,:) =0.0_wp ;
  435. pmrui(:,:) =0.0_wp ; pmrui(:,:) =0.0_wp ;
  436. pge3rui(:,:)=0.0_wp ; pge3rvi(:,:)=0.0_wp ;
  437. DO jj = 1, jpjm1
  438. DO ji = 1, jpim1
  439. iku = miku(ji,jj)
  440. ikv = mikv(ji,jj)
  441. ze3wu = (gdepw_0(ji+1,jj,iku+1) - gdept_0(ji+1,jj,iku)) - (gdepw_0(ji,jj,iku+1) - gdept_0(ji,jj,iku))
  442. ze3wv = (gdepw_0(ji,jj+1,ikv+1) - gdept_0(ji,jj+1,ikv)) - (gdepw_0(ji,jj,ikv+1) - gdept_0(ji,jj,ikv))
  443. IF( ze3wu >= 0._wp ) THEN ; zhi(ji,jj) = fsdept(ji+1,jj,iku) + ze3wu ! i-direction: case 1
  444. ELSE ; zhi(ji,jj) = fsdept(ji ,jj,iku) - ze3wu ! - - case 2
  445. ENDIF
  446. IF( ze3wv >= 0._wp ) THEN ; zhj(ji,jj) = fsdept(ji,jj+1,ikv) + ze3wv ! j-direction: case 1
  447. ELSE ; zhj(ji,jj) = fsdept(ji,jj ,ikv) - ze3wv ! - - case 2
  448. ENDIF
  449. END DO
  450. END DO
  451. ! Compute interpolated rd from zti, ztj for the 2 cases at the depth of the partial
  452. ! step and store it in zri, zrj for each case
  453. CALL eos( zti, zhi, zri )
  454. CALL eos( ztj, zhj, zrj )
  455. ! Gradient of density at the last level
  456. DO jj = 1, jpjm1
  457. DO ji = 1, jpim1
  458. iku = miku(ji,jj) ; ikup1 = miku(ji,jj) + 1
  459. ikv = mikv(ji,jj) ; ikvp1 = mikv(ji,jj) + 1
  460. ze3wu = (gdepw_0(ji+1,jj,iku+1) - gdept_0(ji+1,jj,iku)) - (gdepw_0(ji,jj,iku+1) - gdept_0(ji,jj,iku))
  461. ze3wv = (gdepw_0(ji,jj+1,ikv+1) - gdept_0(ji,jj+1,ikv)) - (gdepw_0(ji,jj,ikv+1) - gdept_0(ji,jj,ikv))
  462. IF( ze3wu >= 0._wp ) THEN
  463. pgzui (ji,jj) = (fsde3w(ji+1,jj,iku) + ze3wu) - fsde3w(ji,jj,iku)
  464. pgrui (ji,jj) = umask(ji,jj,iku) * ( zri(ji,jj) - prd(ji,jj,iku) ) ! i: 1
  465. pmrui (ji,jj) = umask(ji,jj,iku) * ( zri(ji,jj) + prd(ji,jj,iku) ) ! i: 1
  466. pge3rui(ji,jj) = umask(ji,jj,iku+1) &
  467. * ( (fse3w(ji+1,jj,iku+1) - ze3wu) * (zri(ji,jj ) + prd(ji+1,jj,iku+1) + 2._wp) &
  468. - fse3w(ji ,jj,iku+1) * (prd(ji,jj,iku) + prd(ji ,jj,iku+1) + 2._wp) ) ! i: 1
  469. ELSE
  470. pgzui (ji,jj) = fsde3w(ji+1,jj,iku) - (fsde3w(ji,jj,iku) - ze3wu)
  471. pgrui (ji,jj) = umask(ji,jj,iku) * ( prd(ji+1,jj,iku) - zri(ji,jj) ) ! i: 2
  472. pmrui (ji,jj) = umask(ji,jj,iku) * ( prd(ji+1,jj,iku) + zri(ji,jj) ) ! i: 2
  473. pge3rui(ji,jj) = umask(ji,jj,iku+1) &
  474. * ( fse3w(ji+1,jj,iku+1) * (prd(ji+1,jj,iku) + prd(ji+1,jj,iku+1) + 2._wp) &
  475. -(fse3w(ji ,jj,iku+1) + ze3wu) * (zri(ji,jj ) + prd(ji ,jj,iku+1) + 2._wp) ) ! i: 2
  476. ENDIF
  477. IF( ze3wv >= 0._wp ) THEN
  478. pgzvi (ji,jj) = (fsde3w(ji,jj+1,ikv) + ze3wv) - fsde3w(ji,jj,ikv)
  479. pgrvi (ji,jj) = vmask(ji,jj,ikv) * ( zrj(ji,jj ) - prd(ji,jj,ikv) ) ! j: 1
  480. pmrvi (ji,jj) = vmask(ji,jj,ikv) * ( zrj(ji,jj ) + prd(ji,jj,ikv) ) ! j: 1
  481. pge3rvi(ji,jj) = vmask(ji,jj,ikv+1) &
  482. * ( (fse3w(ji,jj+1,ikv+1) - ze3wv) * ( zrj(ji,jj ) + prd(ji,jj+1,ikv+1) + 2._wp) &
  483. - fse3w(ji,jj ,ikv+1) * ( prd(ji,jj,ikv) + prd(ji,jj ,ikv+1) + 2._wp) ) ! j: 1
  484. ! + 2 due to the formulation in density and not in anomalie in hpg sco
  485. ELSE
  486. pgzvi (ji,jj) = fsde3w(ji,jj+1,ikv) - (fsde3w(ji,jj,ikv) - ze3wv)
  487. pgrvi (ji,jj) = vmask(ji,jj,ikv) * ( prd(ji,jj+1,ikv) - zrj(ji,jj) ) ! j: 2
  488. pmrvi (ji,jj) = vmask(ji,jj,ikv) * ( prd(ji,jj+1,ikv) + zrj(ji,jj) ) ! j: 2
  489. pge3rvi(ji,jj) = vmask(ji,jj,ikv+1) &
  490. * ( fse3w(ji,jj+1,ikv+1) * ( prd(ji,jj+1,ikv) + prd(ji,jj+1,ikv+1) + 2._wp) &
  491. -(fse3w(ji,jj ,ikv+1) + ze3wv) * ( zrj(ji,jj ) + prd(ji,jj ,ikv+1) + 2._wp) ) ! j: 2
  492. ENDIF
  493. END DO
  494. END DO
  495. CALL lbc_lnk( pgrui , 'U', -1. ) ; CALL lbc_lnk( pgrvi , 'V', -1. ) ! Lateral boundary conditions
  496. CALL lbc_lnk( pmrui , 'U', 1. ) ; CALL lbc_lnk( pmrvi , 'V', 1. ) ! Lateral boundary conditions
  497. CALL lbc_lnk( pgzui , 'U', -1. ) ; CALL lbc_lnk( pgzvi , 'V', -1. ) ! Lateral boundary conditions
  498. CALL lbc_lnk( pge3rui , 'U', -1. ) ; CALL lbc_lnk( pge3rvi , 'V', -1. ) ! Lateral boundary conditions
  499. !
  500. END IF
  501. !
  502. IF( nn_timing == 1 ) CALL timing_stop( 'zps_hde_isf')
  503. !
  504. END SUBROUTINE zps_hde_isf
  505. !!======================================================================
  506. END MODULE zpshde