emission_data__co2.F90 23 KB

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