emission_bc.F90 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710
  1. !
  2. #define TRACEBACK write (gol,'("in ",a," (",a,", line",i5,")")') rname, __FILE__, __LINE__; call goErr
  3. #define IF_NOTOK_RETURN(action) if (status/=0) then; TRACEBACK; action; return; end if
  4. #define IF_ERROR_RETURN(action) if (status> 0) then; TRACEBACK; action; return; end if
  5. !
  6. #include "tm5.inc"
  7. !
  8. !-----------------------------------------------------------------------------
  9. ! TM5 !
  10. !-----------------------------------------------------------------------------
  11. !BOP
  12. !
  13. ! !MODULE: EMISSION_BC
  14. !
  15. ! !DESCRIPTION: Data and methods fo Black Carbon (BC) emissions.
  16. !
  17. !>>> TvN
  18. ! The latest revision allows to apply
  19. ! different sizes for the emissions from
  20. ! different sectors, as well as for
  21. ! biofuel emissions.
  22. ! The assumption that all BC
  23. ! is emitted in the insoluble Aitken mode
  24. ! has been relaxed.
  25. ! See settings in emission_data.F90.
  26. !<<< TvN
  27. !
  28. !\\
  29. !\\
  30. ! !INTERFACE:
  31. !
  32. MODULE EMISSION_BC
  33. !
  34. ! !USES:
  35. !
  36. use GO, only : gol, goErr, goPr
  37. use tm5_distgrid, only : dgrid, get_distgrid, scatter, gather
  38. use dims, only : nregions, okdebug
  39. use global_data, only : emis_data, d3_data
  40. use emission_data, only : emis_input_year_bc
  41. use emission_read, only : used_providers_aer, has_aer_emis
  42. IMPLICIT NONE
  43. PRIVATE
  44. !
  45. ! !PUBLIC MEMBER FUNCTIONS:
  46. !
  47. public :: emission_bc_init, emission_BC_done, emission_bc_declare
  48. !
  49. ! !PRIVATE DATA MEMBERS:
  50. !
  51. character(len=*), parameter :: mname = 'emission_bc'
  52. type(emis_data), dimension(:,:), allocatable :: bc_emis_2d, bc_bf_emis_2d
  53. type(d3_data), dimension(:,:), allocatable :: bc_emis_3d
  54. integer :: bc_2dsec, bc_3dsec
  55. !
  56. ! !REVISION HISTORY:
  57. ! ? ??? 2005 - Elisabetta Vignati - changed for coupling with M7
  58. ! 1 Sep 2010 - Achim Strunk - revised for AR5 emissions
  59. ! 22 Jun 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  60. !
  61. ! !REMARKS:
  62. !
  63. !EOP
  64. !------------------------------------------------------------------------
  65. CONTAINS
  66. !--------------------------------------------------------------------------
  67. ! TM5 !
  68. !--------------------------------------------------------------------------
  69. !BOP
  70. !
  71. ! !IROUTINE: EMISSION_BC_INIT
  72. !
  73. ! !DESCRIPTION: Allocate space needed to handle the emissions.
  74. !\\
  75. !\\
  76. ! !INTERFACE:
  77. !
  78. SUBROUTINE EMISSION_BC_INIT( status )
  79. !
  80. ! !USES:
  81. !
  82. use dims, only : lm
  83. use emission_read, only : providers_def, numb_providers
  84. use emission_data, only : LAR5BMB
  85. use emission_read, only : n_ar5_ant_sec, n_ar5_shp_sec, n_ar5_air_sec, n_ar5_bmb_sec
  86. use emission_read, only : ar5_cat_ant, ar5_cat_shp, ar5_cat_air, ar5_cat_bmb
  87. !
  88. ! !OUTPUT PARAMETERS:
  89. !
  90. integer, intent(out) :: status
  91. !
  92. ! !REVISION HISTORY:
  93. ! 1 Oct 2010 - Achim Strunk -
  94. ! 25 Jun 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  95. !
  96. !EOP
  97. !------------------------------------------------------------------------
  98. !BOC
  99. character(len=*), parameter :: rname = mname//'/Emission_BC_Init'
  100. integer :: region, lsec
  101. integer :: lmr, lprov, i1, i2, j1, j2
  102. ! --- begin --------------------------------------
  103. status = 0
  104. if(.not. has_aer_emis) return
  105. ! nb of sectors
  106. bc_2dsec = 0
  107. bc_3dsec = 0
  108. do lprov = 1, numb_providers
  109. if (count(used_providers_aer.eq.providers_def(lprov)%name)/=0) then
  110. if (trim(providers_def(lprov)%name) .eq. 'AR5') then
  111. ! nb of available sectors in AR5 depends on category
  112. bc_2dsec = bc_2dsec + n_ar5_ant_sec*count('BC'.eq.ar5_cat_ant) + &
  113. n_ar5_shp_sec*count('BC'.eq.ar5_cat_shp)
  114. if (LAR5BMB) bc_2dsec = bc_2dsec + n_ar5_bmb_sec*count('BC'.eq.ar5_cat_bmb)
  115. bc_3dsec = bc_3dsec + count('BC'.eq.ar5_cat_air)
  116. else
  117. bc_2dsec = bc_2dsec + providers_def(lprov)%nsect2d
  118. bc_3dsec = bc_3dsec + providers_def(lprov)%nsect3d
  119. endif
  120. endif
  121. enddo
  122. allocate( bc_emis_2d( nregions, bc_2dsec ) )
  123. allocate( bc_bf_emis_2d( nregions, bc_2dsec ) )
  124. allocate( bc_emis_3d( nregions, bc_3dsec ) )
  125. ! allocate information arrays (2d and 3d)
  126. do region=1,nregions
  127. CALL GET_DISTGRID( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  128. lmr = lm(region)
  129. do lsec=1,bc_2dsec
  130. allocate( bc_emis_2d(region,lsec)%surf(i1:i2,j1:j2) )
  131. allocate( bc_bf_emis_2d(region,lsec)%surf(i1:i2,j1:j2) )
  132. end do
  133. do lsec=1,bc_3dsec
  134. allocate( bc_emis_3d(region,lsec)%d3(i1:i2,j1:j2,lmr) )
  135. end do
  136. enddo
  137. ! ok
  138. status = 0
  139. END SUBROUTINE EMISSION_BC_INIT
  140. !EOC
  141. !--------------------------------------------------------------------------
  142. ! TM5 !
  143. !--------------------------------------------------------------------------
  144. !BOP
  145. !
  146. ! !IROUTINE: EMISSION_BC_DONE
  147. !
  148. ! !DESCRIPTION: Free space after handling of BC emissions.
  149. !\\
  150. !\\
  151. ! !INTERFACE:
  152. !
  153. SUBROUTINE EMISSION_BC_DONE( status )
  154. !
  155. ! !OUTPUT PARAMETERS:
  156. !
  157. integer, intent(out) :: status
  158. !
  159. ! !REVISION HISTORY:
  160. ! 1 Oct 2010 - Achim Strunk -
  161. !
  162. !EOP
  163. !------------------------------------------------------------------------
  164. !BOC
  165. character(len=*), parameter :: rname = mname//'/Emission_BC_Done'
  166. integer :: region, lsec
  167. ! --- begin --------------------------------------
  168. status = 0
  169. if(.not. has_aer_emis) return
  170. do region = 1, nregions
  171. do lsec=1,bc_2dsec
  172. deallocate( bc_emis_2d(region,lsec)%surf )
  173. deallocate( bc_bf_emis_2d(region,lsec)%surf )
  174. end do
  175. do lsec=1,bc_3dsec
  176. deallocate( bc_emis_3d(region,lsec)%d3 )
  177. end do
  178. end do
  179. deallocate( bc_emis_2d )
  180. deallocate( bc_bf_emis_2d )
  181. deallocate( bc_emis_3d )
  182. ! ok
  183. status = 0
  184. END SUBROUTINE EMISSION_BC_DONE
  185. !EOC
  186. !--------------------------------------------------------------------------
  187. ! TM5 !
  188. !--------------------------------------------------------------------------
  189. !BOP
  190. !
  191. ! !IROUTINE: EMISSION_BC_DECLARE
  192. !
  193. ! !DESCRIPTION: Opens, reads and evaluates input files (per month).
  194. ! Provides emissions on 2d/3d-arrays which are then given
  195. ! to emis_number and emis_mass, which are used in
  196. ! sedimentation. (no *_apply!)
  197. !\\
  198. !\\
  199. ! !INTERFACE:
  200. !
  201. SUBROUTINE EMISSION_BC_DECLARE( status )
  202. !
  203. ! !USES:
  204. !
  205. use binas, only : pi
  206. use partools, only : isRoot, par_broadcast
  207. use toolbox, only : coarsen_emission
  208. use dims, only : im, jm, lm, idate, sec_month, nlon360, nlat180
  209. use chem_param, only : xmbc, sigma_lognormal, carbon_density
  210. use chem_param, only : mode_aii, mode_ais, mode_acs
  211. use emission_data, only : emis_mass, emis_number, msg_emis, LAR5BMB
  212. use emission_data, only : rad_emi_ff_sol, rad_emi_ff_insol
  213. use emission_data, only : rad_emi_ene_sol, rad_emi_ene_insol
  214. use emission_data, only : rad_emi_ind_sol, rad_emi_ind_insol
  215. use emission_data, only : rad_emi_tra_sol, rad_emi_tra_insol
  216. use emission_data, only : rad_emi_shp_sol, rad_emi_shp_insol
  217. use emission_data, only : rad_emi_air_sol, rad_emi_air_insol
  218. use emission_data, only : rad_emi_bf_sol, rad_emi_bf_insol
  219. use emission_data, only : rad_emi_bb_sol, rad_emi_bb_insol
  220. use emission_data, only : frac_bc_sol_ff, frac_bc_sol_bf, frac_bc_sol_bb
  221. use emission_data, only : emission_vdist_by_sector
  222. ! ---------------- AR5 - GFED - RETRO - MACC --------------------
  223. use emission_data, only : LAR5BMB
  224. use emission_data, only : emis_input_dir_mac
  225. use emission_data, only : emis_input_dir_retro
  226. use emission_data, only : emis_input_dir_gfed
  227. use emission_read, only : emission_ar5_regrid_aircraft
  228. use emission_read, only : emission_cmip6_ReadSector
  229. use emission_read, only : emission_cmip6bmb_ReadSector
  230. use emission_read, only : emission_ar5_ReadSector
  231. use emission_read, only : emission_macc_ReadSector
  232. use emission_read, only : emission_gfed_ReadSector
  233. use emission_read, only : emission_retro_ReadSector
  234. use emission_read, only : sectors_def, numb_sectors
  235. use emission_read, only : ar5_dim_3ddata
  236. !
  237. ! !OUTPUT PARAMETERS:
  238. !
  239. integer, intent(out) :: status
  240. !
  241. ! !REVISION HISTORY:
  242. ! 1 Oct 2010 - Achim Strunk - adapted for AR5
  243. ! 22 Jun 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  244. !
  245. !EOP
  246. !------------------------------------------------------------------------
  247. !BOC
  248. character(len=*), parameter :: rname = mname//'/emission_bc_declare'
  249. integer :: region, hasData
  250. integer, parameter :: add_field=0
  251. integer, parameter :: amonth=2
  252. real :: numbscale_exp
  253. integer :: imr, jmr, lmr, lsec, i1, i2, j1, j2, l
  254. ! ---------------------------------------------------------------
  255. real,dimension(:,:,:), allocatable :: field3d
  256. real,dimension(:,:), allocatable :: field2d_bf
  257. real :: mass2numb_fact
  258. real :: mass2numb_ff_sol, mass2numb_ff_insol
  259. real :: mass2numb_ene_sol, mass2numb_ene_insol
  260. real :: mass2numb_ind_sol, mass2numb_ind_insol
  261. real :: mass2numb_tra_sol, mass2numb_tra_insol
  262. real :: mass2numb_shp_sol, mass2numb_shp_insol
  263. real :: mass2numb_air_sol, mass2numb_air_insol
  264. real :: mass2numb_bf_sol, mass2numb_bf_insol
  265. real :: mass2numb_bb_sol, mass2numb_bb_insol
  266. real :: mass2numb_nonbf_sol, mass2numb_nonbf_insol
  267. type(d3_data), dimension(nregions) :: emis3d, work, work_bf, work3d
  268. type(d3_data), dimension(nregions) :: frac_bf
  269. type(emis_data), dimension(nregions) :: wrk2D, wrk2D_bf
  270. integer :: seccount2d, seccount3d
  271. ! --- begin -----------------------------------------
  272. status = 0
  273. if(.not. has_aer_emis) return
  274. write(gol,'(" EMISS-INFO ------------- read BC emissions -------------")'); call goPr
  275. ! Reset emissions
  276. do region = 1, nregions
  277. do lsec=1,bc_2dsec
  278. bc_emis_2d(region,lsec)%surf = 0.0
  279. bc_bf_emis_2d(region,lsec)%surf = 0.0
  280. end do
  281. do lsec=1,bc_3dsec
  282. bc_emis_3d(region,lsec)%d3 = 0.0
  283. end do
  284. end do
  285. ! Allocate work arrays
  286. do region = 1, nregions
  287. CALL GET_DISTGRID( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  288. lmr = lm(region)
  289. allocate( work3d(region)%d3 (i1:i2,j1:j2, ar5_dim_3ddata) ) ; work3d(region)%d3 = 0.0
  290. allocate( emis3d(region)%d3 (i1:i2,j1:j2, lmr ) ) ; emis3d(region)%d3 = 0.0
  291. allocate( frac_bf(region)%d3 (i1:i2,j1:j2, 1 ) )
  292. end do
  293. ! Global arrays for coarsening
  294. do region = 1, nregions
  295. if (isRoot)then
  296. allocate(work(region)%d3(im(region),jm(region),ar5_dim_3ddata))
  297. allocate(work_bf(region)%d3(im(region),jm(region),1))
  298. else
  299. allocate(work(region)%d3(1,1,1))
  300. allocate(work_bf(region)%d3(1,1,1))
  301. end if
  302. enddo
  303. do region = 1, nregions
  304. wrk2D(region)%surf => work(region)%d3(:,:,1)
  305. wrk2D_bf(region)%surf => work_bf(region)%d3(:,:,1)
  306. end do
  307. ! --------------------------------
  308. ! Loop over available sectors
  309. ! --------------------------------
  310. ! count 2d and 3d sectors
  311. seccount2d = 0
  312. seccount3d = 0
  313. ! always allocate here 3d data set (for 2d sectors it will be filled in first layer only)
  314. if (isRoot) then
  315. allocate( field3d( nlon360, nlat180, ar5_dim_3ddata ) ) ; field3d = 0.0
  316. allocate( field2d_bf( nlon360, nlat180 ) ) ; field2d_bf = 0.0
  317. else
  318. allocate( field3d( 1, 1, 1 ) )
  319. allocate( field2d_bf( 1, 1 ) )
  320. end if
  321. ! mass to number conversion factors for the relevant modes
  322. numbscale_exp = EXP(1.5*(LOG(sigma_lognormal(mode_aii)))**2)
  323. mass2numb_fact = 3./(4.*pi*(numbscale_exp**3)*carbon_density)
  324. mass2numb_ff_insol = mass2numb_fact/(rad_emi_ff_insol**3)
  325. mass2numb_ene_insol = mass2numb_fact/(rad_emi_ene_insol**3)
  326. mass2numb_ind_insol = mass2numb_fact/(rad_emi_ind_insol**3)
  327. mass2numb_tra_insol = mass2numb_fact/(rad_emi_tra_insol**3)
  328. mass2numb_shp_insol = mass2numb_fact/(rad_emi_shp_insol**3)
  329. mass2numb_air_insol = mass2numb_fact/(rad_emi_air_insol**3)
  330. mass2numb_bf_insol = mass2numb_fact/(rad_emi_bf_insol**3)
  331. mass2numb_bb_insol = mass2numb_fact/(rad_emi_bb_insol**3)
  332. numbscale_exp = EXP(1.5*(LOG(sigma_lognormal(mode_ais)))**2)
  333. mass2numb_fact = 3./(4.*pi*(numbscale_exp**3)*carbon_density)
  334. mass2numb_ff_sol = mass2numb_fact/(rad_emi_ff_sol**3)
  335. mass2numb_ene_sol = mass2numb_fact/(rad_emi_ene_sol**3)
  336. mass2numb_ind_sol = mass2numb_fact/(rad_emi_ind_sol**3)
  337. mass2numb_tra_sol = mass2numb_fact/(rad_emi_tra_sol**3)
  338. mass2numb_shp_sol = mass2numb_fact/(rad_emi_shp_sol**3)
  339. mass2numb_air_sol = mass2numb_fact/(rad_emi_air_sol**3)
  340. numbscale_exp = EXP(1.5*(LOG(sigma_lognormal(mode_acs)))**2)
  341. mass2numb_fact = 3./(4.*pi*(numbscale_exp**3)*carbon_density)
  342. mass2numb_bf_sol = mass2numb_fact/(rad_emi_bf_sol**3)
  343. mass2numb_bb_sol = mass2numb_fact/(rad_emi_bb_sol**3)
  344. sec : do lsec = 1, numb_sectors
  345. if (count(used_providers_aer.eq.sectors_def(lsec)%prov).eq.0) cycle ! skip unused providers
  346. if (associated(sectors_def(lsec)%species)) then ! AR5 check
  347. if (count('BC'.eq.sectors_def(lsec)%species).eq.0) cycle
  348. if ((trim(sectors_def(lsec)%catname) .eq. 'biomassburning').and.(.not.LAR5BMB)) cycle
  349. endif
  350. field3d = 0.0
  351. field2d_bf = 0.0
  352. if( sectors_def(lsec)%f3d ) then
  353. seccount3d = seccount3d + 1
  354. else
  355. seccount2d = seccount2d + 1
  356. end if
  357. if (isRoot) then ! READ
  358. select case( trim(sectors_def(lsec)%prov) )
  359. case( 'CMIP6' )
  360. call emission_cmip6_ReadSector( 'BC', emis_input_year_bc, idate(2), lsec, field3d, status, field2d_bf )
  361. IF_NOTOK_RETURN(status=1;deallocate(field3d,field2d_bf))
  362. case( 'CMIP6BMB' )
  363. call emission_cmip6bmb_ReadSector( 'BC', emis_input_year_bc, idate(2), lsec, field3d, status )
  364. IF_NOTOK_RETURN(status=1;deallocate(field3d))
  365. case( 'AR5' )
  366. ! Screen out agricultural and solvent sectors for BC,
  367. ! because they are zero in the RCPs
  368. ! and not present in the historical files.
  369. if (trim(sectors_def(lsec)%name) .ne. 'emiss_agr' .and. &
  370. trim(sectors_def(lsec)%name) .ne. 'emiss_slv') then
  371. call emission_ar5_ReadSector( 'BC', emis_input_year_bc, idate(2), lsec, field3d, status )
  372. IF_NOTOK_RETURN(status=1;deallocate(field3d))
  373. endif
  374. case( 'MACC' )
  375. ! Screen out 'soil', 'nat', 'oc', bio', and 'air' since they are not available for BC.
  376. if ( ( .not. (trim(sectors_def(lsec)%name) .eq. 'emiss_soil')) .and. &
  377. ( .not. (trim(sectors_def(lsec)%name) .eq. 'emiss_nat') ) .and. &
  378. ( .not. (trim(sectors_def(lsec)%name) .eq. 'emiss_oc') ) .and. &
  379. ( .not. (trim(sectors_def(lsec)%name) .eq. 'emiss_bio' ) ) .and. &
  380. ( .not. (trim(sectors_def(lsec)%name) .eq. 'emiss_air') ) ) then
  381. call emission_macc_ReadSector( emis_input_dir_mac, 'BC', emis_input_year_bc, idate(2), &
  382. '0.5x0.5_kg.nc', sectors_def(lsec)%name, 'kg / s', field3d, status )
  383. IF_NOTOK_RETURN(status=1;deallocate(field3d))
  384. end if
  385. case('GFEDv3')
  386. call emission_gfed_ReadSector( emis_input_dir_gfed, 'bc', emis_input_year_bc, idate(2), &
  387. 'GFED', 'kg / s', field3d(:,:,1), status )
  388. IF_NOTOK_RETURN(status=1)
  389. case('RETRO')
  390. call emission_retro_ReadSector( emis_input_dir_retro, 'BC', emis_input_year_bc, idate(2), &
  391. sectors_def(lsec)%name, 'kg / s', field3d(:,:,1), status )
  392. IF_NOTOK_RETURN(status=1)
  393. case default
  394. write(gol,*) "Error in list of providers for BC"; call goErr
  395. status=1; TRACEBACK; return
  396. end select
  397. ! nothing found???
  398. if( sum(field3d) < 100.*TINY(1.0) ) then
  399. if (okdebug ) then
  400. write(gol,'("EMISS-INFO - no BC emissions found for ",a," ",a," for month ",i2 )') &
  401. trim(sectors_def(lsec)%prov), trim(sectors_def(lsec)%name), idate(2) ; call goPr
  402. endif
  403. hasData=0
  404. else
  405. if (okdebug) then
  406. write(gol,'("EMISS-INFO - found BC emissions for ",a," ",a," for month ",i2 )') &
  407. trim(sectors_def(lsec)%prov), trim(sectors_def(lsec)%name), idate(2) ; call goPr
  408. endif
  409. ! scale from kg/s to kg/month
  410. field3d = field3d * sec_month ! kg / month
  411. field2d_bf = field2d_bf * sec_month
  412. hasData=1
  413. end if
  414. end if
  415. call Par_broadcast(hasData, status)
  416. IF_NOTOK_RETURN(status=1)
  417. if (hasData == 0) cycle sec
  418. ! distinguish 2d/3d sectors
  419. if( sectors_def(lsec)%f3d ) then
  420. ! ---------------------------
  421. ! 3d data (AIRCRAFT)
  422. ! ---------------------------
  423. if (isRoot) then
  424. ! write some numbers
  425. call msg_emis( amonth, trim(sectors_def(lsec)%prov), sectors_def(lsec)%name, 'BC', xmbc, sum(field3d) )
  426. ! distribute to work arrays in regions
  427. call Coarsen_Emission( 'BC '//trim(sectors_def(lsec)%name), nlon360, nlat180, ar5_dim_3ddata, &
  428. field3d, work, add_field, status )
  429. IF_NOTOK_RETURN(status=1)
  430. end if
  431. ! scatter, sum up on target array
  432. do region = 1, nregions
  433. call scatter(dgrid(region), work3d(region)%d3, work(region)%d3, 0, status)
  434. IF_NOTOK_RETURN( status=1 )
  435. CALL GET_DISTGRID( dgrid(region), I_STRT=i1, J_STRT=j1)
  436. ! aircraft data: regrid vertically to model layers
  437. call emission_ar5_regrid_aircraft( region, i1, j1, work3d(region)%d3, emis3d(region)%d3, status )
  438. IF_NOTOK_RETURN( status=1 )
  439. bc_emis_3d(region,seccount3d)%d3 = bc_emis_3d(region,seccount3d)%d3 + emis3d(region)%d3
  440. end do
  441. ! add to emis target arrays (scale mass to get number)
  442. do region = 1, nregions
  443. emis_mass (region,mode_aii)%d4(:,:,:,1) = &
  444. emis_mass (region,mode_aii)%d4(:,:,:,1) + &
  445. (1.-frac_bc_sol_ff) * bc_emis_3d(region,seccount3d)%d3(:,:,:)
  446. emis_mass (region,mode_ais)%d4(:,:,:,2) = &
  447. emis_mass (region,mode_ais)%d4(:,:,:,2) + &
  448. ( frac_bc_sol_ff) * bc_emis_3d(region,seccount3d)%d3(:,:,:)
  449. emis_number(region,mode_aii)%d4(:,:,:,1) = &
  450. emis_number(region,mode_aii)%d4(:,:,:,1) + &
  451. (1.-frac_bc_sol_ff) * bc_emis_3d(region,seccount3d)%d3(:,:,:) * mass2numb_air_insol
  452. emis_number(region,mode_ais)%d4(:,:,:,2) = &
  453. emis_number(region,mode_ais)%d4(:,:,:,2) + &
  454. ( frac_bc_sol_ff) * bc_emis_3d(region,seccount3d)%d3(:,:,:) * mass2numb_air_sol
  455. end do
  456. else ! sector is 2d
  457. ! ---------------------------
  458. ! 2d data (Anthropogenic, Ships, Biomassburning)
  459. ! ---------------------------
  460. if (isRoot) then ! print total & regrid
  461. call msg_emis( amonth, trim(sectors_def(lsec)%prov), sectors_def(lsec)%name, 'BC', xmbc, sum(field3d(:,:,1)) )
  462. call coarsen_emission( 'BC '//sectors_def(lsec)%name, nlon360, nlat180, field3d(:,:,1), &
  463. wrk2D, add_field, status )
  464. IF_NOTOK_RETURN(status=1)
  465. call coarsen_emission( 'BC solid biofuel '//sectors_def(lsec)%name, nlon360, nlat180, field2d_bf(:,:), &
  466. wrk2D_bf, add_field, status )
  467. IF_NOTOK_RETURN(status=1)
  468. end if
  469. ! get temporary array for vertical distribution
  470. do region = 1, nregions
  471. call scatter(dgrid(region), bc_emis_2d(region,seccount2d)%surf, work(region)%d3(:,:,1), 0, status)
  472. IF_NOTOK_RETURN(status=1)
  473. call scatter(dgrid(region), bc_bf_emis_2d(region,seccount2d)%surf, work_bf(region)%d3(:,:,1), 0, status)
  474. IF_NOTOK_RETURN(status=1)
  475. emis3d(region)%d3 = 0.0
  476. ! do vertical distribution
  477. call emission_vdist_by_sector( sectors_def(lsec)%vdisttype, 'BC', region, bc_emis_2d(region,seccount2d), &
  478. emis3d(region), status )
  479. IF_NOTOK_RETURN(status=1)
  480. if( trim(sectors_def(lsec)%catname) == 'biomassburning' ) then
  481. emis_mass (region,mode_aii)%d4(:,:,:,1) = &
  482. emis_mass (region,mode_aii)%d4(:,:,:,1) + emis3d(region)%d3(:,:,:) * &
  483. (1.-frac_bc_sol_bb)
  484. emis_number(region,mode_aii)%d4(:,:,:,1) = &
  485. emis_number(region,mode_aii)%d4(:,:,:,1) + emis3d(region)%d3(:,:,:) * &
  486. (1.-frac_bc_sol_bb) * mass2numb_bb_insol
  487. emis_mass (region,mode_acs)%d4(:,:,:,2) = &
  488. emis_mass (region,mode_acs)%d4(:,:,:,2) + emis3d(region)%d3(:,:,:) * &
  489. frac_bc_sol_bb
  490. emis_number(region,mode_acs)%d4(:,:,:,2) = &
  491. emis_number(region,mode_acs)%d4(:,:,:,2) + emis3d(region)%d3(:,:,:) * &
  492. frac_bc_sol_bb * mass2numb_bb_sol
  493. else
  494. ! currenly only for CMIP6 sector names
  495. select case( trim(sectors_def(lsec)%name) )
  496. case ('ENE')
  497. mass2numb_nonbf_sol = mass2numb_ene_sol
  498. mass2numb_nonbf_insol = mass2numb_ene_insol
  499. case ('IND')
  500. mass2numb_nonbf_sol = mass2numb_ind_sol
  501. mass2numb_nonbf_insol = mass2numb_ind_insol
  502. case ('TRA')
  503. mass2numb_nonbf_sol = mass2numb_tra_sol
  504. mass2numb_nonbf_insol = mass2numb_tra_insol
  505. case ('SHP')
  506. mass2numb_nonbf_sol = mass2numb_shp_sol
  507. mass2numb_nonbf_insol = mass2numb_shp_insol
  508. case default
  509. mass2numb_nonbf_sol = mass2numb_ff_sol
  510. mass2numb_nonbf_insol = mass2numb_ff_insol
  511. end select
  512. if ( trim(sectors_def(lsec)%prov) == 'CMIP6' ) then
  513. ! calculate mass fraction related to solid biofuel
  514. where ( bc_emis_2d(region,seccount2d)%surf(:,:) > tiny(0.0) )
  515. frac_bf(region)%d3(:,:,1) = bc_bf_emis_2d(region,seccount2d)%surf(:,:) / &
  516. bc_emis_2d(region,seccount2d)%surf(:,:)
  517. elsewhere
  518. frac_bf(region)%d3(:,:,1) = 0.0
  519. endwhere
  520. ! for safety, prevent fractions larger than unity.
  521. where (frac_bf(region)%d3(:,:,1) > 1.0 )
  522. frac_bf(region)%d3(:,:,1) = 1.0
  523. endwhere
  524. endif
  525. do l = 1, lmr
  526. emis_mass (region,mode_aii)%d4(:,:,l,1) = &
  527. emis_mass (region,mode_aii)%d4(:,:,l,1) + emis3d(region)%d3(:,:,l) * &
  528. ( (1.-frac_bf(region)%d3(:,:,1)) * (1.-frac_bc_sol_ff) + &
  529. frac_bf(region)%d3(:,:,1) * (1.-frac_bc_sol_bf) )
  530. emis_number(region,mode_aii)%d4(:,:,l,1) = &
  531. emis_number(region,mode_aii)%d4(:,:,l,1) + emis3d(region)%d3(:,:,l) * &
  532. ( (1.-frac_bf(region)%d3(:,:,1)) * (1.-frac_bc_sol_ff) * mass2numb_nonbf_insol + &
  533. frac_bf(region)%d3(:,:,1) * (1.-frac_bc_sol_bf) * mass2numb_bf_insol )
  534. emis_mass (region,mode_ais)%d4(:,:,l,2) = &
  535. emis_mass (region,mode_ais)%d4(:,:,l,2) + emis3d(region)%d3(:,:,l) * &
  536. ( (1.-frac_bf(region)%d3(:,:,1)) * frac_bc_sol_ff )
  537. emis_number(region,mode_ais)%d4(:,:,l,2) = &
  538. emis_number(region,mode_ais)%d4(:,:,l,2) + emis3d(region)%d3(:,:,l) * &
  539. ( (1.-frac_bf(region)%d3(:,:,1)) * frac_bc_sol_ff * mass2numb_nonbf_sol )
  540. emis_mass (region,mode_acs)%d4(:,:,l,2) = &
  541. emis_mass (region,mode_acs)%d4(:,:,l,2) + emis3d(region)%d3(:,:,l) * &
  542. ( frac_bf(region)%d3(:,:,1) * frac_bc_sol_bf )
  543. emis_number(region,mode_acs)%d4(:,:,l,2) = &
  544. emis_number(region,mode_acs)%d4(:,:,l,2) + emis3d(region)%d3(:,:,l) * &
  545. ( frac_bf(region)%d3(:,:,1) * frac_bc_sol_bf * mass2numb_bf_sol )
  546. enddo
  547. endif
  548. end do
  549. end if
  550. end do sec
  551. deallocate( field3d )
  552. deallocate( field2d_bf )
  553. do region = 1, nregions
  554. if (associated(wrk2D(region)%surf)) nullify(wrk2D(region)%surf)
  555. if (associated(wrk2D_bf(region)%surf)) nullify(wrk2D_bf(region)%surf)
  556. deallocate( work(region)%d3 )
  557. deallocate( work_bf(region)%d3 )
  558. deallocate( work3d(region)%d3 )
  559. deallocate( emis3d(region)%d3 )
  560. deallocate( frac_bf(region)%d3 )
  561. end do
  562. ! check sectors found
  563. if( seccount2d /= bc_2dsec ) then
  564. write(gol,'(80("-"))') ; call goPr
  565. write(gol,'("ERROR: 2d sectors do not equal total number:",i4," /= ",i4," !")') seccount2d, bc_2dsec ; call goErr
  566. write(gol,'(80("-"))') ; call goPr
  567. status=1; return
  568. end if
  569. if( seccount3d /= bc_3dsec ) then
  570. write(gol,'(80("-"))') ; call goPr
  571. write(gol,'("ERROR: 3d sectors do not equal total number:",i4," /= ",i4," !")') seccount3d, bc_3dsec ; call goErr
  572. write(gol,'(80("-"))') ; call goPr
  573. status=1; return
  574. end if
  575. ! ok
  576. status = 0
  577. END SUBROUTINE EMISSION_BC_DECLARE
  578. !EOC
  579. END MODULE EMISSION_BC