icbdia.F90 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  1. MODULE icbdia
  2. !!======================================================================
  3. !! *** MODULE icbdia ***
  4. !! Icebergs: initialise variables for iceberg budgets and diagnostics
  5. !!======================================================================
  6. !! History : 3.3 ! 2010-01 (Martin, Adcroft) Original code
  7. !! - ! 2011-03 (Madec) Part conversion to NEMO form
  8. !! - ! Removal of mapping from another grid
  9. !! - ! 2011-04 (Alderson) Split into separate modules
  10. !! - ! 2011-05 (Alderson) Budgets are now all here with lots
  11. !! - ! of silly routines to call to get values in
  12. !! - ! from the right points in the code
  13. !!----------------------------------------------------------------------
  14. !!----------------------------------------------------------------------
  15. !! icb_dia_init : initialise iceberg budgeting
  16. !! icb_dia : global iceberg diagnostics
  17. !! icb_dia_step : reset at the beginning of each timestep
  18. !! icb_dia_put : output (via iom_put) iceberg fields
  19. !! icb_dia_calve :
  20. !! icb_dia_income:
  21. !! icb_dia_size :
  22. !! icb_dia_speed :
  23. !! icb_dia_melt :
  24. !! report_state :
  25. !! report_consistant :
  26. !! report_budget :
  27. !! report_istate :
  28. !! report_ibudget:
  29. !!----------------------------------------------------------------------
  30. USE par_oce ! ocean parameters
  31. USE dom_oce ! ocean domain
  32. USE in_out_manager ! nemo IO
  33. USE lib_mpp ! MPP library
  34. USE iom ! I/O library
  35. USE icb_oce ! iceberg variables
  36. USE icbutl ! iceberg utility routines
  37. IMPLICIT NONE
  38. PRIVATE
  39. PUBLIC icb_dia_init ! routine called in icbini.F90 module
  40. PUBLIC icb_dia ! routine called in icbstp.F90 module
  41. PUBLIC icb_dia_step ! routine called in icbstp.F90 module
  42. PUBLIC icb_dia_put ! routine called in icbstp.F90 module
  43. PUBLIC icb_dia_melt ! routine called in icbthm.F90 module
  44. PUBLIC icb_dia_size ! routine called in icbthm.F90 module
  45. PUBLIC icb_dia_speed ! routine called in icbdyn.F90 module
  46. PUBLIC icb_dia_calve ! routine called in icbclv.F90 module
  47. PUBLIC icb_dia_income ! routine called in icbclv.F90 module
  48. REAL(wp), DIMENSION(:,:) , ALLOCATABLE, PUBLIC :: berg_melt ! Melting+erosion rate of icebergs [kg/s/m2]
  49. REAL(wp), DIMENSION(:,:) , ALLOCATABLE, PUBLIC :: berg_melt_hcflx ! Heat flux to ocean due to heat content of melting icebergs [J/s/m2]
  50. REAL(wp), DIMENSION(:,:) , ALLOCATABLE, PUBLIC :: berg_melt_qlat ! Heat flux to ocean due to latent heat of melting icebergs [J/s/m2]
  51. REAL(wp), DIMENSION(:,:) , ALLOCATABLE, PUBLIC :: buoy_melt ! Buoyancy component of melting rate [kg/s/m2]
  52. REAL(wp), DIMENSION(:,:) , ALLOCATABLE, PUBLIC :: eros_melt ! Erosion component of melting rate [kg/s/m2]
  53. REAL(wp), DIMENSION(:,:) , ALLOCATABLE, PUBLIC :: conv_melt ! Convective component of melting rate [kg/s/m2]
  54. REAL(wp), DIMENSION(:,:) , ALLOCATABLE, PUBLIC :: bits_src ! Mass flux from berg erosion into bergy bits [kg/s/m2]
  55. REAL(wp), DIMENSION(:,:) , ALLOCATABLE, PUBLIC :: bits_melt ! Melting rate of bergy bits [kg/s/m2]
  56. REAL(wp), DIMENSION(:,:) , ALLOCATABLE, PUBLIC :: bits_mass ! Mass distribution of bergy bits [kg/s/m2]
  57. REAL(wp), DIMENSION(:,:) , ALLOCATABLE, PUBLIC :: berg_mass ! Mass distribution [kg/m2]
  58. REAL(wp), DIMENSION(:,:,:), ALLOCATABLE, PUBLIC :: real_calving ! Calving rate into iceberg class at
  59. ! ! calving locations [kg/s]
  60. REAL(wp), DIMENSION(:,:) , ALLOCATABLE :: tmpc ! Temporary work space
  61. REAL(wp), DIMENSION(:) , ALLOCATABLE :: rsumbuf ! Temporary work space to reduce mpp exchanges
  62. INTEGER , DIMENSION(:) , ALLOCATABLE :: nsumbuf ! Temporary work space to reduce mpp exchanges
  63. REAL(wp) :: berg_melt_net
  64. REAL(wp) :: bits_src_net
  65. REAL(wp) :: bits_melt_net
  66. REAL(wp) :: bits_mass_start , bits_mass_end
  67. REAL(wp) :: floating_heat_start , floating_heat_end
  68. REAL(wp) :: floating_mass_start , floating_mass_end
  69. REAL(wp) :: bergs_mass_start , bergs_mass_end
  70. REAL(wp) :: stored_start , stored_heat_start
  71. REAL(wp) :: stored_end , stored_heat_end
  72. REAL(wp) :: calving_src_net , calving_out_net
  73. REAL(wp) :: calving_src_heat_net, calving_out_heat_net
  74. REAL(wp) :: calving_src_heat_used_net
  75. REAL(wp) :: calving_rcv_net , calving_ret_net , calving_used_net
  76. REAL(wp) :: heat_to_bergs_net, heat_to_ocean_net, melt_net
  77. REAL(wp) :: calving_to_bergs_net
  78. INTEGER :: nbergs_start, nbergs_end, nbergs_calved
  79. INTEGER :: nbergs_melted
  80. INTEGER :: nspeeding_tickets, nspeeding_tickets_all
  81. INTEGER , DIMENSION(nclasses) :: nbergs_calved_by_class
  82. !!----------------------------------------------------------------------
  83. !! NEMO/OCE 4.0 , NEMO Consortium (2018)
  84. !! $Id: icbdia.F90 14773 2021-04-30 10:23:51Z clem $
  85. !! Software governed by the CeCILL license (see ./LICENSE)
  86. !!----------------------------------------------------------------------
  87. CONTAINS
  88. SUBROUTINE icb_dia_init( )
  89. !!----------------------------------------------------------------------
  90. !!----------------------------------------------------------------------
  91. !
  92. IF( .NOT.ln_bergdia ) RETURN
  93. ALLOCATE( berg_melt (jpi,jpj) ) ; berg_melt (:,:) = 0._wp
  94. ALLOCATE( berg_melt_hcflx(jpi,jpj) ) ; berg_melt_hcflx(:,:) = 0._wp
  95. ALLOCATE( berg_melt_qlat(jpi,jpj) ) ; berg_melt_qlat(:,:) = 0._wp
  96. ALLOCATE( buoy_melt (jpi,jpj) ) ; buoy_melt (:,:) = 0._wp
  97. ALLOCATE( eros_melt (jpi,jpj) ) ; eros_melt (:,:) = 0._wp
  98. ALLOCATE( conv_melt (jpi,jpj) ) ; conv_melt (:,:) = 0._wp
  99. ALLOCATE( bits_src (jpi,jpj) ) ; bits_src (:,:) = 0._wp
  100. ALLOCATE( bits_melt (jpi,jpj) ) ; bits_melt (:,:) = 0._wp
  101. ALLOCATE( bits_mass (jpi,jpj) ) ; bits_mass (:,:) = 0._wp
  102. ALLOCATE( berg_mass (jpi,jpj) ) ; berg_mass (:,:) = 0._wp
  103. ALLOCATE( real_calving (jpi,jpj,nclasses) ) ; real_calving(:,:,:) = 0._wp
  104. ALLOCATE( tmpc(jpi,jpj) ) ; tmpc (:,:) = 0._wp
  105. nbergs_start = 0
  106. nbergs_end = 0
  107. stored_end = 0._wp
  108. nbergs_start = 0._wp
  109. stored_start = 0._wp
  110. nbergs_melted = 0
  111. nbergs_calved = 0
  112. nbergs_calved_by_class(:) = 0
  113. nspeeding_tickets = 0
  114. nspeeding_tickets_all = 0
  115. stored_heat_end = 0._wp
  116. floating_heat_end = 0._wp
  117. floating_mass_end = 0._wp
  118. bergs_mass_end = 0._wp
  119. bits_mass_end = 0._wp
  120. stored_heat_start = 0._wp
  121. floating_heat_start = 0._wp
  122. floating_mass_start = 0._wp
  123. bergs_mass_start = 0._wp
  124. bits_mass_start = 0._wp
  125. bits_mass_end = 0._wp
  126. calving_used_net = 0._wp
  127. calving_to_bergs_net = 0._wp
  128. heat_to_bergs_net = 0._wp
  129. heat_to_ocean_net = 0._wp
  130. calving_rcv_net = 0._wp
  131. calving_ret_net = 0._wp
  132. calving_src_net = 0._wp
  133. calving_out_net = 0._wp
  134. calving_src_heat_net = 0._wp
  135. calving_src_heat_used_net = 0._wp
  136. calving_out_heat_net = 0._wp
  137. melt_net = 0._wp
  138. berg_melt_net = 0._wp
  139. bits_melt_net = 0._wp
  140. bits_src_net = 0._wp
  141. floating_mass_start = icb_utl_mass( first_berg )
  142. bergs_mass_start = icb_utl_mass( first_berg, justbergs=.TRUE. )
  143. bits_mass_start = icb_utl_mass( first_berg, justbits =.TRUE. )
  144. IF( lk_mpp ) THEN
  145. ALLOCATE( rsumbuf(23) ) ; rsumbuf(:) = 0._wp
  146. ALLOCATE( nsumbuf(4+nclasses) ) ; nsumbuf(:) = 0
  147. rsumbuf(1) = floating_mass_start
  148. rsumbuf(2) = bergs_mass_start
  149. rsumbuf(3) = bits_mass_start
  150. CALL mpp_sum( 'icbdia', rsumbuf(1:3), 3 )
  151. floating_mass_start = rsumbuf(1)
  152. bergs_mass_start = rsumbuf(2)
  153. bits_mass_start = rsumbuf(3)
  154. ENDIF
  155. !
  156. END SUBROUTINE icb_dia_init
  157. SUBROUTINE icb_dia( ld_budge )
  158. !!----------------------------------------------------------------------
  159. !! sum all the things we've accumulated so far in the current processor
  160. !! in MPP case then add these sums across all processors
  161. !! for this we pack variables into buffer so we only need one mpp_sum
  162. !!----------------------------------------------------------------------
  163. LOGICAL, INTENT(in) :: ld_budge !
  164. !
  165. INTEGER :: ik
  166. REAL(wp):: zunused_calving, ztmpsum, zgrdd_berg_mass, zgrdd_bits_mass
  167. !!----------------------------------------------------------------------
  168. !
  169. IF( .NOT.ln_bergdia ) RETURN
  170. zunused_calving = SUM( berg_grid%calving(:,:) )
  171. ztmpsum = SUM( berg_grid%floating_melt(:,:) * e1e2t(:,:) * tmask_i(:,:) )
  172. melt_net = melt_net + ztmpsum * berg_dt
  173. calving_out_net = calving_out_net + ( zunused_calving + ztmpsum ) * berg_dt
  174. ztmpsum = SUM( berg_melt(:,:) * e1e2t(:,:) * tmask_i(:,:) )
  175. berg_melt_net = berg_melt_net + ztmpsum * berg_dt
  176. ztmpsum = SUM( bits_src(:,:) * e1e2t(:,:) * tmask_i(:,:) )
  177. bits_src_net = bits_src_net + ztmpsum * berg_dt
  178. ztmpsum = SUM( bits_melt(:,:) * e1e2t(:,:) * tmask_i(:,:) )
  179. bits_melt_net = bits_melt_net + ztmpsum * berg_dt
  180. ztmpsum = SUM( src_calving(:,:) * tmask_i(:,:) )
  181. calving_ret_net = calving_ret_net + ztmpsum * berg_dt
  182. ztmpsum = SUM( berg_grid%calving_hflx(:,:) * e1e2t(:,:) * tmask_i(:,:) )
  183. calving_out_heat_net = calving_out_heat_net + ztmpsum * berg_dt ! Units of J
  184. !
  185. IF( ld_budge ) THEN
  186. stored_end = SUM( berg_grid%stored_ice(:,:,:) )
  187. stored_heat_end = SUM( berg_grid%stored_heat(:,:) )
  188. floating_mass_end = icb_utl_mass( first_berg )
  189. bergs_mass_end = icb_utl_mass( first_berg,justbergs=.TRUE. )
  190. bits_mass_end = icb_utl_mass( first_berg,justbits =.TRUE. )
  191. floating_heat_end = icb_utl_heat( first_berg )
  192. !
  193. nbergs_end = icb_utl_count()
  194. zgrdd_berg_mass = SUM( berg_mass(:,:)*e1e2t(:,:)*tmask_i(:,:) )
  195. zgrdd_bits_mass = SUM( bits_mass(:,:)*e1e2t(:,:)*tmask_i(:,:) )
  196. !
  197. IF( lk_mpp ) THEN
  198. rsumbuf( 1) = stored_end
  199. rsumbuf( 2) = stored_heat_end
  200. rsumbuf( 3) = floating_mass_end
  201. rsumbuf( 4) = bergs_mass_end
  202. rsumbuf( 5) = bits_mass_end
  203. rsumbuf( 6) = floating_heat_end
  204. rsumbuf( 7) = calving_ret_net
  205. rsumbuf( 8) = calving_out_net
  206. rsumbuf( 9) = calving_rcv_net
  207. rsumbuf(10) = calving_src_net
  208. rsumbuf(11) = calving_src_heat_net
  209. rsumbuf(12) = calving_src_heat_used_net
  210. rsumbuf(13) = calving_out_heat_net
  211. rsumbuf(14) = calving_used_net
  212. rsumbuf(15) = calving_to_bergs_net
  213. rsumbuf(16) = heat_to_bergs_net
  214. rsumbuf(17) = heat_to_ocean_net
  215. rsumbuf(18) = melt_net
  216. rsumbuf(19) = berg_melt_net
  217. rsumbuf(20) = bits_src_net
  218. rsumbuf(21) = bits_melt_net
  219. rsumbuf(22) = zgrdd_berg_mass
  220. rsumbuf(23) = zgrdd_bits_mass
  221. !
  222. CALL mpp_sum( 'icbdia', rsumbuf(1:23), 23)
  223. !
  224. stored_end = rsumbuf( 1)
  225. stored_heat_end = rsumbuf( 2)
  226. floating_mass_end = rsumbuf( 3)
  227. bergs_mass_end = rsumbuf( 4)
  228. bits_mass_end = rsumbuf( 5)
  229. floating_heat_end = rsumbuf( 6)
  230. calving_ret_net = rsumbuf( 7)
  231. calving_out_net = rsumbuf( 8)
  232. calving_rcv_net = rsumbuf( 9)
  233. calving_src_net = rsumbuf(10)
  234. calving_src_heat_net = rsumbuf(11)
  235. calving_src_heat_used_net = rsumbuf(12)
  236. calving_out_heat_net = rsumbuf(13)
  237. calving_used_net = rsumbuf(14)
  238. calving_to_bergs_net = rsumbuf(15)
  239. heat_to_bergs_net = rsumbuf(16)
  240. heat_to_ocean_net = rsumbuf(17)
  241. melt_net = rsumbuf(18)
  242. berg_melt_net = rsumbuf(19)
  243. bits_src_net = rsumbuf(20)
  244. bits_melt_net = rsumbuf(21)
  245. zgrdd_berg_mass = rsumbuf(22)
  246. zgrdd_bits_mass = rsumbuf(23)
  247. !
  248. nsumbuf(1) = nbergs_end
  249. nsumbuf(2) = nbergs_calved
  250. nsumbuf(3) = nbergs_melted
  251. nsumbuf(4) = nspeeding_tickets
  252. DO ik = 1, nclasses
  253. nsumbuf(4+ik) = nbergs_calved_by_class(ik)
  254. END DO
  255. CALL mpp_sum( 'icbdia', nsumbuf(1:nclasses+4), nclasses+4 )
  256. !
  257. nbergs_end = nsumbuf(1)
  258. nbergs_calved = nsumbuf(2)
  259. nbergs_melted = nsumbuf(3)
  260. nspeeding_tickets_all = nsumbuf(4)
  261. DO ik = 1,nclasses
  262. nbergs_calved_by_class(ik)= nsumbuf(4+ik)
  263. END DO
  264. !
  265. ENDIF
  266. !
  267. CALL report_state ( 'stored ice','kg','',stored_start,'',stored_end,'')
  268. CALL report_state ( 'floating','kg','',floating_mass_start,'',floating_mass_end,'',nbergs_end )
  269. CALL report_state ( 'icebergs','kg','',bergs_mass_start,'',bergs_mass_end,'')
  270. CALL report_state ( 'bits','kg','',bits_mass_start,'',bits_mass_end,'')
  271. CALL report_istate ( 'berg #','',nbergs_start,'',nbergs_end,'')
  272. CALL report_ibudget( 'berg #','calved',nbergs_calved, &
  273. & 'melted',nbergs_melted, &
  274. & '#',nbergs_start,nbergs_end)
  275. CALL report_budget( 'stored mass','kg','calving used',calving_used_net, &
  276. & 'bergs',calving_to_bergs_net, &
  277. & 'stored mass',stored_start,stored_end)
  278. CALL report_budget( 'floating mass','kg','calving used',calving_to_bergs_net, &
  279. & 'bergs',melt_net, &
  280. & 'stored mass',floating_mass_start,floating_mass_end)
  281. CALL report_budget( 'berg mass','kg','calving',calving_to_bergs_net, &
  282. & 'melt+eros',berg_melt_net, &
  283. & 'berg mass',bergs_mass_start,bergs_mass_end)
  284. CALL report_budget( 'bits mass','kg','eros used',bits_src_net, &
  285. & 'bergs',bits_melt_net, &
  286. & 'stored mass',bits_mass_start,bits_mass_end)
  287. CALL report_budget( 'net mass','kg','recvd',calving_rcv_net, &
  288. & 'rtrnd',calving_ret_net, &
  289. & 'net mass',stored_start+floating_mass_start, &
  290. & stored_end+floating_mass_end)
  291. CALL report_consistant( 'iceberg mass','kg','gridded',zgrdd_berg_mass,'bergs',bergs_mass_end)
  292. CALL report_consistant( 'bits mass','kg','gridded',zgrdd_bits_mass,'bits',bits_mass_end)
  293. CALL report_state( 'net heat','J','',stored_heat_start+floating_heat_start,'', &
  294. & stored_heat_end+floating_heat_end,'')
  295. CALL report_state( 'stored heat','J','',stored_heat_start,'',stored_heat_end,'')
  296. CALL report_state( 'floating heat','J','',floating_heat_start,'',floating_heat_end,'')
  297. CALL report_budget( 'net heat','J','net heat',calving_src_heat_net, &
  298. & 'net heat',calving_out_heat_net, &
  299. & 'net heat',stored_heat_start+floating_heat_start, &
  300. & stored_heat_end+floating_heat_end)
  301. CALL report_budget( 'stored heat','J','calving used',calving_src_heat_used_net, &
  302. & 'bergs',heat_to_bergs_net, &
  303. & 'net heat',stored_heat_start,stored_heat_end)
  304. CALL report_budget( 'flting heat','J','calved',heat_to_bergs_net, &
  305. & 'melt',heat_to_ocean_net, &
  306. & 'net heat',floating_heat_start,floating_heat_end)
  307. IF (nn_verbose_level >= 1) THEN
  308. CALL report_consistant( 'top interface','kg','from SIS',calving_src_net, &
  309. & 'received',calving_rcv_net)
  310. CALL report_consistant( 'bot interface','kg','sent',calving_out_net, &
  311. & 'returned',calving_ret_net)
  312. ENDIF
  313. IF (nn_verbose_level > 0) THEN
  314. WRITE( numicb, '("calved by class = ",i6,20(",",i6))') (nbergs_calved_by_class(ik),ik=1,nclasses)
  315. IF( nspeeding_tickets_all > 0 ) THEN
  316. WRITE( numicb, '("speeding tickets issued (this domain) = ",i6)') nspeeding_tickets
  317. WRITE( numicb, '("speeding tickets issued (all domains) = ",i6)') nspeeding_tickets_all
  318. END IF
  319. ENDIF
  320. !
  321. nbergs_start = nbergs_end
  322. stored_start = stored_end
  323. nbergs_melted = 0
  324. nbergs_calved = 0
  325. nbergs_calved_by_class(:) = 0
  326. nspeeding_tickets = 0
  327. nspeeding_tickets_all = 0
  328. stored_heat_start = stored_heat_end
  329. floating_heat_start = floating_heat_end
  330. floating_mass_start = floating_mass_end
  331. bergs_mass_start = bergs_mass_end
  332. bits_mass_start = bits_mass_end
  333. calving_used_net = 0._wp
  334. calving_to_bergs_net = 0._wp
  335. heat_to_bergs_net = 0._wp
  336. heat_to_ocean_net = 0._wp
  337. calving_rcv_net = 0._wp
  338. calving_ret_net = 0._wp
  339. calving_src_net = 0._wp
  340. calving_out_net = 0._wp
  341. calving_src_heat_net = 0._wp
  342. calving_src_heat_used_net = 0._wp
  343. calving_out_heat_net = 0._wp
  344. melt_net = 0._wp
  345. berg_melt_net = 0._wp
  346. bits_melt_net = 0._wp
  347. bits_src_net = 0._wp
  348. ENDIF
  349. !
  350. END SUBROUTINE icb_dia
  351. SUBROUTINE icb_dia_step
  352. !!----------------------------------------------------------------------
  353. !! things to reset at the beginning of each timestep
  354. !!----------------------------------------------------------------------
  355. !
  356. IF( .NOT.ln_bergdia ) RETURN
  357. berg_melt (:,:) = 0._wp
  358. berg_melt_hcflx(:,:) = 0._wp
  359. berg_melt_qlat(:,:) = 0._wp
  360. buoy_melt (:,:) = 0._wp
  361. eros_melt (:,:) = 0._wp
  362. conv_melt (:,:) = 0._wp
  363. bits_src (:,:) = 0._wp
  364. bits_melt (:,:) = 0._wp
  365. bits_mass (:,:) = 0._wp
  366. berg_mass (:,:) = 0._wp
  367. real_calving(:,:,:) = 0._wp
  368. !
  369. END SUBROUTINE icb_dia_step
  370. SUBROUTINE icb_dia_put
  371. !!----------------------------------------------------------------------
  372. !!----------------------------------------------------------------------
  373. !
  374. IF( .NOT.ln_bergdia ) RETURN !!gm useless iom will control whether it is output or not
  375. !
  376. CALL iom_put( "berg_melt" , berg_melt (:,:) ) ! Melt rate of icebergs [kg/m2/s]
  377. !! NB. The berg_melt_hcflx field is currently always zero - see comment in icbthm.F90
  378. CALL iom_put( "berg_melt_hcflx" , berg_melt_hcflx(:,:)) ! Heat flux to ocean due to heat content of melting icebergs [J/m2/s]
  379. CALL iom_put( "berg_melt_qlat" , berg_melt_qlat(:,:) ) ! Heat flux to ocean due to latent heat of melting icebergs [J/m2/s]
  380. CALL iom_put( "berg_buoy_melt" , buoy_melt (:,:) ) ! Buoyancy component of iceberg melt rate [kg/m2/s]
  381. CALL iom_put( "berg_eros_melt" , eros_melt (:,:) ) ! Erosion component of iceberg melt rate [kg/m2/s]
  382. CALL iom_put( "berg_conv_melt" , conv_melt (:,:) ) ! Convective component of iceberg melt rate [kg/m2/s]
  383. CALL iom_put( "berg_virtual_area", virtual_area(:,:) ) ! Virtual coverage by icebergs [m2]
  384. CALL iom_put( "bits_src" , bits_src (:,:) ) ! Mass source of bergy bits [kg/m2/s]
  385. CALL iom_put( "bits_melt" , bits_melt (:,:) ) ! Melt rate of bergy bits [kg/m2/s]
  386. CALL iom_put( "bits_mass" , bits_mass (:,:) ) ! Bergy bit density field [kg/m2]
  387. CALL iom_put( "berg_mass" , berg_mass (:,:) ) ! Iceberg density field [kg/m2]
  388. CALL iom_put( "berg_real_calving", real_calving(:,:,:) ) ! Calving into iceberg class [kg/s]
  389. !
  390. END SUBROUTINE icb_dia_put
  391. SUBROUTINE icb_dia_calve( ki, kj, kn, pcalved, pheated )
  392. !!----------------------------------------------------------------------
  393. !!----------------------------------------------------------------------
  394. INTEGER , INTENT(in) :: ki, kj, kn
  395. REAL(wp), INTENT(in) :: pcalved
  396. REAL(wp), INTENT(in) :: pheated
  397. !!----------------------------------------------------------------------
  398. !
  399. IF( .NOT. ln_bergdia ) RETURN
  400. real_calving(ki,kj,kn) = real_calving(ki,kj,kn) + pcalved / berg_dt
  401. nbergs_calved = nbergs_calved + 1
  402. nbergs_calved_by_class(kn) = nbergs_calved_by_class(kn) + 1
  403. calving_to_bergs_net = calving_to_bergs_net + pcalved
  404. heat_to_bergs_net = heat_to_bergs_net + pheated
  405. !
  406. END SUBROUTINE icb_dia_calve
  407. SUBROUTINE icb_dia_income( kt, pcalving_used, pheat_used )
  408. !!----------------------------------------------------------------------
  409. !!----------------------------------------------------------------------
  410. INTEGER , INTENT(in) :: kt
  411. REAL(wp), INTENT(in) :: pcalving_used
  412. REAL(wp), DIMENSION(:,:), INTENT(in) :: pheat_used
  413. !!----------------------------------------------------------------------
  414. !
  415. IF( .NOT.ln_bergdia ) RETURN
  416. !
  417. IF( kt == nit000 ) THEN
  418. stored_start = SUM( berg_grid%stored_ice(:,:,:) )
  419. CALL mpp_sum( 'icbdia', stored_start )
  420. !
  421. stored_heat_start = SUM( berg_grid%stored_heat(:,:) )
  422. CALL mpp_sum( 'icbdia', stored_heat_start )
  423. IF (nn_verbose_level > 0) THEN
  424. WRITE(numicb,'(a,es13.6,a)') 'icb_dia_income: initial stored mass=',stored_start,' kg'
  425. WRITE(numicb,'(a,es13.6,a)') 'icb_dia_income: initial stored heat=',stored_heat_start,' J'
  426. ENDIF
  427. ENDIF
  428. !
  429. calving_rcv_net = calving_rcv_net + SUM( berg_grid%calving(:,:) ) * berg_dt
  430. calving_src_net = calving_rcv_net
  431. calving_src_heat_net = calving_src_heat_net + &
  432. & SUM( berg_grid%calving_hflx(:,:) * e1e2t(:,:) ) * berg_dt ! Units of J
  433. calving_used_net = calving_used_net + pcalving_used * berg_dt
  434. calving_src_heat_used_net = calving_src_heat_used_net + SUM( pheat_used(:,:) )
  435. !
  436. END SUBROUTINE icb_dia_income
  437. SUBROUTINE icb_dia_size(ki, kj, pWn, pLn, pAbits, &
  438. & pmass_scale, pMnew, pnMbits, pz1_e1e2)
  439. !!----------------------------------------------------------------------
  440. !!----------------------------------------------------------------------
  441. INTEGER , INTENT(in) :: ki, kj
  442. REAL(wp), INTENT(in) :: pWn, pLn, pAbits, pmass_scale, pMnew, pnMbits, pz1_e1e2
  443. !!----------------------------------------------------------------------
  444. !
  445. IF( .NOT.ln_bergdia ) RETURN
  446. berg_mass(ki,kj) = berg_mass(ki,kj) + pMnew * pz1_e1e2 ! kg/m2
  447. bits_mass(ki,kj) = bits_mass(ki,kj) + pnMbits * pz1_e1e2 ! kg/m2
  448. !
  449. END SUBROUTINE icb_dia_size
  450. SUBROUTINE icb_dia_speed()
  451. !!----------------------------------------------------------------------
  452. !!----------------------------------------------------------------------
  453. !
  454. IF( .NOT.ln_bergdia ) RETURN
  455. nspeeding_tickets = nspeeding_tickets + 1
  456. !
  457. END SUBROUTINE icb_dia_speed
  458. SUBROUTINE icb_dia_melt(ki, kj, pmnew, pheat_hcflux, pheat_latent, pmass_scale, &
  459. & pdM, pdMbitsE, pdMbitsM, pdMb, pdMe, &
  460. & pdMv, pz1_dt_e1e2, pz1_e1e2 )
  461. !!----------------------------------------------------------------------
  462. !!----------------------------------------------------------------------
  463. INTEGER , INTENT(in) :: ki, kj
  464. REAL(wp), INTENT(in) :: pmnew, pheat_hcflux, pheat_latent, pmass_scale
  465. REAL(wp), INTENT(in) :: pdM, pdMbitsE, pdMbitsM, pdMb, pdMe, pdMv, pz1_dt_e1e2, pz1_e1e2
  466. !!----------------------------------------------------------------------
  467. !
  468. IF( .NOT.ln_bergdia ) RETURN
  469. !
  470. berg_melt (ki,kj) = berg_melt (ki,kj) + pdM * pz1_dt_e1e2 ! kg/m2/s
  471. berg_melt_hcflx (ki,kj) = berg_melt_hcflx (ki,kj) + pheat_hcflux * pz1_e1e2 ! W/m2
  472. berg_melt_qlat (ki,kj) = berg_melt_qlat (ki,kj) + pheat_latent * pz1_e1e2 ! W/m2
  473. bits_src (ki,kj) = bits_src (ki,kj) + pdMbitsE * pz1_dt_e1e2 ! mass flux into bergy bitskg/m2/s
  474. bits_melt (ki,kj) = bits_melt (ki,kj) + pdMbitsM * pz1_dt_e1e2 ! melt rate of bergy bits kg/m2/s
  475. buoy_melt (ki,kj) = buoy_melt (ki,kj) + pdMb * pz1_dt_e1e2 ! kg/m2/s
  476. eros_melt (ki,kj) = eros_melt (ki,kj) + pdMe * pz1_dt_e1e2 ! erosion rate kg/m2/s
  477. conv_melt (ki,kj) = conv_melt (ki,kj) + pdMv * pz1_dt_e1e2 ! kg/m2/s
  478. heat_to_ocean_net = heat_to_ocean_net + (pheat_hcflux + pheat_latent) * pmass_scale * berg_dt ! J
  479. IF( pmnew <= 0._wp ) nbergs_melted = nbergs_melted + 1 ! Delete the berg if completely melted
  480. !
  481. END SUBROUTINE icb_dia_melt
  482. SUBROUTINE report_state( cd_budgetstr, cd_budgetunits, cd_startstr, pstartval, cd_endstr, &
  483. & pendval, cd_delstr, kbergs )
  484. !!----------------------------------------------------------------------
  485. !!----------------------------------------------------------------------
  486. CHARACTER*(*), INTENT(in) :: cd_budgetstr, cd_budgetunits, cd_startstr, cd_endstr, cd_delstr
  487. REAL(wp), INTENT(in) :: pstartval, pendval
  488. INTEGER, INTENT(in), OPTIONAL :: kbergs
  489. !!----------------------------------------------------------------------
  490. !
  491. IF (nn_verbose_level == 0) RETURN
  492. IF( PRESENT(kbergs) ) THEN
  493. WRITE(numicb,100) cd_budgetstr // ' state:', &
  494. & cd_startstr // ' start', pstartval, cd_budgetunits, &
  495. & cd_endstr // ' end', pendval, cd_budgetunits, &
  496. & 'Delta ' // cd_delstr, pendval-pstartval, cd_budgetunits, &
  497. & '# of bergs', kbergs
  498. ELSE
  499. WRITE(numicb,100) cd_budgetstr // ' state:', &
  500. & cd_startstr // ' start', pstartval, cd_budgetunits, &
  501. & cd_endstr // ' end', pendval, cd_budgetunits, &
  502. & cd_delstr // 'Delta', pendval-pstartval, cd_budgetunits
  503. ENDIF
  504. 100 FORMAT(a19,3(a18,"=",es14.7,x,a2,:,","),a12,i8)
  505. !
  506. END SUBROUTINE report_state
  507. SUBROUTINE report_consistant( cd_budgetstr, cd_budgetunits, cd_startstr, pstartval, cd_endstr, pendval)
  508. !!----------------------------------------------------------------------
  509. !!----------------------------------------------------------------------
  510. CHARACTER*(*), INTENT(in) :: cd_budgetstr, cd_budgetunits, cd_startstr, cd_endstr
  511. REAL(wp), INTENT(in) :: pstartval, pendval
  512. !!----------------------------------------------------------------------
  513. !
  514. IF (nn_verbose_level == 0) RETURN
  515. WRITE(numicb,200) cd_budgetstr // ' check:', &
  516. & cd_startstr, pstartval, cd_budgetunits, &
  517. & cd_endstr, pendval, cd_budgetunits, &
  518. & 'error', (pendval-pstartval)/((pendval+pstartval)+1e-30), 'nd'
  519. 200 FORMAT(a19,10(a18,"=",es14.7,x,a2,:,","))
  520. !
  521. END SUBROUTINE report_consistant
  522. SUBROUTINE report_budget( cd_budgetstr, cd_budgetunits, cd_instr, pinval, cd_outstr, &
  523. & poutval, cd_delstr, pstartval, pendval)
  524. !!----------------------------------------------------------------------
  525. !!----------------------------------------------------------------------
  526. CHARACTER*(*), INTENT(in) :: cd_budgetstr, cd_budgetunits, cd_instr, cd_outstr, cd_delstr
  527. REAL(wp), INTENT(in) :: pinval, poutval, pstartval, pendval
  528. !
  529. REAL(wp) :: zval
  530. !!----------------------------------------------------------------------
  531. !
  532. IF (nn_verbose_level == 0) RETURN
  533. zval = ( ( pendval - pstartval ) - ( pinval - poutval ) ) / &
  534. & MAX( 1.e-30, MAX( ABS( pendval - pstartval ) , ABS( pinval - poutval ) ) )
  535. !
  536. WRITE(numicb,200) cd_budgetstr // ' budget:', &
  537. & cd_instr // ' in', pinval, cd_budgetunits, &
  538. & cd_outstr // ' out', poutval, cd_budgetunits, &
  539. & 'Delta ' // cd_delstr, pinval-poutval, cd_budgetunits, &
  540. & 'error', zval, 'nd'
  541. 200 FORMAT(a19,3(a18,"=",es14.7,x,a2,:,","),a8,"=",es10.3,x,a2)
  542. !
  543. END SUBROUTINE report_budget
  544. SUBROUTINE report_istate( cd_budgetstr, cd_startstr, pstartval, cd_endstr, pendval, cd_delstr)
  545. !!----------------------------------------------------------------------
  546. !!----------------------------------------------------------------------
  547. CHARACTER*(*), INTENT(in) :: cd_budgetstr, cd_startstr, cd_endstr, cd_delstr
  548. INTEGER , INTENT(in) :: pstartval, pendval
  549. !!----------------------------------------------------------------------
  550. !
  551. IF (nn_verbose_level == 0) RETURN
  552. WRITE(numicb,100) cd_budgetstr // ' state:', &
  553. & cd_startstr // ' start', pstartval, &
  554. & cd_endstr // ' end', pendval, &
  555. & cd_delstr // 'Delta', pendval-pstartval
  556. 100 FORMAT(a19,3(a18,"=",i14,x,:,","))
  557. !
  558. END SUBROUTINE report_istate
  559. SUBROUTINE report_ibudget( cd_budgetstr, cd_instr, pinval, cd_outstr, poutval, &
  560. & cd_delstr, pstartval, pendval)
  561. !!----------------------------------------------------------------------
  562. !!----------------------------------------------------------------------
  563. CHARACTER*(*), INTENT(in) :: cd_budgetstr, cd_instr, cd_outstr, cd_delstr
  564. INTEGER, INTENT(in) :: pinval, poutval, pstartval, pendval
  565. !!----------------------------------------------------------------------
  566. !
  567. IF (nn_verbose_level == 0) RETURN
  568. WRITE(numicb,200) cd_budgetstr // ' budget:', &
  569. & cd_instr // ' in', pinval, &
  570. & cd_outstr // ' out', poutval, &
  571. & 'Delta ' // cd_delstr, pinval-poutval, &
  572. & 'error', ( ( pendval - pstartval ) - ( pinval - poutval ) )
  573. 200 FORMAT(a19,10(a18,"=",i14,x,:,","))
  574. !
  575. END SUBROUTINE report_ibudget
  576. !!======================================================================
  577. END MODULE icbdia