sedimentation.F90 69 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819
  1. #define TRACEBACK write (gol,'("in ",a," (",a,i6,")")') rname, __FILE__, __LINE__ ; call goErr
  2. #define IF_NOTOK_RETURN(action) if (status/=0) then; TRACEBACK; action; return; end if
  3. #define IF_ERROR_RETURN(action) if (status> 0) then; TRACEBACK; action; return; end if
  4. !
  5. #include "tm5.inc"
  6. !
  7. !------------------------------------------------------------------------------
  8. ! TM5 !
  9. !------------------------------------------------------------------------------
  10. !BOP
  11. !
  12. ! !MODULE: SEDIMENTATION
  13. !
  14. ! !DESCRIPTION: This module calculates sedimentation of aerosol particles.
  15. ! Also the deposition at the surface is calculated here since
  16. ! it uses similar routines.
  17. !
  18. ! It is assumed that the distribution is described by nmodes log-normal
  19. ! distributions as described in chem_param.F90.
  20. !
  21. ! Each mode has a number and mass and a sigma_lognormal. Number and mass are
  22. ! related and the mean aerosol radius can thus be calculated for each mode.
  23. !
  24. ! mass=pi*4./3.*radius**3.*number*exp(9./2.*ln2s) /1e18*density, with:
  25. !
  26. ! density = density of aerosol type
  27. ! ln2s = (alog(sigma_lognormal(mode)))**2
  28. ! mass = mode mass
  29. ! number = mode number
  30. !
  31. ! mode1 : accumulation
  32. ! mode2 : coarse
  33. ! mode3 : super coarse (ss) coarse
  34. !
  35. ! For each mode a separate fall velocity is calculated according to the mass
  36. ! and number mean radii. Water take-up by seasalt particles is taken into
  37. ! account. This changes the density, radius, and sigma of the distribution.
  38. !
  39. ! Also included is the deposition calculation. based on a lookup table
  40. ! calculated for a reference aerosol density (e.g. 1800 kg/m3) and a number of
  41. ! radii. This deposition curve is convoluted with the number/volume
  42. ! distribution of the aerosols.
  43. !
  44. ! Again, for SS the water takeup is accounted for, and the effects on density,
  45. ! sigma and radius are calculated. The density has effect on the impaction
  46. ! term is the depotion calculation. This can be modeled by a shift in the
  47. ! radius. Thus the radii of the lookup table are adapted for density
  48. ! differences when impaction becomes important.
  49. !
  50. ! routine Sedimentation_Init : initialisation of sedimentation routine
  51. ! routine Sedimentation_Done : free memory
  52. ! routine sedimentation_calcv : calculate velocities
  53. ! routine deposition_calcv : calculate velocities
  54. ! routine Sedimentation_Apply : do the accutual sedimentation
  55. !\\
  56. !\\
  57. ! !INTERFACE:
  58. !
  59. MODULE SEDIMENTATION
  60. !
  61. ! !USES:
  62. !
  63. use GO, only: gol, goPr, goErr, goBug
  64. use GO, only: GO_Timer_Def, GO_Timer_End, GO_Timer_Start
  65. use Binas, only: grav, xmair, Avog
  66. use dims, only: nregions
  67. use tm5_distgrid, only: dgrid, Get_DistGrid, gather
  68. use partools, only: isRoot
  69. use global_types, only: d3_data, emis_data, aerosol_emis_data
  70. use chem_param, only: ntracet, imsa, inh4, ino3_a
  71. #ifdef with_m7
  72. use chem_param, only: inus_n, iso4nus, isoanus, iais_n, iso4ais, ibcais, ipomais, isoaais
  73. use chem_param, only: iacs_n, iso4acs, ibcacs, ipomacs, issacs, iduacs, isoaacs
  74. use chem_param, only: icos_n, iso4cos, ibccos, ipomcos, isscos, iducos, isoacos
  75. use chem_param, only: iaii_n, ibcaii, ipomaii, isoaaii, iaci_n, iduaci, icoi_n, iducoi
  76. #else
  77. use chem_param, only: iso4
  78. #endif
  79. use chem_param, only: nmod
  80. #ifdef with_budgets
  81. use budget_global, only: nbudg, nbud_vg, nzon_vg
  82. #endif
  83. IMPLICIT NONE
  84. PRIVATE
  85. !
  86. ! !PUBLIC MEMBER FUNCTIONS:
  87. !
  88. public Sedimentation_Init, Sedimentation_Done
  89. public Sedimentation_Apply
  90. public calculate_rh
  91. public aerosol_radius
  92. !
  93. ! !PUBLIC DATA MEMBERS:
  94. !
  95. real, dimension(nregions), public :: sum_drydep, sum_sedimentation ! budgets for tracer #1 (significant on root only)
  96. type(d3_data), dimension(nregions), public :: rh, rha ! rh (0-1), cloudfree vs. allsky
  97. #ifdef with_m7
  98. integer, parameter, public :: nsed=33 ! number of tracers for which sedimentation is applied
  99. integer, parameter, dimension(nsed), public :: ised = (/ inh4, ino3_a, imsa, &
  100. inus_n, iso4nus, isoanus, iais_n, iso4ais, ibcais, ipomais, isoaais, &
  101. iacs_n, iso4acs, ibcacs, ipomacs, issacs, iduacs, isoaacs, &
  102. icos_n, iso4cos, ibccos, ipomcos, isscos, iducos, isoacos, &
  103. iaii_n, ibcaii, ipomaii, isoaaii, iaci_n, iduaci, icoi_n, &
  104. iducoi /)
  105. #else
  106. ! sedimentation of few gas-phase species
  107. integer, parameter, public :: nsed= 4 ! number of tracers for which sedimentation is applied
  108. integer, parameter, dimension(nsed), public :: ised = (/ iso4, inh4, ino3_a, imsa /)
  109. #endif
  110. ! TB This was made public, to allow getting indices in AerChemMIP output
  111. integer, dimension(ntracet),public :: sindex ! pointer to match ntracet array with nsed
  112. !
  113. ! !PRIVATE DATA MEMBERS:
  114. !
  115. ! Mean values at the surface, per mode (i,j,mode)
  116. type(aerosol_emis_data), dimension(nregions) :: vn_deposition_mean ! number mean deposition velocity (m/s)
  117. type(aerosol_emis_data), dimension(nregions) :: vn_sedimentation_mean ! number mean sedim. velocity at surface (m/s)
  118. type(aerosol_emis_data), dimension(nregions) :: vm_deposition_mean ! mass mean deposition velocity (m/s)
  119. type(aerosol_emis_data), dimension(nregions) :: vm_sedimentation_mean ! mass mean sedim. velocity at surface (m/s)
  120. type(d3_data), dimension(nregions,nmod) :: vn_sedimentation ! number sedimentation velocities (Pa/s)
  121. type(emis_data), dimension(nregions,nmod) :: vn_deposition ! number deposition velocity (Pa/s)
  122. type(d3_data), dimension(nregions,nmod) :: vm_sedimentation ! mass sedimentation velocities (Pa/s)
  123. type(emis_data), dimension(nregions,nmod) :: vm_deposition ! mass deposition velocity (Pa/s)
  124. integer, dimension(nregions) :: n_deposition_mean ! counter
  125. integer, dimension(nregions) :: n_sedimentation_mean ! counter
  126. logical, parameter :: vd_in_deposition = .false. ! is sedimentation treated in deposition routine?
  127. integer, parameter :: ndp = 3 ! limit of the velocity to ndp times the layer thickness
  128. ! iteration will account for a fall length through multiple layers
  129. real, parameter :: m_to_pa = 7.24e16*grav*xmair*1e3/Avog !factor from m/s --> Pa/s
  130. !
  131. ! !PUBLIC TYPES:
  132. !
  133. #ifdef with_budgets
  134. ! budget terms on grid basis:
  135. type, public :: buddep_data
  136. real, dimension(:,:,:,:), pointer :: sed ! im,jm,nbud_vg,nsed
  137. end type buddep_data
  138. type(buddep_data),dimension(nregions),target,public :: buddep_m7_dat
  139. #endif
  140. integer :: itim_appl
  141. real :: sigma, density
  142. character(len=*), parameter :: mname = 'sedimentation'
  143. !
  144. ! !REVISION HISTORY:
  145. ! Feb 2004 by MK -
  146. ! 2 Apr 2010 - P. Le Sager - Optimize arrays de/allocation if m7 is not used.
  147. ! 19 Mar 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  148. !
  149. ! !REMARKS:
  150. ! (1) Only relative humidity is used when not using m7.
  151. ! (2) sedimentation is defined at the bottom of the gridbox (see init)
  152. ! (3) Note the switch from emiss_data to aerosol_emiss_data type for the
  153. ! *_mean variables (simplify and speedup mpi comm in sedimentation_done)
  154. !
  155. ! !TODO:
  156. !
  157. !EOP
  158. !------------------------------------------------------------------------------
  159. CONTAINS
  160. !------------------------------------------------------------------------------
  161. ! TM5 !
  162. !------------------------------------------------------------------------------
  163. !BOP
  164. !
  165. ! !IROUTINE: SEDIMENTATION_INIT
  166. !
  167. ! !DESCRIPTION: allocate memory, map ised
  168. !\\
  169. !\\
  170. ! !INTERFACE:
  171. !
  172. SUBROUTINE SEDIMENTATION_INIT ( status )
  173. !
  174. ! !USES:
  175. !
  176. use dims, only : lm, iglbsfc
  177. use chem_param, only : ntracet
  178. use meteodata, only : Set, spm_dat, temper_dat, humid_dat, cc_dat, phlb_dat
  179. use meteodata, only : lsp_dat, cp_dat
  180. !
  181. ! !OUTPUT PARAMETERS:
  182. !
  183. integer,intent(out) :: status
  184. !
  185. ! !REVISION HISTORY:
  186. ! 2 Apr 2010 - P. Le Sager - Added test on "with_m7"
  187. ! 20 Mar 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  188. !
  189. ! !REMARKS:
  190. !
  191. !EOP
  192. !------------------------------------------------------------------------------
  193. !BOC
  194. character(len=*), parameter :: rname = mname//'/Sedimentation_Init'
  195. integer :: region, lmr, i
  196. integer :: imode, n, i1, i2, j1, j2
  197. ! --- begin ---------------------------------
  198. ! meteo to be used
  199. do region = 1, nregions
  200. call Set( temper_dat(region), status, used=.true. )
  201. call Set( phlb_dat(region), status, used=.true. )
  202. call Set( humid_dat(region), status, used=.true. )
  203. call Set( cc_dat(region), status, used=.true. )
  204. call Set( lsp_dat(region), status, used=.true. )
  205. call Set( cp_dat(region), status, used=.true. )
  206. end do
  207. #ifdef with_m7
  208. ! Calculate mapping of ntracer to sedimentation arrays:
  209. sindex(:) = 0
  210. do i=1,nsed
  211. do n=1,ntracet
  212. if(ised(i) == n) sindex(n) = i
  213. enddo
  214. enddo
  215. #endif
  216. ! Allocate
  217. do region = 1, nregions
  218. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  219. lmr=lm(region)
  220. #ifdef with_m7
  221. #ifdef with_budgets
  222. sum_sedimentation(region) = 0.0
  223. sum_drydep(region) = 0.0
  224. allocate( buddep_m7_dat(region)%sed(i1:i2, j1:j2, nbud_vg, nsed) )
  225. buddep_m7_dat(region)%sed = 0.0
  226. #endif
  227. allocate(vn_deposition_mean (region)%surf(i1:i2, j1:j2, nmod)) ! defined at bottom of surface layer
  228. allocate(vn_sedimentation_mean(region)%surf(i1:i2, j1:j2, nmod)) ! defined at bottom of surface layer
  229. allocate(vm_sedimentation_mean(region)%surf(i1:i2, j1:j2, nmod)) ! defined at bottom of surface layer
  230. allocate(vm_deposition_mean (region)%surf(i1:i2, j1:j2, nmod)) ! defined at bottom of surface layer
  231. vn_deposition_mean (region)%surf = 0.0
  232. vn_sedimentation_mean(region)%surf = 0.0
  233. vm_sedimentation_mean(region)%surf = 0.0
  234. vm_deposition_mean (region)%surf = 0.0
  235. do imode = 1, nmod
  236. allocate(vn_sedimentation(region,imode)%d3 (i1:i2, j1:j2, lmr)) ! defined at bottom of layer
  237. allocate(vn_deposition (region,imode)%surf(i1:i2, j1:j2 )) ! defined at bottom of surface layer
  238. allocate(vm_sedimentation(region,imode)%d3 (i1:i2, j1:j2, lmr)) ! defined at bottom of layer
  239. allocate(vm_deposition (region,imode)%surf(i1:i2, j1:j2 )) ! defined at bottom of surface layer
  240. vn_sedimentation(region,imode)%d3 = 0.0
  241. vn_deposition (region,imode)%surf = 0.0
  242. vm_sedimentation(region,imode)%d3 = 0.0
  243. vm_deposition (region,imode)%surf = 0.0
  244. enddo
  245. #endif
  246. allocate( rh(region)%d3(i1:i2, j1:j2, lmr))
  247. allocate(rha(region)%d3(i1:i2, j1:j2, lmr))
  248. n_deposition_mean(region) = 0
  249. n_sedimentation_mean(region) = 0
  250. enddo
  251. call GO_Timer_Def( itim_appl, 'sedimentation appl', status )
  252. IF_NOTOK_RETURN(status=1)
  253. status = 0
  254. END SUBROUTINE SEDIMENTATION_INIT
  255. !EOC
  256. !------------------------------------------------------------------------------
  257. ! TM5 !
  258. !------------------------------------------------------------------------------
  259. !BOP
  260. !
  261. ! !IROUTINE: SEDIMENTATION_DONE
  262. !
  263. ! !DESCRIPTION: gather/aggregate/write budgets, and free memory
  264. !\\
  265. !\\
  266. ! !INTERFACE:
  267. !
  268. SUBROUTINE SEDIMENTATION_DONE( status )
  269. !
  270. ! !USES:
  271. !
  272. use io_hdf, only : DFACC_WRITE, io_write, DFNT_INT32
  273. use dims, only : im, jm
  274. #ifdef with_budgets
  275. use budget_global, only : budget_file_global, nbud_vg, budg_dat, nbudg, NHAB
  276. use file_hdf, only : THdfFile, TSds
  277. use file_hdf, only : Init, Done, WriteAttribute, WriteData, SetDim
  278. use Dims, only : region_name
  279. use partools, only : par_reduce_element
  280. #endif
  281. !
  282. ! !OUTPUT PARAMETERS:
  283. !
  284. integer, intent(out) :: status
  285. !
  286. ! !REMARKS:
  287. !
  288. !EOP
  289. !------------------------------------------------------------------------------
  290. !BOC
  291. character(len=*), parameter :: rname = mname//'/Sedimentation_Done'
  292. Integer :: region, i1, i2, j1, j2
  293. #ifdef with_m7
  294. #ifdef with_budgets
  295. type(THdfFile) :: io
  296. type(TSds) :: sds
  297. integer :: j, i, n, nzone, nzone_v
  298. real, dimension(nbudg, nbud_vg, nsed) :: budsedg
  299. real, dimension(nbudg, nbud_vg, nsed) :: budsedg_all ! for buggy MPI
  300. real, dimension(:,:), allocatable :: budget2d ! to gather budget terms on PEs
  301. real, dimension(:,:,:), allocatable :: budget3d
  302. real, dimension(:,:,:,:),allocatable :: budget4d
  303. #endif
  304. #endif
  305. integer :: imode
  306. ! --- begin ------------------------------
  307. #ifdef with_m7
  308. #ifdef with_budgets
  309. ! open file
  310. if( isRoot ) then
  311. call Init(io, budget_file_global, 'write', status)
  312. IF_NOTOK_RETURN(status=1)
  313. call WriteAttribute(io,'sum_drydep_m7',sum_drydep,status)
  314. IF_NOTOK_RETURN(status=1)
  315. call WriteAttribute(io,'sum_sedimentation_m7',sum_sedimentation,status)
  316. IF_NOTOK_RETURN(status=1)
  317. call WriteAttribute(io,'nsed',nsed,status)
  318. IF_NOTOK_RETURN(status=1)
  319. call WriteAttribute(io,'ised',ised,status)
  320. IF_NOTOK_RETURN(status=1)
  321. endif
  322. budsedg(:,:,:) = 0.0
  323. REG: do region=1,nregions
  324. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  325. !-- bin aggregated sed budget
  326. do n=1,nsed
  327. do j=j1,j2
  328. do i=i1,i2
  329. nzone = budg_dat(region)%nzong(i,j)
  330. budsedg(nzone,:,n) = budsedg(nzone,:,n) + buddep_m7_dat(region)%sed(i,j,:,n)
  331. end do
  332. end do
  333. end do
  334. !-- write Non-Horizontally-Aggregated-Budgets
  335. if (NHAB) then
  336. ! gather sed budget and write to file
  337. if (isRoot )then
  338. allocate(budget4d(im(region), jm(region), nbud_vg, nsed))
  339. else
  340. allocate(budget4d(1,1,1,1))
  341. end if
  342. call GATHER( dgrid(region), buddep_m7_dat(region)%sed, budget4d, 0, status)
  343. IF_NOTOK_RETURN(status=1)
  344. if(isRoot )then
  345. call Init(Sds,io, 'buddep_dat_sed_'//region_name(region),(/im(region),jm(region),nbud_vg,nsed/), 'real(4)', status)
  346. IF_NOTOK_RETURN(status=1)
  347. call WriteAttribute(Sds,'ised',ised,status)
  348. IF_NOTOK_RETURN(status=1)
  349. call SetDim(Sds, 0, 'im_'//region_name(region),'longitude', (/(j, j=1,im(region))/), status)
  350. call SetDim(Sds, 1, 'jm_'//region_name(region),'latitude', (/(j, j=1,jm(region))/), status)
  351. call SetDim(Sds, 2, 'nbud_vg','vertical layer', (/(j, j=1,nbud_vg)/), status)
  352. call SetDim(Sds, 3, 'nsed','sedimentation', (/(j, j=1,nsed)/), status)
  353. call WriteData(Sds, budget4d ,status)
  354. IF_NOTOK_RETURN(status=1)
  355. call Done(Sds, status)
  356. IF_NOTOK_RETURN(status=1)
  357. endif
  358. deallocate(budget4d)
  359. ! gather deposition velocities and write to file
  360. if (isRoot ) then
  361. allocate(budget3d(im(region), jm(region), nmod))
  362. else
  363. allocate(budget3d(1,1,1))
  364. end if
  365. call GATHER( dgrid(region), vn_deposition_mean(region)%surf, budget3d, 0, status)
  366. IF_NOTOK_RETURN(status=1)
  367. if(isRoot ) then
  368. if (n_deposition_mean(region)==0)then
  369. budget3d = 0.
  370. else
  371. budget3d = budget3d / n_deposition_mean(region)
  372. end if
  373. call Init(Sds,io, 'vd_n_'//region_name(region),(/im(region),jm(region),nmod/), 'real(4)', status)
  374. IF_NOTOK_RETURN(status=1)
  375. call SetDim(Sds, 0, 'im_'//region_name(region),'longitude', (/(j, j=1,im(region))/), status)
  376. IF_NOTOK_RETURN(status=1)
  377. call SetDim(Sds, 1, 'jm_'//region_name(region),'latitude', (/(j, j=1,jm(region))/), status)
  378. IF_NOTOK_RETURN(status=1)
  379. call SetDim(Sds, 2, 'nmodes','deposition modes', (/(j, j=1,nmod)/), status)
  380. IF_NOTOK_RETURN(status=1)
  381. call WriteData(Sds, budget3d ,status)
  382. IF_NOTOK_RETURN(status=1)
  383. call Done(Sds, status)
  384. IF_NOTOK_RETURN(status=1)
  385. endif
  386. ! gather and write deposition velocities (mass tracers)
  387. call GATHER( dgrid(region), vm_deposition_mean(region)%surf, budget3d, 0, status)
  388. IF_NOTOK_RETURN(status=1)
  389. if(isRoot ) then
  390. if (n_deposition_mean(region)==0)then
  391. budget3d = 0.
  392. else
  393. budget3d = budget3d / n_deposition_mean(region)
  394. end if
  395. call Init(Sds,io, 'vd_m_'//region_name(region),(/im(region),jm(region),nmod/), 'real(4)', status)
  396. IF_NOTOK_RETURN(status=1)
  397. call SetDim(Sds, 0, 'im_'//region_name(region),'longitude', (/(j, j=1,im(region))/), status)
  398. IF_NOTOK_RETURN(status=1)
  399. call SetDim(Sds, 1, 'jm_'//region_name(region),'latitude', (/(j, j=1,jm(region))/), status)
  400. IF_NOTOK_RETURN(status=1)
  401. call SetDim(Sds, 2, 'nmodes','deposition modes', (/(j, j=1,nmod)/), status)
  402. IF_NOTOK_RETURN(status=1)
  403. call WriteData(Sds, budget3d ,status)
  404. IF_NOTOK_RETURN(status=1)
  405. call Done(Sds, status)
  406. IF_NOTOK_RETURN(status=1)
  407. endif
  408. ! gather and write sedimentation velocities
  409. call GATHER( dgrid(region), vn_sedimentation_mean(region)%surf, budget3d, 0, status)
  410. IF_NOTOK_RETURN(status=1)
  411. if(isRoot ) then
  412. if (n_sedimentation_mean(region)==0)then
  413. budget3d = 0.
  414. else
  415. budget3d = budget3d / n_sedimentation_mean(region)
  416. end if
  417. call Init(Sds,io, 'vs_n_'//region_name(region),(/im(region),jm(region),nmod/), 'real(4)', status)
  418. IF_NOTOK_RETURN(status=1)
  419. call SetDim(Sds, 0, 'im_'//region_name(region),'longitude', (/(j, j=1,im(region))/), status)
  420. IF_NOTOK_RETURN(status=1)
  421. call SetDim(Sds, 1, 'jm_'//region_name(region),'latitude', (/(j, j=1,jm(region))/), status)
  422. IF_NOTOK_RETURN(status=1)
  423. call SetDim(Sds, 2, 'nmodes','deposition modes', (/(j, j=1,nmod)/), status)
  424. IF_NOTOK_RETURN(status=1)
  425. call WriteData(Sds, budget3d ,status)
  426. IF_NOTOK_RETURN(status=1)
  427. call Done(Sds, status)
  428. IF_NOTOK_RETURN(status=1)
  429. endif
  430. ! gather and write sedimentation velocities (mass tracers)
  431. call GATHER( dgrid(region), vm_sedimentation_mean(region)%surf, budget3d, 0, status)
  432. IF_NOTOK_RETURN(status=1)
  433. if(isRoot) then
  434. if (n_sedimentation_mean(region)==0)then
  435. budget3d = 0.
  436. else
  437. budget3d = budget3d / n_sedimentation_mean(region)
  438. end if
  439. call Init(Sds,io, 'vs_m_'//region_name(region),(/im(region),jm(region),nmod/), 'real(4)', status)
  440. IF_NOTOK_RETURN(status=1)
  441. call SetDim(Sds, 0, 'im_'//region_name(region),'longitude', (/(j, j=1,im(region))/), status)
  442. IF_NOTOK_RETURN(status=1)
  443. call SetDim(Sds, 1, 'jm_'//region_name(region),'latitude', (/(j, j=1,jm(region))/), status)
  444. IF_NOTOK_RETURN(status=1)
  445. call SetDim(Sds, 2, 'nmodes','deposition modes', (/(j, j=1,nmod)/), status)
  446. IF_NOTOK_RETURN(status=1)
  447. call WriteData(Sds, budget3d ,status)
  448. IF_NOTOK_RETURN(status=1)
  449. call Done(Sds, status)
  450. IF_NOTOK_RETURN(status=1)
  451. endif
  452. deallocate(budget3d)
  453. endif ! NHAB
  454. enddo REG ! regions
  455. !------- Gather and write aggregated budget
  456. ! Sum up contribution from each proc into root array
  457. call PAR_REDUCE_ELEMENT( budsedg, 'SUM', budsedg_all, status )
  458. IF_NOTOK_RETURN(status=1)
  459. if(isRoot )then
  460. call Init(Sds, io, 'budsed_m7', (/nbudg,nbud_vg,nsed/), 'real(8)', status)
  461. IF_NOTOK_RETURN(status=1)
  462. call SetDim(Sds, 0, 'nbudg', 'horizontal region', (/(j, j=1,nbudg)/), status)
  463. call SetDim(Sds, 1, 'nbud_vg', 'vertical layer', (/(j, j=1,nbud_vg)/), status)
  464. call SetDim(Sds, 2, 'nsed', 'sedimentation', (/(j, j=1,nsed)/), status)
  465. IF_NOTOK_RETURN(status=1)
  466. call WriteData(Sds, budsedg_all, status)
  467. IF_NOTOK_RETURN(status=1)
  468. call Done(Sds, status)
  469. IF_NOTOK_RETURN(status=1)
  470. call Done(io, status)
  471. IF_NOTOK_RETURN(status=1)
  472. endif
  473. #endif /* BUDGET */
  474. #endif /* M7 */
  475. !-------- Done
  476. do region = 1, nregions
  477. #ifdef with_m7
  478. #ifdef with_budgets
  479. deallocate( buddep_m7_dat(region)%sed)
  480. #endif
  481. deallocate( vn_deposition_mean (region)%surf )
  482. deallocate( vn_sedimentation_mean(region)%surf )
  483. deallocate( vm_deposition_mean (region)%surf )
  484. deallocate( vm_sedimentation_mean(region)%surf )
  485. do imode = 1, nmod
  486. deallocate(vn_sedimentation(region,imode)%d3 )
  487. deallocate(vn_deposition (region,imode)%surf)
  488. deallocate(vm_sedimentation(region,imode)%d3 )
  489. deallocate(vm_deposition (region,imode)%surf)
  490. enddo
  491. #endif
  492. deallocate(rh(region)%d3)
  493. deallocate(rha(region)%d3)
  494. enddo
  495. status = 0
  496. END SUBROUTINE SEDIMENTATION_DONE
  497. !EOC
  498. !------------------------------------------------------------------------------
  499. ! TM5 !
  500. !------------------------------------------------------------------------------
  501. !BOP
  502. !
  503. ! !IROUTINE: DEPOSITION_CALCV
  504. !
  505. ! !DESCRIPTION: calculate velocities
  506. !\\
  507. !\\
  508. ! !INTERFACE:
  509. !
  510. SUBROUTINE DEPOSITION_CALCV( region, status )
  511. !
  512. ! !USES:
  513. !
  514. use global_data, only : mass_dat, region_dat
  515. use meteodata, only : spm_dat, temper_dat, cc_dat
  516. use chem_param, only : sigma_lognormal, density_ref
  517. use chem_param, only : mode_start, mode_end, names
  518. use dims, only : at, bt, nsrce, tref, im, jm, lm, okdebug
  519. use chem_param, only : nrdep, lur
  520. use dry_deposition, only : vd=>vda
  521. use binas, only : pi
  522. use partools, only : par_reduce
  523. #ifdef with_m7
  524. use m7_data, only : dens_mode, rw_mode ! density (kg/m3) r (m)
  525. #endif
  526. !
  527. ! !INPUT PARAMETERS:
  528. !
  529. integer, intent(in) :: region
  530. !
  531. ! !OUTPUT PARAMETERS:
  532. !
  533. integer, intent(out) :: status
  534. !
  535. ! !REVISION HISTORY:
  536. ! 2 Apr 2010 - P. Le Sager -
  537. ! 21 Mar 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  538. !
  539. ! !REMARKS:
  540. ! (1) Called only if m7 used.
  541. !
  542. !EOP
  543. !------------------------------------------------------------------------------
  544. !BOC
  545. character(len=*), parameter :: rname = mname//'/DEPOSITION_CALCV'
  546. real, dimension(:,:,:), pointer :: p ! surface pressure (Pa)
  547. real, dimension(:,:,:), pointer :: t ! temperature (K)
  548. real, dimension(:,:,:), pointer :: cc ! cloud_cover (0-1)
  549. real, dimension(:,:,:,:), pointer :: rm ! tracer array (kg)
  550. real :: pb ! pressure at bottom of box (Pa)
  551. real :: dt ! general timestep (s)
  552. real :: dp ! pressure difference layer
  553. integer :: i,j,l, mode, n, proc, itn, itracer
  554. real :: temp ! temperature
  555. real :: to_pascal
  556. real, dimension(nmod) :: lns
  557. real :: radius
  558. real, dimension(nmod,2) :: vd_mean_all, vd_max_all
  559. real, dimension(nmod,2) :: vd_mean, vd_max
  560. integer, dimension(nmod,2) :: nvd, nvd_all
  561. real, dimension(nmod) :: r_mean_all, r_max_all
  562. real, dimension(nmod) :: r_mean, r_max
  563. integer, dimension(nmod) :: nr, nr_all
  564. real, dimension(nrdep) :: d_aer ! diameter vd loopup table (um)
  565. real, dimension(nrdep) :: nnumb,nvolume ! number and volume distribution
  566. real, dimension(nrdep) :: vdi ! for the integration
  567. real, dimension(nrdep) :: vdi_def ! for the integration
  568. real, dimension(nrdep) :: lure ! effective loo
  569. real, dimension(nrdep) :: ddpi ! integration bin-sizes
  570. real, dimension(nrdep+1) :: dlogdp,ddp ! integration edges
  571. real, dimension(nrdep) :: logdp,logde ! log(diameter)
  572. real :: dpg, ntot, vt
  573. real :: lnsigma, rho_aer, sigma
  574. integer :: ir, ir1, nshift, nrd, nglob
  575. integer :: i1, i2, j1, j2
  576. !________________________start_________________________________
  577. nullify(rm)
  578. nullify(p)
  579. nullify(t)
  580. nullify(cc)
  581. rm => mass_dat (region)%rm
  582. p => spm_dat (region)%data
  583. t => temper_dat(region)%data
  584. cc => cc_dat (region)%data
  585. dt = float(nsrce)/(2*tref(region)) ! timestep
  586. do mode =1,nmod
  587. lns(mode) = log(sigma_lognormal(mode))
  588. enddo
  589. ! calculate the binsizes (um) around the radii of the pre-calculated vd's
  590. d_aer = 2.0*lur ! diameter (um)
  591. logdp = log10(d_aer) ! log(diameter)
  592. n_deposition_mean(region) = n_deposition_mean(region) + 1
  593. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  594. if (okdebug) then
  595. if (isRoot) then
  596. write(gol,*) '________________________________________________________________________________' ; call goPr
  597. write(gol,*) 'Statistics for the deposition routine:' ; call goPr
  598. write(gol,*) '________________________________________________________________________________' ; call goPr
  599. write(gol,*) 'level mode r_mean r_max(um) vd_n(cm/s) vd_max(cm/s) vd_m(cm/s) vd_mmax(cm/s) ' ; call goPr
  600. write(gol,*) '________________________________________________________________________________' ; call goPr
  601. end if
  602. vd_mean = 0.0
  603. r_mean = 0.0
  604. vd_max = 0.0
  605. r_max = 0.0
  606. nvd = 0
  607. nr = 0
  608. endif
  609. !$OMP PARALLEL &
  610. !$OMP default (none) &
  611. !$OMP shared (region, t, at, bt, p, dt, vd, &
  612. !$OMP rm, rh, logdp, &
  613. !$OMP vn_deposition_mean, vn_deposition, vm_deposition_mean, vm_deposition, &
  614. !$OMP lur, sigma_lognormal, mode_start, mode_end) &
  615. !$OMP shared (okdebug, vd_mean, vd_max, nvd, r_max, r_mean, nr) &
  616. #ifdef with_m7
  617. !$OMP shared (rw_mode, dens_mode) &
  618. #endif
  619. !$OMP private (i, j, l, temp, pb, dp, to_pascal, vdi_def, &
  620. !$OMP itn, radius, vdi, sigma, lnsigma, density, &
  621. !$OMP lure, dlogdp, logde, nshift, nrd, &
  622. !$OMP ddp, ddpi, d_aer, dpg, ntot, nnumb, nvolume, vt)
  623. l = 1
  624. do j=j1,j2
  625. do i=i1,i2
  626. temp = t(i,j,1) ! at surface to temp box
  627. pb = at(l) + bt(l)*p(i,j,1) ! pressure at bottom of box (Pa)
  628. dp = (at(l)-at(l+1)) + p(i,j,1)*(bt(l)-bt(l+1)) ! layer thickness
  629. to_pascal = m_to_pa*dt*pb/temp ! convert from m/s ---> Pa/timestep
  630. do n=1,nrdep
  631. vdi_def(n) = vd(region,n)%surf(i,j)
  632. enddo
  633. #ifdef with_m7
  634. M7MODES: do mode = 1, nmod
  635. itn = mode_start(mode) ! position of number tracer
  636. ! compute radius:
  637. radius = rw_mode(region,mode)%d3(i,j,1)
  638. ! initial deposition velocities for increasing radia:
  639. vdi = vdi_def
  640. sigma = sigma_lognormal(mode)
  641. lnsigma = log(sigma)
  642. density = dens_mode(region,mode)%d3(i,j,1)
  643. if(okdebug) then
  644. if(radius > tiny(radius)) then
  645. r_mean(mode) = r_mean(mode) + radius
  646. nr(mode) = nr(mode) + 1
  647. r_max(mode) = max(r_max(mode), radius)
  648. endif
  649. endif
  650. RADENS: if (radius > 1e-11 .and. density > 1e-2) then
  651. ! account for density different than density_ref of the look-up table (lur --> vdi):
  652. lure(:) = lur(:)
  653. logde(:) = logdp(:)
  654. do ir = 2, nrdep
  655. if(vdi(ir) > vdi(ir-1)) exit ! for bigger r's : impaction dominates (density effects)
  656. if ( ir == nrdep ) exit ! trap upper boundary
  657. enddo
  658. do ir1 = ir, nrdep
  659. lure(ir1) = lur(ir1)*sqrt(density_ref/density)
  660. logde(ir1) = log10(2*lure(ir1))
  661. enddo
  662. ! compress look-up table such that radii are increasing monotonic:
  663. nshift = 0
  664. ir1 = ir
  665. do
  666. if ( logde(ir1) > logde(ir-1) ) exit
  667. nshift = nshift + 1
  668. ir = ir -1
  669. if(ir == 1) exit
  670. enddo
  671. nrd = nrdep - nshift
  672. if (nshift > 0) then
  673. do ir1 = ir, nrd
  674. logde(ir1) = logde(ir1+nshift)
  675. lure(ir1) = lure(ir1+nshift)
  676. vdi(ir1) = vdi(ir1+nshift)
  677. enddo
  678. endif
  679. ! do the integration of the shifted lookup table:
  680. dlogdp(1) = -3.0
  681. do ir=2,nrd
  682. dlogdp(ir) = 0.5*(logde(ir-1)+logde(ir)) ! take middle of the log scale
  683. enddo
  684. dlogdp(nrd+1) = 3.0 ! 1000 um
  685. ddp(1:nrd+1) = 10**dlogdp(1:nrd+1)
  686. ddpi(1:nrd) = ddp(2:nrd+1)-ddp(1:nrd) ! integration intervals (um)
  687. d_aer(1:nrd) = 2.0*lure(1:nrd)
  688. ! perform convolution with log-normal distribution:
  689. dpg = 2*radius*1e6 ! diameter in um
  690. ntot = rm(i,j,1,itn)
  691. ! calculate the distribution (number and mass) over the deposition bins:
  692. if(ntot > 1.0 .and. radius > tiny(radius) ) then ! you need some aerosol!
  693. do n=1,nrd
  694. nnumb(n) = ntot/(sqrt(2.*pi)*d_aer(n)*lnsigma)*exp(-(log(d_aer(n))-log(dpg))**2/(2*lnsigma**2))
  695. nvolume(n) = nnumb(n)*(pi/6.0)*d_aer(n)**3
  696. enddo
  697. vt = sum(nnumb(1:nrd)*ddpi(1:nrd)*vdi(1:nrd))/sum(nnumb(1:nrd)*ddpi(1:nrd))
  698. else
  699. vt = 0.0
  700. endif
  701. vn_deposition_mean(region)%surf(i,j,mode) = vn_deposition_mean(region)%surf(i,j, mode) + vt
  702. vn_deposition(region,mode)%surf(i,j) = min(to_pascal*vt,ndp*dp) ! in Pa/timestep downwards
  703. if(okdebug) then
  704. if ( vt > tiny(vt) ) then
  705. vd_mean(mode,1) = vd_mean(mode,1) + vt
  706. vd_max(mode,1) = max(vd_max(mode,1) , vt)
  707. nvd(mode,1) = nvd(mode,1) + 1
  708. endif
  709. endif
  710. ! for mass:
  711. if(ntot > 1.0 .and. radius > tiny(radius) ) then ! you need some aerosol!
  712. vt = sum(nvolume(1:nrd)*ddpi(1:nrd)*vdi(1:nrd))/sum(nvolume(1:nrd)*ddpi(1:nrd))
  713. else
  714. vt = 0.0
  715. endif
  716. vm_deposition_mean(region)%surf(i,j, mode) = vm_deposition_mean(region)%surf(i,j, mode) + vt
  717. vm_deposition(region,mode)%surf(i,j) = min(to_pascal*vt,ndp*dp) ! in Pa/timestep downwards
  718. if(okdebug) then
  719. if ( vt > tiny(vt) ) then
  720. vd_mean(mode,2) = vd_mean(mode,2) + vt
  721. vd_max(mode,2) = max(vd_max(mode,2) , vt)
  722. nvd(mode,2) = nvd(mode,2) + 1
  723. endif
  724. endif !
  725. else
  726. vm_deposition(region,mode)%surf(i,j) = 0.0
  727. vn_deposition(region,mode)%surf(i,j) = 0.0
  728. endif RADENS
  729. end do M7MODES
  730. #endif /* M7 */
  731. enddo !i
  732. enddo !j
  733. !$OMP END PARALLEL
  734. if(okdebug) then
  735. do mode = 1, nmod
  736. call Par_reduce( r_mean(mode) , 'sum', r_mean_all(mode) , status)
  737. IF_NOTOK_RETURN(status=1)
  738. call Par_reduce( nr(mode) , 'sum', nr_all(mode) , status)
  739. IF_NOTOK_RETURN(status=1)
  740. call Par_reduce( r_max(mode) , 'max', r_max_all(mode) , status)
  741. IF_NOTOK_RETURN(status=1)
  742. call Par_reduce( vd_mean(mode,1), 'sum', vd_mean_all(mode,1), status)
  743. IF_NOTOK_RETURN(status=1)
  744. call Par_reduce( nvd(mode,1) , 'sum', nvd_all(mode,1) , status)
  745. IF_NOTOK_RETURN(status=1)
  746. call Par_reduce( vd_max(mode,1) , 'max', vd_max_all(mode,1) , status)
  747. IF_NOTOK_RETURN(status=1)
  748. call Par_reduce( vd_mean(mode,2), 'sum', vd_mean_all(mode,2), status)
  749. IF_NOTOK_RETURN(status=1)
  750. call Par_reduce( nvd(mode,2) , 'sum', nvd_all(mode,2) , status)
  751. IF_NOTOK_RETURN(status=1)
  752. call Par_reduce( vd_max(mode,2) , 'max', vd_max_all(mode,2) , status)
  753. IF_NOTOK_RETURN(status=1)
  754. if (isRoot) then
  755. if(nr_all(mode) > 0) then
  756. r_mean_all(mode) = r_mean_all(mode)*1e6/nr_all(mode)
  757. else
  758. r_mean_all(mode) = 0.
  759. end if
  760. if(nvd_all(mode,1) > 0) then
  761. vd_mean_all(mode,1) = 1e2*vd_mean_all(mode,1)/nvd_all(mode,1)
  762. else
  763. vd_mean_all(mode,1) = 0.
  764. end if
  765. if(nvd_all(mode,2) > 0) then
  766. vd_mean_all(mode,2) = 1e2*vd_mean_all(mode,2)/nvd_all(mode,2)
  767. else
  768. vd_mean_all(mode,2) = 0.
  769. end if
  770. print '(i6,i4,2f10.4,2f12.6,2f12.6)', 0, mode, r_mean_all(mode), 1e6*r_max_all(mode), &
  771. vd_mean_all(mode,1), 1e2*vd_max_all(mode,1), vd_mean_all(mode,2), 1e2*vd_max_all(mode,2)
  772. end if
  773. enddo
  774. write(gol,*) '________________________________________________________________________________' ; call goPr
  775. endif
  776. status=0
  777. END SUBROUTINE DEPOSITION_CALCV
  778. !EOC
  779. !------------------------------------------------------------------------------
  780. ! TM5 !
  781. !------------------------------------------------------------------------------
  782. !BOP
  783. !
  784. ! !IROUTINE: SEDIMENTATION_CALCV
  785. !
  786. ! !DESCRIPTION: calculate velocities
  787. !\\
  788. !\\
  789. ! !INTERFACE:
  790. !
  791. SUBROUTINE SEDIMENTATION_CALCV(region, status)
  792. !
  793. ! !USES:
  794. !
  795. use global_data, only : mass_dat, region_dat
  796. use meteodata, only : spm_dat, temper_dat, cc_dat
  797. use chem_param, only : sigma_lognormal, names, mode_start, mode_end
  798. use dims, only : at, bt, nsrce, tref, im, jm, lm, okdebug
  799. #ifdef with_m7
  800. use m7_data, only : rw_mode, dens_mode
  801. #endif
  802. use partools, only : par_reduce
  803. !
  804. ! !INPUT PARAMETERS:
  805. !
  806. integer, intent(in) :: region
  807. !
  808. ! !OUTPUT PARAMETERS:
  809. !
  810. integer, intent(out) :: status
  811. !
  812. ! !REVISION HISTORY:
  813. ! 2 Apr 2010 - P. Le Sager -
  814. ! 21 Mar 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  815. !
  816. ! !REMARKS:
  817. ! (1) Called only if m7 used.
  818. !
  819. !EOP
  820. !------------------------------------------------------------------------------
  821. !BOC
  822. character(len=*), parameter :: rname = mname//'/Sedimentation_calcv'
  823. real, dimension(:,:,:), pointer :: p ! surface pressure (Pa)
  824. real, dimension(:,:,:), pointer :: t ! temperature (K)
  825. real, dimension(:,:,:), pointer :: cc ! cloud cover (0-1)
  826. real, dimension(:,:,:), pointer :: q ! humidity (kg/kg)
  827. real, dimension(:,:,:,:), pointer :: rm ! tracer array (kg)
  828. real :: pb ! pressure at bottom of box (Pa)
  829. real :: dt ! general timestep (s)
  830. real :: dp ! pressure difference layer
  831. integer :: i,j,l, mode, proc, itn, n, nglob
  832. real :: temp ! temperature
  833. real :: to_pascal
  834. real :: slinnfac
  835. real :: zvis, rho_air, radius, Dpg, vt
  836. real, dimension(nmod,2) :: vd_mean_all, vd_max_all
  837. real, dimension(nmod,2) :: vd_mean, vd_max
  838. integer, dimension(nmod,2) :: nvd, nvd_all
  839. real, dimension(nmod) :: r_mean_all, r_max_all
  840. real, dimension(nmod) :: r_mean, r_max
  841. integer, dimension(nmod) :: nr, nr_all
  842. real :: lnsigma, sigma
  843. integer :: i1, j1, i2, j2
  844. !________________________start_________________________________
  845. nullify(rm)
  846. nullify(p)
  847. nullify(cc)
  848. nullify(t)
  849. p => spm_dat (region)%data
  850. t => temper_dat(region)%data
  851. cc => cc_dat (region)%data
  852. rm => mass_dat (region)%rm
  853. dt = float(nsrce)/(2*tref(region)) ! timestep
  854. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  855. ! transfer sedimentation vel. from m/s to Pa/s (note define this as positive = falling)
  856. ! dp = -rho*g*dz
  857. ! rho is calculated from temperature and pressure....
  858. ! 7.24e16*p/T (#/cm3) (pV=nRT--> nR/V = p/T )
  859. ! #/cm3 ---> kg/m3 f = xmair*1e3/Avog
  860. ! Thus: rho (kg/m3) = 7.24e16*p/T * xmair*1e3/Avog
  861. ! and (dPa) = -rho*g*(vdep)*dt = -7.24e16*grav*xmair*1e3/Avog * (p/T) *dt
  862. n_sedimentation_mean(region) = n_sedimentation_mean(region) + 1
  863. if(okdebug.and.isRoot) then
  864. write(gol,*) '________________________________________________________________________________' ; call goPr
  865. write(gol,*) 'Statistics for the sedimentation routine:' ; call goPr
  866. write(gol,*) '________________________________________________________________________________' ; call goPr
  867. write(gol,*) 'level mode r_mean r_max(um) vd_n(cm/s) vd_max(cm/s) vd_m(cm/s) vd_mmax(cm/s) ' ; call goPr
  868. write(gol,*) '________________________________________________________________________________' ; call goPr
  869. endif
  870. #ifdef with_m7
  871. !$OMP PARALLEL &
  872. !$OMP default (none) &
  873. !$OMP shared (region, t, at, bt, p, dt, &
  874. !$OMP rm, lm, &
  875. !$OMP vn_sedimentation_mean, vn_sedimentation, vm_sedimentation_mean, vm_sedimentation, &
  876. !$OMP sigma_lognormal, mode_start, mode_end) &
  877. !$OMP shared (okdebug, vd_mean, vd_max, nvd, r_max, r_mean, nr) &
  878. !$OMP shared (rw_mode, dens_mode) &
  879. !$OMP private (i, j, l, temp, pb, dp, zvis, rho_air, &
  880. !$OMP to_pascal, mode, itn, radius, sigma, lnsigma, &
  881. !$OMP density, slinnfac, dpg, vt)
  882. LEVS: do l=1, lm(region)
  883. if(okdebug) then
  884. vd_mean = 0.0
  885. r_mean = 0.0
  886. vd_max = 0.0
  887. r_max = 0.0
  888. nvd = 0
  889. nr = 0
  890. endif
  891. do j=j1, j2
  892. do i=i1, i2
  893. if(l == 1) then
  894. temp = t(i,j,1) ! at surface to temp box
  895. else
  896. temp = 0.5*(t(i,j,l)+t(i,j,l-1)) ! interpolate to bottom of box
  897. endif
  898. pb = at(l) + bt(l)*p(i,j,1) ! pressure at bottom of box (Pa)
  899. dp = (at(l)-at(l+1)) + p(i,j,1)*(bt(l)-bt(l+1)) ! layer thickness
  900. zvis = 0.0000014963*temp*sqrt(temp)/(temp+120.) ! viscocity (kg/ms)
  901. rho_air = 7.24e16*pb/temp * xmair*1e3/Avog ! kg/m3
  902. to_pascal = m_to_pa*dt*pb/temp ! convert from m/s ---> Pa/timestep
  903. M7MODES: do mode = 1, nmod
  904. radius = rw_mode(region,mode)%d3(i,j,l)
  905. sigma = sigma_lognormal(mode)
  906. lnsigma = log(sigma)
  907. density = dens_mode(region,mode)%d3(i,j,l)
  908. slinnfac = exp(2.0*lnsigma*lnsigma)
  909. if(okdebug) then
  910. if(radius > tiny(radius)) then
  911. r_mean(mode) = r_mean(mode) + radius
  912. nr(mode) = nr(mode) + 1
  913. r_max(mode) = max(r_max(mode), radius)
  914. endif
  915. endif
  916. ! for number: take first mode (Seinfeld, 1986, pg 286)
  917. dpg = radius*2.0*exp(lnsigma*lnsigma) ! diameter in m
  918. vt = fall1(pb,Dpg,zvis,temp,rho_air,density)
  919. if(okdebug) then
  920. if ( vt > tiny(vt) ) then
  921. vd_mean(mode,1) = vd_mean(mode,1) + vt
  922. vd_max(mode,1) = max(vd_max(mode,1) , vt)
  923. nvd(mode,1) = nvd(mode,1) + 1
  924. endif
  925. endif
  926. vn_sedimentation(region,mode)%d3(i,j,l) = min(to_pascal*vt,ndp*dp) ! in Pa/timestep downwards
  927. if(l == 1) then
  928. vn_sedimentation_mean(region)%surf(i,j,mode) = &
  929. vn_sedimentation_mean(region)%surf(i,j,mode) + vt
  930. endif
  931. ! for mass: the third moment
  932. dpg = radius*2.0*exp(3*lnsigma*lnsigma) ! diameter in m
  933. vt = fall1(pb,Dpg,zvis,temp,rho_air,density)
  934. if(okdebug) then
  935. if ( vt > tiny(vt) ) then
  936. vd_mean(mode,2) = vd_mean(mode,2) + vt*slinnfac
  937. vd_max(mode,2) = max(vd_max(mode,2) , vt*slinnfac)
  938. nvd(mode,2) = nvd(mode,2) + 1
  939. endif
  940. endif
  941. vm_sedimentation(region,mode)%d3(i,j,l) = min(to_pascal*vt*slinnfac,ndp*dp) ! multiply with slinnfac
  942. if(l == 1) then
  943. vm_sedimentation_mean(region)%surf(i,j,mode) = &
  944. vm_sedimentation_mean(region)%surf(i,j,mode) + vt*slinnfac
  945. endif
  946. enddo M7MODES
  947. enddo ! i
  948. enddo ! j
  949. if(okdebug) then
  950. do mode = 1, nmod
  951. call Par_reduce( r_mean(mode) , 'sum', r_mean_all(mode) , status)
  952. IF_NOTOK_RETURN(status=1)
  953. call Par_reduce( nr(mode) , 'sum', nr_all(mode) , status)
  954. IF_NOTOK_RETURN(status=1)
  955. call Par_reduce( r_max(mode) , 'max', r_max_all(mode) , status)
  956. IF_NOTOK_RETURN(status=1)
  957. call Par_reduce( vd_mean(mode,1), 'sum', vd_mean_all(mode,1), status)
  958. IF_NOTOK_RETURN(status=1)
  959. call Par_reduce( nvd(mode,1) , 'sum', nvd_all(mode,1) , status)
  960. IF_NOTOK_RETURN(status=1)
  961. call Par_reduce( vd_max(mode,1) , 'max', vd_max_all(mode,1) , status)
  962. IF_NOTOK_RETURN(status=1)
  963. call Par_reduce( vd_mean(mode,2), 'sum', vd_mean_all(mode,2), status)
  964. IF_NOTOK_RETURN(status=1)
  965. call Par_reduce( nvd(mode,2) , 'sum', nvd_all(mode,2) , status)
  966. IF_NOTOK_RETURN(status=1)
  967. call Par_reduce( vd_max(mode,2) , 'max', vd_max_all(mode,2) , status)
  968. IF_NOTOK_RETURN(status=1)
  969. if (isRoot) then
  970. if(nr_all(mode) > 0) then
  971. r_mean_all(mode) = r_mean_all(mode)*1e6/nr_all(mode)
  972. else
  973. r_mean_all(mode) = 0.
  974. end if
  975. if(nvd_all(mode,1) > 0) then
  976. vd_mean_all(mode,1) = 1e2*vd_mean_all(mode,1)/nvd_all(mode,1)
  977. else
  978. vd_mean_all(mode,1) = 0.
  979. end if
  980. if(nvd_all(mode,2) > 0) then
  981. vd_mean_all(mode,2) = 1e2*vd_mean_all(mode,2)/nvd_all(mode,2)
  982. else
  983. vd_mean_all(mode,2) = 0.
  984. end if
  985. print '(i6,i4,2f10.4,2f12.6,2f12.6)', l, mode, r_mean_all(mode), 1e6*r_max_all(mode), &
  986. vd_mean_all(mode,1), 1e2*vd_max_all(mode,1), vd_mean_all(mode,2), 1e2*vd_max_all(mode,2)
  987. end if
  988. enddo
  989. write(gol,*) '________________________________________________________________________________' ; call goPr
  990. endif
  991. enddo LEVS
  992. !$OMP END PARALLEL
  993. #endif /* M7 */
  994. status = 0
  995. END SUBROUTINE SEDIMENTATION_CALCV
  996. !EOC
  997. !------------------------------------------------------------------------------
  998. ! TM5 !
  999. !------------------------------------------------------------------------------
  1000. !BOP
  1001. !
  1002. ! !IROUTINE: SEDIMENTATION_APPLY
  1003. !
  1004. ! !DESCRIPTION: Sedimentation calculation based on pre-calculated
  1005. ! v_sedimentation.
  1006. ! Based on dynamw routine, including the slopes.
  1007. !\\
  1008. !\\
  1009. ! !INTERFACE:
  1010. !
  1011. SUBROUTINE SEDIMENTATION_APPLY( region, status )
  1012. !
  1013. ! !USES:
  1014. !
  1015. use global_data, only : mass_dat, region_dat
  1016. use meteodata , only : spm_dat
  1017. use chem_param, only : ra
  1018. use dims, only : lm, at, bt, limits, sec_month, nsrce, tref, okdebug
  1019. use chem_param, only : mode_nm, mode_tracers, mode_tracers_sed,names, mode_nm_sed
  1020. use partools, only : par_reduce, par_reduce_element
  1021. #ifdef with_m7
  1022. use emission_data, only : bb_lm
  1023. #ifndef without_emission
  1024. use emission_data, only : emis_mass, emis_number
  1025. #endif
  1026. #endif
  1027. #ifdef with_budgets
  1028. use emission_data, only : budemi_dat, sum_emission
  1029. use ebischeme, only : buddep_dat
  1030. #endif
  1031. !
  1032. ! !INPUT PARAMETERS:
  1033. !
  1034. integer, intent(in) :: region
  1035. !
  1036. ! !OUTPUT PARAMETERS:
  1037. !
  1038. integer, intent(out) :: status
  1039. !
  1040. ! !REVISION HISTORY:
  1041. ! 19 Mar 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  1042. !
  1043. ! !REMARKS:
  1044. ! (1) effective only if m7 used...
  1045. !
  1046. !EOP
  1047. !------------------------------------------------------------------------------
  1048. !BOC
  1049. character(len=*), parameter :: rname = mname//'/Sedimentation_Apply'
  1050. real,dimension(:,:,:,:),pointer :: rm,rxm,rym,rzm
  1051. real,dimension(:,:,:),pointer :: vsold
  1052. real,dimension(:,: ),pointer :: vdold
  1053. real,dimension(:,:,:),pointer :: p ! surface pressure
  1054. real,dimension(:,:,:),allocatable :: f, pf, fx, fy, vs
  1055. real,dimension(:,:,:),allocatable :: emit
  1056. real,dimension(:,:),allocatable :: vd
  1057. integer :: i, j, l, n, lmr, mode
  1058. real, parameter :: one = 1.0
  1059. real :: gamma, gam, l_gam
  1060. real :: dp, dtime, month2dt
  1061. real :: rmold, rmnew, rmplus, fdep, fsed
  1062. integer,parameter :: iter_limit=200
  1063. integer :: n_advz, iter
  1064. integer :: nzone_v
  1065. integer :: ls, le, ii, inmode
  1066. real :: l_sum(3), g_sum(3)
  1067. integer :: i1, j1, i2, j2, iflag, jflag, lflag
  1068. !________________________start_________________________________
  1069. ! Big if-condition over all routine
  1070. ! start timing:
  1071. call GO_Timer_Start( itim_appl, status )
  1072. IF_NOTOK_RETURN(status=1)
  1073. #ifdef with_m7
  1074. ! Bounds
  1075. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  1076. lmr = lm(region)
  1077. allocate( f ( i1:i2, j1:j2, lmr )) ! flux of tracer (kg)
  1078. allocate(pf ( i1:i2, j1:j2, lmr )) ! rxz moment flux
  1079. allocate(fx ( i1:i2, j1:j2, lmr )) ! rmx flux
  1080. allocate(fy ( i1:i2, j1:j2, lmr )) ! rmy flux
  1081. allocate(vs ( i1:i2, j1:j2, lmr ))
  1082. allocate(vd ( i1:i2, j1:j2 ))
  1083. allocate(emit( i1:i2, j1:j2, bb_lm))
  1084. call sedimentation_calcv(region, status) ! calculate sedimentation....
  1085. IF_NOTOK_RETURN(status=1)
  1086. call deposition_calcv(region, status) ! calculate deposition.....
  1087. IF_NOTOK_RETURN(status=1)
  1088. nullify(rm)
  1089. nullify(rxm)
  1090. nullify(rym)
  1091. nullify(rzm)
  1092. nullify(p)
  1093. p => spm_dat(region)%data
  1094. rm => mass_dat(region)%rm
  1095. rxm => mass_dat(region)%rxm
  1096. rym => mass_dat(region)%rym
  1097. rzm => mass_dat(region)%rzm
  1098. if(okdebug) then
  1099. write(gol,*) ' call sedimentation'; call goPr
  1100. end if
  1101. ! If requested, limit vertical slopes such that no non-negative tracer masses should occur
  1102. ls = 1 ; le = lmr
  1103. if (limits) then
  1104. do n = 1, ubound (rzm, 4)
  1105. do l = ls, le
  1106. do j = j1, j2
  1107. do i = i1, i2
  1108. rzm(i,j,l,n) = max(min(rzm(i,j,l,n),rm(i,j,l,n)), -rm(i,j,l,n))
  1109. end do
  1110. end do
  1111. end do
  1112. end do
  1113. endif
  1114. ! determine timestep
  1115. dtime=float(nsrce)/(2*tref(region))
  1116. ! conversion to emission per timestep
  1117. month2dt=dtime/sec_month
  1118. ! =================
  1119. ! Loop over tracers
  1120. ! =================
  1121. do mode =1,nmod
  1122. !do inmode=0,mode_nm(mode)
  1123. do inmode=0,mode_nm_sed(mode)
  1124. n = mode_tracers_sed(inmode,mode)
  1125. !n = mode_tracers(inmode,mode)
  1126. !------------- reset
  1127. n_advz=1
  1128. nullify(vsold)
  1129. nullify(vdold)
  1130. if (inmode == 0) then ! number or mass tracer
  1131. vsold => vn_sedimentation(region,mode)%d3
  1132. vdold => vn_deposition(region,mode)%surf
  1133. else
  1134. vsold => vm_sedimentation(region,mode)%d3
  1135. vdold => vm_deposition(region,mode)%surf
  1136. endif
  1137. !------------- find # iter needed for no CFL violation
  1138. cfl: do
  1139. vs(:,j1:j2,:) = vsold(:,j1:j2,:)/float(n_advz)
  1140. vd(:,j1:j2) = vdold(:,j1:j2) /float(n_advz)
  1141. advz: do iter=1,n_advz
  1142. ! reset gamma
  1143. l_gam = 0.
  1144. do l= 1, lmr
  1145. do j= j1, j2
  1146. do i= i1, i2
  1147. ! vs (Pa) always downwards
  1148. ! calculate the flux at the bottom of box:
  1149. ! note that we define this as negative (vs>0, f<0)
  1150. ! pressure difference in layer dp (Pa)
  1151. dp = (at(l)-at(l+1)) + p(i,j,1)*(bt(l)-bt(l+1)) ! positive..
  1152. if(l /= 1) then
  1153. gamma=-vs(i,j,l)/dp !always negative (according to negative cm dynamw)
  1154. else
  1155. gamma=-(vs(i,j,l)+vd(i,j))/dp !always negative (according to negative cm dynamw)
  1156. endif
  1157. ! replace 'one' with 0.99999 (NB/PLS)
  1158. if (abs(gamma)>=0.9999999) then
  1159. l_gam=max(l_gam,abs(gamma))
  1160. ! exit advz ! commented for consistency with TM5
  1161. end if
  1162. enddo
  1163. enddo
  1164. enddo
  1165. enddo advz
  1166. call Par_REDUCE( l_gam, 'MAX', gam, status, all=.true.)
  1167. ! if CFL violation increase iteration counter and re-start cfl loop
  1168. ! but check if the number of iterations becomes too large
  1169. if(abs(gam)>=0.9999999) then ! PLS: replace "one" with 0.9999999 to be consistent with above
  1170. !Commented since "exit advz" is commented, and hence not meaningfull
  1171. ! if(okdebug)then
  1172. !
  1173. ! iflag=min(i,i2)
  1174. ! jflag=min(j,j2)
  1175. ! lflag=min(l,lmr)
  1176. !
  1177. ! ! i-j-l information correct if from the processor where violation happened
  1178. ! print *,' --- CFL violation: gamma=',gam,vs(iflag,jflag,lflag),' in (region,i,j,l,n)= ',region,iflag,jflag,lflag,n
  1179. ! print*,' #iterations:', n_advz
  1180. ! endif
  1181. n_advz = n_advz + 1
  1182. if ( n_advz > iter_limit ) then
  1183. status=1
  1184. IF_NOTOK_RETURN(status=1)
  1185. end if
  1186. cycle cfl
  1187. else ! situation OK, no CFL: use this n_advz
  1188. exit cfl
  1189. endif
  1190. enddo cfl
  1191. !------------- Apply number of iterations to calculate new tracer distributions
  1192. #ifdef with_budgets
  1193. l_sum = 0.0
  1194. #endif
  1195. #ifndef without_emission
  1196. if (n==ino3_a.or.n==inh4.or.n==imsa) then
  1197. emit(:,j1:j2,:) = 0.0
  1198. else if(inmode == 0) then
  1199. emit(:,j1:j2,:) = 0.0
  1200. do ii=1,mode_nm(mode) ! add up all number emissions in the mode...
  1201. emit(:,j1:j2,:) = emit(:,j1:j2,:) + emis_number(region,mode)%d4(:,j1:j2,:,ii)*month2dt/float(n_advz)
  1202. enddo
  1203. else ! this is a 'mass' emission with index nmode
  1204. emit(:,j1:j2,:) = emis_mass(region,mode)%d4(:,j1:j2,:,inmode)*month2dt/float(n_advz)
  1205. endif
  1206. #else
  1207. emit = 0.0
  1208. #endif
  1209. ! do the iteration
  1210. do iter=1,n_advz
  1211. ! compute f, pf, fx and fy
  1212. do l= 1, lmr
  1213. do j= j1, j2
  1214. do i= i1, i2
  1215. ! vs (Pa) always downwards
  1216. ! calculate the flux at the bottom of box:
  1217. ! note that we define this as negative (vs>0, f<0)
  1218. ! pressure difference in layer dp (Pa)
  1219. dp = (at(l)-at(l+1)) + p(i,j,1)*(bt(l)-bt(l+1)) ! positive..
  1220. if(l /= 1) then
  1221. gamma=-vs(i,j,l)/dp !always negative (according to negative cm dynamw)
  1222. else
  1223. gamma=-(vs(i,j,l)+vd(i,j))/dp !always negative (according to negative cm dynamw)
  1224. endif
  1225. f(i,j,l) = gamma*(rm(i,j,l,n)-(one+gamma)*rzm(i,j,l,n)) !kg (neg.)
  1226. pf(i,j,l) = -vs(i,j,l)*(gamma*gamma*rzm(i,j,l,n)-3.*f(i,j,l)) !neg.
  1227. fx(i,j,l) = gamma*rxm(i,j,l,n) !kg (neg.)
  1228. fy(i,j,l) = gamma*rym(i,j,l,n) !kg (neg.)
  1229. ! - Cannot happen unless there is a bug (pls)
  1230. !if (abs(gamma)>=one) then
  1231. ! status=1
  1232. ! IF_NOTOK_RETURN(status=1)
  1233. !end if
  1234. enddo
  1235. enddo
  1236. enddo
  1237. ! calculate new tracer mass, and tracer mass slopes
  1238. ! update rm, rzm, rxm and rym in interior layers of the column
  1239. l = lmr
  1240. do j = j1, j2
  1241. do i = i1, i2
  1242. dp = (at(l)-at(l+1)) + p(i,j,1)*(bt(l)-bt(l+1))
  1243. rm (i,j,l,n)=rm(i,j,l,n) + f(i,j,l)
  1244. rzm(i,j,l,n)=rzm(i,j,l,n)+ &
  1245. ( pf(i,j,l) &
  1246. -(-vs(i,j,l)) *rzm(i,j,l,n) &
  1247. +3.*( ( -vs(i,j,l)) *rm (i,j,l,n) &
  1248. -( f(i,j,l))*dp ))/dp
  1249. if(limits) then
  1250. rzm(i,j,l,n) = max(min(rzm(i,j,l,n), rm(i,j,l,n)), -rm(i,j,l,n))
  1251. endif
  1252. rxm(i,j,l,n)=rxm(i,j,l,n)+(fx(i,j,l))
  1253. rym(i,j,l,n)=rym(i,j,l,n)+(fy(i,j,l))
  1254. #ifdef with_budgets
  1255. nzone_v=nzon_vg(l)
  1256. !if (n==40)write(1332,*) f(i,j,l)*1e3/ra(n)
  1257. buddep_m7_dat(region)%sed(i,j,nzone_v,sindex(n)) = &
  1258. buddep_m7_dat(region)%sed(i,j,nzone_v,sindex(n)) - f(i,j,l)*1e3/ra(n) ! in mole
  1259. ! Downward flux is negative. And it is defined at the bottom of the box. A positive flux
  1260. ! is positive and would be an income for the respective grid cell. A minus sign takes care
  1261. ! We want to define the sedimentation as a cost.
  1262. #endif
  1263. enddo
  1264. enddo
  1265. do l = lmr-1, 2, -1
  1266. do j = j1, j2
  1267. do i = i1, i2
  1268. dp = (at(l)-at(l+1)) + p(i,j,1)*(bt(l)-bt(l+1))
  1269. rmold = rm(i,j,l,n)
  1270. if (l .le. bb_lm) then
  1271. rmplus = rmold + f(i,j,l)-f(i,j,l+1) + emit(i,j,l)
  1272. else
  1273. rmplus = rmold + f(i,j,l)-f(i,j,l+1)
  1274. endif
  1275. rm(i,j,l,n) = rmplus
  1276. rzm(i,j,l,n)=rzm(i,j,l,n)+ &
  1277. ( pf(i,j,l)-pf(i,j,l+1) &
  1278. -(vs(i,j,l+1)-vs(i,j,l)) *rzm(i,j,l,n) &
  1279. +3.*( (-vs(i,j,l+1)-vs(i,j,l)) *rm (i,j,l,n) &
  1280. -(f(i,j,l+1)+ f(i,j,l)) *dp ))/dp
  1281. if(limits) then
  1282. rzm(i,j,l,n) = max(min(rzm(i,j,l,n), rm(i,j,l,n)), -rm(i,j,l,n))
  1283. endif
  1284. rxm(i,j,l,n)=rxm(i,j,l,n)+(fx(i,j,l)-fx(i,j,l+1))
  1285. rym(i,j,l,n)=rym(i,j,l,n)+(fy(i,j,l)-fy(i,j,l+1))
  1286. #ifdef with_budgets
  1287. nzone_v=nzon_vg(l)
  1288. buddep_m7_dat(region)%sed(i,j,nzone_v,sindex(n)) = &
  1289. buddep_m7_dat(region)%sed(i,j,nzone_v,sindex(n)) - (f(i,j,l)-f(i,j,l+1))*1e3/ra(n) ! in mole
  1290. ! The sedimentation is calculated as 'income' again. With the minus sign, those are costs.
  1291. #ifndef without_emission
  1292. if ( l <= bb_lm ) then
  1293. budemi_dat(region)%emi(i,j,nzone_v,n) = &
  1294. budemi_dat(region)%emi(i,j,nzone_v,n) + emit(i,j,l)*1e3/ra(n) ! in mole
  1295. end if
  1296. #endif
  1297. #endif
  1298. enddo
  1299. enddo
  1300. enddo
  1301. l = 1
  1302. do j = j1, j2
  1303. do i = i1, i2
  1304. dp = (at(l)-at(l+1)) + p(i,j,1)*(bt(l)-bt(l+1))
  1305. if(vd_in_deposition) then
  1306. write(gol,*)' apply_sedimentation: vs in deposition disabled'; call goBug
  1307. status=1
  1308. IF_NOTOK_RETURN(status=1)
  1309. end if
  1310. !if(vd_in_deposition) then
  1311. ! rm (i,j,l,n)=rm(i,j,l,n) - f(i,j,l+1)
  1312. ! rzm(i,j,l,n)=rzm(i,j,l,n)+ &
  1313. ! ( -pf(i,j,l+1) &
  1314. ! -(vs(i,j,l+1)) *rzm(i,j,l,n) &
  1315. ! +3.*( (-vs(i,j,l+1)) *rm (i,j,l,n) &
  1316. ! -(f(i,j,l+1))*dp ))/dp
  1317. ! if(limits) then
  1318. ! rzm(i,j,l,n) = max(min(rzm(i,j,l,n), rm(i,j,l,n)), -rm(i,j,l,n))
  1319. ! endif
  1320. ! rxm(i,j,l,n)=rxm(i,j,l,n)+(-fx(i,j,l+1))
  1321. ! rym(i,j,l,n)=rym(i,j,l,n)+(-fy(i,j,l+1))
  1322. !else
  1323. ! rm (i,j,l,n)=rm(i,j,l,n) + f(i,j,l)-f(i,j,l+1)
  1324. ! rzm(i,j,l,n)=rzm(i,j,l,n)+ &
  1325. ! ( pf(i,j,l)-pf(i,j,l+1) &
  1326. ! -(vs(i,j,l+1)-vs(i,j,l)) *rzm(i,j,l,n) &
  1327. ! +3.*( (-vs(i,j,l+1)-vs(i,j,l)) *rm (i,j,l,n) &
  1328. ! -(f(i,j,l+1)+ f(i,j,l))*dp ))/dp
  1329. ! if(limits) then
  1330. ! rzm(i,j,l,n) = max(min(rzm(i,j,l,n), rm(i,j,l,n)), -rm(i,j,l,n))
  1331. ! endif
  1332. ! apply to rxm, rym the fluxes:
  1333. rxm(i,j,l,n)=rxm(i,j,l,n)+(fx(i,j,l)-fx(i,j,l+1))
  1334. rym(i,j,l,n)=rym(i,j,l,n)+(fy(i,j,l)-fy(i,j,l+1))
  1335. ! for rm: apply emissions, sedimentation flux from above
  1336. ! deposition and sedimentation at surface: Backward Eularian
  1337. rmold = rm(i,j,l,n)
  1338. rmplus = (rmold - f(i,j,l+1) + emit(i,j,l)) ! note f is negative !
  1339. rmnew = rmplus/(1. + (vd(i,j) + vs(i,j,1))/dp)
  1340. rm(i,j,l,n) = rmnew
  1341. if(rmold > 1e-8) rzm(i,j,l,n) = rzm(i,j,l,n)*rmnew/rmold
  1342. ! budget:
  1343. #ifdef with_budgets
  1344. if((vs(i,j,1) + vd(i,j)) > 1e-12) then
  1345. fsed = -(rmplus-rmnew)*vs(i,j,1)/(vs(i,j,1) + vd(i,j)) ! is negative
  1346. fdep = -(rmplus-rmnew)*vd(i,j) /(vs(i,j,1) + vd(i,j))
  1347. else
  1348. fsed = 0.0
  1349. fdep = 0.0
  1350. endif
  1351. if(n == 1) then
  1352. l_sum(1) = l_sum(1) + f(i,j,l+1) - fsed ! goes into sum_sedimentation
  1353. l_sum(2) = l_sum(2) - fdep ! goes into sum_drydep
  1354. #ifndef without_emission
  1355. l_sum(3) = l_sum(3) + emit(i,j,1) ! goes into sum_emission
  1356. #endif
  1357. endif
  1358. nzone_v=nzon_vg(l)
  1359. buddep_m7_dat(region)%sed(i,j,nzone_v,sindex(n)) = &
  1360. buddep_m7_dat(region)%sed(i,j,nzone_v,sindex(n)) - (fsed - f(i,j,l+1) )*1e3/ra(n) ! in mole
  1361. ! The comment line says that fsed is negative. As we regard sedimentation as a cost, we define
  1362. ! a positive sedimentation as a loss of material. A negative fsed is loss of material, so we
  1363. ! need to have -fsed. The (upward) flux on the top of the grid cell is a cost as well.
  1364. buddep_dat(region)%dry(i,j,n) = &
  1365. buddep_dat(region)%dry(i,j,n) - fdep*1e3/ra(n) ! in mole
  1366. #ifndef without_emission
  1367. budemi_dat(region)%emi(i,j,1,n) = &
  1368. budemi_dat(region)%emi(i,j,1,n) + emit(i,j,1)*1e3/ra(n) ! in mole
  1369. #endif
  1370. #endif /* BUDGETS */
  1371. enddo !i
  1372. enddo !j
  1373. enddo ! iter !
  1374. #ifdef with_budgets
  1375. call PAR_REDUCE_ELEMENT( l_sum, 'SUM', g_sum, status )
  1376. if(isRoot ) then
  1377. sum_sedimentation(region) = sum_sedimentation(region) + g_sum(1)
  1378. sum_drydep (region) = sum_drydep (region) + g_sum(2)
  1379. #ifndef without_emission
  1380. sum_emission (region) = sum_emission (region) + g_sum(3)
  1381. #endif
  1382. end if
  1383. #endif
  1384. enddo ! loop over tracers in mode
  1385. enddo ! loop over modes
  1386. deallocate( f)
  1387. deallocate(pf)
  1388. deallocate(fx)
  1389. deallocate(fy)
  1390. deallocate(vs)
  1391. deallocate(vd)
  1392. deallocate(emit)
  1393. nullify(rm)
  1394. nullify(rxm)
  1395. nullify(rym)
  1396. nullify(rzm)
  1397. nullify(vsold)
  1398. nullify(vdold)
  1399. #endif /* M7 */
  1400. ! end timing:
  1401. call GO_Timer_End( itim_appl, status )
  1402. IF_NOTOK_RETURN(status=1)
  1403. status = 0
  1404. END SUBROUTINE SEDIMENTATION_APPLY
  1405. !EOC
  1406. #ifdef with_m7
  1407. !------------------------------------------------------------------------------
  1408. ! TM5 !
  1409. !------------------------------------------------------------------------------
  1410. !BOP
  1411. !
  1412. ! !IROUTINE: FALL1
  1413. !
  1414. ! !DESCRIPTION: function to calculate the fall velocity from the particle
  1415. ! diameter, as a function of density, temperature and pressure.
  1416. !\\
  1417. !\\
  1418. ! !INTERFACE:
  1419. !
  1420. REAL FUNCTION FALL1( press, zmd, zvis, t, zdensair, densaer_p) result(vt)
  1421. !
  1422. ! !INPUT PARAMETERS:
  1423. !
  1424. real, intent(in) :: press ! pressure in Pa (or bar?)
  1425. real, intent(in) :: zmd ! median radius of aerosol (m)
  1426. real, intent(in) :: zvis ! viscosity (kg/(sm))
  1427. real, intent(in) :: t ! temperature (K)
  1428. real, intent(in) :: zdensair ! density air (kg/m3)
  1429. real, intent(in) :: densaer_p ! density aerosol particles (kg/m3)
  1430. !
  1431. ! !REVISION HISTORY:
  1432. ! 2 Apr 2010 - P. Le Sager -
  1433. !
  1434. ! !REMARKS:
  1435. ! Called in Sedimentation_Apply, only if m7 used.
  1436. !
  1437. !EOP
  1438. !------------------------------------------------------------------------------
  1439. !BOC
  1440. real :: zlair
  1441. ! ----------- start
  1442. if (zmd > tiny(zmd)) then
  1443. vt=2./9.*(densaer_p-zdensair) * grav/zvis*(zmd/2.)**2.
  1444. zlair=0.066*(1.01325e5/press)*t/293.15*1e-6
  1445. !--- With cunnigham slip- flow correction (S&P, Equation 8.34):
  1446. vt = vt * (1.+ 1.257*zlair/zmd*2. + 0.4*zlair/zmd*2. * exp(-1.1/(zlair/zmd*2.)) )
  1447. else
  1448. vt = 0.0
  1449. endif
  1450. END FUNCTION FALL1
  1451. !EOC
  1452. #endif /* M7 */
  1453. !------------------------------------------------------------------------------
  1454. ! TM5 !
  1455. !------------------------------------------------------------------------------
  1456. !BOP
  1457. !
  1458. ! !IROUTINE: AEROSOL_RADIUS
  1459. !
  1460. ! !DESCRIPTION: function that calculates the median aerosol radius (m),
  1461. ! given the total mass and number of a log-normal distribution.
  1462. !\\
  1463. !\\
  1464. ! !INTERFACE:
  1465. !
  1466. REAL FUNCTION AEROSOL_RADIUS(mtot, ntot, sigma, rho_aer) result(radius)
  1467. !
  1468. ! !USES:
  1469. !
  1470. use Binas, only: Pi
  1471. !
  1472. ! !INPUT PARAMETERS:
  1473. !
  1474. real, intent(in) :: mtot ! total mass (kg)
  1475. real, intent(in) :: ntot ! total number (#)
  1476. real, intent(in) :: sigma ! the sigma of the log-normal aerosol size distribution
  1477. real, intent(in) :: rho_aer ! the density of the aerosol (kg/m3)
  1478. !
  1479. ! !REVISION HISTORY:
  1480. ! 2 Apr 2010 - P. Le Sager -
  1481. !
  1482. ! !REMARKS:
  1483. !
  1484. !EOP
  1485. !------------------------------------------------------------------------------
  1486. !BOC
  1487. real :: lns
  1488. if(mtot > tiny(mtot) .and. ntot > tiny(ntot)) then
  1489. lns = alog(sigma)
  1490. radius = (mtot/(rho_aer*4.0*pi/3.0 *ntot *exp((9./2.)*lns**2)))**(1./3.)
  1491. else
  1492. radius = 0.0
  1493. endif
  1494. END FUNCTION AEROSOL_RADIUS
  1495. !EOC
  1496. !------------------------------------------------------------------------------
  1497. ! TM5 !
  1498. !------------------------------------------------------------------------------
  1499. !BOP
  1500. !
  1501. ! !IROUTINE: CALCULATE_RH
  1502. !
  1503. ! !DESCRIPTION: calculate the rh, with 100% rh assumption in cloudy part.
  1504. ! In the cloud free part, the rh thus is smaller, and the water
  1505. ! uptake by aerosols will be smaller.
  1506. !\\
  1507. !\\
  1508. ! !INTERFACE:
  1509. !
  1510. SUBROUTINE CALCULATE_RH
  1511. !
  1512. ! !USES:
  1513. !
  1514. use chem_param, only : xmh2o
  1515. use meteodata, only : phlb_dat
  1516. use MeteoData, only : temper_dat, humid_dat, cc_dat
  1517. use dims, only : nregions, im, jm ,lm
  1518. !
  1519. ! !REVISION HISTORY:
  1520. ! 19 Mar 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  1521. !
  1522. !EOP
  1523. !------------------------------------------------------------------------------
  1524. !BOC
  1525. real, dimension(:,:,:), pointer :: phlb ! pressure at border (Pa)
  1526. real, dimension(:,:,:), pointer :: t ! temperature (K)
  1527. real, dimension(:,:,:), pointer :: q ! humidity (kg h2o / kg air)
  1528. real, dimension(:,:,:), pointer :: cc ! cloud cover (0-1)
  1529. real :: tr, wv, airn, h2on, rrh, s, ccs
  1530. integer :: region, i,j,l, i1,i2,j1,j2
  1531. do region = 1, nregions
  1532. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  1533. nullify(phlb)
  1534. nullify(t)
  1535. nullify(q)
  1536. nullify(cc)
  1537. phlb => phlb_dat(region)%data
  1538. t => temper_dat(region)%data
  1539. q => humid_dat(region)%data
  1540. cc => cc_dat(region)%data
  1541. do l=1, lm(region)
  1542. do j=j1, j2
  1543. do i=i1, i2
  1544. tr = 1. - 373.15/t(i,j,l)
  1545. wv=exp((((-.1299*tr-.6445)*tr-1.976)*tr+13.3185)*tr)
  1546. airn = 7.24e16*0.5*(phlb(i,j,l) + phlb(i,j,l+1))/t(i,j,l) ! somethings seem redundent here!
  1547. h2on = q(i,j,l)*airn*xmair/xmh2o ! leave it for readability!
  1548. rrh = h2on*t(i,j,l)/(1013.25*wv*7.24e16)
  1549. s = 0.01*max(0.0, min(rrh, 99.9 ) ) ! 0-0.999 scale!
  1550. rha(region)%d3(i,j,l) = s
  1551. ! scale relative humidity to cloudfree part
  1552. ! assuming 100% rh in the cloudy part, but never smaller than 0.75!
  1553. if (s > 0.90) then
  1554. ccs = cc(i,j,l)
  1555. if((1. - ccs) > tiny(ccs)) s = max(0.75, (s-ccs)/(1. - ccs))
  1556. endif
  1557. rh(region)%d3(i,j,l) = s
  1558. enddo
  1559. enddo
  1560. enddo
  1561. nullify(phlb)
  1562. nullify(t)
  1563. nullify(q)
  1564. nullify(cc)
  1565. enddo
  1566. END SUBROUTINE CALCULATE_RH
  1567. !EOC
  1568. END MODULE SEDIMENTATION