emission_nmvoc.F90 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978
  1. #define TRACEBACK write (gol,'("in ",a," (",a,", line",i5,")")') rname, __FILE__, __LINE__; call goErr
  2. #define IF_NOTOK_RETURN(action) if (status/=0) then; TRACEBACK; action; return; end if
  3. #define IF_ERROR_RETURN(action) if (status> 0) then; TRACEBACK; action; return; end if
  4. !
  5. #include "tm5.inc"
  6. !
  7. !-----------------------------------------------------------------------------
  8. ! TM5 !
  9. !-----------------------------------------------------------------------------
  10. !BOP
  11. !
  12. ! !MODULE: EMISSION_NMVOC
  13. !
  14. ! !DESCRIPTION: hold data and methods for NMVOC emissions.
  15. !
  16. ! Non-methane VOC's :
  17. ! nmhc(ncb5) = (/ipar,ieth,iole,iald2,imgly,ich2o/)
  18. !\\
  19. !\\
  20. ! !INTERFACE:
  21. !
  22. MODULE EMISSION_NMVOC
  23. !
  24. ! !USES:
  25. !
  26. use GO, only : gol, goPr, goErr
  27. use tm5_distgrid, only : dgrid, get_distgrid, scatter
  28. use partools, only : isRoot, par_broadcast
  29. use dims, only : nregions, okdebug
  30. use global_types, only : emis_data, d3_data
  31. use chem_param, only : ncb5
  32. use emission_read, only : used_providers, has_emis
  33. IMPLICIT NONE
  34. PRIVATE
  35. !
  36. ! !PUBLIC MEMBER FUNCTIONS:
  37. !
  38. public :: Emission_NMVOC_Init ! allocate memory
  39. public :: Emission_NMVOC_Done ! deallocate memory
  40. public :: Emission_NMVOC_Declare ! read input data
  41. public :: Emission_NMVOC_Apply ! add emissions to tracer array
  42. !
  43. ! !PRIVATE DATA MEMBERS:
  44. !
  45. character(len=*), parameter :: mname = 'emission_nmvoc'
  46. type( emis_data ),dimension(:,:,:),allocatable :: hc_emis_2d
  47. type( d3_data ),dimension(:,:,:),allocatable :: hc_emis_3d
  48. logical, allocatable :: has_data_3d(:,:), has_data_2d(:,:)
  49. integer :: hc_2dsec, hc_3dsec
  50. !
  51. ! !REVISION HISTORY:
  52. ! 1 Oct 2010 - Achim Strunk - overhaul for AR5
  53. ! 1 Dec 2011 - Narcisa Banda - added EDGAR 4
  54. ! 29 Jun 2012 - Ph. Le Sager - adapted for lon-lat MPI domain decomposition
  55. !
  56. ! !REMARKS:
  57. !
  58. !EOP
  59. !------------------------------------------------------------------------
  60. CONTAINS
  61. !--------------------------------------------------------------------------
  62. ! TM5 !
  63. !--------------------------------------------------------------------------
  64. !BOP
  65. !
  66. ! !IROUTINE: EMISSION_NMVOC_INIT
  67. !
  68. ! !DESCRIPTION: Allocate memory
  69. !\\
  70. !\\
  71. ! !INTERFACE:
  72. !
  73. SUBROUTINE EMISSION_NMVOC_INIT( status )
  74. !
  75. ! !USES:
  76. !
  77. use dims, only : lm
  78. use emission_read, only : providers_def, numb_providers
  79. use emission_read , only : ed42_nsect_hc
  80. !
  81. ! !OUTPUT PARAMETERS:
  82. !
  83. integer, intent(out) :: status
  84. !
  85. ! !REVISION HISTORY:
  86. ! 1 Oct 2010 - Achim Strunk - adapted for AR5
  87. ! 29 Jun 2012 - Ph. Le Sager - adapted for lon-lat MPI domain decomposition
  88. !
  89. !EOP
  90. !------------------------------------------------------------------------
  91. !BOC
  92. character(len=*), parameter :: rname = mname//'/Emission_NMVOC_Init'
  93. integer :: region, lsec, icb5
  94. integer :: lmr, lprov, i1, i2, j1, j2
  95. ! --- begin --------------------------------------
  96. status = 0
  97. if(.not. has_emis) return
  98. ! nb of sectors
  99. hc_2dsec = 0
  100. hc_3dsec = 0
  101. do lprov = 1, numb_providers
  102. if (count(used_providers.eq.providers_def(lprov)%name)/=0) then
  103. if (trim(providers_def(lprov)%name) .eq. 'ED42') then
  104. hc_2dsec = hc_2dsec + ed42_nsect_hc
  105. ! no 3d sectors in EDGAR 4.2
  106. else
  107. hc_2dsec = hc_2dsec + providers_def(lprov)%nsect2d
  108. hc_3dsec = hc_3dsec + providers_def(lprov)%nsect3d
  109. endif
  110. endif
  111. enddo
  112. allocate( hc_emis_2d( nregions, hc_2dsec, ncb5 ) )
  113. allocate( hc_emis_3d( nregions, hc_3dsec, ncb5 ) )
  114. allocate( has_data_2d(hc_2dsec, ncb5 ) ) ; has_data_2d=.false.
  115. allocate( has_data_3d(hc_3dsec, ncb5 ) ) ; has_data_3d=.false.
  116. ! allocate information arrays (2d and 3d)
  117. do region=1,nregions
  118. CALL GET_DISTGRID( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  119. lmr = lm(region)
  120. do icb5 = 1, ncb5
  121. do lsec=1,hc_2dsec
  122. allocate( hc_emis_2d(region,lsec,icb5)%surf(i1:i2, j1:j2) )
  123. end do
  124. do lsec=1,hc_3dsec
  125. allocate( hc_emis_3d(region,lsec,icb5)%d3(i1:i2, j1:j2, lmr) )
  126. end do
  127. end do
  128. enddo
  129. status = 0
  130. END SUBROUTINE EMISSION_NMVOC_INIT
  131. !EOC
  132. !--------------------------------------------------------------------------
  133. ! TM5 !
  134. !--------------------------------------------------------------------------
  135. !BOP
  136. !
  137. ! !IROUTINE: EMISSION_NMVOC_DONE
  138. !
  139. ! !DESCRIPTION: Free memory
  140. !\\
  141. !\\
  142. ! !INTERFACE:
  143. !
  144. SUBROUTINE EMISSION_NMVOC_DONE( status )
  145. !
  146. ! !OUTPUT PARAMETERS:
  147. !
  148. integer, intent(out) :: status
  149. !
  150. ! !REVISION HISTORY:
  151. ! 1 Oct 2010 - Achim Strunk - adapted to new structures
  152. ! 29 Jun 2012 - Ph. Le Sager - adapted for lon-lat MPI domain decomposition
  153. !
  154. !EOP
  155. !------------------------------------------------------------------------
  156. !BOC
  157. character(len=*), parameter :: rname = mname//'/Emission_NMVOC_Done'
  158. integer :: region, lsec, icb5
  159. ! --- begin --------------------------------------
  160. status = 0
  161. if(.not. has_emis) return
  162. do region = 1, nregions
  163. do icb5 = 1, ncb5
  164. do lsec=1,hc_2dsec
  165. deallocate( hc_emis_2d(region,lsec,icb5)%surf )
  166. end do
  167. do lsec=1,hc_3dsec
  168. deallocate( hc_emis_3d(region,lsec,icb5)%d3 )
  169. end do
  170. end do
  171. end do
  172. deallocate( hc_emis_2d )
  173. deallocate( hc_emis_3d )
  174. deallocate( has_data_2d, has_data_3d)
  175. status = 0
  176. END SUBROUTINE EMISSION_NMVOC_DONE
  177. !EOC
  178. !--------------------------------------------------------------------------
  179. ! TM5 !
  180. !--------------------------------------------------------------------------
  181. !BOP
  182. !
  183. ! !IROUTINE: EMISSION_NMVOC_DECLARE
  184. !
  185. ! !DESCRIPTION: Opens, reads and evaluates input files (per month).
  186. ! Provides emissions on 2d/3d-arrays which are then added
  187. ! to tracers in routine *apply.
  188. ! Fields are communicated to all procs.
  189. !\\
  190. !\\
  191. ! !INTERFACE:
  192. !
  193. SUBROUTINE EMISSION_NMVOC_DECLARE( status )
  194. !
  195. ! !USES:
  196. !
  197. use toolbox, only : coarsen_emission
  198. use dims, only : im, jm, lm, idate, sec_month, nlon360, nlat180, iglbsfc
  199. use chem_param, only : xmc, ncb5, nmhc, names
  200. use emission_data, only : msg_emis, LAR5BMB, LMEGAN
  201. ! ---------------- AR5 - EDGAR 4 - ETC. --------------------
  202. use emission_data, only : emis_input_year_nmvoc, emis_input_year_nat
  203. use emission_data, only : emis_input_dir_mac
  204. use emission_data, only : emis_input_dir_megan
  205. use emission_data, only : emis_input_dir_retro
  206. use emission_data, only : emis_input_dir_gfed
  207. use emission_data, only : emis_input_dir_ed4
  208. use emission_read, only : emission_ar5_regrid_aircraft
  209. use emission_read, only : emission_cmip6_ReadSector
  210. use emission_read, only : emission_cmip6bmb_ReadSector
  211. use emission_read, only : emission_ar5_ReadSector
  212. use emission_read, only : emission_macc_ReadSector
  213. use emission_read, only : emission_ed4_ReadSector
  214. use emission_read, only : emission_gfed_ReadSector
  215. use emission_read, only : emission_megan_ReadSector
  216. use emission_read, only : emission_retro_ReadSector
  217. use emission_read, only : sectors_def, numb_sectors
  218. use emission_read, only : ar5_dim_3ddata
  219. use emission_read, only : emis_cmip6_voc_name
  220. use emission_read, only : emis_cmip6_aircraft_tot2voc
  221. use emission_read, only : emis_cmip6_aircraft_tl_tot2voc
  222. use emission_read, only : emis_cmip6bmb_nvoc, emis_cmip6bmb_voc_name
  223. use emission_read, only : emis_cmip6bmb_voc2cbm5
  224. use emission_read, only : emis_ar5_nvoc, emis_ar5_voc_name
  225. use emission_read, only : emis_ar5_voc2cbm5_default
  226. use emission_read, only : emis_ar5_voc2cbm5_biomassb
  227. use emission_read, only : emis_ar5_voc2cbm5_biogenic
  228. use emission_read, only : emis_macc_nvoc, emis_macc_voc_name
  229. use emission_read, only : emis_megan_voc2cbm5_biogenic
  230. use emission_read, only : emis_macc_voc2cbm5_default
  231. use emission_read, only : emis_macc_voc2cbm5_biomassb
  232. use emission_read, only : emis_macc_voc2cbm5_biogenic
  233. use emission_read, only : emis_megan_voc2cbm5_biogenic
  234. use emission_read, only : emis_megan_nvoc, emis_megan_voc_name
  235. use emission_read, only : emis_gfed_nvoc, emis_gfed_voc_name, emis_voc2cbm5_gfed
  236. use emission_read, only : emis_retro_voc_name
  237. use emission_read, only : ed42_hc_sectors
  238. !
  239. ! !OUTPUT PARAMETERS:
  240. !
  241. integer, intent(out) :: status
  242. !
  243. ! !REVISION HISTORY:
  244. ! 1 Oct 2010 - Achim Strunk - revamped for AR5
  245. ! 1 Dec 2011 - Narcisa Banda - added EDGAR 4
  246. ! 29 Jun 2012 - Ph. Le Sager - adapted for lon-lat MPI domain decomposition
  247. !
  248. !EOP
  249. !------------------------------------------------------------------------
  250. !BOC
  251. character(len=*), parameter :: rname = mname//'/emission_nmvoc_declare'
  252. ! --- local ---------------------------------------
  253. integer :: region
  254. logical :: hasData(ncb5)
  255. integer, parameter :: add_field = 0
  256. integer, parameter :: amonth = 2
  257. integer :: imr, jmr, lmr, i1, i2, j1, j2
  258. integer :: lsec, ivoc, icb5, ilev
  259. ! AR5
  260. real,dimension(:,:,:), allocatable :: field3d
  261. real,dimension(:,:,:,:),allocatable :: field4d
  262. type(d3_data), dimension(nregions) :: emis3d, work, work3d
  263. type(emis_data) :: wrk2D(nregions)
  264. integer :: seccount2d, seccount3d
  265. real,dimension(:,:), allocatable :: voc2cbm5
  266. ! --- begin ----------------------------------------
  267. status = 0
  268. if(.not. has_emis) return
  269. write(gol,'(" EMISS-INFO ------------- read NMVOC emissions -------------")'); call goPr
  270. ! reset arrays
  271. do region = 1, nregions
  272. do icb5 = 1, ncb5
  273. do lsec=1,hc_2dsec
  274. hc_emis_2d(region,lsec,icb5)%surf = 0.0
  275. end do
  276. do lsec=1,hc_3dsec
  277. hc_emis_3d(region,lsec,icb5)%d3 = 0.0
  278. end do
  279. end do
  280. CALL GET_DISTGRID( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  281. lmr = lm(region)
  282. allocate( work3d(region)%d3 (i1:i2,j1:j2, ar5_dim_3ddata) ) ; work3d(region)%d3 = 0.0
  283. allocate( emis3d(region)%d3 (i1:i2,j1:j2, lmr ) ) ; emis3d(region)%d3 = 0.0
  284. end do
  285. ! global arrays for coarsening
  286. do region = 1, nregions
  287. if (isRoot)then
  288. allocate(work(region)%d3(im(region),jm(region),ar5_dim_3ddata))
  289. else
  290. allocate(work(region)%d3(1,1,1))
  291. end if
  292. enddo
  293. do region = 1, nregions
  294. wrk2D(region)%surf => work(region)%d3(:,:,1)
  295. end do
  296. ! count 2d and 3d sectors
  297. seccount2d = 0
  298. seccount3d = 0
  299. ! always allocate here 3D/4D data set (for 2d sectors it will be filled in first layer only)
  300. if (isRoot) then
  301. allocate( field3d( nlon360, nlat180, ar5_dim_3ddata ) ) ; field3d = 0.0
  302. allocate( field4d( nlon360, nlat180, ar5_dim_3ddata, ncb5 ) ) ; field4d = 0.0
  303. else
  304. allocate( field3d( 1, 1, 1 ) )
  305. allocate( field4d( 1, 1, 1, 1 ) )
  306. end if
  307. ! --------------------------------
  308. ! do a loop over available sectors
  309. ! --------------------------------
  310. sec : do lsec = 1, numb_sectors
  311. if (count(used_providers.eq.sectors_def(lsec)%prov).eq.0) cycle
  312. if ((trim(sectors_def(lsec)%prov).eq.'ED42') .and. (count(ed42_hc_sectors.eq.sectors_def(lsec)%name) .eq. 0)) cycle
  313. if( sectors_def(lsec)%f3d ) then
  314. seccount3d = seccount3d + 1
  315. else
  316. seccount2d = seccount2d + 1
  317. end if
  318. field3d = 0.0
  319. field4d = 0.0
  320. if (isRoot) then ! READ
  321. select case( trim(sectors_def(lsec)%prov) )
  322. case( 'CMIP6' )
  323. ! get appropriate array of splitting values from input to cbm5
  324. allocate( voc2cbm5(emis_ar5_nvoc,ncb5) )
  325. voc2cbm5 = reshape( emis_ar5_voc2cbm5_default, (/emis_ar5_nvoc,ncb5/) )
  326. if (trim(sectors_def(lsec)%catname).ne.'aircraft') then
  327. ! --------------------------------
  328. ! do a loop over available constituents (25)
  329. ! --------------------------------
  330. do ivoc = 1, emis_ar5_nvoc
  331. ! skip anthropogenic emissions for isoprene and terpenes,
  332. ! which are not provided:
  333. if (trim(emis_cmip6_voc_name(ivoc)).eq.'VOC10-isoprene') cycle
  334. if (trim(emis_cmip6_voc_name(ivoc)).eq.'VOC11-terpenes') cycle
  335. call emission_cmip6_ReadSector( trim(emis_cmip6_voc_name(ivoc)), &
  336. emis_input_year_nmvoc, idate(2), lsec, field3d, status )
  337. IF_NOTOK_RETURN(status=1)
  338. do icb5 = 1, ncb5
  339. field4d(:,:,:,icb5) = field4d(:,:,:,icb5) + field3d(:,:,:) * voc2cbm5(ivoc,icb5)
  340. end do
  341. end do
  342. else
  343. ! For the aviation sector only the total NMVOC emissions are provided
  344. call emission_cmip6_ReadSector('NMVOC', emis_input_year_nmvoc, idate(2), lsec, field3d, status )
  345. ! Apply takeoff and landing VOC profile
  346. ! to the lowest two layers (0.305 km and 0.915 km)
  347. ! in the aircraft emissions file:
  348. do ivoc = 1, emis_ar5_nvoc
  349. do icb5 = 1, ncb5
  350. do ilev = 1, 2
  351. field4d(:,:,ilev,icb5) = field4d(:,:,ilev,icb5) + field3d(:,:,ilev) * &
  352. emis_cmip6_aircraft_tl_tot2voc(ivoc) * voc2cbm5(ivoc,icb5)
  353. end do
  354. do ilev = 3, ar5_dim_3ddata
  355. field4d(:,:,ilev,icb5) = field4d(:,:,ilev,icb5) + field3d(:,:,ilev) * &
  356. emis_cmip6_aircraft_tot2voc(ivoc) * voc2cbm5(ivoc,icb5)
  357. end do
  358. end do
  359. end do
  360. endif
  361. deallocate( voc2cbm5 )
  362. case( 'CMIP6BMB' )
  363. ! get appropriate array of splitting values from input to cbm5
  364. allocate( voc2cbm5(emis_cmip6bmb_nvoc,ncb5) )
  365. voc2cbm5 = reshape( emis_cmip6bmb_voc2cbm5, (/emis_cmip6bmb_nvoc,ncb5/) )
  366. ! --------------------------------
  367. ! do a loop over available constituents
  368. ! --------------------------------
  369. do ivoc = 1, emis_cmip6bmb_nvoc
  370. ! skip species for which biomass burning emissions are not provided
  371. if (trim(emis_cmip6bmb_voc_name(ivoc)).eq.'not provided') cycle
  372. ! skip isoprene or terpenes,
  373. ! as their contributions will be zero anyhow
  374. if (trim(emis_cmip6bmb_voc_name(ivoc)).eq.'C5H8') cycle
  375. if (trim(emis_cmip6bmb_voc_name(ivoc)).eq.'C10H16') cycle
  376. call emission_cmip6bmb_ReadSector( 'NMVOC-'//trim(emis_cmip6bmb_voc_name(ivoc)), &
  377. emis_input_year_nmvoc, idate(2), lsec, field3d, status )
  378. IF_NOTOK_RETURN(status=1)
  379. do icb5 = 1, ncb5
  380. field4d(:,:,:,icb5) = field4d(:,:,:,icb5) + field3d(:,:,:) * voc2cbm5(ivoc,icb5)
  381. end do
  382. end do
  383. deallocate( voc2cbm5 )
  384. case( 'AR5' )
  385. ! screen out AR5 biomass burning if not wanted
  386. if ( .not. ((trim(sectors_def(lsec)%catname) .eq. 'biomassburning').and.(.not.LAR5BMB)) ) then
  387. ! get appropriate array of splitting values from input to cbm5
  388. allocate( voc2cbm5(emis_ar5_nvoc,ncb5) )
  389. ! Changing the tables here in order to get ALD and PAR etc from Biomassburning
  390. voc2cbm5 = reshape( emis_ar5_voc2cbm5_default, (/emis_ar5_nvoc,ncb5/) )
  391. ! --------------------------------
  392. ! do a loop over available constituents (25)
  393. ! --------------------------------
  394. vocAR5: do ivoc = 1, emis_ar5_nvoc
  395. ! skip missing categories
  396. if (count(trim(emis_ar5_voc_name(ivoc)).eq.sectors_def(lsec)%species).eq.0) cycle
  397. call emission_ar5_ReadSector( trim(emis_ar5_voc_name(ivoc)), emis_input_year_nmvoc, idate(2), lsec, field3d, status )
  398. IF_NOTOK_RETURN(status=1)
  399. do icb5 = 1, ncb5
  400. field4d(:,:,:,icb5) = field4d(:,:,:,icb5) + field3d(:,:,:) * voc2cbm5(ivoc,icb5)
  401. end do
  402. end do vocAR5
  403. deallocate( voc2cbm5 )
  404. end if
  405. case( 'MACC' )
  406. ! screen out biomass burning (a/k/a emiss_bb), and 'soil', 'nat' and 'air' sectors (no NMVOC)
  407. ! skip 'bio' source if already provided by MEGAN
  408. if ( ( .not. (trim(sectors_def(lsec)%catname) .eq. 'biomassburning') ) .and. &
  409. ( .not. (trim(sectors_def(lsec)%name) .eq. 'emiss_soil') ) .and. &
  410. ( .not. (trim(sectors_def(lsec)%name) .eq. 'emiss_nat') ) .and. &
  411. ( .not. (trim(sectors_def(lsec)%name) .eq. 'emiss_air') ) .and. &
  412. ( .not. (LMEGAN .and. (trim(sectors_def(lsec)%name) .eq. 'emiss_bio'))) ) then
  413. ! get appropriate array of splitting values from input to cbm5
  414. allocate( voc2cbm5(emis_macc_nvoc,ncb5) )
  415. select case( trim(sectors_def(lsec)%catname) )
  416. case( 'anthropogenic', 'ships', 'aircraft' )
  417. voc2cbm5 = reshape( emis_macc_voc2cbm5_default, (/emis_macc_nvoc,ncb5/) )
  418. case( 'natural' )
  419. voc2cbm5 = reshape( emis_macc_voc2cbm5_biogenic, (/emis_macc_nvoc,ncb5/) )
  420. case default
  421. write(gol,'(80("-"))') ; call goPr
  422. write(gol,'("ERROR: wrong category name `",a,"`!")') sectors_def(lsec)%catname ; call goErr
  423. write(gol,'(80("-"))') ; call goPr
  424. end select
  425. ! --------------------------------
  426. ! do a loop over available constituents (14)
  427. ! --------------------------------
  428. do ivoc = 1, emis_macc_nvoc
  429. if (trim(sectors_def(lsec)%catname) .eq. 'natural') then
  430. call emission_macc_ReadSector( emis_input_dir_mac, trim(emis_macc_voc_name(ivoc)), emis_input_year_nat, idate(2), &
  431. '0.5x0.5_kg.nc', sectors_def(lsec)%name, 'kg / s', field3d, status )
  432. IF_NOTOK_RETURN(status=1;deallocate(field3d,field4d))
  433. else
  434. call emission_macc_ReadSector( emis_input_dir_mac, trim(emis_macc_voc_name(ivoc)), emis_input_year_nmvoc, idate(2), &
  435. '0.5x0.5_kg.nc', sectors_def(lsec)%name, 'kg / s', field3d, status )
  436. IF_NOTOK_RETURN(status=1;deallocate(field3d,field4d))
  437. endif
  438. do icb5 = 1, ncb5
  439. field4d(:,:,:,icb5) = field4d(:,:,:,icb5) + field3d(:,:,:) * voc2cbm5(ivoc,icb5)
  440. end do
  441. end do
  442. deallocate( voc2cbm5 )
  443. endif
  444. case( 'ED41' )
  445. select case(trim(sectors_def(lsec)%name))
  446. case ('1A3b_c_e','1A3d_SHIP','1A3d1')
  447. ! AR5 NMVOC emissions and were used to split EDGAR NMVOC totals into separate (AR5) NMVOC species
  448. ! get appropriate array of splitting values from input to cbm5
  449. allocate( voc2cbm5(emis_ar5_nvoc,ncb5) )
  450. ! Changing the tables here in order to get ALD and PAR etc from Biomassburning
  451. voc2cbm5 = reshape( emis_ar5_voc2cbm5_default, (/emis_ar5_nvoc,ncb5/) )
  452. ! --------------------------------
  453. ! do a loop over available constituents (25)
  454. ! --------------------------------
  455. vocED41: do ivoc = 1, emis_ar5_nvoc
  456. ! screen out missing dataset
  457. if ((ivoc==10).or.(ivoc==11)) cycle vocED41
  458. if ( trim(sectors_def(lsec)%name) /= '1A3b_c_e') then
  459. if ((ivoc==1).or.(ivoc>=18)) cycle vocED41
  460. endif
  461. if (((ivoc==1).or.(ivoc==24)).and.(emis_input_year_nmvoc<2005)) cycle vocED41 ! kludge (waiting for NB input)
  462. call emission_ed4_ReadSector( emis_input_dir_ed4, trim(emis_ar5_voc_name(ivoc)), trim(emis_ar5_voc_name(ivoc)),&
  463. emis_input_year_nmvoc, idate(2), lsec, trim(sectors_def(lsec)%prov), 'kg / s', field3d,&
  464. status )
  465. IF_NOTOK_RETURN(status=1;deallocate(field3d,field4d,voc2cbm5))
  466. do icb5 = 1, ncb5
  467. field4d(:,:,:,icb5) = field4d(:,:,:,icb5) + field3d(:,:,:) * voc2cbm5(ivoc,icb5)
  468. end do
  469. end do vocED41
  470. deallocate( voc2cbm5 )
  471. end select
  472. case( 'ED42' )
  473. ! Biomass burning (GFED/RETRO/AR5BMB) and transport (ED41) are excluded through ED42_HC_SECTORS definition
  474. ! Same constituents as AR5 NMVOC are used
  475. ! get appropriate array of splitting values from input to cbm5
  476. allocate( voc2cbm5(emis_ar5_nvoc,ncb5) )
  477. voc2cbm5 = reshape( emis_ar5_voc2cbm5_default, (/emis_ar5_nvoc,ncb5/) )
  478. ! --------------------------------
  479. ! do a loop over available constituents (25)
  480. ! --------------------------------
  481. vocED42: do ivoc = 1, emis_ar5_nvoc
  482. ! screen out missing dataset
  483. if ((ivoc==10).or.(ivoc==11)) cycle vocED42
  484. if ( trim(sectors_def(lsec)%name) == '3') then
  485. if (count(ivoc.eq.(/2,3,4,5,7,8,9,12,13,16,21,22,24/)).eq.1) cycle vocED42
  486. endif
  487. if ( trim(sectors_def(lsec)%name) == '1A4') then
  488. if (count(ivoc.eq.(/1,24/)).eq.1) cycle vocED42
  489. endif
  490. if ( trim(sectors_def(lsec)%name) == '4F') then
  491. if (count(ivoc.eq.(/16,17,18,19,20,25/)).eq.1) cycle vocED42
  492. endif
  493. if ( ( trim(sectors_def(lsec)%name) == '1A1a') .or. &
  494. ( trim(sectors_def(lsec)%name) == '1A1b_c_1B_2C1_2C2') .or. &
  495. ( trim(sectors_def(lsec)%name) == '1A2') .or. &
  496. ( trim(sectors_def(lsec)%name) == '2A_B_D_E_F_G') .or. &
  497. ( trim(sectors_def(lsec)%name) == '7A') ) then
  498. if (count(ivoc.eq.(/18,19,20/)).eq.1) cycle vocED42
  499. endif
  500. call emission_ed4_ReadSector( emis_input_dir_ed4, trim(emis_ar5_voc_name(ivoc)), &
  501. trim(emis_ar5_voc_name(ivoc)), emis_input_year_nmvoc, idate(2), lsec, &
  502. trim(sectors_def(lsec)%prov), 'kg / s', field3d, status )
  503. IF_NOTOK_RETURN(status=1)
  504. do icb5 = 1, ncb5
  505. field4d(:,:,:,icb5) = field4d(:,:,:,icb5) + field3d(:,:,:) * voc2cbm5(ivoc,icb5)
  506. end do
  507. end do vocED42
  508. deallocate( voc2cbm5 )
  509. case( 'GFEDv3' )
  510. ! We use the MACC voc split, since GFED3 contains the same species,
  511. ! except for the last 3 species - Acetone, Acetaldehyde and MEK - which are not provided in GFED3
  512. ! get appropriate array of splitting values from input to cbm5
  513. allocate( voc2cbm5(emis_gfed_nvoc,ncb5) )
  514. voc2cbm5 = reshape( emis_voc2cbm5_gfed, (/emis_gfed_nvoc,ncb5/) )
  515. ! --------------------------------
  516. ! do a loop over available constituents (11)
  517. ! --------------------------------
  518. do ivoc = 1, emis_gfed_nvoc
  519. call emission_gfed_ReadSector( emis_input_dir_gfed, trim(emis_gfed_voc_name(ivoc)), emis_input_year_nmvoc, idate(2), &
  520. sectors_def(lsec)%name, 'kg / s', field3d(:,:,1), status )
  521. IF_NOTOK_RETURN(status=1;deallocate(field3d,field4d))
  522. do icb5 = 1, ncb5
  523. field4d(:,:,:,icb5) = field4d(:,:,:,icb5) + field3d(:,:,:) * voc2cbm5(ivoc,icb5)
  524. end do
  525. end do
  526. deallocate( voc2cbm5 )
  527. case( 'RETRO' )
  528. allocate( voc2cbm5(emis_ar5_nvoc,ncb5) )
  529. voc2cbm5 = reshape( emis_ar5_voc2cbm5_biomassb, (/emis_ar5_nvoc,ncb5/) )
  530. ! --------------------------------
  531. ! do a loop over available constituents (25)
  532. ! --------------------------------
  533. do ivoc = 1, emis_ar5_nvoc
  534. if (trim(emis_retro_voc_name(ivoc)).eq.'not provided') cycle
  535. call emission_retro_ReadSector( emis_input_dir_retro, trim(emis_retro_voc_name(ivoc)), emis_input_year_nmvoc, idate(2), &
  536. sectors_def(lsec)%name, 'kg / s', field3d(:,:,1), status )
  537. IF_NOTOK_RETURN(status=1;deallocate(field3d))
  538. do icb5 = 1, ncb5
  539. field4d(:,:,:,icb5) = field4d(:,:,:,icb5) + field3d(:,:,:) * voc2cbm5(ivoc,icb5)
  540. end do
  541. end do
  542. deallocate( voc2cbm5 )
  543. case( 'MEGAN' )
  544. allocate( voc2cbm5(emis_megan_nvoc,ncb5) )
  545. voc2cbm5 = reshape( emis_megan_voc2cbm5_biogenic, (/emis_megan_nvoc,ncb5/) )
  546. ! --------------------------------
  547. ! do a loop over available constituents (25)
  548. ! --------------------------------
  549. do ivoc = 1, emis_megan_nvoc
  550. if (trim(emis_megan_voc_name(ivoc)).eq.'not provided') cycle
  551. call emission_megan_ReadSector( emis_input_dir_megan, trim(emis_megan_voc_name(ivoc)), emis_input_year_nat, idate(2), &
  552. sectors_def(lsec)%name, 'kg / s', field3d(:,:,1), status )
  553. IF_NOTOK_RETURN(status=1;deallocate(field3d))
  554. do icb5 = 1, ncb5
  555. field4d(:,:,:,icb5) = field4d(:,:,:,icb5) + field3d(:,:,:) * voc2cbm5(ivoc,icb5)
  556. end do
  557. end do
  558. deallocate( voc2cbm5 )
  559. case('DUMMY')
  560. case default
  561. write(gol,*) "Error in buidling list of providers USED_PROVIDERS"; call goErr
  562. status=1; TRACEBACK; return
  563. END SELECT
  564. ! nothing found?
  565. do icb5 = 1, ncb5
  566. if( sum(field4d(:,:,:,icb5)) < 100.*TINY(1.0) ) then
  567. if (okdebug) then
  568. write(gol,'("EMISS-INFO - no NMVOC emissions found for ",a," ",a," for month ",i2 )') &
  569. trim(sectors_def(lsec)%prov), trim(sectors_def(lsec)%name), idate(2) ; call goPr
  570. endif
  571. hasData(icb5)=.false.
  572. else
  573. if (okdebug) then
  574. write(gol,'("EMISS-INFO - found NMVOC emissions for ",a," ",a," for month ",i2 )') &
  575. trim(sectors_def(lsec)%prov), trim(sectors_def(lsec)%name), idate(2) ; call goPr
  576. endif
  577. field4d(:,:,:,icb5) = field4d(:,:,:,icb5) * sec_month ! from kg/s to kg/month
  578. hasData(icb5)=.true.
  579. end if
  580. enddo
  581. end if
  582. call Par_broadcast(hasData, status)
  583. IF_NOTOK_RETURN(status=1)
  584. ! if (.not.(any(hasData))) cycle sec ! early exit?
  585. if ( sectors_def(lsec)%f3d ) then
  586. has_data_3d(seccount3d,:)=hasData
  587. else
  588. has_data_2d(seccount2d,:)=hasData
  589. end if
  590. ! Loop over cb5 components and distinguish b/w 2d/3d sectors
  591. do icb5 = 1, ncb5
  592. if( sectors_def(lsec)%f3d ) then
  593. if (has_data_3d(seccount3d,icb5)) then
  594. ! ---------------------------------------
  595. ! 3d data (AIRCRAFT), available for CMIP6
  596. ! ---------------------------------------
  597. if (isRoot) then
  598. ! write some numbers
  599. call msg_emis( amonth, trim(sectors_def(lsec)%prov), sectors_def(lsec)%name, &
  600. trim(names(nmhc(icb5))), xmc, sum(field4d(:,:,:,icb5)) )
  601. ! distribute to work arrays in regions
  602. call Coarsen_Emission( trim(names(nmhc(icb5)))//trim(sectors_def(lsec)%name), &
  603. nlon360, nlat180, ar5_dim_3ddata, field4d(:,:,:,icb5), work, add_field, status )
  604. IF_NOTOK_RETURN(status=1)
  605. end if
  606. ! scatter, sum up on target array
  607. do region = 1, nregions
  608. call scatter(dgrid(region), work3d(region)%d3, work(region)%d3, 0, status)
  609. IF_NOTOK_RETURN( status=1 )
  610. CALL GET_DISTGRID( dgrid(region), I_STRT=i1, J_STRT=j1)
  611. ! aircraft data: regrid vertically to model layers
  612. call emission_ar5_regrid_aircraft( region, i1, j1, work3d(region)%d3, emis3d(region)%d3, status )
  613. IF_NOTOK_RETURN( status=1 )
  614. hc_emis_3d(region,seccount3d,icb5)%d3 = hc_emis_3d(region,seccount3d,icb5)%d3 + emis3d(region)%d3
  615. end do
  616. endif
  617. else
  618. ! ---------------------------
  619. ! 2d data (Anthropogenic, Ships, Biomassburning)
  620. ! ---------------------------
  621. if (has_data_2d(seccount2d,icb5)) then
  622. if (isRoot) then ! print total & regrid
  623. call msg_emis( amonth, trim(sectors_def(lsec)%prov),sectors_def(lsec)%name, &
  624. trim(names(nmhc(icb5))), xmc, sum(field4d(:,:,1,icb5)) )
  625. call coarsen_emission( trim(names(nmhc(icb5)))//sectors_def(lsec)%name, &
  626. nlon360, nlat180, field4d(:,:,1,icb5), wrk2D, add_field, status )
  627. IF_NOTOK_RETURN(status=1)
  628. end if
  629. do region = 1, nregions
  630. call scatter(dgrid(region), hc_emis_2d(region,seccount2d,icb5)%surf, work(region)%d3(:,:,1), 0, status)
  631. IF_NOTOK_RETURN(status=1)
  632. end do
  633. endif
  634. endif ! 2D/3D
  635. enddo
  636. end do sec ! sectors
  637. deallocate( field3d, field4d )
  638. do region = 1, nregions
  639. if (associated(wrk2D(region)%surf)) nullify(wrk2D(region)%surf)
  640. deallocate( work(region)%d3 )
  641. deallocate( work3d(region)%d3 )
  642. deallocate( emis3d(region)%d3 )
  643. end do
  644. ! check sectors found
  645. if( seccount2d /= hc_2dsec ) then
  646. write(gol,'(80("-"))') ; call goPr
  647. write(gol,'("ERROR: 2d sectors do not equal total number:",i4," /= ",i4," !")') seccount2d, hc_2dsec ; call goErr
  648. write(gol,'(80("-"))') ; call goPr
  649. status=1; return
  650. end if
  651. if( seccount3d /= hc_3dsec ) then
  652. write(gol,'(80("-"))') ; call goPr
  653. write(gol,'("ERROR: 3d sectors do not equal total number:",i4," /= ",i4," !")') seccount3d, hc_3dsec ; call goErr
  654. write(gol,'(80("-"))') ; call goPr
  655. status=1; return
  656. end if
  657. status = 0
  658. end subroutine emission_nmvoc_declare
  659. !EOC
  660. !--------------------------------------------------------------------------
  661. ! TM5 !
  662. !--------------------------------------------------------------------------
  663. !BOP
  664. !
  665. ! !IROUTINE: EMISSION_NMVOC_APPLY
  666. !
  667. ! !DESCRIPTION: Take monthly emissions, and
  668. ! - split them vertically
  669. ! - apply time splitting factors
  670. ! - add them up (add_3d)
  671. !\\
  672. !\\
  673. ! !INTERFACE:
  674. !
  675. SUBROUTINE EMISSION_NMVOC_APPLY( region, status )
  676. !
  677. ! !USES:
  678. !
  679. use dims, only : idate, itaur, nsrce, tref
  680. use dims, only : im, jm, lm
  681. use chem_param, only : xmcb5, xmc, ntracet, nmhc, names
  682. use datetime, only : tau2date
  683. use emission_data, only : emission_vdist_by_sector
  684. use emission_data, only : do_add_3d, do_add_3d_cycle, bb_cycle
  685. use emission_data, only : emis_bb_trop_cycle
  686. use emission_read, only : sectors_def, numb_sectors
  687. use emission_read, only : ed42_hc_sectors
  688. !
  689. ! !INPUT PARAMETERS:
  690. !
  691. integer, intent(in) :: region
  692. !
  693. ! !OUTPUT PARAMETERS:
  694. !
  695. integer, intent(out) :: status
  696. !
  697. ! !REVISION HISTORY:
  698. ! 1 Oct 2010 - Achim Strunk - rewritten for AR5
  699. ! 29 Jun 2012 - Ph. Le Sager - adapted for lon-lat MPI domain decomposition
  700. !
  701. !EOP
  702. !------------------------------------------------------------------------
  703. !BOC
  704. character(len=*), parameter :: rname = mname//'/emission_nmvoc_apply'
  705. ! --- local ---------------------------------------
  706. integer,dimension(6) :: idater
  707. real :: dtime, fraction
  708. integer :: imr, jmr, lmr, lsec, icb5, i1, i2, j1, j2
  709. integer :: seccount2d, seccount3d
  710. type(d3_data) :: emis3d
  711. ! --- begin -----------------------------------------
  712. status = 0
  713. if(.not. has_emis) return
  714. if( okdebug ) then
  715. write(gol,*) 'start of emission_nmvoc_apply'; call goPr
  716. end if
  717. call tau2date(itaur(region),idater)
  718. dtime=float(nsrce)/(2*tref(region)) !emissions are added in two steps...XYZECCEZYX.
  719. ! get a working structure for 3d emissions
  720. call get_distgrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  721. allocate( emis3d%d3(i1:i2,j1:j2,lm(region)) ) ; emis3d%d3 = 0.0
  722. ! count 2d and 3d sectors
  723. seccount2d = 0
  724. seccount3d = 0
  725. ! cycle over sectors
  726. do lsec = 1, numb_sectors
  727. if (count(used_providers.eq.sectors_def(lsec)%prov).eq.0) cycle
  728. if ((trim(sectors_def(lsec)%prov).eq.'ED42') .and. (count(ed42_hc_sectors.eq.sectors_def(lsec)%name) .eq. 0)) cycle
  729. if( sectors_def(lsec)%f3d ) then ! count
  730. seccount3d = seccount3d + 1
  731. else
  732. seccount2d = seccount2d + 1
  733. end if
  734. fraction = 1.0 ! default: no additional splitting
  735. ! ----------------------------------------------------------------------------------------
  736. ! distinguish here between sectors and whether they should have additional splitting
  737. ! if( sectors_def(lsec)%catname == 'biomassburning' ) fraction = fraction * bb_frac etc...
  738. ! ----------------------------------------------------------------------------------------
  739. cb05: do icb5=1,ncb5
  740. if( nmhc(icb5).gt. ntracet ) cycle cb05 ! only transported species, skip short lived species
  741. ! distinguish between 2d/3d sectors
  742. if( sectors_def(lsec)%f3d ) then
  743. if (.not.has_data_3d(seccount3d,icb5)) cycle cb05
  744. emis3d%d3 = hc_emis_3d(region,seccount3d,icb5)%d3
  745. else
  746. if (.not.has_data_2d(seccount2d,icb5)) cycle cb05
  747. ! vertically distribute according to sector
  748. emis3d%d3 = 0.0
  749. call emission_vdist_by_sector( sectors_def(lsec)%vdisttype, trim(names(nmhc(icb5))), region, &
  750. hc_emis_2d(region,seccount2d,icb5), emis3d, status )
  751. IF_NOTOK_RETURN(status=1)
  752. endif
  753. ! add dataset according to sector and category
  754. if( emis_bb_trop_cycle .and. trim(sectors_def(lsec)%catname) == "biomassburning" ) then
  755. call do_add_3d_cycle( region, nmhc(icb5), i1, j1, emis3d%d3, bb_cycle(region)%scalef, &
  756. xmcb5(icb5), xmcb5(icb5), status, fraction )
  757. IF_NOTOK_RETURN(status=1)
  758. else
  759. call do_add_3d( region, nmhc(icb5), i1, j1, emis3d%d3, xmcb5(icb5), xmcb5(icb5), status, fraction )
  760. IF_NOTOK_RETURN(status=1)
  761. endif
  762. enddo cb05
  763. enddo ! sectors
  764. deallocate( emis3d%d3 )
  765. if(okdebug) then
  766. write(gol,*) 'end of emission_nmvoc_apply'; call goPr
  767. end if
  768. status = 0
  769. END SUBROUTINE EMISSION_NMVOC_APPLY
  770. !EOC
  771. END MODULE EMISSION_NMVOC