[3083] | 1 | ! Copyright 2013-2015,2017,2022 Université de Reims Champagne-Ardenne |
---|
[1793] | 2 | ! Contributor: J. Burgalat (GSMA, URCA) |
---|
| 3 | ! email of the author : jeremie.burgalat@univ-reims.fr |
---|
[3083] | 4 | ! |
---|
[1793] | 5 | ! This software is a computer program whose purpose is to compute |
---|
| 6 | ! microphysics processes using a two-moments scheme. |
---|
[3083] | 7 | ! |
---|
[1793] | 8 | ! This library is governed by the CeCILL-B license under French law and |
---|
[3083] | 9 | ! abiding by the rules of distribution of free software. You can use, |
---|
[1793] | 10 | ! modify and/ or redistribute the software under the terms of the CeCILL-B |
---|
| 11 | ! license as circulated by CEA, CNRS and INRIA at the following URL |
---|
[3083] | 12 | ! "http://www.cecill.info". |
---|
| 13 | ! |
---|
[1793] | 14 | ! As a counterpart to the access to the source code and rights to copy, |
---|
| 15 | ! modify and redistribute granted by the license, users are provided only |
---|
| 16 | ! with a limited warranty and the software's author, the holder of the |
---|
| 17 | ! economic rights, and the successive licensors have only limited |
---|
[3083] | 18 | ! liability. |
---|
| 19 | ! |
---|
[1793] | 20 | ! In this respect, the user's attention is drawn to the risks associated |
---|
| 21 | ! with loading, using, modifying and/or developing or reproducing the |
---|
| 22 | ! software by the user in light of its specific status of free software, |
---|
| 23 | ! that may mean that it is complicated to manipulate, and that also |
---|
| 24 | ! therefore means that it is reserved for developers and experienced |
---|
| 25 | ! professionals having in-depth computer knowledge. Users are therefore |
---|
| 26 | ! encouraged to load and test the software's suitability as regards their |
---|
[3083] | 27 | ! requirements in conditions enabling the security of their systems and/or |
---|
| 28 | ! data to be ensured and, more generally, to use and operate it in the |
---|
| 29 | ! same conditions as regards security. |
---|
| 30 | ! |
---|
[1793] | 31 | ! The fact that you are presently reading this means that you have had |
---|
| 32 | ! knowledge of the CeCILL-B license and that you accept its terms. |
---|
| 33 | |
---|
| 34 | !! file: mm_haze.f90 |
---|
| 35 | !! summary: Haze microphysics module. |
---|
| 36 | !! author: J. Burgalat |
---|
[3083] | 37 | !! date: 2013-2015,2017,2022 |
---|
[1793] | 38 | MODULE MM_HAZE |
---|
| 39 | !! Haze microphysics module. |
---|
| 40 | !! |
---|
| 41 | !! This module contains all definitions of the microphysics processes related to aerosols: |
---|
| 42 | !! |
---|
| 43 | !! - [coagulation](page/haze.html#coagulation) |
---|
| 44 | !! - [sedimentation](page/haze.html#sedimentation) |
---|
| 45 | !! - [production](page/haze.html#production) |
---|
| 46 | !! |
---|
| 47 | !! @note |
---|
[3083] | 48 | !! The production function is specific to Titan, where aerosols are created above the detached |
---|
| 49 | !! haze layer. No other source is taken into account. This process is controled by two parameters, |
---|
| 50 | !! the pressure level of production and the production rate. Then both M0 and M3 of the aerosols |
---|
[1793] | 51 | !! distribution are updated in the production zone by addition of the production rate along a |
---|
| 52 | !! gaussian shape. |
---|
| 53 | !! |
---|
| 54 | !! @note |
---|
[3083] | 55 | !! The interface methods always uses the global variables defined in [[mm_globals(module)]] when |
---|
[1793] | 56 | !! values (any kind, temperature, pressure, moments...) over the vertical grid are required. |
---|
| 57 | !! |
---|
| 58 | !! @warning |
---|
[3083] | 59 | !! The tendencies returned by the method are always defined over the vertical grid from __TOP__ |
---|
[1793] | 60 | !! to __GROUND__. |
---|
| 61 | !! |
---|
[3083] | 62 | !! @todo |
---|
[1793] | 63 | !! Modify tests on tendencies vectors to get sure that allocation is done: |
---|
| 64 | !! Currently, we assume the compiler handles automatic allocation of arrays. |
---|
| 65 | USE MM_MPREC |
---|
| 66 | USE MM_GLOBALS |
---|
| 67 | USE MM_INTERFACES |
---|
| 68 | USE MM_METHODS |
---|
| 69 | IMPLICIT NONE |
---|
| 70 | |
---|
| 71 | PRIVATE |
---|
| 72 | |
---|
| 73 | PUBLIC :: mm_haze_microphysics, mm_haze_coagulation, mm_haze_sedimentation, & |
---|
[3083] | 74 | mm_haze_production |
---|
[1793] | 75 | |
---|
[3083] | 76 | CONTAINS |
---|
[1793] | 77 | |
---|
| 78 | !============================================================================ |
---|
| 79 | ! HAZE MICROPHYSICS INTERFACE SUBROUTINE |
---|
| 80 | !============================================================================ |
---|
| 81 | |
---|
| 82 | SUBROUTINE mm_haze_microphysics(dm0a_s,dm3a_s,dm0a_f,dm3a_f) |
---|
| 83 | !! Get the evolution of moments tracers through haze microphysics processes. |
---|
| 84 | !! |
---|
[3083] | 85 | !! The subroutine is a wrapper to the haze microphysics methods. It computes the tendencies |
---|
| 86 | !! of moments tracers for coagulation, sedimentation and production processes for the |
---|
[1793] | 87 | !! atmospheric column. |
---|
| 88 | REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dm0a_s |
---|
[3083] | 89 | !! Tendency of the 0th order moment of the spherical mode distribution (\(m^{-3}\)). |
---|
[1793] | 90 | REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dm3a_s |
---|
[3083] | 91 | !! Tendency of the 3rd order moment of the spherical mode distribution (\(m^{3}.m^{-3}\)). |
---|
[1793] | 92 | REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dm0a_f |
---|
[3083] | 93 | !! Tendency of the 0th order moment of the fractal mode distribution (\(m^{-3}\)). |
---|
[1793] | 94 | REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dm3a_f |
---|
[3083] | 95 | !! Tendency of the 3rd order moment of the fractal mode distribution (\(m^{3}.m^{-3}\)). |
---|
[1793] | 96 | REAL(kind=mm_wp), DIMENSION(:), ALLOCATABLE :: zdm0as |
---|
| 97 | REAL(kind=mm_wp), DIMENSION(:), ALLOCATABLE :: zdm3as |
---|
| 98 | REAL(kind=mm_wp), DIMENSION(:), ALLOCATABLE :: zdm0af |
---|
| 99 | REAL(kind=mm_wp), DIMENSION(:), ALLOCATABLE :: zdm3af |
---|
| 100 | |
---|
| 101 | dm0a_s = 0._mm_wp ; dm3a_s = 0._mm_wp ; dm0a_f = 0._mm_wp ; dm3a_f = 0._mm_wp |
---|
| 102 | |
---|
| 103 | ALLOCATE(zdm0as(mm_nla),zdm3as(mm_nla),zdm0af(mm_nla),zdm3af(mm_nla)) |
---|
| 104 | zdm0as(1:mm_nla) = 0._mm_wp |
---|
| 105 | zdm3as(1:mm_nla) = 0._mm_wp |
---|
| 106 | zdm0af(1:mm_nla) = 0._mm_wp |
---|
| 107 | zdm3af(1:mm_nla) = 0._mm_wp |
---|
| 108 | |
---|
[3083] | 109 | IF (mm_w_haze_coag) THEN |
---|
[1793] | 110 | ! Calls coagulation |
---|
| 111 | call mm_haze_coagulation(dm0a_s,dm3a_s,dm0a_f,dm3a_f) |
---|
| 112 | ENDIF |
---|
| 113 | |
---|
| 114 | IF (mm_w_haze_sed) THEN |
---|
| 115 | ! Calls sedimentation |
---|
| 116 | call mm_haze_sedimentation(zdm0as,zdm3as,zdm0af,zdm3af) |
---|
| 117 | |
---|
| 118 | ! Computes precipitations |
---|
| 119 | mm_aer_prec = SUM(zdm3as*mm_dzlev) + SUM(zdm3af*mm_dzlev) |
---|
| 120 | |
---|
| 121 | ! Updates tendencies |
---|
[3083] | 122 | dm0a_s=dm0a_s+zdm0as ; dm3a_s=dm3a_s+zdm3as |
---|
[1793] | 123 | dm0a_f=dm0a_f+zdm0af ; dm3a_f=dm3a_f+zdm3af |
---|
| 124 | ENDIF |
---|
| 125 | |
---|
| 126 | IF (mm_w_haze_prod) THEN |
---|
| 127 | call mm_haze_production(zdm0as,zdm3as) |
---|
[2109] | 128 | ! We only produce spherical aerosols |
---|
[3083] | 129 | dm0a_s=dm0a_s+zdm0as ; dm3a_s=dm3a_s+zdm3as |
---|
[1793] | 130 | ENDIF |
---|
| 131 | |
---|
| 132 | RETURN |
---|
| 133 | END SUBROUTINE mm_haze_microphysics |
---|
| 134 | |
---|
| 135 | |
---|
| 136 | !============================================================================ |
---|
| 137 | ! COAGULATION PROCESS RELATED METHODS |
---|
| 138 | !============================================================================ |
---|
[3083] | 139 | |
---|
[1793] | 140 | SUBROUTINE mm_haze_coagulation(dM0s,dM3s,dM0f,dM3f) |
---|
| 141 | !! Get the evolution of the aerosols moments vertical column due to coagulation process. |
---|
[3083] | 142 | !! |
---|
[1793] | 143 | !! This is main method of the coagulation process: |
---|
| 144 | !! |
---|
| 145 | !! 1. Computes gamma pre-factor for each parts of the coagulation equation(s) |
---|
| 146 | !! 2. Applies the electic correction on the gamma pre-factor |
---|
| 147 | !! 3. Computes the specific flow regime "kernels" |
---|
| 148 | !! 4. Computes the harmonic mean of the kernels |
---|
| 149 | !! 5. Finally computes the tendencies of the moments. |
---|
| 150 | !! |
---|
[3083] | 151 | !! All arguments are assumed vectors of __N__ elements where __N__ is the total number of |
---|
[1793] | 152 | !! vertical __layers__. |
---|
| 153 | !! |
---|
| 154 | !! @note |
---|
[3083] | 155 | !! The method uses directly the global variables related to the vertical atmospheric structure |
---|
| 156 | !! stored in [[mm_globals(module)]]. Consequently they must be updated before calling the subroutine. |
---|
[1793] | 157 | !! |
---|
| 158 | !! @bug |
---|
[3083] | 159 | !! If the transfert probabilities are set to 1 for the two flow regimes (pco and pfm), |
---|
[1793] | 160 | !! a floating point exception occured (i.e. a NaN) as we perform a division by zero |
---|
| 161 | !! |
---|
| 162 | !! @todo |
---|
| 163 | !! Get rid of the fu\*\*\*\* STOP statement... |
---|
| 164 | REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dM0s |
---|
[3083] | 165 | !! Tendency of the 0th order moment of the spherical size-distribution over a time step (\(m^{-3}\)). |
---|
[1793] | 166 | REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dM3s |
---|
[3083] | 167 | !! Tendency of the 3rd order moment of the spherical size-distribution (\(m^{3}.m^{-3}\)). |
---|
[1793] | 168 | REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dM0f |
---|
[3083] | 169 | !! Tendency of the 0th order moment of the fractal size-distribution over a time step (\(m^{-3}\)). |
---|
[1793] | 170 | REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dM3f |
---|
[3083] | 171 | !! Tendency of the 3rd order moment of the fractal size-distribution over a time step (\(m^{3}.m^{-3}\)). |
---|
[1793] | 172 | REAL(kind=mm_wp), DIMENSION(:), ALLOCATABLE :: c_kco,c_kfm,c_slf,tmp, & |
---|
[3083] | 173 | kco,kfm,pco,pfm,mq |
---|
[1793] | 174 | REAL(kind=mm_wp), DIMENSION(:), ALLOCATABLE :: a_ss,a_sf,b_ss,b_ff,c_ss,c_sf |
---|
| 175 | INTEGER :: i |
---|
| 176 | |
---|
| 177 | IF (mm_coag_choice < 0 .OR. mm_coag_choice > mm_coag_ss+mm_coag_sf+mm_coag_ff) & |
---|
| 178 | STOP "invalid choice for coagulation mode interaction activation" |
---|
| 179 | |
---|
| 180 | ! Alloctes local arrays |
---|
| 181 | ALLOCATE(kco(mm_nla),kfm(mm_nla),c_slf(mm_nla), & |
---|
[3083] | 182 | c_kco(mm_nla),c_kfm(mm_nla),mq(mm_nla), & |
---|
| 183 | pco(mm_nla),pfm(mm_nla)) |
---|
[1793] | 184 | ALLOCATE(a_ss(mm_nla),a_sf(mm_nla), & |
---|
[3083] | 185 | b_ss(mm_nla),b_ff(mm_nla), & |
---|
| 186 | c_ss(mm_nla),c_sf(mm_nla)) |
---|
| 187 | |
---|
[1793] | 188 | a_ss(:) = 0._mm_wp ; a_sf(:) = 0._mm_wp |
---|
[3083] | 189 | b_ss(:) = 0._mm_wp ; b_ff(:) = 0._mm_wp |
---|
[1793] | 190 | c_ss(:) = 0._mm_wp ; c_sf(:) = 0._mm_wp |
---|
| 191 | |
---|
| 192 | ! gets kco, kfm pre-factors |
---|
| 193 | c_kco(:) = mm_get_kco(mm_temp) ; c_kfm(:) = mm_get_kfm(mm_temp) |
---|
| 194 | ! get slf (slip-flow factor) |
---|
[3083] | 195 | c_slf(:) = mm_akn * mm_lambda_g(mm_temp,mm_play) |
---|
[1793] | 196 | |
---|
| 197 | DO i=1,mm_nla |
---|
| 198 | ! SS interactions |
---|
| 199 | IF (mm_rcs(i) > mm_rc_min .AND. IAND(mm_coag_choice,mm_coag_ss) /= 0) THEN |
---|
| 200 | ! compute probability for M0/CO and M0/FM (resp.) |
---|
| 201 | pco(i) = mm_ps2s(mm_rcs(i),0,0,mm_temp(i),mm_play(i)) |
---|
| 202 | pfm(i) = mm_ps2s(mm_rcs(i),0,1,mm_temp(i),mm_play(i)) |
---|
| 203 | ! (A_SS_CO x A_SS_FM) / (A_SS_CO + A_SS_FM) |
---|
[3083] | 204 | kco(i) = g0ssco(mm_rcs(i),c_slf(i),c_kco(i)) |
---|
| 205 | kfm(i) = g0ssfm(mm_rcs(i),c_kfm(i)) |
---|
[1793] | 206 | IF (kco(i)*(pco(i)-2._mm_wp)+kfm(i)*(pfm(i)-2._mm_wp) /=0) THEN |
---|
| 207 | a_ss(i) = (kco(i)*(pco(i)-2._mm_wp)*kfm(i)*(pfm(i)-2._mm_wp))/(kco(i)*(pco(i)-2._mm_wp)+kfm(i)*(pfm(i)-2._mm_wp)) |
---|
| 208 | ENDIF |
---|
| 209 | ! (B_SS_CO x B_SS_FM) / (B_SS_CO + B_SS_FM) |
---|
| 210 | kco(i) = kco(i) * (1._mm_wp-pco(i)) ; kfm(i) = kfm(i) * (1._mm_wp-pfm(i)) |
---|
| 211 | IF (kco(i) + kfm(i) /= 0._mm_wp) THEN |
---|
| 212 | b_ss(i) = kco(i)*kfm(i)/(kco(i)+kfm(i)) |
---|
| 213 | ENDIF |
---|
| 214 | ! compute and apply eletric charge correction for M0/SS interactions |
---|
| 215 | mq(i) = mm_qmean(mm_rcs(i),mm_rcs(i),0,'SS',mm_temp(i),mm_play(i)) |
---|
| 216 | |
---|
| 217 | a_ss(i) = a_ss(i) * mq(i) |
---|
| 218 | b_ss(i) = b_ss(i) * mq(i) |
---|
| 219 | kco(i) = 0._mm_wp ; kfm(i) = 0._mm_wp ; mq(i) = 1._mm_wp |
---|
| 220 | ! compute probability for M3/CO and M3/FM (resp.) |
---|
| 221 | pco(i) = mm_ps2s(mm_rcs(i),3,0,mm_temp(i),mm_play(i)) |
---|
| 222 | pfm(i) = mm_ps2s(mm_rcs(i),3,1,mm_temp(i),mm_play(i)) |
---|
| 223 | ! (C_SS_CO x C_SS_FM) / (C_SS_CO + C_SS_FM) |
---|
| 224 | kco(i) = g3ssco(mm_rcs(i),c_slf(i),c_kco(i))*(pco(i)-1._mm_wp) |
---|
| 225 | kfm(i) = g3ssfm(mm_rcs(i),c_kfm(i))*(pfm(i)-1._mm_wp) |
---|
| 226 | IF (kco(i) + kfm(i) /= 0._mm_wp) THEN |
---|
| 227 | c_ss(i) = (kco(i)*kfm(i))/(kco(i)+kfm(i)) |
---|
| 228 | ENDIF |
---|
| 229 | IF (b_ss(i) <= 0._mm_wp) c_ss(i) = 0._mm_wp |
---|
| 230 | ! compute and apply eletric charge correction for M3/SS interactions |
---|
| 231 | mq(i) = mm_qmean(mm_rcs(i),mm_rcs(i),3,'SS',mm_temp(i),mm_play(i)) |
---|
| 232 | c_ss(i) = c_ss(i) * mq(i) |
---|
| 233 | ENDIF |
---|
| 234 | kco(i) = 0._mm_wp ; kfm(i) = 0._mm_wp ; mq(i) = 1._mm_wp |
---|
| 235 | |
---|
| 236 | ! SF interactions |
---|
| 237 | IF (mm_rcs(i) > mm_rc_min .AND. mm_rcf(i) > mm_rc_min .AND. IAND(mm_coag_choice,mm_coag_sf) /= 0) THEN |
---|
| 238 | ! (A_SF_CO x A_SF_FM) / (A_SF_CO + A_SF_FM) |
---|
| 239 | kco(i) = g0sfco(mm_rcs(i),mm_rcf(i),c_slf(i),c_kco(i)) |
---|
| 240 | kfm(i) = g0sffm(mm_rcs(i),mm_rcf(i),c_kfm(i)) |
---|
| 241 | IF(kco(i)+kfm(i) /= 0._mm_wp) THEN |
---|
| 242 | a_sf(i) = (kco(i)*kfm(i))/(kco(i)+kfm(i)) |
---|
| 243 | ENDIF |
---|
| 244 | ! compute and apply eletric charge correction for M0/SF interactions |
---|
| 245 | mq(i) = mm_qmean(mm_rcs(i),mm_rcf(i),0,'SF',mm_temp(i),mm_play(i)) |
---|
| 246 | a_sf(i) = a_sf(i) * mq(i) |
---|
| 247 | ! (C_SF_CO x C_SF_FM) / (C_SF_CO + C_SF_FM) |
---|
| 248 | kco(i) = g3sfco(mm_rcs(i),mm_rcf(i),c_slf(i),c_kco(i)) |
---|
| 249 | kfm(i) = g3sffm(mm_rcs(i),mm_rcf(i),c_kfm(i)) |
---|
| 250 | IF (kco(i)+kfm(i) /= 0._mm_wp) THEN |
---|
| 251 | c_sf(i) = (kco(i)*kfm(i))/(kco(i)+kfm(i)) |
---|
| 252 | ENDIF |
---|
| 253 | ! compute and apply eletric charge correction for M3/SF interactions |
---|
| 254 | mq(i) = mm_qmean(mm_rcs(i),mm_rcf(i),3,'SF',mm_temp(i),mm_play(i)) |
---|
| 255 | c_sf(i) = c_sf(i) * mq(i) |
---|
| 256 | ENDIF |
---|
| 257 | kco(i) = 0._mm_wp ; kfm(i) = 0._mm_wp ; mq(i) = 1._mm_wp |
---|
| 258 | ! FF interactions |
---|
| 259 | IF(mm_rcf(i) > mm_rc_min .AND. IAND(mm_coag_choice,mm_coag_sf) /= 0) THEN |
---|
| 260 | ! (B_FF_CO x B_FF_FM) / (B_FF_CO + B_FF_FM) |
---|
| 261 | kco(i) = g0ffco(mm_rcf(i),c_slf(i),c_kco(i)) |
---|
| 262 | kfm(i) = g0fffm(mm_rcf(i),c_kfm(i)) |
---|
| 263 | b_ff(i) = (kco(i)*kfm(i))/(kco(i)+kfm(i)) |
---|
| 264 | ! compute and apply eletric charge correction for M0/FF interactions |
---|
| 265 | mq(i) = mm_qmean(mm_rcf(i),mm_rcf(i),0,'FF',mm_temp(i),mm_play(i)) |
---|
| 266 | b_ff(i) = b_ff(i) * mq(i) |
---|
| 267 | ENDIF |
---|
| 268 | ENDDO |
---|
[3083] | 269 | |
---|
[1793] | 270 | DEALLOCATE(kco,kfm,c_kco,c_kfm,pco,pfm,c_slf) |
---|
| 271 | |
---|
| 272 | ! Now we will use the kharm two by two to compute : |
---|
| 273 | ! dm_0_S/mm_dt = kharm(1) * m_0_S^2 - kharm(2) * m_0_S * m_0_F |
---|
| 274 | ! dm_0_F/mm_dt = kharm(3) * m_0_S^2 - kharm(4) * m_0_F^2 |
---|
| 275 | ! dm_3_S/mm_dt = kharm(5) * m_3_S^2 - kharm(6) * m_3_S * m_3_F |
---|
| 276 | ! ... and finally : |
---|
| 277 | ! dm_3_F/mm_dt = - dm_3_S/mm_dt |
---|
| 278 | ! |
---|
| 279 | ! We use a (semi) implicit scheme : when X appears as square we set one X |
---|
| 280 | ! at t+1, the other a t |
---|
| 281 | ALLOCATE(tmp(mm_nla)) |
---|
| 282 | ! --- dm0s |
---|
| 283 | tmp(:) = mm_dt*(a_ss*mm_m0aer_s - a_sf*mm_m0aer_f) |
---|
| 284 | dm0s(:) = mm_m0aer_s * (tmp/(1._mm_wp - tmp)) |
---|
| 285 | ! --- dm0f |
---|
| 286 | tmp(:) = b_ff*mm_dt*mm_m0aer_f |
---|
| 287 | dm0f(:) = (b_ss*mm_dt*mm_m0aer_s**2 - tmp*mm_m0aer_f)/(1._mm_wp + tmp) |
---|
| 288 | ! --- dm3s |
---|
| 289 | tmp(:) = mm_dt*(c_ss*mm_m3aer_s - c_sf*mm_m3aer_f) |
---|
| 290 | dm3s(:) = mm_m3aer_s * (tmp/(1._mm_wp - tmp)) |
---|
| 291 | ! --- dmm3f |
---|
| 292 | dm3f(:) = -dm3s |
---|
| 293 | |
---|
| 294 | ! Deallocates memory explicitly ... another obsolete statement :) |
---|
| 295 | DEALLOCATE(a_ss,a_sf,b_ss,b_ff,c_ss,c_sf,tmp) |
---|
| 296 | |
---|
| 297 | ! Time to do something else ! |
---|
| 298 | RETURN |
---|
| 299 | END SUBROUTINE mm_haze_coagulation |
---|
| 300 | |
---|
| 301 | ELEMENTAL FUNCTION g0ssco(rcs,c_slf,c_kco) RESULT(res) |
---|
| 302 | !! Get γ pre-factor for the 0th order moment with SS interactions in the continuous flow regime. |
---|
| 303 | !! |
---|
[3083] | 304 | !! @note |
---|
[1793] | 305 | !! If __rcs__ is 0, the function returns 0. |
---|
| 306 | REAL(kind=mm_wp), INTENT(in) :: rcs !! Characteristic radius of the spherical size-distribution. |
---|
| 307 | REAL(kind=mm_wp), INTENT(in) :: c_slf !! Slip-Flow correction pre-factor. |
---|
| 308 | REAL(kind=mm_wp), INTENT(in) :: c_kco !! Thermodynamic continuous flow regime pre-factor. |
---|
| 309 | REAL(kind=mm_wp) :: res !! γ coagulation kernel pre-factor. |
---|
| 310 | REAL(kind=mm_wp) :: a1, a2, a3 |
---|
| 311 | res = 0._mm_wp ; IF (rcs <= 0._mm_wp) RETURN |
---|
| 312 | ! computes mm_alpha coefficients |
---|
| 313 | a1=mm_alpha_s(1._mm_wp) ; a2=mm_alpha_s(-1._mm_wp) ; a3=mm_alpha_s(-2._mm_wp) |
---|
| 314 | ! Computes gamma pre-factor |
---|
| 315 | res = (1._mm_wp + a1*a2 + c_slf/rcs *(a2+a1*a3))*c_kco |
---|
| 316 | RETURN |
---|
| 317 | END FUNCTION g0ssco |
---|
| 318 | |
---|
| 319 | ELEMENTAL FUNCTION g0sfco(rcs,rcf,c_slf,c_kco) RESULT(res) |
---|
| 320 | !! Get γ pre-factor for the 0th order moment with SF interactions in the continuous flow regime. |
---|
| 321 | !! |
---|
[3083] | 322 | !! @note |
---|
[1793] | 323 | !! If __rcs__ or __rcf__ is 0, the function returns 0. |
---|
| 324 | REAL(kind=mm_wp), INTENT(in) :: rcs !! Characteristic radius of the spherical size-distribution. |
---|
| 325 | REAL(kind=mm_wp), INTENT(in) :: rcf !! Characteristic radius of the fractal size-distribution. |
---|
| 326 | REAL(kind=mm_wp), INTENT(in) :: c_slf !! Slip-Flow correction pre-factor. |
---|
| 327 | REAL(kind=mm_wp), INTENT(in) :: c_kco !! Thermodynamic continuous flow regime pre-factor. |
---|
| 328 | REAL(kind=mm_wp) :: res !! γ coagulation kernel pre-factor. |
---|
| 329 | REAL(kind=mm_wp) :: a1, a2, a3, a4, a5, a6, e, rcff |
---|
| 330 | res = 0._mm_wp ; IF (rcs <= 0._mm_wp .OR. rcf <= 0._mm_wp) RETURN |
---|
[3083] | 331 | e=3._mm_wp/mm_df ; rcff = rcf**e*mm_rb2ra |
---|
[1793] | 332 | ! computes mm_alpha coefficients |
---|
[3083] | 333 | a1=mm_alpha_s(1._mm_wp) ; a2=mm_alpha_f(-e) ; a3=mm_alpha_f(e) |
---|
[1793] | 334 | a4=mm_alpha_s(-1._mm_wp) ; a5=mm_alpha_s(-2._mm_wp) ; a6=mm_alpha_f(-2._mm_wp*e) |
---|
| 335 | ! Computes gamma pre-factor |
---|
| 336 | res = c_kco*( 2._mm_wp + a1*a2*rcs/rcff + a4*a3*rcff/rcs + c_slf*( a4/rcs + & |
---|
[3083] | 337 | a2/rcff + a5*a3*rcff/rcs**2 + a1*a6*rcs/rcff**2)) |
---|
[1793] | 338 | RETURN |
---|
| 339 | END FUNCTION g0sfco |
---|
| 340 | |
---|
| 341 | ELEMENTAL FUNCTION g0ffco(rcf,c_slf,c_kco) RESULT(res) |
---|
| 342 | !! Get γ pre-factor for the 0th order moment with FF interactions in the continuous flow regime. |
---|
| 343 | !! |
---|
[3083] | 344 | !! @note |
---|
[1793] | 345 | !! If __rcf__ is 0, the function returns 0. |
---|
| 346 | REAL(kind=mm_wp), INTENT(in) :: rcf !! Characteristic radius of the fractal size-distribution. |
---|
| 347 | REAL(kind=mm_wp), INTENT(in) :: c_slf !! Slip-Flow correction pre-factor. |
---|
| 348 | REAL(kind=mm_wp), INTENT(in) :: c_kco !! Thermodynamic continuous flow regime pre-factor. |
---|
| 349 | REAL(kind=mm_wp) :: res !! γ coagulation kernel pre-factor. |
---|
| 350 | REAL(kind=mm_wp) :: a1, a2, a3, e, rcff |
---|
| 351 | res = 0._mm_wp ; IF (rcf <= 0._mm_wp) RETURN |
---|
| 352 | ! computes mm_alpha coefficients |
---|
| 353 | e = 3._mm_wp/mm_df ; rcff = rcf**e*mm_rb2ra |
---|
| 354 | a1=mm_alpha_f(e) ; a2=mm_alpha_f(-e) ; a3=mm_alpha_s(-2._mm_wp*e) |
---|
| 355 | ! Computes gamma pre-factor |
---|
| 356 | res = (1._mm_wp + a1*a2 + c_slf/rcff *(a2+a1*a3))*c_kco |
---|
| 357 | RETURN |
---|
| 358 | END FUNCTION g0ffco |
---|
| 359 | |
---|
| 360 | ELEMENTAL FUNCTION g3ssco(rcs, c_slf, c_kco) RESULT(res) |
---|
| 361 | !! Get γ pre-factor for the 3rd order moment with SS interactions in the continuous flow regime. |
---|
| 362 | !! |
---|
[3083] | 363 | !! @note |
---|
[1793] | 364 | !! If __rcs__ is 0, the function returns 0. |
---|
| 365 | REAL(kind=mm_wp), INTENT(in) :: rcs !! Characteristic radius of the spherical size-distribution. |
---|
| 366 | REAL(kind=mm_wp), INTENT(in) :: c_slf !! Slip-Flow correction pre-factor. |
---|
| 367 | REAL(kind=mm_wp), INTENT(in) :: c_kco !! Thermodynamic continuous flow regime pre-factor. |
---|
| 368 | REAL(kind=mm_wp) :: res !! γ coagulation kernel pre-factor. |
---|
| 369 | REAL(kind=mm_wp) :: a1, a2, a3, a4, a5, a6 |
---|
| 370 | res = 0._mm_wp ; IF (rcs <= 0._mm_wp) RETURN |
---|
| 371 | ! computes mm_alpha coefficients |
---|
[3083] | 372 | a1=mm_alpha_s(3._mm_wp) ; a2=mm_alpha_s(2._mm_wp) ; a3=mm_alpha_s(1._mm_wp) |
---|
[1793] | 373 | a4=mm_alpha_s(4._mm_wp) ; a5=mm_alpha_s(-1._mm_wp) ; a6=mm_alpha_s(-2._mm_wp) |
---|
| 374 | |
---|
| 375 | ! Computes gamma pre-factor |
---|
[3083] | 376 | res = (2._mm_wp*a1 + a2*a3 + a4*a5 + c_slf/rcs*(a3**2 + a4*a6 + a1*a5 + a2))* & |
---|
| 377 | c_kco/(a1**2*rcs**3) |
---|
[1793] | 378 | RETURN |
---|
| 379 | END FUNCTION g3ssco |
---|
| 380 | |
---|
| 381 | ELEMENTAL FUNCTION g3sfco(rcs, rcf, c_slf, c_kco) RESULT(res) |
---|
| 382 | !! Get γ pre-factor for the 3rd order moment with SF interactions in the continuous flow regime. |
---|
| 383 | !! |
---|
[3083] | 384 | !! @note |
---|
[1793] | 385 | !! If __rcs__ or __rcf__ is 0, the function returns 0. |
---|
| 386 | REAL(kind=mm_wp), INTENT(in) :: rcs !! Characteristic radius of the spherical size-distribution. |
---|
| 387 | REAL(kind=mm_wp), INTENT(in) :: rcf !! Characteristic radius of the fractal size-distribution. |
---|
| 388 | REAL(kind=mm_wp), INTENT(in) :: c_slf !! Slip-Flow correction pre-factor. |
---|
| 389 | REAL(kind=mm_wp), INTENT(in) :: c_kco !! Thermodynamic continuous flow regime pre-factor. |
---|
| 390 | REAL(kind=mm_wp) :: res !! γ coagulation kernel pre-factor. |
---|
| 391 | REAL(kind=mm_wp) :: a1, a2, a3, a4, a5, a6, a7, a8, e, rcff |
---|
| 392 | res = 0._mm_wp ; IF (rcs <= 0._mm_wp .OR. rcf <= 0._mm_wp) RETURN |
---|
| 393 | ! computes mm_alpha coefficients |
---|
[3083] | 394 | e=3._mm_wp/mm_df ; rcff = rcf**e*mm_rb2ra |
---|
| 395 | a1=mm_alpha_s(3._mm_wp) ; a2=mm_alpha_s(4._mm_wp) ; a3=mm_alpha_f(-e) |
---|
[1793] | 396 | a4=mm_alpha_s(2._mm_wp) ; a5=mm_alpha_f(e) ; a6=mm_alpha_s(1._mm_wp) |
---|
| 397 | a7=mm_alpha_f(-2._mm_wp*e) ; a8=mm_alpha_f(3._mm_wp) |
---|
| 398 | ! Computes gamma pre-factor |
---|
| 399 | res = (2._mm_wp*a1*rcs**3 + a2*rcs**4*a3/rcff + a4*rcs**2*a5*rcff + & |
---|
[3083] | 400 | c_slf *( a4*rcs**2 + a1*rcs**3*a3/rcff + a6*rcs*a5*rcff + & |
---|
| 401 | a2*rcs**4*a7/rcff**2))* c_kco/(a1*a8*(rcs*rcf)**3) |
---|
[1793] | 402 | RETURN |
---|
| 403 | END FUNCTION g3sfco |
---|
| 404 | |
---|
| 405 | ELEMENTAL FUNCTION g0ssfm(rcs, c_kfm) RESULT(res) |
---|
| 406 | !! Get γ pre-factor for the 0th order moment with SS interactions in the Free Molecular flow regime. |
---|
| 407 | !! |
---|
[3083] | 408 | !! @note |
---|
[1793] | 409 | !! If __rcs__ is 0, the function returns 0. |
---|
| 410 | REAL(kind=mm_wp), INTENT(in) :: rcs !! Characteristic radius of the spherical size-distribution. |
---|
| 411 | REAL(kind=mm_wp), INTENT(in) :: c_kfm !! Thermodynamic free molecular flow regime pre-factor. |
---|
| 412 | REAL(kind=mm_wp) :: res !! γ coagulation kernel pre-factor. |
---|
| 413 | REAL(kind=mm_wp) :: a1, a2, a3, a4, a5 |
---|
| 414 | res = 0._mm_wp ; IF (rcs <= 0._mm_wp) RETURN |
---|
| 415 | ! computes mm_alpha coefficients |
---|
| 416 | a1=mm_alpha_s(0.5_mm_wp) ; a2=mm_alpha_s(1._mm_wp) ; a3=mm_alpha_s(-0.5_mm_wp) |
---|
| 417 | a4=mm_alpha_s(2._mm_wp) ; a5=mm_alpha_s(-1.5_mm_wp) |
---|
| 418 | ! Computes gamma pre-factor |
---|
| 419 | res = (a1 + 2._mm_wp*a2*a3 + a4*a5)*rcs**0.5_mm_wp*mm_get_btk(1,0)*c_kfm |
---|
| 420 | RETURN |
---|
| 421 | END FUNCTION g0ssfm |
---|
| 422 | |
---|
| 423 | ELEMENTAL FUNCTION g0sffm(rcs, rcf, c_kfm) RESULT(res) |
---|
[3083] | 424 | !> Get γ pre-factor for the 0th order moment with SF interactions in the Free Molecular flow regime. |
---|
[1793] | 425 | !! |
---|
[3083] | 426 | !! @note |
---|
[1793] | 427 | !! If __rcs__ or __rcf__ is 0, the function returns 0. |
---|
| 428 | REAL(kind=mm_wp), INTENT(in) :: rcs !! Characteristic radius of the spherical size-distribution. |
---|
| 429 | REAL(kind=mm_wp), INTENT(in) :: rcf !! Characteristic radius of the fractal size-distribution. |
---|
| 430 | REAL(kind=mm_wp), INTENT(in) :: c_kfm !! Thermodynamic free molecular flow regime pre-factor. |
---|
| 431 | REAL(kind=mm_wp) :: res !! γ coagulation kernel pre-factor. |
---|
| 432 | REAL(kind=mm_wp) :: a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 |
---|
| 433 | REAL(kind=mm_wp) :: e1, e2, e3, e4 |
---|
| 434 | REAL(kind=mm_wp) :: rcff1, rcff2, rcff3, rcff4 |
---|
| 435 | res = 0._mm_wp ; IF (rcs <= 0._mm_wp .OR. rcf <= 0._mm_wp) RETURN |
---|
| 436 | ! computes mm_alpha coefficients |
---|
[3083] | 437 | e1 = 3._mm_wp/mm_df |
---|
| 438 | e2 = 6._mm_wp/mm_df |
---|
[1793] | 439 | e3 = (6._mm_wp-3._mm_wp*mm_df)/(2._mm_wp*mm_df) |
---|
| 440 | e4 = (12._mm_wp-3._mm_wp*mm_df)/(2._mm_wp*mm_df) |
---|
| 441 | |
---|
[3083] | 442 | rcff1 = mm_rb2ra * rcf**e1 |
---|
[1793] | 443 | rcff2 = rcff1**2 |
---|
[3083] | 444 | rcff3 = mm_rb2ra * rcf**e3 |
---|
[1793] | 445 | rcff4 = mm_rb2ra**2 * rcf**e4 |
---|
| 446 | |
---|
[3083] | 447 | a1=mm_alpha_s(0.5_mm_wp) ; a2=mm_alpha_s(-0.5_mm_wp) ; a3=mm_alpha_f(e1) |
---|
[1793] | 448 | a4=mm_alpha_s(-1.5_mm_wp) ; a5=mm_alpha_f(e2) ; a6=mm_alpha_s(2._mm_wp) |
---|
[3083] | 449 | a7=mm_alpha_f(-1.5_mm_wp) ; a8=mm_alpha_s(1._mm_wp) ; a9=mm_alpha_f(e3) |
---|
[1793] | 450 | a10=mm_alpha_f(e4) |
---|
| 451 | |
---|
| 452 | ! Computes gamma pre-factor |
---|
| 453 | res = (a1*rcs**0.5_mm_wp + 2._mm_wp*rcff1*a2*a3/rcs**0.5_mm_wp + a4*a5*rcff2/rcs**1.5_mm_wp + & |
---|
[3083] | 454 | a6*a7*rcs**2/rcf**1.5_mm_wp + 2._mm_wp*a8*a9*rcs*rcff3 + a10*rcff4 & |
---|
| 455 | )*mm_get_btk(4,0)*c_kfm |
---|
[1793] | 456 | RETURN |
---|
| 457 | END FUNCTION g0sffm |
---|
| 458 | |
---|
| 459 | ELEMENTAL FUNCTION g0fffm(rcf, c_kfm) RESULT(res) |
---|
[3083] | 460 | !! Get γ pre-factor for the 0th order moment with FF interactions in the Free Molecular flow regime. |
---|
[1793] | 461 | !! |
---|
[3083] | 462 | !! @note |
---|
[1793] | 463 | !! If __rcf__ is 0, the function returns 0. |
---|
| 464 | REAL(kind=mm_wp), INTENT(in) :: rcf !! Characteristic radius of the fractal size-distribution. |
---|
| 465 | REAL(kind=mm_wp), INTENT(in) :: c_kfm !! Thermodynamic free molecular flow regime pre-factor. |
---|
[3083] | 466 | REAL(kind=mm_wp) :: res !! γ coagulation kernel pre-factor. |
---|
[1793] | 467 | REAL(kind=mm_wp) :: a1, a2, a3, a4, a5, e1, e2, e3, rcff |
---|
| 468 | res = 0._mm_wp ; IF (rcf <= 0._mm_wp) RETURN |
---|
| 469 | ! computes mm_alpha coefficients |
---|
[3083] | 470 | e1=3._mm_wp/mm_df ; e2=(6_mm_wp-3._mm_wp*mm_df)/(2._mm_wp*mm_df) |
---|
[1793] | 471 | e3=(12._mm_wp-3._mm_wp*mm_df)/(2._mm_wp*mm_df) |
---|
| 472 | rcff=mm_rb2ra**2*rcf**e3 |
---|
| 473 | a1=mm_alpha_f(e3) ; a2=mm_alpha_f(e1) ; a3=mm_alpha_f(e2) |
---|
| 474 | a4=mm_alpha_f(-1.5_mm_wp) ; a5=mm_alpha_f(2._mm_wp*e1) |
---|
| 475 | ! Computes gamma pre-factor |
---|
| 476 | res = (a1 + 2._mm_wp*a2*a3 + a4*a5)*rcff*mm_get_btk(3,0)*c_kfm |
---|
| 477 | RETURN |
---|
| 478 | END FUNCTION g0fffm |
---|
| 479 | |
---|
| 480 | ELEMENTAL FUNCTION g3ssfm(rcs, c_kfm) RESULT(res) |
---|
| 481 | !! Get γ pre-factor for the 3rd order moment with SS interactions in the Free Molecular flow regime. |
---|
| 482 | !! |
---|
| 483 | !! @note |
---|
| 484 | !! If __rcs__ is 0, the function returns 0. |
---|
| 485 | REAL(kind=mm_wp), INTENT(in) :: rcs !! Characteristic radius of the spherical size-distribution. |
---|
| 486 | REAL(kind=mm_wp), INTENT(in) :: c_kfm !! Thermodynamic free molecular flow regime pre-factor. |
---|
| 487 | REAL(kind=mm_wp) :: res !! γ coagulation kernel pre-factor. |
---|
| 488 | REAL(kind=mm_wp) :: a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11 |
---|
| 489 | res = 0._mm_wp ; IF (rcs <= 0._mm_wp) RETURN |
---|
| 490 | ! computes mm_alpha coefficients |
---|
[3083] | 491 | a1=mm_alpha_s(3.5_mm_wp) ; a2=mm_alpha_s(1._mm_wp) ; a3=mm_alpha_s(2.5_mm_wp) |
---|
[1793] | 492 | a4=mm_alpha_s(2._mm_wp) ; a5=mm_alpha_s(1.5_mm_wp) ; a6=mm_alpha_s(5._mm_wp) |
---|
[3083] | 493 | a7=mm_alpha_s(-1.5_mm_wp) ; a8=mm_alpha_s(4._mm_wp) ; a9=mm_alpha_s(-0.5_mm_wp) |
---|
[1793] | 494 | a10=mm_alpha_s(3._mm_wp) ; a11=mm_alpha_s(0.5_mm_wp) |
---|
| 495 | ! Computes gamma pre-factor |
---|
| 496 | res = (a1 + 2._mm_wp*a2*a3 + a4*a5 + a6*a7 + 2._mm_wp*a8*a9 + a10*a11) & |
---|
[3083] | 497 | *mm_get_btk(1,3)*c_kfm/(a10**2*rcs**2.5_mm_wp) |
---|
[1793] | 498 | RETURN |
---|
| 499 | END FUNCTION g3ssfm |
---|
| 500 | |
---|
| 501 | ELEMENTAL FUNCTION g3sffm(rcs, rcf, c_kfm) RESULT(res) |
---|
| 502 | !! Get γ pre-factor for the 3rd order moment with SF interactions in the Free Molecular flow regime. |
---|
| 503 | !! |
---|
[3083] | 504 | !! @note |
---|
[1793] | 505 | !! If __rcs__ or __rcf__ is 0, the function returns 0. |
---|
| 506 | REAL(kind=mm_wp), INTENT(in) :: rcs !! Characteristic radius of the spherical size-distribution. |
---|
| 507 | REAL(kind=mm_wp), INTENT(in) :: rcf !! Characteristic radius of the fractal size-distribution. |
---|
| 508 | REAL(kind=mm_wp), INTENT(in) :: c_kfm !! Thermodynamic free molecular flow regime pre-factor. |
---|
| 509 | REAL(kind=mm_wp) :: res !! γ coagulation kernel pre-factor. |
---|
| 510 | REAL(kind=mm_wp) :: a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 |
---|
| 511 | REAL(kind=mm_wp) :: e1, e2, e3, rcff1, rcff2, rcff3 |
---|
| 512 | res = 0._mm_wp ; IF (rcs <= 0._mm_wp .OR. rcf <= 0._mm_wp) RETURN |
---|
| 513 | ! computes mm_alpha coefficients |
---|
[3083] | 514 | e1=3._mm_wp/mm_df |
---|
| 515 | e2=(6._mm_wp-3._mm_wp*mm_df)/(2._mm_wp*mm_df) |
---|
[1793] | 516 | e3=(12._mm_wp-3._mm_wp*mm_df)/(2._mm_wp*mm_df) |
---|
| 517 | rcff1=mm_rb2ra*rcf**e1 ; rcff2=mm_rb2ra*rcf**e2 ; rcff3=mm_rb2ra**2*rcf**e3 |
---|
[3083] | 518 | a1=mm_alpha_s(3.5_mm_wp) ; a2=mm_alpha_s(2.5_mm_wp) ; a3=mm_alpha_f(e1) |
---|
| 519 | a4=mm_alpha_s(1.5_mm_wp) ; a5=mm_alpha_f(2._mm_wp*e1) ; a6=mm_alpha_s(5._mm_wp) |
---|
| 520 | a7=mm_alpha_f(-1.5_mm_wp) ; a8=mm_alpha_s(4._mm_wp) ; a9=mm_alpha_f(e2) |
---|
[1793] | 521 | a10=mm_alpha_s(3._mm_wp) ; a11=mm_alpha_f(e3) ; a12=mm_alpha_f(3._mm_wp) |
---|
| 522 | ! Computes gamma pre-factor |
---|
| 523 | res = (a1*rcs**3.5_mm_wp + 2._mm_wp*a2*a3*rcs**2.5_mm_wp*rcff1 + a4*a5*rcs**1.5_mm_wp*rcff1**2 + & |
---|
[3083] | 524 | a6*a7*rcs**5/rcf**1.5_mm_wp + 2._mm_wp*a8*a9*rcs**4*rcff2 + & |
---|
| 525 | a10*a11*rcs**3*rcff3)*mm_get_btk(4,3)*c_kfm/(a10*a12*(rcs*rcf)**3) |
---|
[1793] | 526 | RETURN |
---|
| 527 | END FUNCTION g3sffm |
---|
| 528 | |
---|
| 529 | !============================================================================ |
---|
| 530 | ! SEDIMENTATION PROCESS RELATED METHODS |
---|
| 531 | !============================================================================ |
---|
[3083] | 532 | |
---|
[1793] | 533 | SUBROUTINE mm_haze_sedimentation(dm0s,dm3s,dm0f,dm3f) |
---|
| 534 | !! Interface to sedimentation algorithm. |
---|
| 535 | !! |
---|
| 536 | !! The subroutine computes the evolution of each moment of the aerosols tracers |
---|
[3083] | 537 | !! through sedimentation process and returns their tendencies for a timestep. |
---|
[1793] | 538 | REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dm0s |
---|
[3083] | 539 | !! Tendency of the 0th order moment of the spherical mode (\(m^{-3}\)). |
---|
[1793] | 540 | REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dm3s |
---|
[3083] | 541 | !! Tendency of the 3rd order moment of the spherical mode (\(m^{3}.m^{-3}\)). |
---|
[1793] | 542 | REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dm0f |
---|
[3083] | 543 | !! Tendency of the 0th order moment of the fractal mode (\(m^{-3}\)). |
---|
[1793] | 544 | REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dm3f |
---|
[3083] | 545 | !! Tendency of the 3rd order moment of the fractal mode (\(m^{3}.m^{-3}\)). |
---|
[1793] | 546 | REAL(kind=mm_wp), DIMENSION(:), ALLOCATABLE :: ft,fdcor,wth |
---|
[3083] | 547 | REAL(kind=mm_wp), PARAMETER :: fac = 4._mm_wp/3._mm_wp * mm_pi |
---|
[1793] | 548 | |
---|
| 549 | ALLOCATE(ft(mm_nle),wth(mm_nle),fdcor(mm_nle)) |
---|
| 550 | |
---|
| 551 | !mm_aer_s_flux(:) = 0._mm_wp ; mm_aer_f_flux(:) = 0._mm_wp |
---|
| 552 | IF (mm_wsed_m0) THEN |
---|
| 553 | ! Spherical particles |
---|
| 554 | ! M0 |
---|
| 555 | call get_weff(mm_m0aer_s,0._mm_wp,3._mm_wp,mm_rcs,mm_dt,mm_alpha_s,wth,fdcor) |
---|
| 556 | ft(:) = wth(:) * fdcor(:) ; mm_m0as_vsed(:) = ft(1:mm_nla) |
---|
| 557 | call let_me_fall_in_peace(mm_m0aer_s,-ft,mm_dt,dm0s) |
---|
| 558 | ! M3 |
---|
| 559 | mm_m3as_vsed(:) = ft(1:mm_nla) |
---|
| 560 | call let_me_fall_in_peace(mm_m3aer_s,-ft,mm_dt,dm3s) |
---|
| 561 | ! get mass flux |
---|
| 562 | mm_aer_s_flux(:) = fac * mm_rhoaer * ft(2:) * mm_m3aer_s |
---|
| 563 | ! Fractal particles |
---|
| 564 | ! M0 |
---|
| 565 | call get_weff(mm_m0aer_f,0._mm_wp,mm_df,mm_rcf,mm_dt,mm_alpha_f,wth,fdcor) |
---|
| 566 | ft(:) = wth(:) * fdcor(:) ; mm_m0af_vsed(:) = ft(1:mm_nla) |
---|
| 567 | call let_me_fall_in_peace(mm_m0aer_f,-ft,mm_dt,dm0f) |
---|
| 568 | ! M3 |
---|
| 569 | mm_m3af_vsed(:) = ft(1:mm_nla) |
---|
| 570 | call let_me_fall_in_peace(mm_m3aer_f,-ft,mm_dt,dm3f) |
---|
| 571 | ! get mass flux |
---|
| 572 | mm_aer_f_flux(:) = fac * mm_rhoaer * ft(2:) * mm_m3aer_f |
---|
| 573 | ELSEIF (mm_wsed_m3) THEN |
---|
| 574 | ! Spherical particles |
---|
| 575 | ! M3 |
---|
| 576 | call get_weff(mm_m3aer_s,3._mm_wp,3._mm_wp,mm_rcs,mm_dt,mm_alpha_s,wth,fdcor) |
---|
| 577 | ft(:) = wth(:) * fdcor(:) ; mm_m3as_vsed(:) = ft(1:mm_nla) |
---|
| 578 | call let_me_fall_in_peace(mm_m3aer_s,-ft,mm_dt,dm3s) |
---|
| 579 | ! get mass flux |
---|
| 580 | mm_aer_s_flux(:) = fac * mm_rhoaer * ft(2:) * mm_m3aer_s |
---|
| 581 | ! M0 |
---|
| 582 | mm_m0as_vsed(:) = ft(1:mm_nla) |
---|
| 583 | call let_me_fall_in_peace(mm_m0aer_s,-ft,mm_dt,dm0s) |
---|
| 584 | ! Fractal particles |
---|
| 585 | ! M3 |
---|
| 586 | call get_weff(mm_m3aer_f,3._mm_wp,mm_df,mm_rcf,mm_dt,mm_alpha_f,wth,fdcor) |
---|
| 587 | ft(:) = wth(:) * fdcor(:) ; mm_m3af_vsed(:) = ft(1:mm_nla) |
---|
| 588 | call let_me_fall_in_peace(mm_m3aer_f,-ft,mm_dt,dm3f) |
---|
| 589 | ! get mass flux |
---|
| 590 | mm_aer_f_flux(:) = fac * mm_rhoaer * ft(2:) * mm_m3aer_f |
---|
| 591 | ! M0 |
---|
| 592 | mm_m0af_vsed(:) = ft(1:mm_nla) |
---|
| 593 | call let_me_fall_in_peace(mm_m0aer_f,-ft,mm_dt,dm0f) |
---|
| 594 | ELSE |
---|
| 595 | ! Spherical particles |
---|
| 596 | ! M0 |
---|
| 597 | call get_weff(mm_m0aer_s,0._mm_wp,3._mm_wp,mm_rcs,mm_dt,mm_alpha_s,wth,fdcor) |
---|
| 598 | ft(:) = wth(:) * fdcor(:) ; mm_m0as_vsed(:) = ft(1:mm_nla) |
---|
| 599 | call let_me_fall_in_peace(mm_m0aer_s,-ft,mm_dt,dm0s) |
---|
| 600 | ! M3 |
---|
| 601 | call get_weff(mm_m3aer_s,3._mm_wp,3._mm_wp,mm_rcs,mm_dt,mm_alpha_s,wth,fdcor) |
---|
| 602 | ft(:) = wth(:) * fdcor(:) ; mm_m3as_vsed(:) = ft(1:mm_nla) |
---|
| 603 | call let_me_fall_in_peace(mm_m3aer_s,-ft,mm_dt,dm3s) |
---|
| 604 | ! get mass flux |
---|
| 605 | mm_aer_s_flux(:) = fac * mm_rhoaer * ft(2:) * mm_m3aer_s |
---|
| 606 | ! Fractal particles |
---|
| 607 | ! M0 |
---|
| 608 | call get_weff(mm_m0aer_f,0._mm_wp,mm_df,mm_rcf,mm_dt,mm_alpha_f,wth,fdcor) |
---|
| 609 | ft(:) = wth(:) * fdcor(:) ; mm_m0af_vsed(:) = ft(1:mm_nla) |
---|
| 610 | call let_me_fall_in_peace(mm_m0aer_f,-ft,mm_dt,dm0f) |
---|
| 611 | ! M3 |
---|
| 612 | call get_weff(mm_m3aer_f,3._mm_wp,mm_df,mm_rcf,mm_dt,mm_alpha_f,wth,fdcor) |
---|
| 613 | ft(:) = wth(:) * fdcor(:) ; mm_m3af_vsed(:) = ft(1:mm_nla) |
---|
| 614 | call let_me_fall_in_peace(mm_m3aer_f,-ft,mm_dt,dm3f) |
---|
| 615 | ! get mass flux |
---|
| 616 | mm_aer_f_flux(:) = fac * mm_rhoaer * ft(2:) * mm_m3aer_f |
---|
| 617 | ENDIF |
---|
| 618 | DEALLOCATE(ft,wth,fdcor) |
---|
| 619 | RETURN |
---|
| 620 | END SUBROUTINE mm_haze_sedimentation |
---|
| 621 | |
---|
| 622 | SUBROUTINE let_me_fall_in_peace(mk,ft,dt,dmk) |
---|
| 623 | !! Compute the tendency of the moment through sedimentation process. |
---|
| 624 | !! |
---|
[3083] | 625 | !! |
---|
[1793] | 626 | !! The method computes the time evolution of the \(k^{th}\) order moment through sedimentation: |
---|
| 627 | !! |
---|
| 628 | !! $$ \dfrac{dM_{k}}{dt} = \dfrac{\Phi_{k}}{dz} $$ |
---|
| 629 | !! |
---|
| 630 | !! The equation is resolved using a [Crank-Nicolson algorithm](http://en.wikipedia.org/wiki/Crank-Nicolson_method). |
---|
[3083] | 631 | !! |
---|
| 632 | !! Sedimentation algorithm is quite messy. It appeals to the dark side of the Force and uses evil black magic spells |
---|
[1793] | 633 | !! from ancient times. It is based on \cite{toon1988b,fiadeiro1977,turco1979} and is an update of the algorithm |
---|
| 634 | !! originally implemented in the LMDZ-Titan 2D GCM. |
---|
| 635 | REAL(kind=mm_wp), INTENT(in), DIMENSION(:) :: mk !! \(k^{th}\) order moment to sediment (in \(m^{k}\)). |
---|
| 636 | REAL(kind=mm_wp), INTENT(in) :: dt !! Time step (s). |
---|
| 637 | REAL(kind=mm_wp), INTENT(in), DIMENSION(:) :: ft !! Downward sedimentation flux (effective velocity of the moment). |
---|
| 638 | REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dmk !! Tendency of \(k^{th}\) order moment (in \(m^{k}.m^{-3}\)). |
---|
[3083] | 639 | INTEGER :: i |
---|
[1793] | 640 | REAL(kind=mm_wp), DIMENSION(:), ALLOCATABLE :: as,bs,cs,mko |
---|
| 641 | ALLOCATE(as(mm_nla), bs(mm_nla), cs(mm_nla), mko(mm_nla)) |
---|
| 642 | mko(1:mm_nla) = 0._mm_wp |
---|
| 643 | cs(1:mm_nla) = ft(2:mm_nla+1) - mm_dzlay(1:mm_nla)/dt |
---|
| 644 | IF (ANY(cs > 0._mm_wp)) THEN |
---|
| 645 | ! implicit case |
---|
| 646 | as(1:mm_nla) = ft(1:mm_nla) |
---|
| 647 | bs(1:mm_nla) = -(ft(2:mm_nle)+mm_dzlay(1:mm_nla)/dt) |
---|
| 648 | cs(1:mm_nla) = -mm_dzlay(1:mm_nla)/dt*mk(1:mm_nla) |
---|
[3083] | 649 | ! (Tri)diagonal matrix inversion |
---|
[1793] | 650 | mko(1) = cs(1)/bs(1) |
---|
| 651 | DO i=2,mm_nla ; mko(i) = (cs(i)-mko(i-1)*as(i))/bs(i) ; ENDDO |
---|
| 652 | ELSE |
---|
| 653 | ! explicit case |
---|
| 654 | as(1:mm_nla)=-mm_dzlay(1:mm_nla)/dt |
---|
| 655 | bs(1:mm_nla)=-ft(1:mm_nla) |
---|
| 656 | ! boundaries |
---|
| 657 | mko(1)=cs(1)*mk(1)/as(1) |
---|
| 658 | mko(mm_nla)=(bs(mm_nla)*mk(mm_nla-1)+cs(mm_nla)*mk(mm_nla))/as(mm_nla) |
---|
| 659 | ! interior |
---|
| 660 | mko(2:mm_nla-1)=(bs(2:mm_nla-1)*mk(1:mm_nla-2) + & |
---|
[3083] | 661 | cs(2:mm_nla-1)*mk(2:mm_nla-1) & |
---|
| 662 | )/as(2:mm_nla-1) |
---|
[1793] | 663 | ENDIF |
---|
| 664 | dmk = mko - mk |
---|
| 665 | DEALLOCATE(as,bs,cs,mko) |
---|
| 666 | RETURN |
---|
| 667 | END SUBROUTINE let_me_fall_in_peace |
---|
| 668 | |
---|
| 669 | SUBROUTINE get_weff(mk,k,df,rc,dt,afun,wth,corf) |
---|
| 670 | !! Get the effective settling velocity for aerosols moments. |
---|
[3083] | 671 | !! |
---|
| 672 | !! This method computes the effective settling velocity of the \(k^{th}\) order moment of aerosol |
---|
| 673 | !! tracers. The basic settling velocity (\(v^{eff}_{M_{k}}\)) is computed using the following |
---|
[1793] | 674 | !! equation: |
---|
[3083] | 675 | !! |
---|
| 676 | !! $$ |
---|
[1793] | 677 | !! \begin{eqnarray*} |
---|
[3083] | 678 | !! \Phi^{sed}_{M_{k}} &=& \int_{0}^{\infty} n(r) r^{k} \times w(r) dr |
---|
[1793] | 679 | !! == M_{k} \times v^{eff}_{M_{k}} \\ |
---|
| 680 | !! v^{eff}_{M_{k} &=& \dfrac{2 \rho g r_{c}^{\dfrac{3D_{f}-3}{D_{f}}}} |
---|
| 681 | !! {r_{m}^{D_{f}-3}/D_{f}} \times \alpha(k)} \times \left( \alpha \right( |
---|
| 682 | !! \frac{D_{f}(k+3)-3}{D_{f}}\left) + \dfrac{A_{kn}\lambda_{g}}{r_{c}^{ |
---|
| 683 | !! 3/D_{f}}} \alpha \right( \frac{D_{f}(k+3)-6}{D_{f}}\left)\left) |
---|
| 684 | !! \end{eqnarray*} |
---|
| 685 | !! $$ |
---|
| 686 | !! |
---|
[3083] | 687 | !! \(v^{eff}_{M_{k}\) is then corrected to reduce numerical diffusion of the sedimentation algorithm |
---|
[1793] | 688 | !! as defined in \cite{toon1988b}. |
---|
| 689 | !! |
---|
| 690 | !! @warning |
---|
[3083] | 691 | !! Both __df__, __rc__ and __afun__ must be consistent with each other otherwise wrong values will |
---|
[1793] | 692 | !! be computed. |
---|
| 693 | REAL(kind=mm_wp), INTENT(in), DIMENSION(mm_nla) :: mk |
---|
[3083] | 694 | !! Moment of order __k__ (\(m^{k}.m^{-3}\)) at each layer. |
---|
[1793] | 695 | REAL(kind=mm_wp), INTENT(in), DIMENSION(mm_nla) :: rc |
---|
[3083] | 696 | !! Characteristic radius associated to the moment at each layer. |
---|
[1793] | 697 | REAL(kind=mm_wp), INTENT(in) :: k |
---|
[3083] | 698 | !! The order of the moment. |
---|
[1793] | 699 | REAL(kind=mm_wp), INTENT(in) :: df |
---|
[3083] | 700 | !! Fractal dimension of the aersols. |
---|
[1793] | 701 | REAL(kind=mm_wp), INTENT(in) :: dt |
---|
[3083] | 702 | !! Time step (s). |
---|
[1793] | 703 | REAL(kind=mm_wp), INTENT(out), DIMENSION(mm_nle) :: wth |
---|
[3083] | 704 | !! Theoretical Settling velocity at each vertical __levels__ (\( wth \times corf = weff\)). |
---|
| 705 | REAL(kind=mm_wp), INTENT(out), DIMENSION(mm_nle), OPTIONAL :: corf |
---|
| 706 | !! _Fiadero_ correction factor applied to the theoretical settling velocity at each vertical __levels__. |
---|
[1793] | 707 | INTERFACE |
---|
| 708 | FUNCTION afun(order) |
---|
| 709 | !! Inter-moment relation function (see [[mm_interfaces(module):mm_alpha_s(interface)]]). |
---|
| 710 | IMPORT mm_wp |
---|
| 711 | REAL(kind=mm_wp), INTENT(in) :: order !! Order of the moment. |
---|
| 712 | REAL(kind=mm_wp) :: afun !! Alpha value. |
---|
| 713 | END FUNCTION afun |
---|
[3083] | 714 | END INTERFACE |
---|
[1793] | 715 | INTEGER :: i |
---|
| 716 | REAL(kind=mm_wp) :: af1,af2,ar1,ar2 |
---|
| 717 | REAL(kind=mm_wp) :: csto,cslf,ratio,wdt,dzb |
---|
| 718 | REAL(kind=mm_wp) :: rb2ra |
---|
| 719 | REAL(kind=mm_wp), DIMENSION(mm_nle) :: zcorf |
---|
| 720 | ! ------------------ |
---|
[3083] | 721 | |
---|
[1793] | 722 | wth(:) = 0._mm_wp ; zcorf(:) = 1._mm_wp |
---|
| 723 | |
---|
| 724 | ar1 = (3._mm_wp*df -3._mm_wp)/df ; ar2 = (3._mm_wp*df -6._mm_wp)/df |
---|
[3083] | 725 | af1 = (df*(k+3._mm_wp)-3._mm_wp)/df ; af2 = (df*(k+3._mm_wp)-6._mm_wp)/df |
---|
[1793] | 726 | rb2ra = mm_rm**((df-3._mm_wp)/df) |
---|
| 727 | DO i=2,mm_nla |
---|
[3083] | 728 | IF (rc(i-1) <= 0._mm_wp) CYCLE |
---|
[1793] | 729 | dzb = (mm_dzlay(i)+mm_dzlay(i-1))/2._mm_wp |
---|
| 730 | csto = 2._mm_wp*mm_rhoaer*mm_effg(mm_zlev(i))/(9._mm_wp*mm_eta_g(mm_btemp(i))) |
---|
| 731 | cslf = mm_akn * mm_lambda_g(mm_btemp(i),mm_plev(i)) |
---|
[3083] | 732 | wth(i) = - csto/(rb2ra*afun(k)) * (rc(i-1)**ar1 * afun(af1) + cslf/rb2ra * rc(i-1)**ar2 * afun(af2)) |
---|
| 733 | |
---|
[1793] | 734 | ! now correct velocity to reduce numerical diffusion |
---|
| 735 | IF (.NOT.mm_no_fiadero_w) THEN |
---|
| 736 | IF (mk(i) <= 0._mm_wp) THEN |
---|
[3083] | 737 | ratio = mm_fiadero_max |
---|
[1793] | 738 | ELSE |
---|
[3083] | 739 | ratio = MAX(MIN(mk(i-1)/mk(i),mm_fiadero_max),mm_fiadero_min) |
---|
[1793] | 740 | ENDIF |
---|
| 741 | ! apply correction |
---|
| 742 | IF ((ratio <= 0.9_mm_wp .OR. ratio >= 1.1_mm_wp) .AND. wth(i) /= 0._mm_wp) THEN |
---|
| 743 | wdt = wth(i)*dt |
---|
[1819] | 744 | ! bugfix: max exponential arg to 30) |
---|
| 745 | zcorf(i) = dzb/wdt * (exp(MIN(30._mm_wp,-wdt*log(ratio)/dzb))-1._mm_wp) / (1._mm_wp-ratio) |
---|
| 746 | !zcorf(i) = dzb/wdt * (exp(-wdt*log(ratio)/dzb)-1._mm_wp) / (1._mm_wp-ratio) |
---|
[1793] | 747 | ENDIF |
---|
| 748 | ENDIF |
---|
| 749 | ENDDO |
---|
| 750 | ! last value (ground) set to first layer value: arbitrary :) |
---|
| 751 | wth(i) = wth(i-1) |
---|
| 752 | IF (PRESENT(corf)) corf(:) = zcorf(:) |
---|
| 753 | RETURN |
---|
| 754 | END SUBROUTINE get_weff |
---|
| 755 | |
---|
| 756 | !============================================================================ |
---|
| 757 | ! PRODUCTION PROCESS RELATED METHOD |
---|
| 758 | !============================================================================ |
---|
| 759 | |
---|
| 760 | SUBROUTINE mm_haze_production(dm0s,dm3s) |
---|
| 761 | !! Compute the production of aerosols moments. |
---|
[3083] | 762 | !! |
---|
| 763 | !! The method computes the tendencies of M0 and M3 for the spherical mode through production process. |
---|
| 764 | !! Production values are distributed along a normal law in altitude, centered at |
---|
[1793] | 765 | !! [[mm_globals(module):mm_p_prod(variable)]] pressure level with a fixed sigma of 20km. |
---|
| 766 | !! |
---|
[3083] | 767 | !! First M3 tendency is computed and M0 is retrieved using the inter-moments relation a spherical |
---|
[1793] | 768 | !! characteristic radius set to [[mm_globals(module):mm_rc_prod(variable)]]. |
---|
| 769 | !! |
---|
| 770 | !! If [[mm_globals(module):mm_var_prod(variable)]] is set to .true., the method computes time-dependent |
---|
| 771 | !! tendencies using a sine wave of anuglar frequency [[mm_globals(module):mm_w_prod(variable)]] |
---|
| 772 | REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dm0s !! Tendency of M0 (\(m^{-3}\)). |
---|
| 773 | REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dm3s !! Tendency of M3 (\(m^{3}.m^{-3}\)). |
---|
| 774 | INTEGER :: i |
---|
[3083] | 775 | REAL(kind=mm_wp) :: zprod,cprod,timefact |
---|
[1793] | 776 | REAL(kind=mm_wp), PARAMETER :: sigz = 20e3_mm_wp, & |
---|
| 777 | fnorm = 1._mm_wp/(dsqrt(2._mm_wp*mm_pi)*sigz), & |
---|
| 778 | znorm = dsqrt(2._mm_wp)*sigz |
---|
| 779 | REAL(kind=mm_wp), SAVE :: ctime = 0._mm_wp |
---|
| 780 | !$OMP THREADPRIVATE (ctime) |
---|
| 781 | zprod = -1._mm_wp |
---|
| 782 | ! locate production altitude |
---|
| 783 | DO i=1, mm_nla-1 |
---|
| 784 | IF (mm_plev(i) < mm_p_prod.AND.mm_plev(i+1) >= mm_p_prod) THEN |
---|
| 785 | zprod = mm_zlay(i) ; EXIT |
---|
| 786 | ENDIF |
---|
| 787 | ENDDO |
---|
| 788 | IF (zprod < 0._mm_wp) THEN |
---|
| 789 | WRITE(*,'(a)') "cannot find aerosols production altitude" |
---|
| 790 | call EXIT(11) |
---|
| 791 | ENDIF |
---|
| 792 | |
---|
| 793 | dm3s(:)= mm_tx_prod *0.75_mm_wp/mm_pi *mm_dt / mm_rhoaer / 2._mm_wp / mm_dzlev(1:mm_nla) * & |
---|
| 794 | (erf((mm_zlev(1:mm_nla)-zprod)/znorm) - & |
---|
[3083] | 795 | erf((mm_zlev(2:mm_nla+1)-zprod)/znorm)) |
---|
[1793] | 796 | dm0s(:) = dm3s(:)/(mm_rc_prod**3*mm_alpha_s(3._mm_wp)) |
---|
| 797 | |
---|
| 798 | IF (mm_var_prod) THEN |
---|
| 799 | timefact = mm_d_prod*sin(mm_w_prod*ctime)+1._mm_wp |
---|
| 800 | dm3s(:) = timefact*dm3s(:) |
---|
| 801 | dm0s(:) = timefact*dm0s(:) |
---|
| 802 | ctime = ctime + mm_dt |
---|
| 803 | ENDIF |
---|
| 804 | |
---|
| 805 | END SUBROUTINE mm_haze_production |
---|
| 806 | |
---|
| 807 | END MODULE MM_HAZE |
---|