emission_data.F90 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309
  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_DATA
  14. !
  15. ! !DESCRIPTION: Provides general methods and fields needed for the emission
  16. ! routines.
  17. !
  18. ! emission_vdist_by_sector : distribute vertically emissions according to source sector
  19. ! msg_emis : print formated emission total
  20. ! do_add_2d : add 2D emission to tracer mass array
  21. ! do_add_3d : add 3D emission to tracer mass array
  22. ! do_add_3d_cycle : add 3D emission to tracer mass array with a daily cycle
  23. ! scale_cycle : evaluate a daily cycle
  24. ! distribute_l44 : scale input field with NH (SH) fires distributed over JAS (JFM)
  25. !\\
  26. !\\
  27. ! !INTERFACE:
  28. !
  29. MODULE EMISSION_DATA
  30. !
  31. ! !USES:
  32. !
  33. use GO, only : gol, goPr, goErr
  34. use Dims, only : nregions, lm
  35. use global_types, only : emis_data, d2_data, d23_data, d3_data
  36. #ifdef with_m7
  37. use mo_aero_m7, only : nmod
  38. use mo_aero, only : cmr_ff, cmr_bb, cmr_sk, cmr_sa, cmr_sc, facso2
  39. use mo_aero, only : zbb_wsoc_perc, zbge_wsoc_perc
  40. !use mo_aero, only : zom2oc
  41. use global_types, only : modal_emissions
  42. #endif
  43. #ifdef with_budgets
  44. use budget_global,only : budg_dat, nzon_vg
  45. #endif
  46. IMPLICIT NONE
  47. !
  48. ! !PUBLIC DATA MEMBERS & TYPES:
  49. !
  50. public :: emis_data, d2_data, d23_data
  51. !
  52. type(emis_data), target :: plandr(nregions) ! Land fraction
  53. type(emis_data), target :: emis2D(nregions) ! 2D emiss prior vertical redistribution
  54. type(emis_data), target :: emis_temp(nregions) ! temp array to store emission
  55. #ifdef with_m7
  56. type(modal_emissions), dimension(nregions,nmod), target :: emis_mass
  57. type(modal_emissions), dimension(nregions,nmod), target :: emis_number
  58. #endif
  59. #ifdef with_m7
  60. ! Count median / geometric mean radii of
  61. ! primary carbonaceous and sulfate emissions
  62. ! based on AeroCom-I recommendations (Dentener et al., ACP, 2006).
  63. ! The corresponding values for the M7 modes are given by Stier et al. (ACP, 2005).
  64. ! The same values have also been adopted in GLOMAP (Mann et al., 2010).
  65. !
  66. ! Count median radii for carbonaceous aerosol emissions from Dentener et al.,
  67. ! corresponding to sigma = 1.8:
  68. !real, parameter :: rad_emi_ff = 0.015e-6
  69. !real, parameter :: rad_emi_bb = 0.04e-6
  70. ! The corresponding values for sigma = 1.59 used in M7
  71. ! are cmr_ff and cmr_bb, specified in mo_aero.F90.
  72. ! For comparison, Bond et al. (JGR, 2013) give number median radii
  73. ! between 25 and 40 nm for fresh BC in the urban areas
  74. ! of Tokyo, Nagoya, and Seoul,
  75. ! of 60 nm in plumes associated with wildfires,
  76. ! and about 15 nm from aircraft jet engines.
  77. ! These values are volume-equivalent radii (see their Fig. 4).
  78. !
  79. ! According to the original paper by Schwarz et al. (GRL, 2008)
  80. ! the corresponding geometric standard deviation
  81. ! is sigma = 1.71 for the urban BC
  82. ! and 1.43 for the biomass burning aerosol.
  83. !
  84. ! For BC in biomass burning plumes,
  85. ! Kondo et al (JGR, 2011) estimated
  86. ! number median radii in the range 68-70.5 nm (+- 6-8 nm)
  87. ! and geometric standard deviation between 1.32 and 1.36 (+- 0.01-0.04),
  88. ! for particles thickly coated by organics.
  89. !
  90. ! Janhaell et al. (ACP, 2010) have compiled measurements of
  91. ! particle size in fresh biomass burning smoke from vegetation fires.
  92. ! They mention that particles from biomass burning are dominated
  93. ! by an accumulation mode.
  94. ! They also present a relation between the geometric mean diameter Dg
  95. ! and geometric standard deviation sigma for fresh smoke:
  96. ! Dg (um) = (584 +- 5) - (269 +-1) sigma
  97. ! This gives a geometric mean radius of 78 um for sigma = 1.59,
  98. ! in close agreement with the value used by Stier et al.
  99. !
  100. ! Another way to account for differences in sigma
  101. ! is to modify the number median radius rg
  102. ! such that the number of particles (N)
  103. ! emitted for a certain mass (M) is the same.
  104. ! N is proportional to M/rv^3,
  105. ! where rv is the volume mean radius,
  106. ! which is related to rg by
  107. ! rv = rg * exp(1.5*(ln(sigma))^2).
  108. ! According to Janhall, fresh smoke has an average
  109. ! Dg of 117 +- 13 nm and sigma of 1.7 +- 0.1.
  110. ! At sigma=1.59, this would translate into Dg of about 129 nm,
  111. ! or rg of about 65 nm.
  112. ! For the estimates from Kondo et al. and Schwarz et al.,
  113. ! this would give somewhat smaller rg values
  114. ! of about 58 and 53 nm, resp.
  115. !
  116. ! Particles emitted by grass and savannah fires are generally
  117. ! somewhat smaller than those from wood burning.
  118. ! Janhaell et al. estimate that the mean emission radii
  119. ! for grass and savannah fires, resp., are 12.5 and 10 nm smaller.
  120. ! These differences is not accounted for in the model.
  121. !
  122. ! In a later version of ECHAM-HAM particles the emission radius
  123. ! for biomass burning was reduced to the value for fossil fuel
  124. ! (Zhang et al., ACP, 2012).
  125. ! However, such as a small value seems inconsistent with measurements.
  126. !
  127. ! In the CMIP6 emission data set,
  128. ! the contributions from solid biofuel combustion
  129. ! are included in the 2-D anthropogenic sectors,
  130. ! and provided separately in a supplementary data set.
  131. ! In CMIP6, biofuel is only non-zero
  132. ! for the energy, industry and residential and
  133. ! transportation sectors.
  134. ! Most of the residential emissions are due
  135. ! to solid biofuel combustion.
  136. ! The contribution to the industrial sector
  137. ! is only substantial in developing countries,
  138. ! while the contributions to the energy
  139. ! and transportation sectors are generally very small.
  140. !
  141. ! For inventories other than CMIP6,
  142. ! no distinction between fossil and biofuel emissions
  143. ! is made in the model.
  144. !
  145. ! Winijkul et al. (Atm. Env., 2015) have measured
  146. ! size distributions from energy-related combustion
  147. ! sources for the residential, industrial, power and
  148. ! transportation sectors.
  149. ! They give regional and global estimates of
  150. ! mass median diameters.
  151. ! In their supplementary material they give
  152. ! an overview of results from other studies.
  153. ! These results indicate that the size distribution
  154. ! for both biofuel and fossil fuel combustion sources
  155. ! are strongly dependent on the technique.
  156. ! Count median radii for the residential sector,
  157. ! presented in their Table S1, vary between about
  158. ! 15 nm for modern (improved) wood-fueled stoves,
  159. ! and 25-30 for fireplaces,
  160. ! to 160 nm for (regular) wood-fueled heating stoves,
  161. ! to 270 nm for traditional cookstoves.
  162. ! General fossil fuel (2-d sectors)
  163. ! emitted in the Aitken mode
  164. real, parameter :: rad_emi_ff_sol = cmr_ff
  165. real, parameter :: rad_emi_ff_insol = cmr_ff
  166. ! Energy sector
  167. ! emitted in the Aitken mode.
  168. real, parameter :: rad_emi_ene_sol = cmr_ff
  169. real, parameter :: rad_emi_ene_insol = cmr_ff
  170. ! Industry sector
  171. ! emitted in the Aitken mode.
  172. real, parameter :: rad_emi_ind_sol = cmr_ff
  173. real, parameter :: rad_emi_ind_insol = cmr_ff
  174. ! Transportation sector
  175. ! emitted in the Aitken mode.
  176. real, parameter :: rad_emi_tra_sol = cmr_ff
  177. real, parameter :: rad_emi_tra_insol = cmr_ff
  178. ! Shipping sector
  179. ! emitted in the Aitken mode.
  180. ! Currently set to cmr_ff,
  181. ! but could be changed.
  182. real, parameter :: rad_emi_shp_sol = cmr_ff
  183. real, parameter :: rad_emi_shp_insol = cmr_ff
  184. ! Aircraft sector
  185. ! emitted in the Aitken mode.
  186. ! Currently set to cmr_ff,
  187. ! but a smaller value could be used,
  188. ! e.g. 10 or 15 nm.
  189. real, parameter :: rad_emi_air_sol = cmr_ff
  190. real, parameter :: rad_emi_air_insol = cmr_ff
  191. ! Open biomass burning
  192. ! Soluble part emitted in the accumulation mode,
  193. ! insoluble part in the Aitken mode.
  194. ! Stier et al. apply cmr_ff to the insoluble part,
  195. ! but a slightly larger value seems more realistic,
  196. ! e.g. 40 nm.
  197. real, parameter :: rad_emi_bb_sol = cmr_bb
  198. real, parameter :: rad_emi_bb_insol = cmr_ff
  199. ! Solid biofuel combustion
  200. ! Currently treated as biomass burning,
  201. ! but could be changed (see comments above).
  202. ! The value cmr_bb = 75 nm corresponds
  203. ! with the value of 50 nm at sigma=2
  204. ! assumed by Kondros et al. (ACP, 2015)
  205. ! for emissions from biofuel combusion
  206. ! in their baseline run.
  207. ! In one of their sensitivity runs,
  208. ! they increase it by a factor of 2.
  209. real, parameter :: rad_emi_bf_sol = cmr_bb
  210. real, parameter :: rad_emi_bf_insol = cmr_ff
  211. ! not used anymore:
  212. !real, parameter :: rad_soa = 0.01e-6 ! soa average radius
  213. ! assuming 3nm particle formation and growth to
  214. ! that size in half an hour
  215. ! Count median radii for sulfate aerosol emissions adapted to the M7 modes:
  216. real, parameter :: rad_so4_ait = cmr_sk ! aitken mode radius
  217. real, parameter :: rad_so4_acc = cmr_sa ! accumulation mode radius
  218. real, parameter :: rad_so4_coa = cmr_sc ! coarse mode radius
  219. ! Count median dry radii for sea salt emissions.
  220. ! These values have been updated
  221. ! following Vignati et al. (Atmos. Environ., 2010)
  222. ! For further explanations, see emission_ss.F90.
  223. !real, parameter :: radius_ssa = 0.0794e-6
  224. !real, parameter :: radius_ssc = 0.63e-6
  225. real, parameter :: radius_ssa = 0.09e-6 ! accumulation mode
  226. real, parameter :: radius_ssc = 0.794e-6 ! coarse mode
  227. ! Soluble fraction of POM mass
  228. ! According to Janhall et al. (ACP, 2010)
  229. ! 40 to 80% of the organic matter from
  230. ! vegetation fires is water soluble.
  231. ! Kondros et al. (ACP, 2015) use 80%
  232. ! for POM from biofuel combustion
  233. ! in their base run.
  234. ! For the moment, emisions from
  235. ! biofuel combustion and open biomass burning
  236. ! are treated in the same way.
  237. !
  238. ! open biomass burning
  239. real, parameter :: frac_pom_sol_bb = zbb_wsoc_perc
  240. ! solid biofuel combustion
  241. real, parameter :: frac_pom_sol_bf = zbb_wsoc_perc
  242. !real, parameter :: frac_pom_sol_bf = 0.8 ! alternative value
  243. ! fossil fuel combustion
  244. !real, parameter :: frac_pom_sol_ff = 0.65 ! original value
  245. real, parameter :: frac_pom_sol_ff = 0.0 ! value since 2015 revision
  246. ! Soluble fraction of BC mass
  247. ! In the original code,
  248. ! fresh BC was assumed 100% insoluble,
  249. ! and therefore emitted into the Aitken mode.
  250. ! The new code allows to use a non-zero fraction,
  251. ! to account for non-resolved ageing close to the source.
  252. ! See e.g. Kondros et al.,
  253. ! who use 50% for biofuel combustion
  254. ! in their base run.
  255. ! In the standard EMEP MSC-W model,
  256. ! 20% of the elemental carbon (EC) from
  257. ! anthropogenic sources
  258. ! (representative of fossil fuel combustion)
  259. ! and all EC from open biomass fires
  260. ! is assumed hygroscopic.
  261. !
  262. ! open biomass burning
  263. !real, parameter :: frac_bc_sol_bb = 0.0 ! original value
  264. real, parameter :: frac_bc_sol_bb = 0.5
  265. ! solid biofuel combustion
  266. !real, parameter :: frac_bc_sol_bf = 0.0 ! original value
  267. real, parameter :: frac_bc_sol_bf = 0.5
  268. ! fossil fuel combustion
  269. real, parameter :: frac_bc_sol_ff = 0.0
  270. ! Soluble fraction of surrogate SOA emissions
  271. ! POM from SOA is considered 65% soluble,
  272. ! as recommended by AeroCom.
  273. ! The paper by Kanakidou et al. (ACP, 2004)
  274. ! (mentioned in emission_pom.F90)
  275. ! does not seem to support 100% solubility,
  276. ! as was previously assumed.
  277. !real, parameter :: frac_soa_sol = 1.0 ! original value
  278. real, parameter :: frac_soa_sol = zbge_wsoc_perc ! value since 2015 revision
  279. ! Fraction of SOx mass emitted directly as sulfate
  280. real, parameter :: frac_so4=1.-facso2
  281. #else
  282. real, parameter :: frac_so4=1.-0.975
  283. #endif
  284. #ifdef with_m7
  285. ! The value of 1.4 for the POM to OC mass ratio,
  286. ! set in mo_aero.F90, is an outdated estimate,
  287. ! see e.g. Turpin and Lim (Aerosol Sci. Technol., 2001) and
  288. ! Aiken et al. (Environ. Sci. Technol., 2008).
  289. ! Turpin and Lim estimate a ratio of 1.6 +- 0.2 for urban aerosol,
  290. ! and 2.1 +- 0.2 for aged (nonurban) aerosol;
  291. ! They also note that aerosols heavily impacted by woodsmoke can
  292. ! have an even higher ratio (2.2 to 2.6).
  293. ! According to Reid et al. (ACP, 2005),
  294. ! the POM to OC ratio in fresh biomass burning smoke is very uncertain,
  295. ! somewhere in between 1.4 and ~2.
  296. ! Aiken et al. measure ambient aerosol values
  297. ! between 1.25 for O/C = 0 to 2.44 for O/C = 1.0.
  298. ! For OA from biomass burning, they measure 1.56-1.70,
  299. ! lower than the estimates from Turpin and Lim (~2.0).
  300. ! They find the highest ratios for
  301. ! aged and freshly formed SOA (~2.4 and ~1.9, respectively)
  302. ! and lowest values for primary OA from urban combustion.
  303. ! Based on these studies, we apply different values
  304. ! for emissions from biomass burning versus other emissions,
  305. ! as is also done in some other models
  306. ! (see Table 1 in Tsigaridis et al., ACP, 2014),
  307. ! For SOA (seem emission_pom.F90)
  308. ! we apply a relatively high value valid for aged SOA.
  309. ! This compensates for the lack of SOA formation from isoprene,
  310. ! and improves the agreement with aerosol optical depth (AOD)
  311. ! derived from satellite observations (MODIS).
  312. !
  313. ! We could go even further and apply different values for the
  314. ! water soluble and insoluble fractions (Turpin and Lim).
  315. !
  316. ! It should be acknowledged that the representation of OA
  317. ! with a single tracer is very simplistic.
  318. ! In particular, increase in OA mass due to ageing
  319. ! is not properly accounted for.
  320. !
  321. !real, parameter :: oc2pom = zom2oc !factor for conversion of OC mass to POM
  322. real, parameter :: oc2pom_ff = 1.6 ! fossil fuel
  323. real, parameter :: oc2pom_bf = 1.6 ! solid biofuel combustion
  324. real, parameter :: oc2pom_bb = 1.6 ! open biomass burning
  325. real, parameter :: oc2pom_soa = 2.4 ! SOA
  326. #endif
  327. ! CMIP6 - AR5 - EDGAR4 - RETRO - GFED3 - MACC - LPJ - HYMN - MEGAN
  328. logical :: LCMIP6, LCMIP6BMB, LCMIP6_CH4
  329. logical :: LAR5, LAR5BMB, LEDGAR4, LRETROF, LGFED3, LMACC, LLPJ, LHYMN, LMACCITY, LMEGAN
  330. character(len=256) :: cmip6_ch4_dirname
  331. character(len=256) :: emis_input_dir
  332. character(len=256) :: emis_input_dir_cmip6
  333. character(len=256) :: emis_input_dir_ar5
  334. character(len=256) :: emis_input_dir_megan
  335. character(len=256) :: emis_input_dir_ed4
  336. character(len=256) :: emis_input_dir_mac
  337. integer :: emis_input_year_nat
  338. integer :: emis_input_year_bc
  339. integer :: emis_input_year_oc
  340. integer :: emis_input_year_sox
  341. integer :: emis_input_year_nh3
  342. integer :: emis_input_year_nox
  343. integer :: emis_input_year_co
  344. integer :: emis_input_year_nmvoc
  345. integer :: emis_input_year_ch4
  346. character(len=256) :: emis_input_dir_gfed
  347. character(len=256) :: emis_input_dir_retro
  348. character(len=256) :: emis_input_dir_aerocom
  349. character(len=256) :: emis_input_dir_dms
  350. character(len=256) :: emis_input_dir_rn222
  351. character(len=256) :: emis_input_dir_dust, emis_input_dust
  352. #ifdef with_ch4_emis
  353. character(len=256) :: emis_input_dir_natch4
  354. #endif
  355. logical :: emis_ch4_single
  356. logical :: emis_ch4_fix3d
  357. real :: emis_ch4_fixed_ppb
  358. character(len=256) :: emis_zch4_fname
  359. logical :: ch4_fixyear
  360. integer :: ch4_year
  361. ! biomass burning levels:
  362. integer, parameter :: bb_nlev = 5
  363. integer, parameter :: bb_lm = lm(1) ! to be reduced to strip stratosphere!
  364. integer, parameter :: bl_lm = lm(1) ! to be reduced to the BL (around 8)
  365. real, parameter :: bb_hlow (0:bb_nlev) = (/ 0., 100., 500., 1000., 2000., 3000./)
  366. real, parameter :: bb_hhigh(0:bb_nlev) = (/ 100., 500., 1000., 2000., 3000., 6000./)
  367. ! biomass burning levels in tropics (-20 - 20)::
  368. integer, parameter :: bb_nlev_trop = 3
  369. real, parameter :: bb_hlow_trop (0:bb_nlev_trop) = (/ 0., 100., 500., 1000./)
  370. real, parameter :: bb_hhigh_trop(0:bb_nlev_trop) = (/ 100., 500., 1000., 2000./)
  371. ! -----------------------------------------------------------------------------------
  372. ! Biomassburning time splitting factors (now globally, instead of by constituent)
  373. logical :: emis_bb_trop_cycle
  374. type bb_cycle_data
  375. real, pointer :: scalef(:)
  376. end type bb_cycle_data
  377. type(bb_cycle_data), dimension(nregions), target :: bb_cycle
  378. ! -----------------------------------------------------------------------------------
  379. ! Budgets
  380. #ifdef with_budgets
  381. real, dimension(nregions) :: sum_emission
  382. type budemi_data
  383. real,dimension(:,:,:,:),pointer :: emi ! [i, j, nbud_vg, ntracet]
  384. end type budemi_data
  385. type(budemi_data),dimension(nregions),target :: budemi_dat
  386. #endif
  387. logical :: use_tiedkte ! read from rc file, used to scale LiNOx
  388. ! ----------------------------------------------------
  389. ! Vertical splitting : used now for all sectors, for biomassburning and other categories
  390. ! (tables in Dentener, 2006, ACP)
  391. !
  392. ! ATTENTION: changes here have impact on the routine emission_vdist_by_sector (contained)
  393. ! Note: vdist_* variable could be hold private
  394. !
  395. integer, parameter :: vd_class_name_len = 12
  396. ! biomassburning
  397. integer, parameter :: vdist_bb_nlev = 6
  398. real,dimension(vdist_bb_nlev),parameter :: vdist_bb_hlow = (/ 0., 100., 500., 1000., 2000., 3000./)
  399. real,dimension(vdist_bb_nlev),parameter :: vdist_bb_hhigh = (/ 100., 500., 1000., 2000., 3000., 6000./)
  400. ! other sources (related to surface)
  401. integer, parameter :: vdist_nn_nlev = 6
  402. real,dimension(vdist_nn_nlev),parameter :: vdist_nn_hlow = (/ 0., 30. , 100., 300., 600., 1000. /)
  403. real,dimension(vdist_nn_nlev),parameter :: vdist_nn_hhigh = (/ 30., 100., 300., 600., 1000., 2000. /)
  404. !
  405. ! !PRIVATE TYPES:
  406. !
  407. character(len=*), parameter, private :: mname = 'emission_data'
  408. !
  409. ! !REVISION HISTORY:
  410. ! 1 Oct 2010 - Achim Strunk - adapted for AR5
  411. ! 28 Jun 2012 - Ph. Le Sager - made everything public by default
  412. ! - adapted for lon-lat MPI domain decomposition
  413. ! !REMARKS:
  414. !
  415. !EOP
  416. !------------------------------------------------------------------------
  417. CONTAINS
  418. !--------------------------------------------------------------------------
  419. ! TM5 !
  420. !--------------------------------------------------------------------------
  421. !BOP
  422. !
  423. ! !IROUTINE: EMISSION_VDIST_BY_SECTOR
  424. !
  425. ! !DESCRIPTION: Return vertically distributed emissions depending on given
  426. ! sector and constituent.
  427. ! Distribution is done as 'compromise' between
  428. ! 1) Dentener et al., 2006, ACP, slightly modified for
  429. ! emissions supposed to enter the surface layer.
  430. ! 2) De Meij et al., ACP, 2006
  431. ! 3) EMEP model (docu, model code, publications)
  432. ! 4) Bieser et al., GMDD, 2010
  433. ! 5) Small updates to biomassburning following
  434. ! Huijnen et al., GMDD, 2010
  435. !\\
  436. !\\
  437. ! !INTERFACE:
  438. !
  439. SUBROUTINE EMISSION_VDIST_BY_SECTOR( splitname, constituent, region, emis2D, emis3D, status )
  440. !
  441. ! !USES:
  442. !
  443. use toolbox, only : distribute_emis2D
  444. !
  445. ! !INPUT PARAMETERS:
  446. !
  447. character(len=vd_class_name_len), intent(in) :: splitname
  448. character(len=*), intent(in) :: constituent
  449. integer, intent(in) :: region
  450. type(emis_data), intent(in) :: emis2D
  451. !
  452. ! !INPUT/OUTPUT PARAMETERS:
  453. !
  454. type(d3_data), intent(inout) :: emis3D
  455. !
  456. ! !OUTPUT PARAMETERS:
  457. !
  458. integer, intent(out) :: status
  459. !
  460. ! !REVISION HISTORY:
  461. ! 1 Oct 2010 - Achim Strunk - v0
  462. !
  463. ! !REMARKS: Splitting depending on constituent is still to code.
  464. !
  465. !EOP
  466. !------------------------------------------------------------------------
  467. !BOC
  468. character(len=*), parameter :: rname = mname//'/emission_vdist_by_sector'
  469. integer :: ilev
  470. character(len=2) :: splittype
  471. integer, parameter :: maxvdist_nlev = max(vdist_bb_nlev,vdist_nn_nlev)
  472. real, dimension(maxvdist_nlev) :: sfglobal, sfintrop, sfintemp
  473. ! --- begin --------------------------------------
  474. ! control implicit settings here in this routine
  475. if( vdist_bb_nlev /= 6 .or. vdist_nn_nlev /= 6 ) then
  476. write(gol, '("ERROR: wrong number of layers: bb_nlev /= 6 or nn_lev /= 6")'); call goErr
  477. status=1; return
  478. end if
  479. ! initialise
  480. sfglobal = 0.0
  481. sfintrop = 0.0
  482. sfintemp = 0.0
  483. ! -------------------------------------------------
  484. ! This here is selection by emission source sectors
  485. ! -------------------------------------------------
  486. select case( trim(splitname) )
  487. case( 'combenergy' )
  488. ! Combustion from energy production and transformation, power-plants
  489. ! no zonal differences, no dependency on species
  490. ! --
  491. ! assumed to be related to EMEP SNAP category [1]
  492. ! AEROCOM equivalent: power-plants
  493. ! --
  494. splittype = 'nn'
  495. sfglobal = (/ 0.0, 0.1, 0.7, 0.2, 0.0, 0.0 /)
  496. case( 'combrescom' )
  497. ! Residential and commercial combustion
  498. ! no zonal differences, no dependency on species
  499. ! --
  500. ! assumed to be related to EMEP SNAP category [2]
  501. ! AEROCOM equivalent: domestic/industry
  502. ! --
  503. splittype = 'nn'
  504. sfglobal = (/ 0.4, 0.4, 0.2, 0.0, 0.0, 0.0 /)
  505. case( 'industry' )
  506. ! Industrial processes and combustion
  507. ! no zonal differences, no dependency on species
  508. ! --
  509. ! assumed to be an aggregate of EMEP SNAP categories [3,4,5]
  510. ! AEROCOM equivalent: industry
  511. ! --
  512. splittype = 'nn'
  513. sfglobal = (/ 0.1, 0.2, 0.6, 0.1, 0.0, 0.0 /)
  514. case( 'waste' )
  515. ! Waste treatment and disposal
  516. ! no zonal differences, no dependency on species
  517. ! --
  518. ! assumed to be related to EMEP SNAP category [9]
  519. ! AEROCOM equivalent: -
  520. ! --
  521. splittype = 'nn'
  522. sfglobal = (/ 0.1, 0.2, 0.4, 0.3, 0.0, 0.0 /)
  523. case( 'nearsurface' )
  524. ! Near surface emissions
  525. ! no zonal differences, no dependency on species
  526. ! --
  527. ! AR5: solvent production and use, agricultural waste burning, &
  528. ! ships, grassland fire, mineral dust (AEROCOM or Tegen-Vignati)
  529. ! EMEP equivalents: SNAP categories [6,8]
  530. ! AEROCOM equivalents: ships, agricultural waste
  531. ! --
  532. splittype = 'nn'
  533. sfglobal = (/ 0.8, 0.2, 0.0, 0.0, 0.0, 0.0 /)
  534. case( 'surface' )
  535. ! Surface emissions
  536. ! no zonal differences, no dependency on species
  537. ! --
  538. ! AR5: agriculture, transport, soil, oceanic, biogenic
  539. ! EMEP equivalents: SNAP categories [7,8,10]
  540. ! AEROCOM equivalents: surface emissions from road/off-road, ships, agricultural waste
  541. ! --
  542. splittype = 'nn'
  543. sfglobal = (/ 1.0, 0.0, 0.0, 0.0, 0.0, 0.0 /)
  544. !!$ case ( 'mindust' )
  545. !!$ ! Mineral dust emissions
  546. !!$ ! no zonal differences
  547. !!$ ! --
  548. !!$ ! AR5: surface dust emissions from either from AEROCOM or Tegen-Vignati
  549. !!$ ! assumed to be slightly higher than near-surface
  550. !!$ splittype = 'nn'
  551. !!$ sfglobal = (/ 0.8, 0.2, 0.0, 0.0, 0.0, 0.0 /)
  552. case( 'volcanic' )
  553. ! Volcanic emissions
  554. ! --
  555. ! AR5: natural SOx emissions (from MACC repository)
  556. ! EMEP equivalents: SNAP categories [11]
  557. ! AEROCOM equivalents: continuous: 2/3 to 1 of height of volcano top
  558. ! explosive: 0.5 to 1.5 km above volcano top
  559. ! Since no data is available about volcano top levels, we assume here, that
  560. ! a volcano top is usually 200-1000 m higher than the grid's surrounding terrain
  561. ! height, thus emissions are distributed from 100 - 2000 m almost homogeneously
  562. ! --
  563. splittype = 'nn'
  564. sfglobal = (/ 0.0, 0.0, 0.1, 0.3, 0.4, 0.2 /)
  565. case( 'forestfire' )
  566. ! forest fires: 6 layer model, different splitting for different regions
  567. ! dont distinguish between boreal Europe and boreal Canada, use Europe globally
  568. ! Dentener et al., modified in tropics (up to 2 km) with respect to Huijnen et al., GMD 2010, \
  569. ! who are citing Labonne et al., 2007 ofr new information based on satellite data.
  570. splittype = 'bb'
  571. sfglobal = (/ 0.1, 0.1, 0.2, 0.2, 0.4, 0.0 /)
  572. sfintemp = (/ 0.2, 0.2, 0.2, 0.4, 0.0, 0.0 /)
  573. sfintrop = (/ 0.2, 0.2, 0.2, 0.4, 0.0, 0.0 /)
  574. case default
  575. write(gol, '("ERROR: wrong specification of emission sector ",a,"in vdist_by_sector called for constituent ",a)') &
  576. trim(splitname), trim(constituent); call goErr
  577. status=1; return
  578. end select
  579. ! --------------------
  580. ! Do the splitting -
  581. ! no need to skip cases of fraction (sfglobal, sfintemp, ..) being zero:
  582. ! distribute_emis2D is optimized for those and will return right away
  583. ! --------------------
  584. select case( splittype )
  585. case( 'nn' )
  586. do ilev = 1, vdist_nn_nlev
  587. call distribute_emis2D( region, emis2D, emis3D, vdist_nn_hlow(ilev), vdist_nn_hhigh(ilev), status, sfglobal(ilev) )
  588. IF_NOTOK_RETURN(status=1)
  589. end do
  590. case( 'bb' )
  591. do ilev = 1, vdist_bb_nlev
  592. ! boreal
  593. call distribute_emis2D( region, emis2D, emis3D, vdist_bb_hlow(ilev), vdist_bb_hhigh(ilev), status, &
  594. sfglobal(ilev), -90.,-61.)
  595. IF_NOTOK_RETURN(status=1)
  596. call distribute_emis2D( region, emis2D, emis3D, vdist_bb_hlow(ilev), vdist_bb_hhigh(ilev), status, &
  597. sfglobal(ilev), 60., 90.)
  598. IF_NOTOK_RETURN(status=1)
  599. ! temperate
  600. call distribute_emis2D( region, emis2D, emis3D, vdist_bb_hlow(ilev), vdist_bb_hhigh(ilev), status, &
  601. sfintemp(ilev), -60.,-31.)
  602. IF_NOTOK_RETURN(status=1)
  603. call distribute_emis2D( region, emis2D, emis3D, vdist_bb_hlow(ilev), vdist_bb_hhigh(ilev), status, &
  604. sfintemp(ilev), 30., 59.)
  605. IF_NOTOK_RETURN(status=1)
  606. ! tropics
  607. call distribute_emis2D( region, emis2D, emis3D, vdist_bb_hlow(ilev), vdist_bb_hhigh(ilev), status, &
  608. sfintrop(ilev), -30., 29.)
  609. IF_NOTOK_RETURN(status=1)
  610. end do
  611. case default
  612. write(gol, '("ERROR: wrong specification of splitting type in vdist_by_sector.")'); call goErr
  613. status=1; return
  614. end select
  615. ! OK
  616. status=0
  617. END SUBROUTINE EMISSION_VDIST_BY_SECTOR
  618. !EOC
  619. !--------------------------------------------------------------------------
  620. ! TM5 !
  621. !--------------------------------------------------------------------------
  622. !BOP
  623. !
  624. ! !IROUTINE: MSG_EMIS
  625. !
  626. ! !DESCRIPTION: Provide output to verify the amount of emissions
  627. ! entering the calculations
  628. !\\
  629. !\\
  630. ! !INTERFACE:
  631. !
  632. SUBROUTINE MSG_EMIS(year_month, provider, sector, msg_comp, msg_mass, summed_emissions)
  633. !
  634. ! !USES:
  635. !
  636. use dims, only: idate
  637. !
  638. ! !INPUT PARAMETERS:
  639. !
  640. integer, intent(in) :: year_month ! 1: year, 2: monthly amount
  641. character(len=*), intent(in) :: provider, sector, msg_comp
  642. real, intent(in) :: msg_mass, summed_emissions
  643. !
  644. ! !REVISION HISTORY:
  645. ! 1 Oct 2010 - Achim Strunk - protex; increase space for output
  646. !
  647. !EOP
  648. !------------------------------------------------------------------------
  649. !BOC
  650. character(len=7),dimension(2), parameter:: ym=(/'Yearly ','Monthly'/)
  651. 1111 format(' EMISS-INFO - ',a7,' Emission from ',a8,' -> ',a18,1x,a6,' : mw=',f5.1,', month=',i2.2,', Sum [kg]=',1x,1pe11.4)
  652. 1112 format(' EMISS-INFO - ',a7,' Emission from ',a8,' -> ',a18,1x,a6,' : mw=',f5.1,', --------, Sum [kg]=',1x,1pe11.4)
  653. if (year_month==1) then
  654. write (gol,1112) ym(year_month), provider, sector, msg_comp, msg_mass, summed_emissions; call goPr
  655. else
  656. write (gol,1111) ym(year_month), provider, sector, msg_comp, msg_mass, idate(2), summed_emissions; call goPr
  657. endif
  658. END SUBROUTINE MSG_EMIS
  659. !EOC
  660. !--------------------------------------------------------------------------
  661. ! TM5 !
  662. !--------------------------------------------------------------------------
  663. !BOP
  664. !
  665. ! !IROUTINE: SCALE_CYCLE
  666. !
  667. ! !DESCRIPTION: Evaluates a daily cycle to be used for the biomass
  668. ! burning emissions. It is based on the isoprene daily
  669. ! cycle, except that the max peak is at 14:00h LT.
  670. ! Calculates factors to be multiplied with an
  671. ! emission field (e.g. co) in order to simulate a
  672. ! diurnal cycle in emissions (caused by solar dependency/
  673. ! human activity), e.g.
  674. ! rm(i,j,1,isop) = rm(i,j,1,isop) + e_isop(i,j)*scalef(ipos,j)*dt
  675. ! with ipos depending on time and longitude.
  676. ! The scalefactor is calculated for -180 longitude and
  677. ! the mean value for ntim timesteps during a day is scaled
  678. ! to 1.
  679. ! The routine should be called only once, since
  680. ! the position relative to the sun is not relevant here.
  681. !\\
  682. !\\
  683. ! !INTERFACE:
  684. !
  685. SUBROUTINE SCALE_CYCLE(ntim, scalef)
  686. !
  687. ! !INPUT PARAMETERS:
  688. !
  689. integer, intent(in) :: ntim
  690. !
  691. ! !OUTPUT PARAMETERS:
  692. !
  693. real, dimension(ntim), intent(out) :: scalef
  694. !
  695. ! !REVISION HISTORY:
  696. ! 1 Oct 2010 - Achim Strunk - added without_diurnal_emission_cycle
  697. ! (to be removed again :-( )
  698. ! 19 Oct 2010 - Narcisa Banda - changed without_diurnal_emission_cycle to with_....
  699. ! 31 Jan 2013 - Ph. Le Sager - get rid of with_diurnal_emission_cycle!
  700. !
  701. ! !REMARKS:
  702. ! - This routine is called only once (see emission.F90), and only if
  703. ! emis_bb_trop_cycle is .true.. The later is set with the
  704. ! input.emis.bb.dailycycle in the rc file (chem.input.rc)
  705. !
  706. !EOP
  707. !------------------------------------------------------------------------
  708. !BOC
  709. real :: pi, piby, obliq, deday, delta, dt, lon, hr, lat, houra, smm, w, sig
  710. integer :: i
  711. ! The calling routine (emission_declare) defines NTIM as follows:
  712. ! dtime=float(ndyn_max)/(2*tref(region)) ! timestep emissions
  713. ! ntim=86400/nint(dtime) ! number of timesteps in 24 hours.
  714. pi = acos(-1.0)
  715. piby = pi/180.0
  716. ! obliq = 23.45 * piby
  717. w = 0.2
  718. sig = 2.0
  719. dt = 24./ntim !timestep in hours
  720. lon = -180.0*piby !calculate for dateline
  721. hr = - 0.5*dt !shift half an interval back
  722. if (hr .gt. 12) hr = hr - 24
  723. ! hr = hr - 2 !shift two hours. This means that Local-day-time maximum will be at 14:00 h LT.
  724. smm = 0.0
  725. do i=1,ntim
  726. hr = hr + dt
  727. houra = lon - pi + hr * (2.*pi/24.)
  728. scalef(i) = w + (1-w)*24.0/(sig*sqrt(2*pi))*exp(-0.5*(((hr-1.5)/sig)**2))
  729. ! scalef(i) = max(1+(cos(houra)),0.0)
  730. smm = smm+scalef(i)/ntim
  731. end do
  732. if ( smm > 1e-5 ) then
  733. scalef(1:ntim) = scalef(1:ntim)/smm
  734. else
  735. scalef(1:ntim) = 1.0
  736. end if
  737. END SUBROUTINE SCALE_CYCLE
  738. !EOC
  739. !--------------------------------------------------------------------------
  740. ! TM5 !
  741. !--------------------------------------------------------------------------
  742. !BOP
  743. !
  744. ! !IROUTINE: DO_ADD_2D
  745. !
  746. ! !DESCRIPTION: General routine to add a 2D emission field (given in kg
  747. ! /month) into tracer mass array. The mass increase is done
  748. ! at level L_LEVEL, and for tracer I_TRACER.
  749. !
  750. ! Update accordingly the budget.
  751. !\\
  752. !\\
  753. ! !INTERFACE:
  754. !
  755. SUBROUTINE DO_ADD_2D( region, i_tracer, l_level, is, js, emis_field, &
  756. mol_mass, mol_mass_e, status, xfrac )
  757. !
  758. ! !USES:
  759. !
  760. use dims, only : CheckShape, tref, nsrce
  761. use dims, only : sec_month, im, jm, okdebug
  762. use global_data, only : mass_dat, region_dat
  763. use chem_param, only : ntracet, names
  764. use tm5_distgrid, only : get_distgrid, dgrid
  765. #ifdef with_budgets
  766. use budget_global, only : budg_dat, nzon_vg
  767. #endif
  768. !
  769. ! !INPUT PARAMETERS:
  770. !
  771. integer, intent(in) :: region
  772. integer, intent(in) :: i_tracer
  773. integer, intent(in) :: l_level
  774. integer, intent(in) :: is, js
  775. real, intent(in) :: emis_field(is:,js:)
  776. real, intent(in) :: mol_mass ! mol mass of tracer field
  777. real, intent(in) :: mol_mass_e ! mol mass of emission field (e.g. NOx emission ar in kgN/month)
  778. real, intent(in), optional :: xfrac ! partial addition
  779. !
  780. ! !OUTPUT PARAMETERS:
  781. !
  782. integer, intent(out) :: status
  783. !
  784. ! !REVISION HISTORY:
  785. ! 27 Mar 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  786. !
  787. !EOP
  788. !------------------------------------------------------------------------
  789. !BOC
  790. character(len=*), parameter :: rname = mname//'/do_add_2d'
  791. integer :: i, j, nzone, nzone_v, i1, i2, j1, j2
  792. real :: x, efrac, dtime, month2dt
  793. real :: mbef, maft, sume ! mass BEFore, AFTer, SUM Emiss (debug)
  794. real, dimension(:,:,:,:), pointer :: rm, rzm
  795. ! --- begin --------------------------------------
  796. call GET_DISTGRID( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  797. call CheckShape( (/i2-i1+1,j2-j1+1/), shape(emis_field), status )
  798. IF_NOTOK_RETURN(status=1)
  799. dtime=float(nsrce)/(2*tref(region)) ! timestep emissions
  800. month2dt=dtime/sec_month ! conversion to emission per timestep
  801. rm => mass_dat(region)%rm
  802. rzm => mass_dat(region)%rzm
  803. if(present(xfrac)) then
  804. efrac = xfrac
  805. else
  806. efrac = 1.0
  807. endif
  808. if (okdebug) then
  809. write (gol, '("--------------------------------------------------------------")') ; call goPr
  810. write (gol, '(" DO ADD 2D debug in region:",i3) ' ) region ; call goPr
  811. write (gol, '(" itracer :",i3,a8)' ) i_tracer, ' :'//names(i_tracer) ; call goPr
  812. write (gol, '(" xfrac :",f6.1)' ) efrac ; call goPr
  813. write (gol, '(" mol_mass :",f6.1 ) ' ) mol_mass ; call goPr
  814. write (gol, '(" mol_mass_e :",f6.1 )' ) mol_mass_e ; call goPr
  815. write (gol, '(" emisfield :",2e12.4 )') minval(emis_field),maxval(emis_field) ; call goPr
  816. sume = sum(emis_field)*month2dt*(mol_mass/mol_mass_e)*efrac
  817. write (gol, '(" sum emmis :",e12.4 )' ) sume ; call goPr
  818. mbef = sum(rm(i1:i2,j1:j2,:,i_tracer))
  819. endif
  820. do j=j1,j2
  821. do i=i1,i2
  822. x = emis_field(i,j)*month2dt*(mol_mass/mol_mass_e)*efrac
  823. rm(i,j,l_level,i_tracer) = rm(i,j,l_level,i_tracer) + x
  824. #ifdef slopes
  825. ! injection of emissions at surface, thus vertical slope more negative
  826. ! (keep concentration at top of layer the same as before emission)
  827. if ( i_tracer <= ntracet ) then
  828. rzm(i,j,l_level,i_tracer) = rzm(i,j,l_level,i_tracer) - x
  829. end if
  830. #endif
  831. #ifdef with_budgets
  832. nzone = budg_dat(region)%nzong(i,j) !global budget
  833. nzone_v = nzon_vg(l_level)
  834. #ifndef without_emission
  835. budemi_dat(region)%emi(i,j,nzone_v,i_tracer) = &
  836. budemi_dat(region)%emi(i,j,nzone_v,i_tracer) + x/mol_mass*1e3
  837. if(i_tracer == 1) sum_emission(region) = sum_emission(region) + x !in kg
  838. #endif
  839. #endif
  840. enddo
  841. enddo
  842. if (okdebug) then
  843. maft = sum(rm(i1:i2,j1:j2,:,i_tracer))
  844. write (gol, '(" Added amount :",e12.4 )' ) maft-mbef ; call goPr
  845. write (gol, '(" Added amount can be different when inner zoom is present!" )' ) ; call goPr
  846. if (maft-mbef-sume > 1e-8*sume) then
  847. write (gol, '(" Warning: error in emission ")' ) ; call goErr
  848. endif
  849. endif
  850. nullify(rm)
  851. nullify(rzm)
  852. status=0
  853. END SUBROUTINE DO_ADD_2D
  854. !EOC
  855. !--------------------------------------------------------------------------
  856. ! TM5 !
  857. !--------------------------------------------------------------------------
  858. !BOP
  859. !
  860. ! !IROUTINE: DO_ADD_3D
  861. !
  862. ! !DESCRIPTION: General routine to add a 3D emission field (given in kg
  863. ! /month) into tracer mass array. The mass increase is done
  864. ! for tracer I_TRACER.
  865. !
  866. ! Update accordingly the budget.
  867. !\\
  868. !\\
  869. ! !INTERFACE:
  870. !
  871. SUBROUTINE DO_ADD_3D( region, i_tracer, is, js, emis_field, mol_mass, mol_mass_e, status, xfrac)
  872. !
  873. ! !USES:
  874. !
  875. use dims, only : CheckShape, nsrce, tref
  876. use dims, only : sec_month, im, jm, lm, okdebug
  877. use global_data, only : mass_dat, region_dat
  878. use chem_param, only : ntracet, names
  879. use tm5_distgrid, only : get_distgrid, dgrid
  880. #ifdef with_budgets
  881. use budget_global, only : budg_dat, nzon_vg
  882. #endif
  883. !
  884. ! !INPUT PARAMETERS:
  885. !
  886. integer, intent(in) :: region ! region #
  887. integer, intent(in) :: i_tracer ! id of tracer to increase
  888. integer, intent(in) :: is, js
  889. real, intent(in) :: emis_field(is:,js:,:)
  890. real, intent(in) :: mol_mass, mol_mass_e
  891. real, intent(in), optional :: xfrac !partial addition
  892. !
  893. ! !OUTPUT PARAMETERS:
  894. !
  895. integer, intent(out) :: status
  896. !
  897. ! !REVISION HISTORY:
  898. ! 27 Mar 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  899. !
  900. !EOP
  901. !------------------------------------------------------------------------
  902. !BOC
  903. character(len=*), parameter :: rname = mname//'/do_add_3d'
  904. integer :: i, j, l, nzone, nzone_v, i1,j1,i2,j2
  905. integer, dimension(3) :: ubound_e
  906. real :: x, efrac, dtime, month2dt
  907. real, dimension(:,:,:,:), pointer :: rm
  908. real :: mbef, maft, sume ! debug
  909. ! --- begin --------------------------------------
  910. call GET_DISTGRID( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  911. status = 0
  912. ! check arguments
  913. ubound_e = ubound(emis_field)
  914. if(ubound_e(1) /= i2) then
  915. write(gol,'(A)') 'do_add_3d: im emission not consistent' ; call goPr
  916. status = 1
  917. endif
  918. if(ubound_e(2) /= j2) then
  919. write(gol,'(A)') 'do_add_3d: jm emission not consistent' ; call goPr
  920. status = 1
  921. endif
  922. if(ubound_e(3) > lm(region)) then
  923. write(gol,'(A)') 'do_add_3d: lm emission not consistent' ; call goPr
  924. status = 1
  925. endif
  926. IF_NOTOK_RETURN(status=1)
  927. rm => mass_dat(region)%rm
  928. dtime=float(nsrce)/(2*tref(region)) ! timestep emissions
  929. month2dt=dtime/sec_month ! conversion to emission per timestep
  930. if(present(xfrac)) then
  931. efrac = xfrac
  932. else
  933. efrac = 1.0
  934. endif
  935. ! if (okdebug) then
  936. ! write (gol, '("--------------------------------------------------------------")') ; call goPr
  937. ! write (gol, '(" DO ADD 3D debug in region:",i3) ' ) region ; call goPr
  938. ! write (gol, '(" itracer :",i3,a8)' ) i_tracer, ' :'//names(i_tracer) ; call goPr
  939. ! write (gol, '(" xfrac :",f6.1)' ) efrac ; call goPr
  940. ! write (gol, '(" mol_mass :",f6.1 ) ' ) mol_mass ; call goPr
  941. ! write (gol, '(" mol_mass_e :",f6.1 )' ) mol_mass_e ; call goPr
  942. ! write (gol, '(" emisfield :",2e12.4 )') minval(emis_field), maxval(emis_field) ; call goPr
  943. ! write (gol, '(" ubound(3) :",i3 )' ) ubound_e(3) ; call goPr
  944. ! sume = sum(emis_field)*month2dt*(mol_mass/mol_mass_e)*efrac
  945. ! write (gol, '(" sume :", e12.4 )') sume ; call goPr
  946. ! mbef = sum(rm(i1:i2,j1:j2,:,i_tracer))
  947. ! endif
  948. do l=1,ubound_e(3)
  949. do j=j1,j2
  950. do i=i1,i2
  951. x = emis_field(i,j,l)*month2dt*(mol_mass/mol_mass_e)*efrac
  952. rm(i,j,l,i_tracer) = rm(i,j,l,i_tracer) + x
  953. #ifdef with_budgets
  954. ! budget___
  955. nzone=budg_dat(region)%nzong(i,j) !global budget
  956. nzone_v=nzon_vg(l)
  957. #ifndef without_emission
  958. budemi_dat(region)%emi(i,j,nzone_v,i_tracer) = &
  959. budemi_dat(region)%emi(i,j,nzone_v,i_tracer) + x/mol_mass*1e3
  960. if(i_tracer ==1) sum_emission(region) = sum_emission(region) + x !in kg
  961. #endif
  962. #endif
  963. enddo
  964. enddo
  965. enddo !levels
  966. ! if (okdebug) then
  967. ! maft = sum(rm(i1:i2,j1:j2,:,i_tracer))
  968. ! write (gol, '(" after-before :", e12.4 )' ) maft-mbef ; call goPr
  969. ! write (gol, '(" END debug output ")' ) ; call goPr
  970. ! endif
  971. nullify(rm)
  972. END SUBROUTINE DO_ADD_3D
  973. !EOC
  974. !--------------------------------------------------------------------------
  975. ! TM5 !
  976. !--------------------------------------------------------------------------
  977. !BOP
  978. !
  979. ! !IROUTINE: DO_ADD_3D_CYCLE
  980. !
  981. ! !DESCRIPTION: Routine to add a 3D emission field (given in kg/month),
  982. ! scaled with a daily cycle. To be used for biomass burning
  983. ! emissions.
  984. !\\
  985. !\\
  986. ! !INTERFACE:
  987. !
  988. SUBROUTINE DO_ADD_3D_CYCLE( region, i_tracer, is, js, emis_field, curr_cycle, mol_mass, mol_mass_e, status, xfrac)
  989. !
  990. ! !USES:
  991. !
  992. use dims, only : CheckShape, tref, nsrce, itaur
  993. use dims, only : sec_month, im,jm,lm, okdebug
  994. use dims, only : ndyn_max,dx, xref, xbeg,dy,yref,ybeg
  995. use global_data, only : mass_dat, region_dat
  996. use chem_param, only : ntracet, names
  997. use tm5_distgrid, only : get_distgrid, dgrid
  998. #ifdef with_budgets
  999. use budget_global, only : budg_dat, nzon_vg
  1000. #endif
  1001. use datetime, only : tau2date
  1002. use toolbox, only : dumpfield
  1003. !
  1004. ! !INPUT PARAMETERS:
  1005. !
  1006. integer, intent(in) :: region
  1007. integer, intent(in) :: i_tracer
  1008. integer, intent(in) :: is, js
  1009. real, intent(in) :: emis_field(is:,js:,:)
  1010. real, dimension(:), intent(in) :: curr_cycle
  1011. real, intent(in) :: mol_mass ! first is the mass of tracer field
  1012. real, intent(in) :: mol_mass_e ! mass of emission field (e.g. NOx emission ar in kgN/month)
  1013. real, intent(in), optional :: xfrac ! partial addition
  1014. !
  1015. ! !OUTPUT PARAMETERS:
  1016. !
  1017. integer, intent(out) :: status
  1018. !
  1019. ! !REVISION HISTORY:
  1020. ! 1 Oct 2010 - Achim Strunk - v0 based on do_add_3d
  1021. ! 20 Jun 2012 - Ph. Le Sager - adapted for lon-lat MPI domain decomposition
  1022. !
  1023. ! !REMARKS:
  1024. !
  1025. !EOP
  1026. !------------------------------------------------------------------------
  1027. !BOC
  1028. character(len=*), parameter :: rname = mname//'/do_add_3d_cycle'
  1029. integer :: i, j, l, ipos, nzone, nzone_v
  1030. integer,dimension(6) :: idater
  1031. integer :: sec_in_day, ntim, itim, i1, j1, i2, j2
  1032. integer, dimension(3) :: ubound_e
  1033. real :: x, xlon, xlat, efrac, dtime, month2dt, dtime2
  1034. real,dimension(:,:,:,:),pointer :: rm
  1035. real :: mbef, maft, sume
  1036. ! --- begin --------------------------------------
  1037. call GET_DISTGRID( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  1038. status = 0
  1039. ! check arguments
  1040. ubound_e = ubound(emis_field)
  1041. if(ubound_e(1) /= i2) then
  1042. write(gol,'(A)') 'do_add_3d: im emission not consistent' ; call goPr
  1043. status = 1
  1044. endif
  1045. if(ubound_e(2) /= j2) then
  1046. write(gol,'(A)') 'do_add_3d: jm emission not consistent' ; call goPr
  1047. status = 1
  1048. endif
  1049. if(ubound_e(3) > lm(region)) then
  1050. write(gol,'(A)') 'do_add_3d: lm emission not consistent' ; call goPr
  1051. status = 1
  1052. endif
  1053. IF_NOTOK_RETURN(status=1)
  1054. rm => mass_dat(region)%rm
  1055. dtime = float(nsrce)/(2*tref(region)) !timestep emissions
  1056. month2dt = dtime/sec_month ! conversion to emission per timestep
  1057. dtime2 = float(ndyn_max)/(2*tref(region)) !timestep emissions based on non-CFL interference (CMK 05/2006)
  1058. ntim = 86400/nint(dtime2) !number of timesteps in 24 hours based on non-CFL interference (CMK 05/2006)
  1059. call tau2date(itaur(region),idater)
  1060. sec_in_day = idater(4)*3600 + idater(5)*60 + idater(6) !elapsed seconds this day
  1061. itim = sec_in_day/nint(dtime2)+1 !time interval
  1062. if(present(xfrac)) then
  1063. efrac = xfrac
  1064. else
  1065. efrac = 1.0
  1066. endif
  1067. ! if (okdebug) then
  1068. ! write (gol, '("--------------------------------------------------------------")') ; call goPr
  1069. ! write (gol, '(" DO ADD 3D CYCLE debug in region:",i3) ' ) region ; call goPr
  1070. ! write (gol, '(" itracer :",i3,a8)' ) i_tracer, ' :'//names(i_tracer) ; call goPr
  1071. ! write (gol, '(" xfrac :",f6.1)' ) efrac ; call goPr
  1072. ! write (gol, '(" mol_mass :",f6.1 ) ' ) mol_mass ; call goPr
  1073. ! write (gol, '(" mol_mass_e :", f6.1 )' ) mol_mass_e ; call goPr
  1074. ! write (gol, '(" emisfield :", 2e12.4 )') minval(emis_field),maxval(emis_field) ; call goPr
  1075. ! write (gol, '(" ubound(3) :", i3 )' ) ubound_e(3) ; call goPr
  1076. ! sume = sum(emis_field)*month2dt*(mol_mass/mol_mass_e)*efrac
  1077. ! write (gol, '(" sume :", e12.4 )' ) sume ; call goPr
  1078. ! mbef = sum(rm(i1:i2,j1:j2,:,i_tracer))
  1079. ! write (gol,*) 'lbounds:', is,i1,js,j1 ; call goPr
  1080. ! endif
  1081. do l=1,ubound_e(3)
  1082. do j=j1,j2
  1083. do i=i1,i2
  1084. xlat = ybeg(region) + (j-0.5)*dy/yref(region)
  1085. if (xlat .gt. -20 .and. xlat .lt. 20) then
  1086. ! apply emission cycle in tropics only
  1087. ! itim = 1 and lon = -180 --->position 1
  1088. ! itim = ntim ant lon = -180 --->position ntim, etc.
  1089. ! itim = 1 and lon = 0 ---->position ntim/2
  1090. xlon = xbeg(region) + (i-0.5)*dx/xref(region)
  1091. ipos = 1 + mod(int((xlon+180.)*ntim/360.) + (itim-1),ntim) !position in array depending on time and lon.
  1092. x = emis_field(i,j,l)*month2dt*(mol_mass/mol_mass_e)*efrac*curr_cycle(ipos)
  1093. else
  1094. x = emis_field(i,j,l)*month2dt*(mol_mass/mol_mass_e)*efrac
  1095. endif
  1096. rm(i,j,l,i_tracer) = rm(i,j,l,i_tracer) + x
  1097. #ifdef with_budgets
  1098. ! budget___
  1099. ! if(region==nregions) then !sub budget finest region
  1100. ! nzone=nzon(i,j)
  1101. ! nzone_v=nzon_v(l)
  1102. ! budemi(nzone,nzone_v,i_tracer)=budemi(nzone,nzone_v,i_tracer)+x/mol_mass*1e3 !mole
  1103. ! endif
  1104. nzone=budg_dat(region)%nzong(i,j) !global budget
  1105. nzone_v=nzon_vg(l)
  1106. #ifndef without_emission
  1107. budemi_dat(region)%emi(i,j,nzone_v,i_tracer) = &
  1108. budemi_dat(region)%emi(i,j,nzone_v,i_tracer) + x/mol_mass*1e3
  1109. if(i_tracer ==1) sum_emission(region) = sum_emission(region) + x !in kg
  1110. #endif
  1111. #endif
  1112. enddo
  1113. enddo
  1114. enddo !levels
  1115. ! if (okdebug) then
  1116. ! maft = sum(rm(i1:i2,j1:j2,:,i_tracer))
  1117. ! write (gol, '(" after-before :", e12.4 )' ) maft-mbef ; call goPr
  1118. ! !if ( sume > tiny(sume) ) then
  1119. ! ! This is wrong...
  1120. ! ! if ( (maft-mbef)/sume < 0.5) then
  1121. ! ! write (gol, '(" spurious do_add_3d_cycle.... ")' ) ; call goPr
  1122. ! ! call dumpfield(1, 'spurious.hdf', im(region), jm(region), ubound_e(3), 1, emis_field, names(i_tracer))
  1123. ! ! endif
  1124. ! !endif
  1125. ! write (gol, '(" END debug output ")' ) ; call goPr
  1126. ! endif
  1127. nullify(rm)
  1128. end subroutine do_add_3d_cycle
  1129. !EOC
  1130. !--------------------------------------------------------------------------
  1131. ! TM5 !
  1132. !--------------------------------------------------------------------------
  1133. !BOP
  1134. !
  1135. ! !IROUTINE: DISTRIBUTE_L44
  1136. !
  1137. ! !DESCRIPTION: Scales input field (field2d) such that
  1138. ! 1) NH temperate vegetation fires are distributed over the
  1139. ! months: july-august-september
  1140. ! 2) SH temperate vegetation fires are distributed over the
  1141. ! months: January-February-March
  1142. !\\
  1143. !\\
  1144. ! !INTERFACE:
  1145. !
  1146. SUBROUTINE DISTRIBUTE_L44(month, imdim, jmdim, field2d)
  1147. !
  1148. ! !USES:
  1149. !
  1150. use dims, only : okdebug
  1151. !
  1152. ! !INPUT PARAMETERS:
  1153. !
  1154. integer, intent(in) :: month ! month
  1155. integer, intent(in) :: jmdim, imdim ! dimension of grid
  1156. !
  1157. ! !REVISION HISTORY:
  1158. ! 1 Oct 2010 - Achim Strunk - protex
  1159. !
  1160. !EOP
  1161. !------------------------------------------------------------------------
  1162. !BOC
  1163. real,dimension(imdim,jmdim) :: field2d
  1164. real :: bb_nh,bb_sh ! multiplication factor for yearly temperate fires
  1165. integer :: j,i
  1166. bb_nh=0.
  1167. bb_sh=0.
  1168. if (month==7.or.month==8.or.month==9) bb_nh=3./12.
  1169. if (month==1.or.month==2.or.month==3) bb_sh=3./12.
  1170. do i=1, imdim
  1171. do j=1, jmdim/2
  1172. field2d(i,j)=field2d(i,j)*bb_sh
  1173. enddo
  1174. do j=jmdim/2+1,jmdim
  1175. field2d(i,j)=field2d(i,j)*bb_nh
  1176. enddo
  1177. enddo
  1178. if(okdebug) then
  1179. write(gol,*) 'l44 is distributed' ; call goPr
  1180. endif
  1181. END SUBROUTINE DISTRIBUTE_L44
  1182. !EOC
  1183. END MODULE EMISSION_DATA