1 | ! Copyright 2013-2015,2017,2022 Université de Reims Champagne-Ardenne |
---|
2 | ! Contributor: J. Burgalat (GSMA, URCA) |
---|
3 | ! email of the author : jeremie.burgalat@univ-reims.fr |
---|
4 | ! |
---|
5 | ! This software is a computer program whose purpose is to compute |
---|
6 | ! microphysics processes using a two-moments scheme. |
---|
7 | ! |
---|
8 | ! This library is governed by the CeCILL-B license under French law and |
---|
9 | ! abiding by the rules of distribution of free software. You can use, |
---|
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 |
---|
12 | ! "http://www.cecill.info". |
---|
13 | ! |
---|
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 |
---|
18 | ! liability. |
---|
19 | ! |
---|
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 |
---|
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 | ! |
---|
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 |
---|
37 | !! date: 2013-2015,2017,2022 |
---|
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 |
---|
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 |
---|
51 | !! distribution are updated in the production zone by addition of the production rate along a |
---|
52 | !! gaussian shape. |
---|
53 | !! |
---|
54 | !! @note |
---|
55 | !! The interface methods always uses the global variables defined in [[mm_globals(module)]] when |
---|
56 | !! values (any kind, temperature, pressure, moments...) over the vertical grid are required. |
---|
57 | !! |
---|
58 | !! @warning |
---|
59 | !! The tendencies returned by the method are always defined over the vertical grid from __TOP__ |
---|
60 | !! to __GROUND__. |
---|
61 | !! |
---|
62 | !! @todo |
---|
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, & |
---|
74 | mm_haze_production |
---|
75 | |
---|
76 | CONTAINS |
---|
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 | !! |
---|
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 |
---|
87 | !! atmospheric column. |
---|
88 | REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dm0a_s |
---|
89 | !! Tendency of the 0th order moment of the spherical mode distribution (\(m^{-3}\)). |
---|
90 | REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dm3a_s |
---|
91 | !! Tendency of the 3rd order moment of the spherical mode distribution (\(m^{3}.m^{-3}\)). |
---|
92 | REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dm0a_f |
---|
93 | !! Tendency of the 0th order moment of the fractal mode distribution (\(m^{-3}\)). |
---|
94 | REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dm3a_f |
---|
95 | !! Tendency of the 3rd order moment of the fractal mode distribution (\(m^{3}.m^{-3}\)). |
---|
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 | |
---|
109 | IF (mm_w_haze_coag) THEN |
---|
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 |
---|
122 | dm0a_s=dm0a_s+zdm0as ; dm3a_s=dm3a_s+zdm3as |
---|
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) |
---|
128 | ! We only produce spherical aerosols |
---|
129 | dm0a_s=dm0a_s+zdm0as ; dm3a_s=dm3a_s+zdm3as |
---|
130 | ENDIF |
---|
131 | |
---|
132 | RETURN |
---|
133 | END SUBROUTINE mm_haze_microphysics |
---|
134 | |
---|
135 | |
---|
136 | !============================================================================ |
---|
137 | ! COAGULATION PROCESS RELATED METHODS |
---|
138 | !============================================================================ |
---|
139 | |
---|
140 | SUBROUTINE mm_haze_coagulation(dM0s,dM3s,dM0f,dM3f) |
---|
141 | !! Get the evolution of the aerosols moments vertical column due to coagulation process. |
---|
142 | !! |
---|
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 | !! |
---|
151 | !! All arguments are assumed vectors of __N__ elements where __N__ is the total number of |
---|
152 | !! vertical __layers__. |
---|
153 | !! |
---|
154 | !! @note |
---|
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. |
---|
157 | !! |
---|
158 | !! @bug |
---|
159 | !! If the transfert probabilities are set to 1 for the two flow regimes (pco and pfm), |
---|
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 |
---|
165 | !! Tendency of the 0th order moment of the spherical size-distribution over a time step (\(m^{-3}\)). |
---|
166 | REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dM3s |
---|
167 | !! Tendency of the 3rd order moment of the spherical size-distribution (\(m^{3}.m^{-3}\)). |
---|
168 | REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dM0f |
---|
169 | !! Tendency of the 0th order moment of the fractal size-distribution over a time step (\(m^{-3}\)). |
---|
170 | REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dM3f |
---|
171 | !! Tendency of the 3rd order moment of the fractal size-distribution over a time step (\(m^{3}.m^{-3}\)). |
---|
172 | REAL(kind=mm_wp), DIMENSION(:), ALLOCATABLE :: c_kco,c_kfm,c_slf,tmp, & |
---|
173 | kco,kfm,pco,pfm,mq |
---|
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), & |
---|
182 | c_kco(mm_nla),c_kfm(mm_nla),mq(mm_nla), & |
---|
183 | pco(mm_nla),pfm(mm_nla)) |
---|
184 | ALLOCATE(a_ss(mm_nla),a_sf(mm_nla), & |
---|
185 | b_ss(mm_nla),b_ff(mm_nla), & |
---|
186 | c_ss(mm_nla),c_sf(mm_nla)) |
---|
187 | |
---|
188 | a_ss(:) = 0._mm_wp ; a_sf(:) = 0._mm_wp |
---|
189 | b_ss(:) = 0._mm_wp ; b_ff(:) = 0._mm_wp |
---|
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) |
---|
195 | c_slf(:) = mm_akn * mm_lambda_g(mm_temp,mm_play) |
---|
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) |
---|
204 | kco(i) = g0ssco(mm_rcs(i),c_slf(i),c_kco(i)) |
---|
205 | kfm(i) = g0ssfm(mm_rcs(i),c_kfm(i)) |
---|
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 |
---|
269 | |
---|
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 | !! |
---|
304 | !! @note |
---|
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 | !! |
---|
322 | !! @note |
---|
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 |
---|
331 | e=3._mm_wp/mm_df ; rcff = rcf**e*mm_rb2ra |
---|
332 | ! computes mm_alpha coefficients |
---|
333 | a1=mm_alpha_s(1._mm_wp) ; a2=mm_alpha_f(-e) ; a3=mm_alpha_f(e) |
---|
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 + & |
---|
337 | a2/rcff + a5*a3*rcff/rcs**2 + a1*a6*rcs/rcff**2)) |
---|
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 | !! |
---|
344 | !! @note |
---|
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 | !! |
---|
363 | !! @note |
---|
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 |
---|
372 | a1=mm_alpha_s(3._mm_wp) ; a2=mm_alpha_s(2._mm_wp) ; a3=mm_alpha_s(1._mm_wp) |
---|
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 |
---|
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) |
---|
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 | !! |
---|
384 | !! @note |
---|
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 |
---|
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) |
---|
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 + & |
---|
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) |
---|
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 | !! |
---|
408 | !! @note |
---|
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) |
---|
424 | !> Get γ pre-factor for the 0th order moment with SF interactions in the Free Molecular flow regime. |
---|
425 | !! |
---|
426 | !! @note |
---|
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 |
---|
437 | e1 = 3._mm_wp/mm_df |
---|
438 | e2 = 6._mm_wp/mm_df |
---|
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 | |
---|
442 | rcff1 = mm_rb2ra * rcf**e1 |
---|
443 | rcff2 = rcff1**2 |
---|
444 | rcff3 = mm_rb2ra * rcf**e3 |
---|
445 | rcff4 = mm_rb2ra**2 * rcf**e4 |
---|
446 | |
---|
447 | a1=mm_alpha_s(0.5_mm_wp) ; a2=mm_alpha_s(-0.5_mm_wp) ; a3=mm_alpha_f(e1) |
---|
448 | a4=mm_alpha_s(-1.5_mm_wp) ; a5=mm_alpha_f(e2) ; a6=mm_alpha_s(2._mm_wp) |
---|
449 | a7=mm_alpha_f(-1.5_mm_wp) ; a8=mm_alpha_s(1._mm_wp) ; a9=mm_alpha_f(e3) |
---|
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 + & |
---|
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 |
---|
456 | RETURN |
---|
457 | END FUNCTION g0sffm |
---|
458 | |
---|
459 | ELEMENTAL FUNCTION g0fffm(rcf, c_kfm) RESULT(res) |
---|
460 | !! Get γ pre-factor for the 0th order moment with FF interactions in the Free Molecular flow regime. |
---|
461 | !! |
---|
462 | !! @note |
---|
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. |
---|
466 | REAL(kind=mm_wp) :: res !! γ coagulation kernel pre-factor. |
---|
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 |
---|
470 | e1=3._mm_wp/mm_df ; e2=(6_mm_wp-3._mm_wp*mm_df)/(2._mm_wp*mm_df) |
---|
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 |
---|
491 | a1=mm_alpha_s(3.5_mm_wp) ; a2=mm_alpha_s(1._mm_wp) ; a3=mm_alpha_s(2.5_mm_wp) |
---|
492 | a4=mm_alpha_s(2._mm_wp) ; a5=mm_alpha_s(1.5_mm_wp) ; a6=mm_alpha_s(5._mm_wp) |
---|
493 | a7=mm_alpha_s(-1.5_mm_wp) ; a8=mm_alpha_s(4._mm_wp) ; a9=mm_alpha_s(-0.5_mm_wp) |
---|
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) & |
---|
497 | *mm_get_btk(1,3)*c_kfm/(a10**2*rcs**2.5_mm_wp) |
---|
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 | !! |
---|
504 | !! @note |
---|
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 |
---|
514 | e1=3._mm_wp/mm_df |
---|
515 | e2=(6._mm_wp-3._mm_wp*mm_df)/(2._mm_wp*mm_df) |
---|
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 |
---|
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) |
---|
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 + & |
---|
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) |
---|
526 | RETURN |
---|
527 | END FUNCTION g3sffm |
---|
528 | |
---|
529 | !============================================================================ |
---|
530 | ! SEDIMENTATION PROCESS RELATED METHODS |
---|
531 | !============================================================================ |
---|
532 | |
---|
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 |
---|
537 | !! through sedimentation process and returns their tendencies for a timestep. |
---|
538 | REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dm0s |
---|
539 | !! Tendency of the 0th order moment of the spherical mode (\(m^{-3}\)). |
---|
540 | REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dm3s |
---|
541 | !! Tendency of the 3rd order moment of the spherical mode (\(m^{3}.m^{-3}\)). |
---|
542 | REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dm0f |
---|
543 | !! Tendency of the 0th order moment of the fractal mode (\(m^{-3}\)). |
---|
544 | REAL(kind=mm_wp), INTENT(out), DIMENSION(:) :: dm3f |
---|
545 | !! Tendency of the 3rd order moment of the fractal mode (\(m^{3}.m^{-3}\)). |
---|
546 | REAL(kind=mm_wp), DIMENSION(:), ALLOCATABLE :: ft,fdcor,wth |
---|
547 | REAL(kind=mm_wp), PARAMETER :: fac = 4._mm_wp/3._mm_wp * mm_pi |
---|
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 | !! |
---|
625 | !! |
---|
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). |
---|
631 | !! |
---|
632 | !! Sedimentation algorithm is quite messy. It appeals to the dark side of the Force and uses evil black magic spells |
---|
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}\)). |
---|
639 | INTEGER :: i |
---|
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) |
---|
649 | ! (Tri)diagonal matrix inversion |
---|
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) + & |
---|
661 | cs(2:mm_nla-1)*mk(2:mm_nla-1) & |
---|
662 | )/as(2:mm_nla-1) |
---|
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. |
---|
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 |
---|
674 | !! equation: |
---|
675 | !! |
---|
676 | !! $$ |
---|
677 | !! \begin{eqnarray*} |
---|
678 | !! \Phi^{sed}_{M_{k}} &=& \int_{0}^{\infty} n(r) r^{k} \times w(r) dr |
---|
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 | !! |
---|
687 | !! \(v^{eff}_{M_{k}\) is then corrected to reduce numerical diffusion of the sedimentation algorithm |
---|
688 | !! as defined in \cite{toon1988b}. |
---|
689 | !! |
---|
690 | !! @warning |
---|
691 | !! Both __df__, __rc__ and __afun__ must be consistent with each other otherwise wrong values will |
---|
692 | !! be computed. |
---|
693 | REAL(kind=mm_wp), INTENT(in), DIMENSION(mm_nla) :: mk |
---|
694 | !! Moment of order __k__ (\(m^{k}.m^{-3}\)) at each layer. |
---|
695 | REAL(kind=mm_wp), INTENT(in), DIMENSION(mm_nla) :: rc |
---|
696 | !! Characteristic radius associated to the moment at each layer. |
---|
697 | REAL(kind=mm_wp), INTENT(in) :: k |
---|
698 | !! The order of the moment. |
---|
699 | REAL(kind=mm_wp), INTENT(in) :: df |
---|
700 | !! Fractal dimension of the aersols. |
---|
701 | REAL(kind=mm_wp), INTENT(in) :: dt |
---|
702 | !! Time step (s). |
---|
703 | REAL(kind=mm_wp), INTENT(out), DIMENSION(mm_nle) :: wth |
---|
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__. |
---|
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 |
---|
714 | END INTERFACE |
---|
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 | ! ------------------ |
---|
721 | |
---|
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 |
---|
725 | af1 = (df*(k+3._mm_wp)-3._mm_wp)/df ; af2 = (df*(k+3._mm_wp)-6._mm_wp)/df |
---|
726 | rb2ra = mm_rm**((df-3._mm_wp)/df) |
---|
727 | DO i=2,mm_nla |
---|
728 | IF (rc(i-1) <= 0._mm_wp) CYCLE |
---|
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)) |
---|
732 | wth(i) = - csto/(rb2ra*afun(k)) * (rc(i-1)**ar1 * afun(af1) + cslf/rb2ra * rc(i-1)**ar2 * afun(af2)) |
---|
733 | |
---|
734 | ! now correct velocity to reduce numerical diffusion |
---|
735 | IF (.NOT.mm_no_fiadero_w) THEN |
---|
736 | IF (mk(i) <= 0._mm_wp) THEN |
---|
737 | ratio = mm_fiadero_max |
---|
738 | ELSE |
---|
739 | ratio = MAX(MIN(mk(i-1)/mk(i),mm_fiadero_max),mm_fiadero_min) |
---|
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 |
---|
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) |
---|
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. |
---|
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 |
---|
765 | !! [[mm_globals(module):mm_p_prod(variable)]] pressure level with a fixed sigma of 20km. |
---|
766 | !! |
---|
767 | !! First M3 tendency is computed and M0 is retrieved using the inter-moments relation a spherical |
---|
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 |
---|
775 | REAL(kind=mm_wp) :: zprod,cprod,timefact |
---|
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) - & |
---|
795 | erf((mm_zlev(2:mm_nla+1)-zprod)/znorm)) |
---|
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 |
---|