limthd_dh.F90 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739
  1. MODULE limthd_dh
  2. !!======================================================================
  3. !! *** MODULE limthd_dh ***
  4. !! LIM-3 : thermodynamic growth and decay of the ice
  5. !!======================================================================
  6. !! History : LIM ! 2003-05 (M. Vancoppenolle) Original code in 1D
  7. !! ! 2005-06 (M. Vancoppenolle) 3D version
  8. !! 3.2 ! 2009-07 (M. Vancoppenolle, Y. Aksenov, G. Madec) bug correction in wfx_snw & wfx_ice
  9. !! 3.4 ! 2011-02 (G. Madec) dynamical allocation
  10. !! 3.5 ! 2012-10 (G. Madec & co) salt flux + bug fixes
  11. !!----------------------------------------------------------------------
  12. #if defined key_lim3
  13. !!----------------------------------------------------------------------
  14. !! 'key_lim3' LIM3 sea-ice model
  15. !!----------------------------------------------------------------------
  16. !! lim_thd_dh : vertical accr./abl. and lateral ablation of sea ice
  17. !!----------------------------------------------------------------------
  18. USE par_oce ! ocean parameters
  19. USE phycst ! physical constants (OCE directory)
  20. USE sbc_oce ! Surface boundary condition: ocean fields
  21. USE ice ! LIM variables
  22. USE thd_ice ! LIM thermodynamics
  23. USE in_out_manager ! I/O manager
  24. USE lib_mpp ! MPP library
  25. USE wrk_nemo ! work arrays
  26. USE lib_fortran ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined)
  27. IMPLICIT NONE
  28. PRIVATE
  29. PUBLIC lim_thd_dh ! called by lim_thd
  30. PUBLIC lim_thd_snwblow ! called in sbcblk/sbcclio/sbccpl and here
  31. INTERFACE lim_thd_snwblow
  32. MODULE PROCEDURE lim_thd_snwblow_1d, lim_thd_snwblow_2d
  33. END INTERFACE
  34. !!----------------------------------------------------------------------
  35. !! NEMO/LIM3 4.0 , UCL - NEMO Consortium (2010)
  36. !! $Id: limthd_dh.F90 4990 2014-12-15 16:42:49Z timgraham $
  37. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  38. !!----------------------------------------------------------------------
  39. CONTAINS
  40. SUBROUTINE lim_thd_dh( kideb, kiut )
  41. !!------------------------------------------------------------------
  42. !! *** ROUTINE lim_thd_dh ***
  43. !!
  44. !! ** Purpose : determines variations of ice and snow thicknesses.
  45. !!
  46. !! ** Method : Ice/Snow surface melting arises from imbalance in surface fluxes
  47. !! Bottom accretion/ablation arises from flux budget
  48. !! Snow thickness can increase by precipitation and decrease by sublimation
  49. !! If snow load excesses Archmiede limit, snow-ice is formed by
  50. !! the flooding of sea-water in the snow
  51. !!
  52. !! 1) Compute available flux of heat for surface ablation
  53. !! 2) Compute snow and sea ice enthalpies
  54. !! 3) Surface ablation and sublimation
  55. !! 4) Bottom accretion/ablation
  56. !! 5) Case of Total ablation
  57. !! 6) Snow ice formation
  58. !!
  59. !! References : Bitz and Lipscomb, 1999, J. Geophys. Res.
  60. !! Fichefet T. and M. Maqueda 1997, J. Geophys. Res., 102(C6), 12609-12646
  61. !! Vancoppenolle, Fichefet and Bitz, 2005, Geophys. Res. Let.
  62. !! Vancoppenolle et al.,2009, Ocean Modelling
  63. !!------------------------------------------------------------------
  64. INTEGER , INTENT(in) :: kideb, kiut ! Start/End point on which the the computation is applied
  65. !!
  66. INTEGER :: ji , jk ! dummy loop indices
  67. INTEGER :: ii, ij ! 2D corresponding indices to ji
  68. INTEGER :: iter
  69. REAL(wp) :: ztmelts ! local scalar
  70. REAL(wp) :: zdum
  71. REAL(wp) :: zfracs ! fractionation coefficient for bottom salt entrapment
  72. REAL(wp) :: zs_snic ! snow-ice salinity
  73. REAL(wp) :: zswi1 ! switch for computation of bottom salinity
  74. REAL(wp) :: zswi12 ! switch for computation of bottom salinity
  75. REAL(wp) :: zswi2 ! switch for computation of bottom salinity
  76. REAL(wp) :: zgrr ! bottom growth rate
  77. REAL(wp) :: zt_i_new ! bottom formation temperature
  78. REAL(wp) :: zQm ! enthalpy exchanged with the ocean (J/m2), >0 towards the ocean
  79. REAL(wp) :: zEi ! specific enthalpy of sea ice (J/kg)
  80. REAL(wp) :: zEw ! specific enthalpy of exchanged water (J/kg)
  81. REAL(wp) :: zdE ! specific enthalpy difference (J/kg)
  82. REAL(wp) :: zfmdt ! exchange mass flux x time step (J/m2), >0 towards the ocean
  83. REAL(wp) :: zsstK ! SST in Kelvin
  84. REAL(wp), POINTER, DIMENSION(:) :: zqprec ! energy of fallen snow (J.m-3)
  85. REAL(wp), POINTER, DIMENSION(:) :: zq_su ! heat for surface ablation (J.m-2)
  86. REAL(wp), POINTER, DIMENSION(:) :: zq_bo ! heat for bottom ablation (J.m-2)
  87. REAL(wp), POINTER, DIMENSION(:) :: zq_rema ! remaining heat at the end of the routine (J.m-2)
  88. REAL(wp), POINTER, DIMENSION(:) :: zf_tt ! Heat budget to determine melting or freezing(W.m-2)
  89. REAL(wp), POINTER, DIMENSION(:) :: zevap_rema ! remaining mass flux from sublimation (kg.m-2)
  90. REAL(wp), POINTER, DIMENSION(:) :: zdh_s_mel ! snow melt
  91. REAL(wp), POINTER, DIMENSION(:) :: zdh_s_pre ! snow precipitation
  92. REAL(wp), POINTER, DIMENSION(:) :: zdh_s_sub ! snow sublimation
  93. REAL(wp), POINTER, DIMENSION(:,:) :: zdeltah
  94. REAL(wp), POINTER, DIMENSION(:,:) :: zh_i ! ice layer thickness
  95. INTEGER , POINTER, DIMENSION(:,:) :: icount ! number of layers vanished by melting
  96. REAL(wp), POINTER, DIMENSION(:) :: zqh_i ! total ice heat content (J.m-2)
  97. REAL(wp), POINTER, DIMENSION(:) :: zsnw ! distribution of snow after wind blowing
  98. REAL(wp) :: zswitch_sal
  99. ! Heat conservation
  100. INTEGER :: num_iter_max
  101. !!------------------------------------------------------------------
  102. ! Discriminate between varying salinity (nn_icesal=2) and prescribed cases (other values)
  103. SELECT CASE( nn_icesal ) ! varying salinity or not
  104. CASE( 1, 3 ) ; zswitch_sal = 0 ! prescribed salinity profile
  105. CASE( 2 ) ; zswitch_sal = 1 ! varying salinity profile
  106. END SELECT
  107. CALL wrk_alloc( jpij, zqprec, zq_su, zq_bo, zf_tt, zq_rema, zsnw, zevap_rema )
  108. CALL wrk_alloc( jpij, zdh_s_mel, zdh_s_pre, zdh_s_sub, zqh_i )
  109. CALL wrk_alloc( jpij, nlay_i, zdeltah, zh_i )
  110. CALL wrk_alloc( jpij, nlay_i, icount )
  111. dh_i_surf (:) = 0._wp ; dh_i_bott (:) = 0._wp ; dh_snowice(:) = 0._wp ; dh_i_sub(:) = 0._wp
  112. dsm_i_se_1d(:) = 0._wp ; dsm_i_si_1d(:) = 0._wp
  113. zqprec (:) = 0._wp ; zq_su (:) = 0._wp ; zq_bo (:) = 0._wp ; zf_tt(:) = 0._wp
  114. zq_rema (:) = 0._wp ; zsnw (:) = 0._wp ; zevap_rema(:) = 0._wp ;
  115. zdh_s_mel(:) = 0._wp ; zdh_s_pre(:) = 0._wp ; zdh_s_sub(:) = 0._wp ; zqh_i(:) = 0._wp
  116. zdeltah(:,:) = 0._wp ; zh_i(:,:) = 0._wp
  117. icount (:,:) = 0
  118. ! Initialize enthalpy at nlay_i+1
  119. DO ji = kideb, kiut
  120. q_i_1d(ji,nlay_i+1) = 0._wp
  121. END DO
  122. ! initialize layer thicknesses and enthalpies
  123. h_i_old (:,0:nlay_i+1) = 0._wp
  124. qh_i_old(:,0:nlay_i+1) = 0._wp
  125. DO jk = 1, nlay_i
  126. DO ji = kideb, kiut
  127. h_i_old (ji,jk) = ht_i_1d(ji) * r1_nlay_i
  128. qh_i_old(ji,jk) = q_i_1d(ji,jk) * h_i_old(ji,jk)
  129. ENDDO
  130. ENDDO
  131. !
  132. !------------------------------------------------------------------------------!
  133. ! 1) Calculate available heat for surface and bottom ablation !
  134. !------------------------------------------------------------------------------!
  135. !
  136. DO ji = kideb, kiut
  137. zdum = qns_ice_1d(ji) + ( 1._wp - i0(ji) ) * qsr_ice_1d(ji) - fc_su(ji)
  138. zf_tt(ji) = fc_bo_i(ji) + fhtur_1d(ji) + fhld_1d(ji)
  139. zq_su (ji) = MAX( 0._wp, zdum * rdt_ice ) * MAX( 0._wp , SIGN( 1._wp, t_su_1d(ji) - rt0 ) )
  140. zq_bo (ji) = MAX( 0._wp, zf_tt(ji) * rdt_ice )
  141. END DO
  142. !
  143. !------------------------------------------------------------------------------!
  144. ! If snow temperature is above freezing point, then snow melts
  145. ! (should not happen but sometimes it does)
  146. !------------------------------------------------------------------------------!
  147. DO ji = kideb, kiut
  148. IF( t_s_1d(ji,1) > rt0 ) THEN !!! Internal melting
  149. ! Contribution to heat flux to the ocean [W.m-2], < 0
  150. hfx_res_1d(ji) = hfx_res_1d(ji) + q_s_1d(ji,1) * ht_s_1d(ji) * a_i_1d(ji) * r1_rdtice
  151. ! Contribution to mass flux
  152. wfx_snw_1d(ji) = wfx_snw_1d(ji) + rhosn * ht_s_1d(ji) * a_i_1d(ji) * r1_rdtice
  153. ! updates
  154. ht_s_1d(ji) = 0._wp
  155. q_s_1d (ji,1) = 0._wp
  156. t_s_1d (ji,1) = rt0
  157. END IF
  158. END DO
  159. !------------------------------------------------------------!
  160. ! 2) Computing layer thicknesses and enthalpies. !
  161. !------------------------------------------------------------!
  162. !
  163. DO jk = 1, nlay_i
  164. DO ji = kideb, kiut
  165. zh_i(ji,jk) = ht_i_1d(ji) * r1_nlay_i
  166. zqh_i(ji) = zqh_i(ji) + q_i_1d(ji,jk) * zh_i(ji,jk)
  167. END DO
  168. END DO
  169. !
  170. !------------------------------------------------------------------------------|
  171. ! 3) Surface ablation and sublimation |
  172. !------------------------------------------------------------------------------|
  173. !
  174. !-------------------------
  175. ! 3.1 Snow precips / melt
  176. !-------------------------
  177. ! Snow accumulation in one thermodynamic time step
  178. ! snowfall is partitionned between leads and ice
  179. ! if snow fall was uniform, a fraction (1-at_i) would fall into leads
  180. ! but because of the winds, more snow falls on leads than on sea ice
  181. ! and a greater fraction (1-at_i)^beta of the total mass of snow
  182. ! (beta < 1) falls in leads.
  183. ! In reality, beta depends on wind speed,
  184. ! and should decrease with increasing wind speed but here, it is
  185. ! considered as a constant. an average value is 0.66
  186. ! Martin Vancoppenolle, December 2006
  187. CALL lim_thd_snwblow( 1. - at_i_1d(kideb:kiut), zsnw(kideb:kiut) ) ! snow distribution over ice after wind blowing
  188. zdeltah(:,:) = 0._wp
  189. DO ji = kideb, kiut
  190. !-----------
  191. ! Snow fall
  192. !-----------
  193. ! thickness change
  194. zdh_s_pre(ji) = zsnw(ji) * sprecip_1d(ji) * rdt_ice * r1_rhosn / at_i_1d(ji)
  195. ! enthalpy of the precip (>0, J.m-3)
  196. zqprec (ji) = - qprec_ice_1d(ji)
  197. IF( sprecip_1d(ji) == 0._wp ) zqprec(ji) = 0._wp
  198. ! heat flux from snow precip (>0, W.m-2)
  199. hfx_spr_1d(ji) = hfx_spr_1d(ji) + zdh_s_pre(ji) * a_i_1d(ji) * zqprec(ji) * r1_rdtice
  200. ! mass flux, <0
  201. wfx_spr_1d(ji) = wfx_spr_1d(ji) - rhosn * a_i_1d(ji) * zdh_s_pre(ji) * r1_rdtice
  202. !---------------------
  203. ! Melt of falling snow
  204. !---------------------
  205. ! thickness change
  206. rswitch = MAX( 0._wp , SIGN( 1._wp , zqprec(ji) - epsi20 ) )
  207. zdeltah (ji,1) = - rswitch * zq_su(ji) / MAX( zqprec(ji) , epsi20 )
  208. zdeltah (ji,1) = MAX( - zdh_s_pre(ji), zdeltah(ji,1) ) ! bound melting
  209. ! heat used to melt snow (W.m-2, >0)
  210. hfx_snw_1d(ji) = hfx_snw_1d(ji) - zdeltah(ji,1) * a_i_1d(ji) * zqprec(ji) * r1_rdtice
  211. ! snow melting only = water into the ocean (then without snow precip), >0
  212. wfx_snw_1d(ji) = wfx_snw_1d(ji) - rhosn * a_i_1d(ji) * zdeltah(ji,1) * r1_rdtice
  213. ! updates available heat + precipitations after melting
  214. zq_su (ji) = MAX( 0._wp , zq_su (ji) + zdeltah(ji,1) * zqprec(ji) )
  215. zdh_s_pre (ji) = zdh_s_pre(ji) + zdeltah(ji,1)
  216. ! update thickness
  217. ht_s_1d(ji) = MAX( 0._wp , ht_s_1d(ji) + zdh_s_pre(ji) )
  218. END DO
  219. ! If heat still available (zq_su > 0), then melt more snow
  220. zdeltah(:,:) = 0._wp
  221. DO jk = 1, nlay_s
  222. DO ji = kideb, kiut
  223. ! thickness change
  224. rswitch = 1._wp - MAX( 0._wp, SIGN( 1._wp, - ht_s_1d(ji) ) )
  225. rswitch = rswitch * ( MAX( 0._wp, SIGN( 1._wp, q_s_1d(ji,jk) - epsi20 ) ) )
  226. zdeltah (ji,jk) = - rswitch * zq_su(ji) / MAX( q_s_1d(ji,jk), epsi20 )
  227. zdeltah (ji,jk) = MAX( zdeltah(ji,jk) , - ht_s_1d(ji) ) ! bound melting
  228. zdh_s_mel(ji) = zdh_s_mel(ji) + zdeltah(ji,jk)
  229. ! heat used to melt snow(W.m-2, >0)
  230. hfx_snw_1d(ji) = hfx_snw_1d(ji) - zdeltah(ji,jk) * a_i_1d(ji) * q_s_1d(ji,jk) * r1_rdtice
  231. ! snow melting only = water into the ocean (then without snow precip)
  232. wfx_snw_1d(ji) = wfx_snw_1d(ji) - rhosn * a_i_1d(ji) * zdeltah(ji,jk) * r1_rdtice
  233. ! updates available heat + thickness
  234. zq_su (ji) = MAX( 0._wp , zq_su (ji) + zdeltah(ji,jk) * q_s_1d(ji,jk) )
  235. ht_s_1d(ji) = MAX( 0._wp , ht_s_1d(ji) + zdeltah(ji,jk) )
  236. END DO
  237. END DO
  238. !------------------------------
  239. ! 3.2 Sublimation (part1: snow)
  240. !------------------------------
  241. ! qla_ice is always >=0 (upwards), heat goes to the atmosphere, therefore snow sublimates
  242. ! clem comment: not counted in mass/heat exchange in limsbc since this is an exchange with atm. (not ocean)
  243. zdeltah(:,:) = 0._wp
  244. DO ji = kideb, kiut
  245. zdh_s_sub(ji) = MAX( - ht_s_1d(ji) , - evap_ice_1d(ji) * r1_rhosn * rdt_ice )
  246. ! remaining evap in kg.m-2 (used for ice melting later on)
  247. zevap_rema(ji) = evap_ice_1d(ji) * rdt_ice + zdh_s_sub(ji) * rhosn
  248. ! Heat flux by sublimation [W.m-2], < 0 (sublimate first snow that had fallen, then pre-existing snow)
  249. zdeltah(ji,1) = MAX( zdh_s_sub(ji), - zdh_s_pre(ji) )
  250. hfx_sub_1d(ji) = hfx_sub_1d(ji) + ( zdeltah(ji,1) * zqprec(ji) + ( zdh_s_sub(ji) - zdeltah(ji,1) ) * q_s_1d(ji,1) &
  251. & ) * a_i_1d(ji) * r1_rdtice
  252. ! Mass flux by sublimation
  253. wfx_sub_1d(ji) = wfx_sub_1d(ji) - rhosn * a_i_1d(ji) * zdh_s_sub(ji) * r1_rdtice
  254. ! new snow thickness
  255. ht_s_1d(ji) = MAX( 0._wp , ht_s_1d(ji) + zdh_s_sub(ji) )
  256. ! update precipitations after sublimation and correct sublimation
  257. zdh_s_pre(ji) = zdh_s_pre(ji) + zdeltah(ji,1)
  258. zdh_s_sub(ji) = zdh_s_sub(ji) - zdeltah(ji,1)
  259. END DO
  260. ! --- Update snow diags --- !
  261. DO ji = kideb, kiut
  262. dh_s_tot(ji) = zdh_s_mel(ji) + zdh_s_pre(ji) + zdh_s_sub(ji)
  263. END DO
  264. !-------------------------------------------
  265. ! 3.3 Update temperature, energy
  266. !-------------------------------------------
  267. ! new temp and enthalpy of the snow (remaining snow precip + remaining pre-existing snow)
  268. DO jk = 1, nlay_s
  269. DO ji = kideb,kiut
  270. rswitch = MAX( 0._wp , SIGN( 1._wp, ht_s_1d(ji) - epsi20 ) )
  271. q_s_1d(ji,jk) = rswitch / MAX( ht_s_1d(ji), epsi20 ) * &
  272. & ( ( zdh_s_pre(ji) ) * zqprec(ji) + &
  273. & ( ht_s_1d(ji) - zdh_s_pre(ji) ) * rhosn * ( cpic * ( rt0 - t_s_1d(ji,jk) ) + lfus ) )
  274. END DO
  275. END DO
  276. !--------------------------
  277. ! 3.4 Surface ice ablation
  278. !--------------------------
  279. zdeltah(:,:) = 0._wp ! important
  280. DO jk = 1, nlay_i
  281. DO ji = kideb, kiut
  282. ztmelts = - tmut * s_i_1d(ji,jk) + rt0 ! Melting point of layer k [K]
  283. IF( t_i_1d(ji,jk) >= ztmelts ) THEN !!! Internal melting
  284. zEi = - q_i_1d(ji,jk) * r1_rhoic ! Specific enthalpy of layer k [J/kg, <0]
  285. zdE = 0._wp ! Specific enthalpy difference (J/kg, <0)
  286. ! set up at 0 since no energy is needed to melt water...(it is already melted)
  287. zdeltah(ji,jk) = MIN( 0._wp , - zh_i(ji,jk) ) ! internal melting occurs when the internal temperature is above freezing
  288. ! this should normally not happen, but sometimes, heat diffusion leads to this
  289. zfmdt = - zdeltah(ji,jk) * rhoic ! Mass flux x time step > 0
  290. dh_i_surf(ji) = dh_i_surf(ji) + zdeltah(ji,jk) ! Cumulate surface melt
  291. zfmdt = - rhoic * zdeltah(ji,jk) ! Recompute mass flux [kg/m2, >0]
  292. ! Contribution to heat flux to the ocean [W.m-2], <0 (ice enthalpy zEi is "sent" to the ocean)
  293. hfx_res_1d(ji) = hfx_res_1d(ji) + zfmdt * a_i_1d(ji) * zEi * r1_rdtice
  294. ! Contribution to salt flux (clem: using sm_i_1d and not s_i_1d(jk) is ok)
  295. sfx_res_1d(ji) = sfx_res_1d(ji) - rhoic * a_i_1d(ji) * zdeltah(ji,jk) * sm_i_1d(ji) * r1_rdtice
  296. ! Contribution to mass flux
  297. wfx_res_1d(ji) = wfx_res_1d(ji) - rhoic * a_i_1d(ji) * zdeltah(ji,jk) * r1_rdtice
  298. ELSE !!! Surface melting
  299. zEi = - q_i_1d(ji,jk) * r1_rhoic ! Specific enthalpy of layer k [J/kg, <0]
  300. zEw = rcp * ( ztmelts - rt0 ) ! Specific enthalpy of resulting meltwater [J/kg, <0]
  301. zdE = zEi - zEw ! Specific enthalpy difference < 0
  302. zfmdt = - zq_su(ji) / zdE ! Mass flux to the ocean [kg/m2, >0]
  303. zdeltah(ji,jk) = - zfmdt * r1_rhoic ! Melt of layer jk [m, <0]
  304. zdeltah(ji,jk) = MIN( 0._wp , MAX( zdeltah(ji,jk) , - zh_i(ji,jk) ) ) ! Melt of layer jk cannot exceed the layer thickness [m, <0]
  305. zq_su(ji) = MAX( 0._wp , zq_su(ji) - zdeltah(ji,jk) * rhoic * zdE ) ! update available heat
  306. dh_i_surf(ji) = dh_i_surf(ji) + zdeltah(ji,jk) ! Cumulate surface melt
  307. zfmdt = - rhoic * zdeltah(ji,jk) ! Recompute mass flux [kg/m2, >0]
  308. zQm = zfmdt * zEw ! Energy of the melt water sent to the ocean [J/m2, <0]
  309. ! Contribution to salt flux >0 (clem: using sm_i_1d and not s_i_1d(jk) is ok)
  310. sfx_sum_1d(ji) = sfx_sum_1d(ji) - rhoic * a_i_1d(ji) * zdeltah(ji,jk) * sm_i_1d(ji) * r1_rdtice
  311. ! Contribution to heat flux [W.m-2], < 0
  312. hfx_thd_1d(ji) = hfx_thd_1d(ji) + zfmdt * a_i_1d(ji) * zEw * r1_rdtice
  313. ! Total heat flux used in this process [W.m-2], > 0
  314. hfx_sum_1d(ji) = hfx_sum_1d(ji) - zfmdt * a_i_1d(ji) * zdE * r1_rdtice
  315. ! Contribution to mass flux
  316. wfx_sum_1d(ji) = wfx_sum_1d(ji) - rhoic * a_i_1d(ji) * zdeltah(ji,jk) * r1_rdtice
  317. END IF
  318. ! ----------------------
  319. ! Sublimation part2: ice
  320. ! ----------------------
  321. zdum = MAX( - ( zh_i(ji,jk) + zdeltah(ji,jk) ) , - zevap_rema(ji) * r1_rhoic )
  322. zdeltah(ji,jk) = zdeltah(ji,jk) + zdum
  323. dh_i_sub(ji) = dh_i_sub(ji) + zdum
  324. ! Salt flux > 0 (clem2016: flux is sent to the ocean for simplicity but salt should remain in the ice except if all ice is melted.
  325. ! It must be corrected at some point)
  326. sfx_sub_1d(ji) = sfx_sub_1d(ji) - rhoic * a_i_1d(ji) * zdum * sm_i_1d(ji) * r1_rdtice
  327. ! Heat flux [W.m-2], < 0
  328. hfx_sub_1d(ji) = hfx_sub_1d(ji) + zdum * q_i_1d(ji,jk) * a_i_1d(ji) * r1_rdtice
  329. ! Mass flux > 0
  330. wfx_sub_1d(ji) = wfx_sub_1d(ji) - rhoic * a_i_1d(ji) * zdum * r1_rdtice
  331. ! update remaining mass flux
  332. zevap_rema(ji) = zevap_rema(ji) + zdum * rhoic
  333. ! record which layers have disappeared (for bottom melting)
  334. ! => icount=0 : no layer has vanished
  335. ! => icount=5 : 5 layers have vanished
  336. rswitch = MAX( 0._wp , SIGN( 1._wp , - ( zh_i(ji,jk) + zdeltah(ji,jk) ) ) )
  337. icount(ji,jk) = NINT( rswitch )
  338. zh_i(ji,jk) = MAX( 0._wp , zh_i(ji,jk) + zdeltah(ji,jk) )
  339. ! update heat content (J.m-2) and layer thickness
  340. qh_i_old(ji,jk) = qh_i_old(ji,jk) + zdeltah(ji,jk) * q_i_1d(ji,jk)
  341. h_i_old (ji,jk) = h_i_old (ji,jk) + zdeltah(ji,jk)
  342. END DO
  343. END DO
  344. ! update ice thickness
  345. DO ji = kideb, kiut
  346. ht_i_1d(ji) = MAX( 0._wp , ht_i_1d(ji) + dh_i_surf(ji) + dh_i_sub(ji) )
  347. END DO
  348. ! remaining "potential" evap is sent to ocean
  349. DO ji = kideb, kiut
  350. ii = MOD( npb(ji) - 1, jpi ) + 1 ; ij = ( npb(ji) - 1 ) / jpi + 1
  351. wfx_err_sub(ii,ij) = wfx_err_sub(ii,ij) - zevap_rema(ji) * a_i_1d(ji) * r1_rdtice ! <=0 (net evap for the ocean in kg.m-2.s-1)
  352. END DO
  353. !
  354. !------------------------------------------------------------------------------!
  355. ! 4) Basal growth / melt !
  356. !------------------------------------------------------------------------------!
  357. !
  358. !------------------
  359. ! 4.1 Basal growth
  360. !------------------
  361. ! Basal growth is driven by heat imbalance at the ice-ocean interface,
  362. ! between the inner conductive flux (fc_bo_i), from the open water heat flux
  363. ! (fhld) and the turbulent ocean flux (fhtur).
  364. ! fc_bo_i is positive downwards. fhtur and fhld are positive to the ice
  365. ! If salinity varies in time, an iterative procedure is required, because
  366. ! the involved quantities are inter-dependent.
  367. ! Basal growth (dh_i_bott) depends upon new ice specific enthalpy (zEi),
  368. ! which depends on forming ice salinity (s_i_new), which depends on dh/dt (dh_i_bott)
  369. ! -> need for an iterative procedure, which converges quickly
  370. num_iter_max = 1
  371. IF( nn_icesal == 2 ) num_iter_max = 5
  372. ! Iterative procedure
  373. DO iter = 1, num_iter_max
  374. DO ji = kideb, kiut
  375. IF( zf_tt(ji) < 0._wp ) THEN
  376. ! New bottom ice salinity (Cox & Weeks, JGR88 )
  377. !--- zswi1 if dh/dt < 2.0e-8
  378. !--- zswi12 if 2.0e-8 < dh/dt < 3.6e-7
  379. !--- zswi2 if dh/dt > 3.6e-7
  380. zgrr = MIN( 1.0e-3, MAX ( dh_i_bott(ji) * r1_rdtice , epsi10 ) )
  381. zswi2 = MAX( 0._wp , SIGN( 1._wp , zgrr - 3.6e-7 ) )
  382. zswi12 = MAX( 0._wp , SIGN( 1._wp , zgrr - 2.0e-8 ) ) * ( 1.0 - zswi2 )
  383. zswi1 = 1. - zswi2 * zswi12
  384. zfracs = MIN ( zswi1 * 0.12 + zswi12 * ( 0.8925 + 0.0568 * LOG( 100.0 * zgrr ) ) &
  385. & + zswi2 * 0.26 / ( 0.26 + 0.74 * EXP ( - 724300.0 * zgrr ) ) , 0.5 )
  386. ii = MOD( npb(ji) - 1, jpi ) + 1 ; ij = ( npb(ji) - 1 ) / jpi + 1
  387. s_i_new(ji) = zswitch_sal * zfracs * sss_m(ii,ij) & ! New ice salinity
  388. + ( 1. - zswitch_sal ) * sm_i_1d(ji)
  389. ! New ice growth
  390. ztmelts = - tmut * s_i_new(ji) + rt0 ! New ice melting point (K)
  391. zt_i_new = zswitch_sal * t_bo_1d(ji) + ( 1. - zswitch_sal) * t_i_1d(ji, nlay_i)
  392. zEi = cpic * ( zt_i_new - ztmelts ) & ! Specific enthalpy of forming ice (J/kg, <0)
  393. & - lfus * ( 1.0 - ( ztmelts - rt0 ) / ( zt_i_new - rt0 ) ) &
  394. & + rcp * ( ztmelts-rt0 )
  395. zEw = rcp * ( t_bo_1d(ji) - rt0 ) ! Specific enthalpy of seawater (J/kg, < 0)
  396. zdE = zEi - zEw ! Specific enthalpy difference (J/kg, <0)
  397. dh_i_bott(ji) = rdt_ice * MAX( 0._wp , zf_tt(ji) / ( zdE * rhoic ) )
  398. q_i_1d(ji,nlay_i+1) = -zEi * rhoic ! New ice energy of melting (J/m3, >0)
  399. ENDIF
  400. END DO
  401. END DO
  402. ! Contribution to Energy and Salt Fluxes
  403. DO ji = kideb, kiut
  404. IF( zf_tt(ji) < 0._wp ) THEN
  405. ! New ice growth
  406. zfmdt = - rhoic * dh_i_bott(ji) ! Mass flux x time step (kg/m2, < 0)
  407. ztmelts = - tmut * s_i_new(ji) + rt0 ! New ice melting point (K)
  408. zt_i_new = zswitch_sal * t_bo_1d(ji) + ( 1. - zswitch_sal) * t_i_1d(ji, nlay_i)
  409. zEi = cpic * ( zt_i_new - ztmelts ) & ! Specific enthalpy of forming ice (J/kg, <0)
  410. & - lfus * ( 1.0 - ( ztmelts - rt0 ) / ( zt_i_new - rt0 ) ) &
  411. & + rcp * ( ztmelts-rt0 )
  412. zEw = rcp * ( t_bo_1d(ji) - rt0 ) ! Specific enthalpy of seawater (J/kg, < 0)
  413. zdE = zEi - zEw ! Specific enthalpy difference (J/kg, <0)
  414. ! Contribution to heat flux to the ocean [W.m-2], >0
  415. hfx_thd_1d(ji) = hfx_thd_1d(ji) + zfmdt * a_i_1d(ji) * zEw * r1_rdtice
  416. ! Total heat flux used in this process [W.m-2], <0
  417. hfx_bog_1d(ji) = hfx_bog_1d(ji) - zfmdt * a_i_1d(ji) * zdE * r1_rdtice
  418. ! Contribution to salt flux, <0
  419. sfx_bog_1d(ji) = sfx_bog_1d(ji) - rhoic * a_i_1d(ji) * dh_i_bott(ji) * s_i_new(ji) * r1_rdtice
  420. ! Contribution to mass flux, <0
  421. wfx_bog_1d(ji) = wfx_bog_1d(ji) - rhoic * a_i_1d(ji) * dh_i_bott(ji) * r1_rdtice
  422. ! update heat content (J.m-2) and layer thickness
  423. qh_i_old(ji,nlay_i+1) = qh_i_old(ji,nlay_i+1) + dh_i_bott(ji) * q_i_1d(ji,nlay_i+1)
  424. h_i_old (ji,nlay_i+1) = h_i_old (ji,nlay_i+1) + dh_i_bott(ji)
  425. ENDIF
  426. END DO
  427. !----------------
  428. ! 4.2 Basal melt
  429. !----------------
  430. zdeltah(:,:) = 0._wp ! important
  431. DO jk = nlay_i, 1, -1
  432. DO ji = kideb, kiut
  433. IF( zf_tt(ji) > 0._wp .AND. jk > icount(ji,jk) ) THEN ! do not calculate where layer has already disappeared by surface melting
  434. ztmelts = - tmut * s_i_1d(ji,jk) + rt0 ! Melting point of layer jk (K)
  435. IF( t_i_1d(ji,jk) >= ztmelts ) THEN !!! Internal melting
  436. zEi = - q_i_1d(ji,jk) * r1_rhoic ! Specific enthalpy of melting ice (J/kg, <0)
  437. zdE = 0._wp ! Specific enthalpy difference (J/kg, <0)
  438. ! set up at 0 since no energy is needed to melt water...(it is already melted)
  439. zdeltah (ji,jk) = MIN( 0._wp , - zh_i(ji,jk) ) ! internal melting occurs when the internal temperature is above freezing
  440. ! this should normally not happen, but sometimes, heat diffusion leads to this
  441. dh_i_bott (ji) = dh_i_bott(ji) + zdeltah(ji,jk)
  442. zfmdt = - zdeltah(ji,jk) * rhoic ! Mass flux x time step > 0
  443. ! Contribution to heat flux to the ocean [W.m-2], <0 (ice enthalpy zEi is "sent" to the ocean)
  444. hfx_res_1d(ji) = hfx_res_1d(ji) + zfmdt * a_i_1d(ji) * zEi * r1_rdtice
  445. ! Contribution to salt flux (clem: using sm_i_1d and not s_i_1d(jk) is ok)
  446. sfx_res_1d(ji) = sfx_res_1d(ji) - rhoic * a_i_1d(ji) * zdeltah(ji,jk) * sm_i_1d(ji) * r1_rdtice
  447. ! Contribution to mass flux
  448. wfx_res_1d(ji) = wfx_res_1d(ji) - rhoic * a_i_1d(ji) * zdeltah(ji,jk) * r1_rdtice
  449. ! update heat content (J.m-2) and layer thickness
  450. qh_i_old(ji,jk) = qh_i_old(ji,jk) + zdeltah(ji,jk) * q_i_1d(ji,jk)
  451. h_i_old (ji,jk) = h_i_old (ji,jk) + zdeltah(ji,jk)
  452. ELSE !!! Basal melting
  453. zEi = - q_i_1d(ji,jk) * r1_rhoic ! Specific enthalpy of melting ice (J/kg, <0)
  454. zEw = rcp * ( ztmelts - rt0 ) ! Specific enthalpy of meltwater (J/kg, <0)
  455. zdE = zEi - zEw ! Specific enthalpy difference (J/kg, <0)
  456. zfmdt = - zq_bo(ji) / zdE ! Mass flux x time step (kg/m2, >0)
  457. zdeltah(ji,jk) = - zfmdt * r1_rhoic ! Gross thickness change
  458. zdeltah(ji,jk) = MIN( 0._wp , MAX( zdeltah(ji,jk), - zh_i(ji,jk) ) ) ! bound thickness change
  459. zq_bo(ji) = MAX( 0._wp , zq_bo(ji) - zdeltah(ji,jk) * rhoic * zdE ) ! update available heat. MAX is necessary for roundup errors
  460. dh_i_bott(ji) = dh_i_bott(ji) + zdeltah(ji,jk) ! Update basal melt
  461. zfmdt = - zdeltah(ji,jk) * rhoic ! Mass flux x time step > 0
  462. zQm = zfmdt * zEw ! Heat exchanged with ocean
  463. ! Contribution to heat flux to the ocean [W.m-2], <0
  464. hfx_thd_1d(ji) = hfx_thd_1d(ji) + zfmdt * a_i_1d(ji) * zEw * r1_rdtice
  465. ! Contribution to salt flux (clem: using sm_i_1d and not s_i_1d(jk) is ok)
  466. sfx_bom_1d(ji) = sfx_bom_1d(ji) - rhoic * a_i_1d(ji) * zdeltah(ji,jk) * sm_i_1d(ji) * r1_rdtice
  467. ! Total heat flux used in this process [W.m-2], >0
  468. hfx_bom_1d(ji) = hfx_bom_1d(ji) - zfmdt * a_i_1d(ji) * zdE * r1_rdtice
  469. ! Contribution to mass flux
  470. wfx_bom_1d(ji) = wfx_bom_1d(ji) - rhoic * a_i_1d(ji) * zdeltah(ji,jk) * r1_rdtice
  471. ! update heat content (J.m-2) and layer thickness
  472. qh_i_old(ji,jk) = qh_i_old(ji,jk) + zdeltah(ji,jk) * q_i_1d(ji,jk)
  473. h_i_old (ji,jk) = h_i_old (ji,jk) + zdeltah(ji,jk)
  474. ENDIF
  475. ENDIF
  476. END DO
  477. END DO
  478. !-------------------------------------------
  479. ! Update temperature, energy
  480. !-------------------------------------------
  481. DO ji = kideb, kiut
  482. ht_i_1d(ji) = MAX( 0._wp , ht_i_1d(ji) + dh_i_bott(ji) )
  483. END DO
  484. !-------------------------------------------
  485. ! 5. What to do with remaining energy
  486. !-------------------------------------------
  487. ! If heat still available for melting and snow remains, then melt more snow
  488. !-------------------------------------------
  489. zdeltah(:,:) = 0._wp ! important
  490. DO ji = kideb, kiut
  491. zq_rema(ji) = zq_su(ji) + zq_bo(ji)
  492. rswitch = 1._wp - MAX( 0._wp, SIGN( 1._wp, - ht_s_1d(ji) ) ) ! =1 if snow
  493. rswitch = rswitch * MAX( 0._wp, SIGN( 1._wp, q_s_1d(ji,1) - epsi20 ) )
  494. zdeltah (ji,1) = - rswitch * zq_rema(ji) / MAX( q_s_1d(ji,1), epsi20 )
  495. zdeltah (ji,1) = MIN( 0._wp , MAX( zdeltah(ji,1) , - ht_s_1d(ji) ) ) ! bound melting
  496. dh_s_tot (ji) = dh_s_tot(ji) + zdeltah(ji,1)
  497. ht_s_1d (ji) = ht_s_1d(ji) + zdeltah(ji,1)
  498. zq_rema(ji) = zq_rema(ji) + zdeltah(ji,1) * q_s_1d(ji,1) ! update available heat (J.m-2)
  499. ! heat used to melt snow
  500. hfx_snw_1d(ji) = hfx_snw_1d(ji) - zdeltah(ji,1) * a_i_1d(ji) * q_s_1d(ji,1) * r1_rdtice ! W.m-2 (>0)
  501. ! Contribution to mass flux
  502. wfx_snw_1d(ji) = wfx_snw_1d(ji) - rhosn * a_i_1d(ji) * zdeltah(ji,1) * r1_rdtice
  503. !
  504. ii = MOD( npb(ji) - 1, jpi ) + 1 ; ij = ( npb(ji) - 1 ) / jpi + 1
  505. ! Remaining heat flux (W.m-2) is sent to the ocean heat budget
  506. hfx_out(ii,ij) = hfx_out(ii,ij) + ( zq_rema(ji) * a_i_1d(ji) ) * r1_rdtice
  507. IF( ln_icectl .AND. zq_rema(ji) < 0. .AND. lwp ) WRITE(numout,*) 'ALERTE zq_rema <0 = ', zq_rema(ji)
  508. END DO
  509. !
  510. !------------------------------------------------------------------------------|
  511. ! 6) Snow-Ice formation |
  512. !------------------------------------------------------------------------------|
  513. ! When snow load excesses Archimede's limit, snow-ice interface goes down under sea-level,
  514. ! flooding of seawater transforms snow into ice dh_snowice is positive for the ice
  515. DO ji = kideb, kiut
  516. !
  517. dh_snowice(ji) = MAX( 0._wp , ( rhosn * ht_s_1d(ji) + (rhoic-rau0) * ht_i_1d(ji) ) / ( rhosn+rau0-rhoic ) )
  518. ht_i_1d(ji) = ht_i_1d(ji) + dh_snowice(ji)
  519. ht_s_1d(ji) = ht_s_1d(ji) - dh_snowice(ji)
  520. ! Salinity of snow ice
  521. ii = MOD( npb(ji) - 1, jpi ) + 1 ; ij = ( npb(ji) - 1 ) / jpi + 1
  522. zs_snic = zswitch_sal * sss_m(ii,ij) * ( rhoic - rhosn ) * r1_rhoic + ( 1. - zswitch_sal ) * sm_i_1d(ji)
  523. ! entrapment during snow ice formation
  524. ! new salinity difference stored (to be used in limthd_sal.F90)
  525. IF ( nn_icesal == 2 ) THEN
  526. rswitch = MAX( 0._wp , SIGN( 1._wp , ht_i_1d(ji) - epsi20 ) )
  527. ! salinity dif due to snow-ice formation
  528. dsm_i_si_1d(ji) = ( zs_snic - sm_i_1d(ji) ) * dh_snowice(ji) / MAX( ht_i_1d(ji), epsi20 ) * rswitch
  529. ! salinity dif due to bottom growth
  530. IF ( zf_tt(ji) < 0._wp ) THEN
  531. dsm_i_se_1d(ji) = ( s_i_new(ji) - sm_i_1d(ji) ) * dh_i_bott(ji) / MAX( ht_i_1d(ji), epsi20 ) * rswitch
  532. ENDIF
  533. ENDIF
  534. ! Contribution to energy flux to the ocean [J/m2], >0 (if sst<0)
  535. zfmdt = ( rhosn - rhoic ) * MAX( dh_snowice(ji), 0._wp ) ! <0
  536. zsstK = sst_m(ii,ij) + rt0
  537. zEw = rcp * ( zsstK - rt0 )
  538. zQm = zfmdt * zEw
  539. ! Contribution to heat flux
  540. hfx_thd_1d(ji) = hfx_thd_1d(ji) + zfmdt * a_i_1d(ji) * zEw * r1_rdtice
  541. ! Contribution to salt flux
  542. sfx_sni_1d(ji) = sfx_sni_1d(ji) + sss_m(ii,ij) * a_i_1d(ji) * zfmdt * r1_rdtice
  543. ! virtual salt flux to keep salinity constant
  544. IF( nn_icesal == 1 .OR. nn_icesal == 3 ) THEN
  545. sfx_bri_1d(ji) = sfx_bri_1d(ji) - sss_m(ii,ij) * a_i_1d(ji) * zfmdt * r1_rdtice & ! put back sss_m into the ocean
  546. & - sm_i_1d(ji) * a_i_1d(ji) * dh_snowice(ji) * rhoic * r1_rdtice ! and get sm_i from the ocean
  547. ENDIF
  548. ! Contribution to mass flux
  549. ! All snow is thrown in the ocean, and seawater is taken to replace the volume
  550. wfx_sni_1d(ji) = wfx_sni_1d(ji) - a_i_1d(ji) * dh_snowice(ji) * rhoic * r1_rdtice
  551. wfx_snw_1d(ji) = wfx_snw_1d(ji) + a_i_1d(ji) * dh_snowice(ji) * rhosn * r1_rdtice
  552. ! update heat content (J.m-2) and layer thickness
  553. qh_i_old(ji,0) = qh_i_old(ji,0) + dh_snowice(ji) * q_s_1d(ji,1) + zfmdt * zEw
  554. h_i_old (ji,0) = h_i_old (ji,0) + dh_snowice(ji)
  555. END DO
  556. !
  557. !-------------------------------------------
  558. ! Update temperature, energy
  559. !-------------------------------------------
  560. DO ji = kideb, kiut
  561. rswitch = 1.0 - MAX( 0._wp , SIGN( 1._wp , - ht_i_1d(ji) ) )
  562. t_su_1d(ji) = rswitch * t_su_1d(ji) + ( 1.0 - rswitch ) * rt0
  563. END DO
  564. DO jk = 1, nlay_s
  565. DO ji = kideb,kiut
  566. ! mask enthalpy
  567. rswitch = 1._wp - MAX( 0._wp , SIGN( 1._wp, - ht_s_1d(ji) ) )
  568. q_s_1d(ji,jk) = rswitch * q_s_1d(ji,jk)
  569. ! recalculate t_s_1d from q_s_1d
  570. t_s_1d(ji,jk) = rt0 + rswitch * ( - q_s_1d(ji,jk) / ( rhosn * cpic ) + lfus / cpic )
  571. END DO
  572. END DO
  573. ! --- ensure that a_i = 0 where ht_i = 0 ---
  574. WHERE( ht_i_1d == 0._wp ) a_i_1d = 0._wp
  575. CALL wrk_dealloc( jpij, zqprec, zq_su, zq_bo, zf_tt, zq_rema, zsnw, zevap_rema )
  576. CALL wrk_dealloc( jpij, zdh_s_mel, zdh_s_pre, zdh_s_sub, zqh_i )
  577. CALL wrk_dealloc( jpij, nlay_i, zdeltah, zh_i )
  578. CALL wrk_dealloc( jpij, nlay_i, icount )
  579. !
  580. !
  581. END SUBROUTINE lim_thd_dh
  582. !!--------------------------------------------------------------------------
  583. !! INTERFACE lim_thd_snwblow
  584. !! ** Purpose : Compute distribution of precip over the ice
  585. !!--------------------------------------------------------------------------
  586. SUBROUTINE lim_thd_snwblow_2d( pin, pout )
  587. REAL(wp), DIMENSION(:,:), INTENT(in ) :: pin ! previous fraction lead ( pfrld or (1. - a_i_b) )
  588. REAL(wp), DIMENSION(:,:), INTENT(inout) :: pout
  589. pout = ( 1._wp - ( pin )**rn_betas )
  590. END SUBROUTINE lim_thd_snwblow_2d
  591. SUBROUTINE lim_thd_snwblow_1d( pin, pout )
  592. REAL(wp), DIMENSION(:), INTENT(in ) :: pin
  593. REAL(wp), DIMENSION(:), INTENT(inout) :: pout
  594. pout = ( 1._wp - ( pin )**rn_betas )
  595. END SUBROUTINE lim_thd_snwblow_1d
  596. #else
  597. !!----------------------------------------------------------------------
  598. !! Default option NO LIM3 sea-ice model
  599. !!----------------------------------------------------------------------
  600. CONTAINS
  601. SUBROUTINE lim_thd_dh ! Empty routine
  602. END SUBROUTINE lim_thd_dh
  603. #endif
  604. !!======================================================================
  605. END MODULE limthd_dh