emission_data__co2.F90 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605
  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. !\\
  23. !\\
  24. ! !INTERFACE:
  25. !
  26. MODULE EMISSION_DATA
  27. !
  28. ! !USES:
  29. !
  30. use GO, only : gol, goPr, goErr
  31. use Dims, only : nregions, lm
  32. use global_types, only : emis_data, d2_data, d23_data, d3_data
  33. #ifdef with_budgets
  34. use budget_global,only : budg_dat, nzon_vg
  35. #endif
  36. IMPLICIT NONE
  37. !
  38. ! !PUBLIC DATA MEMBERS & TYPES:
  39. !
  40. public :: emis_data, d2_data, d23_data
  41. !
  42. type(emis_data), target :: plandr(nregions) ! Land fraction
  43. type(emis_data), target :: emis2D(nregions) ! 2D emiss prior vertical redistribution
  44. type(emis_data), target :: emis_temp(nregions) ! temp array to store emission
  45. ! AR5
  46. logical :: LAR5
  47. character(len=256) :: emis_input_dir
  48. character(len=256) :: emis_input_dir_ar5
  49. integer :: emis_input_year
  50. ! biomass burning levels:
  51. integer, parameter :: bb_nlev = 5
  52. integer, parameter :: bb_lm = lm(1) ! to be reduced to strip stratosphere!
  53. integer, parameter :: bl_lm = lm(1) ! to be reduced to the BL (around 8)
  54. real, parameter :: bb_hlow (0:bb_nlev) = (/ 0., 100., 500., 1000., 2000., 3000./)
  55. real, parameter :: bb_hhigh(0:bb_nlev) = (/ 100., 500., 1000., 2000., 3000., 6000./)
  56. ! biomass burning levels in tropics (-20 - 20)::
  57. integer, parameter :: bb_nlev_trop = 3
  58. real, parameter :: bb_hlow_trop (0:bb_nlev_trop) = (/ 0., 100., 500., 1000./)
  59. real, parameter :: bb_hhigh_trop(0:bb_nlev_trop) = (/ 100., 500., 1000., 2000./)
  60. ! -----------------------------------------------------------------------------------
  61. ! Budgets
  62. #ifdef with_budgets
  63. real, dimension(nregions) :: sum_emission
  64. type budemi_data
  65. real,dimension(:,:,:,:),pointer :: emi ! [i, j, nbud_vg, ntracet]
  66. end type budemi_data
  67. type(budemi_data),dimension(nregions),target :: budemi_dat
  68. #endif
  69. ! ----------------------------------------------------
  70. ! Vertical splitting : used now for all sectors
  71. ! (tables in Dentener, 2006, ACP)
  72. !
  73. ! ATTENTION: changes here have impact on the routine emission_vdist_by_sector (contained)
  74. ! Note: vdist_* variable could be hold private
  75. !
  76. integer, parameter :: vd_class_name_len = 12
  77. ! biomassburning
  78. integer, parameter :: vdist_bb_nlev = 6
  79. real,dimension(vdist_bb_nlev),parameter :: vdist_bb_hlow = (/ 0., 100., 500., 1000., 2000., 3000./)
  80. real,dimension(vdist_bb_nlev),parameter :: vdist_bb_hhigh = (/ 100., 500., 1000., 2000., 3000., 6000./)
  81. ! other sources (related to surface)
  82. integer, parameter :: vdist_nn_nlev = 6
  83. real,dimension(vdist_nn_nlev),parameter :: vdist_nn_hlow = (/ 0., 30. , 100., 300., 600., 1000. /)
  84. real,dimension(vdist_nn_nlev),parameter :: vdist_nn_hhigh = (/ 30., 100., 300., 600., 1000., 2000. /)
  85. !
  86. ! !PRIVATE TYPES:
  87. !
  88. character(len=*), parameter, private :: mname = 'emission_data'
  89. !
  90. ! !REVISION HISTORY:
  91. ! 1 Oct 2010 - Achim Strunk - adapted for AR5
  92. ! 28 Jun 2012 - Ph. Le Sager - made everything public by default
  93. ! - adapted for lon-lat MPI domain decomposition
  94. ! !REMARKS:
  95. !
  96. !EOP
  97. !------------------------------------------------------------------------
  98. CONTAINS
  99. !--------------------------------------------------------------------------
  100. ! TM5 !
  101. !--------------------------------------------------------------------------
  102. !BOP
  103. !
  104. ! !IROUTINE: EMISSION_VDIST_BY_SECTOR
  105. !
  106. ! !DESCRIPTION: Return vertically distributed emissions depending on given
  107. ! sector and constituent.
  108. ! Distribution is done as 'compromise' between
  109. ! 1) Dentener et al., 2006, ACP, slightly modified for
  110. ! emissions supposed to enter the surface layer.
  111. ! 2) De Meij et al., ACP, 2006
  112. ! 3) EMEP model (docu, model code, publications)
  113. ! 4) Bieser et al., GMDD, 2010
  114. ! 5) Small updates to biomassburning following
  115. ! Huijnen et al., GMDD, 2010
  116. !\\
  117. !\\
  118. ! !INTERFACE:
  119. !
  120. SUBROUTINE EMISSION_VDIST_BY_SECTOR( splitname, constituent, region, emis2D, emis3D, status )
  121. !
  122. ! !USES:
  123. !
  124. use toolbox, only : distribute_emis2D
  125. !
  126. ! !INPUT PARAMETERS:
  127. !
  128. character(len=vd_class_name_len), intent(in) :: splitname
  129. character(len=*), intent(in) :: constituent
  130. integer, intent(in) :: region
  131. type(emis_data), intent(in) :: emis2D
  132. !
  133. ! !INPUT/OUTPUT PARAMETERS:
  134. !
  135. type(d3_data), intent(inout) :: emis3D
  136. !
  137. ! !OUTPUT PARAMETERS:
  138. !
  139. integer, intent(out) :: status
  140. !
  141. ! !REVISION HISTORY:
  142. ! 1 Oct 2010 - Achim Strunk - v0
  143. !
  144. ! !REMARKS: Splitting depending on constituent is still to code.
  145. !
  146. !EOP
  147. !------------------------------------------------------------------------
  148. !BOC
  149. character(len=*), parameter :: rname = mname//'/emission_vdist_by_sector'
  150. integer :: ilev
  151. character(len=2) :: splittype
  152. integer, parameter :: maxvdist_nlev = max(vdist_bb_nlev,vdist_nn_nlev)
  153. real, dimension(maxvdist_nlev) :: sfglobal, sfintrop, sfintemp
  154. ! --- begin --------------------------------------
  155. ! control implicit settings here in this routine
  156. if( vdist_bb_nlev /= 6 .or. vdist_nn_nlev /= 6 ) then
  157. write(gol, '("ERROR: wrong number of layers: bb_nlev /= 6 or nn_lev /= 6")'); call goErr
  158. status=1; return
  159. end if
  160. ! initialise
  161. sfglobal = 0.0
  162. sfintrop = 0.0
  163. sfintemp = 0.0
  164. ! -------------------------------------------------
  165. ! This here is selection by emission source sectors
  166. ! -------------------------------------------------
  167. select case( trim(splitname) )
  168. case( 'combenergy' )
  169. ! Combustion from energy production and transformation, power-plants
  170. ! no zonal differences, no dependency on species
  171. ! --
  172. ! assumed to be related to EMEP SNAP category [1]
  173. ! AEROCOM equivalent: power-plants
  174. ! --
  175. splittype = 'nn'
  176. sfglobal = (/ 0.0, 0.1, 0.7, 0.2, 0.0, 0.0 /)
  177. case( 'combrescom' )
  178. ! Residential and commercial combustion
  179. ! no zonal differences, no dependency on species
  180. ! --
  181. ! assumed to be related to EMEP SNAP category [2]
  182. ! AEROCOM equivalent: domestic/industry
  183. ! --
  184. splittype = 'nn'
  185. sfglobal = (/ 0.4, 0.4, 0.2, 0.0, 0.0, 0.0 /)
  186. case( 'industry' )
  187. ! Industrial processes and combustion
  188. ! no zonal differences, no dependency on species
  189. ! --
  190. ! assumed to be an aggregate of EMEP SNAP categories [3,4,5]
  191. ! AEROCOM equivalent: industry
  192. ! --
  193. splittype = 'nn'
  194. sfglobal = (/ 0.1, 0.2, 0.6, 0.1, 0.0, 0.0 /)
  195. case( 'waste' )
  196. ! Waste treatment and disposal
  197. ! no zonal differences, no dependency on species
  198. ! --
  199. ! assumed to be related to EMEP SNAP category [9]
  200. ! AEROCOM equivalent: -
  201. ! --
  202. splittype = 'nn'
  203. sfglobal = (/ 0.1, 0.2, 0.4, 0.3, 0.0, 0.0 /)
  204. case( 'nearsurface' )
  205. ! Near surface emissions
  206. ! no zonal differences, no dependency on species
  207. ! --
  208. ! AR5: solvent production and use, agricultural waste burning, &
  209. ! ships, grassland fire, mineral dust (AEROCOM or Tegen-Vignati)
  210. ! EMEP equivalents: SNAP categories [6,8]
  211. ! AEROCOM equivalents: ships, agricultural waste
  212. ! --
  213. splittype = 'nn'
  214. sfglobal = (/ 0.8, 0.2, 0.0, 0.0, 0.0, 0.0 /)
  215. case( 'surface' )
  216. ! Surface emissions
  217. ! no zonal differences, no dependency on species
  218. ! --
  219. ! AR5: agriculture, transport, soil, oceanic, biogenic
  220. ! EMEP equivalents: SNAP categories [7,8,10]
  221. ! AEROCOM equivalents: surface emissions from road/off-road, ships, agricultural waste
  222. ! --
  223. splittype = 'nn'
  224. sfglobal = (/ 1.0, 0.0, 0.0, 0.0, 0.0, 0.0 /)
  225. case( 'forestfire' )
  226. ! forest fires: 6 layer model, different splitting for different regions
  227. ! dont distinguish between boreal Europe and boreal Canada, use Europe globally
  228. ! Dentener et al., modified in tropics (up to 2 km) with respect to Huijnen et al., GMD 2010, \
  229. ! who are citing Labonne et al., 2007 ofr new information based on satellite data.
  230. splittype = 'bb'
  231. sfglobal = (/ 0.1, 0.1, 0.2, 0.2, 0.4, 0.0 /)
  232. sfintemp = (/ 0.2, 0.2, 0.2, 0.4, 0.0, 0.0 /)
  233. sfintrop = (/ 0.2, 0.2, 0.2, 0.4, 0.0, 0.0 /)
  234. case default
  235. write(gol, '("ERROR: wrong specification of emission sector ",a,"in vdist_by_sector called for constituent ",a)') &
  236. trim(splitname), trim(constituent); call goErr
  237. status=1; return
  238. end select
  239. ! --------------------
  240. ! do the splitting
  241. ! --------------------
  242. select case( splittype )
  243. case( 'nn' )
  244. do ilev = 1, vdist_nn_nlev
  245. call distribute_emis2D( region, emis2D, emis3D, vdist_nn_hlow(ilev), vdist_nn_hhigh(ilev), status, sfglobal(ilev) )
  246. IF_NOTOK_RETURN(status=1)
  247. end do
  248. case( 'bb' )
  249. do ilev = 1, vdist_bb_nlev
  250. ! boreal
  251. call distribute_emis2D( region, emis2D, emis3D, vdist_bb_hlow(ilev), vdist_bb_hhigh(ilev), status, sfglobal(ilev), -90.,-61.)
  252. IF_NOTOK_RETURN(status=1)
  253. call distribute_emis2D( region, emis2D, emis3D, vdist_bb_hlow(ilev), vdist_bb_hhigh(ilev), status, sfglobal(ilev), 60., 90.)
  254. IF_NOTOK_RETURN(status=1)
  255. ! temperate
  256. call distribute_emis2D( region, emis2D, emis3D, vdist_bb_hlow(ilev), vdist_bb_hhigh(ilev), status, sfintemp(ilev), -60.,-31.)
  257. IF_NOTOK_RETURN(status=1)
  258. call distribute_emis2D( region, emis2D, emis3D, vdist_bb_hlow(ilev), vdist_bb_hhigh(ilev), status, sfintemp(ilev), 30., 59.)
  259. IF_NOTOK_RETURN(status=1)
  260. ! tropics
  261. call distribute_emis2D( region, emis2D, emis3D, vdist_bb_hlow(ilev), vdist_bb_hhigh(ilev), status, sfintrop(ilev), -30., 29.)
  262. IF_NOTOK_RETURN(status=1)
  263. end do
  264. case default
  265. write(gol, '("ERROR: wrong specification of splitting type in vdist_by_sector.")'); call goErr
  266. status=1; return
  267. end select
  268. ! OK
  269. status=0
  270. END SUBROUTINE EMISSION_VDIST_BY_SECTOR
  271. !EOC
  272. !--------------------------------------------------------------------------
  273. ! TM5 !
  274. !--------------------------------------------------------------------------
  275. !BOP
  276. !
  277. ! !IROUTINE: MSG_EMIS
  278. !
  279. ! !DESCRIPTION: Provide output to verify the amount of emissions
  280. ! entering the calculations
  281. !\\
  282. !\\
  283. ! !INTERFACE:
  284. !
  285. SUBROUTINE MSG_EMIS(year_month, msg, msg_comp, msg_mass, summed_emissions)
  286. !
  287. ! !USES:
  288. !
  289. use dims, only: idate
  290. !
  291. ! !INPUT PARAMETERS:
  292. !
  293. integer, intent(in) :: year_month ! 1: year, 2: monthly amount
  294. character(len=*), intent(in) :: msg, msg_comp
  295. real, intent(in) :: msg_mass, summed_emissions
  296. !
  297. ! !REVISION HISTORY:
  298. ! 1 Oct 2010 - Achim Strunk - protex; increase space for output
  299. !
  300. !EOP
  301. !------------------------------------------------------------------------
  302. !BOC
  303. character(len=7),dimension(2), parameter:: ym=(/'Yearly ','Monthly'/)
  304. 1111 format('EMISS-INFO - ',a7,' Emission category ',a34,1x,a6,' [kg], mw:',f5.1,', month=',i2.2,', Sum',1x,1pe10.4)
  305. write (gol,1111) ym(year_month), msg, msg_comp, msg_mass, idate(2), summed_emissions; call goPr
  306. END SUBROUTINE MSG_EMIS
  307. !EOC
  308. !--------------------------------------------------------------------------
  309. ! TM5 !
  310. !--------------------------------------------------------------------------
  311. !BOP
  312. !
  313. ! !IROUTINE: DO_ADD_2D
  314. !
  315. ! !DESCRIPTION: General routine to add a 2D emission field (given in kg
  316. ! /month) into tracer mass array. The mass increase is done
  317. ! at level L_LEVEL, and for tracer I_TRACER.
  318. !
  319. ! Update accordingly the budget.
  320. !\\
  321. !\\
  322. ! !INTERFACE:
  323. !
  324. SUBROUTINE DO_ADD_2D( region, i_tracer, l_level, is, js, emis_field, &
  325. mol_mass, mol_mass_e, status, xfrac )
  326. !
  327. ! !USES:
  328. !
  329. use dims, only : CheckShape, tref, nsrce
  330. use dims, only : sec_month, im, jm, okdebug
  331. use global_data, only : mass_dat, region_dat
  332. use chem_param, only : ntracet, names
  333. use tm5_distgrid, only : get_distgrid, dgrid
  334. #ifdef with_budgets
  335. use budget_global, only : budg_dat, nzon_vg
  336. #endif
  337. !
  338. ! !INPUT PARAMETERS:
  339. !
  340. integer, intent(in) :: region
  341. integer, intent(in) :: i_tracer
  342. integer, intent(in) :: l_level
  343. integer, intent(in) :: is, js
  344. real, intent(in) :: emis_field(is:,js:)
  345. real, intent(in) :: mol_mass ! mol mass of tracer field
  346. real, intent(in) :: mol_mass_e ! mol mass of emission field (e.g. NOx emission ar in kgN/month)
  347. real, intent(in), optional :: xfrac ! partial addition
  348. !
  349. ! !OUTPUT PARAMETERS:
  350. !
  351. integer, intent(out) :: status
  352. !
  353. ! !REVISION HISTORY:
  354. ! 27 Mar 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  355. !
  356. !EOP
  357. !------------------------------------------------------------------------
  358. !BOC
  359. character(len=*), parameter :: rname = mname//'/do_add_2d'
  360. integer :: i, j, nzone, nzone_v, i1, i2, j1, j2
  361. real :: x, efrac, dtime, month2dt
  362. real :: mbef, maft, sume ! mass BEFore, AFTer, SUM Emiss (debug)
  363. real, dimension(:,:,:,:), pointer :: rm, rzm
  364. ! --- begin --------------------------------------
  365. call GET_DISTGRID( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  366. call CheckShape( (/i2-i1+1,j2-j1+1/), shape(emis_field), status )
  367. IF_NOTOK_RETURN(status=1)
  368. dtime=float(nsrce)/(2*tref(region)) ! timestep emissions
  369. month2dt=dtime/sec_month ! conversion to emission per timestep
  370. rm => mass_dat(region)%rm
  371. rzm => mass_dat(region)%rzm
  372. if(present(xfrac)) then
  373. efrac = xfrac
  374. else
  375. efrac = 1.0
  376. endif
  377. if (okdebug) then
  378. write (gol, '("--------------------------------------------------------------")') ; call goPr
  379. write (gol, '(" DO ADD 2D debug in region:",i3) ' ) region ; call goPr
  380. write (gol, '(" itracer :",i3,a8)' ) i_tracer, ' :'//names(i_tracer) ; call goPr
  381. write (gol, '(" xfrac :",f6.1)' ) efrac ; call goPr
  382. write (gol, '(" mol_mass :",f6.1 ) ' ) mol_mass ; call goPr
  383. write (gol, '(" mol_mass_e :",f6.1 )' ) mol_mass_e ; call goPr
  384. write (gol, '(" emisfield :",2e12.4 )') minval(emis_field),maxval(emis_field) ; call goPr
  385. sume = sum(emis_field)*month2dt*(mol_mass/mol_mass_e)*efrac
  386. write (gol, '(" sum emmis :",e12.4 )' ) sume ; call goPr
  387. mbef = sum(rm(i1:i2,j1:j2,:,i_tracer))
  388. endif
  389. do j=j1,j2
  390. do i=i1,i2
  391. x = emis_field(i,j)*month2dt*(mol_mass/mol_mass_e)*efrac
  392. rm(i,j,l_level,i_tracer) = rm(i,j,l_level,i_tracer) + x
  393. #ifdef slopes
  394. ! injection of emissions at surface, thus vertical slope more negative
  395. ! (keep concentration at top of layer the same as before emission)
  396. if ( i_tracer <= ntracet ) then
  397. rzm(i,j,l_level,i_tracer) = rzm(i,j,l_level,i_tracer) - x
  398. end if
  399. #endif
  400. #ifdef with_budgets
  401. nzone = budg_dat(region)%nzong(i,j) !global budget
  402. nzone_v = nzon_vg(l_level)
  403. budemi_dat(region)%emi(i,j,nzone_v,i_tracer) = &
  404. budemi_dat(region)%emi(i,j,nzone_v,i_tracer) + x/mol_mass*1e3
  405. if(i_tracer == 1) sum_emission(region) = sum_emission(region) + x !in kg
  406. #endif
  407. enddo
  408. enddo
  409. if (okdebug) then
  410. maft = sum(rm(i1:i2,j1:j2,:,i_tracer))
  411. write (gol, '(" Added amount :",e12.4 )' ) maft-mbef ; call goPr
  412. write (gol, '(" Added amount can be different when inner zoom is present!" )' ) ; call goPr
  413. if (maft-mbef-sume > 1e-8*sume) then
  414. write (gol, '(" Warning: error in emission ")' ) ; call goErr
  415. endif
  416. endif
  417. nullify(rm)
  418. nullify(rzm)
  419. status=0
  420. END SUBROUTINE DO_ADD_2D
  421. !EOC
  422. !--------------------------------------------------------------------------
  423. ! TM5 !
  424. !--------------------------------------------------------------------------
  425. !BOP
  426. !
  427. ! !IROUTINE: DO_ADD_3D
  428. !
  429. ! !DESCRIPTION: General routine to add a 3D emission field (given in kg
  430. ! /month) into tracer mass array. The mass increase is done
  431. ! for tracer I_TRACER.
  432. !
  433. ! Update accordingly the budget.
  434. !\\
  435. !\\
  436. ! !INTERFACE:
  437. !
  438. SUBROUTINE DO_ADD_3D( region, i_tracer, is, js, emis_field, mol_mass, mol_mass_e, status, xfrac)
  439. !
  440. ! !USES:
  441. !
  442. use dims, only : CheckShape, nsrce, tref
  443. use dims, only : sec_month, im, jm, lm, okdebug
  444. use global_data, only : mass_dat, region_dat
  445. use chem_param, only : ntracet, names
  446. use tm5_distgrid, only : get_distgrid, dgrid
  447. #ifdef with_budgets
  448. use budget_global, only : budg_dat, nzon_vg
  449. #endif
  450. !
  451. ! !INPUT PARAMETERS:
  452. !
  453. integer, intent(in) :: region ! region #
  454. integer, intent(in) :: i_tracer ! id of tracer to increase
  455. integer, intent(in) :: is, js
  456. real, intent(in) :: emis_field(is:,js:,:)
  457. real, intent(in) :: mol_mass, mol_mass_e
  458. real, intent(in), optional :: xfrac !partial addition
  459. !
  460. ! !OUTPUT PARAMETERS:
  461. !
  462. integer, intent(out) :: status
  463. !
  464. ! !REVISION HISTORY:
  465. ! 27 Mar 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  466. !
  467. !EOP
  468. !------------------------------------------------------------------------
  469. !BOC
  470. character(len=*), parameter :: rname = mname//'/do_add_3d'
  471. integer :: i, j, l, nzone, nzone_v, i1,j1,i2,j2
  472. integer, dimension(3) :: ubound_e
  473. real :: x, efrac, dtime, month2dt
  474. real, dimension(:,:,:,:), pointer :: rm
  475. real :: mbef, maft, sume ! debug
  476. ! --- begin --------------------------------------
  477. call GET_DISTGRID( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  478. status = 0
  479. ! check arguments
  480. ubound_e = ubound(emis_field)
  481. if(ubound_e(1) /= i2) then
  482. write(gol,'(A)') 'do_add_3d: im emission not consistent' ; call goPr
  483. status = 1
  484. endif
  485. if(ubound_e(2) /= j2) then
  486. write(gol,'(A)') 'do_add_3d: jm emission not consistent' ; call goPr
  487. status = 1
  488. endif
  489. if(ubound_e(3) > lm(region)) then
  490. write(gol,'(A)') 'do_add_3d: lm emission not consistent' ; call goPr
  491. status = 1
  492. endif
  493. IF_NOTOK_RETURN(status=1)
  494. rm => mass_dat(region)%rm
  495. dtime=float(nsrce)/(2*tref(region)) ! timestep emissions
  496. month2dt=dtime/sec_month ! conversion to emission per timestep
  497. if(present(xfrac)) then
  498. efrac = xfrac
  499. else
  500. efrac = 1.0
  501. endif
  502. ! if (okdebug) then
  503. ! write (gol, '("--------------------------------------------------------------")') ; call goPr
  504. ! write (gol, '(" DO ADD 3D debug in region:",i3) ' ) region ; call goPr
  505. ! write (gol, '(" itracer :",i3,a8)' ) i_tracer, ' :'//names(i_tracer) ; call goPr
  506. ! write (gol, '(" xfrac :",f6.1)' ) efrac ; call goPr
  507. ! write (gol, '(" mol_mass :",f6.1 ) ' ) mol_mass ; call goPr
  508. ! write (gol, '(" mol_mass_e :",f6.1 )' ) mol_mass_e ; call goPr
  509. ! write (gol, '(" emisfield :",2e12.4 )') minval(emis_field), maxval(emis_field) ; call goPr
  510. ! write (gol, '(" ubound(3) :",i3 )' ) ubound_e(3) ; call goPr
  511. ! sume = sum(emis_field)*month2dt*(mol_mass/mol_mass_e)*efrac
  512. ! write (gol, '(" sume :", e12.4 )') sume ; call goPr
  513. ! mbef = sum(rm(i1:i2,j1:j2,:,i_tracer))
  514. ! endif
  515. do l=1,ubound_e(3)
  516. do j=j1,j2
  517. do i=i1,i2
  518. x = emis_field(i,j,l)*month2dt*(mol_mass/mol_mass_e)*efrac
  519. rm(i,j,l,i_tracer) = rm(i,j,l,i_tracer) + x
  520. #ifdef with_budgets
  521. ! budget___
  522. nzone=budg_dat(region)%nzong(i,j) !global budget
  523. nzone_v=nzon_vg(l)
  524. budemi_dat(region)%emi(i,j,nzone_v,i_tracer) = &
  525. budemi_dat(region)%emi(i,j,nzone_v,i_tracer) + x/mol_mass*1e3
  526. if(i_tracer ==1) sum_emission(region) = sum_emission(region) + x !in kg
  527. #endif
  528. enddo
  529. enddo
  530. enddo !levels
  531. ! if (okdebug) then
  532. ! maft = sum(rm(i1:i2,j1:j2,:,i_tracer))
  533. ! write (gol, '(" after-before :", e12.4 )' ) maft-mbef ; call goPr
  534. ! write (gol, '(" END debug output ")' ) ; call goPr
  535. ! endif
  536. nullify(rm)
  537. END SUBROUTINE DO_ADD_3D
  538. !EOC
  539. END MODULE EMISSION_DATA