m7_concoag.F90 11 KB

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