sedimentation.F90 69 KB

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