limthd_2.F90 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. MODULE limthd_2
  2. !!======================================================================
  3. !! *** MODULE limthd_2 ***
  4. !! LIM thermo ice model : ice thermodynamic
  5. !!======================================================================
  6. !! History : 1.0 ! 2000-01 (LIM)
  7. !! 2.0 ! 2002-07 (C. Ethe, G. Madec) F90
  8. !! 2.0 ! 2003-08 (C. Ethe) add lim_thd_init
  9. !! - ! 2008-2008 (A. Caubel, G. Madec, E. Maisonnave, S. Masson ) generic coupled interface
  10. !!---------------------------------------------------------------------
  11. #if defined key_lim2
  12. !!----------------------------------------------------------------------
  13. !! 'key_lim2' : LIM 2.0 sea-ice model
  14. !!----------------------------------------------------------------------
  15. !! lim_thd_2 : thermodynamic of sea ice
  16. !! lim_thd_init_2 : initialisation of sea-ice thermodynamic
  17. !!----------------------------------------------------------------------
  18. USE phycst ! physical constants
  19. USE dom_oce ! ocean space and time domain variables
  20. USE domvvl
  21. USE lbclnk
  22. USE in_out_manager ! I/O manager
  23. USE lib_mpp
  24. USE wrk_nemo ! work arrays
  25. USE iom ! IOM library
  26. USE ice_2 ! LIM sea-ice variables
  27. USE sbc_oce !
  28. USE sbc_ice !
  29. USE thd_ice_2 ! LIM thermodynamic sea-ice variables
  30. USE dom_ice_2 ! LIM sea-ice domain
  31. USE limthd_zdf_2
  32. USE limthd_lac_2
  33. USE limtab_2
  34. USE prtctl ! Print control
  35. USE lib_fortran ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined)
  36. IMPLICIT NONE
  37. PRIVATE
  38. PUBLIC lim_thd_2 ! called by lim_step
  39. REAL(wp) :: epsi20 = 1.e-20 ! constant values
  40. REAL(wp) :: epsi16 = 1.e-16 !
  41. REAL(wp) :: epsi04 = 1.e-04 !
  42. REAL(wp) :: rzero = 0.e0 !
  43. REAL(wp) :: rone = 1.e0 !
  44. !! * Substitutions
  45. # include "domzgr_substitute.h90"
  46. # include "vectopt_loop_substitute.h90"
  47. !!-------- -------------------------------------------------------------
  48. !! NEMO/LIM2 3.3 , UCL - NEMO Consortium (2010)
  49. !! $Id: limthd_2.F90 4990 2014-12-15 16:42:49Z timgraham $
  50. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  51. !!----------------------------------------------------------------------
  52. CONTAINS
  53. SUBROUTINE lim_thd_2( kt )
  54. !!-------------------------------------------------------------------
  55. !! *** ROUTINE lim_thd_2 ***
  56. !!
  57. !! ** Purpose : This routine manages the ice thermodynamic.
  58. !!
  59. !! ** Action : - Initialisation of some variables
  60. !! - Some preliminary computation (oceanic heat flux
  61. !! at the ice base, snow acc.,heat budget of the leads)
  62. !! - selection of the icy points and put them in an array
  63. !! - call lim_vert_ther for vert ice thermodynamic
  64. !! - back to the geographic grid
  65. !! - selection of points for lateral accretion
  66. !! - call lim_lat_acc for the ice accretion
  67. !! - back to the geographic grid
  68. !!
  69. !! References : Goosse et al. 1996, Bul. Soc. Roy. Sc. Liege, 65, 87-90
  70. !!---------------------------------------------------------------------
  71. INTEGER, INTENT(in) :: kt ! number of iteration
  72. !!
  73. INTEGER :: ji, jj ! dummy loop indices
  74. INTEGER :: nbpb ! nb of icy pts for thermo. cal.
  75. INTEGER :: nbpac ! nb of pts for lateral accretion
  76. CHARACTER (len=22) :: charout
  77. REAL(wp) :: zfric_umin = 5e-03 ! lower bound for the friction velocity
  78. REAL(wp) :: zfric_umax = 2e-02 ! upper bound for the friction velocity
  79. REAL(wp) :: zinda ! switch for test. the val. of concen.
  80. REAL(wp) :: zindb, zindg ! switches for test. the val of arg
  81. REAL(wp) :: zfricp ! temporary scalar
  82. REAL(wp) :: za , zh, zthsnice !
  83. REAL(wp) :: zfric_u ! friction velocity
  84. REAL(wp) :: zfntlat, zpareff ! test. the val. of lead heat budget
  85. REAL(wp) :: zuice_m, zvice_m ! Sea-ice velocities at U & V-points
  86. REAL(wp) :: zhice_u, zhice_v ! Sea-ice volume at U & V-points
  87. REAL(wp) :: ztr_fram ! Sea-ice transport through Fram strait
  88. REAL(wp) :: zrhoij, zrhoijm1 ! temporary scalars
  89. REAL(wp) :: zztmp ! temporary scalars within a loop
  90. REAL(wp), POINTER, DIMENSION(:,:) :: ztmp ! 2D workspace
  91. REAL(wp), POINTER, DIMENSION(:,:) :: zqlbsbq ! link with lead energy budget qldif
  92. REAL(wp), POINTER, DIMENSION(:,:) :: zlicegr ! link with lateral ice growth
  93. !!$ REAL(wp), DIMENSION(:,:) :: firic ! IR flux over the ice (outputs only)
  94. !!$ REAL(wp), DIMENSION(:,:) :: fcsic ! Sensible heat flux over the ice (outputs only)
  95. !!$ REAL(wp), DIMENSION(:,:) :: fleic ! Latent heat flux over the ice (outputs only)
  96. !!$ REAL(wp), DIMENSION(:,:) :: qlatic ! latent flux (outputs only)
  97. REAL(wp), POINTER, DIMENSION(:,:) :: zdvosif ! Variation of volume at surface (outputs only)
  98. REAL(wp), POINTER, DIMENSION(:,:) :: zdvobif ! Variation of ice volume at the bottom ice (outputs only)
  99. REAL(wp), POINTER, DIMENSION(:,:) :: zdvolif ! Total variation of ice volume (outputs only)
  100. REAL(wp), POINTER, DIMENSION(:,:) :: zdvonif ! Surface accretion Snow to Ice transformation (outputs only)
  101. REAL(wp), POINTER, DIMENSION(:,:) :: zdvomif ! Bottom variation of ice volume due to melting (outputs only)
  102. REAL(wp), POINTER, DIMENSION(:,:) :: zu_imasstr ! Sea-ice transport along i-axis at U-point (outputs only)
  103. REAL(wp), POINTER, DIMENSION(:,:) :: zv_imasstr ! Sea-ice transport along j-axis at V-point (outputs only)
  104. REAL(wp), POINTER, DIMENSION(:,:,:) :: zmsk ! 3D workspace
  105. !!-------------------------------------------------------------------
  106. CALL wrk_alloc( jpi, jpj, ztmp, zqlbsbq, zlicegr, zdvosif, zdvobif, zdvolif, zdvonif, zdvomif, zu_imasstr, zv_imasstr )
  107. CALL wrk_alloc( jpi, jpj, jpk, zmsk )
  108. IF( kt == nit000 ) CALL lim_thd_init_2 ! Initialization (first time-step only)
  109. !-------------------------------------------!
  110. ! Initilization of diagnostic variables !
  111. !-------------------------------------------!
  112. !!gm needed? yes at least for some of these arrays
  113. zdvosif(:,:) = 0.e0 ! variation of ice volume at surface
  114. zdvobif(:,:) = 0.e0 ! variation of ice volume at bottom
  115. zdvolif(:,:) = 0.e0 ! total variation of ice volume
  116. zdvonif(:,:) = 0.e0 ! transformation of snow to sea-ice volume
  117. zlicegr(:,:) = 0.e0 ! lateral variation of ice volume
  118. zdvomif(:,:) = 0.e0 ! variation of ice volume at bottom due to melting only
  119. ztr_fram = 0.e0 ! sea-ice transport through Fram strait
  120. fstric (:,:) = 0.e0 ! part of solar radiation absorbing inside the ice
  121. fscmbq (:,:) = 0.e0 ! linked with fstric
  122. ffltbif(:,:) = 0.e0 ! linked with fstric
  123. qfvbq (:,:) = 0.e0 ! linked with fstric
  124. rdm_snw(:,:) = 0.e0 ! variation of snow mass over 1 time step
  125. rdq_snw(:,:) = 0.e0 ! heat content associated with rdm_snw
  126. rdm_ice(:,:) = 0.e0 ! variation of ice mass over 1 time step
  127. rdq_ice(:,:) = 0.e0 ! heat content associated with rdm_ice
  128. zmsk (:,:,:) = 0.e0
  129. ! set to zero snow thickness smaller than epsi04
  130. DO jj = 1, jpj
  131. DO ji = 1, jpi
  132. hsnif(ji,jj) = hsnif(ji,jj) * MAX( rzero, SIGN( rone , hsnif(ji,jj) - epsi04 ) )
  133. END DO
  134. END DO
  135. !!gm better coded (do not use SIGN...)
  136. ! WHERE( hsnif(:,:) < epsi04 ) hsnif(:,:) = 0.e0
  137. !!gm
  138. IF(ln_ctl) CALL prt_ctl( tab2d_1=hsnif, clinfo1=' lim_thd: hsnif : ' )
  139. !-----------------------------------!
  140. ! Treatment of particular cases !
  141. !-----------------------------------!
  142. DO jj = 1, jpj
  143. DO ji = 1, jpi
  144. ! snow is transformed into ice if the original ice cover disappears.
  145. zindg = tms(ji,jj) * MAX( rzero , SIGN( rone , -hicif(ji,jj) ) )
  146. hicif(ji,jj) = hicif(ji,jj) + zindg * rhosn * hsnif(ji,jj) / rau0
  147. hsnif(ji,jj) = ( rone - zindg ) * hsnif(ji,jj) + zindg * hicif(ji,jj) * ( rau0 - rhoic ) / rhosn
  148. dmgwi(ji,jj) = zindg * (1.0 - frld(ji,jj)) * rhoic * hicif(ji,jj) ! snow/ice mass
  149. ! the lead fraction, frld, must be little than or equal to amax (ice ridging).
  150. zthsnice = hsnif(ji,jj) + hicif(ji,jj)
  151. zindb = tms(ji,jj) * ( 1.0 - MAX( rzero , SIGN( rone , - zthsnice ) ) )
  152. za = zindb * MIN( rone, ( 1.0 - frld(ji,jj) ) * uscomi )
  153. hsnif (ji,jj) = hsnif(ji,jj) * za
  154. hicif (ji,jj) = hicif(ji,jj) * za
  155. qstoif(ji,jj) = qstoif(ji,jj) * za
  156. frld (ji,jj) = 1.0 - zindb * ( 1.0 - frld(ji,jj) ) / MAX( za, epsi20 )
  157. ! the in situ ice thickness, hicif, must be equal to or greater than hiclim.
  158. zh = MAX( rone , zindb * hiclim / MAX( hicif(ji,jj), epsi20 ) )
  159. hsnif (ji,jj) = hsnif(ji,jj) * zh
  160. hicif (ji,jj) = hicif(ji,jj) * zh
  161. qstoif(ji,jj) = qstoif(ji,jj) * zh
  162. frld (ji,jj) = ( frld(ji,jj) + ( zh - 1.0 ) ) / zh
  163. END DO
  164. END DO
  165. IF(ln_ctl) THEN
  166. CALL prt_ctl( tab2d_1=hicif , clinfo1=' lim_thd: hicif : ' )
  167. CALL prt_ctl( tab2d_1=hsnif , clinfo1=' lim_thd: hsnif : ' )
  168. CALL prt_ctl( tab2d_1=dmgwi , clinfo1=' lim_thd: dmgwi : ' )
  169. CALL prt_ctl( tab2d_1=qstoif, clinfo1=' lim_thd: qstoif : ' )
  170. CALL prt_ctl( tab2d_1=frld , clinfo1=' lim_thd: frld : ' )
  171. ENDIF
  172. !-------------------------------!
  173. ! Thermodynamics of sea ice !
  174. !-------------------------------!
  175. ! Partial computation of forcing for the thermodynamic sea ice model.
  176. !--------------------------------------------------------------------------
  177. !CDIR NOVERRCHK
  178. DO jj = 1, jpj
  179. !CDIR NOVERRCHK
  180. DO ji = 1, jpi
  181. zthsnice = hsnif(ji,jj) + hicif(ji,jj)
  182. zindb = tms(ji,jj) * ( 1.0 - MAX( rzero , SIGN( rone , - zthsnice ) ) )
  183. pfrld(ji,jj) = frld(ji,jj)
  184. zfricp = 1.0 - frld(ji,jj)
  185. zinda = 1.0 - MAX( rzero , SIGN( rone , - zfricp ) )
  186. ! solar irradiance transmission at the mixed layer bottom and used in the lead heat budget
  187. thcm(ji,jj) = 0.e0
  188. ! net downward heat flux from the ice to the ocean, expressed as a function of ocean
  189. ! temperature and turbulent mixing (McPhee, 1992)
  190. zfric_u = MAX ( MIN( SQRT( ust2s(ji,jj) ) , zfric_umax ) , zfric_umin ) ! friction velocity
  191. fdtcn(ji,jj) = zindb * rau0 * rcp * 0.006 * zfric_u * ( sst_m(ji,jj) + rt0 - tfu(ji,jj) )
  192. qdtcn(ji,jj) = zindb * fdtcn(ji,jj) * frld(ji,jj) * rdt_ice
  193. ! partial computation of the lead energy budget (qldif)
  194. IF( ln_cpl ) THEN
  195. qldif(ji,jj) = tms(ji,jj) * rdt_ice &
  196. & * ( ( qsr_tot(ji,jj) - qsr_ice(ji,jj,1) * zfricp ) * ( 1.0 - thcm(ji,jj) ) &
  197. & + ( qns_tot(ji,jj) - qns_ice(ji,jj,1) * zfricp ) &
  198. & + frld(ji,jj) * ( fdtcn(ji,jj) + ( 1.0 - zindb ) * fsbbq(ji,jj) ) )
  199. ELSE
  200. qldif(ji,jj) = tms(ji,jj) * rdt_ice * frld(ji,jj) &
  201. & * ( qsr(ji,jj) * ( 1.0 - thcm(ji,jj) ) &
  202. & + qns(ji,jj) + fdtcn(ji,jj) &
  203. & + ( 1.0 - zindb ) * fsbbq(ji,jj) )
  204. ENDIF
  205. ! parlat : percentage of energy used for lateral ablation (0.0)
  206. zfntlat = 1.0 - MAX( rzero , SIGN( rone , - qldif(ji,jj) ) )
  207. zpareff = 1.0 + ( parlat - 1.0 ) * zinda * zfntlat
  208. zqlbsbq(ji,jj) = qldif(ji,jj) * ( 1.0 - zpareff ) / MAX( (1.0 - frld(ji,jj)) * rdt_ice , epsi16 )
  209. qldif (ji,jj) = zpareff * qldif(ji,jj)
  210. qdtcn (ji,jj) = zpareff * qdtcn(ji,jj)
  211. ! energy needed to bring ocean surface layer until its freezing
  212. qcmif (ji,jj) = rau0 * rcp * fse3t_m(ji,jj) * ( tfu(ji,jj) - sst_m(ji,jj) - rt0 ) * ( 1 - zinda )
  213. ! calculate oceanic heat flux.
  214. fbif (ji,jj) = zindb * ( fsbbq(ji,jj) / MAX( (1.0 - frld(ji,jj)) , epsi20 ) + fdtcn(ji,jj) )
  215. ! computation of the thermodynamic ice production (only needed for output)
  216. hicifp(ji,jj) = hicif(ji,jj) * ( 1.0 - frld(ji,jj) )
  217. END DO
  218. END DO
  219. ! Select icy points and fulfill arrays for the vectorial grid.
  220. !----------------------------------------------------------------------
  221. nbpb = 0
  222. DO jj = 1, jpj
  223. DO ji = 1, jpi
  224. IF ( frld(ji,jj) < 1.0 ) THEN
  225. nbpb = nbpb + 1
  226. npb(nbpb) = (jj - 1) * jpi + ji
  227. ENDIF
  228. END DO
  229. END DO
  230. IF(ln_ctl) THEN
  231. CALL prt_ctl(tab2d_1=pfrld, clinfo1=' lim_thd: pfrld : ', tab2d_2=thcm , clinfo2=' thcm : ')
  232. CALL prt_ctl(tab2d_1=fdtcn, clinfo1=' lim_thd: fdtcn : ', tab2d_2=qdtcn , clinfo2=' qdtcn : ')
  233. CALL prt_ctl(tab2d_1=qldif, clinfo1=' lim_thd: qldif : ', tab2d_2=zqlbsbq, clinfo2=' zqlbsbq : ')
  234. CALL prt_ctl(tab2d_1=qcmif, clinfo1=' lim_thd: qcmif : ', tab2d_2=fbif , clinfo2=' fbif : ')
  235. zmsk(:,:,1) = tms(:,:)
  236. CALL prt_ctl(tab2d_1=qcmif , clinfo1=' lim_thd: qcmif : ', mask1=zmsk)
  237. CALL prt_ctl(tab2d_1=hicifp, clinfo1=' lim_thd: hicifp : ')
  238. WRITE(charout, FMT="('lim_thd: nbpb = ',I4)") nbpb
  239. CALL prt_ctl_info(charout)
  240. ENDIF
  241. ! If there is no ice, do nothing. Otherwise, compute Top and Bottom accretion/ablation
  242. !------------------------------------------------------------------------------------
  243. IF( nbpb > 0 ) THEN
  244. !
  245. ! put the variable in a 1-D array for thermodynamics process
  246. CALL tab_2d_1d_2( nbpb, frld_1d (1:nbpb) , frld , jpi, jpj, npb(1:nbpb) )
  247. CALL tab_2d_1d_2( nbpb, h_ice_1d (1:nbpb) , hicif , jpi, jpj, npb(1:nbpb) )
  248. CALL tab_2d_1d_2( nbpb, h_snow_1d (1:nbpb) , hsnif , jpi, jpj, npb(1:nbpb) )
  249. CALL tab_2d_1d_2( nbpb, sist_1d (1:nbpb) , sist , jpi, jpj, npb(1:nbpb) )
  250. CALL tab_2d_1d_2( nbpb, tbif_1d (1:nbpb , 1 ), tbif(:,:,1) , jpi, jpj, npb(1:nbpb) )
  251. CALL tab_2d_1d_2( nbpb, tbif_1d (1:nbpb , 2 ), tbif(:,:,2) , jpi, jpj, npb(1:nbpb) )
  252. CALL tab_2d_1d_2( nbpb, tbif_1d (1:nbpb , 3 ), tbif(:,:,3) , jpi, jpj, npb(1:nbpb) )
  253. CALL tab_2d_1d_2( nbpb, qsr_ice_1d (1:nbpb) , qsr_ice(:,:,1) , jpi, jpj, npb(1:nbpb) )
  254. CALL tab_2d_1d_2( nbpb, fr1_i0_1d (1:nbpb) , fr1_i0 , jpi, jpj, npb(1:nbpb) )
  255. CALL tab_2d_1d_2( nbpb, fr2_i0_1d (1:nbpb) , fr2_i0 , jpi, jpj, npb(1:nbpb) )
  256. CALL tab_2d_1d_2( nbpb, qns_ice_1d(1:nbpb) , qns_ice(:,:,1), jpi, jpj, npb(1:nbpb) )
  257. CALL tab_2d_1d_2( nbpb, dqns_ice_1d(1:nbpb) , dqns_ice(:,:,1), jpi, jpj, npb(1:nbpb) )
  258. IF( .NOT. ln_cpl ) THEN
  259. CALL tab_2d_1d_2( nbpb, qla_ice_1d (1:nbpb) , qla_ice(:,:,1), jpi, jpj, npb(1:nbpb) )
  260. CALL tab_2d_1d_2( nbpb, dqla_ice_1d(1:nbpb) , dqla_ice(:,:,1), jpi, jpj, npb(1:nbpb) )
  261. ENDIF
  262. CALL tab_2d_1d_2( nbpb, tfu_1d (1:nbpb) , tfu , jpi, jpj, npb(1:nbpb) )
  263. CALL tab_2d_1d_2( nbpb, sprecip_1d (1:nbpb) , sprecip , jpi, jpj, npb(1:nbpb) )
  264. CALL tab_2d_1d_2( nbpb, fbif_1d (1:nbpb) , fbif , jpi, jpj, npb(1:nbpb) )
  265. CALL tab_2d_1d_2( nbpb, thcm_1d (1:nbpb) , thcm , jpi, jpj, npb(1:nbpb) )
  266. CALL tab_2d_1d_2( nbpb, qldif_1d (1:nbpb) , qldif , jpi, jpj, npb(1:nbpb) )
  267. CALL tab_2d_1d_2( nbpb, qstbif_1d (1:nbpb) , qstoif , jpi, jpj, npb(1:nbpb) )
  268. CALL tab_2d_1d_2( nbpb, rdm_ice_1d (1:nbpb) , rdm_ice , jpi, jpj, npb(1:nbpb) )
  269. CALL tab_2d_1d_2( nbpb, rdq_ice_1d (1:nbpb) , rdq_ice , jpi, jpj, npb(1:nbpb) )
  270. CALL tab_2d_1d_2( nbpb, dmgwi_1d (1:nbpb) , dmgwi , jpi, jpj, npb(1:nbpb) )
  271. CALL tab_2d_1d_2( nbpb, rdm_snw_1d (1:nbpb) , rdm_snw , jpi, jpj, npb(1:nbpb) )
  272. CALL tab_2d_1d_2( nbpb, rdq_snw_1d (1:nbpb) , rdq_snw , jpi, jpj, npb(1:nbpb) )
  273. CALL tab_2d_1d_2( nbpb, qlbbq_1d (1:nbpb) , zqlbsbq , jpi, jpj, npb(1:nbpb) )
  274. !
  275. CALL lim_thd_zdf_2( 1, nbpb ) ! compute ice growth
  276. !
  277. ! back to the geographic grid.
  278. CALL tab_1d_2d_2( nbpb, frld , npb, frld_1d (1:nbpb) , jpi, jpj )
  279. CALL tab_1d_2d_2( nbpb, hicif , npb, h_ice_1d (1:nbpb) , jpi, jpj )
  280. CALL tab_1d_2d_2( nbpb, hsnif , npb, h_snow_1d (1:nbpb) , jpi, jpj )
  281. CALL tab_1d_2d_2( nbpb, sist , npb, sist_1d (1:nbpb) , jpi, jpj )
  282. CALL tab_1d_2d_2( nbpb, tbif(:,:,1), npb, tbif_1d (1:nbpb , 1 ), jpi, jpj )
  283. CALL tab_1d_2d_2( nbpb, tbif(:,:,2), npb, tbif_1d (1:nbpb , 2 ), jpi, jpj )
  284. CALL tab_1d_2d_2( nbpb, tbif(:,:,3), npb, tbif_1d (1:nbpb , 3 ), jpi, jpj )
  285. CALL tab_1d_2d_2( nbpb, fscmbq , npb, fscbq_1d (1:nbpb) , jpi, jpj )
  286. CALL tab_1d_2d_2( nbpb, ffltbif , npb, fltbif_1d (1:nbpb) , jpi, jpj )
  287. CALL tab_1d_2d_2( nbpb, fstric , npb, fstbif_1d (1:nbpb) , jpi, jpj )
  288. CALL tab_1d_2d_2( nbpb, qldif , npb, qldif_1d (1:nbpb) , jpi, jpj )
  289. CALL tab_1d_2d_2( nbpb, qfvbq , npb, qfvbq_1d (1:nbpb) , jpi, jpj )
  290. CALL tab_1d_2d_2( nbpb, qstoif , npb, qstbif_1d (1:nbpb) , jpi, jpj )
  291. CALL tab_1d_2d_2( nbpb, rdm_ice , npb, rdm_ice_1d(1:nbpb) , jpi, jpj )
  292. CALL tab_1d_2d_2( nbpb, rdq_ice , npb, rdq_ice_1d(1:nbpb) , jpi, jpj )
  293. CALL tab_1d_2d_2( nbpb, dmgwi , npb, dmgwi_1d (1:nbpb) , jpi, jpj )
  294. CALL tab_1d_2d_2( nbpb, rdm_snw , npb, rdm_snw_1d(1:nbpb) , jpi, jpj )
  295. CALL tab_1d_2d_2( nbpb, rdq_snw , npb, rdq_snw_1d(1:nbpb) , jpi, jpj )
  296. CALL tab_1d_2d_2( nbpb, zdvosif , npb, dvsbq_1d (1:nbpb) , jpi, jpj )
  297. CALL tab_1d_2d_2( nbpb, zdvobif , npb, dvbbq_1d (1:nbpb) , jpi, jpj )
  298. CALL tab_1d_2d_2( nbpb, zdvomif , npb, rdvomif_1d(1:nbpb) , jpi, jpj )
  299. CALL tab_1d_2d_2( nbpb, zdvolif , npb, dvlbq_1d (1:nbpb) , jpi, jpj )
  300. CALL tab_1d_2d_2( nbpb, zdvonif , npb, dvnbq_1d (1:nbpb) , jpi, jpj )
  301. CALL tab_1d_2d_2( nbpb, qsr_ice(:,:,1), npb, qsr_ice_1d(1:nbpb) , jpi, jpj )
  302. CALL tab_1d_2d_2( nbpb, qns_ice(:,:,1), npb, qns_ice_1d(1:nbpb) , jpi, jpj )
  303. IF( .NOT. ln_cpl ) CALL tab_1d_2d_2( nbpb, qla_ice(:,:,1), npb, qla_ice_1d(1:nbpb), jpi, jpj )
  304. !
  305. ENDIF
  306. ! Up-date sea ice thickness
  307. !--------------------------
  308. DO jj = 1, jpj
  309. DO ji = 1, jpi
  310. phicif(ji,jj) = hicif(ji,jj)
  311. hicif(ji,jj) = hicif(ji,jj) * ( rone - MAX( rzero, SIGN( rone, - ( 1.0 - frld(ji,jj) ) ) ) )
  312. END DO
  313. END DO
  314. ! Tricky trick : add 2 to frld in the Southern Hemisphere
  315. !--------------------------------------------------------
  316. IF( fcor(1,1) < 0.e0 ) THEN
  317. DO jj = 1, njeqm1
  318. DO ji = 1, jpi
  319. frld(ji,jj) = frld(ji,jj) + 2.0
  320. END DO
  321. END DO
  322. ENDIF
  323. CALL lbc_lnk( frld , 'T', 1. )
  324. ! Select points for lateral accretion (this occurs when heat exchange
  325. ! between ice and ocean is negative; ocean losing heat)
  326. !-----------------------------------------------------------------
  327. nbpac = 0
  328. DO jj = 1, jpj
  329. DO ji = 1, jpi
  330. !i yes! IF ( ( qcmif(ji,jj) - qldif(ji,jj) ) > 0.e0 ) THEN
  331. IF ( tms(ji,jj) * ( qcmif(ji,jj) - qldif(ji,jj) ) > 0.e0 ) THEN
  332. nbpac = nbpac + 1
  333. npac( nbpac ) = (jj - 1) * jpi + ji
  334. ENDIF
  335. END DO
  336. END DO
  337. IF(ln_ctl) THEN
  338. CALL prt_ctl(tab2d_1=phicif, clinfo1=' lim_thd: phicif : ', tab2d_2=hicif, clinfo2=' hicif : ')
  339. WRITE(charout, FMT="('lim_thd: nbpac = ',I4)") nbpac
  340. CALL prt_ctl_info(charout)
  341. ENDIF
  342. ! If ocean gains heat do nothing ; otherwise, one performs lateral accretion
  343. !--------------------------------------------------------------------------------
  344. IF( nbpac > 0 ) THEN
  345. !
  346. zlicegr(:,:) = rdm_ice(:,:) ! to output the lateral sea-ice growth
  347. !...Put the variable in a 1-D array for lateral accretion
  348. CALL tab_2d_1d_2( nbpac, frld_1d (1:nbpac) , frld , jpi, jpj, npac(1:nbpac) )
  349. CALL tab_2d_1d_2( nbpac, h_snow_1d (1:nbpac) , hsnif , jpi, jpj, npac(1:nbpac) )
  350. CALL tab_2d_1d_2( nbpac, h_ice_1d (1:nbpac) , hicif , jpi, jpj, npac(1:nbpac) )
  351. CALL tab_2d_1d_2( nbpac, tbif_1d (1:nbpac , 1 ), tbif(:,:,1), jpi, jpj, npac(1:nbpac) )
  352. CALL tab_2d_1d_2( nbpac, tbif_1d (1:nbpac , 2 ), tbif(:,:,2), jpi, jpj, npac(1:nbpac) )
  353. CALL tab_2d_1d_2( nbpac, tbif_1d (1:nbpac , 3 ), tbif(:,:,3), jpi, jpj, npac(1:nbpac) )
  354. CALL tab_2d_1d_2( nbpac, qldif_1d (1:nbpac) , qldif , jpi, jpj, npac(1:nbpac) )
  355. CALL tab_2d_1d_2( nbpac, qcmif_1d (1:nbpac) , qcmif , jpi, jpj, npac(1:nbpac) )
  356. CALL tab_2d_1d_2( nbpac, qstbif_1d (1:nbpac) , qstoif , jpi, jpj, npac(1:nbpac) )
  357. CALL tab_2d_1d_2( nbpac, rdm_ice_1d(1:nbpac) , rdm_ice , jpi, jpj, npac(1:nbpac) )
  358. CALL tab_2d_1d_2( nbpac, rdq_ice_1d(1:nbpac) , rdq_ice , jpi, jpj, npac(1:nbpac) )
  359. CALL tab_2d_1d_2( nbpac, dvlbq_1d (1:nbpac) , zdvolif , jpi, jpj, npac(1:nbpac) )
  360. CALL tab_2d_1d_2( nbpac, tfu_1d (1:nbpac) , tfu , jpi, jpj, npac(1:nbpac) )
  361. !
  362. CALL lim_thd_lac_2( 1 , nbpac ) ! lateral accretion routine.
  363. !
  364. ! back to the geographic grid
  365. CALL tab_1d_2d_2( nbpac, frld , npac(1:nbpac), frld_1d (1:nbpac) , jpi, jpj )
  366. CALL tab_1d_2d_2( nbpac, hsnif , npac(1:nbpac), h_snow_1d (1:nbpac) , jpi, jpj )
  367. CALL tab_1d_2d_2( nbpac, hicif , npac(1:nbpac), h_ice_1d (1:nbpac) , jpi, jpj )
  368. CALL tab_1d_2d_2( nbpac, tbif(:,:,1), npac(1:nbpac), tbif_1d (1:nbpac , 1 ), jpi, jpj )
  369. CALL tab_1d_2d_2( nbpac, tbif(:,:,2), npac(1:nbpac), tbif_1d (1:nbpac , 2 ), jpi, jpj )
  370. CALL tab_1d_2d_2( nbpac, tbif(:,:,3), npac(1:nbpac), tbif_1d (1:nbpac , 3 ), jpi, jpj )
  371. CALL tab_1d_2d_2( nbpac, qstoif , npac(1:nbpac), qstbif_1d (1:nbpac) , jpi, jpj )
  372. CALL tab_1d_2d_2( nbpac, rdm_ice , npac(1:nbpac), rdm_ice_1d(1:nbpac) , jpi, jpj )
  373. CALL tab_1d_2d_2( nbpac, rdq_ice , npac(1:nbpac), rdq_ice_1d(1:nbpac) , jpi, jpj )
  374. CALL tab_1d_2d_2( nbpac, zdvolif , npac(1:nbpac), dvlbq_1d (1:nbpac) , jpi, jpj )
  375. !
  376. ENDIF
  377. ! Recover frld values between 0 and 1 in the Southern Hemisphere (tricky trick)
  378. ! Update daily thermodynamic ice production.
  379. !------------------------------------------------------------------------------
  380. DO jj = 1, jpj
  381. DO ji = 1, jpi
  382. frld (ji,jj) = MIN( frld(ji,jj), ABS( frld(ji,jj) - 2.0 ) )
  383. fr_i (ji,jj) = 1.0 - frld(ji,jj)
  384. hicifp(ji,jj) = hicif(ji,jj) * fr_i(ji,jj) - hicifp(ji,jj)
  385. END DO
  386. END DO
  387. ! Outputs
  388. !--------------------------------------------------------------------------------
  389. ztmp(:,:) = 1. - pfrld(:,:) ! fraction of ice after the dynamic, before the thermodynamic
  390. IF( iom_use('ist_cea' ) ) CALL iom_put( 'ist_cea', (sist(:,:) - rt0) * ztmp(:,:) ) ! Ice surface temperature [Celius]
  391. IF( iom_use('qsr_ai_cea' ) ) CALL iom_put( 'qsr_ai_cea', qsr_ice(:,:,1) * ztmp(:,:) ) ! Solar flux over the ice [W/m2]
  392. IF( iom_use('qns_ai_cea' ) ) CALL iom_put( 'qns_ai_cea', qns_ice(:,:,1) * ztmp(:,:) ) ! Non-solar flux over the ice [W/m2]
  393. IF( iom_use('qla_ai_cea' ) .AND. .NOT. ln_cpl ) &
  394. & CALL iom_put( 'qla_ai_cea', qla_ice(:,:,1) * ztmp(:,:) ) ! Latent flux over the ice [W/m2]
  395. !
  396. IF( iom_use('snowthic_cea')) CALL iom_put( 'snowthic_cea', hsnif (:,:) * fr_i(:,:) ) ! Snow thickness [m]
  397. IF( iom_use('icethic_cea' )) CALL iom_put( 'icethic_cea' , hicif (:,:) * fr_i(:,:) ) ! Ice thickness [m]
  398. zztmp = 1.0 / rdt_ice
  399. IF( iom_use('iceprod_cea') ) CALL iom_put( 'iceprod_cea' , hicifp (:,:) * zztmp ) ! Ice produced [m/s]
  400. IF( iom_use('iiceconc' ) ) CALL iom_put( 'iiceconc' , fr_i(:,:) ) ! Ice concentration [-]
  401. IF( iom_use('snowmel_cea') ) CALL iom_put( 'snowmel_cea' , rdm_snw(:,:) * zztmp ) ! Snow melt [kg/m2/s]
  402. zztmp = rhoic / rdt_ice
  403. IF( iom_use('sntoice_cea') ) CALL iom_put( 'sntoice_cea' , zdvonif(:,:) * zztmp ) ! Snow to Ice transformation [kg/m2/s]
  404. IF( iom_use('ticemel_cea') ) CALL iom_put( 'ticemel_cea' , zdvosif(:,:) * zztmp ) ! Melt at Sea Ice top [kg/m2/s]
  405. IF( iom_use('bicemel_cea') ) CALL iom_put( 'bicemel_cea' , zdvomif(:,:) * zztmp ) ! Melt at Sea Ice bottom [kg/m2/s]
  406. IF( iom_use('licepro_cea') ) THEN
  407. zlicegr(:,:) = MAX( 0.e0, rdm_ice(:,:)-zlicegr(:,:) )
  408. CALL iom_put( 'licepro_cea' , zlicegr(:,:) * zztmp ) ! Lateral sea ice growth [kg/m2/s]
  409. ENDIF
  410. !
  411. ! Compute the Eastward & Northward sea-ice transport
  412. IF( iom_use('u_imasstr') ) THEN
  413. zztmp = 0.25 * rhoic
  414. DO jj = 1, jpjm1
  415. DO ji = 1, jpim1 ! NO vector opt.
  416. ! Ice velocities, volume & transport at U-points
  417. zuice_m = u_ice(ji+1,jj+1) + u_ice(ji+1,jj )
  418. zhice_u = hicif(ji,jj)*e2t(ji,jj)*fr_i(ji,jj) + hicif(ji+1,jj )*e2t(ji+1,jj )*fr_i(ji+1,jj )
  419. zu_imasstr(ji,jj) = zztmp * zhice_u * zuice_m
  420. END DO
  421. END DO
  422. CALL lbc_lnk( zu_imasstr, 'U', -1. )
  423. CALL iom_put( 'u_imasstr', zu_imasstr(:,:) ) ! Ice transport along i-axis at U-point [kg/s]
  424. ENDIF
  425. IF( iom_use('v_imasstr') ) THEN
  426. zztmp = 0.25 * rhoic
  427. DO jj = 1, jpjm1
  428. DO ji = 1, jpim1 ! NO vector opt.
  429. ! Ice velocities, volume & transport at V-points
  430. zvice_m = v_ice(ji+1,jj+1) + v_ice(ji ,jj+1)
  431. zhice_v = hicif(ji,jj)*e1t(ji,jj)*fr_i(ji,jj) + hicif(ji ,jj+1)*e1t(ji ,jj+1)*fr_i(ji ,jj+1)
  432. zv_imasstr(ji,jj) = zztmp * zhice_v * zvice_m
  433. END DO
  434. END DO
  435. CALL lbc_lnk( zv_imasstr, 'V', -1. )
  436. CALL iom_put( 'v_imasstr', zv_imasstr(:,:) ) ! Ice transport along j-axis at V-point [kg/s]
  437. ENDIF
  438. !! Fram Strait sea-ice transport (sea-ice + snow) (in ORCA2 = 5 points)
  439. IF( iom_use('fram_trans') .and. cp_cfg == "orca" .AND. jp_cfg == 2 ) THEN ! ORCA R2 configuration
  440. DO jj = mj0(137), mj1(137) ! B grid
  441. IF( mj0(jj-1) >= nldj ) THEN
  442. DO ji = MAX(mi0(134),nldi), MIN(mi1(138),nlei)
  443. zrhoij = e1t(ji,jj ) * fr_i(ji,jj ) * ( rhoic*hicif(ji,jj ) + rhosn*hsnif(ji,jj ) )
  444. zrhoijm1 = e1t(ji,jj-1) * fr_i(ji,jj-1) * ( rhoic*hicif(ji,jj-1) + rhosn*hsnif(ji,jj-1) )
  445. ztr_fram = ztr_fram - 0.25 * ( v_ice(ji,jj)+ v_ice(ji+1,jj) ) * ( zrhoij + zrhoijm1 )
  446. END DO
  447. ENDIF
  448. END DO
  449. IF( lk_mpp ) CALL mpp_sum( ztr_fram )
  450. CALL iom_put( 'fram_trans', ztr_fram ) ! Ice transport through Fram strait [kg/s]
  451. ENDIF
  452. IF( iom_use('ice_pres') .OR. iom_use('ist_ipa') .OR. iom_use('uice_ipa') .OR. iom_use('vice_ipa') ) THEN
  453. !! ce ztmp(:,:) = 1. - AINT( frld(:,:), wp ) ! return 1 as soon as there is ice
  454. !! ce A big warning because the model crashes on IDRIS/IBM SP6 with xlf 13.1.0.3, see ticket #761
  455. !! ce We Unroll the loop and everything works fine
  456. DO jj = 1, jpj
  457. DO ji = 1, jpi
  458. ztmp(ji,jj) = 1. - AINT( frld(ji,jj), wp ) ! return 1 as soon as there is ice
  459. END DO
  460. END DO
  461. !
  462. IF( iom_use('ice_pres') ) CALL iom_put( 'ice_pres', ztmp ) ! Ice presence [-]
  463. IF( iom_use('ist_ipa' ) ) CALL iom_put( 'ist_ipa' , ( sist(:,:) - rt0 ) * ztmp(:,:) ) ! Ice surface temperature [Celius]
  464. IF( iom_use('uice_ipa') ) CALL iom_put( 'uice_ipa', u_ice(:,:) * ztmp(:,:) ) ! Ice velocity along i-axis at I-point [m/s]
  465. IF( iom_use('vice_ipa') ) CALL iom_put( 'vice_ipa', v_ice(:,:) * ztmp(:,:) ) ! Ice velocity along j-axis at I-point [m/s]
  466. ENDIF
  467. IF(ln_ctl) THEN
  468. CALL prt_ctl_info(' lim_thd end ')
  469. CALL prt_ctl( tab2d_1=hicif , clinfo1=' lim_thd: hicif : ', tab2d_2=hsnif , clinfo2=' hsnif : ' )
  470. CALL prt_ctl( tab2d_1=frld , clinfo1=' lim_thd: frld : ', tab2d_2=hicifp, clinfo2=' hicifp : ' )
  471. CALL prt_ctl( tab2d_1=phicif , clinfo1=' lim_thd: phicif : ', tab2d_2=pfrld , clinfo2=' pfrld : ' )
  472. CALL prt_ctl( tab2d_1=sist , clinfo1=' lim_thd: sist : ' )
  473. CALL prt_ctl( tab2d_1=tbif(:,:,1), clinfo1=' lim_thd: tbif 1 : ' )
  474. CALL prt_ctl( tab2d_1=tbif(:,:,2), clinfo1=' lim_thd: tbif 2 : ' )
  475. CALL prt_ctl( tab2d_1=tbif(:,:,3), clinfo1=' lim_thd: tbif 3 : ' )
  476. CALL prt_ctl( tab2d_1=fdtcn , clinfo1=' lim_thd: fdtcn : ', tab2d_2=qdtcn , clinfo2=' qdtcn : ' )
  477. CALL prt_ctl( tab2d_1=qstoif , clinfo1=' lim_thd: qstoif : ', tab2d_2=fsbbq , clinfo2=' fsbbq : ' )
  478. ENDIF
  479. !
  480. CALL wrk_dealloc( jpi, jpj, ztmp, zqlbsbq, zlicegr, zdvosif, zdvobif, zdvolif, zdvonif, zdvomif, zu_imasstr, zv_imasstr )
  481. CALL wrk_dealloc( jpi, jpj, jpk, zmsk )
  482. !
  483. END SUBROUTINE lim_thd_2
  484. SUBROUTINE lim_thd_init_2
  485. !!-------------------------------------------------------------------
  486. !! *** ROUTINE lim_thd_init_2 ***
  487. !!
  488. !! ** Purpose : Physical constants and parameters linked to the ice
  489. !! thermodynamics
  490. !!
  491. !! ** Method : Read the namicethd namelist and check the ice-thermo
  492. !! parameter values called at the first timestep (nit000)
  493. !!
  494. !! ** input : Namelist namicether
  495. !!-------------------------------------------------------------------
  496. INTEGER :: ios ! Local integer output status for namelist read
  497. NAMELIST/namicethd/ hmelt , hiccrit, hicmin, hiclim, amax , &
  498. & swiqst, sbeta , parlat, hakspl, hibspl, exld, &
  499. & hakdif, hnzst , thth , parsub, alphs
  500. !!-------------------------------------------------------------------
  501. REWIND( numnam_ice_ref ) ! Namelist namicethd in reference namelist : Ice thermodynamics
  502. READ ( numnam_ice_ref, namicethd, IOSTAT = ios, ERR = 901)
  503. 901 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namicethd in reference namelist', lwp )
  504. REWIND( numnam_ice_cfg ) ! Namelist namicethd in configuration namelist : Ice thermodynamics
  505. READ ( numnam_ice_cfg, namicethd, IOSTAT = ios, ERR = 902 )
  506. 902 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namicethd in configuration namelist', lwp )
  507. IF(lwm) WRITE ( numoni, namicethd )
  508. IF( ln_cpl .AND. parsub /= 0.0 ) CALL ctl_stop( 'In coupled mode, use parsub = 0. or send dqla' )
  509. !
  510. IF(lwp) THEN ! control print
  511. WRITE(numout,*)
  512. WRITE(numout,*)'lim_thd_init_2: ice parameters for ice thermodynamic computation '
  513. WRITE(numout,*)'~~~~~~~~~~~~~~'
  514. WRITE(numout,*)' maximum melting at the bottom hmelt = ', hmelt
  515. WRITE(numout,*)' ice thick. for lateral accretion in NH (SH) hiccrit(1/2) = ', hiccrit
  516. WRITE(numout,*)' ice thick. corr. to max. energy stored in brine pocket hicmin = ', hicmin
  517. WRITE(numout,*)' minimum ice thickness hiclim = ', hiclim
  518. WRITE(numout,*)' maximum lead fraction amax = ', amax
  519. WRITE(numout,*)' energy stored in brine pocket (=1) or not (=0) swiqst = ', swiqst
  520. WRITE(numout,*)' numerical carac. of the scheme for diffusion in ice '
  521. WRITE(numout,*)' Cranck-Nicholson (=0.5), implicit (=1), explicit (=0) sbeta = ', sbeta
  522. WRITE(numout,*)' percentage of energy used for lateral ablation parlat = ', parlat
  523. WRITE(numout,*)' slope of distr. for Hakkinen-Mellor lateral melting hakspl = ', hakspl
  524. WRITE(numout,*)' slope of distribution for Hibler lateral melting hibspl = ', hibspl
  525. WRITE(numout,*)' exponent for leads-closure rate exld = ', exld
  526. WRITE(numout,*)' coefficient for diffusions of ice and snow hakdif = ', hakdif
  527. WRITE(numout,*)' threshold thick. for comp. of eq. thermal conductivity zhth = ', thth
  528. WRITE(numout,*)' thickness of the surf. layer in temp. computation hnzst = ', hnzst
  529. WRITE(numout,*)' switch for snow sublimation (=1) or not (=0) parsub = ', parsub
  530. WRITE(numout,*)' coefficient for snow density when snow ice formation alphs = ', alphs
  531. ENDIF
  532. !
  533. uscomi = 1.0 / ( 1.0 - amax ) ! inverse of minimum lead fraction
  534. rcdsn = hakdif * rcdsn
  535. rcdic = hakdif * rcdic
  536. !
  537. IF( hsndif > 100.e0 .OR. hicdif > 100.e0 ) THEN
  538. cnscg = 0.e0
  539. ELSE
  540. cnscg = rcpsn / rcpic ! ratio rcpsn/rcpic
  541. ENDIF
  542. !
  543. END SUBROUTINE lim_thd_init_2
  544. #else
  545. !!----------------------------------------------------------------------
  546. !! Default option Dummy module NO LIM 2.0 sea-ice model
  547. !!----------------------------------------------------------------------
  548. CONTAINS
  549. SUBROUTINE lim_thd_2 ! Dummy routine
  550. END SUBROUTINE lim_thd_2
  551. #endif
  552. !!======================================================================
  553. END MODULE limthd_2