sedimentation.F90 69 KB

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