sbcisf.F90 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970
  1. MODULE sbcisf
  2. !!======================================================================
  3. !! *** MODULE sbcisf ***
  4. !! Surface module : update surface ocean boundary condition under ice
  5. !! shelf
  6. !!======================================================================
  7. !! History : 3.2 ! 2011-02 (C.Harris ) Original code isf cav
  8. !! X.X ! 2006-02 (C. Wang ) Original code bg03
  9. !! 3.4 ! 2013-03 (P. Mathiot) Merging + parametrization
  10. !!----------------------------------------------------------------------
  11. !!----------------------------------------------------------------------
  12. !! sbc_isf : update sbc under ice shelf
  13. !!----------------------------------------------------------------------
  14. USE oce ! ocean dynamics and tracers
  15. USE dom_oce ! ocean space and time domain
  16. USE phycst ! physical constants
  17. USE eosbn2 ! equation of state
  18. USE sbc_oce ! surface boundary condition: ocean fields
  19. USE lbclnk !
  20. USE iom ! I/O manager library
  21. USE in_out_manager ! I/O manager
  22. USE wrk_nemo ! Memory allocation
  23. USE timing ! Timing
  24. USE lib_fortran ! glob_sum
  25. USE zdfbfr
  26. USE fldread ! read input field at current time step
  27. IMPLICIT NONE
  28. PRIVATE
  29. PUBLIC sbc_isf, sbc_isf_init, sbc_isf_div, sbc_isf_alloc ! routine called in sbcmod and divcur
  30. ! public in order to be able to output then
  31. REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: risf_tsc_b, risf_tsc
  32. REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: qisf !: net heat flux from ice shelf
  33. REAL(wp), PUBLIC :: rn_hisf_tbl !: thickness of top boundary layer [m]
  34. LOGICAL , PUBLIC :: ln_divisf !: flag to correct divergence
  35. INTEGER , PUBLIC :: nn_isfblk !:
  36. INTEGER , PUBLIC :: nn_gammablk !:
  37. LOGICAL , PUBLIC :: ln_conserve !:
  38. REAL(wp), PUBLIC :: rn_gammat0 !: temperature exchange coeficient
  39. REAL(wp), PUBLIC :: rn_gammas0 !: salinity exchange coeficient
  40. REAL(wp), PUBLIC :: rdivisf !: flag to test if fwf apply on divergence
  41. REAL(wp) , PUBLIC, ALLOCATABLE, SAVE, DIMENSION (:,:) :: rzisf_tbl !:depth of calving front (shallowest point) nn_isf ==2/3
  42. REAL(wp) , PUBLIC, ALLOCATABLE, SAVE, DIMENSION (:,:) :: rhisf_tbl, rhisf_tbl_0 !:thickness of tbl
  43. REAL(wp) , PUBLIC, ALLOCATABLE, SAVE, DIMENSION (:,:) :: r1_hisf_tbl !:1/thickness of tbl
  44. REAL(wp) , PUBLIC, ALLOCATABLE, SAVE, DIMENSION (:,:) :: ralpha !:proportion of bottom cell influenced by tbl
  45. REAL(wp) , PUBLIC, ALLOCATABLE, SAVE, DIMENSION (:,:) :: risfLeff !:effective length (Leff) BG03 nn_isf==2
  46. REAL(wp) , PUBLIC, ALLOCATABLE, SAVE, DIMENSION (:,:) :: ttbl, stbl, utbl, vtbl !:top boundary layer variable at T point
  47. INTEGER, PUBLIC, ALLOCATABLE, SAVE, DIMENSION (:,:) :: misfkt, misfkb !:Level of ice shelf base
  48. LOGICAL, PUBLIC :: l_isfcpl = .false. ! isf recieved from oasis
  49. REAL(wp), PUBLIC, SAVE :: rcpi = 2000.0_wp ! phycst ?
  50. REAL(wp), PUBLIC, SAVE :: kappa = 1.54e-6_wp ! phycst ?
  51. REAL(wp), PUBLIC, SAVE :: rhoisf = 920.0_wp ! phycst ?
  52. REAL(wp), PUBLIC, SAVE :: tsurf = -20.0_wp ! phycst ?
  53. REAL(wp), PUBLIC, SAVE :: lfusisf= 0.334e6_wp ! phycst ?
  54. !: Variable used in fldread to read the forcing file (nn_isf == 4 .OR. nn_isf == 3)
  55. CHARACTER(len=100), PUBLIC :: cn_dirisf = './' !: Root directory for location of ssr files
  56. TYPE(FLD_N) , PUBLIC :: sn_qisf, sn_fwfisf !: information about the runoff file to be read
  57. TYPE(FLD), ALLOCATABLE, DIMENSION(:) :: sf_qisf, sf_fwfisf
  58. TYPE(FLD_N) , PUBLIC :: sn_rnfisf !: information about the runoff file to be read
  59. TYPE(FLD), ALLOCATABLE, DIMENSION(:) :: sf_rnfisf
  60. TYPE(FLD_N) , PUBLIC :: sn_depmax_isf, sn_depmin_isf, sn_Leff_isf !: information about the runoff file to be read
  61. !! * Substitutions
  62. # include "domzgr_substitute.h90"
  63. !!----------------------------------------------------------------------
  64. !! NEMO/OPA 3.0 , LOCEAN-IPSL (2008)
  65. !! $Id: sbcisf.F90 5424 2018-04-27 07:03:10Z ufla $
  66. !! Software governed by the CeCILL licence (modipsl/doc/NEMO_CeCILL.txt)
  67. !!----------------------------------------------------------------------
  68. CONTAINS
  69. SUBROUTINE sbc_isf(kt)
  70. INTEGER, INTENT(in) :: kt ! ocean time step
  71. INTEGER :: ji, jj, jk
  72. INTEGER :: ikt, ikb ! top and bottom level of the isf boundary layer
  73. REAL(wp) :: zhk
  74. REAL(wp) :: zt_frz, zpress
  75. REAL(wp), DIMENSION(:,:,:), POINTER :: zfwfisf3d, zqhcisf3d, zqlatisf3d
  76. REAL(wp), DIMENSION(:,: ), POINTER :: zqhcisf2d
  77. REAL(wp) :: zhisf
  78. IF( MOD( kt-1, nn_fsbc) == 0 ) THEN
  79. ! compute bottom level of isf tbl and thickness of tbl below the ice shelf
  80. DO jj = 1,jpj
  81. DO ji = 1,jpi
  82. ikt = misfkt(ji,jj)
  83. ikb = misfkt(ji,jj)
  84. ! thickness of boundary layer at least the top level thickness
  85. rhisf_tbl(ji,jj) = MAX(rhisf_tbl_0(ji,jj), fse3t_n(ji,jj,ikt))
  86. ! determine the deepest level influenced by the boundary layer
  87. DO jk = ikt, mbkt(ji,jj)
  88. IF ( (SUM(fse3t_n(ji,jj,ikt:jk-1)) .LT. rhisf_tbl(ji,jj)) .AND. (tmask(ji,jj,jk) == 1) ) ikb = jk
  89. END DO
  90. rhisf_tbl(ji,jj) = MIN(rhisf_tbl(ji,jj), SUM(fse3t_n(ji,jj,ikt:ikb))) ! limit the tbl to water thickness.
  91. misfkb(ji,jj) = ikb ! last wet level of the tbl
  92. r1_hisf_tbl(ji,jj) = 1._wp / rhisf_tbl(ji,jj)
  93. zhk = SUM( fse3t(ji, jj, ikt:ikb - 1)) * r1_hisf_tbl(ji,jj) ! proportion of tbl cover by cell from ikt to ikb - 1
  94. ralpha(ji,jj) = rhisf_tbl(ji,jj) * (1._wp - zhk ) / fse3t(ji,jj,ikb) ! proportion of bottom cell influenced by boundary layer
  95. END DO
  96. END DO
  97. ! compute salf and heat flux
  98. IF (nn_isf == 1) THEN
  99. ! realistic ice shelf formulation
  100. ! compute T/S/U/V for the top boundary layer
  101. CALL sbc_isf_tbl(tsn(:,:,:,jp_tem),ttbl(:,:),'T')
  102. CALL sbc_isf_tbl(tsn(:,:,:,jp_sal),stbl(:,:),'T')
  103. CALL sbc_isf_tbl(un(:,:,:),utbl(:,:),'U')
  104. CALL sbc_isf_tbl(vn(:,:,:),vtbl(:,:),'V')
  105. ! iom print
  106. CALL iom_put('ttbl',ttbl(:,:))
  107. CALL iom_put('stbl',stbl(:,:))
  108. CALL iom_put('utbl',utbl(:,:))
  109. CALL iom_put('vtbl',vtbl(:,:))
  110. ! compute fwf and heat flux
  111. IF( .NOT.l_isfcpl ) THEN ; CALL sbc_isf_cav (kt)
  112. ELSE ; qisf(:,:) = fwfisf(:,:) * lfusisf ! heat flux
  113. ENDIF
  114. ELSE IF (nn_isf == 2) THEN
  115. ! Beckmann and Goosse parametrisation
  116. stbl(:,:) = soce
  117. CALL sbc_isf_bg03(kt)
  118. ELSE IF (nn_isf == 3) THEN
  119. ! specified runoff in depth (Mathiot et al., XXXX in preparation)
  120. IF( .NOT.l_isfcpl ) THEN
  121. CALL fld_read ( kt, nn_fsbc, sf_rnfisf )
  122. fwfisf(:,:) = - sf_rnfisf(1)%fnow(:,:,1) ! fresh water flux from the isf (fwfisf <0 mean melting)
  123. ENDIF
  124. qisf(:,:) = fwfisf(:,:) * lfusisf ! heat flux
  125. stbl(:,:) = soce
  126. ELSE IF (nn_isf == 4) THEN
  127. ! specified fwf and heat flux forcing beneath the ice shelf
  128. IF( .NOT.l_isfcpl ) THEN
  129. CALL fld_read ( kt, nn_fsbc, sf_fwfisf )
  130. !CALL fld_read ( kt, nn_fsbc, sf_qisf )
  131. fwfisf(:,:) = sf_fwfisf(1)%fnow(:,:,1) ! fwf
  132. ENDIF
  133. qisf(:,:) = fwfisf(:,:) * lfusisf ! heat flux
  134. !qisf(:,:) = sf_qisf(1)%fnow(:,:,1) ! heat flux
  135. stbl(:,:) = soce
  136. END IF
  137. ! compute tsc due to isf
  138. ! WARNING water add at temp = 0C, correction term is added, maybe better here but need a 3D variable).
  139. ! zpress = grav*rau0*fsdept(ji,jj,jk)*1.e-04
  140. zt_frz = -1.9 !eos_fzp( tsn(ji,jj,jk,jp_sal), zpress )
  141. risf_tsc(:,:,jp_tem) = qisf(:,:) * r1_rau0_rcp - rdivisf * fwfisf(:,:) * zt_frz * r1_rau0 !
  142. ! salt effect already take into account in vertical advection
  143. risf_tsc(:,:,jp_sal) = (1.0_wp-rdivisf) * fwfisf(:,:) * soce * r1_rau0
  144. ! lbclnk
  145. CALL lbc_lnk(risf_tsc(:,:,jp_tem),'T',1.)
  146. CALL lbc_lnk(risf_tsc(:,:,jp_sal),'T',1.)
  147. CALL lbc_lnk(fwfisf(:,:) ,'T',1.)
  148. CALL lbc_lnk(qisf(:,:) ,'T',1.)
  149. ! output
  150. IF( iom_use('iceshelf_cea') ) CALL iom_put( 'iceshelf_cea', -fwfisf(:,:) ) ! isf mass flux
  151. IF( iom_use('hflx_isf_cea') ) CALL iom_put( 'hflx_isf_cea', risf_tsc(:,:,jp_tem) * rau0 * rcp ) ! isf sensible+latent heat (W/m2)
  152. IF( iom_use('qlatisf' ) ) CALL iom_put( 'qlatisf' , qisf(:,:) ) ! isf latent heat
  153. IF( iom_use('fwfisf' ) ) CALL iom_put( 'fwfisf' , fwfisf(:,:) ) ! isf mass flux (opposite sign)
  154. ! Diagnostics
  155. IF( iom_use('fwfisf3d') .OR. iom_use('qlatisf3d') .OR. iom_use('qhcisf3d') .OR. iom_use('qhcisf')) THEN
  156. !
  157. CALL wrk_alloc( jpi,jpj,jpk, zfwfisf3d, zqhcisf3d, zqlatisf3d )
  158. CALL wrk_alloc( jpi,jpj, zqhcisf2d )
  159. !
  160. zfwfisf3d(:,:,:) = 0.0_wp ! 3d ice shelf melting (kg/m2/s)
  161. zqhcisf3d(:,:,:) = 0.0_wp ! 3d heat content flux (W/m2)
  162. zqlatisf3d(:,:,:)= 0.0_wp ! 3d ice shelf melting latent heat flux (W/m2)
  163. zqhcisf2d(:,:) = rdivisf * fwfisf(:,:) * zt_frz * rcp ! 2d heat content flux (W/m2)
  164. !
  165. DO jj = 1,jpj
  166. DO ji = 1,jpi
  167. ikt = misfkt(ji,jj)
  168. ikb = misfkb(ji,jj)
  169. DO jk = ikt, ikb - 1
  170. zhisf = r1_hisf_tbl(ji,jj) * fse3t(ji,jj,jk)
  171. zfwfisf3d (ji,jj,jk) = zfwfisf3d (ji,jj,jk) + fwfisf(ji,jj) * zhisf
  172. zqhcisf3d (ji,jj,jk) = zqhcisf3d (ji,jj,jk) + zqhcisf2d(ji,jj) * zhisf
  173. zqlatisf3d(ji,jj,jk) = zqlatisf3d(ji,jj,jk) + qisf(ji,jj) * zhisf
  174. END DO
  175. jk = ikb
  176. zhisf = r1_hisf_tbl(ji,jj) * fse3t(ji,jj,jk)
  177. zfwfisf3d (ji,jj,jk) = zfwfisf3d (ji,jj,jk) + fwfisf (ji,jj) * zhisf * ralpha(ji,jj)
  178. zqhcisf3d (ji,jj,jk) = zqhcisf3d (ji,jj,jk) + zqhcisf2d(ji,jj) * zhisf * ralpha(ji,jj)
  179. zqlatisf3d(ji,jj,jk) = zqlatisf3d(ji,jj,jk) + qisf (ji,jj) * zhisf * ralpha(ji,jj)
  180. END DO
  181. END DO
  182. !
  183. CALL iom_put( 'fwfisf3d' , zfwfisf3d (:,:,:) )
  184. CALL iom_put( 'qlatisf3d', zqlatisf3d(:,:,:) )
  185. CALL iom_put( 'qhcisf3d' , zqhcisf3d (:,:,:) )
  186. CALL iom_put( 'qhcisf' , zqhcisf2d (:,: ) )
  187. !
  188. CALL wrk_dealloc( jpi,jpj,jpk, zfwfisf3d, zqhcisf3d, zqlatisf3d )
  189. CALL wrk_dealloc( jpi,jpj, zqhcisf2d )
  190. !
  191. END IF
  192. ! if apply only on the trend and not as a volume flux (rdivisf = 0), fwfisf have to be set to 0 now
  193. fwfisf(:,:) = rdivisf * fwfisf(:,:)
  194. !
  195. END IF
  196. !
  197. !
  198. IF( kt == nit000 ) THEN ! set the forcing field at nit000 - 1 !
  199. IF( ln_rstart .AND. & ! Restart: read in restart file
  200. & iom_varid( numror, 'fwf_isf_b', ldstop = .FALSE. ) > 0 ) THEN
  201. IF(lwp) WRITE(numout,*) ' nit000-1 isf tracer content forcing fields read in the restart file'
  202. CALL iom_get( numror, jpdom_autoglo, 'fwf_isf_b', fwfisf_b(:,:) ) ! before salt content isf_tsc trend
  203. CALL iom_get( numror, jpdom_autoglo, 'isf_sc_b', risf_tsc_b(:,:,jp_sal) ) ! before salt content isf_tsc trend
  204. CALL iom_get( numror, jpdom_autoglo, 'isf_hc_b', risf_tsc_b(:,:,jp_tem) ) ! before salt content isf_tsc trend
  205. ELSE
  206. fwfisf_b(:,:) = fwfisf(:,:)
  207. risf_tsc_b(:,:,:)= risf_tsc(:,:,:)
  208. END IF
  209. ENDIF
  210. !
  211. IF( lrst_oce ) THEN
  212. IF(lwp) WRITE(numout,*)
  213. IF(lwp) WRITE(numout,*) 'sbc : isf surface tracer content forcing fields written in ocean restart file ', &
  214. & 'at it= ', kt,' date= ', ndastp
  215. IF(lwp) WRITE(numout,*) '~~~~'
  216. CALL iom_rstput( kt, nitrst, numrow, 'fwf_isf_b', fwfisf(:,:) )
  217. CALL iom_rstput( kt, nitrst, numrow, 'isf_hc_b' , risf_tsc(:,:,jp_tem) )
  218. CALL iom_rstput( kt, nitrst, numrow, 'isf_sc_b' , risf_tsc(:,:,jp_sal) )
  219. ENDIF
  220. !
  221. END SUBROUTINE sbc_isf
  222. SUBROUTINE sbc_isf_init
  223. INTEGER :: ji, jj, jk, ijkmin, inum, ierror
  224. INTEGER :: ikt, ikb ! top and bottom level of the isf boundary layer
  225. REAL(wp) :: zhk
  226. CHARACTER(len=256) :: cfisf , cvarzisf, cvarhisf ! name for isf file
  227. CHARACTER(LEN=256) :: cnameis ! name of iceshelf file
  228. CHARACTER (LEN=32) :: cvarLeff ! variable name for efficient Length scale
  229. INTEGER :: ios ! Local integer output status for namelist read
  230. !
  231. !!---------------------------------------------------------------------
  232. NAMELIST/namsbc_isf/ nn_isfblk, rn_hisf_tbl, ln_divisf, ln_conserve, rn_gammat0, rn_gammas0, nn_gammablk, &
  233. & sn_fwfisf, sn_qisf, sn_rnfisf, sn_depmax_isf, sn_depmin_isf, sn_Leff_isf
  234. !
  235. !
  236. REWIND( numnam_ref ) ! Namelist namsbc_rnf in reference namelist : Runoffs
  237. READ ( numnam_ref, namsbc_isf, IOSTAT = ios, ERR = 901)
  238. 901 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namsbc_isf in reference namelist', lwp )
  239. REWIND( numnam_cfg ) ! Namelist namsbc_rnf in configuration namelist : Runoffs
  240. READ ( numnam_cfg, namsbc_isf, IOSTAT = ios, ERR = 902 )
  241. 902 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namsbc_isf in configuration namelist', lwp )
  242. IF(lwm) WRITE ( numond, namsbc_isf )
  243. IF ( lwp ) WRITE(numout,*)
  244. IF ( lwp ) WRITE(numout,*) 'sbc_isf: heat flux of the ice shelf'
  245. IF ( lwp ) WRITE(numout,*) '~~~~~~~~~'
  246. IF ( lwp ) WRITE(numout,*) 'sbcisf :'
  247. IF ( lwp ) WRITE(numout,*) '~~~~~~~~'
  248. IF ( lwp ) WRITE(numout,*) ' nn_isf = ', nn_isf
  249. IF ( lwp ) WRITE(numout,*) ' nn_isfblk = ', nn_isfblk
  250. IF ( lwp ) WRITE(numout,*) ' rn_hisf_tbl = ', rn_hisf_tbl
  251. IF ( lwp ) WRITE(numout,*) ' ln_divisf = ', ln_divisf
  252. IF ( lwp ) WRITE(numout,*) ' nn_gammablk = ', nn_gammablk
  253. IF ( lwp ) WRITE(numout,*) ' rn_tfri2 = ', rn_tfri2
  254. IF (ln_divisf) THEN ! keep it in the namelist ??? used true anyway as for runoff ? (PM)
  255. rdivisf = 1._wp
  256. ELSE
  257. rdivisf = 0._wp
  258. END IF
  259. !
  260. ! Allocate public variable
  261. IF ( sbc_isf_alloc() /= 0 ) CALL ctl_stop( 'STOP', 'sbc_isf : unable to allocate arrays' )
  262. !
  263. ! initialisation
  264. qisf(:,:) = 0._wp ; fwfisf(:,:) = 0._wp
  265. risf_tsc(:,:,:) = 0._wp
  266. !
  267. ! define isf tbl tickness, top and bottom indice
  268. IF (nn_isf == 1) THEN
  269. rhisf_tbl(:,:) = rn_hisf_tbl
  270. misfkt(:,:) = mikt(:,:) ! same indice for bg03 et cav => used in isfdiv
  271. ELSE IF ((nn_isf == 3) .OR. (nn_isf == 2)) THEN
  272. IF( .NOT.l_isfcpl ) THEN
  273. ALLOCATE( sf_rnfisf(1), STAT=ierror )
  274. ALLOCATE( sf_rnfisf(1)%fnow(jpi,jpj,1), sf_rnfisf(1)%fdta(jpi,jpj,1,2) )
  275. CALL fld_fill(sf_rnfisf, (/ sn_rnfisf /), cn_dirisf, 'sbc_isf_init', 'read fresh water flux isf data', 'namsbc_isf')
  276. ENDIF
  277. !: read effective lenght (BG03)
  278. IF (nn_isf == 2) THEN
  279. ! Read Data and save some integral values
  280. CALL iom_open( sn_Leff_isf%clname, inum )
  281. cvarLeff = 'soLeff' !: variable name for Efficient Length scale
  282. CALL iom_get( inum, jpdom_data, cvarLeff, risfLeff , 1)
  283. CALL iom_close(inum)
  284. !
  285. risfLeff = risfLeff*1000 !: convertion in m
  286. END IF
  287. ! read depth of the top and bottom of the isf top boundary layer (in this case, isf front depth and grounding line depth)
  288. CALL iom_open( sn_depmax_isf%clname, inum )
  289. cvarhisf = TRIM(sn_depmax_isf%clvar)
  290. CALL iom_get( inum, jpdom_data, cvarhisf, rhisf_tbl, 1) !: depth of deepest point of the ice shelf base
  291. CALL iom_close(inum)
  292. !
  293. CALL iom_open( sn_depmin_isf%clname, inum )
  294. cvarzisf = TRIM(sn_depmin_isf%clvar)
  295. CALL iom_get( inum, jpdom_data, cvarzisf, rzisf_tbl, 1) !: depth of shallowest point of the ice shelves base
  296. CALL iom_close(inum)
  297. !
  298. rhisf_tbl(:,:) = rhisf_tbl(:,:) - rzisf_tbl(:,:) !: tickness isf boundary layer
  299. !! compute first level of the top boundary layer
  300. DO ji = 1, jpi
  301. DO jj = 1, jpj
  302. jk = 2
  303. DO WHILE ( jk .LE. mbkt(ji,jj) .AND. gdepw_0(ji,jj,jk) < rzisf_tbl(ji,jj) ) ; jk = jk + 1 ; END DO
  304. misfkt(ji,jj) = jk-1
  305. END DO
  306. END DO
  307. ELSE IF ( nn_isf == 4 ) THEN
  308. ! as in nn_isf == 1
  309. rhisf_tbl(:,:) = rn_hisf_tbl
  310. misfkt(:,:) = mikt(:,:) ! same indice for bg03 et cav => used in isfdiv
  311. ! load variable used in fldread (use for temporal interpolation of isf fwf forcing)
  312. IF( .NOT.l_isfcpl ) THEN
  313. ALLOCATE( sf_fwfisf(1), sf_qisf(1), STAT=ierror )
  314. ALLOCATE( sf_fwfisf(1)%fnow(jpi,jpj,1), sf_fwfisf(1)%fdta(jpi,jpj,1,2) )
  315. ALLOCATE( sf_qisf(1)%fnow(jpi,jpj,1), sf_qisf(1)%fdta(jpi,jpj,1,2) )
  316. CALL fld_fill(sf_fwfisf, (/ sn_fwfisf /), cn_dirisf, 'sbc_isf_init', 'read fresh water flux isf data', 'namsbc_isf')
  317. !CALL fld_fill( sf_qisf , (/ sn_qisf /), cn_dirisf, 'sbc_isf_init', 'read heat flux isf data' , 'namsbc_isf' )
  318. ENDIF
  319. END IF
  320. ! save initial top boundary layer thickness
  321. rhisf_tbl_0(:,:) = rhisf_tbl(:,:)
  322. !
  323. END SUBROUTINE sbc_isf_init
  324. INTEGER FUNCTION sbc_isf_alloc()
  325. !!----------------------------------------------------------------------
  326. !! *** FUNCTION sbc_isf_rnf_alloc ***
  327. !!----------------------------------------------------------------------
  328. sbc_isf_alloc = 0 ! set to zero if no array to be allocated
  329. IF( .NOT. ALLOCATED( qisf ) ) THEN
  330. ALLOCATE( risf_tsc(jpi,jpj,jpts), risf_tsc_b(jpi,jpj,jpts), qisf(jpi,jpj) , &
  331. & rhisf_tbl(jpi,jpj) , r1_hisf_tbl(jpi,jpj), rzisf_tbl(jpi,jpj) , &
  332. & ttbl(jpi,jpj) , stbl(jpi,jpj) , utbl(jpi,jpj) , &
  333. & vtbl(jpi, jpj) , risfLeff(jpi,jpj) , rhisf_tbl_0(jpi,jpj), &
  334. & ralpha(jpi,jpj) , misfkt(jpi,jpj) , misfkb(jpi,jpj) , &
  335. & STAT= sbc_isf_alloc )
  336. !
  337. IF( lk_mpp ) CALL mpp_sum ( sbc_isf_alloc )
  338. IF( sbc_isf_alloc /= 0 ) CALL ctl_warn('sbc_isf_alloc: failed to allocate arrays.')
  339. !
  340. ENDIF
  341. END FUNCTION
  342. SUBROUTINE sbc_isf_bg03(kt)
  343. !!==========================================================================
  344. !! *** SUBROUTINE sbcisf_bg03 ***
  345. !! add net heat and fresh water flux from ice shelf melting
  346. !! into the adjacent ocean using the parameterisation by
  347. !! Beckmann and Goosse (2003), "A parameterization of ice shelf-ocean
  348. !! interaction for climate models", Ocean Modelling 5(2003) 157-170.
  349. !! (hereafter BG)
  350. !!==========================================================================
  351. !!----------------------------------------------------------------------
  352. !! sbc_isf_bg03 : routine called from sbcmod
  353. !!----------------------------------------------------------------------
  354. !!
  355. !! ** Purpose : Add heat and fresh water fluxes due to ice shelf melting
  356. !! ** Reference : Beckmann et Goosse, 2003, Ocean Modelling
  357. !!
  358. !! History :
  359. !! ! 06-02 (C. Wang) Original code
  360. !!----------------------------------------------------------------------
  361. INTEGER, INTENT ( in ) :: kt
  362. INTEGER :: ji, jj, jk, jish !temporary integer
  363. INTEGER :: ijkmin
  364. INTEGER :: ii, ij, ik
  365. INTEGER :: inum
  366. REAL(wp) :: zt_sum ! sum of the temperature between 200m and 600m
  367. REAL(wp) :: zt_ave ! averaged temperature between 200m and 600m
  368. REAL(wp) :: zt_frz ! freezing point temperature at depth z
  369. REAL(wp) :: zpress ! pressure to compute the freezing point in depth
  370. !!----------------------------------------------------------------------
  371. IF ( nn_timing == 1 ) CALL timing_start('sbc_isf_bg03')
  372. !
  373. ! This test is false only in the very first time step of a run (JMM ???- Initialy build to skip 1rst year of run )
  374. DO ji = 1, jpi
  375. DO jj = 1, jpj
  376. ik = misfkt(ji,jj)
  377. !! Initialize arrays to 0 (each step)
  378. zt_sum = 0.e0_wp
  379. IF ( ik .GT. 1 ) THEN
  380. ! 3. -----------the average temperature between 200m and 600m ---------------------
  381. DO jk = misfkt(ji,jj),misfkb(ji,jj)
  382. ! freezing point temperature at ice shelf base BG eq. 2 (JMM sign pb ??? +7.64e-4 !!!)
  383. ! after verif with UNESCO, wrong sign in BG eq. 2
  384. ! Calculate freezing temperature
  385. zpress = grav*rau0*fsdept(ji,jj,ik)*1.e-04
  386. CALL eos_fzp(tsb(ji,jj,ik,jp_sal), zt_frz, zpress)
  387. zt_sum = zt_sum + (tsn(ji,jj,ik,jp_tem)-zt_frz) * fse3t(ji,jj,ik) * tmask(ji,jj,ik) ! sum temp
  388. ENDDO
  389. zt_ave = zt_sum/rhisf_tbl(ji,jj) ! calcul mean value
  390. ! 4. ------------Net heat flux and fresh water flux due to the ice shelf
  391. ! For those corresponding to zonal boundary
  392. qisf(ji,jj) = - rau0 * rcp * rn_gammat0 * risfLeff(ji,jj) * e1t(ji,jj) * zt_ave &
  393. & / (e1t(ji,jj) * e2t(ji,jj)) * tmask(ji,jj,ik)
  394. fwfisf(ji,jj) = qisf(ji,jj) / lfusisf !fresh water flux kg/(m2s)
  395. ELSE
  396. qisf(ji,jj) = 0._wp ; fwfisf(ji,jj) = 0._wp
  397. END IF
  398. ENDDO
  399. ENDDO
  400. !
  401. IF( nn_timing == 1 ) CALL timing_stop('sbc_isf_bg03')
  402. END SUBROUTINE sbc_isf_bg03
  403. SUBROUTINE sbc_isf_cav( kt )
  404. !!---------------------------------------------------------------------
  405. !! *** ROUTINE sbc_isf_cav ***
  406. !!
  407. !! ** Purpose : handle surface boundary condition under ice shelf
  408. !!
  409. !! ** Method : -
  410. !!
  411. !! ** Action : utau, vtau : remain unchanged
  412. !! taum, wndm : remain unchanged
  413. !! qns : update heat flux below ice shelf
  414. !! emp, emps : update freshwater flux below ice shelf
  415. !!---------------------------------------------------------------------
  416. INTEGER, INTENT(in) :: kt ! ocean time step
  417. !
  418. LOGICAL :: ln_isomip = .true.
  419. REAL(wp), DIMENSION(:,:), POINTER :: zfrz,zpress,zti
  420. REAL(wp), DIMENSION(:,:), POINTER :: zgammat2d, zgammas2d
  421. !REAL(wp), DIMENSION(:,:), POINTER :: zqisf, zfwfisf
  422. REAL(wp) :: zlamb1, zlamb2, zlamb3
  423. REAL(wp) :: zeps1,zeps2,zeps3,zeps4,zeps6,zeps7
  424. REAL(wp) :: zaqe,zbqe,zcqe,zaqer,zdis,zsfrz,zcfac
  425. REAL(wp) :: zfwflx, zhtflx, zhtflx_b
  426. REAL(wp) :: zgammat, zgammas
  427. REAL(wp) :: zeps = -1.e-20_wp !== Local constant initialization ==!
  428. INTEGER :: ji, jj ! dummy loop indices
  429. INTEGER :: ii0, ii1, ij0, ij1 ! temporary integers
  430. INTEGER :: ierror ! return error code
  431. LOGICAL :: lit=.TRUE.
  432. INTEGER :: nit
  433. !!---------------------------------------------------------------------
  434. !
  435. ! coeficient for linearisation of tfreez
  436. zlamb1=-0.0575
  437. zlamb2=0.0901
  438. zlamb3=-7.61e-04
  439. IF( nn_timing == 1 ) CALL timing_start('sbc_isf_cav')
  440. !
  441. CALL wrk_alloc( jpi,jpj, zfrz,zpress,zti, zgammat2d, zgammas2d )
  442. zcfac=0.0_wp
  443. IF (ln_conserve) zcfac=1.0_wp
  444. zpress(:,:)=0.0_wp
  445. zgammat2d(:,:)=0.0_wp
  446. zgammas2d(:,:)=0.0_wp
  447. !
  448. !
  449. !CDIR COLLAPSE
  450. DO jj = 1, jpj
  451. DO ji = 1, jpi
  452. ! Crude approximation for pressure (but commonly used)
  453. ! 1e-04 to convert from Pa to dBar
  454. zpress(ji,jj)=grav*rau0*fsdepw(ji,jj,mikt(ji,jj))*1.e-04
  455. !
  456. END DO
  457. END DO
  458. ! convert CT to Tpot
  459. IF (ln_useCT) ttbl=eos_pt_from_ct(ttbl,stbl)
  460. ! Calculate in-situ temperature (ref to surface)
  461. zti(:,:)=tinsitu( ttbl, stbl, zpress )
  462. ! Calculate freezing temperature
  463. CALL eos_fzp( sss_m(:,:), zfrz(:,:), zpress )
  464. zhtflx=0._wp ; zfwflx=0._wp
  465. IF (nn_isfblk == 1) THEN
  466. DO jj = 1, jpj
  467. DO ji = 1, jpi
  468. IF (mikt(ji,jj) > 1 ) THEN
  469. nit = 1; lit = .TRUE.; zgammat=rn_gammat0; zgammas=rn_gammas0; zhtflx_b=0._wp
  470. DO WHILE ( lit )
  471. ! compute gamma
  472. CALL sbc_isf_gammats(zgammat, zgammas, zhtflx, zfwflx, ji, jj, lit)
  473. ! zhtflx is upward heat flux (out of ocean)
  474. zhtflx = zgammat*rcp*rau0*(zti(ji,jj)-zfrz(ji,jj))
  475. ! zwflx is upward water flux
  476. zfwflx = - zhtflx/lfusisf
  477. ! test convergence and compute gammat
  478. IF ( (zhtflx - zhtflx_b) .LE. 0.01 ) lit = .FALSE.
  479. nit = nit + 1
  480. IF (nit .GE. 100) CALL ctl_stop( 'STOP', 'sbc_isf_hol99 : too many iteration ...' )
  481. ! save gammat and compute zhtflx_b
  482. zgammat2d(ji,jj)=zgammat
  483. zhtflx_b = zhtflx
  484. END DO
  485. qisf(ji,jj) = - zhtflx
  486. ! For genuine ISOMIP protocol this should probably be something like
  487. fwfisf(ji,jj) = zfwflx
  488. ELSE
  489. fwfisf(ji,jj) = 0._wp
  490. qisf(ji,jj) = 0._wp
  491. END IF
  492. !
  493. END DO
  494. END DO
  495. ELSE IF (nn_isfblk == 2 ) THEN
  496. ! More complicated 3 equation thermodynamics as in MITgcm
  497. !CDIR COLLAPSE
  498. DO jj = 2, jpj
  499. DO ji = 2, jpi
  500. IF (mikt(ji,jj) > 1 ) THEN
  501. nit=1; lit=.TRUE.; zgammat=rn_gammat0; zgammas=rn_gammas0; zhtflx_b=0._wp; zhtflx=0._wp
  502. DO WHILE ( lit )
  503. CALL sbc_isf_gammats(zgammat, zgammas, zhtflx, zfwflx, ji, jj, lit)
  504. zeps1=rcp*rau0*zgammat
  505. zeps2=lfusisf*rau0*zgammas
  506. zeps3=rhoisf*rcpi*kappa/risfdep(ji,jj)
  507. zeps4=zlamb2+zlamb3*risfdep(ji,jj)
  508. zeps6=zeps4-zti(ji,jj)
  509. zeps7=zeps4-tsurf
  510. zaqe=zlamb1 * (zeps1 + zeps3)
  511. zaqer=0.5/zaqe
  512. zbqe=zeps1*zeps6+zeps3*zeps7-zeps2
  513. zcqe=zeps2*stbl(ji,jj)
  514. zdis=zbqe*zbqe-4.0*zaqe*zcqe
  515. ! Presumably zdis can never be negative because gammas is very small compared to gammat
  516. zsfrz=(-zbqe-SQRT(zdis))*zaqer
  517. IF (zsfrz .lt. 0.0) zsfrz=(-zbqe+SQRT(zdis))*zaqer
  518. zfrz(ji,jj)=zeps4+zlamb1*zsfrz
  519. ! zfwflx is upward water flux
  520. zfwflx= rau0 * zgammas * ( (zsfrz-stbl(ji,jj)) / zsfrz )
  521. IF ( rdivisf==0 ) THEN
  522. ! zhtflx is upward heat flux (out of ocean)
  523. ! If non conservative we have zcfac=0.0 so zhtflx is as ISOMIP but with different zfrz value
  524. zhtflx = ( zgammat*rau0 - zcfac*zfwflx ) * rcp * (zti(ji,jj) - zfrz(ji,jj) )
  525. ! zwflx is upward water flux
  526. ! If non conservative we have zcfac=0.0 so what follows is then zfwflx*sss_m/zsfrz
  527. zfwflx = ( zgammas*rau0 - zcfac*zfwflx ) * (zsfrz - stbl(ji,jj)) / stbl(ji,jj)
  528. ELSE
  529. zhtflx = zgammat*rau0 * rcp * (zti(ji,jj) - zfrz(ji,jj) )
  530. ! nothing to do for fwf
  531. END IF
  532. ! test convergence and compute gammat
  533. IF (( zhtflx - zhtflx_b) .LE. 0.01 ) lit = .FALSE.
  534. nit = nit + 1
  535. IF (nit .GE. 51) THEN
  536. WRITE(numout,*) "sbcisf : too many iteration ... ", &
  537. & zhtflx, zhtflx_b, zgammat, zgammas, nn_gammablk, ji, jj, mikt(ji,jj), narea
  538. CALL ctl_stop( 'STOP', 'sbc_isf_hol99 : too many iteration ...' )
  539. END IF
  540. ! save gammat and compute zhtflx_b
  541. zgammat2d(ji,jj)=zgammat
  542. zgammas2d(ji,jj)=zgammas
  543. zhtflx_b = zhtflx
  544. END DO
  545. ! If non conservative we have zcfac=0.0 so zhtflx is as ISOMIP but with different zfrz value
  546. qisf(ji,jj) = - zhtflx
  547. ! If non conservative we have zcfac=0.0 so what follows is then zfwflx*sss_m/zsfrz
  548. fwfisf(ji,jj) = zfwflx
  549. ELSE
  550. fwfisf(ji,jj) = 0._wp
  551. qisf(ji,jj) = 0._wp
  552. ENDIF
  553. !
  554. END DO
  555. END DO
  556. ENDIF
  557. ! lbclnk
  558. CALL lbc_lnk(zgammas2d(:,:),'T',1.)
  559. CALL lbc_lnk(zgammat2d(:,:),'T',1.)
  560. ! output
  561. CALL iom_put('isfgammat', zgammat2d)
  562. CALL iom_put('isfgammas', zgammas2d)
  563. !
  564. CALL wrk_dealloc( jpi,jpj, zfrz,zpress,zti, zgammat2d, zgammas2d )
  565. !
  566. IF( nn_timing == 1 ) CALL timing_stop('sbc_isf_cav')
  567. END SUBROUTINE sbc_isf_cav
  568. SUBROUTINE sbc_isf_gammats(gt, gs, zqhisf, zqwisf, ji, jj, lit )
  569. !!----------------------------------------------------------------------
  570. !! ** Purpose : compute the coefficient echange for heat flux
  571. !!
  572. !! ** Method : gamma assume constant or depends of u* and stability
  573. !!
  574. !! ** References : Holland and Jenkins, 1999, JPO, p1787-1800, eq 14
  575. !! Jenkins et al., 2010, JPO, p2298-2312
  576. !!---------------------------------------------------------------------
  577. REAL(wp), INTENT(inout) :: gt, gs, zqhisf, zqwisf
  578. INTEGER , INTENT(in) :: ji,jj
  579. LOGICAL , INTENT(inout) :: lit
  580. INTEGER :: ikt ! loop index
  581. REAL(wp) :: zut, zvt, zustar ! U, V at T point and friction velocity
  582. REAL(wp) :: zdku, zdkv ! U, V shear
  583. REAL(wp) :: zPr, zSc, zRc ! Prandtl, Scmidth and Richardson number
  584. REAL(wp) :: zmob, zmols ! Monin Obukov length, coriolis factor at T point
  585. REAL(wp) :: zbuofdep, zhnu ! Bouyancy length scale, sublayer tickness
  586. REAL(wp) :: zhmax ! limitation of mol
  587. REAL(wp) :: zetastar ! stability parameter
  588. REAL(wp) :: zgmolet, zgmoles, zgturb ! contribution of modelecular sublayer and turbulence
  589. REAL(wp) :: zcoef ! temporary coef
  590. REAL(wp) :: zdep
  591. REAL(wp), PARAMETER :: zxsiN = 0.052 ! dimensionless constant
  592. REAL(wp), PARAMETER :: epsln = 1.0e-20 ! a small positive number
  593. REAL(wp), PARAMETER :: znu = 1.95e-6 ! kinamatic viscosity of sea water (m2.s-1)
  594. REAL(wp) :: rcs = 1.0e-3_wp ! conversion: mm/s ==> m/s
  595. REAL(wp), DIMENSION(2) :: zts, zab
  596. !!---------------------------------------------------------------------
  597. !
  598. IF( nn_gammablk == 0 ) THEN
  599. !! gamma is constant (specified in namelist)
  600. gt = rn_gammat0
  601. gs = rn_gammas0
  602. lit = .FALSE.
  603. ELSE IF ( nn_gammablk == 1 ) THEN
  604. !! gamma is assume to be proportional to u*
  605. !! WARNING in case of Losh 2008 tbl parametrization,
  606. !! you have to used the mean value of u in the boundary layer)
  607. !! not yet coded
  608. !! Jenkins et al., 2010, JPO, p2298-2312
  609. ikt = mikt(ji,jj)
  610. !! Compute U and V at T points
  611. ! zut = 0.5 * ( utbl(ji-1,jj ) + utbl(ji,jj) )
  612. ! zvt = 0.5 * ( vtbl(ji ,jj-1) + vtbl(ji,jj) )
  613. zut = utbl(ji,jj)
  614. zvt = vtbl(ji,jj)
  615. !! compute ustar
  616. zustar = SQRT( rn_tfri2 * (zut * zut + zvt * zvt) )
  617. !! Compute mean value over the TBL
  618. !! Compute gammats
  619. gt = zustar * rn_gammat0
  620. gs = zustar * rn_gammas0
  621. lit = .FALSE.
  622. ELSE IF ( nn_gammablk == 2 ) THEN
  623. !! gamma depends of stability of boundary layer
  624. !! WARNING in case of Losh 2008 tbl parametrization,
  625. !! you have to used the mean value of u in the boundary layer)
  626. !! not yet coded
  627. !! Holland and Jenkins, 1999, JPO, p1787-1800, eq 14
  628. !! as MOL depends of flux and flux depends of MOL, best will be iteration (TO DO)
  629. ikt = mikt(ji,jj)
  630. !! Compute U and V at T points
  631. zut = 0.5 * ( utbl(ji-1,jj ) + utbl(ji,jj) )
  632. zvt = 0.5 * ( vtbl(ji ,jj-1) + vtbl(ji,jj) )
  633. !! compute ustar
  634. zustar = SQRT( rn_tfri2 * (zut * zut + zvt * zvt) )
  635. IF (zustar == 0._wp) THEN ! only for kt = 1 I think
  636. gt = rn_gammat0
  637. gs = rn_gammas0
  638. ELSE
  639. !! compute Rc number (as done in zdfric.F90)
  640. zcoef = 0.5 / fse3w(ji,jj,ikt)
  641. ! ! shear of horizontal velocity
  642. zdku = zcoef * ( un(ji-1,jj ,ikt ) + un(ji,jj,ikt ) &
  643. & -un(ji-1,jj ,ikt+1) - un(ji,jj,ikt+1) )
  644. zdkv = zcoef * ( vn(ji ,jj-1,ikt ) + vn(ji,jj,ikt ) &
  645. & -vn(ji ,jj-1,ikt+1) - vn(ji,jj,ikt+1) )
  646. ! ! richardson number (minimum value set to zero)
  647. zRc = rn2(ji,jj,ikt+1) / ( zdku*zdku + zdkv*zdkv + 1.e-20 )
  648. !! compute Pr and Sc number (can be improved)
  649. zPr = 13.8
  650. zSc = 2432.0
  651. !! compute gamma mole
  652. zgmolet = 12.5 * zPr ** (2.0/3.0) - 6.0
  653. zgmoles = 12.5 * zSc ** (2.0/3.0) -6.0
  654. !! compute bouyancy
  655. zts(jp_tem) = ttbl(ji,jj)
  656. zts(jp_sal) = stbl(ji,jj)
  657. zdep = fsdepw(ji,jj,ikt)
  658. !
  659. CALL eos_rab( zts, zdep, zab )
  660. !
  661. !! compute length scale
  662. zbuofdep = grav * ( zab(jp_tem) * zqhisf - zab(jp_sal) * zqwisf ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!
  663. !! compute Monin Obukov Length
  664. ! Maximum boundary layer depth
  665. zhmax = fsdept(ji,jj,mbkt(ji,jj)) - fsdepw(ji,jj,mikt(ji,jj)) -0.001
  666. ! Compute Monin obukhov length scale at the surface and Ekman depth:
  667. zmob = zustar ** 3 / (vkarmn * (zbuofdep + epsln))
  668. zmols = SIGN(1._wp, zmob) * MIN(ABS(zmob), zhmax) * tmask(ji,jj,ikt)
  669. !! compute eta* (stability parameter)
  670. zetastar = 1 / ( SQRT(1 + MAX(zxsiN * zustar / ( ABS(ff(ji,jj)) * zmols * zRc ), 0.0)))
  671. !! compute the sublayer thickness
  672. zhnu = 5 * znu / zustar
  673. !! compute gamma turb
  674. zgturb = 1/vkarmn * LOG(zustar * zxsiN * zetastar * zetastar / ( ABS(ff(ji,jj)) * zhnu )) &
  675. & + 1 / ( 2 * zxsiN * zetastar ) - 1/vkarmn
  676. !! compute gammats
  677. gt = zustar / (zgturb + zgmolet)
  678. gs = zustar / (zgturb + zgmoles)
  679. END IF
  680. END IF
  681. END SUBROUTINE
  682. SUBROUTINE sbc_isf_tbl( varin, varout, cptin )
  683. !!----------------------------------------------------------------------
  684. !! *** SUBROUTINE sbc_isf_tbl ***
  685. !!
  686. !! ** Purpose : compute mean T/S/U/V in the boundary layer
  687. !!
  688. !!----------------------------------------------------------------------
  689. REAL(wp), DIMENSION(:,:,:), INTENT(in) :: varin
  690. REAL(wp), DIMENSION(:,:) , INTENT(out):: varout
  691. CHARACTER(len=1), INTENT(in) :: cptin ! point of variable in/out
  692. REAL(wp) :: ze3, zhk
  693. REAL(wp), DIMENSION(:,:), POINTER :: zikt
  694. INTEGER :: ji,jj,jk
  695. INTEGER :: ikt,ikb
  696. INTEGER, DIMENSION(:,:), POINTER :: mkt, mkb
  697. CALL wrk_alloc( jpi,jpj, mkt, mkb )
  698. CALL wrk_alloc( jpi,jpj, zikt )
  699. ! get first and last level of tbl
  700. mkt(:,:) = misfkt(:,:)
  701. mkb(:,:) = misfkb(:,:)
  702. varout(:,:)=0._wp
  703. DO jj = 2,jpj
  704. DO ji = 2,jpi
  705. IF (ssmask(ji,jj) == 1) THEN
  706. ikt = mkt(ji,jj)
  707. ikb = mkb(ji,jj)
  708. ! level fully include in the ice shelf boundary layer
  709. DO jk = ikt, ikb - 1
  710. ze3 = fse3t_n(ji,jj,jk)
  711. IF (cptin == 'T' ) varout(ji,jj) = varout(ji,jj) + varin(ji,jj,jk) * r1_hisf_tbl(ji,jj) * ze3
  712. IF (cptin == 'U' ) varout(ji,jj) = varout(ji,jj) + 0.5_wp * (varin(ji,jj,jk) + varin(ji-1,jj,jk)) &
  713. & * r1_hisf_tbl(ji,jj) * ze3
  714. IF (cptin == 'V' ) varout(ji,jj) = varout(ji,jj) + 0.5_wp * (varin(ji,jj,jk) + varin(ji,jj-1,jk)) &
  715. & * r1_hisf_tbl(ji,jj) * ze3
  716. END DO
  717. ! level partially include in ice shelf boundary layer
  718. zhk = SUM( fse3t_n(ji, jj, ikt:ikb - 1)) * r1_hisf_tbl(ji,jj)
  719. IF (cptin == 'T') &
  720. & varout(ji,jj) = varout(ji,jj) + varin(ji,jj,ikb) * (1._wp - zhk)
  721. IF (cptin == 'U') &
  722. & varout(ji,jj) = varout(ji,jj) + 0.5_wp * (varin(ji,jj,ikb) + varin(ji-1,jj,ikb)) * (1._wp - zhk)
  723. IF (cptin == 'V') &
  724. & varout(ji,jj) = varout(ji,jj) + 0.5_wp * (varin(ji,jj,ikb) + varin(ji,jj-1,ikb)) * (1._wp - zhk)
  725. END IF
  726. END DO
  727. END DO
  728. CALL wrk_dealloc( jpi,jpj, mkt, mkb )
  729. CALL wrk_dealloc( jpi,jpj, zikt )
  730. IF (cptin == 'T') CALL lbc_lnk(varout,'T',1.)
  731. IF (cptin == 'U' .OR. cptin == 'V') CALL lbc_lnk(varout,'T',-1.)
  732. END SUBROUTINE sbc_isf_tbl
  733. SUBROUTINE sbc_isf_div( phdivn )
  734. !!----------------------------------------------------------------------
  735. !! *** SUBROUTINE sbc_isf_div ***
  736. !!
  737. !! ** Purpose : update the horizontal divergence with the runoff inflow
  738. !!
  739. !! ** Method :
  740. !! CAUTION : risf_tsc(:,:,jp_sal) is negative (outflow) increase the
  741. !! divergence and expressed in m/s
  742. !!
  743. !! ** Action : phdivn decreased by the runoff inflow
  744. !!----------------------------------------------------------------------
  745. REAL(wp), DIMENSION(:,:,:), INTENT(inout) :: phdivn ! horizontal divergence
  746. !!
  747. INTEGER :: ji, jj, jk ! dummy loop indices
  748. INTEGER :: ikt, ikb
  749. INTEGER :: nk_isf
  750. REAL(wp) :: zhk, z1_hisf_tbl, zhisf_tbl
  751. REAL(wp) :: zfact ! local scalar
  752. !!----------------------------------------------------------------------
  753. !
  754. zfact = 0.5_wp
  755. !
  756. IF (lk_vvl) THEN ! need to re compute level distribution of isf fresh water
  757. DO jj = 1,jpj
  758. DO ji = 1,jpi
  759. ikt = misfkt(ji,jj)
  760. ikb = misfkt(ji,jj)
  761. ! thickness of boundary layer at least the top level thickness
  762. rhisf_tbl(ji,jj) = MAX(rhisf_tbl_0(ji,jj), fse3t(ji,jj,ikt))
  763. ! determine the deepest level influenced by the boundary layer
  764. ! test on tmask useless ?????
  765. DO jk = ikt, mbkt(ji,jj)
  766. IF ( (SUM(fse3t(ji,jj,ikt:jk-1)) .LT. rhisf_tbl(ji,jj)) .AND. (tmask(ji,jj,jk) == 1) ) ikb = jk
  767. END DO
  768. rhisf_tbl(ji,jj) = MIN(rhisf_tbl(ji,jj), SUM(fse3t(ji,jj,ikt:ikb))) ! limit the tbl to water thickness.
  769. misfkb(ji,jj) = ikb ! last wet level of the tbl
  770. r1_hisf_tbl(ji,jj) = 1._wp / rhisf_tbl(ji,jj)
  771. zhk = SUM( fse3t(ji, jj, ikt:ikb - 1)) * r1_hisf_tbl(ji,jj) ! proportion of tbl cover by cell from ikt to ikb - 1
  772. ralpha(ji,jj) = rhisf_tbl(ji,jj) * (1._wp - zhk ) / fse3t(ji,jj,ikb) ! proportion of bottom cell influenced by boundary layer
  773. END DO
  774. END DO
  775. END IF ! vvl case
  776. !
  777. DO jj = 1,jpj
  778. DO ji = 1,jpi
  779. ikt = misfkt(ji,jj)
  780. ikb = misfkb(ji,jj)
  781. ! level fully include in the ice shelf boundary layer
  782. DO jk = ikt, ikb - 1
  783. phdivn(ji,jj,jk) = phdivn(ji,jj,jk) + ( fwfisf(ji,jj) + fwfisf_b(ji,jj) ) &
  784. & * r1_hisf_tbl(ji,jj) * r1_rau0 * zfact
  785. END DO
  786. ! level partially include in ice shelf boundary layer
  787. phdivn(ji,jj,ikb) = phdivn(ji,jj,ikb) + ( fwfisf(ji,jj) &
  788. & + fwfisf_b(ji,jj) ) * r1_hisf_tbl(ji,jj) * r1_rau0 * zfact * ralpha(ji,jj)
  789. !== ice shelf melting mass distributed over several levels ==!
  790. END DO
  791. END DO
  792. !
  793. END SUBROUTINE sbc_isf_div
  794. FUNCTION tinsitu( ptem, psal, ppress ) RESULT( pti )
  795. !!----------------------------------------------------------------------
  796. !! *** ROUTINE eos_init ***
  797. !!
  798. !! ** Purpose : Compute the in-situ temperature [Celcius]
  799. !!
  800. !! ** Method :
  801. !!
  802. !! Reference : Bryden,h.,1973,deep-sea res.,20,401-408
  803. !!----------------------------------------------------------------------
  804. REAL(wp), DIMENSION(jpi,jpj), INTENT(in ) :: ptem ! potential temperature [Celcius]
  805. REAL(wp), DIMENSION(jpi,jpj), INTENT(in ) :: psal ! salinity [psu]
  806. REAL(wp), DIMENSION(jpi,jpj), INTENT(in ) :: ppress ! pressure [dBar]
  807. REAL(wp), DIMENSION(:,:), POINTER :: pti ! in-situ temperature [Celcius]
  808. ! REAL(wp) :: fsatg
  809. ! REAL(wp) :: pfps, pfpt, pfphp
  810. REAL(wp) :: zt, zs, zp, zh, zq, zxk
  811. INTEGER :: ji, jj ! dummy loop indices
  812. !
  813. CALL wrk_alloc( jpi,jpj, pti )
  814. !
  815. DO jj=1,jpj
  816. DO ji=1,jpi
  817. zh = ppress(ji,jj)
  818. ! Theta1
  819. zt = ptem(ji,jj)
  820. zs = psal(ji,jj)
  821. zp = 0.0
  822. zxk= zh * fsatg( zs, zt, zp )
  823. zt = zt + 0.5 * zxk
  824. zq = zxk
  825. ! Theta2
  826. zp = zp + 0.5 * zh
  827. zxk= zh*fsatg( zs, zt, zp )
  828. zt = zt + 0.29289322 * ( zxk - zq )
  829. zq = 0.58578644 * zxk + 0.121320344 * zq
  830. ! Theta3
  831. zxk= zh * fsatg( zs, zt, zp )
  832. zt = zt + 1.707106781 * ( zxk - zq )
  833. zq = 3.414213562 * zxk - 4.121320344 * zq
  834. ! Theta4
  835. zp = zp + 0.5 * zh
  836. zxk= zh * fsatg( zs, zt, zp )
  837. pti(ji,jj) = zt + ( zxk - 2.0 * zq ) / 6.0
  838. END DO
  839. END DO
  840. !
  841. CALL wrk_dealloc( jpi,jpj, pti )
  842. !
  843. END FUNCTION tinsitu
  844. !
  845. FUNCTION fsatg( pfps, pfpt, pfphp )
  846. !!----------------------------------------------------------------------
  847. !! *** FUNCTION fsatg ***
  848. !!
  849. !! ** Purpose : Compute the Adiabatic laspse rate [Celcius].[decibar]^-1
  850. !!
  851. !! ** Reference : Bryden,h.,1973,deep-sea res.,20,401-408
  852. !!
  853. !! ** units : pressure pfphp decibars
  854. !! temperature pfpt deg celsius (ipts-68)
  855. !! salinity pfps (ipss-78)
  856. !! adiabatic fsatg deg. c/decibar
  857. !!----------------------------------------------------------------------
  858. REAL(wp) :: pfps, pfpt, pfphp
  859. REAL(wp) :: fsatg
  860. !
  861. fsatg = (((-2.1687e-16*pfpt+1.8676e-14)*pfpt-4.6206e-13)*pfphp &
  862. & +((2.7759e-12*pfpt-1.1351e-10)*(pfps-35.)+((-5.4481e-14*pfpt &
  863. & +8.733e-12)*pfpt-6.7795e-10)*pfpt+1.8741e-8))*pfphp &
  864. & +(-4.2393e-8*pfpt+1.8932e-6)*(pfps-35.) &
  865. & +((6.6228e-10*pfpt-6.836e-8)*pfpt+8.5258e-6)*pfpt+3.5803e-5
  866. !
  867. END FUNCTION fsatg
  868. !!======================================================================
  869. END MODULE sbcisf