emission_nmvoc.F90 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845
  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(ncb4) = (/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 : ncb4
  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, icb4
  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, ncb4 ) )
  113. allocate( hc_emis_3d( nregions, hc_3dsec, ncb4 ) )
  114. allocate( has_data_2d(hc_2dsec, ncb4) ) ; has_data_2d=.false.
  115. allocate( has_data_3d(hc_3dsec, ncb4) ) ; 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 icb4 = 1, ncb4
  121. do lsec=1,hc_2dsec
  122. allocate( hc_emis_2d(region,lsec,icb4)%surf(i1:i2, j1:j2) )
  123. end do
  124. do lsec=1,hc_3dsec
  125. allocate( hc_emis_3d(region,lsec,icb4)%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, icb4
  159. ! --- begin --------------------------------------
  160. status = 0
  161. if(.not. has_emis) return
  162. do region = 1, nregions
  163. do icb4 = 1, ncb4
  164. do lsec=1,hc_2dsec
  165. deallocate( hc_emis_2d(region,lsec,icb4)%surf )
  166. end do
  167. do lsec=1,hc_3dsec
  168. deallocate( hc_emis_3d(region,lsec,icb4)%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, ncb4, nmhc, names
  200. use emission_data, only : msg_emis, LAR5BMB, LMEGAN
  201. ! ---------------- AR5 - EDGAR 4 - ETC. --------------------
  202. use emission_data, only : emis_input_year
  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_ar5_ReadSector
  210. use emission_read, only : emission_macc_ReadSector
  211. use emission_read, only : emission_ed4_ReadSector
  212. use emission_read, only : emission_gfed_ReadSector
  213. use emission_read, only : emission_megan_ReadSector
  214. use emission_read, only : emission_retro_ReadSector
  215. use emission_read, only : sectors_def, numb_sectors
  216. use emission_read, only : ar5_dim_3ddata
  217. use emission_read, only : emis_ar5_nvoc, emis_ar5_voc_name
  218. use emission_read, only : emis_ar5_voc2cbm4_default
  219. use emission_read, only : emis_ar5_voc2cbm4_biomassb
  220. use emission_read, only : emis_ar5_voc2cbm4_biogenic
  221. use emission_read, only : emis_macc_nvoc, emis_macc_voc_name
  222. use emission_read, only : emis_macc_voc2cbm4_default
  223. use emission_read, only : emis_macc_voc2cbm4_biomassb
  224. use emission_read, only : emis_macc_voc2cbm4_biogenic
  225. use emission_read, only : emis_megan_voc2cbm4_biogenic
  226. use emission_read, only : emis_megan_nvoc, emis_megan_voc_name
  227. use emission_read, only : emis_gfed_nvoc, emis_gfed_voc_name
  228. use emission_read, only : emis_retro_voc_name
  229. use emission_read, only : ed42_hc_sectors
  230. !
  231. ! !OUTPUT PARAMETERS:
  232. !
  233. integer, intent(out) :: status
  234. !
  235. ! !REVISION HISTORY:
  236. ! 1 Oct 2010 - Achim Strunk - revamped for AR5
  237. ! 1 Dec 2011 - Narcisa Banda - added EDGAR 4
  238. ! 29 Jun 2012 - Ph. Le Sager - adapted for lon-lat MPI domain decomposition
  239. !
  240. !EOP
  241. !------------------------------------------------------------------------
  242. !BOC
  243. character(len=*), parameter :: rname = mname//'/emission_nmvoc_declare'
  244. ! --- local ---------------------------------------
  245. integer :: region
  246. logical :: hasData(ncb4)
  247. integer, parameter :: add_field = 0
  248. integer, parameter :: amonth = 2
  249. integer :: imr, jmr, lmr, i1, i2, j1, j2
  250. integer :: lsec, ivoc, icb4
  251. ! AR5
  252. real,dimension(:,:,:), allocatable :: field3d
  253. real,dimension(:,:,:,:),allocatable :: field4d
  254. type(d3_data) :: emis3d, work(nregions)
  255. type(emis_data) :: wrk2D(nregions)
  256. integer :: seccount2d, seccount3d
  257. real,dimension(:,:), allocatable :: voc2cbm4
  258. ! --- begin ----------------------------------------
  259. status = 0
  260. if(.not. has_emis) return
  261. write(gol,'(" EMISS-INFO ------------- read NMVOC emissions -------------")'); call goPr
  262. ! reset arrays
  263. do region = 1, nregions
  264. do icb4 = 1, ncb4
  265. do lsec=1,hc_2dsec
  266. hc_emis_2d(region,lsec,icb4)%surf = 0.0
  267. end do
  268. do lsec=1,hc_3dsec
  269. hc_emis_3d(region,lsec,icb4)%d3 = 0.0
  270. end do
  271. end do
  272. end do
  273. ! global arrays for coarsening
  274. do region = 1, nregions
  275. if (isRoot)then
  276. allocate(work(region)%d3(im(region),jm(region),lm(region)))
  277. else
  278. allocate(work(region)%d3(1,1,1))
  279. end if
  280. enddo
  281. do region = 1, nregions
  282. wrk2D(region)%surf => work(region)%d3(:,:,1)
  283. end do
  284. ! count 2d and 3d sectors
  285. seccount2d = 0
  286. seccount3d = 0
  287. ! always allocate here 3D/4D data set (for 2d sectors it will be filled in first layer only)
  288. if (isRoot) then
  289. allocate( field3d( nlon360, nlat180, ar5_dim_3ddata ) ) ; field3d = 0.0
  290. allocate( field4d( nlon360, nlat180, ar5_dim_3ddata, ncb4 ) ) ; field4d = 0.0
  291. else
  292. allocate( field3d( 1, 1, 1 ) )
  293. allocate( field4d( 1, 1, 1, 1 ) )
  294. end if
  295. ! --------------------------------
  296. ! do a loop over available sectors
  297. ! --------------------------------
  298. sec : do lsec = 1, numb_sectors
  299. if (count(used_providers.eq.sectors_def(lsec)%prov).eq.0) cycle
  300. if ((trim(sectors_def(lsec)%prov).eq.'ED42') .and. (count(ed42_hc_sectors.eq.sectors_def(lsec)%name) .eq. 0)) cycle
  301. if( sectors_def(lsec)%f3d ) then
  302. seccount3d = seccount3d + 1
  303. else
  304. seccount2d = seccount2d + 1
  305. end if
  306. field3d = 0.0
  307. field4d = 0.0
  308. if (isRoot) then ! READ
  309. select case( trim(sectors_def(lsec)%prov) )
  310. case( 'AR5' )
  311. ! screen out AR5 biomass burning if not wanted
  312. if ( .not. ((trim(sectors_def(lsec)%catname) .eq. 'biomassburning').and.(.not.LAR5BMB)) ) then
  313. ! get appropriate array of splitting values from input to cbm4
  314. allocate( voc2cbm4(emis_ar5_nvoc,ncb4) )
  315. ! Changing the tables here in order to get ALD and PAR etc from Biomassburning
  316. voc2cbm4 = reshape( emis_ar5_voc2cbm4_default, (/emis_ar5_nvoc,ncb4/) )
  317. ! --------------------------------
  318. ! do a loop over available constituents (25)
  319. ! --------------------------------
  320. vocAR5: do ivoc = 1, emis_ar5_nvoc
  321. ! skip missing categories
  322. if (count(trim(emis_ar5_voc_name(ivoc)).eq.sectors_def(lsec)%species).eq.0) cycle
  323. call emission_ar5_ReadSector( trim(emis_ar5_voc_name(ivoc)), emis_input_year, idate(2), lsec, field3d, status )
  324. IF_NOTOK_RETURN(status=1)
  325. do icb4 = 1, ncb4
  326. field4d(:,:,:,icb4) = field4d(:,:,:,icb4) + field3d(:,:,:) * voc2cbm4(ivoc,icb4)
  327. end do
  328. end do vocAR5
  329. deallocate( voc2cbm4 )
  330. end if
  331. case( 'MACC' )
  332. ! screen out biomass burning (a/k/a emiss_bb), and 'soil', 'nat' and 'air' sectors (no NMVOC)
  333. ! skip 'bio' source if already provided by MEGAN
  334. if ( ( .not. (trim(sectors_def(lsec)%catname) .eq. 'biomassburning') ) .and. &
  335. ( .not. (trim(sectors_def(lsec)%name) .eq. 'emiss_soil') ) .and. &
  336. ( .not. (trim(sectors_def(lsec)%name) .eq. 'emiss_nat') ) .and. &
  337. ( .not. (trim(sectors_def(lsec)%name) .eq. 'emiss_air') ) .and. &
  338. ( .not. (LMEGAN .and. (trim(sectors_def(lsec)%name) .eq. 'emiss_bio'))) ) then
  339. ! get appropriate array of splitting values from input to cbm4
  340. allocate( voc2cbm4(emis_macc_nvoc,ncb4) )
  341. select case( trim(sectors_def(lsec)%catname) )
  342. case( 'anthropogenic', 'ships', 'aircraft' )
  343. voc2cbm4 = reshape( emis_macc_voc2cbm4_default, (/emis_macc_nvoc,ncb4/) )
  344. case( 'natural' )
  345. voc2cbm4 = reshape( emis_macc_voc2cbm4_biogenic, (/emis_macc_nvoc,ncb4/) )
  346. case default
  347. write(gol,'(80("-"))') ; call goPr
  348. write(gol,'("ERROR: wrong category name `",a,"`!")') sectors_def(lsec)%catname ; call goErr
  349. write(gol,'(80("-"))') ; call goPr
  350. end select
  351. ! --------------------------------
  352. ! do a loop over available constituents (14)
  353. ! --------------------------------
  354. do ivoc = 1, emis_macc_nvoc
  355. call emission_macc_ReadSector( emis_input_dir_mac, trim(emis_macc_voc_name(ivoc)), emis_input_year, idate(2), &
  356. '0.5x0.5_kg.nc', sectors_def(lsec)%name, 'kg / s', field3d, status )
  357. IF_NOTOK_RETURN(status=1;deallocate(field3d,field4d))
  358. do icb4 = 1, ncb4
  359. field4d(:,:,:,icb4) = field4d(:,:,:,icb4) + field3d(:,:,:) * voc2cbm4(ivoc,icb4)
  360. end do
  361. end do
  362. deallocate( voc2cbm4 )
  363. endif
  364. case( 'ED41' )
  365. select case(trim(sectors_def(lsec)%name))
  366. case ('1A3b_c_e','1A3d_SHIP','1A3d1')
  367. ! AR5 NMVOC emissions and were used to split EDGAR NMVOC totals into separate (AR5) NMVOC species
  368. ! get appropriate array of splitting values from input to cbm4
  369. allocate( voc2cbm4(emis_ar5_nvoc,ncb4) )
  370. ! Changing the tables here in order to get ALD and PAR etc from Biomassburning
  371. voc2cbm4 = reshape( emis_ar5_voc2cbm4_default, (/emis_ar5_nvoc,ncb4/) )
  372. ! --------------------------------
  373. ! do a loop over available constituents (25)
  374. ! --------------------------------
  375. vocED41: do ivoc = 1, emis_ar5_nvoc
  376. ! screen out missing dataset
  377. if ((ivoc==10).or.(ivoc==11)) cycle vocED41
  378. if ( trim(sectors_def(lsec)%name) /= '1A3b_c_e') then
  379. if ((ivoc==1).or.(ivoc>=18)) cycle vocED41
  380. endif
  381. if (((ivoc==1).or.(ivoc==24)).and.(emis_input_year<2005)) cycle vocED41 ! kludge (waiting for NB input)
  382. call emission_ed4_ReadSector( emis_input_dir_ed4, trim(emis_ar5_voc_name(ivoc)), trim(emis_ar5_voc_name(ivoc)),&
  383. emis_input_year, idate(2), lsec, trim(sectors_def(lsec)%prov), 'kg / s', field3d,&
  384. status )
  385. IF_NOTOK_RETURN(status=1)
  386. do icb4 = 1, ncb4
  387. field4d(:,:,:,icb4) = field4d(:,:,:,icb4) + field3d(:,:,:) * voc2cbm4(ivoc,icb4)
  388. end do
  389. end do vocED41
  390. deallocate( voc2cbm4 )
  391. end select
  392. case( 'ED42' )
  393. ! Biomass burning (GFED/RETRO/AR5BMB) and transport (ED41) are excluded through ED42_HC_SECTORS definition
  394. ! Same constituents as AR5 NMVOC are used
  395. ! get appropriate array of splitting values from input to cbm4
  396. allocate( voc2cbm4(emis_ar5_nvoc,ncb4) )
  397. voc2cbm4 = reshape( emis_ar5_voc2cbm4_default, (/emis_ar5_nvoc,ncb4/) )
  398. ! --------------------------------
  399. ! do a loop over available constituents (25)
  400. ! --------------------------------
  401. vocED42: do ivoc = 1, emis_ar5_nvoc
  402. ! screen out missing dataset
  403. if ((ivoc==10).or.(ivoc==11)) cycle vocED42
  404. if ( trim(sectors_def(lsec)%name) == '3') then
  405. if (count(ivoc.eq.(/2,3,4,5,7,8,9,12,13,16,21,22,24/)).eq.1) cycle vocED42
  406. endif
  407. if ( trim(sectors_def(lsec)%name) == '1A4') then
  408. if (count(ivoc.eq.(/1,24/)).eq.1) cycle vocED42
  409. endif
  410. if ( trim(sectors_def(lsec)%name) == '4F') then
  411. if (count(ivoc.eq.(/16,17,18,19,20,25/)).eq.1) cycle vocED42
  412. endif
  413. if ( ( trim(sectors_def(lsec)%name) == '1A1a') .or. &
  414. ( trim(sectors_def(lsec)%name) == '1A1b_c_1B_2C1_2C2') .or. &
  415. ( trim(sectors_def(lsec)%name) == '1A2') .or. &
  416. ( trim(sectors_def(lsec)%name) == '2A_B_D_E_F_G') .or. &
  417. ( trim(sectors_def(lsec)%name) == '7A') ) then
  418. if (count(ivoc.eq.(/18,19,20/)).eq.1) cycle vocED42
  419. endif
  420. call emission_ed4_ReadSector( emis_input_dir_ed4, trim(emis_ar5_voc_name(ivoc)), &
  421. trim(emis_ar5_voc_name(ivoc)), emis_input_year, idate(2), lsec, &
  422. trim(sectors_def(lsec)%prov), 'kg / s', field3d, status )
  423. IF_NOTOK_RETURN(status=1)
  424. do icb4 = 1, ncb4
  425. field4d(:,:,:,icb4) = field4d(:,:,:,icb4) + field3d(:,:,:) * voc2cbm4(ivoc,icb4)
  426. end do
  427. end do vocED42
  428. deallocate( voc2cbm4 )
  429. case( 'GFEDv3' )
  430. ! We use the MACC voc split, since GFED3 contains the same species,
  431. ! except for the last 3 species - Acetone, Acetaldehyde and MEK - which are not provided in GFED3
  432. ! get appropriate array of splitting values from input to cbm4
  433. allocate( voc2cbm4(emis_macc_nvoc,ncb4) )
  434. voc2cbm4 = reshape( emis_macc_voc2cbm4_biomassb, (/emis_macc_nvoc,ncb4/) )
  435. ! --------------------------------
  436. ! do a loop over available constituents (11)
  437. ! --------------------------------
  438. do ivoc = 1, emis_gfed_nvoc
  439. call emission_gfed_ReadSector( emis_input_dir_gfed, trim(emis_gfed_voc_name(ivoc)), emis_input_year, idate(2), &
  440. sectors_def(lsec)%name, 'kg / s', field3d(:,:,1), status )
  441. IF_NOTOK_RETURN(status=1;deallocate(field3d,field4d))
  442. do icb4 = 1, ncb4
  443. field4d(:,:,:,icb4) = field4d(:,:,:,icb4) + field3d(:,:,:) * voc2cbm4(ivoc,icb4)
  444. end do
  445. end do
  446. deallocate( voc2cbm4 )
  447. case( 'RETRO' )
  448. allocate( voc2cbm4(emis_ar5_nvoc,ncb4) )
  449. voc2cbm4 = reshape( emis_ar5_voc2cbm4_biomassb, (/emis_ar5_nvoc,ncb4/) )
  450. ! --------------------------------
  451. ! do a loop over available constituents (25)
  452. ! --------------------------------
  453. do ivoc = 1, emis_ar5_nvoc
  454. if (trim(emis_retro_voc_name(ivoc)).eq.'not provided') cycle
  455. call emission_retro_ReadSector( emis_input_dir_retro, trim(emis_retro_voc_name(ivoc)), emis_input_year, idate(2), &
  456. sectors_def(lsec)%name, 'kg / s', field3d(:,:,1), status )
  457. IF_NOTOK_RETURN(status=1;deallocate(field3d))
  458. do icb4 = 1, ncb4
  459. field4d(:,:,:,icb4) = field4d(:,:,:,icb4) + field3d(:,:,:) * voc2cbm4(ivoc,icb4)
  460. end do
  461. end do
  462. deallocate( voc2cbm4 )
  463. case( 'MEGAN' )
  464. allocate( voc2cbm4(emis_megan_nvoc,ncb4) )
  465. voc2cbm4 = reshape( emis_megan_voc2cbm4_biogenic, (/emis_megan_nvoc,ncb4/) )
  466. ! --------------------------------
  467. ! do a loop over available constituents (25)
  468. ! --------------------------------
  469. do ivoc = 1, emis_megan_nvoc
  470. if (trim(emis_megan_voc_name(ivoc)).eq.'not provided') cycle
  471. call emission_megan_ReadSector( emis_input_dir_megan, trim(emis_megan_voc_name(ivoc)), emis_input_year, idate(2), &
  472. sectors_def(lsec)%name, 'kg / s', field3d(:,:,1), status )
  473. IF_NOTOK_RETURN(status=1;deallocate(field3d))
  474. do icb4 = 1, ncb4
  475. field4d(:,:,:,icb4) = field4d(:,:,:,icb4) + field3d(:,:,:) * voc2cbm4(ivoc,icb4)
  476. end do
  477. end do
  478. deallocate( voc2cbm4 )
  479. case('DUMMY')
  480. case default
  481. write(gol,*) "Error in buidling list of providers USED_PROVIDERS"; call goErr
  482. status=1; TRACEBACK; return
  483. END SELECT
  484. ! nothing found?
  485. do icb4 = 1, ncb4
  486. if( sum(field4d(:,:,:,icb4)) < 100.*TINY(1.0) ) then
  487. if (okdebug) then
  488. write(gol,'("EMISS-INFO - no NMVOC emissions found for ",a," ",a," for month ",i2 )') &
  489. trim(sectors_def(lsec)%prov), trim(sectors_def(lsec)%name), idate(2) ; call goPr
  490. endif
  491. hasData(icb4)=.false.
  492. else
  493. if (okdebug) then
  494. write(gol,'("EMISS-INFO - found NMVOC emissions for ",a," ",a," for month ",i2 )') &
  495. trim(sectors_def(lsec)%prov), trim(sectors_def(lsec)%name), idate(2) ; call goPr
  496. endif
  497. field4d(:,:,:,icb4) = field4d(:,:,:,icb4) * sec_month ! from kg/s to kg/month
  498. hasData(icb4)=.true.
  499. end if
  500. enddo
  501. end if
  502. call Par_broadcast(hasData, status)
  503. IF_NOTOK_RETURN(status=1)
  504. ! if (.not.(any(hasData))) cycle sec ! early exit?
  505. if ( sectors_def(lsec)%f3d ) then
  506. has_data_3d(seccount3d,:)=hasData
  507. else
  508. has_data_2d(seccount2d,:)=hasData
  509. end if
  510. ! Loop over cb4 components and distinguish b/w 2d/3d sectors
  511. do icb4 = 1, ncb4
  512. if( sectors_def(lsec)%f3d ) then
  513. ! ---------------------------
  514. ! 3d data (AIRCRAFT)
  515. ! ---------------------------
  516. if (has_data_3d(seccount3d,icb4)) then
  517. write(gol,'("EMISS-ERROR - Unexpected 3D data - implement")'); call goErr
  518. status=1; TRACEBACK; return
  519. endif
  520. else
  521. ! ---------------------------
  522. ! 2d data (Anthropogenic, Ships, Biomassburning)
  523. ! ---------------------------
  524. if (has_data_2d(seccount2d,icb4)) then
  525. if (isRoot) then ! print total & regrid
  526. call msg_emis( amonth, trim(sectors_def(lsec)%prov),sectors_def(lsec)%name, &
  527. trim(names(nmhc(icb4))), xmc, sum(field4d(:,:,1,icb4)) )
  528. call coarsen_emission( trim(names(nmhc(icb4)))//sectors_def(lsec)%name, &
  529. nlon360, nlat180, field4d(:,:,1,icb4), wrk2D, add_field, status )
  530. IF_NOTOK_RETURN(status=1)
  531. end if
  532. do region = 1, nregions
  533. call scatter(dgrid(region), hc_emis_2d(region,seccount2d,icb4)%surf, work(region)%d3(:,:,1), 0, status)
  534. IF_NOTOK_RETURN(status=1)
  535. end do
  536. endif
  537. endif ! 2D/3D
  538. enddo
  539. end do sec ! sectors
  540. deallocate( field3d, field4d )
  541. do region = 1, nregions
  542. if (associated(wrk2D(region)%surf)) nullify(wrk2D(region)%surf)
  543. deallocate( work(region)%d3 )
  544. end do
  545. ! check sectors found
  546. if( seccount2d /= hc_2dsec ) then
  547. write(gol,'(80("-"))') ; call goPr
  548. write(gol,'("ERROR: 2d sectors do not equal total number:",i4," /= ",i4," !")') seccount2d, hc_2dsec ; call goErr
  549. write(gol,'(80("-"))') ; call goPr
  550. status=1; return
  551. end if
  552. if( seccount3d /= hc_3dsec ) then
  553. write(gol,'(80("-"))') ; call goPr
  554. write(gol,'("ERROR: 3d sectors do not equal total number:",i4," /= ",i4," !")') seccount3d, hc_3dsec ; call goErr
  555. write(gol,'(80("-"))') ; call goPr
  556. status=1; return
  557. end if
  558. status = 0
  559. end subroutine emission_nmvoc_declare
  560. !EOC
  561. !--------------------------------------------------------------------------
  562. ! TM5 !
  563. !--------------------------------------------------------------------------
  564. !BOP
  565. !
  566. ! !IROUTINE: EMISSION_NMVOC_APPLY
  567. !
  568. ! !DESCRIPTION: Take monthly emissions, and
  569. ! - split them vertically
  570. ! - apply time splitting factors
  571. ! - add them up (add_3d)
  572. !\\
  573. !\\
  574. ! !INTERFACE:
  575. !
  576. SUBROUTINE EMISSION_NMVOC_APPLY( region, status )
  577. !
  578. ! !USES:
  579. !
  580. use dims, only : idate, itaur, nsrce, tref
  581. use dims, only : im, jm, lm
  582. use chem_param, only : xmcb4, xmc, ntracet, nmhc, names
  583. use datetime, only : tau2date
  584. use emission_data, only : emission_vdist_by_sector
  585. use emission_data, only : do_add_3d, do_add_3d_cycle, bb_cycle
  586. use emission_data, only : emis_bb_trop_cycle
  587. use emission_read, only : sectors_def, numb_sectors
  588. use emission_read, only : ed42_hc_sectors
  589. !
  590. ! !INPUT PARAMETERS:
  591. !
  592. integer, intent(in) :: region
  593. !
  594. ! !OUTPUT PARAMETERS:
  595. !
  596. integer, intent(out) :: status
  597. !
  598. ! !REVISION HISTORY:
  599. ! 1 Oct 2010 - Achim Strunk - rewritten for AR5
  600. ! 29 Jun 2012 - Ph. Le Sager - adapted for lon-lat MPI domain decomposition
  601. !
  602. !EOP
  603. !------------------------------------------------------------------------
  604. !BOC
  605. character(len=*), parameter :: rname = mname//'/emission_nmvoc_apply'
  606. ! --- local ---------------------------------------
  607. integer,dimension(6) :: idater
  608. real :: dtime, fraction
  609. integer :: imr, jmr, lmr, lsec, icb4, i1, i2, j1, j2
  610. integer :: seccount2d, seccount3d
  611. type(d3_data) :: emis3d
  612. ! --- begin -----------------------------------------
  613. status = 0
  614. if(.not. has_emis) return
  615. if( okdebug ) then
  616. write(gol,*) 'start of emission_nmvoc_apply'; call goPr
  617. end if
  618. call tau2date(itaur(region),idater)
  619. dtime=float(nsrce)/(2*tref(region)) !emissions are added in two steps...XYZECCEZYX.
  620. ! get a working structure for 3d emissions
  621. call get_distgrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  622. allocate( emis3d%d3(i1:i2,j1:j2,lm(region)) ) ; emis3d%d3 = 0.0
  623. ! count 2d and 3d sectors
  624. seccount2d = 0
  625. seccount3d = 0
  626. ! cycle over sectors
  627. do lsec = 1, numb_sectors
  628. if (count(used_providers.eq.sectors_def(lsec)%prov).eq.0) cycle
  629. if ((trim(sectors_def(lsec)%prov).eq.'ED42') .and. (count(ed42_hc_sectors.eq.sectors_def(lsec)%name) .eq. 0)) cycle
  630. if( sectors_def(lsec)%f3d ) then ! count
  631. seccount3d = seccount3d + 1
  632. else
  633. seccount2d = seccount2d + 1
  634. end if
  635. fraction = 1.0 ! default: no additional splitting
  636. ! ----------------------------------------------------------------------------------------
  637. ! distinguish here between sectors and whether they should have additional splitting
  638. ! if( sectors_def(lsec)%catname == 'biomassburning' ) fraction = fraction * bb_frac etc...
  639. ! ----------------------------------------------------------------------------------------
  640. cb05: do icb4=1,ncb4
  641. if( nmhc(icb4).gt. ntracet ) cycle cb05 ! only transported species, skip short lived species
  642. ! distinguish between 2d/3d sectors
  643. if( sectors_def(lsec)%f3d ) then
  644. if (.not.has_data_3d(seccount3d,icb4)) cycle cb05
  645. emis3d%d3 = hc_emis_3d(region,seccount3d,icb4)%d3
  646. else
  647. if (.not.has_data_2d(seccount2d,icb4)) cycle cb05
  648. ! vertically distribute according to sector
  649. emis3d%d3 = 0.0
  650. call emission_vdist_by_sector( sectors_def(lsec)%vdisttype, trim(names(nmhc(icb4))), region, &
  651. hc_emis_2d(region,seccount2d,icb4), emis3d, status )
  652. IF_NOTOK_RETURN(status=1)
  653. endif
  654. ! add dataset according to sector and category
  655. if( emis_bb_trop_cycle .and. trim(sectors_def(lsec)%catname) == "biomassburning" ) then
  656. call do_add_3d_cycle( region, nmhc(icb4), i1, j1, emis3d%d3, bb_cycle(region)%scalef, &
  657. xmcb4(icb4), xmcb4(icb4), status, fraction )
  658. IF_NOTOK_RETURN(status=1)
  659. else
  660. call do_add_3d( region, nmhc(icb4), i1, j1, emis3d%d3, xmcb4(icb4), xmcb4(icb4), status, fraction )
  661. IF_NOTOK_RETURN(status=1)
  662. endif
  663. enddo cb05
  664. enddo ! sectors
  665. deallocate( emis3d%d3 )
  666. if(okdebug) then
  667. write(gol,*) 'end of emission_nmvoc_apply'; call goPr
  668. end if
  669. status = 0
  670. END SUBROUTINE EMISSION_NMVOC_APPLY
  671. !EOC
  672. END MODULE EMISSION_NMVOC