← Back to Documentation Home
CCPP SciDoc v8.0.0  v8.0.0
Common Community Physics Package Developed at DTC
 
Loading...
Searching...
No Matches
gfdl_cloud_microphys_mod.F90
1
7!***********************************************************************
8!* GNU Lesser General Public License
9!*
10!* This file is part of the GFDL Cloud Microphysics.
11!*
12!* The GFDL Cloud Microphysics is free software: you can
13!* redistribute it and/or modify it under the terms of the
14!* GNU Lesser General Public License as published by the
15!* Free Software Foundation, either version 3 of the License, or
16!* (at your option) any later version.
17!*
18!* The GFDL Cloud Microphysics is distributed in the hope it will be
19!* useful, but WITHOUT ANYWARRANTY; without even the implied warranty
20!* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21!* See the GNU General Public License for more details.
22!*
23!* You should have received a copy of the GNU Lesser General Public
24!* License along with the GFDL Cloud Microphysics.
25!* If not, see <http://www.gnu.org/licenses/>.
26!***********************************************************************
27! =======================================================================
30
33
34 ! use mpp_mod, only: stdlog, mpp_pe, mpp_root_pe, mpp_clock_id, &
35 ! mpp_clock_begin, mpp_clock_end, clock_routine, &
36 ! input_nml_file
37 ! use diag_manager_mod, only: register_diag_field, send_data
38 ! use time_manager_mod, only: time_type, get_time
39 ! use constants_mod, only: grav, rdgas, rvgas, cp_air, hlv, hlf, pi => pi_8
40 ! use fms_mod, only: write_version_number, open_namelist_file, &
41 ! check_nml_error, file_exist, close_file
42
43 ! -----------------------------------------------------------------------
45 use module_gfdlmp_param, only: read_gfdlmp_nml, mp_time, t_min, t_sub, &
46 tau_r2g, tau_smlt, tau_g2r, dw_land, dw_ocean, vi_fac, vr_fac, &
47 vs_fac, vg_fac, ql_mlt, do_qa, fix_negative, vi_max, vs_max, &
48 vg_max, vr_max, qs_mlt, qs0_crt, qi_gen, ql0_max, qi0_max, &
49 qi0_crt, qr0_crt, fast_sat_adj, rh_inc, rh_ins, rh_inr, const_vi, &
50 const_vs, const_vg, const_vr, use_ccn, rthresh, ccn_l, ccn_o, &
51 qc_crt, tau_g2v, tau_v2g, sat_adj0, c_piacr, tau_imlt, tau_v2l, &
52 tau_l2v, tau_i2s, tau_l2r, qi_lim, ql_gen, c_paut, c_psaci, &
53 c_pgacs, z_slope_liq, z_slope_ice, prog_ccn, c_cracw, alin, clin, &
54 tice, rad_snow, rad_graupel, rad_rain, cld_min, use_ppm, &
55 mono_prof, do_sedi_heat, sedi_transport, do_sedi_w, de_ice, &
56 icloud_f, irain_f, mp_print, reiflag, rewmin, rewmax, reimin, &
57 reimax, rermin, rermax, resmin, resmax, regmin, regmax, tintqs, &
58 do_hail
59
60 implicit none
61
62 private
63
66! public wqs1, wqs2, qs_blend, wqsat_moist, wqsat2_moist
67! public qsmith_init, qsmith, es2_table1d, es3_table1d, esw_table1d
68! public setup_con, wet_bulb
69
70 real :: missing_value = - 1.e10
71
72 logical :: module_is_initialized = .false.
73 logical :: qsmith_tables_initialized = .false.
74
75 character (len = 20) :: mod_name = 'gfdl_cloud_microphys'
76
77 real, parameter :: n0r = 8.0e6, n0s = 3.0e6, n0g = 4.0e6
78 real, parameter :: rhos = 0.1e3, rhog = 0.4e3
79 real, parameter :: grav = 9.80665
80 real, parameter :: rdgas = 287.05
81 real, parameter :: rvgas = 461.50
82 real, parameter :: cp_air = 1004.6
83 real, parameter :: hlv = 2.5e6
84 real, parameter :: hlf = 3.3358e5
85 real, parameter :: pi = 3.1415926535897931
86
87 ! real, parameter :: rdgas = 287.04 !< gfdl: gas constant for dry air
88
89 ! real, parameter :: cp_air = rdgas * 7. / 2. ! 1004.675, heat capacity of dry air at constant pressure
90 real, parameter :: cp_vap = 4.0 * rvgas
91 ! real, parameter :: cv_air = 717.56 ! satoh value
92 real, parameter :: cv_air = cp_air - rdgas
93 ! real, parameter :: cv_vap = 1410.0 ! emanuel value
94 real, parameter :: cv_vap = 3.0 * rvgas
95
96 ! the following two are from emanuel's book "atmospheric convection"
97 ! real, parameter :: c_ice = 2106.0 ! heat capacity of ice at 0 deg c: c = c_ice + 7.3 * (t - tice)
98 ! real, parameter :: c_liq = 4190.0 ! heat capacity of water at 0 deg c
99
100 real, parameter :: c_ice = 1972.0
101 real, parameter :: c_liq = 4185.5
102 ! real, parameter :: c_liq = 4218.0 ! ifs: heat capacity of liquid at 0 deg c
103
104 real, parameter :: eps = rdgas / rvgas
105 real, parameter :: zvir = rvgas / rdgas - 1.
106
107 real, parameter :: t_ice = 273.16
108 real, parameter :: table_ice = 273.16
109
110 ! real, parameter :: e00 = 610.71 ! gfdl: saturation vapor pressure at 0 deg c
111 real, parameter :: e00 = 611.21
112
113 real, parameter :: dc_vap = cp_vap - c_liq
114 real, parameter :: dc_ice = c_liq - c_ice
115
116 real, parameter :: hlv0 = hlv
117 ! real, parameter :: hlv0 = 2.501e6 ! emanuel appendix - 2
118 real, parameter :: hlf0 = hlf
119 ! real, parameter :: hlf0 = 3.337e5 ! emanuel
120
121 real, parameter :: lv0 = hlv0 - dc_vap * t_ice
122 real, parameter :: li00 = hlf0 - dc_ice * t_ice
123
124 real, parameter :: d2ice = dc_vap + dc_ice
125 real, parameter :: li2 = lv0 + li00
126
127 real, parameter :: qrmin = 1.e-8
128 real, parameter :: qvmin = 1.e-20
129 real, parameter :: qcmin = 1.e-12
130
131 real, parameter :: vr_min = 1.e-3
132 real, parameter :: vf_min = 1.e-5
133
134 real, parameter :: dz_min = 1.e-2
135
136 real, parameter :: sfcrho = 1.2
137 real, parameter :: rhor = 1.e3
138 ! intercept parameters
139
140 real, parameter :: rnzr = 8.0e6 ! lin83
141 real, parameter :: rnzs = 3.0e6 ! lin83
142 real, parameter :: rnzg = 4.0e6 ! rh84
143 real, parameter :: rnzh = 4.0e4 ! lin83 --- lmh 29 sep 17
144
145 ! density parameters
146
147 real, parameter :: rhoh = 0.917e3 ! lin83 --- lmh 29 sep 17
148
149 public rhor, rhos, rhog, rhoh, rnzr, rnzs, rnzg, rnzh
150 real :: cracs, csacr, cgacr, cgacs, csacw, craci, csaci, cgacw, cgaci, cracw
151 real :: acco (3, 4)
152 real :: cssub (5), cgsub (5), crevp (5), cgfr (2), csmlt (5), cgmlt (5)
153
154 real :: es0, ces0
155 real :: pie, rgrav, fac_rc
156 real :: c_air, c_vap
157
158 real :: lati, latv, lats, lat2, lcp, icp, tcp
159
160 real :: d0_vap
161 real :: lv00
162
163 ! cloud microphysics switchers
164 logical :: do_setup = .true.
165 logical :: p_nonhydro = .false.
166
167 real, allocatable :: table (:), table2 (:), table3 (:), tablew (:)
168 real, allocatable :: des (:), des2 (:), des3 (:), desw (:)
169
170 logical :: tables_are_initialized = .false.
171
172 ! logical :: master
173 ! integer :: id_rh, id_vtr, id_vts, id_vtg, id_vti, id_rain, id_snow, id_graupel, &
174 ! id_ice, id_prec, id_cond, id_var, id_droplets
175 real, parameter :: dt_fr = 8.
176 ! minimum temperature water can exist (moore & molinero nov. 2011, nature)
177 ! dt_fr can be considered as the error bar
178
179 real :: p_min = 100.
180
181 ! slj, the following parameters are for cloud - resolving resolution: 1 - 5 km
182
183 ! qi0_crt = 0.8e-4
184 ! qs0_crt = 0.6e-3
185 ! c_psaci = 0.1
186 ! c_pgacs = 0.1
187
188 real :: log_10, tice0, t_wfr
189
190contains
191
192! -----------------------------------------------------------------------
193! the driver of the gfdl cloud microphysics
194! -----------------------------------------------------------------------
195
199 iis, iie, jjs, jje, kks, kke, ktop, kbot, &
200 qv, ql, qr, qi, qs, qg, qa, qn, &
201 qv_dt, ql_dt, qr_dt, qi_dt, qs_dt, qg_dt, qa_dt, pt_dt, pt, w, &
202 uin, vin, udt, vdt, dz, delp, area, dt_in, land, &
203 rain, snow, ice, graupel, hydrostatic, phys_hydrostatic, &
204 p, lradar, refl_10cm, reset, pfils, pflls)
205
206 implicit none
207
208 ! Interface variables
209 integer, intent (in) :: iis, iie, jjs, jje ! physics window
210 integer, intent (in) :: kks, kke ! vertical dimension
211 integer, intent (in) :: ktop, kbot ! vertical compute domain
212
213 real, intent (in) :: dt_in ! physics time step
214
215 real, intent (in), dimension (iis:iie, jjs:jje) :: area ! cell area
216 real, intent (in), dimension (iis:iie, jjs:jje) :: land ! land fraction
217
218 real, intent (in), dimension (iis:iie, jjs:jje, kks:kke) :: delp, dz, uin, vin
219 real, intent (in), dimension (iis:iie, jjs:jje, kks:kke) :: pt, qv, ql, qr, qg, qa, qn
220
221 real, intent (inout), dimension (iis:iie, jjs:jje, kks:kke) :: qi, qs
222 real, intent (inout), dimension (iis:iie, jjs:jje, kks:kke) :: pt_dt, qa_dt, udt, vdt, w
223 real, intent (inout), dimension (iis:iie, jjs:jje, kks:kke) :: qv_dt, ql_dt, qr_dt
224 real, intent (inout), dimension (iis:iie, jjs:jje, kks:kke) :: qi_dt, qs_dt, qg_dt
225
226 real, intent (out), dimension (iis:iie, jjs:jje) :: rain, snow, ice, graupel
227
228 logical, intent (in) :: hydrostatic, phys_hydrostatic
229
230 !integer, intent (in) :: seconds
231 real, intent (in), dimension (iis:iie, jjs:jje, kks:kke) :: p
232 logical, intent (in) :: lradar
233 real, intent (out), dimension (iis:iie, jjs:jje, kks:kke) :: refl_10cm
234 logical, intent (in) :: reset
235 real, intent (out), dimension (iis:iie, jjs:jje, kks:kke) :: pfils, pflls
236
237 ! Local variables
238 logical :: melti = .false.
239
240 real :: mpdt, rdt, dts, convt, tot_prec
241
242 integer :: i, j, k
243 integer :: is, ie, js, je ! physics window
244 integer :: ks, ke ! vertical dimension
245 integer :: days, ntimes, kflip
246
247 real, dimension (iie-iis+1, jje-jjs+1) :: prec_mp, prec1, cond, w_var, rh0
248
249 real, dimension (iie-iis+1, jje-jjs+1,kke-kks+1) :: vt_r, vt_s, vt_g, vt_i, qn2
250
251 real, dimension (size(pt,1), size(pt,3)) :: m2_rain, m2_sol
252
253 real :: allmax
254!+---+-----------------------------------------------------------------+
255!For 3D reflectivity calculations
256 real, dimension(ktop:kbot):: qv1d, t1d, p1d, qr1d, qs1d, qg1d, dbz
257!+---+-----------------------------------------------------------------+
258
259 is = 1
260 js = 1
261 ks = 1
262 ie = iie - iis + 1
263 je = jje - jjs + 1
264 ke = kke - kks + 1
265 ! call mpp_clock_begin (gfdl_mp_clock)
266
267 ! -----------------------------------------------------------------------
268 ! define heat capacity of dry air and water vapor based on hydrostatical property
269 ! -----------------------------------------------------------------------
270
271 if (phys_hydrostatic .or. hydrostatic) then
272 c_air = cp_air
273 c_vap = cp_vap
274 p_nonhydro = .false.
275 else
276 c_air = cv_air
277 c_vap = cv_vap
278 p_nonhydro = .true.
279 endif
280 d0_vap = c_vap - c_liq
281 lv00 = hlv0 - d0_vap * t_ice
282
283 if (hydrostatic) do_sedi_w = .false.
284
285 ! -----------------------------------------------------------------------
286 ! define latent heat coefficient used in wet bulb and Bigg mechanism
287 ! -----------------------------------------------------------------------
288
289 latv = hlv
290 lati = hlf
291 lats = latv + lati
292 lat2 = lats * lats
293
294 lcp = latv / cp_air
295 icp = lati / cp_air
296 tcp = (latv + lati) / cp_air
297
298 ! tendency zero out for am moist processes should be done outside the driver
299
300 ! -----------------------------------------------------------------------
301 ! define cloud microphysics sub time step
302 ! -----------------------------------------------------------------------
303
304 mpdt = min(dt_in, mp_time)
305 rdt = 1. / dt_in
306 ntimes = nint(dt_in / mpdt)
307
308 ! small time step:
309 dts = dt_in / real(ntimes)
310
311 ! call get_time (time, seconds, days)
312
313 ! -----------------------------------------------------------------------
314 ! initialize precipitation
315 ! -----------------------------------------------------------------------
316
317 do j = js, je
318 do i = is, ie
319 graupel(i, j) = 0.
320 rain(i, j) = 0.
321 snow(i, j) = 0.
322 ice(i, j) = 0.
323 cond(i, j) = 0.
324 enddo
325 enddo
326
327 pfils = 0.
328 pflls = 0.
329
330 ! -----------------------------------------------------------------------
331 ! major cloud microphysics
332 ! -----------------------------------------------------------------------
333
334 do j = js, je
335 call mpdrv (hydrostatic, uin, vin, w, delp, pt, qv, ql, qr, qi, qs, qg,&
336 qa, qn, dz, is, ie, js, je, ks, ke, ktop, kbot, j, dt_in, ntimes, &
337 rain(:, j), snow(:, j), graupel(:, j), ice(:, j), m2_rain, &
338 m2_sol, cond(:, j), area(:, j), land(:, j), udt, vdt, pt_dt, &
339 qv_dt, ql_dt, qr_dt, qi_dt, qs_dt, qg_dt, qa_dt, w_var, vt_r, &
340 vt_s, vt_g, vt_i, qn2)
341 do k = ktop, kbot
342 do i = is, ie
343 pfils(i, j, k) = m2_sol(i, k)
344 pflls(i, j, k) = m2_rain(i, k)
345 enddo
346 enddo
347 enddo
348
349 ! -----------------------------------------------------------------------
350 ! no clouds allowed above ktop
351 ! -----------------------------------------------------------------------
352
353 if (ks < ktop) then
354 do k = ks, ktop
355 if (do_qa) then
356 do j = js, je
357 do i = is, ie
358 qa_dt(i, j, k) = 0.
359 enddo
360 enddo
361 else
362 do j = js, je
363 do i = is, ie
364 ! qa_dt (i, j, k) = - qa (i, j, k) * rdt
365 qa_dt(i, j, k) = 0. ! gfs
366 enddo
367 enddo
368 endif
369 enddo
370 endif
371
372 ! -----------------------------------------------------------------------
373 ! diagnostic output
374 ! -----------------------------------------------------------------------
375
376 ! if (id_vtr > 0) then
377 ! used = send_data (id_vtr, vt_r, time, is_in = iis, js_in = jjs)
378 ! endif
379
380 ! if (id_vts > 0) then
381 ! used = send_data (id_vts, vt_s, time, is_in = iis, js_in = jjs)
382 ! endif
383
384 ! if (id_vtg > 0) then
385 ! used = send_data (id_vtg, vt_g, time, is_in = iis, js_in = jjs)
386 ! endif
387
388 ! if (id_vti > 0) then
389 ! used = send_data (id_vti, vt_i, time, is_in = iis, js_in = jjs)
390 ! endif
391
392 ! if (id_droplets > 0) then
393 ! used = send_data (id_droplets, qn2, time, is_in = iis, js_in = jjs)
394 ! endif
395
396 ! if (id_var > 0) then
397 ! used = send_data (id_var, w_var, time, is_in = iis, js_in = jjs)
398 ! endif
399
400 ! convert to mm / day
401
402 convt = 86400. * rdt * rgrav
403 do j = js, je
404 do i = is, ie
405 rain(i, j) = rain(i, j) * convt
406 snow(i, j) = snow(i, j) * convt
407 ice(i, j) = ice(i, j) * convt
408 graupel(i, j) = graupel(i, j) * convt
409 prec_mp(i, j) = rain(i, j) + snow(i, j) + ice(i, j) + graupel(i, j)
410 enddo
411 enddo
412
413 ! if (id_cond > 0) then
414 ! do j = js, je
415 ! do i = is, ie
416 ! cond (i, j) = cond (i, j) * rgrav
417 ! enddo
418 ! enddo
419 ! used = send_data (id_cond, cond, time, is_in = iis, js_in = jjs)
420 ! endif
421
422 ! if (id_snow > 0) then
423 ! used = send_data (id_snow, snow, time, iis, jjs)
424 ! used = send_data (id_snow, snow, time, is_in = iis, js_in = jjs)
425 ! if (mp_print .and. seconds == 0) then
426 ! tot_prec = g_sum (snow, is, ie, js, je, area, 1)
427 ! if (master) write (*, *) 'mean snow = ', tot_prec
428 ! endif
429 ! endif
430 !
431 ! if (id_graupel > 0) then
432 ! used = send_data (id_graupel, graupel, time, iis, jjs)
433 ! used = send_data (id_graupel, graupel, time, is_in = iis, js_in = jjs)
434 ! if (mp_print .and. seconds == 0) then
435 ! tot_prec = g_sum (graupel, is, ie, js, je, area, 1)
436 ! if (master) write (*, *) 'mean graupel = ', tot_prec
437 ! endif
438 ! endif
439 !
440 ! if (id_ice > 0) then
441 ! used = send_data (id_ice, ice, time, iis, jjs)
442 ! used = send_data (id_ice, ice, time, is_in = iis, js_in = jjs)
443 ! if (mp_print .and. seconds == 0) then
444 ! tot_prec = g_sum (ice, is, ie, js, je, area, 1)
445 ! if (master) write (*, *) 'mean ice_mp = ', tot_prec
446 ! endif
447 ! endif
448 !
449 ! if (id_rain > 0) then
450 ! used = send_data (id_rain, rain, time, iis, jjs)
451 ! used = send_data (id_rain, rain, time, is_in = iis, js_in = jjs)
452 ! if (mp_print .and. seconds == 0) then
453 ! tot_prec = g_sum (rain, is, ie, js, je, area, 1)
454 ! if (master) write (*, *) 'mean rain = ', tot_prec
455 ! endif
456 ! endif
457 !
458 ! if (id_rh > 0) then !not used?
459 ! used = send_data (id_rh, rh0, time, iis, jjs)
460 ! used = send_data (id_rh, rh0, time, is_in = iis, js_in = jjs)
461 ! endif
462 !
463 !
464 ! if (id_prec > 0) then
465 ! used = send_data (id_prec, prec_mp, time, iis, jjs)
466 ! used = send_data (id_prec, prec_mp, time, is_in = iis, js_in = jjs)
467 ! endif
468
469 ! if (mp_print) then
470 ! prec1 (:, :) = prec1 (:, :) + prec_mp (:, :)
471 ! if (seconds == 0) then
472 ! prec1 (:, :) = prec1 (:, :) * dt_in / 86400.
473 ! tot_prec = g_sum (prec1, is, ie, js, je, area, 1)
474 ! if (master) write (*, *) 'daily prec_mp = ', tot_prec
475 ! prec1 (:, :) = 0.
476 ! endif
477 ! endif
478
479 ! call mpp_clock_end (gfdl_mp_clock)
480 if(lradar) then
481 ! Only set melti to true at the output times
482 if (reset) then
483 melti=.true.
484 else
485 melti=.false.
486 endif
487 do j = js, je
488 do i = is, ie
489 do k = ktop,kbot
490 kflip = kbot-ktop+1-k+1
491 t1d(k) = pt(i,j,kflip)
492 p1d(k) = p(i,j,kflip)
493 qv1d(k) = qv(i,j,kflip)/(1-qv(i,j,kflip))
494 qr1d(k) = qr(i,j,kflip)
495 qs1d(k) = qs(i,j,kflip)
496 qg1d(k) = qg(i,j,kflip)
497 enddo
498 call refl10cm_gfdl (qv1d, qr1d, qs1d, qg1d, &
499 t1d, p1d, dbz, ktop, kbot, i, j, melti)
500 do k = ktop,kbot
501 kflip = kbot-ktop+1-k+1
502 refl_10cm(i,j,kflip) = max(-35., dbz(k))
503 enddo
504 enddo
505 enddo
506 endif
507
509
510! -----------------------------------------------------------------------
517subroutine mpdrv (hydrostatic, uin, vin, w, delp, pt, qv, ql, qr, qi, qs, &
518 qg, qa, qn, dz, is, ie, js, je, ks, ke, ktop, kbot, j, dt_in, ntimes, &
519 rain, snow, graupel, ice, m2_rain, m2_sol, cond, area1, land, &
520 u_dt, v_dt, pt_dt, qv_dt, ql_dt, qr_dt, qi_dt, qs_dt, qg_dt, qa_dt, &
521 w_var, vt_r, vt_s, vt_g, vt_i, qn2)
522
523 implicit none
524
525 logical, intent (in) :: hydrostatic
526
527 integer, intent (in) :: j, is, ie, js, je, ks, ke
528 integer, intent (in) :: ntimes, ktop, kbot
529
530 real, intent (in) :: dt_in
531
532 real, intent (in), dimension (is:) :: area1, land
533
534 real, intent (in), dimension (is:, js:, ks:) :: uin, vin, delp, pt, dz
535 real, intent (in), dimension (is:, js:, ks:) :: qv, ql, qr, qg, qa, qn
536
537 real, intent (inout), dimension (is:, js:, ks:) :: qi, qs
538 real, intent (inout), dimension (is:, js:, ks:) :: u_dt, v_dt, w, pt_dt, qa_dt
539 real, intent (inout), dimension (is:, js:, ks:) :: qv_dt, ql_dt, qr_dt, qi_dt, qs_dt, qg_dt
540
541 real, intent (inout), dimension (is:) :: rain, snow, ice, graupel, cond
542
543 real, intent (out), dimension (is:, js:) :: w_var
544
545 real, intent (out), dimension (is:, js:, ks:) :: vt_r, vt_s, vt_g, vt_i, qn2
546
547 real, intent (out), dimension (is:, ks:) :: m2_rain, m2_sol
548
549 real, dimension (ktop:kbot) :: qvz, qlz, qrz, qiz, qsz, qgz, qaz
550 real, dimension (ktop:kbot) :: vtiz, vtsz, vtgz, vtrz
551 real, dimension (ktop:kbot) :: dp0, dp1, dz0, dz1
552 real, dimension (ktop:kbot) :: qv0, ql0, qr0, qi0, qs0, qg0, qa0
553 real, dimension (ktop:kbot) :: t0, den, den0, tz, p1, denfac
554 real, dimension (ktop:kbot) :: ccn, c_praut, m1_rain, m1_sol, m1
555 real, dimension (ktop:kbot) :: u0, v0, u1, v1, w1
556
557 real :: cpaut, rh_adj, rh_rain
558 real :: r1, s1, i1, g1, rdt, ccn0
559 real :: dt_rain, dts
560 real :: s_leng, t_land, t_ocean, h_var
561 real :: cvm, tmp, omq
562 real :: dqi, qio, qin
563
564 integer :: i, k, n
565
566 dts = dt_in / real(ntimes)
567 dt_rain = dts * 0.5
568 rdt = 1. / dt_in
569
570 ! -----------------------------------------------------------------------
571 ! use local variables
572 ! -----------------------------------------------------------------------
573
574 !GJF: assign values to intent(out) variables that are commented out
575 w_var = 0.0
576 vt_r = 0.0
577 vt_s = 0.0
578 vt_g = 0.0
579 vt_i = 0.0
580 qn2 = 0.0
581 !GJF
582
583 do i = is, ie
584
585 do k = ktop, kbot
586 qiz(k) = qi(i, j, k)
587 qsz(k) = qs(i, j, k)
588 enddo
589
590 ! -----------------------------------------------------------------------
592 ! -----------------------------------------------------------------------
593
594 if (de_ice) then
595 do k = ktop, kbot
596 qio = qiz(k) - dt_in * qi_dt(i, j, k) ! original qi before phys
597 qin = max(qio, qi0_max) ! adjusted value
598 if (qiz(k) > qin) then
599 qsz(k) = qsz(k) + qiz(k) - qin
600 qiz(k) = qin
601 dqi = (qin - qio) * rdt ! modified qi tendency
602 qs_dt(i, j, k) = qs_dt(i, j, k) + qi_dt(i, j, k) - dqi
603 qi_dt(i, j, k) = dqi
604 qi(i, j, k) = qiz(k)
605 qs(i, j, k) = qsz(k)
606 endif
607 enddo
608 endif
609
610 do k = ktop, kbot
611
612 t0(k) = pt(i, j, k)
613 tz(k) = t0(k)
614 dp1(k) = delp(i, j, k)
615 dp0(k) = dp1(k) ! moist air mass * grav
616
617 ! -----------------------------------------------------------------------
619 ! -----------------------------------------------------------------------
620
621 qvz(k) = qv(i, j, k)
622 qlz(k) = ql(i, j, k)
623 qrz(k) = qr(i, j, k)
624 qgz(k) = qg(i, j, k)
625
626 ! dp1: dry air_mass
627 ! dp1 (k) = dp1 (k) * (1. - (qvz (k) + qlz (k) + qrz (k) + qiz (k) + qsz (k) + qgz (k)))
628 dp1(k) = dp1(k) * (1. - qvz(k)) ! gfs
629 omq = dp0(k) / dp1(k)
630
631 qvz(k) = qvz(k) * omq
632 qlz(k) = qlz(k) * omq
633 qrz(k) = qrz(k) * omq
634 qiz(k) = qiz(k) * omq
635 qsz(k) = qsz(k) * omq
636 qgz(k) = qgz(k) * omq
637
638 qa0(k) = qa(i, j, k)
639 qaz(k) = 0.
640 dz0(k) = dz(i, j, k)
641
642 den0(k) = - dp1(k) / (grav * dz0(k)) ! density of dry air
643 p1(k) = den0(k) * rdgas * t0(k) ! dry air pressure
644
645 ! -----------------------------------------------------------------------
646 ! save a copy of old value for computing tendencies
647 ! -----------------------------------------------------------------------
648
649 qv0(k) = qvz(k)
650 ql0(k) = qlz(k)
651 qr0(k) = qrz(k)
652 qi0(k) = qiz(k)
653 qs0(k) = qsz(k)
654 qg0(k) = qgz(k)
655
656 ! -----------------------------------------------------------------------
657 ! for sedi_momentum
658 ! -----------------------------------------------------------------------
659
660 m1(k) = 0.
661 u0(k) = uin(i, j, k)
662 v0(k) = vin(i, j, k)
663 u1(k) = u0(k)
664 v1(k) = v0(k)
665
666 enddo
667
668 if (do_sedi_w) then
669 do k = ktop, kbot
670 w1(k) = w(i, j, k)
671 enddo
672 ! Set to -999 if not used
673 else
674 w1(:) = -999.0
675 endif
676
677 ! -----------------------------------------------------------------------
680 ! -----------------------------------------------------------------------
681
682 cpaut = c_paut * 0.104 * grav / 1.717e-5
683
684 if (prog_ccn) then
685 do k = ktop, kbot
686 ! convert # / cc to # / m^3
687 ccn(k) = qn(i, j, k) * 1.e6
688 c_praut(k) = cpaut * (ccn(k) * rhor) ** (- 1. / 3.)
689 enddo
690 use_ccn = .false.
691 else
692 ccn0 = (ccn_l * land(i) + ccn_o * (1. - land(i))) * 1.e6
693 if (use_ccn) then
694 ! -----------------------------------------------------------------------
695 ! ccn is formulted as ccn = ccn_surface * (den / den_surface)
696 ! -----------------------------------------------------------------------
697 ccn0 = ccn0 * rdgas * tz(kbot) / p1(kbot)
698 endif
699 tmp = cpaut * (ccn0 * rhor) ** (- 1. / 3.)
700 do k = ktop, kbot
701 c_praut(k) = tmp
702 ccn(k) = ccn0
703 enddo
704 endif
705
706 ! -----------------------------------------------------------------------
728 ! total water subgrid deviation in horizontal direction
729 ! default area dependent form: use dx ~ 100 km as the base
730 ! -----------------------------------------------------------------------
731
732 s_leng = sqrt(sqrt(area1(i) / 1.e10))
733 t_land = dw_land * s_leng
734 t_ocean = dw_ocean * s_leng
735 h_var = t_land * land(i) + t_ocean * (1. - land(i))
736 h_var = min(0.20, max(0.01, h_var))
737 ! if (id_var > 0) w_var (i, j) = h_var
738
739 ! -----------------------------------------------------------------------
741 ! -----------------------------------------------------------------------
742
743 rh_adj = 1. - h_var - rh_inc
744 rh_rain = max(0.35, rh_adj - rh_inr) ! rh_inr = 0.25
745
746 ! -----------------------------------------------------------------------
748 ! -----------------------------------------------------------------------
749
750 if (fix_negative) &
751 call neg_adj (ktop, kbot, tz, dp1, qvz, qlz, qrz, qiz, qsz, qgz)
752
753 m2_rain(i, :) = 0.
754 m2_sol(i, :) = 0.
755
757 do n = 1, ntimes
758
759 ! -----------------------------------------------------------------------
761 ! -----------------------------------------------------------------------
762
763 if (p_nonhydro) then
764 do k = ktop, kbot
765 dz1(k) = dz0(k)
766 den(k) = den0(k) ! dry air density remains the same
767 denfac(k) = sqrt(sfcrho / den(k))
768 enddo
769 else
770 do k = ktop, kbot
771 dz1(k) = dz0(k) * tz(k) / t0(k) ! hydrostatic balance
772 den(k) = den0(k) * dz0(k) / dz1(k)
773 denfac(k) = sqrt(sfcrho / den(k))
774 enddo
775 endif
776
777 ! -----------------------------------------------------------------------
779 ! -----------------------------------------------------------------------
780
781 call warm_rain (dt_rain, ktop, kbot, dp1, dz1, tz, qvz, qlz, qrz, qiz, qsz, &
782 qgz, den, denfac, ccn, c_praut, rh_rain, vtrz, r1, m1_rain, w1, h_var)
783
784 rain(i) = rain(i) + r1
785
786 do k = ktop, kbot
787 m2_rain(i, k) = m2_rain(i, k) + m1_rain(k)
788 m1(k) = m1(k) + m1_rain(k)
789 enddo
790
791 ! -----------------------------------------------------------------------
793 ! -----------------------------------------------------------------------
794
797 call fall_speed (ktop, kbot, den, qsz, qiz, qgz, qlz, tz, vtsz, vtiz, vtgz)
798
800 call terminal_fall (dts, ktop, kbot, tz, qvz, qlz, qrz, qgz, qsz, qiz, &
801 dz1, dp1, den, vtgz, vtsz, vtiz, r1, g1, s1, i1, m1_sol, w1)
802
803 rain(i) = rain(i) + r1 ! from melted snow & ice that reached the ground
804 snow(i) = snow(i) + s1
805 graupel(i) = graupel(i) + g1
806 ice(i) = ice(i) + i1
807
808 ! -----------------------------------------------------------------------
810 ! -----------------------------------------------------------------------
811
812 if (do_sedi_heat) &
813 call sedi_heat (ktop, kbot, dp1, m1_sol, dz1, tz, qvz, qlz, qrz, qiz, &
814 qsz, qgz, c_ice)
815
816 ! -----------------------------------------------------------------------
818 ! -----------------------------------------------------------------------
819
820 call warm_rain (dt_rain, ktop, kbot, dp1, dz1, tz, qvz, qlz, qrz, qiz, qsz, &
821 qgz, den, denfac, ccn, c_praut, rh_rain, vtrz, r1, m1_rain, w1, h_var)
822
823 rain(i) = rain(i) + r1
824
825 do k = ktop, kbot
826 m2_rain(i, k) = m2_rain(i, k) + m1_rain(k)
827 m2_sol(i, k) = m2_sol(i, k) + m1_sol(k)
828 m1(k) = m1(k) + m1_rain(k) + m1_sol(k)
829 enddo
830
831 ! -----------------------------------------------------------------------
833 ! -----------------------------------------------------------------------
834
835 call icloud (ktop, kbot, tz, p1, qvz, qlz, qrz, qiz, qsz, qgz, dp1, den, &
836 denfac, vtsz, vtgz, vtrz, qaz, rh_adj, rh_rain, dts, h_var)
837
838 enddo
839
840 ! convert units from Pa*kg/kg to kg/m^2/s
841 m2_rain(i, :) = m2_rain(i, :) * rdt * rgrav
842 m2_sol(i, :) = m2_sol(i, :) * rdt * rgrav
843
844 ! -----------------------------------------------------------------------
846 ! note: dp1 is dry mass; dp0 is the old moist (total) mass
847 ! -----------------------------------------------------------------------
848
849 if (sedi_transport) then
850 do k = ktop + 1, kbot
851 u1(k) = (dp0(k) * u1(k) + m1(k - 1) * u1(k - 1)) / (dp0(k) + m1(k - 1))
852 v1(k) = (dp0(k) * v1(k) + m1(k - 1) * v1(k - 1)) / (dp0(k) + m1(k - 1))
853 u_dt(i, j, k) = u_dt(i, j, k) + (u1(k) - u0(k)) * rdt
854 v_dt(i, j, k) = v_dt(i, j, k) + (v1(k) - v0(k)) * rdt
855 enddo
856 endif
857
858 if (do_sedi_w) then
859 do k = ktop, kbot
860 w(i, j, k) = w1(k)
861 enddo
862 endif
863
864 ! -----------------------------------------------------------------------
866 ! convert to dry mixing ratios
867 ! -----------------------------------------------------------------------
868
869 do k = ktop, kbot
870 omq = dp1(k) / dp0(k)
871 qv_dt(i, j, k) = qv_dt(i, j, k) + rdt * (qvz(k) - qv0(k)) * omq
872 ql_dt(i, j, k) = ql_dt(i, j, k) + rdt * (qlz(k) - ql0(k)) * omq
873 qr_dt(i, j, k) = qr_dt(i, j, k) + rdt * (qrz(k) - qr0(k)) * omq
874 qi_dt(i, j, k) = qi_dt(i, j, k) + rdt * (qiz(k) - qi0(k)) * omq
875 qs_dt(i, j, k) = qs_dt(i, j, k) + rdt * (qsz(k) - qs0(k)) * omq
876 qg_dt(i, j, k) = qg_dt(i, j, k) + rdt * (qgz(k) - qg0(k)) * omq
877 cvm = c_air + qvz(k) * c_vap + (qrz(k) + qlz(k)) * c_liq + (qiz(k) + qsz(k) + qgz(k)) * c_ice
878 pt_dt(i, j, k) = pt_dt(i, j, k) + rdt * (tz(k) - t0(k)) * cvm / cp_air
879 enddo
880
881 ! -----------------------------------------------------------------------
883 ! -----------------------------------------------------------------------
884
885 do k = ktop, kbot
886 if (do_qa) then
887 qa_dt(i, j, k) = 0.
888 else
889 qa_dt(i, j, k) = qa_dt(i, j, k) + rdt * (qaz(k) / real(ntimes) - qa0(k))
890 endif
891 enddo
892
893 ! -----------------------------------------------------------------------
894 ! fms diagnostics:
895 ! -----------------------------------------------------------------------
896
897 ! if (id_cond > 0) then
898 ! do k = ktop, kbot ! total condensate
899 ! cond (i) = cond (i) + dp1 (k) * (qlz (k) + qrz (k) + qsz (k) + qiz (k) + qgz (k))
900 ! enddo
901 ! endif
902 !
903 ! if (id_vtr > 0) then
904 ! do k = ktop, kbot
905 ! vt_r (i, j, k) = vtrz (k)
906 ! enddo
907 ! endif
908 !
909 ! if (id_vts > 0) then
910 ! do k = ktop, kbot
911 ! vt_s (i, j, k) = vtsz (k)
912 ! enddo
913 ! endif
914 !
915 ! if (id_vtg > 0) then
916 ! do k = ktop, kbot
917 ! vt_g (i, j, k) = vtgz (k)
918 ! enddo
919 ! endif
920 !
921 ! if (id_vts > 0) then
922 ! do k = ktop, kbot
923 ! vt_i (i, j, k) = vtiz (k)
924 ! enddo
925 ! endif
926 !
927 ! if (id_droplets > 0) then
928 ! do k = ktop, kbot
929 ! qn2 (i, j, k) = ccn (k)
930 ! enddo
931 ! endif
932
933 enddo
934
935end subroutine mpdrv
936
937! -----------------------------------------------------------------------
940subroutine sedi_heat (ktop, kbot, dm, m1, dz, tz, qv, ql, qr, qi, qs, qg, cw)
941
942 implicit none
943
944 ! input q fields are dry mixing ratios, and dm is dry air mass
945
946 integer, intent (in) :: ktop, kbot
947
948 real, intent (in), dimension (ktop:kbot) :: dm, m1, dz, qv, ql, qr, qi, qs, qg
949
950 real, intent (inout), dimension (ktop:kbot) :: tz
951
952 real, intent (in) :: cw ! heat capacity
953
954 real, dimension (ktop:kbot) :: dgz, cvn
955
956 real :: tmp
957
958 integer :: k
959
960 do k = ktop, kbot
961 dgz(k) = - 0.5 * grav * dz(k) ! > 0
962 cvn(k) = dm(k) * (cv_air + qv(k) * cv_vap + (qr(k) + ql(k)) * &
963 c_liq + (qi(k) + qs(k) + qg(k)) * c_ice)
964 enddo
965
966 ! -----------------------------------------------------------------------
967 ! sjl, july 2014
968 ! assumption: the ke in the falling condensates is negligible compared to the potential energy
969 ! that was unaccounted for. local thermal equilibrium is assumed, and the loss in pe is transformed
970 ! into internal energy (to heat the whole grid box)
971 ! backward time - implicit upwind transport scheme:
972 ! dm here is dry air mass
973 ! -----------------------------------------------------------------------
974
975 k = ktop
976 tmp = cvn(k) + m1(k) * cw
977 tz(k) = (tmp * tz(k) + m1(k) * dgz(k)) / tmp
978
979 ! -----------------------------------------------------------------------
980 ! implicit algorithm: can't be vectorized
981 ! needs an inner i - loop for vectorization
982 ! -----------------------------------------------------------------------
983
984 do k = ktop + 1, kbot
985 tz(k) = ((cvn(k) + cw * (m1(k) - m1(k - 1))) * tz(k) + m1(k - 1) * &
986 cw * tz(k - 1) + dgz(k) * (m1(k - 1) + m1(k))) / (cvn(k) + cw * m1(k))
987 enddo
988
989end subroutine sedi_heat
990
991! -----------------------------------------------------------------------
995subroutine warm_rain (dt, ktop, kbot, dp, dz, tz, qv, ql, qr, qi, qs, qg, &
996 den, denfac, ccn, c_praut, rh_rain, vtr, r1, m1_rain, w1, h_var)
997
998 implicit none
999
1000 integer, intent (in) :: ktop, kbot
1001
1002 real, intent (in) :: dt ! time step (s)
1003 real, intent (in) :: rh_rain, h_var
1004
1005 real, intent (in), dimension (ktop:kbot) :: dp, dz, den
1006 real, intent (in), dimension (ktop:kbot) :: denfac, ccn, c_praut
1007
1008 real, intent (inout), dimension (ktop:kbot) :: tz, vtr
1009 real, intent (inout), dimension (ktop:kbot) :: qv, ql, qr, qi, qs, qg
1010 real, intent (inout), dimension (ktop:kbot) :: m1_rain, w1
1011
1012 real, intent (out) :: r1
1013
1014 real, parameter :: so3 = 7. / 3.
1015
1016 real, dimension (ktop:kbot) :: dl, dm
1017 real, dimension (ktop:kbot + 1) :: ze, zt
1018
1019 real :: sink, dq, qc0, qc
1020 real :: qden
1021 real :: zs = 0.
1022 real :: dt5
1023
1024 integer :: k
1025
1026 ! fall velocity constants:
1027
1028 real, parameter :: vconr = 2503.23638966667
1029 real, parameter :: normr = 25132741228.7183
1030 real, parameter :: thr = 1.e-8
1031
1032 logical :: no_fall
1033
1034 dt5 = 0.5 * dt
1035
1036 ! -----------------------------------------------------------------------
1038 ! -----------------------------------------------------------------------
1039
1040 m1_rain(:) = 0.
1041
1042 call check_column (ktop, kbot, qr, no_fall)
1043
1044 if (no_fall) then
1045 vtr(:) = vf_min
1046 r1 = 0.
1047 else
1048
1049 ! -----------------------------------------------------------------------
1051 ! -----------------------------------------------------------------------
1052
1053 if (const_vr) then
1054 vtr(:) = vr_fac ! ifs_2016: 4.0
1055 else
1056 do k = ktop, kbot
1057 qden = qr(k) * den(k)
1058 if (qr(k) < thr) then
1059 vtr(k) = vr_min
1060 else
1061 vtr(k) = vr_fac * vconr * sqrt(min(10., sfcrho / den(k))) * &
1062 exp(0.2 * log(qden / normr))
1063 vtr(k) = min(vr_max, max(vr_min, vtr(k)))
1064 endif
1065 enddo
1066 endif
1067
1068 ze(kbot + 1) = zs
1069 do k = kbot, ktop, - 1
1070 ze(k) = ze(k + 1) - dz(k) ! dz < 0
1071 enddo
1072
1073 ! -----------------------------------------------------------------------
1076 ! -----------------------------------------------------------------------
1077
1078 ! if (.not. fast_sat_adj) &
1079 call revap_racc (ktop, kbot, dt5, tz, qv, ql, qr, qi, qs, qg, den, denfac, rh_rain, h_var)
1080
1081 if (do_sedi_w) then
1082 do k = ktop, kbot
1083 dm(k) = dp(k) * (1. + qv(k) + ql(k) + qr(k) + qi(k) + qs(k) + qg(k))
1084 enddo
1085 endif
1086
1087 ! -----------------------------------------------------------------------
1090 ! -----------------------------------------------------------------------
1091
1092 if (use_ppm) then
1093 zt(ktop) = ze(ktop)
1094 do k = ktop + 1, kbot
1095 zt(k) = ze(k) - dt5 * (vtr(k - 1) + vtr(k))
1096 enddo
1097 zt(kbot + 1) = zs - dt * vtr(kbot)
1098
1099 do k = ktop, kbot
1100 if (zt(k + 1) >= zt(k)) zt(k + 1) = zt(k) - dz_min
1101 enddo
1102 call lagrangian_fall_ppm (ktop, kbot, zs, ze, zt, dp, qr, r1, m1_rain, mono_prof)
1103 else
1104 call implicit_fall (dt, ktop, kbot, ze, vtr, dp, qr, r1, m1_rain)
1105 endif
1106
1107 ! -----------------------------------------------------------------------
1108 ! - Calculate vertical velocity transportation during sedimentation.
1109 ! (do_sedi_w =.true. to turn on vertical motion tranport during sedimentation
1110 ! .false. by default)
1111 ! -----------------------------------------------------------------------
1112
1113 if (do_sedi_w) then
1114 w1(ktop) = (dm(ktop) * w1(ktop) + m1_rain(ktop) * vtr(ktop)) / (dm(ktop) - m1_rain(ktop))
1115 do k = ktop + 1, kbot
1116 w1(k) = (dm(k) * w1(k) - m1_rain(k - 1) * vtr(k - 1) + m1_rain(k) * vtr(k)) &
1117 / (dm(k) + m1_rain(k - 1) - m1_rain(k))
1118 enddo
1119 endif
1120
1121 ! -----------------------------------------------------------------------
1123 ! -----------------------------------------------------------------------
1124
1125 if (do_sedi_heat) &
1126 call sedi_heat (ktop, kbot, dp, m1_rain, dz, tz, qv, ql, qr, qi, qs, qg, c_liq)
1127
1128 ! -----------------------------------------------------------------------
1131 ! -----------------------------------------------------------------------
1132
1133 call revap_racc (ktop, kbot, dt5, tz, qv, ql, qr, qi, qs, qg, den, denfac, rh_rain, h_var)
1134
1135 endif
1136
1137 ! -----------------------------------------------------------------------
1141 ! -----------------------------------------------------------------------
1142
1143 if (irain_f /= 0) then
1144
1145 ! -----------------------------------------------------------------------
1146 ! no subgrid varaibility
1147 ! -----------------------------------------------------------------------
1148
1149 do k = ktop, kbot
1150 qc0 = fac_rc * ccn(k)
1151 if (tz(k) > t_wfr) then
1152 if (use_ccn) then
1153 ! -----------------------------------------------------------------------
1154 ! ccn is formulted as ccn = ccn_surface * (den / den_surface)
1155 ! -----------------------------------------------------------------------
1156 qc = qc0
1157 else
1158 qc = qc0 / den(k)
1159 endif
1160 dq = ql(k) - qc
1161 if (dq > 0.) then
1162 sink = min(dq, dt * c_praut(k) * den(k) * exp(so3 * log(ql(k))))
1163 ql(k) = ql(k) - sink
1164 qr(k) = qr(k) + sink
1165 endif
1166 endif
1167 enddo
1168
1169 else
1170
1171 ! -----------------------------------------------------------------------
1173 ! -----------------------------------------------------------------------
1174
1175 call linear_prof (kbot - ktop + 1, ql(ktop), dl(ktop), z_slope_liq, h_var)
1176
1177 do k = ktop, kbot
1178 qc0 = fac_rc * ccn(k)
1179 if (tz(k) > t_wfr + dt_fr) then
1180 dl(k) = min(max(1.e-6, dl(k)), 0.5 * ql(k))
1181 ! --------------------------------------------------------------------
1182 ! as in klein's gfdl am2 stratiform scheme (with subgrid variations)
1183 ! --------------------------------------------------------------------
1184 if (use_ccn) then
1185 ! --------------------------------------------------------------------
1186 ! ccn is formulted as ccn = ccn_surface * (den / den_surface)
1187 ! --------------------------------------------------------------------
1188 qc = qc0
1189 else
1190 qc = qc0 / den(k)
1191 endif
1192 dq = 0.5 * (ql(k) + dl(k) - qc)
1193 ! --------------------------------------------------------------------
1194 ! dq = dl if qc == q_minus = ql - dl
1195 ! dq = 0 if qc == q_plus = ql + dl
1196 ! --------------------------------------------------------------------
1197 if (dq > 0.) then ! q_plus > qc
1198 ! --------------------------------------------------------------------
1200 ! --------------------------------------------------------------------
1201 sink = min(1., dq / dl(k)) * dt * c_praut(k) * den(k) * exp(so3 * log(ql(k)))
1202 ql(k) = ql(k) - sink
1203 qr(k) = qr(k) + sink
1204 endif
1205 endif
1206 enddo
1207 endif
1208
1209end subroutine warm_rain
1210
1211! -----------------------------------------------------------------------
1215subroutine revap_racc (ktop, kbot, dt, tz, qv, ql, qr, qi, qs, qg, den, denfac, rh_rain, h_var)
1216
1217 implicit none
1218
1219 integer, intent (in) :: ktop, kbot
1220
1221 real, intent (in) :: dt ! time step (s)
1222 real, intent (in) :: rh_rain, h_var
1223
1224 real, intent (in), dimension (ktop:kbot) :: den, denfac
1225
1226 real, intent (inout), dimension (ktop:kbot) :: tz, qv, qr, ql, qi, qs, qg
1227
1228 real, dimension (ktop:kbot) :: lhl, cvm, q_liq, q_sol, lcpk
1229
1230 real :: dqv, qsat, dqsdt, evap, t2, qden, q_plus, q_minus, sink
1231 real :: qpz, dq, dqh, tin
1232
1233 integer :: k
1234
1235 do k = ktop, kbot
1236
1237 if (tz(k) > t_wfr .and. qr(k) > qrmin) then
1238
1239 ! -----------------------------------------------------------------------
1241 ! -----------------------------------------------------------------------
1242
1243 lhl(k) = lv00 + d0_vap * tz(k)
1244 q_liq(k) = ql(k) + qr(k)
1245 q_sol(k) = qi(k) + qs(k) + qg(k)
1246 cvm(k) = c_air + qv(k) * c_vap + q_liq(k) * c_liq + q_sol(k) * c_ice
1247 lcpk(k) = lhl(k) / cvm(k)
1248
1249 tin = tz(k) - lcpk(k) * ql(k) ! presence of clouds suppresses the rain evap
1250 qpz = qv(k) + ql(k)
1251 qsat = wqs2(tin, den(k), dqsdt)
1252 dqh = max(ql(k), h_var * max(qpz, qcmin))
1253 dqh = min(dqh, 0.2 * qpz) ! new limiter
1254 dqv = qsat - qv(k) ! use this to prevent super - sat the gird box
1255 q_minus = qpz - dqh
1256 q_plus = qpz + dqh
1257
1258 ! -----------------------------------------------------------------------
1261 ! -----------------------------------------------------------------------
1262
1263 ! -----------------------------------------------------------------------
1265 ! -----------------------------------------------------------------------
1266
1267 if (dqv > qvmin .and. qsat > q_minus) then
1268 if (qsat > q_plus) then
1269 dq = qsat - qpz
1270 else
1271 ! -----------------------------------------------------------------------
1272 ! q_minus < qsat < q_plus
1273 ! dq == dqh if qsat == q_minus
1274 ! -----------------------------------------------------------------------
1275 dq = 0.25 * (q_minus - qsat) ** 2 / dqh
1276 endif
1277 qden = qr(k) * den(k)
1278 t2 = tin * tin
1279 evap = crevp(1) * t2 * dq * (crevp(2) * sqrt(qden) + crevp(3) * &
1280 exp(0.725 * log(qden))) / (crevp(4) * t2 + crevp(5) * qsat * den(k))
1281 evap = min(qr(k), dt * evap, dqv / (1. + lcpk(k) * dqsdt))
1282 ! -----------------------------------------------------------------------
1283 ! alternative minimum evap in dry environmental air
1284 ! sink = min (qr (k), dim (rh_rain * qsat, qv (k)) / (1. + lcpk (k) * dqsdt))
1285 ! evap = max (evap, sink)
1286 ! -----------------------------------------------------------------------
1287 qr(k) = qr(k) - evap
1288 qv(k) = qv(k) + evap
1289 q_liq(k) = q_liq(k) - evap
1290 cvm(k) = c_air + qv(k) * c_vap + q_liq(k) * c_liq + q_sol(k) * c_ice
1291 tz(k) = tz(k) - evap * lhl(k) / cvm(k)
1292 endif
1293
1294 ! -----------------------------------------------------------------------
1296 ! -----------------------------------------------------------------------
1297
1298 ! if (qr (k) > qrmin .and. ql (k) > 1.e-7 .and. qsat < q_plus) then
1299 if (qr(k) > qrmin .and. ql(k) > 1.e-6 .and. qsat < q_minus) then
1300 sink = dt * denfac(k) * cracw * exp(0.95 * log(qr(k) * den(k)))
1301 sink = sink / (1. + sink) * ql(k)
1302 ql(k) = ql(k) - sink
1303 qr(k) = qr(k) + sink
1304 endif
1305
1306 endif ! warm - rain
1307 enddo
1308
1309end subroutine revap_racc
1310
1311! -----------------------------------------------------------------------
1315! qi -- > ql & ql -- > qr
1316! edges: qe == qbar + / - dm
1318subroutine linear_prof (km, q, dm, z_var, h_var)
1319
1320 implicit none
1321
1322 integer, intent (in) :: km
1323
1324 real, intent (in) :: q (km), h_var
1325
1326 real, intent (out) :: dm (km)
1327
1328 logical, intent (in) :: z_var
1329
1330 real :: dq (km)
1331
1332 integer :: k
1333
1334 if (z_var) then
1335 do k = 2, km
1336 dq(k) = 0.5 * (q(k) - q(k - 1))
1337 enddo
1338 dm(1) = 0.
1339
1340 ! -----------------------------------------------------------------------
1343 ! -----------------------------------------------------------------------
1344
1345 do k = 2, km - 1
1346 dm(k) = 0.5 * min(abs(dq(k) + dq(k + 1)), 0.5 * q(k))
1347 if (dq(k) * dq(k + 1) <= 0.) then
1348 if (dq(k) > 0.) then ! local max
1349 dm(k) = min(dm(k), dq(k), - dq(k + 1))
1350 else
1351 dm(k) = 0.
1352 endif
1353 endif
1354 enddo
1355 dm(km) = 0.
1356
1357 ! -----------------------------------------------------------------------
1360 ! -----------------------------------------------------------------------
1361
1362 do k = 1, km
1363 dm(k) = max(dm(k), qvmin, h_var * q(k))
1364 enddo
1365 else
1366 do k = 1, km
1367 dm(k) = max(qvmin, h_var * q(k))
1368 enddo
1369 endif
1370
1371end subroutine linear_prof
1372
1373! =======================================================================
1383subroutine icloud (ktop, kbot, tzk, p1, qvk, qlk, qrk, qik, qsk, qgk, dp1, &
1384 den, denfac, vts, vtg, vtr, qak, rh_adj, rh_rain, dts, h_var)
1385
1386 implicit none
1387
1388 integer, intent (in) :: ktop, kbot
1389
1390 real, intent (in), dimension (ktop:kbot) :: p1, dp1, den, denfac, vts, vtg, vtr
1391
1392 real, intent (inout), dimension (ktop:kbot) :: tzk, qvk, qlk, qrk, qik, qsk, qgk, qak
1393
1394 real, intent (in) :: rh_adj, rh_rain, dts, h_var
1395
1396 real, dimension (ktop:kbot) :: lcpk, icpk, tcpk, di, lhl, lhi
1397 real, dimension (ktop:kbot) :: cvm, q_liq, q_sol
1398
1399 real :: rdts, fac_g2v, fac_v2g, fac_i2s, fac_imlt
1400 real :: tz, qv, ql, qr, qi, qs, qg, melt
1401 real :: pracs, psacw, pgacw, psacr, pgacr, pgaci, praci, psaci
1402 real :: pgmlt, psmlt, pgfr, pgaut, psaut, pgsub
1403 real :: tc, tsq, dqs0, qden, qim, qsm
1404 real :: dt5, factor, sink, qi_crt
1405 real :: tmp, qsw, qsi, dqsdt, dq
1406 real :: dtmp, qc, q_plus, q_minus
1407
1408 integer :: k
1409
1410 dt5 = 0.5 * dts
1411
1412 rdts = 1. / dts
1413
1414 ! -----------------------------------------------------------------------
1416 ! -----------------------------------------------------------------------
1417
1418 fac_i2s = 1. - exp(- dts / tau_i2s)
1419 fac_g2v = 1. - exp(- dts / tau_g2v)
1420 fac_v2g = 1. - exp(- dts / tau_v2g)
1421
1422 fac_imlt = 1. - exp(- dt5 / tau_imlt)
1423
1424 ! -----------------------------------------------------------------------
1426 ! -----------------------------------------------------------------------
1427
1428 do k = ktop, kbot
1429 lhi(k) = li00 + dc_ice * tzk(k)
1430 q_liq(k) = qlk(k) + qrk(k)
1431 q_sol(k) = qik(k) + qsk(k) + qgk(k)
1432 cvm(k) = c_air + qvk(k) * c_vap + q_liq(k) * c_liq + q_sol(k) * c_ice
1433 icpk(k) = lhi(k) / cvm(k)
1434 enddo
1435
1436 ! -----------------------------------------------------------------------
1437 ! sources of cloud ice: pihom, cold rain, and the sat_adj
1438 ! (initiation plus deposition)
1439 ! sources of snow: cold rain, auto conversion + accretion (from cloud ice)
1440 ! sat_adj (deposition; requires pre - existing snow) ; initial snow comes from auto conversion
1441 ! -----------------------------------------------------------------------
1442
1443 do k = ktop, kbot
1444 if (tzk(k) > tice .and. qik(k) > qcmin) then
1445
1446 ! -----------------------------------------------------------------------
1448 ! -----------------------------------------------------------------------
1449
1450 melt = min(qik(k), fac_imlt * (tzk(k) - tice) / icpk(k))
1451 tmp = min(melt, dim(ql_mlt, qlk(k))) ! max ql amount
1452 qlk(k) = qlk(k) + tmp
1453 qrk(k) = qrk(k) + melt - tmp
1454 qik(k) = qik(k) - melt
1455 q_liq(k) = q_liq(k) + melt
1456 q_sol(k) = q_sol(k) - melt
1457 cvm(k) = c_air + qvk(k) * c_vap + q_liq(k) * c_liq + q_sol(k) * c_ice
1458 tzk(k) = tzk(k) - melt * lhi(k) / cvm(k)
1459
1460 elseif (tzk(k) < t_wfr .and. qlk(k) > qcmin) then
1461
1462 ! -----------------------------------------------------------------------
1465 ! -----------------------------------------------------------------------
1466
1467 dtmp = t_wfr - tzk(k)
1468 factor = min(1., dtmp / dt_fr)
1469 sink = min(qlk(k) * factor, dtmp / icpk(k))
1470 qi_crt = qi_gen * min(qi_lim, 0.1 * (tice - tzk(k))) / den(k)
1471 tmp = min(sink, dim(qi_crt, qik(k)))
1472 qlk(k) = qlk(k) - sink
1473 qsk(k) = qsk(k) + sink - tmp
1474 qik(k) = qik(k) + tmp
1475 q_liq(k) = q_liq(k) - sink
1476 q_sol(k) = q_sol(k) + sink
1477 cvm(k) = c_air + qvk(k) * c_vap + q_liq(k) * c_liq + q_sol(k) * c_ice
1478 tzk(k) = tzk(k) + sink * lhi(k) / cvm(k)
1479
1480 endif
1481 enddo
1482
1483 ! -----------------------------------------------------------------------
1485 ! -----------------------------------------------------------------------
1486
1487 call linear_prof (kbot - ktop + 1, qik(ktop), di(ktop), z_slope_ice, h_var)
1488
1489 ! -----------------------------------------------------------------------
1491 ! -----------------------------------------------------------------------
1492
1493 do k = ktop, kbot
1494 lhl(k) = lv00 + d0_vap * tzk(k)
1495 lhi(k) = li00 + dc_ice * tzk(k)
1496 lcpk(k) = lhl(k) / cvm(k)
1497 icpk(k) = lhi(k) / cvm(k)
1498 tcpk(k) = lcpk(k) + icpk(k)
1499 enddo
1500
1501 do k = ktop, kbot
1502
1503 ! -----------------------------------------------------------------------
1504 ! do nothing above p_min
1505 ! -----------------------------------------------------------------------
1506
1507 if (p1(k) < p_min) cycle
1508
1509 tz = tzk(k)
1510 qv = qvk(k)
1511 ql = qlk(k)
1512 qi = qik(k)
1513 qr = qrk(k)
1514 qs = qsk(k)
1515 qg = qgk(k)
1516
1517 pgacr = 0.
1518 pgacw = 0.
1519 tc = tz - tice
1520
1521 if (tc .ge. 0.) then
1522
1523 ! -----------------------------------------------------------------------
1525 ! -----------------------------------------------------------------------
1526
1527 dqs0 = ces0 / p1(k) - qv
1528
1529 if (qs > qcmin) then
1530
1531 ! -----------------------------------------------------------------------
1533 ! only rate is used (for snow melt) since tc > 0.
1534 ! -----------------------------------------------------------------------
1535
1536 if (ql > qrmin) then
1537 factor = denfac(k) * csacw * exp(0.8125 * log(qs * den(k)))
1538 psacw = factor / (1. + dts * factor) * ql ! rate
1539 else
1540 psacw = 0.
1541 endif
1542
1543 ! -----------------------------------------------------------------------
1546 ! -----------------------------------------------------------------------
1547
1548 if (qr > qrmin) then
1549 psacr = min(acr3d(vts(k), vtr(k), qr, qs, csacr, acco(1, 2), &
1550 den(k)), qr * rdts)
1551 pracs = acr3d(vtr(k), vts(k), qs, qr, cracs, acco(1, 1), den(k))
1552 else
1553 psacr = 0.
1554 pracs = 0.
1555 endif
1556
1557 ! -----------------------------------------------------------------------
1560 ! -----------------------------------------------------------------------
1561
1562 psmlt = max(0., smlt(tc, dqs0, qs * den(k), psacw, psacr, csmlt, &
1563 den(k), denfac(k)))
1564 sink = min(qs, dts * (psmlt + pracs), tc / icpk(k))
1565 qs = qs - sink
1566 ! sjl, 20170321:
1567 tmp = min(sink, dim(qs_mlt, ql)) ! max ql due to snow melt
1568 ql = ql + tmp
1569 qr = qr + sink - tmp
1570 ! qr = qr + sink
1571 ! sjl, 20170321:
1572 q_liq(k) = q_liq(k) + sink
1573 q_sol(k) = q_sol(k) - sink
1574 cvm(k) = c_air + qv * c_vap + q_liq(k) * c_liq + q_sol(k) * c_ice
1575 tz = tz - sink * lhi(k) / cvm(k)
1576 tc = tz - tice
1577
1578 endif
1579
1580 ! -----------------------------------------------------------------------
1582 ! -----------------------------------------------------------------------
1583
1584 lhi(k) = li00 + dc_ice * tz
1585 icpk(k) = lhi(k) / cvm(k)
1586
1587 ! -----------------------------------------------------------------------
1589 ! -----------------------------------------------------------------------
1590
1591 if (qg > qcmin .and. tc > 0.) then
1592
1593 ! -----------------------------------------------------------------------
1595 ! -----------------------------------------------------------------------
1596
1597 if (qr > qrmin) &
1598 pgacr = min(acr3d(vtg(k), vtr(k), qr, qg, cgacr, acco(1, 3), &
1599 den(k)), rdts * qr)
1600
1601 ! -----------------------------------------------------------------------
1603 ! -----------------------------------------------------------------------
1604
1605 qden = qg * den(k)
1606 if (ql > qrmin) then
1607 factor = cgacw * qden / sqrt(den(k) * sqrt(sqrt(qden)))
1608 pgacw = factor / (1. + dts * factor) * ql ! rate
1609 endif
1610
1611 ! -----------------------------------------------------------------------
1613 ! -----------------------------------------------------------------------
1614
1615 pgmlt = dts * gmlt(tc, dqs0, qden, pgacw, pgacr, cgmlt, den(k))
1616 pgmlt = min(max(0., pgmlt), qg, tc / icpk(k))
1617 qg = qg - pgmlt
1618 qr = qr + pgmlt
1619 q_liq(k) = q_liq(k) + pgmlt
1620 q_sol(k) = q_sol(k) - pgmlt
1621 cvm(k) = c_air + qv * c_vap + q_liq(k) * c_liq + q_sol(k) * c_ice
1622 tz = tz - pgmlt * lhi(k) / cvm(k)
1623
1624 endif
1625
1626 else
1627
1628 ! -----------------------------------------------------------------------
1630 ! -----------------------------------------------------------------------
1631
1632 ! -----------------------------------------------------------------------
1634 ! -----------------------------------------------------------------------
1635
1636 if (qi > 3.e-7) then ! cloud ice sink terms
1637
1638 if (qs > 1.e-7) then
1639 ! -----------------------------------------------------------------------
1640 ! sjl added (following lin eq. 23) the temperature dependency
1641 ! to reduce accretion, use esi = exp (0.05 * tc) as in hong et al 2004
1642 ! -----------------------------------------------------------------------
1643 factor = dts * denfac(k) * csaci * exp(0.05 * tc + 0.8125 * log(qs * den(k)))
1644 psaci = factor / (1. + factor) * qi
1645 else
1646 psaci = 0.
1647 endif
1648
1649 ! -----------------------------------------------------------------------
1654 ! -----------------------------------------------------------------------
1655 if (qi0_crt < 0.) then
1656 qim = - qi0_crt
1657 else
1658 qim = qi0_crt / den(k)
1659 endif
1660 ! -----------------------------------------------------------------------
1661 ! assuming linear subgrid vertical distribution of cloud ice
1662 ! the mismatch computation following lin et al. 1994, mwr
1663 ! -----------------------------------------------------------------------
1664
1665 if (const_vi) then
1666 tmp = fac_i2s
1667 else
1668 tmp = fac_i2s * exp(0.025 * tc)
1669 endif
1670
1671 di(k) = max(di(k), qrmin)
1672 q_plus = qi + di(k)
1673 if (q_plus > (qim + qrmin)) then
1674 if (qim > (qi - di(k))) then
1675 dq = (0.25 * (q_plus - qim) ** 2) / di(k)
1676 else
1677 dq = qi - qim
1678 endif
1679 psaut = tmp * dq
1680 else
1681 psaut = 0.
1682 endif
1683 ! -----------------------------------------------------------------------
1684 ! sink is no greater than 75% of qi
1685 ! -----------------------------------------------------------------------
1686 sink = min(0.75 * qi, psaci + psaut)
1687 qi = qi - sink
1688 qs = qs + sink
1689
1690 ! -----------------------------------------------------------------------
1692 ! -----------------------------------------------------------------------
1693
1694 if (qg > 1.e-6) then
1695 ! -----------------------------------------------------------------------
1696 ! factor = dts * cgaci / sqrt (den (k)) * exp (0.05 * tc + 0.875 * log (qg * den (k)))
1697 ! simplified form: remove temp dependency & set the exponent "0.875" -- > 1
1698 ! -----------------------------------------------------------------------
1699 factor = dts * cgaci * sqrt(den(k)) * qg
1700 pgaci = factor / (1. + factor) * qi
1701 qi = qi - pgaci
1702 qg = qg + pgaci
1703 endif
1704
1705 endif
1706
1707 ! -----------------------------------------------------------------------
1709 ! -----------------------------------------------------------------------
1710
1711 ! -----------------------------------------------------------------------
1712 ! rain to ice, snow, graupel processes:
1713 ! -----------------------------------------------------------------------
1714
1715 tc = tz - tice
1716
1717 if (qr > 1.e-7 .and. tc < 0.) then
1718
1719 ! -----------------------------------------------------------------------
1720 ! * sink * terms to qr: psacr + pgfr
1721 ! source terms to qs: psacr
1722 ! source terms to qg: pgfr
1723 ! -----------------------------------------------------------------------
1724
1725 ! -----------------------------------------------------------------------
1727 ! -----------------------------------------------------------------------
1728
1729 if (qs > 1.e-7) then ! if snow exists
1730 psacr = dts * acr3d(vts(k), vtr(k), qr, qs, csacr, acco(1, 2), den(k))
1731 else
1732 psacr = 0.
1733 endif
1734
1735 ! -----------------------------------------------------------------------
1737 ! -----------------------------------------------------------------------
1738
1739 pgfr = dts * cgfr(1) / den(k) * (exp(- cgfr(2) * tc) - 1.) * &
1740 exp(1.75 * log(qr * den(k)))
1741
1742 ! -----------------------------------------------------------------------
1747 ! -----------------------------------------------------------------------
1748
1749 sink = psacr + pgfr
1750 factor = min(sink, qr, - tc / icpk(k)) / max(sink, qrmin)
1751
1752 psacr = factor * psacr
1753 pgfr = factor * pgfr
1754
1755 sink = psacr + pgfr
1756 qr = qr - sink
1757 qs = qs + psacr
1758 qg = qg + pgfr
1759 q_liq(k) = q_liq(k) - sink
1760 q_sol(k) = q_sol(k) + sink
1761 cvm(k) = c_air + qv * c_vap + q_liq(k) * c_liq + q_sol(k) * c_ice
1762 tz = tz + sink * lhi(k) / cvm(k)
1763
1764 endif
1765
1766 ! -----------------------------------------------------------------------
1768 ! -----------------------------------------------------------------------
1769
1770 lhi(k) = li00 + dc_ice * tz
1771 icpk(k) = lhi(k) / cvm(k)
1772
1773 ! -----------------------------------------------------------------------
1775 ! -----------------------------------------------------------------------
1776
1777 if (qs > 1.e-7) then
1778
1779 ! -----------------------------------------------------------------------
1781 ! -----------------------------------------------------------------------
1782
1783 if (qg > qrmin) then
1784 sink = dts * acr3d(vtg(k), vts(k), qs, qg, cgacs, acco(1, 4), den(k))
1785 else
1786 sink = 0.
1787 endif
1788
1789 ! -----------------------------------------------------------------------
1791 ! -----------------------------------------------------------------------
1792
1793 qsm = qs0_crt / den(k)
1794 if (qs > qsm) then
1795 factor = dts * 1.e-3 * exp(0.09 * (tz - tice))
1796 sink = sink + factor / (1. + factor) * (qs - qsm)
1797 endif
1798 sink = min(qs, sink)
1799 qs = qs - sink
1800 qg = qg + sink
1801
1802 endif ! snow existed
1803
1804 if (qg > 1.e-7 .and. tz < tice0) then
1805
1806 ! -----------------------------------------------------------------------
1808 ! -----------------------------------------------------------------------
1809
1810 if (ql > 1.e-6) then
1811 qden = qg * den(k)
1812 factor = dts * cgacw * qden / sqrt(den(k) * sqrt(sqrt(qden)))
1813 pgacw = factor / (1. + factor) * ql
1814 else
1815 pgacw = 0.
1816 endif
1817
1818 ! -----------------------------------------------------------------------
1820 ! -----------------------------------------------------------------------
1821
1822 if (qr > 1.e-6) then
1823 pgacr = min(dts * acr3d(vtg(k), vtr(k), qr, qg, cgacr, acco(1, 3), &
1824 den(k)), qr)
1825 else
1826 pgacr = 0.
1827 endif
1828
1829 sink = pgacr + pgacw
1830 factor = min(sink, dim(tice, tz) / icpk(k)) / max(sink, qrmin)
1831 pgacr = factor * pgacr
1832 pgacw = factor * pgacw
1833
1834 sink = pgacr + pgacw
1835 qg = qg + sink
1836 qr = qr - pgacr
1837 ql = ql - pgacw
1838 q_liq(k) = q_liq(k) - sink
1839 q_sol(k) = q_sol(k) + sink
1840 cvm(k) = c_air + qv * c_vap + q_liq(k) * c_liq + q_sol(k) * c_ice
1841 tz = tz + sink * lhi(k) / cvm(k)
1842
1843 endif
1844
1845 endif
1846
1847 tzk(k) = tz
1848 qvk(k) = qv
1849 qlk(k) = ql
1850 qik(k) = qi
1851 qrk(k) = qr
1852 qsk(k) = qs
1853 qgk(k) = qg
1854
1855 enddo
1856
1857 ! -----------------------------------------------------------------------
1859 ! -----------------------------------------------------------------------
1860
1861 call subgrid_z_proc (ktop, kbot, p1, den, denfac, dts, rh_adj, tzk, qvk, &
1862 qlk, qrk, qik, qsk, qgk, qak, h_var, rh_rain)
1863
1864end subroutine icloud
1865
1866! =======================================================================
1870subroutine subgrid_z_proc (ktop, kbot, p1, den, denfac, dts, rh_adj, tz, qv, &
1871 ql, qr, qi, qs, qg, qa, h_var, rh_rain)
1872
1873 implicit none
1874
1875 integer, intent (in) :: ktop, kbot
1876
1877 real, intent (in), dimension (ktop:kbot) :: p1, den, denfac
1878
1879 real, intent (in) :: dts, rh_adj, h_var, rh_rain
1880
1881 real, intent (inout), dimension (ktop:kbot) :: tz, qv, ql, qr, qi, qs, qg, qa
1882
1883 real, dimension (ktop:kbot) :: lcpk, icpk, tcpk, tcp3, lhl, lhi
1884 real, dimension (ktop:kbot) :: cvm, q_liq, q_sol, q_cond
1885
1886 real :: fac_v2l, fac_l2v
1887
1888 real :: pidep, qi_crt
1889
1890 ! -----------------------------------------------------------------------
1891 ! qstar over water may be accurate only down to - 80 deg c with ~10% uncertainty
1892 ! must not be too large to allow psc
1893 ! -----------------------------------------------------------------------
1894
1895 real :: rh, rqi, tin, qsw, qsi, qpz, qstar
1896 real :: dqsdt, dwsdt, dq, dq0, factor, tmp
1897 real :: q_plus, q_minus, dt_evap, dt_pisub
1898 real :: evap, sink, tc, pisub, q_adj, dtmp
1899 real :: pssub, pgsub, tsq, qden, fac_g2v, fac_v2g
1900
1901 integer :: k
1902
1903 if (fast_sat_adj) then
1904 dt_evap = 0.5 * dts
1905 else
1906 dt_evap = dts
1907 endif
1908
1909 ! -----------------------------------------------------------------------
1911 ! -----------------------------------------------------------------------
1912
1913 fac_v2l = 1. - exp(- dt_evap / tau_v2l)
1914 fac_l2v = 1. - exp(- dt_evap / tau_l2v)
1915
1916 fac_g2v = 1. - exp(- dts / tau_g2v)
1917 fac_v2g = 1. - exp(- dts / tau_v2g)
1918
1919 ! -----------------------------------------------------------------------
1921 ! -----------------------------------------------------------------------
1922
1923 do k = ktop, kbot
1924 lhl(k) = lv00 + d0_vap * tz(k)
1925 lhi(k) = li00 + dc_ice * tz(k)
1926 q_liq(k) = ql(k) + qr(k)
1927 q_sol(k) = qi(k) + qs(k) + qg(k)
1928 cvm(k) = c_air + qv(k) * c_vap + q_liq(k) * c_liq + q_sol(k) * c_ice
1929 lcpk(k) = lhl(k) / cvm(k)
1930 icpk(k) = lhi(k) / cvm(k)
1931 tcpk(k) = lcpk(k) + icpk(k)
1932 tcp3(k) = lcpk(k) + icpk(k) * min(1., dim(tice, tz(k)) / (tice - t_wfr))
1933 enddo
1934
1935 do k = ktop, kbot
1936
1937 if (p1(k) < p_min) cycle
1938
1939 ! -----------------------------------------------------------------------
1941 ! -----------------------------------------------------------------------
1942
1943 if (tz(k) < t_min) then
1944 sink = dim(qv(k), 1.e-7)
1945 qv(k) = qv(k) - sink
1946 qi(k) = qi(k) + sink
1947 q_sol(k) = q_sol(k) + sink
1948 cvm(k) = c_air + qv(k) * c_vap + q_liq(k) * c_liq + q_sol(k) * c_ice
1949 tz(k) = tz(k) + sink * (lhl(k) + lhi(k)) / cvm(k)
1950 if (.not. do_qa) qa(k) = qa(k) + 1. ! air fully saturated; 100 % cloud cover
1951 cycle
1952 endif
1953
1954 ! -----------------------------------------------------------------------
1956 ! -----------------------------------------------------------------------
1957
1958 lhl(k) = lv00 + d0_vap * tz(k)
1959 lhi(k) = li00 + dc_ice * tz(k)
1960 lcpk(k) = lhl(k) / cvm(k)
1961 icpk(k) = lhi(k) / cvm(k)
1962 tcpk(k) = lcpk(k) + icpk(k)
1963 tcp3(k) = lcpk(k) + icpk(k) * min(1., dim(tice, tz(k)) / (tice - t_wfr))
1964
1965 ! -----------------------------------------------------------------------
1967 ! -----------------------------------------------------------------------
1968
1969 qpz = qv(k) + ql(k) + qi(k)
1970 tin = tz(k) - (lhl(k) * (ql(k) + qi(k)) + lhi(k) * qi(k)) / (c_air + &
1971 qpz * c_vap + qr(k) * c_liq + (qs(k) + qg(k)) * c_ice)
1972 if (tin > t_sub + 6.) then
1973 rh = qpz / iqs1(tin, den(k))
1974 if (rh < rh_adj) then ! qpz / rh_adj < qs
1975 tz(k) = tin
1976 qv(k) = qpz
1977 ql(k) = 0.
1978 qi(k) = 0.
1979 cycle ! cloud free
1980 endif
1981 endif
1982
1983 ! -----------------------------------------------------------------------
1985 ! -----------------------------------------------------------------------
1986
1987 qsw = wqs2(tz(k), den(k), dwsdt)
1988 dq0 = qsw - qv(k)
1989 if (dq0 > 0.) then
1990 ! SJL 20170703 added ql factor to prevent the situation of high ql and low RH
1991 ! factor = min (1., fac_l2v * sqrt (max (0., ql (k)) / 1.e-5) * 10. * dq0 / qsw)
1992 ! factor = fac_l2v
1993 ! factor = 1
1994 factor = min(1., fac_l2v * (10. * dq0 / qsw)) ! the rh dependent factor = 1 at 90%
1995 evap = min(ql(k), factor * dq0 / (1. + tcp3(k) * dwsdt))
1996 else ! condensate all excess vapor into cloud water
1997 ! -----------------------------------------------------------------------
1998 ! evap = fac_v2l * dq0 / (1. + tcp3 (k) * dwsdt)
1999 ! sjl, 20161108
2000 ! -----------------------------------------------------------------------
2001 evap = dq0 / (1. + tcp3(k) * dwsdt)
2002 endif
2003 qv(k) = qv(k) + evap
2004 ql(k) = ql(k) - evap
2005 q_liq(k) = q_liq(k) - evap
2006 cvm(k) = c_air + qv(k) * c_vap + q_liq(k) * c_liq + q_sol(k) * c_ice
2007 tz(k) = tz(k) - evap * lhl(k) / cvm(k)
2008
2009 ! -----------------------------------------------------------------------
2011 ! -----------------------------------------------------------------------
2012
2013 lhi(k) = li00 + dc_ice * tz(k)
2014 icpk(k) = lhi(k) / cvm(k)
2015
2016 ! -----------------------------------------------------------------------
2018 ! -----------------------------------------------------------------------
2019
2020 dtmp = t_wfr - tz(k) ! [ - 40, - 48]
2021 if (dtmp > 0. .and. ql(k) > qcmin) then
2022 sink = min(ql(k), ql(k) * dtmp * 0.125, dtmp / icpk(k))
2023 ql(k) = ql(k) - sink
2024 qi(k) = qi(k) + sink
2025 q_liq(k) = q_liq(k) - sink
2026 q_sol(k) = q_sol(k) + sink
2027 cvm(k) = c_air + qv(k) * c_vap + q_liq(k) * c_liq + q_sol(k) * c_ice
2028 tz(k) = tz(k) + sink * lhi(k) / cvm(k)
2029 endif
2030
2031 ! -----------------------------------------------------------------------
2033 ! -----------------------------------------------------------------------
2034
2035 lhi(k) = li00 + dc_ice * tz(k)
2036 icpk(k) = lhi(k) / cvm(k)
2037
2038 ! -----------------------------------------------------------------------
2040 ! -----------------------------------------------------------------------
2041
2042 if (fast_sat_adj) then
2043 dt_pisub = 0.5 * dts
2044 else
2045 dt_pisub = dts
2046 tc = tice - tz(k)
2047 if (ql(k) > qrmin .and. tc > 0.) then
2048 sink = 3.3333e-10 * dts * (exp(0.66 * tc) - 1.) * den(k) * ql(k) * ql(k)
2049 sink = min(ql(k), tc / icpk(k), sink)
2050 ql(k) = ql(k) - sink
2051 qi(k) = qi(k) + sink
2052 q_liq(k) = q_liq(k) - sink
2053 q_sol(k) = q_sol(k) + sink
2054 cvm(k) = c_air + qv(k) * c_vap + q_liq(k) * c_liq + q_sol(k) * c_ice
2055 tz(k) = tz(k) + sink * lhi(k) / cvm(k)
2056 endif ! significant ql existed
2057 endif
2058
2059 ! -----------------------------------------------------------------------
2061 ! -----------------------------------------------------------------------
2062
2063 lhl(k) = lv00 + d0_vap * tz(k)
2064 lhi(k) = li00 + dc_ice * tz(k)
2065 lcpk(k) = lhl(k) / cvm(k)
2066 icpk(k) = lhi(k) / cvm(k)
2067 tcpk(k) = lcpk(k) + icpk(k)
2068
2069 ! -----------------------------------------------------------------------
2071 ! -----------------------------------------------------------------------
2072
2073 if (tz(k) < tice) then
2074 qsi = iqs2(tz(k), den(k), dqsdt)
2075 dq = qv(k) - qsi
2076 sink = dq / (1. + tcpk(k) * dqsdt)
2077 if (qi(k) > qrmin) then
2078 ! eq 9, hong et al. 2004, mwr
2079 ! for a and b, see dudhia 1989: page 3103 eq (b7) and (b8)
2080 pidep = dt_pisub * dq * 349138.78 * exp(0.875 * log(qi(k) * den(k))) &
2081 / (qsi * den(k) * lat2 / (0.0243 * rvgas * tz(k) ** 2) + 4.42478e4)
2082 else
2083 pidep = 0.
2084 endif
2085 if (dq > 0.) then ! vapor - > ice
2086 tmp = tice - tz(k)
2087 ! 20160912: the following should produce more ice at higher altitude
2088 ! qi_crt = 4.92e-11 * exp (1.33 * log (1.e3 * exp (0.1 * tmp))) / den (k)
2089 qi_crt = qi_gen * min(qi_lim, 0.1 * tmp) / den(k)
2090 sink = min(sink, max(qi_crt - qi(k), pidep), tmp / tcpk(k))
2091 else ! ice -- > vapor
2092 pidep = pidep * min(1., dim(tz(k), t_sub) * 0.2)
2093 sink = max(pidep, sink, - qi(k))
2094 endif
2095 qv(k) = qv(k) - sink
2096 qi(k) = qi(k) + sink
2097 q_sol(k) = q_sol(k) + sink
2098 cvm(k) = c_air + qv(k) * c_vap + q_liq(k) * c_liq + q_sol(k) * c_ice
2099 tz(k) = tz(k) + sink * (lhl(k) + lhi(k)) / cvm(k)
2100 endif
2101
2102 ! -----------------------------------------------------------------------
2104 ! -----------------------------------------------------------------------
2105
2106 lhl(k) = lv00 + d0_vap * tz(k)
2107 lhi(k) = li00 + dc_ice * tz(k)
2108 lcpk(k) = lhl(k) / cvm(k)
2109 icpk(k) = lhi(k) / cvm(k)
2110 tcpk(k) = lcpk(k) + icpk(k)
2111
2112 ! -----------------------------------------------------------------------
2114 ! this process happens for all temp rage
2115 ! -----------------------------------------------------------------------
2116
2117 if (qs(k) > qrmin) then
2118 qsi = iqs2(tz(k), den(k), dqsdt)
2119 qden = qs(k) * den(k)
2120 tmp = exp(0.65625 * log(qden))
2121 tsq = tz(k) * tz(k)
2122 dq = (qsi - qv(k)) / (1. + tcpk(k) * dqsdt)
2123 pssub = cssub(1) * tsq * (cssub(2) * sqrt(qden) + cssub(3) * tmp * &
2124 sqrt(denfac(k))) / (cssub(4) * tsq + cssub(5) * qsi * den(k))
2125 pssub = (qsi - qv(k)) * dts * pssub
2126 if (pssub > 0.) then ! qs -- > qv, sublimation
2127 pssub = min(pssub * min(1., dim(tz(k), t_sub) * 0.2), qs(k))
2128 else
2129 if (tz(k) > tice) then
2130 pssub = 0. ! no deposition
2131 else
2132 pssub = max(pssub, dq, (tz(k) - tice) / tcpk(k))
2133 endif
2134 endif
2135 qs(k) = qs(k) - pssub
2136 qv(k) = qv(k) + pssub
2137 q_sol(k) = q_sol(k) - pssub
2138 cvm(k) = c_air + qv(k) * c_vap + q_liq(k) * c_liq + q_sol(k) * c_ice
2139 tz(k) = tz(k) - pssub * (lhl(k) + lhi(k)) / cvm(k)
2140 endif
2141
2142 ! -----------------------------------------------------------------------
2144 ! -----------------------------------------------------------------------
2145
2146 lhl(k) = lv00 + d0_vap * tz(k)
2147 lhi(k) = li00 + dc_ice * tz(k)
2148 lcpk(k) = lhl(k) / cvm(k)
2149 icpk(k) = lhi(k) / cvm(k)
2150 tcpk(k) = lcpk(k) + icpk(k)
2151
2152 ! -----------------------------------------------------------------------
2154 ! -----------------------------------------------------------------------
2155
2156 if (qg(k) > qrmin) then
2157 qsi = iqs2(tz(k), den(k), dqsdt)
2158 dq = (qv(k) - qsi) / (1. + tcpk(k) * dqsdt)
2159 pgsub = (qv(k) / qsi - 1.) * qg(k)
2160 if (pgsub > 0.) then ! deposition
2161 if (tz(k) > tice) then
2162 pgsub = 0. ! no deposition
2163 else
2164 pgsub = min(fac_v2g * pgsub, 0.2 * dq, ql(k) + qr(k), &
2165 (tice - tz(k)) / tcpk(k))
2166 endif
2167 else ! submilation
2168 pgsub = max(fac_g2v * pgsub, dq) * min(1., dim(tz(k), t_sub) * 0.1)
2169 endif
2170 qg(k) = qg(k) + pgsub
2171 qv(k) = qv(k) - pgsub
2172 q_sol(k) = q_sol(k) + pgsub
2173 cvm(k) = c_air + qv(k) * c_vap + q_liq(k) * c_liq + q_sol(k) * c_ice
2174 tz(k) = tz(k) + pgsub * (lhl(k) + lhi(k)) / cvm(k)
2175 endif
2176
2177#ifdef USE_MIN_EVAP
2178 ! -----------------------------------------------------------------------
2180 ! -----------------------------------------------------------------------
2181
2182 lhl(k) = lv00 + d0_vap * tz(k)
2183 lcpk(k) = lhl(k) / cvm(k)
2184
2185 ! -----------------------------------------------------------------------
2187 ! -----------------------------------------------------------------------
2188
2189 if (qr(k) > qcmin) then
2190 qsw = wqs2(tz(k), den(k), dqsdt)
2191 sink = min(qr(k), dim(rh_rain * qsw, qv(k)) / (1. + lcpk(k) * dqsdt))
2192 qv(k) = qv(k) + sink
2193 qr(k) = qr(k) - sink
2194 q_liq(k) = q_liq(k) - sink
2195 cvm(k) = c_air + qv(k) * c_vap + q_liq(k) * c_liq + q_sol(k) * c_ice
2196 tz(k) = tz(k) - sink * lhl(k) / cvm(k)
2197 endif
2198#endif
2199
2200 ! -----------------------------------------------------------------------
2202 ! -----------------------------------------------------------------------
2203
2204 lhl(k) = lv00 + d0_vap * tz(k)
2205 cvm(k) = c_air + (qv(k) + q_liq(k) + q_sol(k)) * c_vap
2206 lcpk(k) = lhl(k) / cvm(k)
2207
2208 ! -----------------------------------------------------------------------
2209 ! compute cloud fraction
2210 ! -----------------------------------------------------------------------
2211
2212 ! -----------------------------------------------------------------------
2214 ! -----------------------------------------------------------------------
2215
2216 if (do_qa) cycle
2217
2218 if (rad_snow) then
2219 q_sol(k) = qi(k) + qs(k)
2220 else
2221 q_sol(k) = qi(k)
2222 endif
2223 if (rad_rain) then
2224 q_liq(k) = ql(k) + qr(k)
2225 else
2226 q_liq(k) = ql(k)
2227 endif
2228 q_cond(k) = q_liq(k) + q_sol(k)
2229
2230 qpz = qv(k) + q_cond(k) ! qpz is conserved
2231
2232 ! -----------------------------------------------------------------------
2234 ! -----------------------------------------------------------------------
2235
2236 tin = tz(k) - (lcpk(k) * q_cond(k) + icpk(k) * q_sol(k)) ! minimum temperature
2237 ! tin = tz (k) - ((lv00 + d0_vap * tz (k)) * q_cond (k) + &
2238 ! (li00 + dc_ice * tz (k)) * q_sol (k)) / (c_air + qpz * c_vap)
2239
2240 ! -----------------------------------------------------------------------
2241 ! determine saturated specific humidity
2242 ! -----------------------------------------------------------------------
2243
2244 if (tin <= t_wfr) then
2245 ! ice phase:
2246 qstar = iqs1(tin, den(k))
2247 elseif (tin >= tice) then
2248 ! liquid phase:
2249 qstar = wqs1(tin, den(k))
2250 else
2251 ! mixed phase:
2252 qsi = iqs1(tin, den(k))
2253 qsw = wqs1(tin, den(k))
2254 if (q_cond(k) > 3.e-6) then
2255 rqi = q_sol(k) / q_cond(k)
2256 else
2257 ! -----------------------------------------------------------------------
2258 ! mostly liquid water q_cond (k) at initial cloud development stage
2259 ! -----------------------------------------------------------------------
2260 rqi = (tice - tin) / (tice - t_wfr)
2261 endif
2262 qstar = rqi * qsi + (1. - rqi) * qsw
2263 endif
2264
2265 ! -----------------------------------------------------------------------
2268 ! -----------------------------------------------------------------------
2269
2270 if (qpz > qrmin) then
2271 ! partial cloudiness by pdf:
2272 dq = max(qcmin, h_var * qpz)
2273 q_plus = qpz + dq ! cloud free if qstar > q_plus
2274 q_minus = qpz - dq
2275 if (qstar < q_minus) then
2276 qa(k) = qa(k) + 1. ! air fully saturated; 100 % cloud cover
2277 elseif (qstar < q_plus .and. q_cond(k) > qc_crt) then
2278 qa(k) = qa(k) + (q_plus - qstar) / (dq + dq) ! partial cloud cover
2279 ! qa (k) = sqrt (qa (k) + (q_plus - qstar) / (dq + dq))
2280 endif
2281 endif
2282
2283 enddo
2284
2285end subroutine subgrid_z_proc
2286
2287! =======================================================================
2290subroutine revap_rac1 (hydrostatic, is, ie, dt, tz, qv, ql, qr, qi, qs, qg, den, hvar)
2291
2292 implicit none
2293
2294 logical, intent (in) :: hydrostatic
2295
2296 integer, intent (in) :: is, ie
2297
2298 real, intent (in) :: dt ! time step (s)
2299
2300 real, intent (in), dimension (is:ie) :: den, hvar, qi, qs, qg
2301
2302 real, intent (inout), dimension (is:ie) :: tz, qv, qr, ql
2303
2304 real, dimension (is:ie) :: lcp2, denfac, q_liq, q_sol, cvm, lhl
2305
2306 real :: dqv, qsat, dqsdt, evap, qden, q_plus, q_minus, sink
2307 real :: tin, t2, qpz, dq, dqh
2308
2309 integer :: i
2310
2311 ! -----------------------------------------------------------------------
2312 ! define latend heat coefficient
2313 ! -----------------------------------------------------------------------
2314
2315 do i = is, ie
2316 lhl(i) = lv00 + d0_vap * tz(i)
2317 q_liq(i) = ql(i) + qr(i)
2318 q_sol(i) = qi(i) + qs(i) + qg(i)
2319 cvm(i) = c_air + qv(i) * c_vap + q_liq(i) * c_liq + q_sol(i) * c_ice
2320 lcp2(i) = lhl(i) / cvm(i)
2321 ! denfac (i) = sqrt (sfcrho / den (i))
2322 enddo
2323
2324 do i = is, ie
2325 if (qr(i) > qrmin .and. tz(i) > t_wfr) then
2326 qpz = qv(i) + ql(i)
2327 tin = tz(i) - lcp2(i) * ql(i) ! presence of clouds suppresses the rain evap
2328 qsat = wqs2(tin, den(i), dqsdt)
2329 dqh = max(ql(i), hvar(i) * max(qpz, qcmin))
2330 dqv = qsat - qv(i)
2331 q_minus = qpz - dqh
2332 q_plus = qpz + dqh
2333
2334 ! -----------------------------------------------------------------------
2335 ! qsat must be > q_minus to activate evaporation
2336 ! qsat must be < q_plus to activate accretion
2337 ! -----------------------------------------------------------------------
2338
2339 ! -----------------------------------------------------------------------
2340 ! rain evaporation
2341 ! -----------------------------------------------------------------------
2342
2343 if (dqv > qvmin .and. qsat > q_minus) then
2344 if (qsat > q_plus) then
2345 dq = qsat - qpz
2346 else
2347 ! q_minus < qsat < q_plus
2348 ! dq == dqh if qsat == q_minus
2349 dq = 0.25 * (q_minus - qsat) ** 2 / dqh
2350 endif
2351 qden = qr(i) * den(i)
2352 t2 = tin * tin
2353 evap = crevp(1) * t2 * dq * (crevp(2) * sqrt(qden) + crevp(3) * exp(0.725 * log(qden))) &
2354 / (crevp(4) * t2 + crevp(5) * qsat * den(i))
2355 evap = min(qr(i), dt * evap, dqv / (1. + lcp2(i) * dqsdt))
2356 qr(i) = qr(i) - evap
2357 qv(i) = qv(i) + evap
2358 q_liq(i) = q_liq(i) - evap
2359 cvm(i) = c_air + qv(i) * c_vap + q_liq(i) * c_liq + q_sol(i) * c_ice
2360 tz(i) = tz(i) - evap * lhl(i) / cvm(i)
2361 endif
2362
2363 ! -----------------------------------------------------------------------
2364 ! accretion: pracc
2365 ! -----------------------------------------------------------------------
2366
2367 if (qr(i) > qrmin .and. ql(i) > 1.e-8 .and. qsat < q_plus) then
2368 denfac(i) = sqrt(sfcrho / den(i))
2369 sink = dt * denfac(i) * cracw * exp(0.95 * log(qr(i) * den(i)))
2370 sink = sink / (1. + sink) * ql(i)
2371 ql(i) = ql(i) - sink
2372 qr(i) = qr(i) + sink
2373 endif
2374 endif
2375 enddo
2376
2377end subroutine revap_rac1
2378
2379! =======================================================================
2383subroutine terminal_fall (dtm, ktop, kbot, tz, qv, ql, qr, qg, qs, qi, dz, dp, &
2384 den, vtg, vts, vti, r1, g1, s1, i1, m1_sol, w1)
2385
2386 implicit none
2387
2388 integer, intent (in) :: ktop, kbot
2389
2390 real, intent (in) :: dtm ! time step (s)
2391
2392 real, intent (in), dimension (ktop:kbot) :: vtg, vts, vti, den, dp, dz
2393
2394 real, intent (inout), dimension (ktop:kbot) :: qv, ql, qr, qg, qs, qi, tz, m1_sol, w1
2395
2396 real, intent (out) :: r1, g1, s1, i1
2397
2398 real, dimension (ktop:kbot + 1) :: ze, zt
2399
2400 real :: qsat, dqsdt, dt5, evap, dtime
2401 real :: factor, frac
2402 real :: tmp, precip, tc, sink
2403
2404 real, dimension (ktop:kbot) :: lcpk, icpk, cvm, q_liq, q_sol, lhl, lhi
2405 real, dimension (ktop:kbot) :: m1, dm
2406
2407 real :: zs = 0.
2408 real :: fac_imlt
2409
2410 integer :: k, k0, m
2411
2412 logical :: no_fall
2413
2414 dt5 = 0.5 * dtm
2415 fac_imlt = 1. - exp(- dt5 / tau_imlt)
2416
2417 ! -----------------------------------------------------------------------
2418 ! define heat capacity and latend heat coefficient
2419 ! -----------------------------------------------------------------------
2420
2421 do k = ktop, kbot
2422 m1_sol(k) = 0.
2423 lhl(k) = lv00 + d0_vap * tz(k)
2424 lhi(k) = li00 + dc_ice * tz(k)
2425 q_liq(k) = ql(k) + qr(k)
2426 q_sol(k) = qi(k) + qs(k) + qg(k)
2427 cvm(k) = c_air + qv(k) * c_vap + q_liq(k) * c_liq + q_sol(k) * c_ice
2428 lcpk(k) = lhl(k) / cvm(k)
2429 icpk(k) = lhi(k) / cvm(k)
2430 enddo
2431
2432 ! -----------------------------------------------------------------------
2433 ! find significant melting level
2434 ! -----------------------------------------------------------------------
2435
2436 k0 = kbot
2437 do k = ktop, kbot - 1
2438 if (tz(k) > tice) then
2439 k0 = k
2440 exit
2441 endif
2442 enddo
2443
2444 ! -----------------------------------------------------------------------
2445 ! melting of cloud_ice (before fall) :
2446 ! -----------------------------------------------------------------------
2447
2448 do k = k0, kbot
2449 tc = tz(k) - tice
2450 if (qi(k) > qcmin .and. tc > 0.) then
2451 sink = min(qi(k), fac_imlt * tc / icpk(k))
2452 tmp = min(sink, dim(ql_mlt, ql(k)))
2453 ql(k) = ql(k) + tmp
2454 qr(k) = qr(k) + sink - tmp
2455 qi(k) = qi(k) - sink
2456 q_liq(k) = q_liq(k) + sink
2457 q_sol(k) = q_sol(k) - sink
2458 cvm(k) = c_air + qv(k) * c_vap + q_liq(k) * c_liq + q_sol(k) * c_ice
2459 tz(k) = tz(k) - sink * lhi(k) / cvm(k)
2460 tc = tz(k) - tice
2461 endif
2462 enddo
2463
2464 ! -----------------------------------------------------------------------
2465 ! turn off melting when cloud microphysics time step is small
2466 ! -----------------------------------------------------------------------
2467
2468 if (dtm < 60.) k0 = kbot
2469
2470 ! sjl, turn off melting of falling cloud ice, snow and graupel
2471 k0 = kbot
2472 ! sjl, turn off melting of falling cloud ice, snow and graupel
2473
2474 ze(kbot + 1) = zs
2475 do k = kbot, ktop, - 1
2476 ze(k) = ze(k + 1) - dz(k) ! dz < 0
2477 enddo
2478
2479 zt(ktop) = ze(ktop)
2480
2481 ! -----------------------------------------------------------------------
2482 ! update capacity heat and latend heat coefficient
2483 ! -----------------------------------------------------------------------
2484
2485 do k = k0, kbot
2486 lhi(k) = li00 + dc_ice * tz(k)
2487 icpk(k) = lhi(k) / cvm(k)
2488 enddo
2489
2490 ! -----------------------------------------------------------------------
2491 ! melting of falling cloud ice into rain
2492 ! -----------------------------------------------------------------------
2493
2494 call check_column (ktop, kbot, qi, no_fall)
2495
2496 if (vi_fac < 1.e-5 .or. no_fall) then
2497 i1 = 0.
2498 else
2499
2500 do k = ktop + 1, kbot
2501 zt(k) = ze(k) - dt5 * (vti(k - 1) + vti(k))
2502 enddo
2503 zt(kbot + 1) = zs - dtm * vti(kbot)
2504
2505 do k = ktop, kbot
2506 if (zt(k + 1) >= zt(k)) zt(k + 1) = zt(k) - dz_min
2507 enddo
2508
2509 if (k0 < kbot) then
2510 do k = kbot - 1, k0, - 1
2511 if (qi(k) > qrmin) then
2512 do m = k + 1, kbot
2513 if (zt(k + 1) >= ze(m)) exit
2514 if (zt(k) < ze(m + 1) .and. tz(m) > tice) then
2515 dtime = min(1.0, (ze(m) - ze(m + 1)) / (max(vr_min, vti(k)) * tau_imlt))
2516 sink = min(qi(k) * dp(k) / dp(m), dtime * (tz(m) - tice) / icpk(m))
2517 tmp = min(sink, dim(ql_mlt, ql(m)))
2518 ql(m) = ql(m) + tmp
2519 qr(m) = qr(m) - tmp + sink
2520 tz(m) = tz(m) - sink * icpk(m)
2521 qi(k) = qi(k) - sink * dp(m) / dp(k)
2522 endif
2523 enddo
2524 endif
2525 enddo
2526 endif
2527
2528 if (do_sedi_w) then
2529 do k = ktop, kbot
2530 dm(k) = dp(k) * (1. + qv(k) + ql(k) + qr(k) + qi(k) + qs(k) + qg(k))
2531 enddo
2532 endif
2533
2534 if (use_ppm) then
2535 call lagrangian_fall_ppm (ktop, kbot, zs, ze, zt, dp, qi, i1, m1_sol, mono_prof)
2536 else
2537 call implicit_fall (dtm, ktop, kbot, ze, vti, dp, qi, i1, m1_sol)
2538 endif
2539
2540 if (do_sedi_w) then
2541 w1(ktop) = (dm(ktop) * w1(ktop) + m1_sol(ktop) * vti(ktop)) / (dm(ktop) - m1_sol(ktop))
2542 do k = ktop + 1, kbot
2543 w1(k) = (dm(k) * w1(k) - m1_sol(k - 1) * vti(k - 1) + m1_sol(k) * vti(k)) &
2544 / (dm(k) + m1_sol(k - 1) - m1_sol(k))
2545 enddo
2546 endif
2547
2548 endif
2549
2550 ! -----------------------------------------------------------------------
2551 ! melting of falling snow into rain
2552 ! -----------------------------------------------------------------------
2553
2554 r1 = 0.
2555
2556 call check_column (ktop, kbot, qs, no_fall)
2557
2558 if (no_fall) then
2559 s1 = 0.
2560 else
2561
2562 do k = ktop + 1, kbot
2563 zt(k) = ze(k) - dt5 * (vts(k - 1) + vts(k))
2564 enddo
2565 zt(kbot + 1) = zs - dtm * vts(kbot)
2566
2567 do k = ktop, kbot
2568 if (zt(k + 1) >= zt(k)) zt(k + 1) = zt(k) - dz_min
2569 enddo
2570
2571 if (k0 < kbot) then
2572 do k = kbot - 1, k0, - 1
2573 if (qs(k) > qrmin) then
2574 do m = k + 1, kbot
2575 if (zt(k + 1) >= ze(m)) exit
2576 dtime = min(dtm, (ze(m) - ze(m + 1)) / (vr_min + vts(k)))
2577 if (zt(k) < ze(m + 1) .and. tz(m) > tice) then
2578 dtime = min(1.0, dtime / tau_smlt)
2579 sink = min(qs(k) * dp(k) / dp(m), dtime * (tz(m) - tice) / icpk(m))
2580 tz(m) = tz(m) - sink * icpk(m)
2581 qs(k) = qs(k) - sink * dp(m) / dp(k)
2582 if (zt(k) < zs) then
2583 r1 = r1 + sink * dp(m) ! precip as rain
2584 else
2585 ! qr source here will fall next time step (therefore, can evap)
2586 qr(m) = qr(m) + sink
2587 endif
2588 endif
2589 if (qs(k) < qrmin) exit
2590 enddo
2591 endif
2592 enddo
2593 endif
2594
2595 if (do_sedi_w) then
2596 do k = ktop, kbot
2597 dm(k) = dp(k) * (1. + qv(k) + ql(k) + qr(k) + qi(k) + qs(k) + qg(k))
2598 enddo
2599 endif
2600
2601 if (use_ppm) then
2602 call lagrangian_fall_ppm (ktop, kbot, zs, ze, zt, dp, qs, s1, m1, mono_prof)
2603 else
2604 call implicit_fall (dtm, ktop, kbot, ze, vts, dp, qs, s1, m1)
2605 endif
2606
2607 do k = ktop, kbot
2608 m1_sol(k) = m1_sol(k) + m1(k)
2609 enddo
2610
2611 if (do_sedi_w) then
2612 w1(ktop) = (dm(ktop) * w1(ktop) + m1(ktop) * vts(ktop)) / (dm(ktop) - m1(ktop))
2613 do k = ktop + 1, kbot
2614 w1(k) = (dm(k) * w1(k) - m1(k - 1) * vts(k - 1) + m1(k) * vts(k)) &
2615 / (dm(k) + m1(k - 1) - m1(k))
2616 enddo
2617 endif
2618
2619 endif
2620
2621 ! ----------------------------------------------
2622 ! melting of falling graupel into rain
2623 ! ----------------------------------------------
2624
2625 call check_column (ktop, kbot, qg, no_fall)
2626
2627 if (no_fall) then
2628 g1 = 0.
2629 else
2630
2631 do k = ktop + 1, kbot
2632 zt(k) = ze(k) - dt5 * (vtg(k - 1) + vtg(k))
2633 enddo
2634 zt(kbot + 1) = zs - dtm * vtg(kbot)
2635
2636 do k = ktop, kbot
2637 if (zt(k + 1) >= zt(k)) zt(k + 1) = zt(k) - dz_min
2638 enddo
2639
2640 if (k0 < kbot) then
2641 do k = kbot - 1, k0, - 1
2642 if (qg(k) > qrmin) then
2643 do m = k + 1, kbot
2644 if (zt(k + 1) >= ze(m)) exit
2645 dtime = min(dtm, (ze(m) - ze(m + 1)) / vtg(k))
2646 if (zt(k) < ze(m + 1) .and. tz(m) > tice) then
2647 dtime = min(1., dtime / tau_g2r)
2648 sink = min(qg(k) * dp(k) / dp(m), dtime * (tz(m) - tice) / icpk(m))
2649 tz(m) = tz(m) - sink * icpk(m)
2650 qg(k) = qg(k) - sink * dp(m) / dp(k)
2651 if (zt(k) < zs) then
2652 r1 = r1 + sink * dp(m)
2653 else
2654 qr(m) = qr(m) + sink
2655 endif
2656 endif
2657 if (qg(k) < qrmin) exit
2658 enddo
2659 endif
2660 enddo
2661 endif
2662
2663 if (do_sedi_w) then
2664 do k = ktop, kbot
2665 dm(k) = dp(k) * (1. + qv(k) + ql(k) + qr(k) + qi(k) + qs(k) + qg(k))
2666 enddo
2667 endif
2668
2669 if (use_ppm) then
2670 call lagrangian_fall_ppm (ktop, kbot, zs, ze, zt, dp, qg, g1, m1, mono_prof)
2671 else
2672 call implicit_fall (dtm, ktop, kbot, ze, vtg, dp, qg, g1, m1)
2673 endif
2674
2675 do k = ktop, kbot
2676 m1_sol(k) = m1_sol(k) + m1(k)
2677 enddo
2678
2679 if (do_sedi_w) then
2680 w1(ktop) = (dm(ktop) * w1(ktop) + m1(ktop) * vtg(ktop)) / (dm(ktop) - m1(ktop))
2681 do k = ktop + 1, kbot
2682 w1(k) = (dm(k) * w1(k) - m1(k - 1) * vtg(k - 1) + m1(k) * vtg(k)) &
2683 / (dm(k) + m1(k - 1) - m1(k))
2684 enddo
2685 endif
2686
2687 endif
2688
2689end subroutine terminal_fall
2690
2691! =======================================================================
2695subroutine check_column (ktop, kbot, q, no_fall)
2696
2697 implicit none
2698
2699 integer, intent (in) :: ktop, kbot
2700
2701 real, intent (in) :: q (ktop:kbot)
2702
2703 logical, intent (out) :: no_fall
2704
2705 integer :: k
2706
2707 no_fall = .true.
2708
2709 do k = ktop, kbot
2710 if (q(k) > qrmin) then
2711 no_fall = .false.
2712 exit
2713 endif
2714 enddo
2715
2716end subroutine check_column
2717
2718! =======================================================================
2723subroutine implicit_fall (dt, ktop, kbot, ze, vt, dp, q, precip, m1)
2724
2725 implicit none
2726
2727 integer, intent (in) :: ktop, kbot
2728
2729 real, intent (in) :: dt
2730
2731 real, intent (in), dimension (ktop:kbot + 1) :: ze
2732
2733 real, intent (in), dimension (ktop:kbot) :: vt, dp
2734
2735 real, intent (inout), dimension (ktop:kbot) :: q
2736
2737 real, intent (out), dimension (ktop:kbot) :: m1
2738
2739 real, intent (out) :: precip
2740
2741 real, dimension (ktop:kbot) :: dz, qm, dd
2742
2743 integer :: k
2744
2745 do k = ktop, kbot
2746 dz(k) = ze(k) - ze(k + 1)
2747 dd(k) = dt * vt(k)
2748 q(k) = q(k) * dp(k)
2749 enddo
2750
2751 ! -----------------------------------------------------------------------
2752 ! sedimentation: non - vectorizable loop
2753 ! -----------------------------------------------------------------------
2754
2755 qm(ktop) = q(ktop) / (dz(ktop) + dd(ktop))
2756 do k = ktop + 1, kbot
2757 qm(k) = (q(k) + dd(k - 1) * qm(k - 1)) / (dz(k) + dd(k))
2758 enddo
2759
2760 ! -----------------------------------------------------------------------
2761 ! qm is density at this stage
2762 ! -----------------------------------------------------------------------
2763
2764 do k = ktop, kbot
2765 qm(k) = qm(k) * dz(k)
2766 enddo
2767
2768 ! -----------------------------------------------------------------------
2769 ! output mass fluxes: non - vectorizable loop
2770 ! -----------------------------------------------------------------------
2771
2772 m1(ktop) = q(ktop) - qm(ktop)
2773 do k = ktop + 1, kbot
2774 m1(k) = m1(k - 1) + q(k) - qm(k)
2775 enddo
2776 precip = m1(kbot)
2777
2778 ! -----------------------------------------------------------------------
2779 ! update:
2780 ! -----------------------------------------------------------------------
2781
2782 do k = ktop, kbot
2783 q(k) = qm(k) / dp(k)
2784 enddo
2785
2786end subroutine implicit_fall
2787
2788! =======================================================================
2792subroutine lagrangian_fall_ppm (ktop, kbot, zs, ze, zt, dp, q, precip, m1, mono)
2793
2794 implicit none
2795
2796 integer, intent (in) :: ktop, kbot
2797
2798 real, intent (in) :: zs
2799
2800 logical, intent (in) :: mono
2801
2802 real, intent (in), dimension (ktop:kbot + 1) :: ze, zt
2803
2804 real, intent (in), dimension (ktop:kbot) :: dp
2805
2806 ! m1: flux
2807 real, intent (inout), dimension (ktop:kbot) :: q, m1
2808
2809 real, intent (out) :: precip
2810
2811 real, dimension (ktop:kbot) :: qm, dz
2812
2813 real :: a4 (4, ktop:kbot)
2814
2815 real :: pl, pr, delz, esl
2816
2817 integer :: k, k0, n, m
2818
2819 real, parameter :: r3 = 1. / 3., r23 = 2. / 3.
2820
2821 ! -----------------------------------------------------------------------
2822 ! density:
2823 ! -----------------------------------------------------------------------
2824
2825 do k = ktop, kbot
2826 dz(k) = zt(k) - zt(k + 1) ! note: dz is positive
2827 q(k) = q(k) * dp(k)
2828 a4(1, k) = q(k) / dz(k)
2829 qm(k) = 0.
2830 enddo
2831
2832 ! -----------------------------------------------------------------------
2833 ! construct vertical profile with zt as coordinate
2834 ! -----------------------------------------------------------------------
2835
2836 call cs_profile (a4(1, ktop), dz(ktop), kbot - ktop + 1, mono)
2837
2838 k0 = ktop
2839 do k = ktop, kbot
2840 n_loop: do n = k0, kbot
2841 if (ze(k) <= zt(n) .and. ze(k) >= zt(n + 1)) then
2842 pl = (zt(n) - ze(k)) / dz(n)
2843 if (zt(n + 1) <= ze(k + 1)) then
2844 ! entire new grid is within the original grid
2845 pr = (zt(n) - ze(k + 1)) / dz(n)
2846 qm(k) = a4(2, n) + 0.5 * (a4(4, n) + a4(3, n) - a4(2, n)) * (pr + pl) - &
2847 a4(4, n) * r3 * (pr * (pr + pl) + pl ** 2)
2848 qm(k) = qm(k) * (ze(k) - ze(k + 1))
2849 k0 = n
2850 exit n_loop
2851 else
2852 qm(k) = (ze(k) - zt(n + 1)) * (a4(2, n) + 0.5 * (a4(4, n) + &
2853 a4(3, n) - a4(2, n)) * (1. + pl) - a4(4, n) * (r3 * (1. + pl * (1. + pl))))
2854 if (n < kbot) then
2855 do m = n + 1, kbot
2856 ! locate the bottom edge: ze (k + 1)
2857 if (ze(k + 1) < zt(m + 1)) then
2858 qm(k) = qm(k) + q(m)
2859 else
2860 delz = zt(m) - ze(k + 1)
2861 esl = delz / dz(m)
2862 qm(k) = qm(k) + delz * (a4(2, m) + 0.5 * esl * &
2863 (a4(3, m) - a4(2, m) + a4(4, m) * (1. - r23 * esl)))
2864 k0 = m
2865 exit n_loop
2866 endif
2867 enddo
2868 endif
2869 exit n_loop
2870 endif
2871 endif
2872 enddo n_loop
2873 enddo
2874
2875 m1(ktop) = q(ktop) - qm(ktop)
2876 do k = ktop + 1, kbot
2877 m1(k) = m1(k - 1) + q(k) - qm(k)
2878 enddo
2879 precip = m1(kbot)
2880
2881 ! convert back to * dry * mixing ratio:
2882 ! dp must be dry air_mass (because moist air mass will be changed due to terminal fall) .
2883
2884 do k = ktop, kbot
2885 q(k) = qm(k) / dp(k)
2886 enddo
2887
2888end subroutine lagrangian_fall_ppm
2889
2891subroutine cs_profile (a4, del, km, do_mono)
2892
2893 implicit none
2894
2895 integer, intent (in) :: km ! vertical dimension
2896
2897 real, intent (in) :: del (km)
2898
2899 logical, intent (in) :: do_mono
2900
2901 real, intent (inout) :: a4 (4, km)
2902
2903 real, parameter :: qp_min = 1.e-6
2904
2905 real :: gam (km)
2906 real :: q (km + 1)
2907 real :: d4, bet, a_bot, grat, pmp, lac
2908 real :: pmp_1, lac_1, pmp_2, lac_2
2909 real :: da1, da2, a6da
2910
2911 integer :: k
2912
2913 logical extm (km)
2914
2915 grat = del(2) / del(1) ! grid ratio
2916 bet = grat * (grat + 0.5)
2917 q(1) = (2. * grat * (grat + 1.) * a4(1, 1) + a4(1, 2)) / bet
2918 gam(1) = (1. + grat * (grat + 1.5)) / bet
2919
2920 do k = 2, km
2921 d4 = del(k - 1) / del(k)
2922 bet = 2. + 2. * d4 - gam(k - 1)
2923 q(k) = (3. * (a4(1, k - 1) + d4 * a4(1, k)) - q(k - 1)) / bet
2924 gam(k) = d4 / bet
2925 enddo
2926
2927 a_bot = 1. + d4 * (d4 + 1.5)
2928 q(km + 1) = (2. * d4 * (d4 + 1.) * a4(1, km) + a4(1, km - 1) - a_bot * q(km)) &
2929 / (d4 * (d4 + 0.5) - a_bot * gam(km))
2930
2931 do k = km, 1, - 1
2932 q(k) = q(k) - gam(k) * q(k + 1)
2933 enddo
2934
2935 ! -----------------------------------------------------------------------
2936 ! apply constraints
2937 ! -----------------------------------------------------------------------
2938
2939 do k = 2, km
2940 gam(k) = a4(1, k) - a4(1, k - 1)
2941 enddo
2942
2943 ! -----------------------------------------------------------------------
2944 ! apply large - scale constraints to all fields if not local max / min
2945 ! -----------------------------------------------------------------------
2946
2947 ! -----------------------------------------------------------------------
2948 ! top:
2949 ! -----------------------------------------------------------------------
2950
2951 q(1) = max(q(1), 0.)
2952 q(2) = min(q(2), max(a4(1, 1), a4(1, 2)))
2953 q(2) = max(q(2), min(a4(1, 1), a4(1, 2)), 0.)
2954
2955 ! -----------------------------------------------------------------------
2956 ! interior:
2957 ! -----------------------------------------------------------------------
2958
2959 do k = 3, km - 1
2960 if (gam(k - 1) * gam(k + 1) > 0.) then
2961 q(k) = min(q(k), max(a4(1, k - 1), a4(1, k)))
2962 q(k) = max(q(k), min(a4(1, k - 1), a4(1, k)))
2963 else
2964 if (gam(k - 1) > 0.) then
2965 ! there exists a local max
2966 q(k) = max(q(k), min(a4(1, k - 1), a4(1, k)))
2967 else
2968 ! there exists a local min
2969 q(k) = min(q(k), max(a4(1, k - 1), a4(1, k)))
2970 q(k) = max(q(k), 0.0)
2971 endif
2972 endif
2973 enddo
2974
2975 ! -----------------------------------------------------------------------
2976 ! bottom :
2977 ! -----------------------------------------------------------------------
2978
2979 q(km) = min(q(km), max(a4(1, km - 1), a4(1, km)))
2980 q(km) = max(q(km), min(a4(1, km - 1), a4(1, km)), 0.)
2981 ! q (km + 1) = max (q (km + 1), 0.)
2982
2983 ! -----------------------------------------------------------------------
2984 ! f (s) = al + s * [ (ar - al) + a6 * (1 - s) ] (0 <= s <= 1)
2985 ! -----------------------------------------------------------------------
2986
2987 do k = 1, km - 1
2988 a4(2, k) = q(k)
2989 a4(3, k) = q(k + 1)
2990 enddo
2991
2992 do k = 2, km - 1
2993 if (gam(k) * gam(k + 1) > 0.0) then
2994 extm(k) = .false.
2995 else
2996 extm(k) = .true.
2997 endif
2998 enddo
2999
3000 if (do_mono) then
3001 do k = 3, km - 2
3002 if (extm(k)) then
3003 ! positive definite constraint only if true local extrema
3004 if (a4(1, k) < qp_min .or. extm(k - 1) .or. extm(k + 1)) then
3005 a4(2, k) = a4(1, k)
3006 a4(3, k) = a4(1, k)
3007 endif
3008 else
3009 a4(4, k) = 6. * a4(1, k) - 3. * (a4(2, k) + a4(3, k))
3010 if (abs(a4(4, k)) > abs(a4(2, k) - a4(3, k))) then
3011 ! check within the smooth region if subgrid profile is non - monotonic
3012 pmp_1 = a4(1, k) - 2.0 * gam(k + 1)
3013 lac_1 = pmp_1 + 1.5 * gam(k + 2)
3014 a4(2, k) = min(max(a4(2, k), min(a4(1, k), pmp_1, lac_1)), &
3015 max(a4(1, k), pmp_1, lac_1))
3016 pmp_2 = a4(1, k) + 2.0 * gam(k)
3017 lac_2 = pmp_2 - 1.5 * gam(k - 1)
3018 a4(3, k) = min(max(a4(3, k), min(a4(1, k), pmp_2, lac_2)), &
3019 max(a4(1, k), pmp_2, lac_2))
3020 endif
3021 endif
3022 enddo
3023 else
3024 do k = 3, km - 2
3025 if (extm(k)) then
3026 if (a4(1, k) < qp_min .or. extm(k - 1) .or. extm(k + 1)) then
3027 a4(2, k) = a4(1, k)
3028 a4(3, k) = a4(1, k)
3029 endif
3030 endif
3031 enddo
3032 endif
3033
3034 do k = 1, km - 1
3035 a4(4, k) = 6. * a4(1, k) - 3. * (a4(2, k) + a4(3, k))
3036 enddo
3037
3038 k = km - 1
3039 if (extm(k)) then
3040 a4(2, k) = a4(1, k)
3041 a4(3, k) = a4(1, k)
3042 a4(4, k) = 0.
3043 else
3044 da1 = a4(3, k) - a4(2, k)
3045 da2 = da1 ** 2
3046 a6da = a4(4, k) * da1
3047 if (a6da < - da2) then
3048 a4(4, k) = 3. * (a4(2, k) - a4(1, k))
3049 a4(3, k) = a4(2, k) - a4(4, k)
3050 elseif (a6da > da2) then
3051 a4(4, k) = 3. * (a4(3, k) - a4(1, k))
3052 a4(2, k) = a4(3, k) - a4(4, k)
3053 endif
3054 endif
3055
3056 call cs_limiters (km - 1, a4)
3057
3058 ! -----------------------------------------------------------------------
3059 ! bottom layer:
3060 ! -----------------------------------------------------------------------
3061
3062 a4(2, km) = a4(1, km)
3063 a4(3, km) = a4(1, km)
3064 a4(4, km) = 0.
3065
3066end subroutine cs_profile
3067
3070subroutine cs_limiters (km, a4)
3071
3072 implicit none
3073
3074 integer, intent (in) :: km
3075
3076 real, intent (inout) :: a4 (4, km) ! ppm array
3077
3078 real, parameter :: r12 = 1. / 12.
3079
3080 integer :: k
3081
3082 ! -----------------------------------------------------------------------
3083 ! positive definite constraint
3084 ! -----------------------------------------------------------------------
3085
3086 do k = 1, km
3087 if (abs(a4(3, k) - a4(2, k)) < - a4(4, k)) then
3088 if ((a4(1, k) + 0.25 * (a4(3, k) - a4(2, k)) ** 2 / a4(4, k) + a4(4, k) * r12) < 0.) then
3089 if (a4(1, k) < a4(3, k) .and. a4(1, k) < a4(2, k)) then
3090 a4(3, k) = a4(1, k)
3091 a4(2, k) = a4(1, k)
3092 a4(4, k) = 0.
3093 elseif (a4(3, k) > a4(2, k)) then
3094 a4(4, k) = 3. * (a4(2, k) - a4(1, k))
3095 a4(3, k) = a4(2, k) - a4(4, k)
3096 else
3097 a4(4, k) = 3. * (a4(3, k) - a4(1, k))
3098 a4(2, k) = a4(3, k) - a4(4, k)
3099 endif
3100 endif
3101 endif
3102 enddo
3103
3104end subroutine cs_limiters
3105
3106! =======================================================================
3109subroutine fall_speed (ktop, kbot, den, qs, qi, qg, ql, tk, vts, vti, vtg)
3110
3111 implicit none
3112
3113 integer, intent (in) :: ktop, kbot
3114
3115 real, intent (in), dimension (ktop:kbot) :: den, qs, qi, qg, ql, tk
3116 real, intent (out), dimension (ktop:kbot) :: vts, vti, vtg
3117
3118 ! fall velocity constants:
3119
3120 real, parameter :: thi = 1.0e-8
3121 real, parameter :: thg = 1.0e-8
3122 real, parameter :: ths = 1.0e-8
3123
3124 ! coefficient for the parameterization of mass weighted fall velocity
3125 ! as a function of temperature and IWC.
3126 ! Table 1 in Deng and Mace (2008) \cite deng_and_mace_2008.
3127 real, parameter :: aa = - 4.14122e-5
3128 real, parameter :: bb = - 0.00538922
3129 real, parameter :: cc = - 0.0516344
3130 real, parameter :: dd = 0.00216078
3131 real, parameter :: ee = 1.9714
3132
3133 ! marshall - palmer constants
3134
3135 real, parameter :: vcons = 6.6280504
3136 real, parameter :: vcong = 87.2382675
3137 real, parameter :: vconh = vcong * sqrt(rhoh / rhog)
3138 real, parameter :: norms = 942477796.076938
3139 real, parameter :: normg = 5026548245.74367
3140 real, parameter :: normh = pi * rhoh * rnzh
3141
3142 real, dimension (ktop:kbot) :: qden, tc, rhof
3143
3144 real :: vi0
3145
3146 integer :: k
3147
3148 ! -----------------------------------------------------------------------
3149 ! marshall - palmer formula
3150 ! -----------------------------------------------------------------------
3151
3152 ! -----------------------------------------------------------------------
3153 ! try the local air density -- for global model; the true value could be
3154 ! much smaller than sfcrho over high mountains
3155 ! -----------------------------------------------------------------------
3156
3157 do k = ktop, kbot
3158 rhof(k) = sqrt(min(10., sfcrho / den(k)))
3159 enddo
3160
3161 ! -----------------------------------------------------------------------
3164 ! -----------------------------------------------------------------------
3165
3166 if (const_vi) then
3167 vti(:) = vi_fac
3168 else
3169 ! -----------------------------------------------------------------------
3170 ! use deng and mace (2008, grl), which gives smaller fall speed than hd90 formula
3171 ! -----------------------------------------------------------------------
3172 vi0 = 0.01 * vi_fac
3173 do k = ktop, kbot
3174 if (qi(k) < thi) then ! this is needed as the fall - speed maybe problematic for small qi
3175 vti(k) = vf_min
3176 else
3177 tc(k) = tk(k) - tice
3178 vti(k) = (3. + log10(qi(k) * den(k))) * (tc(k) * (aa * tc(k) + bb) + cc) + dd * tc(k) + ee
3179 vti(k) = vi0 * exp(log_10 * vti(k)) * 0.9
3180 vti(k) = min(vi_max, max(vf_min, vti(k)))
3181 endif
3182 enddo
3183 endif
3184
3185 ! -----------------------------------------------------------------------
3187 ! -----------------------------------------------------------------------
3188
3189 if (const_vs) then
3190 vts(:) = vs_fac ! 1. ifs_2016
3191 else
3192 do k = ktop, kbot
3193 if (qs(k) < ths) then
3194 vts(k) = vf_min
3195 else
3196 vts(k) = vs_fac * vcons * rhof(k) * exp(0.0625 * log(qs(k) * den(k) / norms))
3197 vts(k) = min(vs_max, max(vf_min, vts(k)))
3198 endif
3199 enddo
3200 endif
3201
3202 ! -----------------------------------------------------------------------
3204 ! -----------------------------------------------------------------------
3205 if (const_vg) then
3206 vtg(:) = vg_fac ! 2.
3207 else
3208 if (do_hail) then
3209 do k = ktop, kbot
3210 if (qg(k) < thg) then
3211 vtg(k) = vf_min
3212 else
3213 vtg(k) = vg_fac * vconh * rhof(k) * sqrt(sqrt(sqrt(qg(k) * den(k) / normh)))
3214 vtg(k) = min(vg_max, max(vf_min, vtg(k)))
3215 endif
3216 enddo
3217 else
3218 do k = ktop, kbot
3219 if (qg(k) < thg) then
3220 vtg(k) = vf_min
3221 else
3222 vtg(k) = vg_fac * vcong * rhof(k) * sqrt(sqrt(sqrt(qg(k) * den(k) / normg)))
3223 vtg(k) = min(vg_max, max(vf_min, vtg(k)))
3224 endif
3225 enddo
3226 endif
3227 endif
3228
3229end subroutine fall_speed
3230
3231! =======================================================================
3234subroutine setupm
3235
3236 implicit none
3237
3238 real :: gcon, cd, scm3, pisq, act (8)
3239 real :: vdifu, tcond
3240 real :: visk
3241 real :: ch2o, hltf
3242 real :: hlts, hltc, ri50
3243
3244 real, parameter :: gam263 = 1.456943, gam275 = 1.608355, gam290 = 1.827363, &
3245 gam325 = 2.54925, gam350 = 3.323363, gam380 = 4.694155, &
3246 gam425 = 8.285063, gam450 = 11.631769, gam480 = 17.837789, &
3247 gam625 = 184.860962, gam680 = 496.604067
3248
3249 ! intercept parameters
3250
3251! real, parameter :: rnzr = 8.0e6 ! lin83
3252! real, parameter :: rnzs = 3.0e6 ! lin83
3253! real, parameter :: rnzg = 4.0e6 ! rh84
3254
3255 ! density parameters
3256
3257! real, parameter :: rhos = 0.1e3 !< lin83 (snow density; 1 / 10 of water)
3258! real, parameter :: rhog = 0.4e3 !< rh84 (graupel density)
3259 real, parameter :: acc (3) = (/ 5.0, 2.0, 0.5 /)
3260
3261 real den_rc
3262
3263 integer :: i, k
3264
3265 pie = 4. * atan(1.0)
3266
3267 ! s. klein's formular (eq 16) from am2
3268
3269 fac_rc = (4. / 3.) * pie * rhor * rthresh ** 3
3270
3271 if (prog_ccn) then
3272 ! if (master) write (*, *) 'prog_ccn option is .t.'
3273 else
3274 den_rc = fac_rc * ccn_o * 1.e6
3275 ! if (master) write (*, *) 'mp: for ccn_o = ', ccn_o, 'ql_rc = ', den_rc
3276 den_rc = fac_rc * ccn_l * 1.e6
3277 ! if (master) write (*, *) 'mp: for ccn_l = ', ccn_l, 'ql_rc = ', den_rc
3278 endif
3279
3280 vdifu = 2.11e-5
3281 tcond = 2.36e-2
3282
3283 visk = 1.259e-5
3284 hlts = 2.8336e6
3285 hltc = 2.5e6
3286 hltf = 3.336e5
3287
3288 ch2o = 4.1855e3
3289 ri50 = 1.e-4
3290
3291 pisq = pie * pie
3292 scm3 = (visk / vdifu) ** (1. / 3.)
3293
3294 cracs = pisq * rnzr * rnzs * rhos
3295 csacr = pisq * rnzr * rnzs * rhor
3296 if (do_hail) then
3297 cgacr = pisq * rnzr * rnzh * rhor
3298 cgacs = pisq * rnzh * rnzs * rhos
3299 else
3300 cgacr = pisq * rnzr * rnzg * rhor
3301 cgacs = pisq * rnzg * rnzs * rhos
3302 endif
3303 cgacs = cgacs * c_pgacs
3304
3305 ! act: 1 - 2:racs (s - r) ; 3 - 4:sacr (r - s) ;
3306 ! 5 - 6:gacr (r - g) ; 7 - 8:gacs (s - g)
3307
3308 act(1) = pie * rnzs * rhos
3309 act(2) = pie * rnzr * rhor
3310 if (do_hail) then
3311 act(6) = pie * rnzh * rhoh
3312 else
3313 act(6) = pie * rnzg * rhog
3314 endif
3315 act(3) = act(2)
3316 act(4) = act(1)
3317 act(5) = act(2)
3318 act(7) = act(1)
3319 act(8) = act(6)
3320
3321 do i = 1, 3
3322 do k = 1, 4
3323 acco(i, k) = acc(i) / (act(2 * k - 1) ** ((7 - i) * 0.25) * act(2 * k) ** (i * 0.25))
3324 enddo
3325 enddo
3326
3327 gcon = 40.74 * sqrt(sfcrho) ! 44.628
3328
3329 csacw = pie * rnzs * clin * gam325 / (4. * act(1) ** 0.8125)
3330 ! decreasing csacw to reduce cloud water --- > snow
3331
3332 craci = pie * rnzr * alin * gam380 / (4. * act(2) ** 0.95)
3333 csaci = csacw * c_psaci
3334
3335 if (do_hail) then
3336 cgacw = pie * rnzh * gam350 * gcon / (4. * act(6) ** 0.875)
3337 else
3338 cgacw = pie * rnzg * gam350 * gcon / (4. * act(6) ** 0.875)
3339 endif
3340 ! cgaci = cgacw * 0.1
3341
3342 ! sjl, may 28, 2012
3343 cgaci = cgacw * 0.05
3344 ! sjl, may 28, 2012
3345
3346 cracw = craci ! cracw = 3.27206196043822
3347 cracw = c_cracw * cracw
3348
3349 ! subl and revp: five constants for three separate processes
3350
3351 cssub(1) = 2. * pie * vdifu * tcond * rvgas * rnzs
3352 if (do_hail) then
3353 cgsub(1) = 2. * pie * vdifu * tcond * rvgas * rnzh
3354 else
3355 cgsub(1) = 2. * pie * vdifu * tcond * rvgas * rnzg
3356 endif
3357 crevp(1) = 2. * pie * vdifu * tcond * rvgas * rnzr
3358 cssub(2) = 0.78 / sqrt(act(1))
3359 cgsub(2) = 0.78 / sqrt(act(6))
3360 crevp(2) = 0.78 / sqrt(act(2))
3361 cssub(3) = 0.31 * scm3 * gam263 * sqrt(clin / visk) / act(1) ** 0.65625
3362 cgsub(3) = 0.31 * scm3 * gam275 * sqrt(gcon / visk) / act(6) ** 0.6875
3363 crevp(3) = 0.31 * scm3 * gam290 * sqrt(alin / visk) / act(2) ** 0.725
3364 cssub(4) = tcond * rvgas
3365 cssub(5) = hlts ** 2 * vdifu
3366 cgsub(4) = cssub(4)
3367 crevp(4) = cssub(4)
3368 cgsub(5) = cssub(5)
3369 crevp(5) = hltc ** 2 * vdifu
3370
3371 cgfr(1) = 20.e2 * pisq * rnzr * rhor / act(2) ** 1.75
3372 cgfr(2) = 0.66
3373
3374 ! smlt: five constants (lin et al. 1983)
3375
3376 csmlt(1) = 2. * pie * tcond * rnzs / hltf
3377 csmlt(2) = 2. * pie * vdifu * rnzs * hltc / hltf
3378 csmlt(3) = cssub(2)
3379 csmlt(4) = cssub(3)
3380 csmlt(5) = ch2o / hltf
3381
3382 ! gmlt: five constants
3383
3384 if (do_hail) then
3385 cgmlt(1) = 2. * pie * tcond * rnzh / hltf
3386 cgmlt(2) = 2. * pie * vdifu * rnzh * hltc / hltf
3387 else
3388 cgmlt(1) = 2. * pie * tcond * rnzg / hltf
3389 cgmlt(2) = 2. * pie * vdifu * rnzg * hltc / hltf
3390 endif
3391 cgmlt(3) = cgsub(2)
3392 cgmlt(4) = cgsub(3)
3393 cgmlt(5) = ch2o / hltf
3394
3395 es0 = 6.107799961e2 ! ~6.1 mb
3396 ces0 = eps * es0
3397
3398end subroutine setupm
3399
3400! =======================================================================
3401! initialization of gfdl cloud microphysics
3405subroutine gfdl_cloud_microphys_mod_init (me, master, nlunit, input_nml_file, logunit, &
3406 fn_nml, errmsg, errflg)
3407
3408 implicit none
3409
3410 integer, intent (in) :: me
3411 integer, intent (in) :: master
3412 integer, intent (in) :: nlunit
3413 integer, intent (in) :: logunit
3414
3415 character (len = 64), intent (in) :: fn_nml
3416 character (len = *), intent (in) :: input_nml_file(:)
3417 character(len=*), intent(out) :: errmsg
3418 integer, intent(out) :: errflg
3419
3420 integer :: ios
3421 logical :: exists
3422
3423 ! integer, intent (in) :: id, jd, kd
3424 ! integer, intent (in) :: axes (4)
3425 ! type (time_type), intent (in) :: time
3426
3427 ! integer :: unit, io, ierr, k, logunit
3428 ! logical :: flag
3429 ! real :: tmp, q1, q2
3430
3431 ! master = (mpp_pe () .eq.mpp_root_pe ())
3432
3433 ! Initialize CCPP error-handling
3434 errflg = 0
3435 errmsg = ''
3436
3437 ! -----------------------------------------------------------------------
3438 ! Read namelist
3439 ! -----------------------------------------------------------------------
3440 call read_gfdlmp_nml(errmsg = errmsg, errflg = errflg, unit = nlunit, &
3441 input_nml_file = input_nml_file, fn_nml = fn_nml, version=1, &
3442 iostat = ios)
3443 if(errflg/=0) return
3444
3445 ! write version number and namelist to log file
3446 if (me == master) then
3447 write (logunit, *) " ================================================================== "
3448 write (logunit, *) "gfdl_cloud_microphysics_nml"
3449 endif
3450
3451 !
3452 if (do_setup) then
3453 call setup_con
3454 call setupm
3455 do_setup = .false.
3456 endif
3457
3458 log_10 = log(10.)
3459
3460 tice0 = tice - 0.01
3461 t_wfr = tice - 40.0 ! supercooled water can exist down to - 48 c, which is the "absolute"
3462
3463 ! if (master) write (logunit, nml = gfdl_cloud_microphys_nml)
3464 !
3465 ! id_vtr = register_diag_field (mod_name, 'vt_r', axes (1:3), time, &
3466 ! 'rain fall speed', 'm / s', missing_value = missing_value)
3467 ! id_vts = register_diag_field (mod_name, 'vt_s', axes (1:3), time, &
3468 ! 'snow fall speed', 'm / s', missing_value = missing_value)
3469 ! id_vtg = register_diag_field (mod_name, 'vt_g', axes (1:3), time, &
3470 ! 'graupel fall speed', 'm / s', missing_value = missing_value)
3471 ! id_vti = register_diag_field (mod_name, 'vt_i', axes (1:3), time, &
3472 ! 'ice fall speed', 'm / s', missing_value = missing_value)
3473
3474 ! id_droplets = register_diag_field (mod_name, 'droplets', axes (1:3), time, &
3475 ! 'droplet number concentration', '# / m3', missing_value = missing_value)
3476 ! id_rh = register_diag_field (mod_name, 'rh_lin', axes (1:2), time, &
3477 ! 'relative humidity', 'n / a', missing_value = missing_value)
3478
3479 ! id_rain = register_diag_field (mod_name, 'rain_lin', axes (1:2), time, &
3480 ! 'rain_lin', 'mm / day', missing_value = missing_value)
3481 ! id_snow = register_diag_field (mod_name, 'snow_lin', axes (1:2), time, &
3482 ! 'snow_lin', 'mm / day', missing_value = missing_value)
3483 ! id_graupel = register_diag_field (mod_name, 'graupel_lin', axes (1:2), time, &
3484 ! 'graupel_lin', 'mm / day', missing_value = missing_value)
3485 ! id_ice = register_diag_field (mod_name, 'ice_lin', axes (1:2), time, &
3486 ! 'ice_lin', 'mm / day', missing_value = missing_value)
3487 ! id_prec = register_diag_field (mod_name, 'prec_lin', axes (1:2), time, &
3488 ! 'prec_lin', 'mm / day', missing_value = missing_value)
3489
3490 ! if (master) write (*, *) 'prec_lin diagnostics initialized.', id_prec
3491
3492 ! id_cond = register_diag_field (mod_name, 'cond_lin', axes (1:2), time, &
3493 ! 'total condensate', 'kg / m ** 2', missing_value = missing_value)
3494 ! id_var = register_diag_field (mod_name, 'var_lin', axes (1:2), time, &
3495 ! 'subgrid variance', 'n / a', missing_value = missing_value)
3496
3497 ! call qsmith_init
3498
3499 ! testing the water vapor tables
3500
3501 ! if (mp_debug .and. master) then
3502 ! write (*, *) 'testing water vapor tables in gfdl_cloud_microphys'
3503 ! tmp = tice - 90.
3504 ! do k = 1, 25
3505 ! q1 = wqsat_moist (tmp, 0., 1.e5)
3506 ! q2 = qs1d_m (tmp, 0., 1.e5)
3507 ! write (*, *) nint (tmp - tice), q1, q2, 'dq = ', q1 - q2
3508 ! tmp = tmp + 5.
3509 ! enddo
3510 ! endif
3511
3512 ! if (master) write (*, *) 'gfdl_cloud_micrphys diagnostics initialized.'
3513
3514 module_is_initialized = .true.
3515
3516!+---+-----------------------------------------------------------------+
3517!..Set these variables needed for computing radar reflectivity. These
3518!.. get used within radar_init to create other variables used in the
3519!.. radar module.
3520
3521 xam_r = pi*rhor/6.
3522 xbm_r = 3.
3523 xmu_r = 0.
3524 xam_s = pi*rhos/6.
3525 xbm_s = 3.
3526 xmu_s = 0.
3527 xam_g = pi*rhog/6.
3528 xbm_g = 3.
3529 xmu_g = 0.
3530
3531 call radar_init
3532
3533end subroutine gfdl_cloud_microphys_mod_init
3534
3535! =======================================================================
3536! end of gfdl cloud microphysics
3541
3542 implicit none
3543
3544 deallocate (table)
3545 deallocate (table2)
3546 deallocate (table3)
3547 deallocate (tablew)
3548 deallocate (des)
3549 deallocate (des2)
3550 deallocate (des3)
3551 deallocate (desw)
3552
3553 tables_are_initialized = .false.
3554
3555end subroutine gfdl_cloud_microphys_mod_end
3556
3557! =======================================================================
3558! qsmith table initialization
3561subroutine setup_con
3562
3563 implicit none
3564
3565 ! master = (mpp_pe () .eq.mpp_root_pe ())
3566
3567 rgrav = 1. / grav
3568
3569 if (.not. qsmith_tables_initialized) call qsmith_init
3570
3571 qsmith_tables_initialized = .true.
3572
3573end subroutine setup_con
3574
3575! =======================================================================
3579! =======================================================================
3580
3581real function acr3d (v1, v2, q1, q2, c, cac, rho)
3582
3583 implicit none
3584
3585 real, intent (in) :: v1, v2, c, rho
3586 real, intent (in) :: q1, q2 ! mixing ratio!!!
3587 real, intent (in) :: cac (3)
3588
3589 real :: t1, s1, s2
3590
3591 ! integer :: k
3592 !
3593 ! real :: a
3594 !
3595 ! a = 0.0
3596 ! do k = 1, 3
3597 ! a = a + cac (k) * ((q1 * rho) ** ((7 - k) * 0.25) * (q2 * rho) ** (k * 0.25))
3598 ! enddo
3599 ! acr3d = c * abs (v1 - v2) * a / rho
3600
3601 ! optimized
3602
3603 t1 = sqrt(q1 * rho)
3604 s1 = sqrt(q2 * rho)
3605 s2 = sqrt(s1) ! s1 = s2 ** 2
3606 acr3d = c * abs(v1 - v2) * q1 * s2 * (cac(1) * t1 + cac(2) * sqrt(t1) * s2 + cac(3) * s1)
3607
3608end function acr3d
3609
3610! =======================================================================
3614! =======================================================================
3615
3616real function smlt (tc, dqs, qsrho, psacw, psacr, c, rho, rhofac)
3617
3618 implicit none
3619
3620 real, intent (in) :: tc, dqs, qsrho, psacw, psacr, c (5), rho, rhofac
3621
3622 smlt = (c(1) * tc / rho - c(2) * dqs) * (c(3) * sqrt(qsrho) + &
3623 c(4) * qsrho ** 0.65625 * sqrt(rhofac)) + c(5) * tc * (psacw + psacr)
3624
3625end function smlt
3626
3627! =======================================================================
3630! =======================================================================
3631
3632real function gmlt (tc, dqs, qgrho, pgacw, pgacr, c, rho)
3633
3634 implicit none
3635
3636 real, intent (in) :: tc, dqs, qgrho, pgacw, pgacr, c (5), rho
3637
3638 gmlt = (c(1) * tc / rho - c(2) * dqs) * (c(3) * sqrt(qgrho) + &
3639 c(4) * qgrho ** 0.6875 / rho ** 0.25) + c(5) * tc * (pgacw + pgacr)
3640
3641end function gmlt
3642
3643! =======================================================================
3644! initialization
3645! prepare saturation water vapor pressure tables
3646! =======================================================================
3653! =======================================================================
3654subroutine qsmith_init
3655
3656 implicit none
3657
3658 integer, parameter :: length = 2621
3659
3660 integer :: i
3661
3662 if (.not. tables_are_initialized) then
3663
3664 ! master = (mpp_pe () .eq. mpp_root_pe ())
3665 ! if (master) print *, ' gfdl mp: initializing qs tables'
3666
3667 ! debug code
3668 ! print *, mpp_pe (), allocated (table), allocated (table2), &
3669 ! allocated (table3), allocated (tablew), allocated (des), &
3670 ! allocated (des2), allocated (des3), allocated (desw)
3671 ! end debug code
3672
3673 ! generate es table (dt = 0.1 deg. c)
3674
3675 allocate (table(length))
3676 allocate (table2(length))
3677 allocate (table3(length))
3678 allocate (tablew(length))
3679 allocate (des(length))
3680 allocate (des2(length))
3681 allocate (des3(length))
3682 allocate (desw(length))
3683
3684 call qs_table (length)
3685 call qs_table2 (length)
3686 call qs_table3 (length)
3687 call qs_tablew (length)
3688
3689 do i = 1, length - 1
3690 des(i) = max(0., table(i + 1) - table(i))
3691 des2(i) = max(0., table2(i + 1) - table2(i))
3692 des3(i) = max(0., table3(i + 1) - table3(i))
3693 desw(i) = max(0., tablew(i + 1) - tablew(i))
3694 enddo
3695 des(length) = des(length - 1)
3696 des2(length) = des2(length - 1)
3697 des3(length) = des3(length - 1)
3698 desw(length) = desw(length - 1)
3699
3700 tables_are_initialized = .true.
3701
3702 endif
3703
3704end subroutine qsmith_init
3705
3706! =======================================================================
3707! compute the saturated specific humidity for table ii
3711real function wqs1 (ta, den)
3712
3713 implicit none
3714
3717
3718 real, intent (in) :: ta, den
3719
3720 real :: es, ap1, tmin
3721
3722 integer :: it
3723
3724 tmin = table_ice - 160.
3725 ap1 = 10. * dim(ta, tmin) + 1.
3726 ap1 = min(2621., ap1)
3727 it = ap1
3728 es = tablew(it) + (ap1 - it) * desw(it)
3729 wqs1 = es / (rvgas * ta * den)
3730
3731end function wqs1
3732
3733! =======================================================================
3734! compute the gradient of saturated specific humidity for table ii
3738! =======================================================================
3739
3740real function wqs2 (ta, den, dqdt)
3741
3742 implicit none
3743
3744 ! pure water phase; universal dry / moist formular using air density
3745 ! input "den" can be either dry or moist air density
3746
3747 real, intent (in) :: ta, den
3748
3749 real, intent (out) :: dqdt
3750
3751 real :: es, ap1, tmin
3752
3753 integer :: it
3754
3755 tmin = table_ice - 160.
3756
3757 if (.not. tables_are_initialized) call qsmith_init
3758
3759 ap1 = 10. * dim(ta, tmin) + 1.
3760 ap1 = min(2621., ap1)
3761 it = ap1
3762 es = tablew(it) + (ap1 - it) * desw(it)
3763 wqs2 = es / (rvgas * ta * den)
3764 it = ap1 - 0.5
3765 ! finite diff, del_t = 0.1:
3766 dqdt = 10. * (desw(it) + (ap1 - it) * (desw(it + 1) - desw(it))) / (rvgas * ta * den)
3767
3768end function wqs2
3769
3770! =======================================================================
3771! compute wet buld temperature
3774! =======================================================================
3775
3776real function wet_bulb (q, t, den)
3777
3778 implicit none
3779
3780 real, intent (in) :: t, q, den
3781
3782 real :: qs, tp, dqdt
3783
3784 wet_bulb = t
3785 qs = wqs2(wet_bulb, den, dqdt)
3786 tp = 0.5 * (qs - q) / (1. + lcp * dqdt) * lcp
3787 wet_bulb = wet_bulb - tp
3788
3789 ! tp is negative if super - saturated
3790 if (tp > 0.01) then
3791 qs = wqs2(wet_bulb, den, dqdt)
3792 tp = (qs - q) / (1. + lcp * dqdt) * lcp
3793 wet_bulb = wet_bulb - tp
3794 endif
3795
3796end function wet_bulb
3797
3798! =======================================================================
3801! =======================================================================
3802
3803real function iqs1 (ta, den)
3804
3805 implicit none
3806
3809
3810 real, intent (in) :: ta, den
3811
3812 real :: es, ap1, tmin
3813
3814 integer :: it
3815
3816 tmin = table_ice - 160.
3817 ap1 = 10. * dim(ta, tmin) + 1.
3818 ap1 = min(2621., ap1)
3819 it = ap1
3820 es = table2(it) + (ap1 - it) * des2(it)
3821 iqs1 = es / (rvgas * ta * den)
3822
3823end function iqs1
3824
3825! =======================================================================
3828! =======================================================================
3829
3830real function iqs2 (ta, den, dqdt)
3831
3832 implicit none
3833
3834 ! water - ice phase; universal dry / moist formular using air density
3835 ! input "den" can be either dry or moist air density
3836
3837 real, intent (in) :: ta, den
3838
3839 real, intent (out) :: dqdt
3840
3841 real :: es, ap1, tmin
3842
3843 integer :: it
3844
3845 tmin = table_ice - 160.
3846 ap1 = 10. * dim(ta, tmin) + 1.
3847 ap1 = min(2621., ap1)
3848 it = ap1
3849 es = table2(it) + (ap1 - it) * des2(it)
3850 iqs2 = es / (rvgas * ta * den)
3851 it = ap1 - 0.5
3852 dqdt = 10. * (des2(it) + (ap1 - it) * (des2(it + 1) - des2(it))) / (rvgas * ta * den)
3853
3854end function iqs2
3855
3856! =======================================================================
3859! =======================================================================
3860
3861real function qs1d_moist (ta, qv, pa, dqdt)
3862
3863 implicit none
3864
3865 real, intent (in) :: ta, pa, qv
3866
3867 real, intent (out) :: dqdt
3868
3869 real :: es, ap1, tmin, eps10
3870
3871 integer :: it
3872
3873 tmin = table_ice - 160.
3874 eps10 = 10. * eps
3875 ap1 = 10. * dim(ta, tmin) + 1.
3876 ap1 = min(2621., ap1)
3877 it = ap1
3878 es = table2(it) + (ap1 - it) * des2(it)
3879 qs1d_moist = eps * es * (1. + zvir * qv) / pa
3880 it = ap1 - 0.5
3881 dqdt = eps10 * (des2(it) + (ap1 - it) * (des2(it + 1) - des2(it))) * (1. + zvir * qv) / pa
3882
3883end function qs1d_moist
3884
3885! =======================================================================
3886! compute the gradient of saturated specific humidity for table ii
3889! =======================================================================
3890
3891real function wqsat2_moist (ta, qv, pa, dqdt)
3892
3893 implicit none
3894
3895 real, intent (in) :: ta, pa, qv
3896
3897 real, intent (out) :: dqdt
3898
3899 real :: es, ap1, tmin, eps10
3900
3901 integer :: it
3902
3903 tmin = table_ice - 160.
3904 eps10 = 10. * eps
3905 ap1 = 10. * dim(ta, tmin) + 1.
3906 ap1 = min(2621., ap1)
3907 it = ap1
3908 es = tablew(it) + (ap1 - it) * desw(it)
3909 wqsat2_moist = eps * es * (1. + zvir * qv) / pa
3910 it = ap1 - 0.5
3911 dqdt = eps10 * (desw(it) + (ap1 - it) * (desw(it + 1) - desw(it))) * (1. + zvir * qv) / pa
3912
3913end function wqsat2_moist
3914
3915! =======================================================================
3916! compute the saturated specific humidity for table ii
3919! =======================================================================
3920
3921real function wqsat_moist (ta, qv, pa)
3922
3923 implicit none
3924
3925 real, intent (in) :: ta, pa, qv
3926
3927 real :: es, ap1, tmin
3928
3929 integer :: it
3930
3931 tmin = table_ice - 160.
3932 ap1 = 10. * dim(ta, tmin) + 1.
3933 ap1 = min(2621., ap1)
3934 it = ap1
3935 es = tablew(it) + (ap1 - it) * desw(it)
3936 wqsat_moist = eps * es * (1. + zvir * qv) / pa
3937
3938end function wqsat_moist
3939
3940! =======================================================================
3943! =======================================================================
3944
3945real function qs1d_m (ta, qv, pa)
3946
3947 implicit none
3948
3949 real, intent (in) :: ta, pa, qv
3950
3951 real :: es, ap1, tmin
3952
3953 integer :: it
3954
3955 tmin = table_ice - 160.
3956 ap1 = 10. * dim(ta, tmin) + 1.
3957 ap1 = min(2621., ap1)
3958 it = ap1
3959 es = table2(it) + (ap1 - it) * des2(it)
3960 qs1d_m = eps * es * (1. + zvir * qv) / pa
3961
3962end function qs1d_m
3963
3964! =======================================================================
3967! =======================================================================
3968
3969real function d_sat (ta, den)
3970
3971 implicit none
3972
3973 real, intent (in) :: ta, den
3974
3975 real :: es_w, es_i, ap1, tmin
3976
3977 integer :: it
3978
3979 tmin = table_ice - 160.
3980 ap1 = 10. * dim(ta, tmin) + 1.
3981 ap1 = min(2621., ap1)
3982 it = ap1
3983 es_w = tablew(it) + (ap1 - it) * desw(it)
3984 es_i = table2(it) + (ap1 - it) * des2(it)
3985 d_sat = dim(es_w, es_i) / (rvgas * ta * den) ! take positive difference
3986
3987end function d_sat
3988
3989! =======================================================================
3992! =======================================================================
3993
3994real function esw_table (ta)
3995
3996 implicit none
3997
3998 real, intent (in) :: ta
3999
4000 real :: ap1, tmin
4001
4002 integer :: it
4003
4004 tmin = table_ice - 160.
4005 ap1 = 10. * dim(ta, tmin) + 1.
4006 ap1 = min(2621., ap1)
4007 it = ap1
4008 esw_table = tablew(it) + (ap1 - it) * desw(it)
4009
4010end function esw_table
4011
4012! =======================================================================
4015! =======================================================================
4016
4017real function es2_table (ta)
4018
4019 implicit none
4020
4021 real, intent (in) :: ta
4022
4023 real :: ap1, tmin
4024
4025 integer :: it
4026
4027 tmin = table_ice - 160.
4028 ap1 = 10. * dim(ta, tmin) + 1.
4029 ap1 = min(2621., ap1)
4030 it = ap1
4031 es2_table = table2(it) + (ap1 - it) * des2(it)
4032
4033end function es2_table
4034
4035! =======================================================================
4039subroutine esw_table1d (ta, es, n)
4040
4041 implicit none
4042
4043 integer, intent (in) :: n
4044
4045 real, intent (in) :: ta (n)
4046
4047 real, intent (out) :: es (n)
4048
4049 real :: ap1, tmin
4050
4051 integer :: i, it
4052
4053 tmin = table_ice - 160.
4054
4055 do i = 1, n
4056 ap1 = 10. * dim(ta(i), tmin) + 1.
4057 ap1 = min(2621., ap1)
4058 it = ap1
4059 es(i) = tablew(it) + (ap1 - it) * desw(it)
4060 enddo
4061
4062end subroutine esw_table1d
4063
4064! =======================================================================
4068subroutine es2_table1d (ta, es, n)
4069
4070 implicit none
4071
4072 integer, intent (in) :: n
4073
4074 real, intent (in) :: ta (n)
4075
4076 real, intent (out) :: es (n)
4077
4078 real :: ap1, tmin
4079
4080 integer :: i, it
4081
4082 tmin = table_ice - 160.
4083
4084 do i = 1, n
4085 ap1 = 10. * dim(ta(i), tmin) + 1.
4086 ap1 = min(2621., ap1)
4087 it = ap1
4088 es(i) = table2(it) + (ap1 - it) * des2(it)
4089 enddo
4090
4091end subroutine es2_table1d
4092
4093! =======================================================================
4097subroutine es3_table1d (ta, es, n)
4098
4099 implicit none
4100
4101 integer, intent (in) :: n
4102
4103 real, intent (in) :: ta (n)
4104
4105 real, intent (out) :: es (n)
4106
4107 real :: ap1, tmin
4108
4109 integer :: i, it
4110
4111 tmin = table_ice - 160.
4112
4113 do i = 1, n
4114 ap1 = 10. * dim(ta(i), tmin) + 1.
4115 ap1 = min(2621., ap1)
4116 it = ap1
4117 es(i) = table3(it) + (ap1 - it) * des3(it)
4118 enddo
4119
4120end subroutine es3_table1d
4121
4122! =======================================================================
4125! 1 - phase table
4126subroutine qs_tablew (n)
4127
4128 implicit none
4129
4130 integer, intent (in) :: n
4131
4132 real :: delt = 0.1
4133 real :: tmin, tem, fac0, fac1, fac2
4134
4135 integer :: i
4136
4137 tmin = table_ice - 160.
4138
4139 ! -----------------------------------------------------------------------
4140 ! compute es over water
4141 ! -----------------------------------------------------------------------
4142
4143 do i = 1, n
4144 tem = tmin + delt * real(i - 1)
4145 fac0 = (tem - t_ice) / (tem * t_ice)
4146 fac1 = fac0 * lv0
4147 fac2 = (dc_vap * log(tem / t_ice) + fac1) / rvgas
4148 tablew(i) = e00 * exp(fac2)
4149 enddo
4150
4151end subroutine qs_tablew
4152
4153! =======================================================================
4156! 2 - phase table
4157subroutine qs_table2 (n)
4158
4159 implicit none
4160
4161 integer, intent (in) :: n
4162
4163 real :: delt = 0.1
4164 real :: tmin, tem0, tem1, fac0, fac1, fac2
4165
4166 integer :: i, i0, i1
4167
4168 tmin = table_ice - 160.
4169
4170 do i = 1, n
4171 tem0 = tmin + delt * real(i - 1)
4172 fac0 = (tem0 - t_ice) / (tem0 * t_ice)
4173 if (i <= 1600) then
4174 ! -----------------------------------------------------------------------
4175 ! compute es over ice between - 160 deg c and 0 deg c.
4176 ! -----------------------------------------------------------------------
4177 fac1 = fac0 * li2
4178 fac2 = (d2ice * log(tem0 / t_ice) + fac1) / rvgas
4179 else
4180 ! -----------------------------------------------------------------------
4181 ! compute es over water between 0 deg c and 102 deg c.
4182 ! -----------------------------------------------------------------------
4183 fac1 = fac0 * lv0
4184 fac2 = (dc_vap * log(tem0 / t_ice) + fac1) / rvgas
4185 endif
4186 table2(i) = e00 * exp(fac2)
4187 enddo
4188
4189 ! -----------------------------------------------------------------------
4190 ! smoother around 0 deg c
4191 ! -----------------------------------------------------------------------
4192
4193 i0 = 1600
4194 i1 = 1601
4195 tem0 = 0.25 * (table2(i0 - 1) + 2. * table(i0) + table2(i0 + 1))
4196 tem1 = 0.25 * (table2(i1 - 1) + 2. * table(i1) + table2(i1 + 1))
4197 table2(i0) = tem0
4198 table2(i1) = tem1
4199
4200end subroutine qs_table2
4201
4202! =======================================================================
4205! 2 - phase table with " - 2 c" as the transition point
4206subroutine qs_table3 (n)
4207
4208 implicit none
4209
4210 integer, intent (in) :: n
4211
4212 real :: delt = 0.1
4213 real :: esbasw, tbasw, esbasi, tmin, tem, aa, b, c, d, e
4214 real :: tem0, tem1
4215
4216 integer :: i, i0, i1
4217
4218 esbasw = 1013246.0
4219 tbasw = table_ice + 100.
4220 esbasi = 6107.1
4221 tmin = table_ice - 160.
4222
4223 do i = 1, n
4224 tem = tmin + delt * real(i - 1)
4225 ! if (i <= 1600) then
4226 if (i <= 1580) then ! change to - 2 c
4227 ! -----------------------------------------------------------------------
4228 ! compute es over ice between - 160 deg c and 0 deg c.
4229 ! see smithsonian meteorological tables page 350.
4230 ! -----------------------------------------------------------------------
4231 aa = - 9.09718 * (table_ice / tem - 1.)
4232 b = - 3.56654 * alog10(table_ice / tem)
4233 c = 0.876793 * (1. - tem / table_ice)
4234 e = alog10(esbasi)
4235 table3(i) = 0.1 * 10 ** (aa + b + c + e)
4236 else
4237 ! -----------------------------------------------------------------------
4238 ! compute es over water between - 2 deg c and 102 deg c.
4239 ! see smithsonian meteorological tables page 350.
4240 ! -----------------------------------------------------------------------
4241 aa = - 7.90298 * (tbasw / tem - 1.)
4242 b = 5.02808 * alog10(tbasw / tem)
4243 c = - 1.3816e-7 * (10 ** ((1. - tem / tbasw) * 11.344) - 1.)
4244 d = 8.1328e-3 * (10 ** ((tbasw / tem - 1.) * (- 3.49149)) - 1.)
4245 e = alog10(esbasw)
4246 table3(i) = 0.1 * 10 ** (aa + b + c + d + e)
4247 endif
4248 enddo
4249
4250 ! -----------------------------------------------------------------------
4251 ! smoother around - 2 deg c
4252 ! -----------------------------------------------------------------------
4253
4254 i0 = 1580
4255 i1 = 1581
4256 tem0 = 0.25 * (table3(i0 - 1) + 2. * table(i0) + table3(i0 + 1))
4257 tem1 = 0.25 * (table3(i1 - 1) + 2. * table(i1) + table3(i1 + 1))
4258 table3(i0) = tem0
4259 table3(i1) = tem1
4260
4261end subroutine qs_table3
4262
4263! =======================================================================
4264! compute the saturated specific humidity for table
4265! note: this routine is based on "moist" mixing ratio
4269real function qs_blend (t, p, q)
4270
4271 implicit none
4272
4273 real, intent (in) :: t, p, q
4274
4275 real :: es, ap1, tmin
4276
4277 integer :: it
4278
4279 tmin = table_ice - 160.
4280 ap1 = 10. * dim(t, tmin) + 1.
4281 ap1 = min(2621., ap1)
4282 it = ap1
4283 es = table(it) + (ap1 - it) * des(it)
4284 qs_blend = eps * es * (1. + zvir * q) / p
4285
4286end function qs_blend
4287
4288! =======================================================================
4291! 3 - phase table
4292subroutine qs_table (n)
4293
4294 implicit none
4295
4296 integer, intent (in) :: n
4297
4298 real :: delt = 0.1
4299 real :: tmin, tem, esh20
4300 real :: wice, wh2o, fac0, fac1, fac2
4301 real :: esupc (200)
4302
4303 integer :: i
4304
4305 tmin = table_ice - 160.
4306
4307 ! -----------------------------------------------------------------------
4308 ! compute es over ice between - 160 deg c and 0 deg c.
4309 ! -----------------------------------------------------------------------
4310
4311 do i = 1, 1600
4312 tem = tmin + delt * real(i - 1)
4313 fac0 = (tem - t_ice) / (tem * t_ice)
4314 fac1 = fac0 * li2
4315 fac2 = (d2ice * log(tem / t_ice) + fac1) / rvgas
4316 table(i) = e00 * exp(fac2)
4317 enddo
4318
4319 ! -----------------------------------------------------------------------
4320 ! compute es over water between - 20 deg c and 102 deg c.
4321 ! -----------------------------------------------------------------------
4322
4323 do i = 1, 1221
4324 tem = 253.16 + delt * real(i - 1)
4325 fac0 = (tem - t_ice) / (tem * t_ice)
4326 fac1 = fac0 * lv0
4327 fac2 = (dc_vap * log(tem / t_ice) + fac1) / rvgas
4328 esh20 = e00 * exp(fac2)
4329 if (i <= 200) then
4330 esupc(i) = esh20
4331 else
4332 table(i + 1400) = esh20
4333 endif
4334 enddo
4335
4336 ! -----------------------------------------------------------------------
4337 ! derive blended es over ice and supercooled water between - 20 deg c and 0 deg c
4338 ! -----------------------------------------------------------------------
4339
4340 do i = 1, 200
4341 tem = 253.16 + delt * real(i - 1)
4342 wice = 0.05 * (table_ice - tem)
4343 wh2o = 0.05 * (tem - 253.16)
4344 table(i + 1400) = wice * table(i + 1400) + wh2o * esupc(i)
4345 enddo
4346
4347end subroutine qs_table
4348
4349! =======================================================================
4350! compute the saturated specific humidity and the gradient of saturated specific humidity
4351! input t in deg k, p in pa; p = rho rdry tv, moist pressure
4355!@details It als oincludes the option for computing des/dT.
4356subroutine qsmith (im, km, ks, t, p, q, qs, dqdt)
4357
4358 implicit none
4359
4360 integer, intent (in) :: im, km, ks
4361
4362 real, intent (in), dimension (im, km) :: t, p, q
4363
4364 real, intent (out), dimension (im, km) :: qs
4365
4366 real, intent (out), dimension (im, km), optional :: dqdt
4367
4368 real :: eps10, ap1, tmin
4369
4370 real, dimension (im, km) :: es
4371
4372 integer :: i, k, it
4373
4374 tmin = table_ice - 160.
4375 eps10 = 10. * eps
4376
4377 if (.not. tables_are_initialized) then
4378 call qsmith_init
4379 endif
4380
4381 do k = ks, km
4382 do i = 1, im
4383 ap1 = 10. * dim(t(i, k), tmin) + 1.
4384 ap1 = min(2621., ap1)
4385 it = ap1
4386 es(i, k) = table(it) + (ap1 - it) * des(it)
4387 qs(i, k) = eps * es(i, k) * (1. + zvir * q(i, k)) / p(i, k)
4388 enddo
4389 enddo
4390
4391 if (present (dqdt)) then
4392 do k = ks, km
4393 do i = 1, im
4394 ap1 = 10. * dim(t(i, k), tmin) + 1.
4395 ap1 = min(2621., ap1) - 0.5
4396 it = ap1
4397 dqdt(i, k) = eps10 * (des(it) + (ap1 - it) * (des(it + 1) - des(it))) * (1. + zvir * q(i, k)) / p(i, k)
4398 enddo
4399 enddo
4400 endif
4401
4402end subroutine qsmith
4403
4404! =======================================================================
4408subroutine neg_adj (ktop, kbot, pt, dp, qv, ql, qr, qi, qs, qg)
4409
4410 implicit none
4411
4412 integer, intent (in) :: ktop, kbot
4413
4414 real, intent (in), dimension (ktop:kbot) :: dp
4415
4416 real, intent (inout), dimension (ktop:kbot) :: pt, qv, ql, qr, qi, qs, qg
4417
4418 real, dimension (ktop:kbot) :: lcpk, icpk
4419
4420 real :: dq, cvm
4421
4422 integer :: k
4423
4424 ! -----------------------------------------------------------------------
4425 ! define heat capacity and latent heat coefficient
4426 ! -----------------------------------------------------------------------
4427
4428 do k = ktop, kbot
4429 cvm = c_air + qv(k) * c_vap + (qr(k) + ql(k)) * c_liq + (qi(k) + qs(k) + qg(k)) * c_ice
4430 lcpk(k) = (lv00 + d0_vap * pt(k)) / cvm
4431 icpk(k) = (li00 + dc_ice * pt(k)) / cvm
4432 enddo
4433
4434 do k = ktop, kbot
4435
4436 ! -----------------------------------------------------------------------
4437 ! ice phase:
4438 ! -----------------------------------------------------------------------
4439
4440 ! if cloud ice < 0, borrow from snow
4441 if (qi(k) < 0.) then
4442 qs(k) = qs(k) + qi(k)
4443 qi(k) = 0.
4444 endif
4445 ! if snow < 0, borrow from graupel
4446 if (qs(k) < 0.) then
4447 qg(k) = qg(k) + qs(k)
4448 qs(k) = 0.
4449 endif
4450 ! if graupel < 0, borrow from rain
4451 if (qg(k) < 0.) then
4452 qr(k) = qr(k) + qg(k)
4453 pt(k) = pt(k) - qg(k) * icpk(k) ! heating
4454 qg(k) = 0.
4455 endif
4456
4457 ! -----------------------------------------------------------------------
4458 ! liquid phase:
4459 ! -----------------------------------------------------------------------
4460
4461 ! if rain < 0, borrow from cloud water
4462 if (qr(k) < 0.) then
4463 ql(k) = ql(k) + qr(k)
4464 qr(k) = 0.
4465 endif
4466 ! if cloud water < 0, borrow from water vapor
4467 if (ql(k) < 0.) then
4468 qv(k) = qv(k) + ql(k)
4469 pt(k) = pt(k) - ql(k) * lcpk(k) ! heating
4470 ql(k) = 0.
4471 endif
4472
4473 enddo
4474
4475 ! -----------------------------------------------------------------------
4476 ! fix water vapor; borrow from below
4477 ! -----------------------------------------------------------------------
4478
4479 do k = ktop, kbot - 1
4480 if (qv(k) < 0.) then
4481 qv(k + 1) = qv(k + 1) + qv(k) * dp(k) / dp(k + 1)
4482 qv(k) = 0.
4483 endif
4484 enddo
4485
4486 ! -----------------------------------------------------------------------
4487 ! bottom layer; borrow from above
4488 ! -----------------------------------------------------------------------
4489
4490 if (qv(kbot) < 0. .and. qv(kbot - 1) > 0.) then
4491 dq = min(- qv(kbot) * dp(kbot), qv(kbot - 1) * dp(kbot - 1))
4492 qv(kbot - 1) = qv(kbot - 1) - dq / dp(kbot - 1)
4493 qv(kbot) = qv(kbot) + dq / dp(kbot)
4494 endif
4495
4496end subroutine neg_adj
4497
4498! =======================================================================
4499! compute global sum
4501! =======================================================================
4502
4503!real function g_sum (p, ifirst, ilast, jfirst, jlast, area, mode)
4504!
4505! use mpp_mod, only: mpp_sum
4506!
4507! implicit none
4508!
4509! integer, intent (in) :: ifirst, ilast, jfirst, jlast
4510! integer, intent (in) :: mode ! if == 1 divided by area
4511!
4512! real, intent (in), dimension (ifirst:ilast, jfirst:jlast) :: p, area
4513!
4514! integer :: i, j
4515!
4516! real :: gsum
4517!
4518! if (global_area < 0.) then
4519! global_area = 0.
4520! do j = jfirst, jlast
4521! do i = ifirst, ilast
4522! global_area = global_area + area (i, j)
4523! enddo
4524! enddo
4525! call mpp_sum (global_area)
4526! endif
4527!
4528! gsum = 0.
4529! do j = jfirst, jlast
4530! do i = ifirst, ilast
4531! gsum = gsum + p (i, j) * area (i, j)
4532! enddo
4533! enddo
4534! call mpp_sum (gsum)
4535!
4536! if (mode == 1) then
4537! g_sum = gsum / global_area
4538! else
4539! g_sum = gsum
4540! endif
4541!
4542!end function g_sum
4543
4544! ==========================================================================
4547subroutine interpolate_z (is, ie, js, je, km, zl, hgt, a3, a2)
4548
4549 implicit none
4550
4551 integer, intent (in) :: is, ie, js, je, km
4552
4553 real, intent (in), dimension (is:ie, js:je, km) :: a3
4554
4555 real, intent (in), dimension (is:ie, js:je, km + 1) :: hgt ! hgt (k) > hgt (k + 1)
4556
4557 real, intent (in) :: zl
4558
4559 real, intent (out), dimension (is:ie, js:je) :: a2
4560
4561 real, dimension (km) :: zm
4562
4563 integer :: i, j, k
4564
4565 !$omp parallel do default (none) shared (is, ie, js, je, km, hgt, zl, a2, a3) private (zm)
4566
4567 do j = js, je
4568 do i = is, ie
4569 do k = 1, km
4570 zm(k) = 0.5 * (hgt(i, j, k) + hgt(i, j, k + 1))
4571 enddo
4572 if (zl >= zm(1)) then
4573 a2(i, j) = a3(i, j, 1)
4574 elseif (zl <= zm(km)) then
4575 a2(i, j) = a3(i, j, km)
4576 else
4577 do k = 1, km - 1
4578 if (zl <= zm(k) .and. zl >= zm(k + 1)) then
4579 a2(i, j) = a3(i, j, k) + (a3(i, j, k + 1) - a3(i, j, k)) * (zm(k) - zl) / (zm(k) - zm(k + 1))
4580 exit
4581 endif
4582 enddo
4583 endif
4584 enddo
4585 enddo
4586
4587end subroutine interpolate_z
4588
4589! =======================================================================
4594! =======================================================================
4595subroutine cloud_diagnosis (is, ie, ks, ke, den, delp, lsm, qmw, qmi, qmr, qms, qmg, t, &
4596 rew, rei, rer, res, reg)
4597
4598 implicit none
4599
4600 integer, intent (in) :: is, ie, ks, ke
4601 integer, intent (in), dimension (is:ie) :: lsm ! land sea mask, 0: ocean, 1: land, 2: sea ice
4602
4603 real, intent (in), dimension (is:ie, ks:ke) :: den, delp, t
4604 real, intent (in), dimension (is:ie, ks:ke) :: qmw, qmi, qmr, qms, qmg
4605
4606 real, intent (out), dimension (is:ie, ks:ke) :: rew, rei, rer, res, reg
4607
4608 real, dimension (is:ie, ks:ke) :: qcw, qci, qcr, qcs, qcg
4609
4610 integer :: i, k
4611
4612 real :: lambdar, lambdas, lambdag
4613 real :: dpg, rei_fac, mask, ccn, bw
4614 real, parameter :: rho_0 = 50.e-3
4615
4616 real :: rhow = 1.0e3, rhor = 1.0e3, rhos = 1.0e2, rhog = 4.0e2
4617 real :: n0r = 8.0e6, n0s = 3.0e6, n0g = 4.0e6
4618 real :: alphar = 0.8, alphas = 0.25, alphag = 0.5
4619 real :: gammar = 17.837789, gammas = 8.2850630, gammag = 11.631769
4620 real :: qmin = 1.0e-12, beta = 1.22, qmin1 = 9.e-6
4621
4622 do k = ks, ke
4623 do i = is, ie
4624
4625 dpg = abs(delp(i, k)) / grav
4626 mask = min(max(real(lsm(i)), 0.0), 2.0)
4627
4628 ! -----------------------------------------------------------------------
4629 ! cloud water (Martin et al., 1994)
4630 ! -----------------------------------------------------------------------
4631
4632 ccn = 0.80 * (- 1.15e-3 * (ccn_o ** 2) + 0.963 * ccn_o + 5.30) * abs(mask - 1.0) + &
4633 0.67 * (- 2.10e-4 * (ccn_l ** 2) + 0.568 * ccn_l - 27.9) * (1.0 - abs(mask - 1.0))
4634
4635 if (qmw(i, k) .gt. qmin) then
4636 qcw(i, k) = dpg * qmw(i, k) * 1.0e3
4637 rew(i, k) = exp(1.0 / 3.0 * log((3.0 * den(i, k) * qmw(i, k)) / (4.0 * pi * rhow * ccn))) * 1.0e4
4638 rew(i, k) = max(rewmin, min(rewmax, rew(i, k)))
4639 else
4640 qcw(i, k) = 0.0
4641 rew(i, k) = rewmin
4642 endif
4643
4644 if (reiflag .eq. 1) then
4645
4646 ! -----------------------------------------------------------------------
4647 ! cloud ice (Heymsfield and Mcfarquhar, 1996)
4648 ! -----------------------------------------------------------------------
4649
4650 if (qmi(i, k) .gt. qmin1) then
4651 qci(i, k) = dpg * qmi(i, k) * 1.0e3
4652 rei_fac = log(1.0e3 * qmi(i, k) * den(i, k))
4653 if (t(i, k) - tice .lt. - 50) then
4654 rei(i, k) = beta / 9.917 * exp(0.109 * rei_fac) * 1.0e3
4655 elseif (t(i, k) - tice .lt. - 40) then
4656 rei(i, k) = beta / 9.337 * exp(0.080 * rei_fac) * 1.0e3
4657 elseif (t(i, k) - tice .lt. - 30) then
4658 rei(i, k) = beta / 9.208 * exp(0.055 * rei_fac) * 1.0e3
4659 else
4660 rei(i, k) = beta / 9.387 * exp(0.031 * rei_fac) * 1.0e3
4661 endif
4662 rei(i, k) = max(reimin, min(reimax, rei(i, k)))
4663 else
4664 qci(i, k) = 0.0
4665 rei(i, k) = reimin
4666 endif
4667
4668 endif
4669
4670 if (reiflag .eq. 2) then
4671
4672 ! -----------------------------------------------------------------------
4673 ! cloud ice (Wyser, 1998)
4674 ! -----------------------------------------------------------------------
4675
4676 if (qmi(i, k) .gt. qmin1) then
4677 qci(i, k) = dpg * qmi(i, k) * 1.0e3
4678 bw = - 2. + 1.e-3 * log10(den(i, k) * qmi(i, k) / rho_0) * max(0.0, tice - t(i, k)) ** 1.5
4679 rei(i, k) = 377.4 + bw * (203.3 + bw * (37.91 + 2.3696 * bw))
4680 rei(i, k) = max(reimin, min(reimax, rei(i, k)))
4681 else
4682 qci(i, k) = 0.0
4683 rei(i, k) = reimin
4684 endif
4685
4686 endif
4687
4688 ! -----------------------------------------------------------------------
4689 ! rain (Lin et al., 1983)
4690 ! -----------------------------------------------------------------------
4691
4692 if (qmr(i, k) .gt. qmin) then
4693 qcr(i, k) = dpg * qmr(i, k) * 1.0e3
4694 lambdar = exp(0.25 * log(pi * rhor * n0r / qmr(i, k) / den(i, k)))
4695 rer(i, k) = 0.5 * exp(log(gammar / 6) / alphar) / lambdar * 1.0e6
4696 rer(i, k) = max(rermin, min(rermax, rer(i, k)))
4697 else
4698 qcr(i, k) = 0.0
4699 rer(i, k) = rermin
4700 endif
4701
4702 ! -----------------------------------------------------------------------
4703 ! snow (Lin et al., 1983)
4704 ! -----------------------------------------------------------------------
4705
4706 if (qms(i, k) .gt. qmin1) then
4707 qcs(i, k) = dpg * qms(i, k) * 1.0e3
4708 lambdas = exp(0.25 * log(pi * rhos * n0s / qms(i, k) / den(i, k)))
4709 res(i, k) = 0.5 * exp(log(gammas / 6) / alphas) / lambdas * 1.0e6
4710 res(i, k) = max(resmin, min(resmax, res(i, k)))
4711 else
4712 qcs(i, k) = 0.0
4713 res(i, k) = resmin
4714 endif
4715
4716 ! -----------------------------------------------------------------------
4717 ! graupel (Lin et al., 1983)
4718 ! -----------------------------------------------------------------------
4719
4720 if (qmg(i, k) .gt. qmin) then
4721 qcg(i, k) = dpg * qmg(i, k) * 1.0e3
4722 lambdag = exp(0.25 * log(pi * rhog * n0g / qmg(i, k) / den(i, k)))
4723 reg(i, k) = 0.5 * exp(log(gammag / 6) / alphag) / lambdag * 1.0e6
4724 reg(i, k) = max(regmin, min(regmax, reg(i, k)))
4725 else
4726 qcg(i, k) = 0.0
4727 reg(i, k) = regmin
4728 endif
4729
4730 enddo
4731 enddo
4732
4733end subroutine cloud_diagnosis
4734
4735!+---+-----------------------------------------------------------------+
4738 subroutine refl10cm_gfdl (qv1d, qr1d, qs1d, qg1d, &
4739 t1d, p1d, dBZ, kts, kte, ii, jj, melti)
4740
4741 IMPLICIT NONE
4742
4743!..Sub arguments
4744 INTEGER, INTENT(IN):: kts, kte, ii,jj
4745 REAL, DIMENSION(kts:kte), INTENT(IN):: &
4746 qv1d, qr1d, qs1d, qg1d, t1d, p1d
4747 REAL, DIMENSION(kts:kte), INTENT(INOUT):: dbz
4748
4749!..Local variables
4750 REAL, DIMENSION(kts:kte):: temp, pres, qv, rho
4751 REAL, DIMENSION(kts:kte):: rr, rs, rg
4752! REAL:: temp_C
4753
4754 DOUBLE PRECISION, DIMENSION(kts:kte):: ilamr, ilams, ilamg
4755 DOUBLE PRECISION, DIMENSION(kts:kte):: n0_r, n0_s, n0_g
4756 DOUBLE PRECISION:: lamr, lams, lamg
4757 LOGICAL, DIMENSION(kts:kte):: l_qr, l_qs, l_qg
4758
4759 REAL, DIMENSION(kts:kte):: ze_rain, ze_snow, ze_graupel
4760 DOUBLE PRECISION:: fmelt_s, fmelt_g
4761
4762 INTEGER:: i, k, k_0, kbot, n
4763 LOGICAL, INTENT(IN):: melti
4764 DOUBLE PRECISION:: cback, x, eta, f_d
4765!+---+
4766
4767 do k = kts, kte
4768 dbz(k) = -35.0
4769 enddo
4770
4771!+---+-----------------------------------------------------------------+
4772!..Put column of data into local arrays.
4773!+---+-----------------------------------------------------------------+
4774 do k = kts, kte
4775 temp(k) = t1d(k)
4776! temp_C = min(-0.001, temp(K)-273.15)
4777 qv(k) = max(1.e-10, qv1d(k))
4778 pres(k) = p1d(k)
4779 rho(k) = 0.622*pres(k)/(rdgas*temp(k)*(qv(k)+0.622))
4780
4781 if (qr1d(k) .gt. 1.e-9) then
4782 rr(k) = qr1d(k)*rho(k)
4783 n0_r(k) = n0r
4784 lamr = (xam_r*xcrg(3)*n0_r(k)/rr(k))**(1./xcre(1))
4785 ilamr(k) = 1./lamr
4786 l_qr(k) = .true.
4787 else
4788 rr(k) = 1.e-12
4789 l_qr(k) = .false.
4790 endif
4791
4792 if (qs1d(k) .gt. 1.e-9) then
4793 rs(k) = qs1d(k)*rho(k)
4794 n0_s(k) = n0s
4795 lams = (xam_s*xcsg(3)*n0_s(k)/rs(k))**(1./xcse(1))
4796 ilams(k) = 1./lams
4797 l_qs(k) = .true.
4798 else
4799 rs(k) = 1.e-12
4800 l_qs(k) = .false.
4801 endif
4802
4803 if (qg1d(k) .gt. 1.e-9) then
4804 rg(k) = qg1d(k)*rho(k)
4805 n0_g(k) = n0g
4806 lamg = (xam_g*xcgg(3)*n0_g(k)/rg(k))**(1./xcge(1))
4807 ilamg(k) = 1./lamg
4808 l_qg(k) = .true.
4809 else
4810 rg(k) = 1.e-12
4811 l_qg(k) = .false.
4812 endif
4813 enddo
4814
4815!+---+-----------------------------------------------------------------+
4816!..Locate K-level of start of melting (k_0 is level above).
4817!+---+-----------------------------------------------------------------+
4818 k_0 = kts
4819 k_loop:do k = kte-1, kts, -1
4820 if ( melti .and. (temp(k).gt.273.15) .and. l_qr(k) &
4821 .and. (l_qs(k+1).or.l_qg(k+1)) ) then
4822 k_0 = max(k+1, k_0)
4823 EXIT k_loop
4824 endif
4825 enddo k_loop
4826!+---+-----------------------------------------------------------------+
4827!..Assume Rayleigh approximation at 10 cm wavelength. Rain (all temps)
4828!.. and non-water-coated snow and graupel when below freezing are
4829!.. simple. Integrations of m(D)*m(D)*N(D)*dD.
4830!+---+-----------------------------------------------------------------+
4831 do k = kts, kte
4832 ze_rain(k) = 1.e-22
4833 ze_snow(k) = 1.e-22
4834 ze_graupel(k) = 1.e-22
4835 if (l_qr(k)) ze_rain(k) = n0_r(k)*xcrg(4)*ilamr(k)**xcre(4)
4836 if (l_qs(k)) ze_snow(k) = (0.176/0.93) * (6.0/pi)*(6.0/pi) &
4837 * (xam_s/900.0)*(xam_s/900.0) &
4838 * n0_s(k)*xcsg(4)*ilams(k)**xcse(4)
4839 if (l_qg(k)) ze_graupel(k) = (0.176/0.93) * (6.0/pi)*(6.0/pi) &
4840 * (xam_g/900.0)*(xam_g/900.0) &
4841 * n0_g(k)*xcgg(4)*ilamg(k)**xcge(4)
4842 enddo
4843
4844
4845!+---+-----------------------------------------------------------------+
4846!..Special case of melting ice (snow/graupel) particles. Assume the
4847!.. ice is surrounded by the liquid water. Fraction of meltwater is
4848!.. extremely simple based on amount found above the melting level.
4849!.. Uses code from Uli Blahak (rayleigh_soak_wetgraupel and supporting
4850!.. routines).
4851!+---+-----------------------------------------------------------------+
4852
4853 if (melti .and. k_0.ge.kts+1) then
4854 do k = k_0-1, kts, -1
4855
4856!..Reflectivity contributed by melting snow
4857 if (l_qs(k) .and. l_qs(k_0) ) then
4858 fmelt_s = max(0.005d0, min(1.0d0-rs(k)/rs(k_0), 0.99d0))
4859 eta = 0.d0
4860 lams = 1./ilams(k)
4861 do n = 1, nrbins
4862 x = xam_s * xxds(n)**xbm_s
4863 call rayleigh_soak_wetgraupel (x,dble(xocms),dble(xobms), &
4864 fmelt_s, melt_outside_s, m_w_0, m_i_0, lamda_radar, &
4865 cback, mixingrulestring_s, matrixstring_s, &
4866 inclusionstring_s, hoststring_s, &
4867 hostmatrixstring_s, hostinclusionstring_s)
4868 f_d = n0_s(k)*xxds(n)**xmu_s * dexp(-lams*xxds(n))
4869 eta = eta + f_d * cback * simpson(n) * xdts(n)
4870 enddo
4871 ze_snow(k) = sngl(lamda4 / (pi5 * k_w) * eta)
4872 endif
4873
4874
4875!..Reflectivity contributed by melting graupel
4876
4877 if (l_qg(k) .and. l_qg(k_0) ) then
4878 fmelt_g = max(0.005d0, min(1.0d0-rg(k)/rg(k_0), 0.99d0))
4879 eta = 0.d0
4880 lamg = 1./ilamg(k)
4881 do n = 1, nrbins
4882 x = xam_g * xxdg(n)**xbm_g
4883 call rayleigh_soak_wetgraupel (x,dble(xocmg),dble(xobmg), &
4884 fmelt_g, melt_outside_g, m_w_0, m_i_0, lamda_radar, &
4885 cback, mixingrulestring_g, matrixstring_g, &
4886 inclusionstring_g, hoststring_g, &
4887 hostmatrixstring_g, hostinclusionstring_g)
4888 f_d = n0_g(k)*xxdg(n)**xmu_g * dexp(-lamg*xxdg(n))
4889 eta = eta + f_d * cback * simpson(n) * xdtg(n)
4890 enddo
4891 ze_graupel(k) = sngl(lamda4 / (pi5 * k_w) * eta)
4892 endif
4893
4894 enddo
4895 endif
4896
4897 do k = kte, kts, -1
4898 dbz(k) = 10.*log10((ze_rain(k)+ze_snow(k)+ze_graupel(k))*1.d18)
4899 enddo
4900
4901
4902 end subroutine refl10cm_gfdl
4903!+---+-----------------------------------------------------------------+
4904
4905end module gfdl_cloud_microphys_mod
subroutine, public cloud_diagnosis(is, ie, ks, ke, den, delp, lsm, qmw, qmi, qmr, qms, qmg, t, rew, rei, rer, res, reg)
The subroutine 'cloud_diagnosis' diagnoses the radius of cloud species.
subroutine, public gfdl_cloud_microphys_mod_end()
The subroutine 'gfdl_cloud_microphys_init' terminates the GFDL cloud microphysics.
subroutine, public gfdl_cloud_microphys_mod_driver(iis, iie, jjs, jje, kks, kke, ktop, kbot, qv, ql, qr, qi, qs, qg, qa, qn, qv_dt, ql_dt, qr_dt, qi_dt, qs_dt, qg_dt, qa_dt, pt_dt, pt, w, uin, vin, udt, vdt, dz, delp, area, dt_in, land, rain, snow, ice, graupel, hydrostatic, phys_hydrostatic, p, lradar, refl_10cm, reset, pfils, pflls)
This subroutine is the driver of the GFDL cloud microphysics.
subroutine, public gfdl_cloud_microphys_mod_init(me, master, nlunit, input_nml_file, logunit, fn_nml, errmsg, errflg)
The subroutine 'gfdl_cloud_microphys_init' initializes the GFDL cloud microphysics.
This module contains the column GFDL Cloud microphysics scheme.
This module is more library code whereas the individual microphysics schemes contains specific detail...