m7_concoag.F90 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. #include "tm5.inc"
  2. #ifdef with_budgets
  3. SUBROUTINE m7_concoag (kproma, kbdim, klev, &
  4. paerml, paernl, pm6rp, pa4delt, panli, &
  5. pa4av1, pa4av2, pbcav5, pocav5, psoaav5, &
  6. pduav6, pduav7, pso4_5, pso4_6, pso4_7, &
  7. pbfract1, pbfract2, &
  8. zcrit_5, zcrit_6, zcrit_7, & !--- m7_box: Added for diagnostics in m7_delcoa
  9. pprocess)
  10. #else
  11. SUBROUTINE m7_concoag (kproma, kbdim, klev, &
  12. paerml, paernl, pm6rp, pa4delt, panli, &
  13. pa4av1, pa4av2, pbcav5, pocav5, psoaav5, &
  14. pduav6, pduav7, pso4_5, pso4_6, pso4_7, &
  15. pbfract1, pbfract2, &
  16. zcrit_5, zcrit_6, zcrit_7 ) !--- m7_box: Added for diagnostics
  17. ! in m7_delcoa
  18. #endif
  19. !
  20. ! *m7_concoag*
  21. !
  22. ! Author:
  23. ! ----------
  24. ! E. Vignati, JRC/EI (original source) 09/2000
  25. ! P. Stier, MPI (f90-version, changes, comments) 2001
  26. ! Version:
  27. ! ----------
  28. ! This version is equivalent to the version concoa_n of the boxmodel.
  29. !
  30. ! Purpose
  31. ! ----------
  32. ! m7_concoag transfers aerosol mass and numbers from the insoluble
  33. ! to the soluble modes.
  34. !
  35. ! Interface:
  36. ! ----------
  37. ! *m7_concoag* is called from *m7_delcoa*
  38. !
  39. ! Externals
  40. ! ----------
  41. ! none
  42. USE mo_aero_m7, ONLY: m7_coat, nmod, naermod, &
  43. ibcks, ibcki, iocks, iocki, &
  44. isoaks, isoaki, &
  45. iduas, iducs, iduai, iduci, &
  46. iaiti, iacci, icoai, &
  47. iaits, iaccs, icoas
  48. #ifdef with_budgets
  49. Use M7_Data, Only: nm7procs
  50. #endif
  51. IMPLICIT NONE
  52. !--- Parameters:
  53. !
  54. ! paerml = total aerosol mass for each compound
  55. ! [molec. cm-3 for sulphate and ug m-3 for bc, oc, ss, and dust]
  56. ! paernl = aerosol number for each mode [cm-3]
  57. ! pm6rp = mean mode actual radius (wet radius for soluble modes
  58. ! and dry radius for insoluble modes) [cm]
  59. ! pa4delt(:,:,:) = change in H2SO4 mass of the respective mode over one timstep
  60. ! due to:
  61. ! - nucleation of H2SO4 (calculated in m7_nuck)
  62. ! - coagulation (calculated here in m7_concoag)
  63. ! pxxavy = average mass of species xx in mode y []!@@@
  64. ! where xx is ss, du, bc, oc, or a4 for sulfate
  65. ! panli(:,:,x) = total number of particles moved by inter-modal
  66. ! coagulation from mode x [cm-3]
  67. ! pbfractx(:,:,y) = fraction of the total number of particles removed by
  68. ! coagulation from mode x that is moved to mode y+1 [1]
  69. ! !@@@ Clumsy notation! Should be moved to mode y !!!
  70. ! pso4_x = mass of sulphate condensed on insoluble mode x [molec. cm-3]
  71. !
  72. !--- Local variables / Constants:
  73. !
  74. ! zso4x = available mass of sulfate from mode 1 and 2
  75. ! condensing and coagulating on mode x (x = insoluble modes 5,6,7).
  76. !
  77. ! zcrtcst = Critical constant, i.e. number of sulfate molecules to cover
  78. ! an average particle of the mode with a layer of the thickness
  79. ! determined by cLayerThickness in mo_aero_m7. Calculated by
  80. ! m7_coat.
  81. !
  82. ! => zso4x/zcrtcst is the total number of particles that could be moved
  83. ! from insoluble mode x to soluble modes.
  84. !
  85. ! zcrit_x = total available number of particles in mode x that are moved from
  86. ! insoluble mode x to the corresponding soluble mode.
  87. INTEGER :: kproma, kbdim, klev
  88. REAL :: pso4_5(kbdim,klev), pso4_6(kbdim,klev), &
  89. pso4_7(kbdim,klev), psoaav5(kbdim,klev), &
  90. pa4av1(kbdim,klev), pa4av2(kbdim,klev), &
  91. pbcav5(kbdim,klev), pocav5(kbdim,klev), &
  92. pduav6(kbdim,klev), pduav7(kbdim,klev)
  93. REAL :: paerml(kbdim,klev,naermod), paernl(kbdim,klev,nmod), &
  94. pbfract1(kbdim,klev,nmod-1), pbfract2(kbdim,klev,nmod-1), &
  95. panli(kbdim,klev,nmod), pa4delt(kbdim,klev,naermod), &
  96. pm6rp(kbdim,klev,nmod)
  97. #ifdef with_budgets
  98. Real :: pprocess(kbdim,klev,nm7procs)
  99. #endif
  100. ! Local variables:
  101. INTEGER :: jl, jk, jmod
  102. REAL :: zcrit_5, zcrit_6, zcrit_7, &
  103. zso45, zso46, zso47, &
  104. zeps
  105. REAL :: zm6rp(nmod), zcrtcst(nmod)
  106. !--- 0) Initializations:
  107. zeps=EPSILON(1.)
  108. !--- 1) Redistribution of mass and numbers after nucleation, coagulation ----
  109. ! and coagulation calculated in the preceeding subroutines:
  110. DO jk=1,klev
  111. DO jl=1,kproma
  112. !--- 1.1) Sum mass of sulphate added to modes 5, 6, and 7 due to
  113. ! coagulation with modes 1 and 2 (1st term) and the mass
  114. ! of sulfate condensed on the insoluble mode x (pso4_x):
  115. zso45=panli(jl,jk,1)*pbfract1(jl,jk,4)*pa4av1(jl,jk)+pso4_5(jl,jk)
  116. zso46=panli(jl,jk,1)*pbfract1(jl,jk,5)*pa4av1(jl,jk)+ &
  117. panli(jl,jk,2)*pbfract2(jl,jk,5)*pa4av2(jl,jk)+pso4_6(jl,jk)
  118. zso47=panli(jl,jk,1)*pbfract1(jl,jk,6)*pa4av1(jl,jk)+ &
  119. panli(jl,jk,2)*pbfract2(jl,jk,6)*pa4av2(jl,jk)+pso4_7(jl,jk)
  120. !--- 1.2) Determine number of particles that can be sufficiently coated
  121. ! by the available sulfate to be transfered to the soluble modes:
  122. ! Optimization of the call of m7_coat to allow for unroll and
  123. ! subsequent vectorization.
  124. !CDIR UNROLL=7
  125. DO jmod = 1, nmod
  126. zm6rp(jmod) = pm6rp(jl,jk,jmod)
  127. END DO
  128. CALL m7_coat(zm6rp,zcrtcst)
  129. !@@@ Changed security check to allow for inconsistent radii:
  130. IF(paernl(jl,jk,iaiti) >= 1.E-5 .AND. zcrtcst(5)>zeps) THEN
  131. zcrit_5=MIN(paernl(jl,jk,iaiti), zso45/zcrtcst(5))
  132. ELSE
  133. zcrit_5=0.
  134. END IF
  135. IF(paernl(jl,jk,iacci) >= 1.E-5 .AND. zcrtcst(6)>zeps) THEN
  136. zcrit_6=MIN(paernl(jl,jk,iacci), zso46/zcrtcst(6))
  137. ELSE
  138. zcrit_6=0.
  139. END IF
  140. IF(paernl(jl,jk,icoai) >= 1.E-5 .AND. zcrtcst(7)>zeps) THEN
  141. zcrit_7=MIN(paernl(jl,jk,icoai), zso47/zcrtcst(7))
  142. ELSE
  143. zcrit_7=0.
  144. END IF
  145. ! Make minutes of condensation before paerml is updates, because that would ruin the min-function. The minutes have no side effect.
  146. #ifdef with_budgets
  147. ! Aging budgets
  148. ! Unfortunately, there are many variables used and thrown away. Therefore
  149. ! It is possible, with Where's. Maybe for later when improving the performance.
  150. ! Then, we would use panli to calcualte it again.
  151. If (zcrit_5 .NE. 0.0) Then
  152. pprocess(jl,jk,48) = zcrit_5 ! Aging 5 N
  153. pprocess(jl,jk,49) = MIN((zso45/zcrtcst(5))*pbcav5(jl,jk)*1.e6,paerml(jl,jk,ibcki)) ! Aging 5 BC
  154. pprocess(jl,jk,50) = MIN((zso45/zcrtcst(5))*pocav5(jl,jk)*1.e6,paerml(jl,jk,iocki)) ! Aging 5 OC
  155. pprocess(jl,jk,84) = MIN((zso45/zcrtcst(5))*psoaav5(jl,jk)*1.e6,paerml(jl,jk,isoaki)) ! Aging 5 SOA
  156. End If
  157. If (zcrit_6 .NE. 0.0) Then
  158. pprocess(jl,jk,51) = zcrit_6 ! Aging 6 N
  159. pprocess(jl,jk,52) = MIN((zso46/zcrtcst(6))*pduav6(jl,jk)*1.e6,paerml(jl,jk,iduai)) ! Aging 6 DU
  160. End If
  161. If (zcrit_7 .NE. 0.0) Then
  162. pprocess(jl,jk,53) = zcrit_7 ! Aging 7 N
  163. pprocess(jl,jk,54) = MIN((zso47/zcrtcst(7))*pduav7(jl,jk)*1.e6,paerml(jl,jk,iduci)) ! Aging 7 DU
  164. End If
  165. #endif
  166. !--- 1.3) Number of particles moved from the mode 5 to 2 due to
  167. ! interaction with 1 and due to condensation:
  168. paernl(jl,jk,iaits)=paernl(jl,jk,iaits)+zcrit_5
  169. paernl(jl,jk,iaiti)=paernl(jl,jk,iaiti)-zcrit_5
  170. !--- 1.4) Mass moved from mode 5 to 2:
  171. pa4delt(jl,jk,2)=pa4delt(jl,jk,2)+pso4_5(jl,jk)
  172. ! JadB: I use an 'own' zero-concentration cap for the masses
  173. ! instead of using the zero-concentration cap for the numbers.
  174. ! Those gave rounding errors and negative concentrations,
  175. ! especially with 8-byte floating points.
  176. ! The same will be done for modi 6 and 7.
  177. ! pa4delt(jl,jk,ibcks)=pa4delt(jl,jk,ibcks)+zcrit_5*pbcav5(jl,jk)*1.e6
  178. ! pa4delt(jl,jk,iocks)=pa4delt(jl,jk,iocks)+zcrit_5*pocav5(jl,jk)*1.e6
  179. IF(zcrit_5 .NE. 0.) THEN
  180. ! Only transport mass if the same conditions
  181. ! as in the case of number transport are met.
  182. pa4delt(jl,jk,ibcks)=pa4delt(jl,jk,ibcks)+ &
  183. MIN((zso45/zcrtcst(5))*pbcav5(jl,jk)*1.e6,paerml(jl,jk,ibcki))
  184. pa4delt(jl,jk,iocks)=pa4delt(jl,jk,iocks)+ &
  185. MIN((zso45/zcrtcst(5))*pocav5(jl,jk)*1.e6,paerml(jl,jk,iocki))
  186. pa4delt(jl,jk,isoaks)=pa4delt(jl,jk,isoaks)+ &
  187. MIN((zso45/zcrtcst(5))*psoaav5(jl,jk)*1.e6,paerml(jl,jk,isoaki))
  188. !--- 1.5) Mass remaining in mode 5:
  189. paerml(jl,jk,ibcki)=paerml(jl,jk,ibcki)- &
  190. MIN((zso45/zcrtcst(5))*pbcav5(jl,jk)*1.e6,paerml(jl,jk,ibcki))
  191. paerml(jl,jk,iocki)=paerml(jl,jk,iocki)- &
  192. MIN((zso45/zcrtcst(5))*pocav5(jl,jk)*1.e6,paerml(jl,jk,iocki))
  193. paerml(jl,jk,isoaki)=paerml(jl,jk,isoaki)- &
  194. MIN((zso45/zcrtcst(5))*psoaav5(jl,jk)*1.e6,paerml(jl,jk,isoaki))
  195. END IF
  196. ! paerml(jl,jk,ibcki)=paerml(jl,jk,ibcki)-zcrit_5*pbcav5(jl,jk)*1.e6
  197. ! paerml(jl,jk,iocki)=paerml(jl,jk,iocki)-zcrit_5*pocav5(jl,jk)*1.e6
  198. !--- 1.6) Number of particles moved from the mode 6 to 3:
  199. paernl(jl,jk,iaccs)=paernl(jl,jk,iaccs)+zcrit_6
  200. paernl(jl,jk,iacci)=paernl(jl,jk,iacci)-zcrit_6
  201. !--- 1.7) Mass moved from mode 6 to 3:
  202. pa4delt(jl,jk,3)=pa4delt(jl,jk,3)+pso4_6(jl,jk)
  203. ! pa4delt(jl,jk,iduas)=pa4delt(jl,jk,iduas)+zcrit_6*pduav6(jl,jk)*1.e6
  204. IF(zcrit_6 .NE. 0.) THEN
  205. pa4delt(jl,jk,iduas)=pa4delt(jl,jk,iduas)+ &
  206. MIN((zso46/zcrtcst(6))*pduav6(jl,jk)*1.e6,paerml(jl,jk,iduai))
  207. !--- 1.8) Mass remaining in mode 6:
  208. paerml(jl,jk,iduai)=paerml(jl,jk,iduai)- &
  209. MIN((zso46/zcrtcst(6))*pduav6(jl,jk)*1.e6,paerml(jl,jk,iduai))
  210. END IF
  211. ! paerml(jl,jk,iduai)=paerml(jl,jk,iduai)-zcrit_6*pduav6(jl,jk)*1.e6
  212. !--- 1.9) Number of particles moved from the mode 7 to 4:
  213. paernl(jl,jk,icoas)=paernl(jl,jk,icoas)+zcrit_7
  214. paernl(jl,jk,icoai)=paernl(jl,jk,icoai)-zcrit_7
  215. !--- 1.10) Mass moved from mode 7 to 4:
  216. pa4delt(jl,jk,4)=pa4delt(jl,jk,4)+pso4_7(jl,jk)
  217. ! pa4delt(jl,jk,iducs)=pa4delt(jl,jk,iducs)+zcrit_7*pduav7(jl,jk)*1.e6
  218. IF(zcrit_7 .NE. 0.) THEN
  219. pa4delt(jl,jk,iducs)=pa4delt(jl,jk,iducs)+ &
  220. MIN((zso47/zcrtcst(7))*pduav7(jl,jk)*1.e6,paerml(jl,jk,iduci))
  221. !--- 1.11) Mass remaining in mode 7:
  222. paerml(jl,jk,iduci)=paerml(jl,jk,iduci)- &
  223. MIN((zso47/zcrtcst(7))*pduav7(jl,jk)*1.e6,paerml(jl,jk,iduci))
  224. END IF
  225. ! paerml(jl,jk,iduci)=paerml(jl,jk,iduci)-zcrit_7*pduav7(jl,jk)*1.e6
  226. END DO
  227. END DO
  228. END SUBROUTINE m7_concoag