emission_nox.F90 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135
  1. !
  2. #define TRACEBACK write (gol,'("in ",a," (",a,i6,")")') 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_NOX
  14. !
  15. ! !DESCRIPTION: hold data and methods for NOx emissions.
  16. ! -----------------
  17. ! AR5 emissions
  18. ! -----------------
  19. ! For each month, arrays emis_nox_2d/3d have to be filled.
  20. ! It follows the following settins:
  21. ! - take emiss_ene/dom/ind/wst/agr/awb/slv/tra/shp/
  22. ! /air/forestfire/grassfire from AR5 data sets (NO GFED!!)
  23. ! - use natural emissions from MACC data sets
  24. ! (emiss_nat/soil/bio/oc)
  25. ! - vertical distribution is done via emission_vdist_by_sector
  26. ! (emission_data.F90)
  27. ! - lightning is done online (eminox_lightning)
  28. !\\
  29. !\\
  30. ! !INTERFACE:
  31. !
  32. MODULE EMISSION_NOX
  33. !
  34. ! !USES:
  35. !
  36. use GO, only : gol, goErr, goPr, goBug
  37. use tm5_distgrid, only : dgrid, get_distgrid, scatter, gather
  38. use dims, only : nregions, idate, dy, okdebug
  39. use global_types, only : emis_data, d3_data,d23_data
  40. use emission_read, only : used_providers, has_emis
  41. IMPLICIT NONE
  42. PRIVATE
  43. !
  44. ! !PUBLIC MEMBER FUNCTIONS:
  45. !
  46. public :: Emission_NOx_Init
  47. public :: Emission_NOx_Done
  48. public :: Emission_NOx_Declare
  49. public :: Emission_NOx_bb_daily_cycle
  50. #ifndef without_convection
  51. public :: lightningNOX
  52. #endif
  53. public :: nox_emis_3d, nox_emis_3d_bb_app
  54. public :: eminox_lightning
  55. public :: flashrate_lightning
  56. !
  57. ! !DATA MEMBERS:
  58. !
  59. character(len=*), parameter :: mname = 'emission_nox'
  60. type(d3_data), dimension(nregions), target :: nox_emis_3d, nox_emis_3d_bb, nox_emis_3d_bb_app
  61. type(d3_data), dimension(nregions), target :: eminox_lightning
  62. type(d23_data), dimension(nregions), target :: flashrate_lightning
  63. integer :: nox_2dsec, nox_3dsec
  64. real :: fscalelig ! scaling used in lightning NOX production to get 5.98 Tg for 2006
  65. !
  66. ! !REVISION HISTORY:
  67. ! 1 Oct 2010 - Achim Strunk - overhaul for AR5
  68. ! 1 Dec 2011 - Narcisa Banda - added EDGAR 4
  69. ! 27 Jun 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  70. !
  71. ! !REMARKS:
  72. ! NOx emissions are added directly in chemistry, instead of apart from it.
  73. !
  74. !EOP
  75. !------------------------------------------------------------------------
  76. CONTAINS
  77. !--------------------------------------------------------------------------
  78. ! TM5 !
  79. !--------------------------------------------------------------------------
  80. !BOP
  81. !
  82. ! !IROUTINE: EMISSION_NOX_INIT
  83. !
  84. ! !DESCRIPTION: allocate memory
  85. !\\
  86. !\\
  87. ! !INTERFACE:
  88. !
  89. subroutine Emission_NOx_Init( status )
  90. !
  91. ! !USES:
  92. !
  93. use dims, only : lm
  94. use emission_read, only : providers_def, numb_providers, ed42_nsect_nox
  95. use emission_data, only : LAR5BMB
  96. use emission_read, only : n_ar5_ant_sec, n_ar5_shp_sec, n_ar5_air_sec, n_ar5_bmb_sec
  97. use emission_read, only : ar5_cat_ant, ar5_cat_shp, ar5_cat_air, ar5_cat_bmb
  98. #ifndef without_convection
  99. use meteodata, only : set, gph_dat, temper_dat, cp_dat
  100. use emission_data, only : use_tiedkte
  101. #endif
  102. !
  103. ! !OUTPUT PARAMETERS:
  104. !
  105. integer, intent(out) :: status
  106. !
  107. ! !REVISION HISTORY:
  108. ! 1 Oct 2010 - Achim Strunk - adapted for AR5
  109. ! 27 Jun 2012 - Ph. Le Sager - adapted for lon-lat MPI domain decomposition
  110. ! 10 Jul 2013 - Ph. Le Sager - init lightning when no inventory is selected
  111. !
  112. !EOP
  113. !------------------------------------------------------------------------
  114. !BOC
  115. character(len=*), parameter :: rname = mname//'/Emission_NOx_Init'
  116. integer :: region, i1, j1, i2, j2
  117. integer :: imr, jmr, lmr, lsec, lprov
  118. ! --- begin --------------------------------------
  119. status = 0
  120. #ifndef without_convection
  121. ! Meteo used for LightningNOx
  122. do region=1,nregions
  123. call Set( temper_dat(region), status, used=.true. )
  124. call Set( gph_dat(region), status, used=.true. )
  125. call Set( cp_dat(region), status, used=.true. )
  126. enddo
  127. !
  128. ! Scaling parameter for LiNOx
  129. !
  130. ! Set to get 5.98 Tg N with 2006 EI met fields. This is resolution
  131. ! and met fields dependent. The factor has been estimated for:
  132. ! - @3x2 and 34 levels, Tiedkte : fscalelig=13.715
  133. ! - @1x1 and 34 levels, Tiedkte : fscalelig=17.051
  134. ! - @3x2 and 34 levels, EI conv : fscalelig=13.715*0.786
  135. ! - @1x1 and 34 levels, EI conv : fscalelig=17.051*0.649
  136. !
  137. if (use_tiedkte) then ! convective fluxes computed from T/rh/wind (Tiedkte)
  138. fscalelig=13.715 ! 3x2-34L, Tiedkte scheme
  139. if (dy == 1) fscalelig=17.051 ! 1x1-34L, Tiedkte scheme
  140. else
  141. fscalelig=10.78 ! 3x2-34L, EI convective fluxes
  142. if (dy == 1) fscalelig=11.066 ! 1x1-34L, EI convective fluxes
  143. endif
  144. #endif
  145. ! allocate information arrays (2d and 3d)
  146. do region=1,nregions
  147. CALL GET_DISTGRID( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  148. lmr = lm(region)
  149. allocate(eminox_lightning(region)%d3(i1:i2,j1:j2,lmr) )
  150. eminox_lightning(region)%d3=0.
  151. allocate(flashrate_lightning(region)%d23(i1:i2,j1:j2) )
  152. flashrate_lightning(region)%d23=0.
  153. enddo
  154. ! Check if any inventory is used
  155. if(.not. has_emis) return
  156. ! nb of sectors
  157. nox_2dsec = 0
  158. nox_3dsec = 0
  159. do lprov = 1, numb_providers
  160. if (count(used_providers.eq.providers_def(lprov)%name)/=0) then
  161. if (trim(providers_def(lprov)%name) .eq. 'AR5') then
  162. ! nb of available sectors in AR5 depends on category
  163. nox_2dsec = nox_2dsec + n_ar5_ant_sec*count('NO'.eq.ar5_cat_ant) + &
  164. n_ar5_shp_sec*count('NO'.eq.ar5_cat_shp)
  165. if (LAR5BMB) nox_2dsec = nox_2dsec + n_ar5_bmb_sec*count('NO'.eq.ar5_cat_bmb)
  166. nox_3dsec = nox_3dsec + n_ar5_air_sec*count('NO'.eq.ar5_cat_air)
  167. ! nox_2dsec = nox_2dsec + providers_def(lprov)%nsect2d
  168. ! nox_3dsec = nox_3dsec + count('NO'.eq.ar5_cat_air)
  169. elseif (trim(providers_def(lprov)%name) .eq. 'ED42') then
  170. nox_2dsec = nox_2dsec + ed42_nsect_nox
  171. ! no 3d sectors in EDGAR 4.2
  172. else
  173. nox_2dsec = nox_2dsec + providers_def(lprov)%nsect2d
  174. nox_3dsec = nox_3dsec + providers_def(lprov)%nsect3d
  175. endif
  176. endif
  177. enddo
  178. ! allocate information arrays (2d and 3d)
  179. do region=1,nregions
  180. CALL GET_DISTGRID( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  181. lmr = lm(region)
  182. allocate( nox_emis_3d (region)%d3(i1:i2,j1:j2,lmr) )
  183. allocate( nox_emis_3d_bb (region)%d3(i1:i2,j1:j2,lmr) )
  184. allocate( nox_emis_3d_bb_app(region)%d3(i1:i2,j1:j2,lmr) )
  185. enddo
  186. status = 0
  187. END SUBROUTINE EMISSION_NOX_INIT
  188. !EOC
  189. !--------------------------------------------------------------------------
  190. ! TM5 !
  191. !--------------------------------------------------------------------------
  192. !BOP
  193. !
  194. ! !IROUTINE: EMISSION_NOX_DONE
  195. !
  196. ! !DESCRIPTION: Free memory
  197. !\\
  198. !\\
  199. ! !INTERFACE:
  200. !
  201. SUBROUTINE EMISSION_NOX_DONE( status )
  202. !
  203. ! !OUTPUT PARAMETERS:
  204. !
  205. integer, intent(out) :: status
  206. !
  207. ! !REVISION HISTORY:
  208. ! 1 Oct 2010 - Achim Strunk - adapted for AR5
  209. !
  210. !EOP
  211. !------------------------------------------------------------------------
  212. !BOC
  213. character(len=*), parameter :: rname = mname//'/Emission_NOx_Done'
  214. integer :: region, lsec
  215. ! --- begin ---------------------------------
  216. status = 0
  217. if(.not. has_emis) return
  218. do region = 1, nregions
  219. deallocate( nox_emis_3d (region)%d3 )
  220. deallocate( nox_emis_3d_bb (region)%d3 )
  221. deallocate( nox_emis_3d_bb_app(region)%d3 )
  222. deallocate( eminox_lightning (region)%d3 )
  223. deallocate( flashrate_lightning (region)%d23 )
  224. end do
  225. status = 0
  226. END SUBROUTINE EMISSION_NOX_DONE
  227. !EOC
  228. !--------------------------------------------------------------------------
  229. ! TM5 !
  230. !--------------------------------------------------------------------------
  231. !BOP
  232. !
  233. ! !IROUTINE: EMISSION_NOX_DECLARE
  234. !
  235. ! !DESCRIPTION: Opens, reads and evaluates input files (per month).
  236. ! Provides emissions on 2d/3d-arrays which are then added
  237. ! in the chemistry routine (no *apply !).
  238. ! Vertically distribute the 2D dataset according to sector.
  239. !\\
  240. !\\
  241. ! !INTERFACE:
  242. !
  243. SUBROUTINE EMISSION_NOX_DECLARE( status )
  244. !
  245. ! !USES:
  246. !
  247. use toolbox, only : coarsen_emission
  248. use partools, only : isRoot, par_broadcast
  249. use dims, only : im, jm, lm, nlon360, nlat180, iglbsfc
  250. use dims, only : newsrun, idate, sec_month
  251. use chem_param, only : xmn, xmno2, xmno
  252. use emission_data, only : msg_emis, emission_vdist_by_sector, LAR5BMB
  253. ! ---------------- AR5 - EDGAR 4 - ETC. --------------------
  254. use emission_data, only : emis_input_year_nox, emis_input_year_nat
  255. use emission_data, only : emis_input_dir_mac, emis_input_dir_ed4
  256. use emission_data, only : emis_input_dir_retro, emis_input_dir_gfed
  257. use emission_read, only : emission_ar5_regrid_aircraft
  258. use emission_read, only : emission_cmip6_ReadSector
  259. use emission_read, only : emission_cmip6bmb_ReadSector
  260. use emission_read, only : emission_ar5_ReadSector, emission_macc_ReadSector
  261. use emission_read, only : emission_ed4_ReadSector, emission_gfed_ReadSector
  262. use emission_read, only : emission_retro_ReadSector
  263. use emission_read, only : sectors_def, numb_sectors
  264. use emission_read, only : ar5_dim_3ddata
  265. use emission_read, only : ed42_nox_sectors
  266. !
  267. ! !OUTPUT PARAMETERS:
  268. !
  269. integer, intent(out) :: status
  270. !
  271. ! !REVISION HISTORY:
  272. ! 1 Oct 2010 - Achim Strunk - adapted for AR5
  273. ! 1 Dec 2011 - Narcisa Banda - added EDGAR 4
  274. ! 27 Jun 2012 - Ph. Le Sager - adapted for lon-lat MPI domain decomposition
  275. ! 25 Feb 2014 - Jason Williams - separate array for BMB so that burning daily cycle can be applied
  276. !
  277. ! !REMARKS:
  278. ! (1) Because we do not use an apply method, the vertical distribution
  279. ! is done here. However this is a bug, since this is time dependent.
  280. ! Possible solution: do vert dist in chemistry like the BMB cycle,
  281. ! or in the more general BMB cycle routine.
  282. !
  283. !
  284. !EOP
  285. !------------------------------------------------------------------------
  286. !BOC
  287. character(len=*), parameter :: rname = mname//'/emission_nox_declare'
  288. integer :: region, hasData
  289. integer,parameter :: add_field=0
  290. integer,parameter :: amonth=2
  291. integer :: imr, jmr, lmr, lsec, i1, i2, j1, j2
  292. ! AR5 temporary arrays
  293. real, dimension(:,:,:), allocatable :: field3d !, field3d2
  294. type(d3_data), dimension(nregions), target :: emis3d, work, work3d
  295. type(emis_data), dimension(nregions), target :: emis2d, wrk2D
  296. ! defensive
  297. integer :: seccount2d, seccount3d
  298. ! --- begin -----------------------------------------
  299. status = 0
  300. if(.not. has_emis) return
  301. write(gol,'(" EMISS-INFO ------------- read NOx emissions -------------")'); call goPr
  302. ! reset emissions, allocate work array
  303. do region = 1, nregions
  304. nox_emis_3d(region)%d3 = 0.0 ; nox_emis_3d_bb(region)%d3 = 0.0
  305. CALL GET_DISTGRID( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  306. lmr = lm(region)
  307. allocate( work3d(region)%d3 (i1:i2,j1:j2, ar5_dim_3ddata) ) ; work3d(region)%d3 = 0.0
  308. allocate( emis3d(region)%d3 (i1:i2,j1:j2, lmr ) ) ; emis3d(region)%d3 = 0.0
  309. allocate( emis2d(region)%surf(i1:i2,j1:j2) ) ; emis2d(region)%surf = 0.0
  310. end do
  311. ! global arrays for coarsening
  312. do region = 1, nregions
  313. if (isRoot)then
  314. allocate(work(region)%d3(im(region),jm(region),ar5_dim_3ddata))
  315. else
  316. allocate(work(region)%d3(1,1,1))
  317. end if
  318. enddo
  319. do region = 1, nregions
  320. wrk2D(region)%surf => work(region)%d3(:,:,1)
  321. end do
  322. ! --------------------------------
  323. ! do a loop over available sectors
  324. ! --------------------------------
  325. ! count 2d and 3d sectors
  326. seccount2d = 0
  327. seccount3d = 0
  328. ! always allocate here 3d data set (for 2d sectors it will be filled in first layer only)
  329. if (isRoot) then
  330. allocate( field3d( nlon360, nlat180, ar5_dim_3ddata ) ) ; field3d = 0.0
  331. else
  332. allocate( field3d( 1, 1, 1 ) )
  333. end if
  334. sec: do lsec = 1, numb_sectors
  335. if (count(used_providers.eq.sectors_def(lsec)%prov).eq.0) cycle
  336. if ((trim(sectors_def(lsec)%prov).eq.'ED42') .and. (count(ed42_nox_sectors.eq.sectors_def(lsec)%name) .eq. 0)) cycle
  337. if (associated(sectors_def(lsec)%species)) then ! AR5 check
  338. if (count('NO'.eq.sectors_def(lsec)%species).eq.0) cycle
  339. if ((trim(sectors_def(lsec)%catname) .eq. 'biomassburning').and.(.not.LAR5BMB)) cycle
  340. endif
  341. if( sectors_def(lsec)%f3d ) then
  342. seccount3d = seccount3d + 1
  343. else
  344. seccount2d = seccount2d + 1
  345. end if
  346. field3d = 0.0
  347. #ifdef with_online_nox
  348. ! skip natural nox in case it is calculated online
  349. if( trim(sectors_def(lsec)%namecat == 'natural') ) then
  350. write (gol,'(80("-"))'); call goPr
  351. write (gol,'("INFO: skipping sector `",a,"` due to `with_online_nox` ")') trim(sectors_def(lsec)%name); call goPr
  352. cycle
  353. end if
  354. #endif
  355. root: if (isRoot) then ! READ
  356. select case( trim(sectors_def(lsec)%prov) )
  357. case( 'CMIP6' )
  358. call emission_cmip6_ReadSector( 'NOx', emis_input_year_nox, idate(2), lsec, field3d, status )
  359. IF_NOTOK_RETURN(status=1;deallocate(field3d))
  360. ! convert from (kg NO2)/s to (kg N)/s
  361. field3d = field3d * xmn / xmno2
  362. case( 'CMIP6BMB' )
  363. call emission_cmip6bmb_ReadSector( 'NOx', emis_input_year_nox, idate(2), lsec, field3d, status )
  364. IF_NOTOK_RETURN(status=1;deallocate(field3d))
  365. ! convert from (kg NO)/s to (kg N)/s
  366. ! both for the historical period and the future scenarios
  367. ! see http://www.falw.vu/~gwerf/GFED/GFED4/ancill/GFED4_Emission_Factors.txt
  368. ! and the following attribute in the SSP NetCDF files:
  369. ! reporting_unit = "Mass flux of NOx, reported as NO"
  370. field3d = field3d * xmn / xmno
  371. case( 'AR5' )
  372. ! AR5 emissions included NO and NO2 aircraft emissions, but they are duplicates. So
  373. ! only take into account one of the sets. (in TM5: NO, skip NO2).
  374. ! Screen out solvent sector for NO,
  375. ! because it is zero in the RCPs
  376. ! and not present in the historical files.
  377. if (trim(sectors_def(lsec)%name) .ne. 'emiss_slv') then
  378. call emission_ar5_ReadSector( 'NO', emis_input_year_nox, idate(2), lsec, field3d, status )
  379. IF_NOTOK_RETURN(status=1)
  380. ! convert from (kg NO)/s to (kg N)/s
  381. field3d = field3d * xmn / xmno
  382. endif
  383. case( 'MACC' )
  384. ! screen out sectors w/o NOx (bio, oc, nat)
  385. if ( (trim(sectors_def(lsec)%name) .eq. 'emiss_soil' ) .or. &
  386. (trim(sectors_def(lsec)%name) .eq. 'emiss_anthro') .or. &
  387. (trim(sectors_def(lsec)%name) .eq. 'emiss_air' ) ) then
  388. if (trim(sectors_def(lsec)%catname) .eq. 'natural') then
  389. call emission_macc_ReadSector( emis_input_dir_mac, 'NO', emis_input_year_nat, idate(2), &
  390. '0.5x0.5_kg.nc', sectors_def(lsec)%name, 'kg NO / s', field3d, status )
  391. IF_NOTOK_RETURN(status=1)
  392. else
  393. call emission_macc_ReadSector( emis_input_dir_mac, 'NO', emis_input_year_nox, idate(2), &
  394. '0.5x0.5_kg.nc', sectors_def(lsec)%name, 'kg NO / s', field3d, status )
  395. IF_NOTOK_RETURN(status=1)
  396. endif
  397. ! convert from (kg NO)/s to (kg N)/s
  398. field3d = field3d * xmn / xmno
  399. endif
  400. case( 'ED41' )
  401. select case(trim(sectors_def(lsec)%name))
  402. case ('1A3a','1A3b_c_e','1A3d_SHIP','1A3d1')
  403. ! anthropogenic sources
  404. call emission_ed4_ReadSector( emis_input_dir_ed4, 'NOx','nox', emis_input_year_nox, idate(2), &
  405. lsec, trim(sectors_def(lsec)%prov), 'kg / s', field3d, status )
  406. IF_NOTOK_RETURN(status=1;deallocate(field3d))
  407. end select
  408. case( 'ED42' )
  409. ! biomass burning (GFED/RETRO/AR5BMB) and transport (ED41) are excluded through ED42_NOX_SECTORS definition
  410. call emission_ed4_ReadSector( emis_input_dir_ed4, 'NOx', 'nox', emis_input_year_nox, idate(2), &
  411. lsec, trim(sectors_def(lsec)%prov), 'kg / s', field3d, status )
  412. IF_NOTOK_RETURN(status=1)
  413. case('GFEDv3')
  414. call emission_gfed_ReadSector( emis_input_dir_gfed, 'nox', emis_input_year_nox, idate(2), &
  415. sectors_def(lsec)%name, 'kg NO2 / s', field3d(:,:,1), status )
  416. IF_NOTOK_RETURN(status=1)
  417. ! convert from (kg NO2)/s to (kg N)/s
  418. field3d = field3d * xmn / xmno2
  419. case('RETRO')
  420. call emission_retro_ReadSector( emis_input_dir_retro, 'NOX', emis_input_year_nox, idate(2), &
  421. sectors_def(lsec)%name, 'kg / s', field3d(:,:,1), status )
  422. IF_NOTOK_RETURN(status=1)
  423. ! in the file kg(species)/m2/s - what does this mean?? by the numbers I assume kg NO2
  424. ! convert from (kg NO2)/s to (kg N)/s
  425. field3d = field3d * xmn / xmno2
  426. case('MEGAN')
  427. !
  428. ! use soil emissions from MACC
  429. !
  430. case('DUMMY')
  431. case default
  432. write(gol,*) "Error in building list of providers USED_PROVIDERS"; call goErr
  433. status=1; TRACEBACK; return
  434. end select
  435. ! verbose
  436. if(sum(field3d) < 100.*TINY(1.0) ) then
  437. if (okdebug) then
  438. write(gol,'("EMISS-INFO - no NOx emissions found for ",a," ",a," for month ",i2 )') &
  439. trim(sectors_def(lsec)%prov), sectors_def(lsec)%name, idate(2) ; call goPr
  440. endif
  441. hasData=0
  442. else
  443. if (okdebug) then
  444. write(gol,'("EMISS-INFO - found NOx emissions for ",a," ",a," for month ",i2 )') &
  445. trim(sectors_def(lsec)%prov), sectors_def(lsec)%name, idate(2) ; call goPr
  446. endif
  447. ! scale from kg/s to kg/month
  448. field3d = field3d * sec_month ! kg / month
  449. hasData=1
  450. endif
  451. end if root
  452. call Par_broadcast(hasData, status)
  453. IF_NOTOK_RETURN(status=1)
  454. if (hasData == 0) cycle sec
  455. ! reset temporary arrays
  456. do region = 1, nregions
  457. emis3d(region)%d3 = 0.0
  458. work3d(region)%d3 = 0.0
  459. emis2d(region)%surf = 0.0
  460. end do
  461. ! distinguish 2d/3d sectors
  462. if( sectors_def(lsec)%f3d ) then
  463. ! ---------------------------
  464. ! 3d data (AIRCRAFT)
  465. ! ---------------------------
  466. if (isRoot) then
  467. ! write some numbers
  468. call msg_emis( amonth, trim(sectors_def(lsec)%prov), sectors_def(lsec)%name, 'NOx', xmn, sum(field3d) )
  469. ! distribute to work arrays in regions
  470. call Coarsen_Emission( 'NOX '//trim(sectors_def(lsec)%name), nlon360, nlat180, ar5_dim_3ddata, &
  471. field3d, work, add_field, status )
  472. IF_NOTOK_RETURN(status=1)
  473. end if
  474. ! scatter, sum up on target array
  475. do region = 1, nregions
  476. call scatter(dgrid(region), work3d(region)%d3, work(region)%d3, 0, status)
  477. IF_NOTOK_RETURN( status=1 )
  478. CALL GET_DISTGRID( dgrid(region), I_STRT=i1, J_STRT=j1)
  479. ! aircraft data: regrid vertically to model layers
  480. call emission_ar5_regrid_aircraft( region, i1, j1, work3d(region)%d3, emis3d(region)%d3, status )
  481. IF_NOTOK_RETURN( status=1 )
  482. nox_emis_3d(region)%d3 = nox_emis_3d(region)%d3 + emis3d(region)%d3
  483. end do
  484. else ! ar5_sector is 2d
  485. ! ---------------------------
  486. ! 2d data (Anthropogenic, Ships, Biomassburning, ...)
  487. ! ---------------------------
  488. if (isRoot) then ! print total & regrid
  489. call msg_emis( amonth, trim(sectors_def(lsec)%prov), sectors_def(lsec)%name, 'NOx', xmn, sum(field3d(:,:,1)) )
  490. call coarsen_emission( 'NOx '//sectors_def(lsec)%name, nlon360, nlat180, field3d(:,:,1), &
  491. wrk2D, add_field, status )
  492. IF_NOTOK_RETURN(status=1)
  493. end if
  494. ! scatter, distribute vertically according to sector, and sum up on target array
  495. do region = 1, nregions
  496. call scatter(dgrid(region), emis2d(region)%surf, work(region)%d3(:,:,1), 0, status)
  497. IF_NOTOK_RETURN(status=1)
  498. call emission_vdist_by_sector( sectors_def(lsec)%vdisttype, 'NOx', region, emis2d(region), emis3d(region), status )
  499. IF_NOTOK_RETURN(status=1)
  500. if ( trim(sectors_def(lsec)%catname) .eq. 'biomassburning') then
  501. nox_emis_3d_bb(region)%d3 = nox_emis_3d_bb(region)%d3 + emis3d(region)%d3
  502. else
  503. nox_emis_3d(region)%d3 = nox_emis_3d(region)%d3 + emis3d(region)%d3
  504. endif
  505. end do
  506. end if ! sectors_def
  507. end do sec ! sectors
  508. deallocate( field3d )
  509. do region = 1, nregions
  510. if (associated(wrk2D(region)%surf)) nullify(wrk2D(region)%surf)
  511. deallocate( emis3d(region)%d3, emis2d(region)%surf )
  512. deallocate( work(region)%d3 )
  513. deallocate( work3d(region)%d3 )
  514. end do
  515. ! check sectors found
  516. if( seccount2d /= nox_2dsec ) then
  517. write(gol,'(80("-"))') ; call goPr
  518. write(gol,'("ERROR: 2d sectors do not equal total number:",i4," /= ",i4," !")') seccount2d, nox_2dsec ; call goErr
  519. write(gol,'(80("-"))') ; call goPr
  520. status=1; return
  521. end if
  522. if( seccount3d /= nox_3dsec ) then
  523. write(gol,'(80("-"))') ; call goPr
  524. write(gol,'("ERROR: 3d sectors do not equal total number:",i4," /= ",i4," !")') seccount3d, nox_3dsec ; call goErr
  525. write(gol,'(80("-"))') ; call goPr
  526. status=1; return
  527. end if
  528. ! ok
  529. status = 0
  530. END SUBROUTINE EMISSION_NOX_DECLARE
  531. !EOC
  532. !--------------------------------------------------------------------------
  533. ! TM5 !
  534. !--------------------------------------------------------------------------
  535. !BOP
  536. !
  537. ! !IROUTINE: EMISSION_NOX_BB_DAILY_CYCLE
  538. !
  539. ! !DESCRIPTION: Impose daily burning cycle to BMB NOx emissions for current
  540. ! time step.
  541. !\\
  542. !\\
  543. ! !INTERFACE:
  544. !
  545. SUBROUTINE EMISSION_NOX_BB_DAILY_CYCLE( status )
  546. !
  547. ! !USES:
  548. !
  549. use dims, only : itaur, nsrce, tref, lm
  550. use dims, only : dx, xref, xbeg, yref, ybeg, ndyn_max
  551. use partools, only : myid
  552. use emission_data, only : emis_bb_trop_cycle, bb_cycle
  553. use datetime, only : tau2date
  554. !
  555. ! !OUTPUT PARAMETERS:
  556. !
  557. integer, intent(out) :: status
  558. !
  559. ! !REVISION HISTORY:
  560. ! 23 Jan 2014 - Jason Williams - V0
  561. !
  562. !EOP
  563. !------------------------------------------------------------------------
  564. !BOC
  565. character(len=*), parameter :: rname = mname//'/emission_nox_bb_daily_cycle'
  566. integer :: i,j,l,region, lmr, itim, ntim
  567. integer :: i1, i2, j1, j2, ipos, sec_in_day
  568. integer, dimension(6) :: idater
  569. real :: dtime, dtime2, xlon, xlat
  570. !
  571. REG: do region = 1, nregions
  572. !
  573. ! Re-initialize the bb NOx array
  574. !
  575. nox_emis_3d_bb_app(region)%d3 = 0.0
  576. call tau2date(itaur(region),idater)
  577. dtime = float(nsrce)/(2*tref(region)) ! emissions are added in two steps...XYZECCEZYX.
  578. dtime2 = float(ndyn_max)/(2*tref(region))
  579. ntim = 86400/nint(dtime2) ! number of timesteps in 24 hours.
  580. sec_in_day = idater(4)*3600 + idater(5)*60 + idater(6) ! elapsed seconds this day
  581. itim = sec_in_day/nint(dtime2)+1 ! time interval
  582. if(okdebug) then
  583. write(gol,*)'emission_nox_bb_daily_cycle in region ',region,' at date: ',idater, ' with time step:', dtime,' on ',myid
  584. call goPr
  585. end if
  586. CALL GET_DISTGRID( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  587. lmr = lm(region)
  588. if( emis_bb_trop_cycle) then
  589. do l=1,lmr
  590. do j=j1,j2
  591. do i=i1,i2
  592. xlat = ybeg(region) + (j-0.5)*dy/yref(region)
  593. if (xlat .gt. -20 .and. xlat .lt. 20) then
  594. ! apply emission cycle in tropics only
  595. ! itim = 1 and lon = -180 --->position 1
  596. ! itim = ntim ant lon = -180 --->position ntim, etc.
  597. ! itim = 1 and lon = 0 ---->position ntim/2
  598. xlon = xbeg(region) + (i-0.5)*dx/xref(region)
  599. ipos = 1 + mod(int((xlon+180.)*ntim/360.) + (itim-1),ntim) !position in array depending on time and lon.
  600. nox_emis_3d_bb_app(region)%d3(i,j,l) = nox_emis_3d_bb(region)%d3(i,j,l)*bb_cycle(region)%scalef(ipos)
  601. else
  602. nox_emis_3d_bb_app(region)%d3(i,j,l) = nox_emis_3d_bb(region)%d3(i,j,l)
  603. endif
  604. enddo
  605. enddo
  606. enddo
  607. else
  608. nox_emis_3d_bb_app(region)%d3 = nox_emis_3d_bb(region)%d3
  609. endif
  610. end do REG
  611. if(okdebug) then
  612. write(gol,*) 'end of emission_nox_bb_daily_cycle'; call goPr
  613. end if
  614. status=0
  615. END SUBROUTINE EMISSION_NOX_BB_DAILY_CYCLE
  616. #ifndef without_convection
  617. !--------------------------------------------------------------------------
  618. ! TM5 !
  619. !--------------------------------------------------------------------------
  620. !BOP
  621. !
  622. ! !IROUTINE: lightningNOx
  623. !
  624. ! !DESCRIPTION: Calculates NOx emissions from lightning as input for
  625. ! photochemistry module. NOx lightning is calculated using a linear
  626. ! relationship between lightning flashes and convective precipitation
  627. !
  628. ! * total annual production is approximately 5 Tg(N)/yr
  629. ! * marine lightning is ten times less active
  630. ! * fraction of cloud-to-ground over total flashes is determined by
  631. ! 4th order polynomial fit of the cold cloud thickness (Price and
  632. ! Rind, GRL 1993).
  633. ! * NOx production per IC and CG flash is according to Price et al,
  634. ! JGR, 1997.
  635. ! * vertical NOx profile is an approximation of the 'outflow' profile
  636. ! adopted from Pickering et al., JGR 1998.
  637. !
  638. ! Calculate distribution of lightning using cloudtop heights
  639. ! of deep convection, cloud cover and convective precipitation
  640. !
  641. ! Reference: E. Meijer, KNMI.
  642. ! Physics and Chemistry of the earth, Manuscript ST6.03-4
  643. !\\
  644. !\\
  645. ! !INTERFACE:
  646. !
  647. SUBROUTINE LIGHTNINGNOX(region, I1, J1, emilig, status)
  648. !
  649. ! !USES:
  650. !
  651. USE dims, only : im,jm,lm,ybeg,yref
  652. use Dims, only : CheckShape
  653. USE Binas, only : Avog
  654. use chem_param, only : xmn
  655. use partools, only : isRoot, par_reduce
  656. USE toolbox, only : ltropo_ifs, lvlpress
  657. USE meteodata, only : m_dat, phlb_dat
  658. use meteodata, only : temper_dat, gph_dat, cp_dat
  659. USE global_data, only : region_dat, conv_dat
  660. USE emission_data, only : plandr
  661. !
  662. ! !INPUT PARAMETERS:
  663. !
  664. integer, intent(in) :: region, i1, j1
  665. !
  666. ! !OUTPUT PARAMETERS:
  667. !
  668. real, intent(out) :: emilig(i1:,j1:,:) ! lighting emissions (kg N/s)
  669. integer, intent(out) :: status
  670. !
  671. ! !REVISION HISTORY:
  672. ! ? ??? 2001 - Ernst Meijer - Set up
  673. ! ? ??? 2002 - Olivie, van Weele - Revisions
  674. ! ? Jul 2002 - Frank Dentener - adapted for TM5
  675. ! ? Jan 2003 - Maarten krol - adapted for NEW TM5
  676. ! 1 Oct 2010 - Achim Strunk - protex
  677. ! 27 Jun 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  678. ! 21 Aug 2013 - Ph. Le Sager - update fscalelig for 1x1
  679. !
  680. ! !REMARKS:
  681. !
  682. !EOP
  683. !------------------------------------------------------------------------
  684. !BOC
  685. character(len=*), parameter :: rname = mname//'/lightningNOx'
  686. real, dimension(:,:,:), pointer :: phlb ! pressure (Pa) (1:lm+1)
  687. real, dimension(:,:,:), pointer :: m ! air mass (kg)
  688. real, dimension(:,:,:), pointer :: gph ! height (incl. oro)
  689. integer,dimension(:,:), pointer :: lutop ! cloud_top
  690. integer,dimension(:,:), pointer :: lubottom ! cloud base
  691. real,dimension(:), pointer :: dxyp ! area (m)
  692. real,dimension(:,:,:), pointer :: t ! temperature (K)
  693. real,dimension(:,:,:), pointer :: cp ! convective precipitation (mm/day)
  694. real,dimension(:,:), pointer :: plandregion ! landfraction (0-1)
  695. !
  696. real,dimension(:),allocatable :: gphx,tx
  697. real :: top ! cloudtop (km)
  698. real :: cldd ! cold cloud extension (km) (0 deg - tep)
  699. integer :: ibase ! base of cloud layer
  700. integer :: itropo ! tropopuase layer
  701. integer :: itop ! top of cloud layer
  702. integer :: itmin15 ! layer with the t=-15 isotherm
  703. integer :: itmin24 ! layer with the t=-24 isotherm
  704. integer :: it0 ! layer with the t= 0 isotherm
  705. !
  706. real :: cpc ! convective precipitation => (m s^-1)
  707. !
  708. real :: fl ! flash rate (1/s)
  709. real :: cg ! cloud-to-ground flashe rate (1/s)
  710. real :: ic ! intra-cloud flash rate (1/s)
  711. real :: pnocg,pnoic ! molecules NO produced per CG, IC flash
  712. ! DIAGNOSTIC variables
  713. real :: flashglob ! global flash frequency (1/s)
  714. real :: flashtrop ! tropical flash frequency (1/s)
  715. real :: ic_flashglob ! global flash frequency (1/s)
  716. real :: ic_flashtrop ! tropical flash frequency (1/s)
  717. real :: noxltrop ! tropical NOxL (kg/s)
  718. !
  719. logical :: cld ! flag for initialisation and cloud
  720. !
  721. integer :: i,j,l,ll,nlay,i2,j2
  722. real :: dsum
  723. real :: airmass
  724. integer :: level_pblh
  725. real :: xlat, dlat, tot_emilig
  726. logical :: lightning_output = .false. ! switch for diagnostic output
  727. logical :: lightning_output_2 = .false.
  728. ! for buggy MPI (see comment in budget_global.F90 for details)
  729. real :: flashglob_all, ic_flashglob_all, flashtrop_all, ic_flashtrop_all, noxltrop_all, tot_emilig_all
  730. ! --- begin --------------------------------
  731. CALL GET_DISTGRID( dgrid(region), I_STOP=i2, J_STOP=j2 )
  732. call CheckShape( (/i2-i1+1,j2-j1+1,lm(region)/), shape(emilig), status )
  733. IF_NOTOK_RETURN(status=1)
  734. m => m_dat (region)%data
  735. phlb => phlb_dat (region)%data
  736. cp => cp_dat (region)%data
  737. plandregion => plandr (region)%surf
  738. dxyp => region_dat (region)%dxyp
  739. lubottom => conv_dat (region)%cloud_base
  740. lutop => conv_dat (region)%cloud_top
  741. t => temper_dat (region)%data
  742. gph => gph_dat (region)%data
  743. !
  744. !
  745. allocate(gphx(0:lm(region))) ! note now from 0-->lm
  746. allocate(tx(lm(region)))
  747. !
  748. ! FD region coordinates are needed for determining statistics in tropics
  749. ! (-30 N,30N) and for excluding polar lightning (75N, 75 S) the emissions
  750. ! in parent regions containing a zoom are only set to zero after budget
  751. ! calculations using zoomed
  752. !
  753. ! Initialising statistics
  754. !
  755. flashglob = 0.
  756. flashtrop = 0.
  757. ic_flashglob = 0.
  758. ic_flashtrop = 0.
  759. noxltrop = 0.
  760. !
  761. ! initialising lightning emission
  762. !
  763. emilig(:,:,:) = 0. ! (im,jm,lm)
  764. dlat = dy/yref(region)
  765. !
  766. do j=j1,j2
  767. xlat = float(ybeg(region)) + j*dlat ! southern edge of gridbox
  768. if(xlat < -75.0 .or. (xlat+dlat) > 75.0) cycle ! exclude poles....
  769. do i=i1,i2
  770. !
  771. fl = 0.
  772. cldd = 0.
  773. cg = 0.
  774. ic = 0.
  775. !
  776. ibase = 0
  777. itop = 0
  778. itmin24 = 0
  779. itmin15 = 0
  780. it0 = 0
  781. !
  782. cld = .false.
  783. !
  784. cpc = cp(i,j,1)
  785. !old data cpc = cp(i,j,1) / 1000./86400. ! mm/day => m/s
  786. !
  787. if (cpc.gt.0.) then
  788. tx(:)=t(i,j,:)
  789. gphx(0:lm(region))=gph(i,j,1:lm(region)+1) !note the bounds
  790. ibase = lubottom(i,j)
  791. itop = lutop(i,j)
  792. itropo = ltropo_ifs(region,i,j,tx,lm(region))
  793. if (ibase.ne.0.and.itop.ne.0) then
  794. do l = itop, ibase, -1
  795. if (tx(l).le.249.15) itmin24=l
  796. if (tx(l).le.258.15) itmin15=l
  797. if (tx(l).le.273.15) it0 = l
  798. enddo !l
  799. top = (gphx(itop)+gphx(itop-1))/2000. ! cloud top (km)
  800. if (itmin24.ne.0.and.top.gt.5) then
  801. cld = .true. ! IF CLOUD REGIONS, IT IS A DEEP CLOUD
  802. if (itop.gt.itropo) itop = itropo
  803. if (it0 .gt.itropo) it0 = itropo
  804. endif ! itmin24
  805. endif !ibase ne 0
  806. !
  807. if (cld) then
  808. !fd top = (gphx(itop)+gphx(itop-1))/2000. ! cloud top (km)
  809. cldd= top - (gphx(it0)+gphx(it0-1))/2000. ! cold top (km)
  810. fl = fscalelig *4.e6 * cpc * dxyp(j)*1.e-12
  811. fl = (0.9*plandregion(i,j) + 0.1) * fl
  812. if (cldd.ge.5.5) then
  813. cg = fl / (.021*cldd**4-.648*cldd**3+7.493*cldd**2-36.54*cldd+64.09)
  814. ic = fl - cg
  815. else
  816. ! changed from [0.;fl] to [fl; fl-cg] (TvN, PLS, 22-04-2013)
  817. ! this increases the LiNOx by ~8.2 TgN/yr
  818. cg = fl
  819. ic = fl-cg
  820. endif !cldd
  821. ! Price et al. (JGR, 1997) assumed that cloud-ground flashed
  822. ! are 10 times more efficient in producing NOx than intraground flashes.
  823. ! They proposed a production efficiency of 6.7e26 and 6.7e25 molecules NO
  824. ! per CG and IC flash, respectively.
  825. ! These values were also adopted by Pickering et al. (JGR, 1998).
  826. ! Ridley et al. (Atm. Env., 2005) argued that the production efficiency
  827. ! is similar for both types, and Ott et al. (JGR, 2010)
  828. ! later come to a similar conclusion.
  829. !
  830. ! changed pnocg factor from 6.7e9 to 6.7e8 (TvN, PLS, 22-04-2013),
  831. ! the value used for pnoic
  832. !
  833. ! The new value of 6.7e25 molecules NO per flash corresponds
  834. ! to about 112 mol NO per flash, which is lower than current estimates.
  835. ! Ott et al. find a mean of 500 mol per flash,
  836. ! while Finney et al. (ACP, 2016) use 250 mol per flash in their model.
  837. ! Assuming these estimates to be realistic,
  838. ! this implies that the resolution dependent scale factor fscalelig
  839. ! can be written as the product of two factors:
  840. ! - a resolution independent factor that increases the production efficiency
  841. ! to more realistic value.
  842. ! Assuming a production efficiency between 250 and 500 mol per flash,
  843. ! this factor is in the range 2.2 to 4.5.
  844. ! - a resolution dependent factor that scales the flash rates.
  845. ! Currently we use an target total NOx production of 6.0 Tg N/yr,
  846. ! using meteorology for the reference year 2006.
  847. ! When ERA-Interim is used (also for the convective fluxes)
  848. ! this results in a scale factor of about 11 (see above).
  849. ! Then the scale factor for the flash rate is in the range 2.5 to 5.
  850. !
  851. ! Reducing the target (e.g to 3.0 TgN/yr),
  852. ! the scale factor for the flash rate would be reduced by proportionally.
  853. !
  854. ! The estimated range for the global NOx production from lightning
  855. ! based on the review by Schumann and Huntrieser (ACP, 2007)
  856. ! is 5 +- 3 Tg N/yr (or 2 to 8 Tg N/yr).
  857. !
  858. pnocg = 1e17*6.7e8*cg *xmn*1e-3/Avog
  859. pnoic = 1e17*6.7e8*ic *xmn*1e-3/Avog
  860. ! DISTRIBUTION of LNOx over the COLUMN
  861. !
  862. ! assume all IC-LNOx and 70% of CG-LNOx betweem t=-15 and cloudtop;
  863. ! assume 10% of CG-LNOx between EARTH SURFACE and t=-15
  864. ! assume 20% of CG-LNOx in BOUNDARY LAYER
  865. !
  866. ! To avoid dependency on the vertical resolution:
  867. ! - surface emission in lowest layers : boundary layer height;
  868. ! - LNOx within one of these three regions is distributed proportional to the mass
  869. ! of each layer.
  870. ! - the algorithm assumes that itropo is 3 or more. If it is less (typically 1 if
  871. ! not found and surface pressure is so low that the default at 100hPa is in the
  872. ! first layer), then we set it to 3, distributing 70% of GC in layer 2 and 10% in
  873. ! layer 1.
  874. dsum = 0.7*pnocg+pnoic
  875. ! determining nlay
  876. itropo=max(3,itropo) ! assumption of the algorithm
  877. itop = min(itop,itropo-1)
  878. nlay = itop - itmin15
  879. if (nlay.le.0) then
  880. itmin15=itop-1
  881. nlay = 1
  882. if (lightning_output_2) write(6,*) 'WARNING noxlight_cvp: itmin15>=itropo: ',i,j,itropo,itmin15
  883. endif !nlay le 0
  884. ! distributing according to airmass
  885. airmass = 0.
  886. do l=itmin15+1,itop
  887. airmass = airmass + m(i,j,l)
  888. enddo
  889. do l=itmin15+1,itop
  890. emilig(i,j,l) = dsum*m(i,j,l)/airmass
  891. enddo
  892. ! distributing 10% of CG LNOx between EARTH SURFACE and t=-15
  893. dsum = 0.1 * pnocg
  894. ! distributing according to air mass
  895. airmass = 0.
  896. do l=1,itmin15
  897. airmass = airmass + m(i,j,l)
  898. enddo
  899. do l=1,itmin15
  900. emilig(i,j,l) = emilig(i,j,l) + dsum*m(i,j,l)/airmass
  901. enddo
  902. ! distributing 20% of CG LNOx between ground pressure and 0.8*ground pressure
  903. dsum = 0.2 * pnocg
  904. level_pblh = lvlpress(region,0.8*phlb(i,j,1),phlb(i,j,1))
  905. ! distributing according to airmass
  906. airmass = 0.
  907. do l=1,level_pblh
  908. airmass = airmass + m(i,j,l)
  909. enddo
  910. do l=1,level_pblh
  911. emilig(i,j,l) = emilig(i,j,l) + dsum*m(i,j,l)/airmass
  912. enddo
  913. flashrate_lightning(region)%d23(i,j)=fl
  914. if (lightning_output) then ! CALCULATE GLOBAL/TROPICAL flash, NOxL rates
  915. flashglob = flashglob + fl
  916. ic_flashglob = ic_flashglob + ic
  917. select case(nint(xlat)) ! xlat is the southern edge of box j....
  918. case(-30:29)
  919. flashtrop = flashtrop + fl
  920. ic_flashtrop = ic_flashtrop + ic
  921. do l = 1, lm(region)
  922. noxltrop = noxltrop + emilig(i,j,l)
  923. enddo
  924. case default
  925. end select
  926. endif ! lightning_output
  927. endif !cld = .true.
  928. endif !cpc.gt.0.
  929. enddo !i
  930. enddo !j
  931. if (lightning_output) then
  932. call par_reduce( flashglob , 'sum', flashglob_all , status )
  933. call par_reduce( ic_flashglob , 'sum', ic_flashglob_all , status )
  934. call par_reduce( flashtrop , 'sum', flashtrop_all , status )
  935. call par_reduce( ic_flashtrop , 'sum', ic_flashtrop_all , status )
  936. call par_reduce( noxltrop , 'sum', noxltrop_all , status )
  937. tot_emilig = sum(emilig)
  938. call par_reduce( tot_emilig, 'sum', tot_emilig_all, status )
  939. if (isRoot) then
  940. write(gol,*) 'EMISS-INFO - global lightning frequency = ',flashglob_all,' s-1' ; call goPr
  941. write(gol,*) 'EMISS-INFO - ic global lightning frequency = ',ic_flashglob_all,' s-1' ; call goPr
  942. write(gol,*) 'EMISS-INFO - tropical lightning frequency = ',flashtrop_all,' s-1' ; call goPr
  943. write(gol,*) 'EMISS-INFO - ic tropical lightning frequency= ',ic_flashtrop_all,' s-1' ; call goPr
  944. write(gol,*) 'EMISS-INFO - global lightning emission : ',tot_emilig_all*1.e-9*365.*86400.,' Tg[N]/a' ; call goPr
  945. write(gol,*) 'EMISS-INFO - tropical lightning emission : ',noxltrop_all*1.e-9*365.*86400.,' Tg[N]/a' ; call goPr
  946. end if
  947. endif
  948. nullify(m)
  949. nullify(phlb)
  950. nullify(gph)
  951. nullify(cp)
  952. nullify(plandregion)
  953. nullify(lubottom)
  954. nullify(lutop)
  955. nullify(dxyp)
  956. nullify(t)
  957. deallocate(gphx)
  958. deallocate(tx)
  959. status=0
  960. END SUBROUTINE LIGHTNINGNOX
  961. #endif
  962. END MODULE EMISSION_NOX