m7_dconc.F90 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. #include "tm5.inc"
  2. #ifdef with_budgets
  3. SUBROUTINE m7_dconc (kproma, kbdim, klev, paerml, paernl, pm6dry, pprocess)
  4. #else
  5. SUBROUTINE m7_dconc (kproma, kbdim, klev, paerml, paernl, pm6dry)
  6. #endif
  7. !
  8. ! *m7_dconc* changes aerosol numbers and masses to account for
  9. ! condensational growth of the mode mean radii
  10. !
  11. ! Authors:
  12. ! --------
  13. ! J. Wilson and E. Vignati, JRC (original source) May 2000
  14. ! P. Stier, MPI-MET (f90 version, changes, comments) 2001
  15. !
  16. ! Purpose:
  17. ! --------
  18. ! This routine repartitions aerosol number and mass between the
  19. ! the modes to account for condensational growth and the formation
  20. ! of an accumulation mode from the upper tail of the aitken mode.
  21. !
  22. ! Interface:
  23. ! ----------
  24. ! *m7_dconc* is called from *m7*
  25. !
  26. ! Method:
  27. ! -------
  28. ! The routine calculates the cumulativ number and mass distribution of the
  29. ! modes up to the respective mode boundary:
  30. !
  31. ! / x _
  32. ! N | 1 1 ln(R)-ln(R) 2
  33. ! N(0,x) = --------- | -------- exp(- - ( ----------- ) ) d ln(R)
  34. ! ln(sigma) | sqrt(2PI) 2 ln(sigma)
  35. ! / 0
  36. !
  37. ! /tx 2
  38. ! | 1 t
  39. ! = N | -------- exp(- - ) d t
  40. ! | sqrt(2PI) 2
  41. ! /-inf
  42. !
  43. ! where:
  44. !
  45. ! _
  46. ! ln(R)-ln(R)
  47. ! t = -----------
  48. ! ln(sigma)
  49. !
  50. ! and:
  51. ! _
  52. ! ln(x)-ln(R)
  53. ! tx = -----------
  54. ! ln(sigma)
  55. ! _
  56. ! R is the Count Mean Radius or the Mass Mean Radius.
  57. !
  58. ! Practically, the routine m7_cumnor calculates the fraction of the number and
  59. ! mass distribution for each mode lying below the respective upper mode boundary (1).
  60. ! In a next step the net fraction of each mode lying between the upper and lower
  61. ! mode boundaries are summed up (2) and the numbers and masses exceeding the mode
  62. ! boundaries are transfered to the neighboring larger mode (3).
  63. ! Finally, these quantities are stored in the respective arrays
  64. ! paernl and paerml (4).
  65. ! The repartititioning is currently only done for the soluble modes as it is
  66. ! assumed that insoluble modes are rather transfered to the soluble modes
  67. ! and grow as soluble particles.
  68. !
  69. ! Externals:
  70. ! ----------
  71. ! None
  72. !
  73. !--- Parameter list:
  74. !
  75. ! paerml(kbdim,klev,naermod)= total aerosol mass for each compound
  76. ! [molec. cm-3 for sulfate and ug m-3 for others]
  77. ! paernl(kbdim,klev,nmod) = aerosol number for each mode [cm-3] !
  78. ! sigma(jmod) = standard deviation of mode jmod [1]
  79. ! crdiv = threshold radii between the different modes [cm]
  80. ! crdiv(jmod) is the lower bound and crdiv(jmod+1) is
  81. ! the upper bound of the respective mode
  82. !
  83. !--- Local Variables:
  84. !
  85. ! zfconn(:,:,jnum,jmod) = absolute fraction of the number of particles in mode jmod,
  86. ! with CMD=2*pm6dry(jmod) and a geometric standard
  87. ! deviation zrcsig, that are smaller than crdiv(jnum+1).
  88. ! I.e. with 0 < CMD < crdiv(jnum+1) [1]
  89. ! zfconm(:,:,jnum,jmod) = absolute fraction of the mass in mode jmod,
  90. ! with CMD=2*pm6dry(jmod) and a geometric standard
  91. ! deviation zrcsig, that are smaller than crdiv(jnum+1).
  92. ! I.e. with 0 < CMD < crdiv(jnum+1) [1]
  93. USE mo_kind, ONLY: wp
  94. USE mo_aero_m7, ONLY: sigma, crdiv, &
  95. nmod, naermod, nsol, &
  96. iso4ns,iso4ks, iso4as,&
  97. ibcks, ibcas, ibccs, &
  98. iocks, iocas, ioccs, &
  99. issas, isscs, &
  100. iduas, iducs, &
  101. pi, avo, wh2so4,&
  102. dh2so4,dbc, doc, &
  103. dnacl, ddust, &
  104. cmr2ram,cmedr2mmedr
  105. #ifdef with_budgets
  106. Use M7_Data, only: nm7procs
  107. #endif
  108. IMPLICIT NONE
  109. INTEGER :: kproma, kbdim, klev
  110. REAL :: paerml(kbdim,klev,naermod), paernl(kbdim,klev,nmod), &
  111. pm6dry(kbdim,klev,nsol)
  112. #ifdef with_budgets
  113. Real :: pprocess(kbdim,klev,nm7procs)
  114. #endif
  115. ! Local variables:
  116. !
  117. INTEGER :: jmod, jnum, jl, jk
  118. REAL :: zrcsig, zarg1, zarg2, zdpmm, zdpcm, &
  119. zarg3, zdpam, zcongn, zcongm, zdummy, &
  120. zr1, zr2, zttnj, zavnj, zmrj, &
  121. zmt, znt, zavmt, zmcr, zfconmj, &
  122. zntnew, zmtnew, zdm, zeps
  123. REAL :: zambc2(4), zambc3(4), zambc4(4), &
  124. zamoc2(4), zamoc3(4), zamoc4(4), &
  125. zamss3(4), zamss4(4), &
  126. zamdu3(4), zamdu4(4)
  127. REAL :: ztotmass(kbdim,klev)
  128. REAL :: zsumn(kbdim,klev,nmod), zsumm(kbdim,klev,nmod), &
  129. zsumbc(kbdim,klev,3), zsumoc(kbdim,klev,3), &
  130. zsumss(kbdim,klev,2), zsumdu(kbdim,klev,2)
  131. REAL :: zfconn(kbdim,klev,nsol,nsol), zfconm(kbdim,klev,nsol,nsol)
  132. !--- 0) Initialisations: ----------------------------------------------------------
  133. zeps=EPSILON(1.0_wp)
  134. zsumn(:,:,:) = 0.
  135. zsumm(:,:,:) = 0.
  136. zsumbc(:,:,:) = 0.
  137. zsumoc(:,:,:) = 0.
  138. zsumss(:,:,:) = 0.
  139. zsumdu(:,:,:) = 0.
  140. zfconm(:,:,:,:) = 0.
  141. zfconn(:,:,:,:) = 0.
  142. !
  143. !--- 1) Identify how much the mode jmod has grown into the next higher mode -------
  144. !
  145. DO jmod=1,nsol-1
  146. !--- Total mass of the mode in equivalent molecules of sulfate:
  147. SELECT CASE(jmod)
  148. CASE(1)
  149. ztotmass(1:kproma,:) = paerml(1:kproma,:,iso4ns)
  150. CASE(2)
  151. ztotmass(1:kproma,:) = paerml(1:kproma,:,iso4ks) + &
  152. (paerml(1:kproma,:,ibcks)/dbc+paerml(1:kproma,:,iocks)/doc) &
  153. *dh2so4/wh2so4*avo*1.E-12
  154. CASE(3)
  155. ztotmass(1:kproma,:) = paerml(1:kproma,:,iso4as) + &
  156. (paerml(1:kproma,:,ibcas)/dbc+paerml(1:kproma,:,iocas)/doc+ &
  157. paerml(1:kproma,:,issas)/dnacl+paerml(1:kproma,:,iduas)/ddust) &
  158. *dh2so4/wh2so4*avo*1.E-12
  159. END SELECT
  160. DO jnum=jmod,nsol-1
  161. DO jk=1,klev
  162. DO jl=1,kproma
  163. IF (paernl(jl,jk,jmod) .GT. zeps .AND. pm6dry(jl,jk,jmod) .GT. 0.0) THEN
  164. !--- 1.1) Calculate necessary parameters:
  165. !--- Geometric Standard Deviation:
  166. zrcsig=LOG(sigma(jmod))
  167. !--- Mass Median Radius:
  168. zarg1=pm6dry(jl,jk,jmod)*cmedr2mmedr(jmod)
  169. !--- Count Median Radius:
  170. zarg2=pm6dry(jl,jk,jmod)
  171. !--- Threshold radius between the modes:
  172. zarg3=crdiv(jnum+1)
  173. !--- Transfer to logarithmic scale:
  174. zdpmm=LOG(zarg1)
  175. zdpcm=LOG(zarg2)
  176. zdpam=LOG(zarg3)
  177. !--- Distance of the CMD of the mode from the threshold mode
  178. ! diameter in terms of geometric standard deviations:
  179. zcongn=(zdpam-zdpcm)/zrcsig
  180. !--- Distance of the MMD of the mode from the threshold mode
  181. ! diameter in terms of geometric standard deviations (t):
  182. zcongm=(zdpam-zdpmm)/zrcsig
  183. !--- Calculate the cumulative of the log-normal number distribution:
  184. CALL m7_cumnor(zcongn,zfconn(jl,jk,jnum,jmod),zdummy)
  185. !--- Limit transfer only to adjacent modes:
  186. IF (jnum .GT. jmod) THEN
  187. zfconn(jl,jk,jnum,jmod)= 1.0
  188. END IF
  189. !--- Set minimum radius and maximum radius:
  190. zr1 = crdiv(jmod)
  191. zr2 = crdiv(jmod+1)
  192. !--- Radius of average mass for a lognormal distribution
  193. zdm = EXP((LOG(zr1)+LOG(zr2))/2.0)*cmr2ram(jmod)
  194. !--- Average mass contained in the mode
  195. zttnj = ztotmass(jl,jk)/paernl(jl,jk,jmod)
  196. !--- Average number of sulfate molecules or equivalent for mixed modes,
  197. ! for a particle with radius zdm
  198. zavnj=zdm**3.0*pi*avo*dh2so4/wh2so4/0.75
  199. !--- If the average mass contained in the mode is larger than the average mass
  200. ! for a particle with radius zdm, the transfer of number and mass is done,
  201. ! else there is no transfer
  202. IF (zttnj .GT. zavnj .AND. jnum .EQ. jmod) THEN
  203. !--- Mass remaining in the mode
  204. zmrj=zfconn(jl,jk,jnum,jmod)*paernl(jl,jk,jmod)*zavnj
  205. !--- Mass transferred
  206. zmt=ztotmass(jl,jk)-zmrj
  207. !--- Numbers transferred
  208. znt=(1.0-zfconn(jl,jk,jnum,jmod))*paernl(jl,jk,jmod)
  209. !--- Average mass of particles transferred
  210. IF(znt>zeps) THEN
  211. zavmt=zmt/znt
  212. ELSE
  213. zavmt=0.
  214. END IF
  215. !--- Average mass of particles of radius zr2
  216. zmcr=(zr2*cmr2ram(jmod))**3.0*pi*avo*dh2so4/wh2so4/0.75
  217. !--- If the average mass of particle transferred is smaller than the average mass
  218. ! mass of particles with radius zr2 then reduce the particles transferred
  219. ! so that zavmt=zmcr, else calculate the mass fraction transferred zfconmj
  220. IF (zavmt .GE. zmcr) THEN
  221. zfconmj=zmrj/ztotmass(jl,jk)
  222. ELSE
  223. if ( zavmt == zavnj ) then
  224. zntnew = 0.0
  225. else
  226. zntnew = znt/(1.0 + (zmcr-zavmt)/(zavmt-zavnj))
  227. end if
  228. zmtnew = zntnew*zmcr
  229. zfconmj = 1.0 - zmtnew/ztotmass(jl,jk)
  230. zfconn(jl,jk,jnum,jmod) = 1.0 - zntnew/paernl(jl,jk,jmod)
  231. END IF
  232. zfconm(jl,jk,jnum,jmod)=zfconmj
  233. ELSE
  234. zfconn(jl,jk,jnum,jmod)=1.
  235. zfconm(jl,jk,jnum,jmod)=1.
  236. END IF
  237. ELSE
  238. zfconn(jl,jk,jnum,jmod)=1.
  239. zfconm(jl,jk,jnum,jmod)=1.
  240. END IF
  241. END DO
  242. END DO
  243. END DO
  244. END DO
  245. DO jmod=1,nsol
  246. DO jk=1,klev
  247. DO jl=1,kproma
  248. !--- 2) Calculate the net fraction of mode jmod that is transfered -------
  249. ! to the mode jnew zfconn(:,:,jnew,jmod) :
  250. !--- Numbers:
  251. zfconn(jl,jk,4,jmod)=1.0 -zfconn(jl,jk,3,jmod)
  252. zfconn(jl,jk,3,jmod)=zfconn(jl,jk,3,jmod)-zfconn(jl,jk,2,jmod)
  253. zfconn(jl,jk,2,jmod)=zfconn(jl,jk,2,jmod)-zfconn(jl,jk,1,jmod)
  254. !--- Mass:
  255. zfconm(jl,jk,4,jmod)=1.0 -zfconm(jl,jk,3,jmod)
  256. zfconm(jl,jk,3,jmod)=zfconm(jl,jk,3,jmod)-zfconm(jl,jk,2,jmod)
  257. zfconm(jl,jk,2,jmod)=zfconm(jl,jk,2,jmod)-zfconm(jl,jk,1,jmod)
  258. !--- 3) Sum the net masses and numbers transfered between the modes: -----
  259. !--- 3.1) Soluble mode numbers and sulfate mass:
  260. zsumn(jl,jk,1)=zsumn(jl,jk,1)+paernl(jl,jk,jmod)*zfconn(jl,jk,1,jmod)
  261. zsumm(jl,jk,1)=zsumm(jl,jk,1)+paerml(jl,jk,jmod)*zfconm(jl,jk,1,jmod)
  262. zsumn(jl,jk,2)=zsumn(jl,jk,2)+paernl(jl,jk,jmod)*zfconn(jl,jk,2,jmod)
  263. zsumm(jl,jk,2)=zsumm(jl,jk,2)+paerml(jl,jk,jmod)*zfconm(jl,jk,2,jmod)
  264. zsumn(jl,jk,3)=zsumn(jl,jk,3)+paernl(jl,jk,jmod)*zfconn(jl,jk,3,jmod)
  265. zsumm(jl,jk,3)=zsumm(jl,jk,3)+paerml(jl,jk,jmod)*zfconm(jl,jk,3,jmod)
  266. zsumn(jl,jk,4)=zsumn(jl,jk,4)+paernl(jl,jk,jmod)*zfconn(jl,jk,4,jmod)
  267. zsumm(jl,jk,4)=zsumm(jl,jk,4)+paerml(jl,jk,jmod)*zfconm(jl,jk,4,jmod)
  268. END DO
  269. END DO
  270. END DO
  271. DO jk=1,klev
  272. DO jl=1,kproma
  273. !--- 3.2) Non-sulfate masses:
  274. zambc2(2)=paerml(jl,jk,ibcks)*zfconm(jl,jk,2,2)
  275. zambc2(3)=paerml(jl,jk,ibcks)*zfconm(jl,jk,3,2)
  276. zambc2(4)=paerml(jl,jk,ibcks)*zfconm(jl,jk,4,2)
  277. zamoc2(2)=paerml(jl,jk,iocks)*zfconm(jl,jk,2,2)
  278. zamoc2(3)=paerml(jl,jk,iocks)*zfconm(jl,jk,3,2)
  279. zamoc2(4)=paerml(jl,jk,iocks)*zfconm(jl,jk,4,2)
  280. zambc3(3)=paerml(jl,jk,ibcas)*zfconm(jl,jk,3,3)
  281. zambc3(4)=paerml(jl,jk,ibcas)*zfconm(jl,jk,4,3)
  282. zamoc3(3)=paerml(jl,jk,iocas)*zfconm(jl,jk,3,3)
  283. zamoc3(4)=paerml(jl,jk,iocas)*zfconm(jl,jk,4,3)
  284. zambc4(4)=paerml(jl,jk,ibccs)
  285. zamoc4(4)=paerml(jl,jk,ioccs)
  286. zamss3(3)=paerml(jl,jk,issas)*zfconm(jl,jk,3,3)
  287. zamss3(4)=paerml(jl,jk,issas)*zfconm(jl,jk,4,3)
  288. zamdu3(3)=paerml(jl,jk,iduas)*zfconm(jl,jk,3,3)
  289. zamdu3(4)=paerml(jl,jk,iduas)*zfconm(jl,jk,4,3)
  290. zamss4(4)=paerml(jl,jk,isscs)
  291. zamdu4(4)=paerml(jl,jk,iducs)
  292. zsumbc(jl,jk,1)=zambc2(2)
  293. zsumbc(jl,jk,2)=zambc2(3)+zambc3(3)
  294. zsumbc(jl,jk,3)=zambc2(4)+zambc3(4)+zambc4(4)
  295. zsumoc(jl,jk,1)=zamoc2(2)
  296. zsumoc(jl,jk,2)=zamoc2(3)+zamoc3(3)
  297. zsumoc(jl,jk,3)=zamoc2(4)+zamoc3(4)+zamoc4(4)
  298. zsumss(jl,jk,1)=zamss3(3)
  299. zsumss(jl,jk,2)=zamss3(4)+zamss4(4)
  300. zsumdu(jl,jk,1)=zamdu3(3)
  301. zsumdu(jl,jk,2)=zamdu3(4)+zamdu4(4)
  302. END DO
  303. END DO
  304. !--- 4) Store final masses and numbers of the modes: ------------------------
  305. #ifdef with_budgets
  306. ! We have the results here. We can calculate the budget by first looking at the losses of mode 1 to get the growth 1->2, then 2->3 and so on.
  307. ! I add Max(0,...) to prevent negative rounding errors if the actual value is zero. They are ugly.
  308. pprocess(:,:,55) = Max(0.0,paernl(:,:,1) - zsumn(:,:,1)) ! Growth 1-2 N
  309. pprocess(:,:,56) = Max(0.0,paerml(:,:,1) - zsumm(:,:,1)) ! Growth 1-2 SU
  310. pprocess(:,:,57) = Max(0.0,paernl(:,:,2) - zsumn(:,:,2) + pprocess(:,:,55)) ! Growth 2-3 N
  311. pprocess(:,:,58) = Max(0.0,paerml(:,:,2) - zsumm(:,:,2) + pprocess(:,:,56)) ! Growth 2-3 SU
  312. pprocess(:,:,59) = Max(0.0,paerml(:,:,ibcks) - zsumbc(:,:,1)) ! Growth 2-3 BC
  313. pprocess(:,:,60) = Max(0.0,paerml(:,:,iocks) - zsumoc(:,:,1)) ! Growth 2-3 OC
  314. pprocess(:,:,61) = Max(0.0,paernl(:,:,3) - zsumn(:,:,3) + pprocess(:,:,57)) ! Growth 3-4 N
  315. pprocess(:,:,62) = Max(0.0,paerml(:,:,3) - zsumm(:,:,3) + pprocess(:,:,58)) ! Growth 3-4 SU
  316. pprocess(:,:,63) = Max(0.0,paerml(:,:,ibcas) - zsumbc(:,:,2) + pprocess(:,:,59)) ! Growth 3-4 BC
  317. pprocess(:,:,64) = Max(0.0,paerml(:,:,iocas) - zsumoc(:,:,2) + pprocess(:,:,60)) ! Growth 3-4 OC
  318. pprocess(:,:,65) = Max(0.0,paerml(:,:,issas) - zsumss(:,:,1)) ! Growth 3-4 SS
  319. pprocess(:,:,66) = Max(0.0,paerml(:,:,iduas) - zsumdu(:,:,1)) ! Growth 3-4 DU
  320. #endif
  321. DO jmod=1,nsol
  322. DO jk=1,klev
  323. DO jl=1,kproma
  324. !--- Particle numbers:
  325. paernl(jl,jk,jmod)=zsumn(jl,jk,jmod)
  326. !--- Sulfate mass:
  327. paerml(jl,jk,jmod)=zsumm(jl,jk,jmod)
  328. END DO
  329. END DO
  330. END DO
  331. !--- Non sulfate masses:
  332. DO jk=1,klev
  333. DO jl=1,kproma
  334. paerml(jl,jk,ibcks)=zsumbc(jl,jk,1)
  335. paerml(jl,jk,ibcas)=zsumbc(jl,jk,2)
  336. paerml(jl,jk,ibccs)=zsumbc(jl,jk,3)
  337. paerml(jl,jk,iocks)=zsumoc(jl,jk,1)
  338. paerml(jl,jk,iocas)=zsumoc(jl,jk,2)
  339. paerml(jl,jk,ioccs)=zsumoc(jl,jk,3)
  340. paerml(jl,jk,issas)=zsumss(jl,jk,1)
  341. paerml(jl,jk,isscs)=zsumss(jl,jk,2)
  342. paerml(jl,jk,iduas)=zsumdu(jl,jk,1)
  343. paerml(jl,jk,iducs)=zsumdu(jl,jk,2)
  344. END DO
  345. END DO
  346. END SUBROUTINE m7_dconc