dynspg_ts.F90 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198
  1. MODULE dynspg_ts
  2. !!======================================================================
  3. !! History : 1.0 ! 2004-12 (L. Bessieres, G. Madec) Original code
  4. !! - ! 2005-11 (V. Garnier, G. Madec) optimization
  5. !! - ! 2006-08 (S. Masson) distributed restart using iom
  6. !! 2.0 ! 2007-07 (D. Storkey) calls to BDY routines
  7. !! - ! 2008-01 (R. Benshila) change averaging method
  8. !! 3.2 ! 2009-07 (R. Benshila, G. Madec) Complete revisit associated to vvl reactivation
  9. !! 3.3 ! 2010-09 (D. Storkey, E. O'Dea) update for BDY for Shelf configurations
  10. !! 3.3 ! 2011-03 (R. Benshila, R. Hordoir, P. Oddo) update calculation of ub_b
  11. !! 3.5 ! 2013-07 (J. Chanut) Switch to Forward-backward time stepping
  12. !! 3.6 ! 2013-11 (A. Coward) Update for z-tilde compatibility
  13. !!---------------------------------------------------------------------
  14. #if defined key_dynspg_ts || defined key_esopa
  15. !!----------------------------------------------------------------------
  16. !! 'key_dynspg_ts' split explicit free surface
  17. !!----------------------------------------------------------------------
  18. !! dyn_spg_ts : compute surface pressure gradient trend using a time-
  19. !! splitting scheme and add to the general trend
  20. !!----------------------------------------------------------------------
  21. USE oce ! ocean dynamics and tracers
  22. USE dom_oce ! ocean space and time domain
  23. USE sbc_oce ! surface boundary condition: ocean
  24. USE sbcisf ! ice shelf variable (fwfisf)
  25. USE dynspg_oce ! surface pressure gradient variables
  26. USE phycst ! physical constants
  27. USE dynvor ! vorticity term
  28. USE bdy_par ! for lk_bdy
  29. USE bdytides ! open boundary condition data
  30. USE bdydyn2d ! open boundary conditions on barotropic variables
  31. USE sbctide ! tides
  32. USE updtide ! tide potential
  33. USE lib_mpp ! distributed memory computing library
  34. USE lbclnk ! ocean lateral boundary conditions (or mpp link)
  35. USE prtctl ! Print control
  36. USE in_out_manager ! I/O manager
  37. USE iom ! IOM library
  38. USE restart ! only for lrst_oce
  39. USE zdf_oce ! Bottom friction coefts
  40. USE wrk_nemo ! Memory Allocation
  41. USE timing ! Timing
  42. USE sbcapr ! surface boundary condition: atmospheric pressure
  43. USE dynadv, ONLY: ln_dynadv_vec
  44. #if defined key_agrif
  45. USE agrif_opa_interp ! agrif
  46. #endif
  47. #if defined key_asminc
  48. USE asminc ! Assimilation increment
  49. #endif
  50. IMPLICIT NONE
  51. PRIVATE
  52. PUBLIC dyn_spg_ts ! routine called in dynspg.F90
  53. PUBLIC dyn_spg_ts_alloc ! " " " "
  54. PUBLIC dyn_spg_ts_init ! " " " "
  55. PUBLIC ts_rst ! " " " "
  56. INTEGER, SAVE :: icycle ! Number of barotropic sub-steps for each internal step nn_baro <= 2.5 nn_baro
  57. REAL(wp),SAVE :: rdtbt ! Barotropic time step
  58. REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:) :: &
  59. wgtbtp1, & ! Primary weights used for time filtering of barotropic variables
  60. wgtbtp2 ! Secondary weights used for time filtering of barotropic variables
  61. REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) :: zwz ! ff/h at F points
  62. REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) :: ftnw, ftne ! triad of coriolis parameter
  63. REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) :: ftsw, ftse ! (only used with een vorticity scheme)
  64. ! Arrays below are saved to allow testing of the "no time averaging" option
  65. ! If this option is not retained, these could be replaced by temporary arrays
  66. REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) :: sshbb_e, sshb_e, & ! Instantaneous barotropic arrays
  67. ubb_e, ub_e, &
  68. vbb_e, vb_e
  69. !! * Substitutions
  70. # include "domzgr_substitute.h90"
  71. # include "vectopt_loop_substitute.h90"
  72. !!----------------------------------------------------------------------
  73. !! NEMO/OPA 3.5 , NEMO Consortium (2013)
  74. !! $Id: dynspg_ts.F90 5628 2015-07-22 20:26:35Z mathiot $
  75. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  76. !!----------------------------------------------------------------------
  77. CONTAINS
  78. INTEGER FUNCTION dyn_spg_ts_alloc()
  79. !!----------------------------------------------------------------------
  80. !! *** routine dyn_spg_ts_alloc ***
  81. !!----------------------------------------------------------------------
  82. INTEGER :: ierr(3)
  83. !!----------------------------------------------------------------------
  84. ierr(:) = 0
  85. ALLOCATE( sshb_e(jpi,jpj), sshbb_e(jpi,jpj), &
  86. & ub_e(jpi,jpj) , vb_e(jpi,jpj) , &
  87. & ubb_e(jpi,jpj) , vbb_e(jpi,jpj) , STAT= ierr(1) )
  88. ALLOCATE( wgtbtp1(3*nn_baro), wgtbtp2(3*nn_baro), zwz(jpi,jpj), STAT= ierr(2) )
  89. IF( ln_dynvor_een .or. ln_dynvor_een_old ) ALLOCATE( ftnw(jpi,jpj) , ftne(jpi,jpj) , &
  90. & ftsw(jpi,jpj) , ftse(jpi,jpj) , STAT=ierr(3) )
  91. dyn_spg_ts_alloc = MAXVAL(ierr(:))
  92. IF( lk_mpp ) CALL mpp_sum( dyn_spg_ts_alloc )
  93. IF( dyn_spg_ts_alloc /= 0 ) CALL ctl_warn('dynspg_oce_alloc: failed to allocate arrays')
  94. !
  95. END FUNCTION dyn_spg_ts_alloc
  96. SUBROUTINE dyn_spg_ts( kt )
  97. !!----------------------------------------------------------------------
  98. !!
  99. !! ** Purpose :
  100. !! -Compute the now trend due to the explicit time stepping
  101. !! of the quasi-linear barotropic system.
  102. !!
  103. !! ** Method :
  104. !! Barotropic variables are advanced from internal time steps
  105. !! "n" to "n+1" if ln_bt_fw=T
  106. !! or from
  107. !! "n-1" to "n+1" if ln_bt_fw=F
  108. !! thanks to a generalized forward-backward time stepping (see ref. below).
  109. !!
  110. !! ** Action :
  111. !! -Update the filtered free surface at step "n+1" : ssha
  112. !! -Update filtered barotropic velocities at step "n+1" : ua_b, va_b
  113. !! -Compute barotropic advective velocities at step "n" : un_adv, vn_adv
  114. !! These are used to advect tracers and are compliant with discrete
  115. !! continuity equation taken at the baroclinic time steps. This
  116. !! ensures tracers conservation.
  117. !! -Update 3d trend (ua, va) with barotropic component.
  118. !!
  119. !! References : Shchepetkin, A.F. and J.C. McWilliams, 2005:
  120. !! The regional oceanic modeling system (ROMS):
  121. !! a split-explicit, free-surface,
  122. !! topography-following-coordinate oceanic model.
  123. !! Ocean Modelling, 9, 347-404.
  124. !!---------------------------------------------------------------------
  125. !
  126. INTEGER, INTENT(in) :: kt ! ocean time-step index
  127. !
  128. LOGICAL :: ll_fw_start ! if true, forward integration
  129. LOGICAL :: ll_init ! if true, special startup of 2d equations
  130. INTEGER :: ji, jj, jk, jn ! dummy loop indices
  131. INTEGER :: ikbu, ikbv, noffset ! local integers
  132. REAL(wp) :: zraur, z1_2dt_b, z2dt_bf ! local scalars
  133. REAL(wp) :: zx1, zy1, zx2, zy2 ! - -
  134. REAL(wp) :: z1_12, z1_8, z1_4, z1_2 ! - -
  135. REAL(wp) :: zu_spg, zv_spg ! - -
  136. REAL(wp) :: zhura, zhvra ! - -
  137. REAL(wp) :: za0, za1, za2, za3 ! - -
  138. !
  139. REAL(wp), POINTER, DIMENSION(:,:) :: zun_e, zvn_e, zsshp2_e
  140. REAL(wp), POINTER, DIMENSION(:,:) :: zu_trd, zv_trd, zu_frc, zv_frc, zssh_frc
  141. REAL(wp), POINTER, DIMENSION(:,:) :: zu_sum, zv_sum, zwx, zwy, zhdiv
  142. REAL(wp), POINTER, DIMENSION(:,:) :: zhup2_e, zhvp2_e, zhust_e, zhvst_e
  143. REAL(wp), POINTER, DIMENSION(:,:) :: zsshu_a, zsshv_a
  144. REAL(wp), POINTER, DIMENSION(:,:) :: zhf
  145. !!----------------------------------------------------------------------
  146. !
  147. IF( nn_timing == 1 ) CALL timing_start('dyn_spg_ts')
  148. !
  149. ! !* Allocate temporary arrays
  150. CALL wrk_alloc( jpi, jpj, zsshp2_e, zhdiv )
  151. CALL wrk_alloc( jpi, jpj, zu_trd, zv_trd, zun_e, zvn_e )
  152. CALL wrk_alloc( jpi, jpj, zwx, zwy, zu_sum, zv_sum, zssh_frc, zu_frc, zv_frc)
  153. CALL wrk_alloc( jpi, jpj, zhup2_e, zhvp2_e, zhust_e, zhvst_e)
  154. CALL wrk_alloc( jpi, jpj, zsshu_a, zsshv_a )
  155. CALL wrk_alloc( jpi, jpj, zhf )
  156. !
  157. ! !* Local constant initialization
  158. z1_12 = 1._wp / 12._wp
  159. z1_8 = 0.125_wp
  160. z1_4 = 0.25_wp
  161. z1_2 = 0.5_wp
  162. zraur = 1._wp / rau0
  163. !
  164. IF( kt == nit000 .AND. neuler == 0 ) THEN ! reciprocal of baroclinic time step
  165. z2dt_bf = rdt
  166. ELSE
  167. z2dt_bf = 2.0_wp * rdt
  168. ENDIF
  169. z1_2dt_b = 1.0_wp / z2dt_bf
  170. !
  171. ll_init = ln_bt_av ! if no time averaging, then no specific restart
  172. ll_fw_start = .FALSE.
  173. !
  174. ! time offset in steps for bdy data update
  175. IF (.NOT.ln_bt_fw) THEN ; noffset=-nn_baro ; ELSE ; noffset = 0 ; ENDIF
  176. !
  177. IF( kt == nit000 ) THEN !* initialisation
  178. !
  179. IF(lwp) WRITE(numout,*)
  180. IF(lwp) WRITE(numout,*) 'dyn_spg_ts : surface pressure gradient trend'
  181. IF(lwp) WRITE(numout,*) '~~~~~~~~~~ free surface with time splitting'
  182. IF(lwp) WRITE(numout,*)
  183. !
  184. IF (neuler==0) ll_init=.TRUE.
  185. !
  186. IF (ln_bt_fw.OR.(neuler==0)) THEN
  187. ll_fw_start=.TRUE.
  188. noffset = 0
  189. ELSE
  190. ll_fw_start=.FALSE.
  191. ENDIF
  192. !
  193. ! Set averaging weights and cycle length:
  194. CALL ts_wgt(ln_bt_av, ll_fw_start, icycle, wgtbtp1, wgtbtp2)
  195. !
  196. !
  197. ENDIF
  198. !
  199. ! Set arrays to remove/compute coriolis trend.
  200. ! Do it once at kt=nit000 if volume is fixed, else at each long time step.
  201. ! Note that these arrays are also used during barotropic loop. These are however frozen
  202. ! although they should be updated in the variable volume case. Not a big approximation.
  203. ! To remove this approximation, copy lines below inside barotropic loop
  204. ! and update depths at T-F points (ht and zhf resp.) at each barotropic time step
  205. !
  206. IF ( kt == nit000 .OR. lk_vvl ) THEN
  207. IF ( ln_dynvor_een_old ) THEN
  208. DO jj = 1, jpjm1
  209. DO ji = 1, jpim1
  210. zwz(ji,jj) = ( ht(ji ,jj+1) + ht(ji+1,jj+1) + &
  211. & ht(ji ,jj ) + ht(ji+1,jj ) ) / 4._wp
  212. IF( zwz(ji,jj) /= 0._wp ) zwz(ji,jj) = 1._wp / zwz(ji,jj)
  213. END DO
  214. END DO
  215. CALL lbc_lnk( zwz, 'F', 1._wp )
  216. zwz(:,:) = ff(:,:) * zwz(:,:)
  217. ftne(1,:) = 0._wp ; ftnw(1,:) = 0._wp ; ftse(1,:) = 0._wp ; ftsw(1,:) = 0._wp
  218. DO jj = 2, jpj
  219. DO ji = fs_2, jpi ! vector opt.
  220. ftne(ji,jj) = zwz(ji-1,jj ) + zwz(ji ,jj ) + zwz(ji ,jj-1)
  221. ftnw(ji,jj) = zwz(ji-1,jj-1) + zwz(ji-1,jj ) + zwz(ji ,jj )
  222. ftse(ji,jj) = zwz(ji ,jj ) + zwz(ji ,jj-1) + zwz(ji-1,jj-1)
  223. ftsw(ji,jj) = zwz(ji ,jj-1) + zwz(ji-1,jj-1) + zwz(ji-1,jj )
  224. END DO
  225. END DO
  226. ELSE IF ( ln_dynvor_een ) THEN
  227. DO jj = 1, jpjm1
  228. DO ji = 1, jpim1
  229. zwz(ji,jj) = ( ht(ji ,jj+1) + ht(ji+1,jj+1) + &
  230. & ht(ji ,jj ) + ht(ji+1,jj ) ) &
  231. & / ( MAX( 1.0_wp, tmask(ji ,jj+1, 1) + tmask(ji+1,jj+1, 1) + &
  232. & tmask(ji ,jj , 1) + tmask(ji+1,jj , 1) ) )
  233. IF( zwz(ji,jj) /= 0._wp ) zwz(ji,jj) = 1._wp / zwz(ji,jj)
  234. END DO
  235. END DO
  236. CALL lbc_lnk( zwz, 'F', 1._wp )
  237. zwz(:,:) = ff(:,:) * zwz(:,:)
  238. ftne(1,:) = 0._wp ; ftnw(1,:) = 0._wp ; ftse(1,:) = 0._wp ; ftsw(1,:) = 0._wp
  239. DO jj = 2, jpj
  240. DO ji = fs_2, jpi ! vector opt.
  241. ftne(ji,jj) = zwz(ji-1,jj ) + zwz(ji ,jj ) + zwz(ji ,jj-1)
  242. ftnw(ji,jj) = zwz(ji-1,jj-1) + zwz(ji-1,jj ) + zwz(ji ,jj )
  243. ftse(ji,jj) = zwz(ji ,jj ) + zwz(ji ,jj-1) + zwz(ji-1,jj-1)
  244. ftsw(ji,jj) = zwz(ji ,jj-1) + zwz(ji-1,jj-1) + zwz(ji-1,jj )
  245. END DO
  246. END DO
  247. ELSE
  248. zwz(:,:) = 0._wp
  249. zhf(:,:) = 0.
  250. IF ( .not. ln_sco ) THEN
  251. ! JC: It not clear yet what should be the depth at f-points over land in z-coordinate case
  252. ! Set it to zero for the time being
  253. ! IF( rn_hmin < 0._wp ) THEN ; jk = - INT( rn_hmin ) ! from a nb of level
  254. ! ELSE ; jk = MINLOC( gdepw_0, mask = gdepw_0 > rn_hmin, dim = 1 ) ! from a depth
  255. ! ENDIF
  256. ! zhf(:,:) = gdepw_0(:,:,jk+1)
  257. ELSE
  258. zhf(:,:) = hbatf(:,:)
  259. END IF
  260. DO jj = 1, jpjm1
  261. zhf(:,jj) = zhf(:,jj)*(1._wp- umask(:,jj,1) * umask(:,jj+1,1))
  262. END DO
  263. DO jk = 1, jpkm1
  264. DO jj = 1, jpjm1
  265. zhf(:,jj) = zhf(:,jj) + fse3f_n(:,jj,jk) * umask(:,jj,jk) * umask(:,jj+1,jk)
  266. END DO
  267. END DO
  268. CALL lbc_lnk( zhf, 'F', 1._wp )
  269. ! JC: TBC. hf should be greater than 0
  270. DO jj = 1, jpj
  271. DO ji = 1, jpi
  272. IF( zhf(ji,jj) /= 0._wp ) zwz(ji,jj) = 1._wp / zhf(ji,jj) ! zhf is actually hf here but it saves an array
  273. END DO
  274. END DO
  275. zwz(:,:) = ff(:,:) * zwz(:,:)
  276. ENDIF
  277. ENDIF
  278. !
  279. ! If forward start at previous time step, and centered integration,
  280. ! then update averaging weights:
  281. IF ((.NOT.ln_bt_fw).AND.((neuler==0).AND.(kt==nit000+1))) THEN
  282. ll_fw_start=.FALSE.
  283. CALL ts_wgt(ln_bt_av, ll_fw_start, icycle, wgtbtp1, wgtbtp2)
  284. ENDIF
  285. ! -----------------------------------------------------------------------------
  286. ! Phase 1 : Coupling between general trend and barotropic estimates (1st step)
  287. ! -----------------------------------------------------------------------------
  288. !
  289. !
  290. ! !* e3*d/dt(Ua) (Vertically integrated)
  291. ! ! --------------------------------------------------
  292. zu_frc(:,:) = 0._wp
  293. zv_frc(:,:) = 0._wp
  294. !
  295. DO jk = 1, jpkm1
  296. zu_frc(:,:) = zu_frc(:,:) + fse3u_n(:,:,jk) * ua(:,:,jk) * umask(:,:,jk)
  297. zv_frc(:,:) = zv_frc(:,:) + fse3v_n(:,:,jk) * va(:,:,jk) * vmask(:,:,jk)
  298. END DO
  299. !
  300. zu_frc(:,:) = zu_frc(:,:) * hur(:,:)
  301. zv_frc(:,:) = zv_frc(:,:) * hvr(:,:)
  302. !
  303. !
  304. ! !* baroclinic momentum trend (remove the vertical mean trend)
  305. DO jk = 1, jpkm1 ! -----------------------------------------------------------
  306. DO jj = 2, jpjm1
  307. DO ji = fs_2, fs_jpim1 ! vector opt.
  308. ua(ji,jj,jk) = ua(ji,jj,jk) - zu_frc(ji,jj) * umask(ji,jj,jk)
  309. va(ji,jj,jk) = va(ji,jj,jk) - zv_frc(ji,jj) * vmask(ji,jj,jk)
  310. END DO
  311. END DO
  312. END DO
  313. ! !* barotropic Coriolis trends (vorticity scheme dependent)
  314. ! ! --------------------------------------------------------
  315. zwx(:,:) = un_b(:,:) * hu(:,:) * e2u(:,:) ! now fluxes
  316. zwy(:,:) = vn_b(:,:) * hv(:,:) * e1v(:,:)
  317. !
  318. IF( ln_dynvor_ene .OR. ln_dynvor_mix ) THEN ! energy conserving or mixed scheme
  319. DO jj = 2, jpjm1
  320. DO ji = fs_2, fs_jpim1 ! vector opt.
  321. zy1 = ( zwy(ji,jj-1) + zwy(ji+1,jj-1) ) / e1u(ji,jj)
  322. zy2 = ( zwy(ji,jj ) + zwy(ji+1,jj ) ) / e1u(ji,jj)
  323. zx1 = ( zwx(ji-1,jj) + zwx(ji-1,jj+1) ) / e2v(ji,jj)
  324. zx2 = ( zwx(ji ,jj) + zwx(ji ,jj+1) ) / e2v(ji,jj)
  325. ! energy conserving formulation for planetary vorticity term
  326. zu_trd(ji,jj) = z1_4 * ( zwz(ji ,jj-1) * zy1 + zwz(ji,jj) * zy2 )
  327. zv_trd(ji,jj) =-z1_4 * ( zwz(ji-1,jj ) * zx1 + zwz(ji,jj) * zx2 )
  328. END DO
  329. END DO
  330. !
  331. ELSEIF ( ln_dynvor_ens ) THEN ! enstrophy conserving scheme
  332. DO jj = 2, jpjm1
  333. DO ji = fs_2, fs_jpim1 ! vector opt.
  334. zy1 = z1_8 * ( zwy(ji ,jj-1) + zwy(ji+1,jj-1) &
  335. & + zwy(ji ,jj ) + zwy(ji+1,jj ) ) / e1u(ji,jj)
  336. zx1 = - z1_8 * ( zwx(ji-1,jj ) + zwx(ji-1,jj+1) &
  337. & + zwx(ji ,jj ) + zwx(ji ,jj+1) ) / e2v(ji,jj)
  338. zu_trd(ji,jj) = zy1 * ( zwz(ji ,jj-1) + zwz(ji,jj) )
  339. zv_trd(ji,jj) = zx1 * ( zwz(ji-1,jj ) + zwz(ji,jj) )
  340. END DO
  341. END DO
  342. !
  343. ELSEIF ( ln_dynvor_een .or. ln_dynvor_een_old ) THEN ! enstrophy and energy conserving scheme
  344. DO jj = 2, jpjm1
  345. DO ji = fs_2, fs_jpim1 ! vector opt.
  346. zu_trd(ji,jj) = + z1_12 / e1u(ji,jj) * ( ftne(ji,jj ) * zwy(ji ,jj ) &
  347. & + ftnw(ji+1,jj) * zwy(ji+1,jj ) &
  348. & + ftse(ji,jj ) * zwy(ji ,jj-1) &
  349. & + ftsw(ji+1,jj) * zwy(ji+1,jj-1) )
  350. zv_trd(ji,jj) = - z1_12 / e2v(ji,jj) * ( ftsw(ji,jj+1) * zwx(ji-1,jj+1) &
  351. & + ftse(ji,jj+1) * zwx(ji ,jj+1) &
  352. & + ftnw(ji,jj ) * zwx(ji-1,jj ) &
  353. & + ftne(ji,jj ) * zwx(ji ,jj ) )
  354. END DO
  355. END DO
  356. !
  357. ENDIF
  358. !
  359. ! !* Right-Hand-Side of the barotropic momentum equation
  360. ! ! ----------------------------------------------------
  361. IF( lk_vvl ) THEN ! Variable volume : remove surface pressure gradient
  362. DO jj = 2, jpjm1
  363. DO ji = fs_2, fs_jpim1 ! vector opt.
  364. zu_trd(ji,jj) = zu_trd(ji,jj) - grav * ( sshn(ji+1,jj ) - sshn(ji ,jj ) ) / e1u(ji,jj)
  365. zv_trd(ji,jj) = zv_trd(ji,jj) - grav * ( sshn(ji ,jj+1) - sshn(ji ,jj ) ) / e2v(ji,jj)
  366. END DO
  367. END DO
  368. ENDIF
  369. DO jj = 2, jpjm1 ! Remove coriolis term (and possibly spg) from barotropic trend
  370. DO ji = fs_2, fs_jpim1
  371. zu_frc(ji,jj) = zu_frc(ji,jj) - zu_trd(ji,jj) * umask(ji,jj,1)
  372. zv_frc(ji,jj) = zv_frc(ji,jj) - zv_trd(ji,jj) * vmask(ji,jj,1)
  373. END DO
  374. END DO
  375. !
  376. ! ! Add bottom stress contribution from baroclinic velocities:
  377. IF (ln_bt_fw) THEN
  378. DO jj = 2, jpjm1
  379. DO ji = fs_2, fs_jpim1 ! vector opt.
  380. ikbu = mbku(ji,jj)
  381. ikbv = mbkv(ji,jj)
  382. zwx(ji,jj) = un(ji,jj,ikbu) - un_b(ji,jj) ! NOW bottom baroclinic velocities
  383. zwy(ji,jj) = vn(ji,jj,ikbv) - vn_b(ji,jj)
  384. END DO
  385. END DO
  386. ELSE
  387. DO jj = 2, jpjm1
  388. DO ji = fs_2, fs_jpim1 ! vector opt.
  389. ikbu = mbku(ji,jj)
  390. ikbv = mbkv(ji,jj)
  391. zwx(ji,jj) = ub(ji,jj,ikbu) - ub_b(ji,jj) ! BEFORE bottom baroclinic velocities
  392. zwy(ji,jj) = vb(ji,jj,ikbv) - vb_b(ji,jj)
  393. END DO
  394. END DO
  395. ENDIF
  396. !
  397. ! Note that the "unclipped" bottom friction parameter is used even with explicit drag
  398. zu_frc(:,:) = zu_frc(:,:) + hur(:,:) * bfrua(:,:) * zwx(:,:)
  399. zv_frc(:,:) = zv_frc(:,:) + hvr(:,:) * bfrva(:,:) * zwy(:,:)
  400. !
  401. IF (ln_bt_fw) THEN ! Add wind forcing
  402. zu_frc(:,:) = zu_frc(:,:) + zraur * utau(:,:) * hur(:,:)
  403. zv_frc(:,:) = zv_frc(:,:) + zraur * vtau(:,:) * hvr(:,:)
  404. ELSE
  405. zu_frc(:,:) = zu_frc(:,:) + zraur * z1_2 * ( utau_b(:,:) + utau(:,:) ) * hur(:,:)
  406. zv_frc(:,:) = zv_frc(:,:) + zraur * z1_2 * ( vtau_b(:,:) + vtau(:,:) ) * hvr(:,:)
  407. ENDIF
  408. !
  409. IF ( ln_apr_dyn ) THEN ! Add atm pressure forcing
  410. IF (ln_bt_fw) THEN
  411. DO jj = 2, jpjm1
  412. DO ji = fs_2, fs_jpim1 ! vector opt.
  413. zu_spg = grav * ( ssh_ib (ji+1,jj ) - ssh_ib (ji,jj) ) /e1u(ji,jj)
  414. zv_spg = grav * ( ssh_ib (ji ,jj+1) - ssh_ib (ji,jj) ) /e2v(ji,jj)
  415. zu_frc(ji,jj) = zu_frc(ji,jj) + zu_spg
  416. zv_frc(ji,jj) = zv_frc(ji,jj) + zv_spg
  417. END DO
  418. END DO
  419. ELSE
  420. DO jj = 2, jpjm1
  421. DO ji = fs_2, fs_jpim1 ! vector opt.
  422. zu_spg = grav * z1_2 * ( ssh_ib (ji+1,jj ) - ssh_ib (ji,jj) &
  423. & + ssh_ibb(ji+1,jj ) - ssh_ibb(ji,jj) ) /e1u(ji,jj)
  424. zv_spg = grav * z1_2 * ( ssh_ib (ji ,jj+1) - ssh_ib (ji,jj) &
  425. & + ssh_ibb(ji ,jj+1) - ssh_ibb(ji,jj) ) /e2v(ji,jj)
  426. zu_frc(ji,jj) = zu_frc(ji,jj) + zu_spg
  427. zv_frc(ji,jj) = zv_frc(ji,jj) + zv_spg
  428. END DO
  429. END DO
  430. ENDIF
  431. ENDIF
  432. ! !* Right-Hand-Side of the barotropic ssh equation
  433. ! ! -----------------------------------------------
  434. ! ! Surface net water flux and rivers
  435. IF (ln_bt_fw) THEN
  436. zssh_frc(:,:) = zraur * ( emp(:,:) - rnf(:,:) + fwfisf(:,:) )
  437. ELSE
  438. zssh_frc(:,:) = zraur * z1_2 * ( emp(:,:) + emp_b(:,:) - rnf(:,:) - rnf_b(:,:) &
  439. & + fwfisf(:,:) + fwfisf_b(:,:) )
  440. ENDIF
  441. #if defined key_asminc
  442. ! ! Include the IAU weighted SSH increment
  443. IF( lk_asminc .AND. ln_sshinc .AND. ln_asmiau ) THEN
  444. zssh_frc(:,:) = zssh_frc(:,:) - ssh_iau(:,:)
  445. ENDIF
  446. #endif
  447. ! !* Fill boundary data arrays for AGRIF
  448. ! ! ------------------------------------
  449. #if defined key_agrif
  450. IF( .NOT.Agrif_Root() ) CALL agrif_dta_ts( kt )
  451. #endif
  452. !
  453. ! -----------------------------------------------------------------------
  454. ! Phase 2 : Integration of the barotropic equations
  455. ! -----------------------------------------------------------------------
  456. !
  457. ! ! ==================== !
  458. ! ! Initialisations !
  459. ! ! ==================== !
  460. ! Initialize barotropic variables:
  461. IF( ll_init )THEN
  462. sshbb_e(:,:) = 0._wp
  463. ubb_e (:,:) = 0._wp
  464. vbb_e (:,:) = 0._wp
  465. sshb_e (:,:) = 0._wp
  466. ub_e (:,:) = 0._wp
  467. vb_e (:,:) = 0._wp
  468. ENDIF
  469. !
  470. IF (ln_bt_fw) THEN ! FORWARD integration: start from NOW fields
  471. sshn_e(:,:) = sshn (:,:)
  472. zun_e (:,:) = un_b (:,:)
  473. zvn_e (:,:) = vn_b (:,:)
  474. !
  475. hu_e (:,:) = hu (:,:)
  476. hv_e (:,:) = hv (:,:)
  477. hur_e (:,:) = hur (:,:)
  478. hvr_e (:,:) = hvr (:,:)
  479. ELSE ! CENTRED integration: start from BEFORE fields
  480. sshn_e(:,:) = sshb (:,:)
  481. zun_e (:,:) = ub_b (:,:)
  482. zvn_e (:,:) = vb_b (:,:)
  483. !
  484. hu_e (:,:) = hu_b (:,:)
  485. hv_e (:,:) = hv_b (:,:)
  486. hur_e (:,:) = hur_b(:,:)
  487. hvr_e (:,:) = hvr_b(:,:)
  488. ENDIF
  489. !
  490. !
  491. !
  492. ! Initialize sums:
  493. ua_b (:,:) = 0._wp ! After barotropic velocities (or transport if flux form)
  494. va_b (:,:) = 0._wp
  495. ssha (:,:) = 0._wp ! Sum for after averaged sea level
  496. zu_sum(:,:) = 0._wp ! Sum for now transport issued from ts loop
  497. zv_sum(:,:) = 0._wp
  498. ! ! ==================== !
  499. DO jn = 1, icycle ! sub-time-step loop !
  500. ! ! ==================== !
  501. ! !* Update the forcing (BDY and tides)
  502. ! ! ------------------
  503. ! Update only tidal forcing at open boundaries
  504. #if defined key_tide
  505. IF ( lk_bdy .AND. lk_tide ) CALL bdy_dta_tides( kt, kit=jn, time_offset=(noffset+1) )
  506. IF ( ln_tide_pot .AND. lk_tide ) CALL upd_tide( kt, kit=jn, time_offset=noffset )
  507. #endif
  508. !
  509. ! Set extrapolation coefficients for predictor step:
  510. IF ((jn<3).AND.ll_init) THEN ! Forward
  511. za1 = 1._wp
  512. za2 = 0._wp
  513. za3 = 0._wp
  514. ELSE ! AB3-AM4 Coefficients: bet=0.281105
  515. za1 = 1.781105_wp ! za1 = 3/2 + bet
  516. za2 = -1.06221_wp ! za2 = -(1/2 + 2*bet)
  517. za3 = 0.281105_wp ! za3 = bet
  518. ENDIF
  519. ! Extrapolate barotropic velocities at step jit+0.5:
  520. ua_e(:,:) = za1 * zun_e(:,:) + za2 * ub_e(:,:) + za3 * ubb_e(:,:)
  521. va_e(:,:) = za1 * zvn_e(:,:) + za2 * vb_e(:,:) + za3 * vbb_e(:,:)
  522. IF( lk_vvl ) THEN !* Update ocean depth (variable volume case only)
  523. ! ! ------------------
  524. ! Extrapolate Sea Level at step jit+0.5:
  525. zsshp2_e(:,:) = za1 * sshn_e(:,:) + za2 * sshb_e(:,:) + za3 * sshbb_e(:,:)
  526. !
  527. DO jj = 2, jpjm1 ! Sea Surface Height at u- & v-points
  528. DO ji = 2, fs_jpim1 ! Vector opt.
  529. zwx(ji,jj) = z1_2 * umask(ji,jj,1) * r1_e12u(ji,jj) &
  530. & * ( e12t(ji ,jj) * zsshp2_e(ji ,jj) &
  531. & + e12t(ji+1,jj) * zsshp2_e(ji+1,jj) )
  532. zwy(ji,jj) = z1_2 * vmask(ji,jj,1) * r1_e12v(ji,jj) &
  533. & * ( e12t(ji,jj ) * zsshp2_e(ji,jj ) &
  534. & + e12t(ji,jj+1) * zsshp2_e(ji,jj+1) )
  535. END DO
  536. END DO
  537. CALL lbc_lnk_multi( zwx, 'U', 1._wp, zwy, 'V', 1._wp )
  538. !
  539. zhup2_e (:,:) = hu_0(:,:) + zwx(:,:) ! Ocean depth at U- and V-points
  540. zhvp2_e (:,:) = hv_0(:,:) + zwy(:,:)
  541. ELSE
  542. zhup2_e (:,:) = hu(:,:)
  543. zhvp2_e (:,:) = hv(:,:)
  544. ENDIF
  545. ! !* after ssh
  546. ! ! -----------
  547. ! One should enforce volume conservation at open boundaries here
  548. ! considering fluxes below:
  549. !
  550. zwx(:,:) = e2u(:,:) * ua_e(:,:) * zhup2_e(:,:) ! fluxes at jn+0.5
  551. zwy(:,:) = e1v(:,:) * va_e(:,:) * zhvp2_e(:,:)
  552. !
  553. #if defined key_agrif
  554. ! Set fluxes during predictor step to ensure
  555. ! volume conservation
  556. IF( (.NOT.Agrif_Root()).AND.ln_bt_fw ) THEN
  557. IF((nbondi == -1).OR.(nbondi == 2)) THEN
  558. DO jj=1,jpj
  559. zwx(2,jj) = ubdy_w(jj) * e2u(2,jj)
  560. END DO
  561. ENDIF
  562. IF((nbondi == 1).OR.(nbondi == 2)) THEN
  563. DO jj=1,jpj
  564. zwx(nlci-2,jj) = ubdy_e(jj) * e2u(nlci-2,jj)
  565. END DO
  566. ENDIF
  567. IF((nbondj == -1).OR.(nbondj == 2)) THEN
  568. DO ji=1,jpi
  569. zwy(ji,2) = vbdy_s(ji) * e1v(ji,2)
  570. END DO
  571. ENDIF
  572. IF((nbondj == 1).OR.(nbondj == 2)) THEN
  573. DO ji=1,jpi
  574. zwy(ji,nlcj-2) = vbdy_n(ji) * e1v(ji,nlcj-2)
  575. END DO
  576. ENDIF
  577. ENDIF
  578. #endif
  579. !
  580. ! Sum over sub-time-steps to compute advective velocities
  581. za2 = wgtbtp2(jn)
  582. zu_sum (:,:) = zu_sum (:,:) + za2 * zwx (:,:) / e2u (:,:)
  583. zv_sum (:,:) = zv_sum (:,:) + za2 * zwy (:,:) / e1v (:,:)
  584. !
  585. ! Set next sea level:
  586. DO jj = 2, jpjm1
  587. DO ji = fs_2, fs_jpim1 ! vector opt.
  588. zhdiv(ji,jj) = ( zwx(ji,jj) - zwx(ji-1,jj) &
  589. & + zwy(ji,jj) - zwy(ji,jj-1) ) * r1_e12t(ji,jj)
  590. END DO
  591. END DO
  592. ssha_e(:,:) = ( sshn_e(:,:) - rdtbt * ( zssh_frc(:,:) + zhdiv(:,:) ) ) * tmask(:,:,1)
  593. CALL lbc_lnk( ssha_e, 'T', 1._wp )
  594. #if defined key_bdy
  595. ! Duplicate sea level across open boundaries (this is only cosmetic if lk_vvl=.false.)
  596. IF (lk_bdy) CALL bdy_ssh( ssha_e )
  597. #endif
  598. #if defined key_agrif
  599. IF( .NOT.Agrif_Root() ) CALL agrif_ssh_ts( jn )
  600. #endif
  601. !
  602. ! Sea Surface Height at u-,v-points (vvl case only)
  603. IF ( lk_vvl ) THEN
  604. DO jj = 2, jpjm1
  605. DO ji = 2, jpim1 ! NO Vector Opt.
  606. zsshu_a(ji,jj) = z1_2 * umask(ji,jj,1) * r1_e12u(ji,jj) &
  607. & * ( e12t(ji ,jj ) * ssha_e(ji ,jj ) &
  608. & + e12t(ji+1,jj ) * ssha_e(ji+1,jj ) )
  609. zsshv_a(ji,jj) = z1_2 * vmask(ji,jj,1) * r1_e12v(ji,jj) &
  610. & * ( e12t(ji ,jj ) * ssha_e(ji ,jj ) &
  611. & + e12t(ji ,jj+1) * ssha_e(ji ,jj+1) )
  612. END DO
  613. END DO
  614. CALL lbc_lnk_multi( zsshu_a, 'U', 1._wp, zsshv_a, 'V', 1._wp )
  615. ENDIF
  616. !
  617. ! Half-step back interpolation of SSH for surface pressure computation:
  618. !----------------------------------------------------------------------
  619. IF ((jn==1).AND.ll_init) THEN
  620. za0=1._wp ! Forward-backward
  621. za1=0._wp
  622. za2=0._wp
  623. za3=0._wp
  624. ELSEIF ((jn==2).AND.ll_init) THEN ! AB2-AM3 Coefficients; bet=0 ; gam=-1/6 ; eps=1/12
  625. za0= 1.0833333333333_wp ! za0 = 1-gam-eps
  626. za1=-0.1666666666666_wp ! za1 = gam
  627. za2= 0.0833333333333_wp ! za2 = eps
  628. za3= 0._wp
  629. ELSE ! AB3-AM4 Coefficients; bet=0.281105 ; eps=0.013 ; gam=0.0880
  630. za0=0.614_wp ! za0 = 1/2 + gam + 2*eps
  631. za1=0.285_wp ! za1 = 1/2 - 2*gam - 3*eps
  632. za2=0.088_wp ! za2 = gam
  633. za3=0.013_wp ! za3 = eps
  634. ENDIF
  635. zsshp2_e(:,:) = za0 * ssha_e(:,:) + za1 * sshn_e (:,:) &
  636. & + za2 * sshb_e(:,:) + za3 * sshbb_e(:,:)
  637. !
  638. ! Compute associated depths at U and V points:
  639. IF ( lk_vvl.AND.(.NOT.ln_dynadv_vec) ) THEN
  640. !
  641. DO jj = 2, jpjm1
  642. DO ji = 2, jpim1
  643. zx1 = z1_2 * umask(ji ,jj,1) * r1_e12u(ji ,jj) &
  644. & * ( e12t(ji ,jj ) * zsshp2_e(ji ,jj) &
  645. & + e12t(ji+1,jj ) * zsshp2_e(ji+1,jj ) )
  646. zy1 = z1_2 * vmask(ji ,jj,1) * r1_e12v(ji ,jj ) &
  647. & * ( e12t(ji ,jj ) * zsshp2_e(ji ,jj ) &
  648. & + e12t(ji ,jj+1) * zsshp2_e(ji ,jj+1) )
  649. zhust_e(ji,jj) = hu_0(ji,jj) + zx1
  650. zhvst_e(ji,jj) = hv_0(ji,jj) + zy1
  651. END DO
  652. END DO
  653. ENDIF
  654. !
  655. ! Add Coriolis trend:
  656. ! zwz array below or triads normally depend on sea level with key_vvl and should be updated
  657. ! at each time step. We however keep them constant here for optimization.
  658. ! Recall that zwx and zwy arrays hold fluxes at this stage:
  659. ! zwx(:,:) = e2u(:,:) * ua_e(:,:) * zhup2_e(:,:) ! fluxes at jn+0.5
  660. ! zwy(:,:) = e1v(:,:) * va_e(:,:) * zhvp2_e(:,:)
  661. !
  662. IF( ln_dynvor_ene .OR. ln_dynvor_mix ) THEN !== energy conserving or mixed scheme ==!
  663. DO jj = 2, jpjm1
  664. DO ji = fs_2, fs_jpim1 ! vector opt.
  665. zy1 = ( zwy(ji ,jj-1) + zwy(ji+1,jj-1) ) / e1u(ji,jj)
  666. zy2 = ( zwy(ji ,jj ) + zwy(ji+1,jj ) ) / e1u(ji,jj)
  667. zx1 = ( zwx(ji-1,jj ) + zwx(ji-1,jj+1) ) / e2v(ji,jj)
  668. zx2 = ( zwx(ji ,jj ) + zwx(ji ,jj+1) ) / e2v(ji,jj)
  669. zu_trd(ji,jj) = z1_4 * ( zwz(ji ,jj-1) * zy1 + zwz(ji,jj) * zy2 )
  670. zv_trd(ji,jj) =-z1_4 * ( zwz(ji-1,jj ) * zx1 + zwz(ji,jj) * zx2 )
  671. END DO
  672. END DO
  673. !
  674. ELSEIF ( ln_dynvor_ens ) THEN !== enstrophy conserving scheme ==!
  675. DO jj = 2, jpjm1
  676. DO ji = fs_2, fs_jpim1 ! vector opt.
  677. zy1 = z1_8 * ( zwy(ji ,jj-1) + zwy(ji+1,jj-1) &
  678. & + zwy(ji ,jj ) + zwy(ji+1,jj ) ) / e1u(ji,jj)
  679. zx1 = - z1_8 * ( zwx(ji-1,jj ) + zwx(ji-1,jj+1) &
  680. & + zwx(ji ,jj ) + zwx(ji ,jj+1) ) / e2v(ji,jj)
  681. zu_trd(ji,jj) = zy1 * ( zwz(ji ,jj-1) + zwz(ji,jj) )
  682. zv_trd(ji,jj) = zx1 * ( zwz(ji-1,jj ) + zwz(ji,jj) )
  683. END DO
  684. END DO
  685. !
  686. ELSEIF ( ln_dynvor_een .or. ln_dynvor_een_old ) THEN !== energy and enstrophy conserving scheme ==!
  687. DO jj = 2, jpjm1
  688. DO ji = fs_2, fs_jpim1 ! vector opt.
  689. zu_trd(ji,jj) = + z1_12 / e1u(ji,jj) * ( ftne(ji,jj ) * zwy(ji ,jj ) &
  690. & + ftnw(ji+1,jj) * zwy(ji+1,jj ) &
  691. & + ftse(ji,jj ) * zwy(ji ,jj-1) &
  692. & + ftsw(ji+1,jj) * zwy(ji+1,jj-1) )
  693. zv_trd(ji,jj) = - z1_12 / e2v(ji,jj) * ( ftsw(ji,jj+1) * zwx(ji-1,jj+1) &
  694. & + ftse(ji,jj+1) * zwx(ji ,jj+1) &
  695. & + ftnw(ji,jj ) * zwx(ji-1,jj ) &
  696. & + ftne(ji,jj ) * zwx(ji ,jj ) )
  697. END DO
  698. END DO
  699. !
  700. ENDIF
  701. !
  702. ! Add tidal astronomical forcing if defined
  703. IF ( lk_tide.AND.ln_tide_pot ) THEN
  704. DO jj = 2, jpjm1
  705. DO ji = fs_2, fs_jpim1 ! vector opt.
  706. zu_spg = grav * ( pot_astro(ji+1,jj) - pot_astro(ji,jj) ) / e1u(ji,jj)
  707. zv_spg = grav * ( pot_astro(ji,jj+1) - pot_astro(ji,jj) ) / e2v(ji,jj)
  708. zu_trd(ji,jj) = zu_trd(ji,jj) + zu_spg
  709. zv_trd(ji,jj) = zv_trd(ji,jj) + zv_spg
  710. END DO
  711. END DO
  712. ENDIF
  713. !
  714. ! Add bottom stresses:
  715. zu_trd(:,:) = zu_trd(:,:) + bfrua(:,:) * zun_e(:,:) * hur_e(:,:)
  716. zv_trd(:,:) = zv_trd(:,:) + bfrva(:,:) * zvn_e(:,:) * hvr_e(:,:)
  717. !
  718. ! Surface pressure trend:
  719. DO jj = 2, jpjm1
  720. DO ji = fs_2, fs_jpim1 ! vector opt.
  721. ! Add surface pressure gradient
  722. zu_spg = - grav * ( zsshp2_e(ji+1,jj) - zsshp2_e(ji,jj) ) / e1u(ji,jj)
  723. zv_spg = - grav * ( zsshp2_e(ji,jj+1) - zsshp2_e(ji,jj) ) / e2v(ji,jj)
  724. zwx(ji,jj) = zu_spg
  725. zwy(ji,jj) = zv_spg
  726. END DO
  727. END DO
  728. !
  729. ! Set next velocities:
  730. IF( ln_dynadv_vec .OR. (.NOT. lk_vvl) ) THEN ! Vector form
  731. DO jj = 2, jpjm1
  732. DO ji = fs_2, fs_jpim1 ! vector opt.
  733. ua_e(ji,jj) = ( zun_e(ji,jj) &
  734. & + rdtbt * ( zwx(ji,jj) &
  735. & + zu_trd(ji,jj) &
  736. & + zu_frc(ji,jj) ) &
  737. & ) * umask(ji,jj,1)
  738. va_e(ji,jj) = ( zvn_e(ji,jj) &
  739. & + rdtbt * ( zwy(ji,jj) &
  740. & + zv_trd(ji,jj) &
  741. & + zv_frc(ji,jj) ) &
  742. & ) * vmask(ji,jj,1)
  743. END DO
  744. END DO
  745. ELSE ! Flux form
  746. DO jj = 2, jpjm1
  747. DO ji = fs_2, fs_jpim1 ! vector opt.
  748. zhura = umask(ji,jj,1)/(hu_0(ji,jj) + zsshu_a(ji,jj) + 1._wp - umask(ji,jj,1))
  749. zhvra = vmask(ji,jj,1)/(hv_0(ji,jj) + zsshv_a(ji,jj) + 1._wp - vmask(ji,jj,1))
  750. ua_e(ji,jj) = ( hu_e(ji,jj) * zun_e(ji,jj) &
  751. & + rdtbt * ( zhust_e(ji,jj) * zwx(ji,jj) &
  752. & + zhup2_e(ji,jj) * zu_trd(ji,jj) &
  753. & + hu(ji,jj) * zu_frc(ji,jj) ) &
  754. & ) * zhura
  755. va_e(ji,jj) = ( hv_e(ji,jj) * zvn_e(ji,jj) &
  756. & + rdtbt * ( zhvst_e(ji,jj) * zwy(ji,jj) &
  757. & + zhvp2_e(ji,jj) * zv_trd(ji,jj) &
  758. & + hv(ji,jj) * zv_frc(ji,jj) ) &
  759. & ) * zhvra
  760. END DO
  761. END DO
  762. ENDIF
  763. !
  764. IF( lk_vvl ) THEN !* Update ocean depth (variable volume case only)
  765. ! ! ----------------------------------------------
  766. hu_e (:,:) = hu_0(:,:) + zsshu_a(:,:)
  767. hv_e (:,:) = hv_0(:,:) + zsshv_a(:,:)
  768. hur_e(:,:) = umask(:,:,1) / ( hu_e(:,:) + 1._wp - umask(:,:,1) )
  769. hvr_e(:,:) = vmask(:,:,1) / ( hv_e(:,:) + 1._wp - vmask(:,:,1) )
  770. !
  771. ENDIF
  772. ! !* domain lateral boundary
  773. ! ! -----------------------
  774. !
  775. CALL lbc_lnk_multi( ua_e, 'U', -1._wp, va_e , 'V', -1._wp )
  776. #if defined key_bdy
  777. ! open boundaries
  778. IF( lk_bdy ) CALL bdy_dyn2d( jn, ua_e, va_e, zun_e, zvn_e, hur_e, hvr_e, ssha_e )
  779. #endif
  780. #if defined key_agrif
  781. IF( .NOT.Agrif_Root() ) CALL agrif_dyn_ts( jn ) ! Agrif
  782. #endif
  783. ! !* Swap
  784. ! ! ----
  785. ubb_e (:,:) = ub_e (:,:)
  786. ub_e (:,:) = zun_e (:,:)
  787. zun_e (:,:) = ua_e (:,:)
  788. !
  789. vbb_e (:,:) = vb_e (:,:)
  790. vb_e (:,:) = zvn_e (:,:)
  791. zvn_e (:,:) = va_e (:,:)
  792. !
  793. sshbb_e(:,:) = sshb_e(:,:)
  794. sshb_e (:,:) = sshn_e(:,:)
  795. sshn_e (:,:) = ssha_e(:,:)
  796. ! !* Sum over whole bt loop
  797. ! ! ----------------------
  798. za1 = wgtbtp1(jn)
  799. IF (( ln_dynadv_vec ).OR. (.NOT. lk_vvl)) THEN ! Sum velocities
  800. ua_b (:,:) = ua_b (:,:) + za1 * ua_e (:,:)
  801. va_b (:,:) = va_b (:,:) + za1 * va_e (:,:)
  802. ELSE ! Sum transports
  803. ua_b (:,:) = ua_b (:,:) + za1 * ua_e (:,:) * hu_e (:,:)
  804. va_b (:,:) = va_b (:,:) + za1 * va_e (:,:) * hv_e (:,:)
  805. ENDIF
  806. ! ! Sum sea level
  807. ssha(:,:) = ssha(:,:) + za1 * ssha_e(:,:)
  808. ! ! ==================== !
  809. END DO ! end loop !
  810. ! ! ==================== !
  811. ! -----------------------------------------------------------------------------
  812. ! Phase 3. update the general trend with the barotropic trend
  813. ! -----------------------------------------------------------------------------
  814. !
  815. ! At this stage ssha holds a time averaged value
  816. ! ! Sea Surface Height at u-,v- and f-points
  817. IF( lk_vvl ) THEN ! (required only in key_vvl case)
  818. DO jj = 1, jpjm1
  819. DO ji = 1, jpim1 ! NO Vector Opt.
  820. zsshu_a(ji,jj) = z1_2 * umask(ji,jj,1) * r1_e12u(ji,jj) &
  821. & * ( e12t(ji ,jj) * ssha(ji ,jj) &
  822. & + e12t(ji+1,jj) * ssha(ji+1,jj) )
  823. zsshv_a(ji,jj) = z1_2 * vmask(ji,jj,1) * r1_e12v(ji,jj) &
  824. & * ( e12t(ji,jj ) * ssha(ji,jj ) &
  825. & + e12t(ji,jj+1) * ssha(ji,jj+1) )
  826. END DO
  827. END DO
  828. CALL lbc_lnk_multi( zsshu_a, 'U', 1._wp, zsshv_a, 'V', 1._wp ) ! Boundary conditions
  829. ENDIF
  830. !
  831. ! Set advection velocity correction:
  832. IF (((kt==nit000).AND.(neuler==0)).OR.(.NOT.ln_bt_fw)) THEN
  833. un_adv(:,:) = zu_sum(:,:)*hur(:,:)
  834. vn_adv(:,:) = zv_sum(:,:)*hvr(:,:)
  835. ELSE
  836. un_adv(:,:) = z1_2 * ( ub2_b(:,:) + zu_sum(:,:)) * hur(:,:)
  837. vn_adv(:,:) = z1_2 * ( vb2_b(:,:) + zv_sum(:,:)) * hvr(:,:)
  838. END IF
  839. IF (ln_bt_fw) THEN ! Save integrated transport for next computation
  840. ub2_b(:,:) = zu_sum(:,:)
  841. vb2_b(:,:) = zv_sum(:,:)
  842. ENDIF
  843. !
  844. ! Update barotropic trend:
  845. IF (( ln_dynadv_vec ).OR. (.NOT. lk_vvl)) THEN
  846. DO jk=1,jpkm1
  847. ua(:,:,jk) = ua(:,:,jk) + ( ua_b(:,:) - ub_b(:,:) ) * z1_2dt_b
  848. va(:,:,jk) = va(:,:,jk) + ( va_b(:,:) - vb_b(:,:) ) * z1_2dt_b
  849. END DO
  850. ELSE
  851. DO jk=1,jpkm1
  852. ua(:,:,jk) = ua(:,:,jk) + hur(:,:) * ( ua_b(:,:) - ub_b(:,:) * hu_b(:,:) ) * z1_2dt_b
  853. va(:,:,jk) = va(:,:,jk) + hvr(:,:) * ( va_b(:,:) - vb_b(:,:) * hv_b(:,:) ) * z1_2dt_b
  854. END DO
  855. ! Save barotropic velocities not transport:
  856. ua_b (:,:) = ua_b(:,:) / ( hu_0(:,:) + zsshu_a(:,:) + 1._wp - umask(:,:,1) )
  857. va_b (:,:) = va_b(:,:) / ( hv_0(:,:) + zsshv_a(:,:) + 1._wp - vmask(:,:,1) )
  858. ENDIF
  859. !
  860. DO jk = 1, jpkm1
  861. ! Correct velocities:
  862. un(:,:,jk) = ( un(:,:,jk) + un_adv(:,:) - un_b(:,:) )*umask(:,:,jk)
  863. vn(:,:,jk) = ( vn(:,:,jk) + vn_adv(:,:) - vn_b(:,:) )*vmask(:,:,jk)
  864. !
  865. END DO
  866. !
  867. #if defined key_agrif
  868. ! Save time integrated fluxes during child grid integration
  869. ! (used to update coarse grid transports at next time step)
  870. !
  871. IF ( (.NOT.Agrif_Root()).AND.(ln_bt_fw) ) THEN
  872. IF ( Agrif_NbStepint().EQ.0 ) THEN
  873. ub2_i_b(:,:) = 0.e0
  874. vb2_i_b(:,:) = 0.e0
  875. END IF
  876. !
  877. za1 = 1._wp / REAL(Agrif_rhot(), wp)
  878. ub2_i_b(:,:) = ub2_i_b(:,:) + za1 * ub2_b(:,:)
  879. vb2_i_b(:,:) = vb2_i_b(:,:) + za1 * vb2_b(:,:)
  880. ENDIF
  881. !
  882. !
  883. #endif
  884. !
  885. ! !* write time-spliting arrays in the restart
  886. IF(lrst_oce .AND.ln_bt_fw) CALL ts_rst( kt, 'WRITE' )
  887. !
  888. CALL wrk_dealloc( jpi, jpj, zsshp2_e, zhdiv )
  889. CALL wrk_dealloc( jpi, jpj, zu_trd, zv_trd, zun_e, zvn_e )
  890. CALL wrk_dealloc( jpi, jpj, zwx, zwy, zu_sum, zv_sum, zssh_frc, zu_frc, zv_frc )
  891. CALL wrk_dealloc( jpi, jpj, zhup2_e, zhvp2_e, zhust_e, zhvst_e )
  892. CALL wrk_dealloc( jpi, jpj, zsshu_a, zsshv_a )
  893. CALL wrk_dealloc( jpi, jpj, zhf )
  894. !
  895. IF( nn_timing == 1 ) CALL timing_stop('dyn_spg_ts')
  896. !
  897. END SUBROUTINE dyn_spg_ts
  898. SUBROUTINE ts_wgt( ll_av, ll_fw, jpit, zwgt1, zwgt2)
  899. !!---------------------------------------------------------------------
  900. !! *** ROUTINE ts_wgt ***
  901. !!
  902. !! ** Purpose : Set time-splitting weights for temporal averaging (or not)
  903. !!----------------------------------------------------------------------
  904. LOGICAL, INTENT(in) :: ll_av ! temporal averaging=.true.
  905. LOGICAL, INTENT(in) :: ll_fw ! forward time splitting =.true.
  906. INTEGER, INTENT(inout) :: jpit ! cycle length
  907. REAL(wp), DIMENSION(3*nn_baro), INTENT(inout) :: zwgt1, & ! Primary weights
  908. zwgt2 ! Secondary weights
  909. INTEGER :: jic, jn, ji ! temporary integers
  910. REAL(wp) :: za1, za2
  911. !!----------------------------------------------------------------------
  912. zwgt1(:) = 0._wp
  913. zwgt2(:) = 0._wp
  914. ! Set time index when averaged value is requested
  915. IF (ll_fw) THEN
  916. jic = nn_baro
  917. ELSE
  918. jic = 2 * nn_baro
  919. ENDIF
  920. ! Set primary weights:
  921. IF (ll_av) THEN
  922. ! Define simple boxcar window for primary weights
  923. ! (width = nn_baro, centered around jic)
  924. SELECT CASE ( nn_bt_flt )
  925. CASE( 0 ) ! No averaging
  926. zwgt1(jic) = 1._wp
  927. jpit = jic
  928. CASE( 1 ) ! Boxcar, width = nn_baro
  929. DO jn = 1, 3*nn_baro
  930. za1 = ABS(float(jn-jic))/float(nn_baro)
  931. IF (za1 < 0.5_wp) THEN
  932. zwgt1(jn) = 1._wp
  933. jpit = jn
  934. ENDIF
  935. ENDDO
  936. CASE( 2 ) ! Boxcar, width = 2 * nn_baro
  937. DO jn = 1, 3*nn_baro
  938. za1 = ABS(float(jn-jic))/float(nn_baro)
  939. IF (za1 < 1._wp) THEN
  940. zwgt1(jn) = 1._wp
  941. jpit = jn
  942. ENDIF
  943. ENDDO
  944. CASE DEFAULT ; CALL ctl_stop( 'unrecognised value for nn_bt_flt' )
  945. END SELECT
  946. ELSE ! No time averaging
  947. zwgt1(jic) = 1._wp
  948. jpit = jic
  949. ENDIF
  950. ! Set secondary weights
  951. DO jn = 1, jpit
  952. DO ji = jn, jpit
  953. zwgt2(jn) = zwgt2(jn) + zwgt1(ji)
  954. END DO
  955. END DO
  956. ! Normalize weigths:
  957. za1 = 1._wp / SUM(zwgt1(1:jpit))
  958. za2 = 1._wp / SUM(zwgt2(1:jpit))
  959. DO jn = 1, jpit
  960. zwgt1(jn) = zwgt1(jn) * za1
  961. zwgt2(jn) = zwgt2(jn) * za2
  962. END DO
  963. !
  964. END SUBROUTINE ts_wgt
  965. SUBROUTINE ts_rst( kt, cdrw )
  966. !!---------------------------------------------------------------------
  967. !! *** ROUTINE ts_rst ***
  968. !!
  969. !! ** Purpose : Read or write time-splitting arrays in restart file
  970. !!----------------------------------------------------------------------
  971. INTEGER , INTENT(in) :: kt ! ocean time-step
  972. CHARACTER(len=*), INTENT(in) :: cdrw ! "READ"/"WRITE" flag
  973. !
  974. !!----------------------------------------------------------------------
  975. !
  976. IF( TRIM(cdrw) == 'READ' ) THEN
  977. CALL iom_get( numror, jpdom_autoglo, 'ub2_b' , ub2_b (:,:) )
  978. CALL iom_get( numror, jpdom_autoglo, 'vb2_b' , vb2_b (:,:) )
  979. IF( .NOT.ln_bt_av ) THEN
  980. CALL iom_get( numror, jpdom_autoglo, 'sshbb_e' , sshbb_e(:,:) )
  981. CALL iom_get( numror, jpdom_autoglo, 'ubb_e' , ubb_e(:,:) )
  982. CALL iom_get( numror, jpdom_autoglo, 'vbb_e' , vbb_e(:,:) )
  983. CALL iom_get( numror, jpdom_autoglo, 'sshb_e' , sshb_e(:,:) )
  984. CALL iom_get( numror, jpdom_autoglo, 'ub_e' , ub_e(:,:) )
  985. CALL iom_get( numror, jpdom_autoglo, 'vb_e' , vb_e(:,:) )
  986. ENDIF
  987. #if defined key_agrif
  988. ! Read time integrated fluxes
  989. IF ( .NOT.Agrif_Root() ) THEN
  990. CALL iom_get( numror, jpdom_autoglo, 'ub2_i_b' , ub2_i_b(:,:) )
  991. CALL iom_get( numror, jpdom_autoglo, 'vb2_i_b' , vb2_i_b(:,:) )
  992. ENDIF
  993. #endif
  994. !
  995. ELSEIF( TRIM(cdrw) == 'WRITE' ) THEN
  996. CALL iom_rstput( kt, nitrst, numrow, 'ub2_b' , ub2_b (:,:) )
  997. CALL iom_rstput( kt, nitrst, numrow, 'vb2_b' , vb2_b (:,:) )
  998. !
  999. IF (.NOT.ln_bt_av) THEN
  1000. CALL iom_rstput( kt, nitrst, numrow, 'sshbb_e' , sshbb_e(:,:) )
  1001. CALL iom_rstput( kt, nitrst, numrow, 'ubb_e' , ubb_e(:,:) )
  1002. CALL iom_rstput( kt, nitrst, numrow, 'vbb_e' , vbb_e(:,:) )
  1003. CALL iom_rstput( kt, nitrst, numrow, 'sshb_e' , sshb_e(:,:) )
  1004. CALL iom_rstput( kt, nitrst, numrow, 'ub_e' , ub_e(:,:) )
  1005. CALL iom_rstput( kt, nitrst, numrow, 'vb_e' , vb_e(:,:) )
  1006. ENDIF
  1007. #if defined key_agrif
  1008. ! Save time integrated fluxes
  1009. IF ( .NOT.Agrif_Root() ) THEN
  1010. CALL iom_rstput( kt, nitrst, numrow, 'ub2_i_b' , ub2_i_b(:,:) )
  1011. CALL iom_rstput( kt, nitrst, numrow, 'vb2_i_b' , vb2_i_b(:,:) )
  1012. ENDIF
  1013. #endif
  1014. ENDIF
  1015. !
  1016. END SUBROUTINE ts_rst
  1017. SUBROUTINE dyn_spg_ts_init( kt )
  1018. !!---------------------------------------------------------------------
  1019. !! *** ROUTINE dyn_spg_ts_init ***
  1020. !!
  1021. !! ** Purpose : Set time splitting options
  1022. !!----------------------------------------------------------------------
  1023. INTEGER , INTENT(in) :: kt ! ocean time-step
  1024. !
  1025. INTEGER :: ji ,jj
  1026. INTEGER :: ios ! Local integer output status for namelist read
  1027. REAL(wp) :: zxr2, zyr2, zcmax
  1028. REAL(wp), POINTER, DIMENSION(:,:) :: zcu
  1029. !!
  1030. NAMELIST/namsplit/ ln_bt_fw, ln_bt_av, ln_bt_nn_auto, &
  1031. & nn_baro, rn_bt_cmax, nn_bt_flt
  1032. !!----------------------------------------------------------------------
  1033. !
  1034. REWIND( numnam_ref ) ! Namelist namsplit in reference namelist : time splitting parameters
  1035. READ ( numnam_ref, namsplit, IOSTAT = ios, ERR = 901)
  1036. 901 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namsplit in reference namelist', lwp )
  1037. REWIND( numnam_cfg ) ! Namelist namsplit in configuration namelist : time splitting parameters
  1038. READ ( numnam_cfg, namsplit, IOSTAT = ios, ERR = 902 )
  1039. 902 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namsplit in configuration namelist', lwp )
  1040. IF(lwm) WRITE ( numond, namsplit )
  1041. !
  1042. ! ! Max courant number for ext. grav. waves
  1043. !
  1044. CALL wrk_alloc( jpi, jpj, zcu )
  1045. !
  1046. IF (lk_vvl) THEN
  1047. DO jj = 1, jpj
  1048. DO ji =1, jpi
  1049. zxr2 = 1./(e1t(ji,jj)*e1t(ji,jj))
  1050. zyr2 = 1./(e2t(ji,jj)*e2t(ji,jj))
  1051. zcu(ji,jj) = sqrt(grav*ht_0(ji,jj)*(zxr2 + zyr2) )
  1052. END DO
  1053. END DO
  1054. ELSE
  1055. DO jj = 1, jpj
  1056. DO ji =1, jpi
  1057. zxr2 = 1./(e1t(ji,jj)*e1t(ji,jj))
  1058. zyr2 = 1./(e2t(ji,jj)*e2t(ji,jj))
  1059. zcu(ji,jj) = sqrt(grav*ht(ji,jj)*(zxr2 + zyr2) )
  1060. END DO
  1061. END DO
  1062. ENDIF
  1063. zcmax = MAXVAL(zcu(:,:))
  1064. IF( lk_mpp ) CALL mpp_max( zcmax )
  1065. ! Estimate number of iterations to satisfy a max courant number= rn_bt_cmax
  1066. IF (ln_bt_nn_auto) nn_baro = CEILING( rdt / rn_bt_cmax * zcmax)
  1067. rdtbt = rdt / FLOAT(nn_baro)
  1068. zcmax = zcmax * rdtbt
  1069. ! Print results
  1070. IF(lwp) WRITE(numout,*)
  1071. IF(lwp) WRITE(numout,*) 'dyn_spg_ts : split-explicit free surface'
  1072. IF(lwp) WRITE(numout,*) '~~~~~~~~~~'
  1073. IF( ln_bt_nn_auto ) THEN
  1074. IF(lwp) WRITE(numout,*) ' ln_ts_nn_auto=.true. Automatically set nn_baro '
  1075. IF(lwp) WRITE(numout,*) ' Max. courant number allowed: ', rn_bt_cmax
  1076. ELSE
  1077. IF(lwp) WRITE(numout,*) ' ln_ts_nn_auto=.false.: Use nn_baro in namelist '
  1078. ENDIF
  1079. IF(ln_bt_av) THEN
  1080. IF(lwp) WRITE(numout,*) ' ln_bt_av=.true. => Time averaging over nn_baro time steps is on '
  1081. ELSE
  1082. IF(lwp) WRITE(numout,*) ' ln_bt_av=.false. => No time averaging of barotropic variables '
  1083. ENDIF
  1084. !
  1085. !
  1086. IF(ln_bt_fw) THEN
  1087. IF(lwp) WRITE(numout,*) ' ln_bt_fw=.true. => Forward integration of barotropic variables '
  1088. ELSE
  1089. IF(lwp) WRITE(numout,*) ' ln_bt_fw =.false.=> Centred integration of barotropic variables '
  1090. ENDIF
  1091. !
  1092. #if defined key_agrif
  1093. ! Restrict the use of Agrif to the forward case only
  1094. IF ((.NOT.ln_bt_fw ).AND.(.NOT.Agrif_Root())) CALL ctl_stop( 'AGRIF not implemented if ln_bt_fw=.FALSE.' )
  1095. #endif
  1096. !
  1097. IF(lwp) WRITE(numout,*) ' Time filter choice, nn_bt_flt: ', nn_bt_flt
  1098. SELECT CASE ( nn_bt_flt )
  1099. CASE( 0 ) ; IF(lwp) WRITE(numout,*) ' Dirac'
  1100. CASE( 1 ) ; IF(lwp) WRITE(numout,*) ' Boxcar: width = nn_baro'
  1101. CASE( 2 ) ; IF(lwp) WRITE(numout,*) ' Boxcar: width = 2*nn_baro'
  1102. CASE DEFAULT ; CALL ctl_stop( 'unrecognised value for nn_bt_flt: should 0,1,2' )
  1103. END SELECT
  1104. !
  1105. IF(lwp) WRITE(numout,*) ' '
  1106. IF(lwp) WRITE(numout,*) ' nn_baro = ', nn_baro
  1107. IF(lwp) WRITE(numout,*) ' Barotropic time step [s] is :', rdtbt
  1108. IF(lwp) WRITE(numout,*) ' Maximum Courant number is :', zcmax
  1109. !
  1110. IF ((.NOT.ln_bt_av).AND.(.NOT.ln_bt_fw)) THEN
  1111. CALL ctl_stop( 'dynspg_ts ERROR: No time averaging => only forward integration is possible' )
  1112. ENDIF
  1113. IF ( zcmax>0.9_wp ) THEN
  1114. CALL ctl_stop( 'dynspg_ts ERROR: Maximum Courant number is greater than 0.9: Inc. nn_baro !' )
  1115. ENDIF
  1116. !
  1117. CALL wrk_dealloc( jpi, jpj, zcu )
  1118. !
  1119. END SUBROUTINE dyn_spg_ts_init
  1120. #else
  1121. !!---------------------------------------------------------------------------
  1122. !! Default case : Empty module No split explicit free surface
  1123. !!---------------------------------------------------------------------------
  1124. CONTAINS
  1125. INTEGER FUNCTION dyn_spg_ts_alloc() ! Dummy function
  1126. dyn_spg_ts_alloc = 0
  1127. END FUNCTION dyn_spg_ts_alloc
  1128. SUBROUTINE dyn_spg_ts( kt ) ! Empty routine
  1129. INTEGER, INTENT(in) :: kt
  1130. WRITE(*,*) 'dyn_spg_ts: You should not have seen this print! error?', kt
  1131. END SUBROUTINE dyn_spg_ts
  1132. SUBROUTINE ts_rst( kt, cdrw ) ! Empty routine
  1133. INTEGER , INTENT(in) :: kt ! ocean time-step
  1134. CHARACTER(len=*), INTENT(in) :: cdrw ! "READ"/"WRITE" flag
  1135. WRITE(*,*) 'ts_rst : You should not have seen this print! error?', kt, cdrw
  1136. END SUBROUTINE ts_rst
  1137. SUBROUTINE dyn_spg_ts_init( kt ) ! Empty routine
  1138. INTEGER , INTENT(in) :: kt ! ocean time-step
  1139. WRITE(*,*) 'dyn_spg_ts_init : You should not have seen this print! error?', kt
  1140. END SUBROUTINE dyn_spg_ts_init
  1141. #endif
  1142. !!======================================================================
  1143. END MODULE dynspg_ts