CCPP SciDoc v7.0.x  v7.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 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 goto 555
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 goto 555
2866 endif
2867 enddo
2868 endif
2869 goto 555
2870 endif
2871 endif
2872 enddo
2873 555 continue
2874 enddo
2875
2876 m1(ktop) = q(ktop) - qm(ktop)
2877 do k = ktop + 1, kbot
2878 m1(k) = m1(k - 1) + q(k) - qm(k)
2879 enddo
2880 precip = m1(kbot)
2881
2882 ! convert back to * dry * mixing ratio:
2883 ! dp must be dry air_mass (because moist air mass will be changed due to terminal fall) .
2884
2885 do k = ktop, kbot
2886 q(k) = qm(k) / dp(k)
2887 enddo
2888
2889end subroutine lagrangian_fall_ppm
2890
2892subroutine cs_profile (a4, del, km, do_mono)
2893
2894 implicit none
2895
2896 integer, intent (in) :: km ! vertical dimension
2897
2898 real, intent (in) :: del (km)
2899
2900 logical, intent (in) :: do_mono
2901
2902 real, intent (inout) :: a4 (4, km)
2903
2904 real, parameter :: qp_min = 1.e-6
2905
2906 real :: gam (km)
2907 real :: q (km + 1)
2908 real :: d4, bet, a_bot, grat, pmp, lac
2909 real :: pmp_1, lac_1, pmp_2, lac_2
2910 real :: da1, da2, a6da
2911
2912 integer :: k
2913
2914 logical extm (km)
2915
2916 grat = del(2) / del(1) ! grid ratio
2917 bet = grat * (grat + 0.5)
2918 q(1) = (2. * grat * (grat + 1.) * a4(1, 1) + a4(1, 2)) / bet
2919 gam(1) = (1. + grat * (grat + 1.5)) / bet
2920
2921 do k = 2, km
2922 d4 = del(k - 1) / del(k)
2923 bet = 2. + 2. * d4 - gam(k - 1)
2924 q(k) = (3. * (a4(1, k - 1) + d4 * a4(1, k)) - q(k - 1)) / bet
2925 gam(k) = d4 / bet
2926 enddo
2927
2928 a_bot = 1. + d4 * (d4 + 1.5)
2929 q(km + 1) = (2. * d4 * (d4 + 1.) * a4(1, km) + a4(1, km - 1) - a_bot * q(km)) &
2930 / (d4 * (d4 + 0.5) - a_bot * gam(km))
2931
2932 do k = km, 1, - 1
2933 q(k) = q(k) - gam(k) * q(k + 1)
2934 enddo
2935
2936 ! -----------------------------------------------------------------------
2937 ! apply constraints
2938 ! -----------------------------------------------------------------------
2939
2940 do k = 2, km
2941 gam(k) = a4(1, k) - a4(1, k - 1)
2942 enddo
2943
2944 ! -----------------------------------------------------------------------
2945 ! apply large - scale constraints to all fields if not local max / min
2946 ! -----------------------------------------------------------------------
2947
2948 ! -----------------------------------------------------------------------
2949 ! top:
2950 ! -----------------------------------------------------------------------
2951
2952 q(1) = max(q(1), 0.)
2953 q(2) = min(q(2), max(a4(1, 1), a4(1, 2)))
2954 q(2) = max(q(2), min(a4(1, 1), a4(1, 2)), 0.)
2955
2956 ! -----------------------------------------------------------------------
2957 ! interior:
2958 ! -----------------------------------------------------------------------
2959
2960 do k = 3, km - 1
2961 if (gam(k - 1) * gam(k + 1) > 0.) then
2962 q(k) = min(q(k), max(a4(1, k - 1), a4(1, k)))
2963 q(k) = max(q(k), min(a4(1, k - 1), a4(1, k)))
2964 else
2965 if (gam(k - 1) > 0.) then
2966 ! there exists a local max
2967 q(k) = max(q(k), min(a4(1, k - 1), a4(1, k)))
2968 else
2969 ! there exists a local min
2970 q(k) = min(q(k), max(a4(1, k - 1), a4(1, k)))
2971 q(k) = max(q(k), 0.0)
2972 endif
2973 endif
2974 enddo
2975
2976 ! -----------------------------------------------------------------------
2977 ! bottom :
2978 ! -----------------------------------------------------------------------
2979
2980 q(km) = min(q(km), max(a4(1, km - 1), a4(1, km)))
2981 q(km) = max(q(km), min(a4(1, km - 1), a4(1, km)), 0.)
2982 ! q (km + 1) = max (q (km + 1), 0.)
2983
2984 ! -----------------------------------------------------------------------
2985 ! f (s) = al + s * [ (ar - al) + a6 * (1 - s) ] (0 <= s <= 1)
2986 ! -----------------------------------------------------------------------
2987
2988 do k = 1, km - 1
2989 a4(2, k) = q(k)
2990 a4(3, k) = q(k + 1)
2991 enddo
2992
2993 do k = 2, km - 1
2994 if (gam(k) * gam(k + 1) > 0.0) then
2995 extm(k) = .false.
2996 else
2997 extm(k) = .true.
2998 endif
2999 enddo
3000
3001 if (do_mono) then
3002 do k = 3, km - 2
3003 if (extm(k)) then
3004 ! positive definite constraint only if true local extrema
3005 if (a4(1, k) < qp_min .or. extm(k - 1) .or. extm(k + 1)) then
3006 a4(2, k) = a4(1, k)
3007 a4(3, k) = a4(1, k)
3008 endif
3009 else
3010 a4(4, k) = 6. * a4(1, k) - 3. * (a4(2, k) + a4(3, k))
3011 if (abs(a4(4, k)) > abs(a4(2, k) - a4(3, k))) then
3012 ! check within the smooth region if subgrid profile is non - monotonic
3013 pmp_1 = a4(1, k) - 2.0 * gam(k + 1)
3014 lac_1 = pmp_1 + 1.5 * gam(k + 2)
3015 a4(2, k) = min(max(a4(2, k), min(a4(1, k), pmp_1, lac_1)), &
3016 max(a4(1, k), pmp_1, lac_1))
3017 pmp_2 = a4(1, k) + 2.0 * gam(k)
3018 lac_2 = pmp_2 - 1.5 * gam(k - 1)
3019 a4(3, k) = min(max(a4(3, k), min(a4(1, k), pmp_2, lac_2)), &
3020 max(a4(1, k), pmp_2, lac_2))
3021 endif
3022 endif
3023 enddo
3024 else
3025 do k = 3, km - 2
3026 if (extm(k)) then
3027 if (a4(1, k) < qp_min .or. extm(k - 1) .or. extm(k + 1)) then
3028 a4(2, k) = a4(1, k)
3029 a4(3, k) = a4(1, k)
3030 endif
3031 endif
3032 enddo
3033 endif
3034
3035 do k = 1, km - 1
3036 a4(4, k) = 6. * a4(1, k) - 3. * (a4(2, k) + a4(3, k))
3037 enddo
3038
3039 k = km - 1
3040 if (extm(k)) then
3041 a4(2, k) = a4(1, k)
3042 a4(3, k) = a4(1, k)
3043 a4(4, k) = 0.
3044 else
3045 da1 = a4(3, k) - a4(2, k)
3046 da2 = da1 ** 2
3047 a6da = a4(4, k) * da1
3048 if (a6da < - da2) then
3049 a4(4, k) = 3. * (a4(2, k) - a4(1, k))
3050 a4(3, k) = a4(2, k) - a4(4, k)
3051 elseif (a6da > da2) then
3052 a4(4, k) = 3. * (a4(3, k) - a4(1, k))
3053 a4(2, k) = a4(3, k) - a4(4, k)
3054 endif
3055 endif
3056
3057 call cs_limiters (km - 1, a4)
3058
3059 ! -----------------------------------------------------------------------
3060 ! bottom layer:
3061 ! -----------------------------------------------------------------------
3062
3063 a4(2, km) = a4(1, km)
3064 a4(3, km) = a4(1, km)
3065 a4(4, km) = 0.
3066
3067end subroutine cs_profile
3068
3071subroutine cs_limiters (km, a4)
3072
3073 implicit none
3074
3075 integer, intent (in) :: km
3076
3077 real, intent (inout) :: a4 (4, km) ! ppm array
3078
3079 real, parameter :: r12 = 1. / 12.
3080
3081 integer :: k
3082
3083 ! -----------------------------------------------------------------------
3084 ! positive definite constraint
3085 ! -----------------------------------------------------------------------
3086
3087 do k = 1, km
3088 if (abs(a4(3, k) - a4(2, k)) < - a4(4, k)) then
3089 if ((a4(1, k) + 0.25 * (a4(3, k) - a4(2, k)) ** 2 / a4(4, k) + a4(4, k) * r12) < 0.) then
3090 if (a4(1, k) < a4(3, k) .and. a4(1, k) < a4(2, k)) then
3091 a4(3, k) = a4(1, k)
3092 a4(2, k) = a4(1, k)
3093 a4(4, k) = 0.
3094 elseif (a4(3, k) > a4(2, k)) then
3095 a4(4, k) = 3. * (a4(2, k) - a4(1, k))
3096 a4(3, k) = a4(2, k) - a4(4, k)
3097 else
3098 a4(4, k) = 3. * (a4(3, k) - a4(1, k))
3099 a4(2, k) = a4(3, k) - a4(4, k)
3100 endif
3101 endif
3102 endif
3103 enddo
3104
3105end subroutine cs_limiters
3106
3107! =======================================================================
3110subroutine fall_speed (ktop, kbot, den, qs, qi, qg, ql, tk, vts, vti, vtg)
3111
3112 implicit none
3113
3114 integer, intent (in) :: ktop, kbot
3115
3116 real, intent (in), dimension (ktop:kbot) :: den, qs, qi, qg, ql, tk
3117 real, intent (out), dimension (ktop:kbot) :: vts, vti, vtg
3118
3119 ! fall velocity constants:
3120
3121 real, parameter :: thi = 1.0e-8
3122 real, parameter :: thg = 1.0e-8
3123 real, parameter :: ths = 1.0e-8
3124
3125 ! coefficient for the parameterization of mass weighted fall velocity
3126 ! as a function of temperature and IWC.
3127 ! Table 1 in Deng and Mace (2008) \cite deng_and_mace_2008.
3128 real, parameter :: aa = - 4.14122e-5
3129 real, parameter :: bb = - 0.00538922
3130 real, parameter :: cc = - 0.0516344
3131 real, parameter :: dd = 0.00216078
3132 real, parameter :: ee = 1.9714
3133
3134 ! marshall - palmer constants
3135
3136 real, parameter :: vcons = 6.6280504
3137 real, parameter :: vcong = 87.2382675
3138 real, parameter :: vconh = vcong * sqrt(rhoh / rhog)
3139 real, parameter :: norms = 942477796.076938
3140 real, parameter :: normg = 5026548245.74367
3141 real, parameter :: normh = pi * rhoh * rnzh
3142
3143 real, dimension (ktop:kbot) :: qden, tc, rhof
3144
3145 real :: vi0
3146
3147 integer :: k
3148
3149 ! -----------------------------------------------------------------------
3150 ! marshall - palmer formula
3151 ! -----------------------------------------------------------------------
3152
3153 ! -----------------------------------------------------------------------
3154 ! try the local air density -- for global model; the true value could be
3155 ! much smaller than sfcrho over high mountains
3156 ! -----------------------------------------------------------------------
3157
3158 do k = ktop, kbot
3159 rhof(k) = sqrt(min(10., sfcrho / den(k)))
3160 enddo
3161
3162 ! -----------------------------------------------------------------------
3165 ! -----------------------------------------------------------------------
3166
3167 if (const_vi) then
3168 vti(:) = vi_fac
3169 else
3170 ! -----------------------------------------------------------------------
3171 ! use deng and mace (2008, grl), which gives smaller fall speed than hd90 formula
3172 ! -----------------------------------------------------------------------
3173 vi0 = 0.01 * vi_fac
3174 do k = ktop, kbot
3175 if (qi(k) < thi) then ! this is needed as the fall - speed maybe problematic for small qi
3176 vti(k) = vf_min
3177 else
3178 tc(k) = tk(k) - tice
3179 vti(k) = (3. + log10(qi(k) * den(k))) * (tc(k) * (aa * tc(k) + bb) + cc) + dd * tc(k) + ee
3180 vti(k) = vi0 * exp(log_10 * vti(k)) * 0.9
3181 vti(k) = min(vi_max, max(vf_min, vti(k)))
3182 endif
3183 enddo
3184 endif
3185
3186 ! -----------------------------------------------------------------------
3188 ! -----------------------------------------------------------------------
3189
3190 if (const_vs) then
3191 vts(:) = vs_fac ! 1. ifs_2016
3192 else
3193 do k = ktop, kbot
3194 if (qs(k) < ths) then
3195 vts(k) = vf_min
3196 else
3197 vts(k) = vs_fac * vcons * rhof(k) * exp(0.0625 * log(qs(k) * den(k) / norms))
3198 vts(k) = min(vs_max, max(vf_min, vts(k)))
3199 endif
3200 enddo
3201 endif
3202
3203 ! -----------------------------------------------------------------------
3205 ! -----------------------------------------------------------------------
3206 if (const_vg) then
3207 vtg(:) = vg_fac ! 2.
3208 else
3209 if (do_hail) then
3210 do k = ktop, kbot
3211 if (qg(k) < thg) then
3212 vtg(k) = vf_min
3213 else
3214 vtg(k) = vg_fac * vconh * rhof(k) * sqrt(sqrt(sqrt(qg(k) * den(k) / normh)))
3215 vtg(k) = min(vg_max, max(vf_min, vtg(k)))
3216 endif
3217 enddo
3218 else
3219 do k = ktop, kbot
3220 if (qg(k) < thg) then
3221 vtg(k) = vf_min
3222 else
3223 vtg(k) = vg_fac * vcong * rhof(k) * sqrt(sqrt(sqrt(qg(k) * den(k) / normg)))
3224 vtg(k) = min(vg_max, max(vf_min, vtg(k)))
3225 endif
3226 enddo
3227 endif
3228 endif
3229
3230end subroutine fall_speed
3231
3232! =======================================================================
3235subroutine setupm
3236
3237 implicit none
3238
3239 real :: gcon, cd, scm3, pisq, act (8)
3240 real :: vdifu, tcond
3241 real :: visk
3242 real :: ch2o, hltf
3243 real :: hlts, hltc, ri50
3244
3245 real, parameter :: gam263 = 1.456943, gam275 = 1.608355, gam290 = 1.827363, &
3246 gam325 = 2.54925, gam350 = 3.323363, gam380 = 4.694155, &
3247 gam425 = 8.285063, gam450 = 11.631769, gam480 = 17.837789, &
3248 gam625 = 184.860962, gam680 = 496.604067
3249
3250 ! intercept parameters
3251
3252! real, parameter :: rnzr = 8.0e6 ! lin83
3253! real, parameter :: rnzs = 3.0e6 ! lin83
3254! real, parameter :: rnzg = 4.0e6 ! rh84
3255
3256 ! density parameters
3257
3258! real, parameter :: rhos = 0.1e3 !< lin83 (snow density; 1 / 10 of water)
3259! real, parameter :: rhog = 0.4e3 !< rh84 (graupel density)
3260 real, parameter :: acc (3) = (/ 5.0, 2.0, 0.5 /)
3261
3262 real den_rc
3263
3264 integer :: i, k
3265
3266 pie = 4. * atan(1.0)
3267
3268 ! s. klein's formular (eq 16) from am2
3269
3270 fac_rc = (4. / 3.) * pie * rhor * rthresh ** 3
3271
3272 if (prog_ccn) then
3273 ! if (master) write (*, *) 'prog_ccn option is .t.'
3274 else
3275 den_rc = fac_rc * ccn_o * 1.e6
3276 ! if (master) write (*, *) 'mp: for ccn_o = ', ccn_o, 'ql_rc = ', den_rc
3277 den_rc = fac_rc * ccn_l * 1.e6
3278 ! if (master) write (*, *) 'mp: for ccn_l = ', ccn_l, 'ql_rc = ', den_rc
3279 endif
3280
3281 vdifu = 2.11e-5
3282 tcond = 2.36e-2
3283
3284 visk = 1.259e-5
3285 hlts = 2.8336e6
3286 hltc = 2.5e6
3287 hltf = 3.336e5
3288
3289 ch2o = 4.1855e3
3290 ri50 = 1.e-4
3291
3292 pisq = pie * pie
3293 scm3 = (visk / vdifu) ** (1. / 3.)
3294
3295 cracs = pisq * rnzr * rnzs * rhos
3296 csacr = pisq * rnzr * rnzs * rhor
3297 if (do_hail) then
3298 cgacr = pisq * rnzr * rnzh * rhor
3299 cgacs = pisq * rnzh * rnzs * rhos
3300 else
3301 cgacr = pisq * rnzr * rnzg * rhor
3302 cgacs = pisq * rnzg * rnzs * rhos
3303 endif
3304 cgacs = cgacs * c_pgacs
3305
3306 ! act: 1 - 2:racs (s - r) ; 3 - 4:sacr (r - s) ;
3307 ! 5 - 6:gacr (r - g) ; 7 - 8:gacs (s - g)
3308
3309 act(1) = pie * rnzs * rhos
3310 act(2) = pie * rnzr * rhor
3311 if (do_hail) then
3312 act(6) = pie * rnzh * rhoh
3313 else
3314 act(6) = pie * rnzg * rhog
3315 endif
3316 act(3) = act(2)
3317 act(4) = act(1)
3318 act(5) = act(2)
3319 act(7) = act(1)
3320 act(8) = act(6)
3321
3322 do i = 1, 3
3323 do k = 1, 4
3324 acco(i, k) = acc(i) / (act(2 * k - 1) ** ((7 - i) * 0.25) * act(2 * k) ** (i * 0.25))
3325 enddo
3326 enddo
3327
3328 gcon = 40.74 * sqrt(sfcrho) ! 44.628
3329
3330 csacw = pie * rnzs * clin * gam325 / (4. * act(1) ** 0.8125)
3331 ! decreasing csacw to reduce cloud water --- > snow
3332
3333 craci = pie * rnzr * alin * gam380 / (4. * act(2) ** 0.95)
3334 csaci = csacw * c_psaci
3335
3336 if (do_hail) then
3337 cgacw = pie * rnzh * gam350 * gcon / (4. * act(6) ** 0.875)
3338 else
3339 cgacw = pie * rnzg * gam350 * gcon / (4. * act(6) ** 0.875)
3340 endif
3341 ! cgaci = cgacw * 0.1
3342
3343 ! sjl, may 28, 2012
3344 cgaci = cgacw * 0.05
3345 ! sjl, may 28, 2012
3346
3347 cracw = craci ! cracw = 3.27206196043822
3348 cracw = c_cracw * cracw
3349
3350 ! subl and revp: five constants for three separate processes
3351
3352 cssub(1) = 2. * pie * vdifu * tcond * rvgas * rnzs
3353 if (do_hail) then
3354 cgsub(1) = 2. * pie * vdifu * tcond * rvgas * rnzh
3355 else
3356 cgsub(1) = 2. * pie * vdifu * tcond * rvgas * rnzg
3357 endif
3358 crevp(1) = 2. * pie * vdifu * tcond * rvgas * rnzr
3359 cssub(2) = 0.78 / sqrt(act(1))
3360 cgsub(2) = 0.78 / sqrt(act(6))
3361 crevp(2) = 0.78 / sqrt(act(2))
3362 cssub(3) = 0.31 * scm3 * gam263 * sqrt(clin / visk) / act(1) ** 0.65625
3363 cgsub(3) = 0.31 * scm3 * gam275 * sqrt(gcon / visk) / act(6) ** 0.6875
3364 crevp(3) = 0.31 * scm3 * gam290 * sqrt(alin / visk) / act(2) ** 0.725
3365 cssub(4) = tcond * rvgas
3366 cssub(5) = hlts ** 2 * vdifu
3367 cgsub(4) = cssub(4)
3368 crevp(4) = cssub(4)
3369 cgsub(5) = cssub(5)
3370 crevp(5) = hltc ** 2 * vdifu
3371
3372 cgfr(1) = 20.e2 * pisq * rnzr * rhor / act(2) ** 1.75
3373 cgfr(2) = 0.66
3374
3375 ! smlt: five constants (lin et al. 1983)
3376
3377 csmlt(1) = 2. * pie * tcond * rnzs / hltf
3378 csmlt(2) = 2. * pie * vdifu * rnzs * hltc / hltf
3379 csmlt(3) = cssub(2)
3380 csmlt(4) = cssub(3)
3381 csmlt(5) = ch2o / hltf
3382
3383 ! gmlt: five constants
3384
3385 if (do_hail) then
3386 cgmlt(1) = 2. * pie * tcond * rnzh / hltf
3387 cgmlt(2) = 2. * pie * vdifu * rnzh * hltc / hltf
3388 else
3389 cgmlt(1) = 2. * pie * tcond * rnzg / hltf
3390 cgmlt(2) = 2. * pie * vdifu * rnzg * hltc / hltf
3391 endif
3392 cgmlt(3) = cgsub(2)
3393 cgmlt(4) = cgsub(3)
3394 cgmlt(5) = ch2o / hltf
3395
3396 es0 = 6.107799961e2 ! ~6.1 mb
3397 ces0 = eps * es0
3398
3399end subroutine setupm
3400
3401! =======================================================================
3402! initialization of gfdl cloud microphysics
3406subroutine gfdl_cloud_microphys_mod_init (me, master, nlunit, input_nml_file, logunit, &
3407 fn_nml, errmsg, errflg)
3408
3409 implicit none
3410
3411 integer, intent (in) :: me
3412 integer, intent (in) :: master
3413 integer, intent (in) :: nlunit
3414 integer, intent (in) :: logunit
3415
3416 character (len = 64), intent (in) :: fn_nml
3417 character (len = *), intent (in) :: input_nml_file(:)
3418 character(len=*), intent(out) :: errmsg
3419 integer, intent(out) :: errflg
3420
3421 integer :: ios
3422 logical :: exists
3423
3424 ! integer, intent (in) :: id, jd, kd
3425 ! integer, intent (in) :: axes (4)
3426 ! type (time_type), intent (in) :: time
3427
3428 ! integer :: unit, io, ierr, k, logunit
3429 ! logical :: flag
3430 ! real :: tmp, q1, q2
3431
3432 ! master = (mpp_pe () .eq.mpp_root_pe ())
3433
3434 ! Initialize CCPP error-handling
3435 errflg = 0
3436 errmsg = ''
3437
3438 ! -----------------------------------------------------------------------
3439 ! Read namelist
3440 ! -----------------------------------------------------------------------
3441 call read_gfdlmp_nml(errmsg = errmsg, errflg = errflg, unit = nlunit, &
3442 input_nml_file = input_nml_file, fn_nml = fn_nml, version=1, &
3443 iostat = ios)
3444 if(errflg/=0) return
3445
3446 ! write version number and namelist to log file
3447 if (me == master) then
3448 write (logunit, *) " ================================================================== "
3449 write (logunit, *) "gfdl_cloud_microphysics_nml"
3450 endif
3451
3452 !
3453 if (do_setup) then
3454 call setup_con
3455 call setupm
3456 do_setup = .false.
3457 endif
3458
3459 log_10 = log(10.)
3460
3461 tice0 = tice - 0.01
3462 t_wfr = tice - 40.0 ! supercooled water can exist down to - 48 c, which is the "absolute"
3463
3464 ! if (master) write (logunit, nml = gfdl_cloud_microphys_nml)
3465 !
3466 ! id_vtr = register_diag_field (mod_name, 'vt_r', axes (1:3), time, &
3467 ! 'rain fall speed', 'm / s', missing_value = missing_value)
3468 ! id_vts = register_diag_field (mod_name, 'vt_s', axes (1:3), time, &
3469 ! 'snow fall speed', 'm / s', missing_value = missing_value)
3470 ! id_vtg = register_diag_field (mod_name, 'vt_g', axes (1:3), time, &
3471 ! 'graupel fall speed', 'm / s', missing_value = missing_value)
3472 ! id_vti = register_diag_field (mod_name, 'vt_i', axes (1:3), time, &
3473 ! 'ice fall speed', 'm / s', missing_value = missing_value)
3474
3475 ! id_droplets = register_diag_field (mod_name, 'droplets', axes (1:3), time, &
3476 ! 'droplet number concentration', '# / m3', missing_value = missing_value)
3477 ! id_rh = register_diag_field (mod_name, 'rh_lin', axes (1:2), time, &
3478 ! 'relative humidity', 'n / a', missing_value = missing_value)
3479
3480 ! id_rain = register_diag_field (mod_name, 'rain_lin', axes (1:2), time, &
3481 ! 'rain_lin', 'mm / day', missing_value = missing_value)
3482 ! id_snow = register_diag_field (mod_name, 'snow_lin', axes (1:2), time, &
3483 ! 'snow_lin', 'mm / day', missing_value = missing_value)
3484 ! id_graupel = register_diag_field (mod_name, 'graupel_lin', axes (1:2), time, &
3485 ! 'graupel_lin', 'mm / day', missing_value = missing_value)
3486 ! id_ice = register_diag_field (mod_name, 'ice_lin', axes (1:2), time, &
3487 ! 'ice_lin', 'mm / day', missing_value = missing_value)
3488 ! id_prec = register_diag_field (mod_name, 'prec_lin', axes (1:2), time, &
3489 ! 'prec_lin', 'mm / day', missing_value = missing_value)
3490
3491 ! if (master) write (*, *) 'prec_lin diagnostics initialized.', id_prec
3492
3493 ! id_cond = register_diag_field (mod_name, 'cond_lin', axes (1:2), time, &
3494 ! 'total condensate', 'kg / m ** 2', missing_value = missing_value)
3495 ! id_var = register_diag_field (mod_name, 'var_lin', axes (1:2), time, &
3496 ! 'subgrid variance', 'n / a', missing_value = missing_value)
3497
3498 ! call qsmith_init
3499
3500 ! testing the water vapor tables
3501
3502 ! if (mp_debug .and. master) then
3503 ! write (*, *) 'testing water vapor tables in gfdl_cloud_microphys'
3504 ! tmp = tice - 90.
3505 ! do k = 1, 25
3506 ! q1 = wqsat_moist (tmp, 0., 1.e5)
3507 ! q2 = qs1d_m (tmp, 0., 1.e5)
3508 ! write (*, *) nint (tmp - tice), q1, q2, 'dq = ', q1 - q2
3509 ! tmp = tmp + 5.
3510 ! enddo
3511 ! endif
3512
3513 ! if (master) write (*, *) 'gfdl_cloud_micrphys diagnostics initialized.'
3514
3515 module_is_initialized = .true.
3516
3517!+---+-----------------------------------------------------------------+
3518!..Set these variables needed for computing radar reflectivity. These
3519!.. get used within radar_init to create other variables used in the
3520!.. radar module.
3521
3522 xam_r = pi*rhor/6.
3523 xbm_r = 3.
3524 xmu_r = 0.
3525 xam_s = pi*rhos/6.
3526 xbm_s = 3.
3527 xmu_s = 0.
3528 xam_g = pi*rhog/6.
3529 xbm_g = 3.
3530 xmu_g = 0.
3531
3532 call radar_init
3533
3534end subroutine gfdl_cloud_microphys_mod_init
3535
3536! =======================================================================
3537! end of gfdl cloud microphysics
3542
3543 implicit none
3544
3545 deallocate (table)
3546 deallocate (table2)
3547 deallocate (table3)
3548 deallocate (tablew)
3549 deallocate (des)
3550 deallocate (des2)
3551 deallocate (des3)
3552 deallocate (desw)
3553
3554 tables_are_initialized = .false.
3555
3556end subroutine gfdl_cloud_microphys_mod_end
3557
3558! =======================================================================
3559! qsmith table initialization
3562subroutine setup_con
3563
3564 implicit none
3565
3566 ! master = (mpp_pe () .eq.mpp_root_pe ())
3567
3568 rgrav = 1. / grav
3569
3570 if (.not. qsmith_tables_initialized) call qsmith_init
3571
3572 qsmith_tables_initialized = .true.
3573
3574end subroutine setup_con
3575
3576! =======================================================================
3580! =======================================================================
3581
3582real function acr3d (v1, v2, q1, q2, c, cac, rho)
3583
3584 implicit none
3585
3586 real, intent (in) :: v1, v2, c, rho
3587 real, intent (in) :: q1, q2 ! mixing ratio!!!
3588 real, intent (in) :: cac (3)
3589
3590 real :: t1, s1, s2
3591
3592 ! integer :: k
3593 !
3594 ! real :: a
3595 !
3596 ! a = 0.0
3597 ! do k = 1, 3
3598 ! a = a + cac (k) * ((q1 * rho) ** ((7 - k) * 0.25) * (q2 * rho) ** (k * 0.25))
3599 ! enddo
3600 ! acr3d = c * abs (v1 - v2) * a / rho
3601
3602 ! optimized
3603
3604 t1 = sqrt(q1 * rho)
3605 s1 = sqrt(q2 * rho)
3606 s2 = sqrt(s1) ! s1 = s2 ** 2
3607 acr3d = c * abs(v1 - v2) * q1 * s2 * (cac(1) * t1 + cac(2) * sqrt(t1) * s2 + cac(3) * s1)
3608
3609end function acr3d
3610
3611! =======================================================================
3615! =======================================================================
3616
3617real function smlt (tc, dqs, qsrho, psacw, psacr, c, rho, rhofac)
3618
3619 implicit none
3620
3621 real, intent (in) :: tc, dqs, qsrho, psacw, psacr, c (5), rho, rhofac
3622
3623 smlt = (c(1) * tc / rho - c(2) * dqs) * (c(3) * sqrt(qsrho) + &
3624 c(4) * qsrho ** 0.65625 * sqrt(rhofac)) + c(5) * tc * (psacw + psacr)
3625
3626end function smlt
3627
3628! =======================================================================
3631! =======================================================================
3632
3633real function gmlt (tc, dqs, qgrho, pgacw, pgacr, c, rho)
3634
3635 implicit none
3636
3637 real, intent (in) :: tc, dqs, qgrho, pgacw, pgacr, c (5), rho
3638
3639 gmlt = (c(1) * tc / rho - c(2) * dqs) * (c(3) * sqrt(qgrho) + &
3640 c(4) * qgrho ** 0.6875 / rho ** 0.25) + c(5) * tc * (pgacw + pgacr)
3641
3642end function gmlt
3643
3644! =======================================================================
3645! initialization
3646! prepare saturation water vapor pressure tables
3647! =======================================================================
3654! =======================================================================
3655subroutine qsmith_init
3656
3657 implicit none
3658
3659 integer, parameter :: length = 2621
3660
3661 integer :: i
3662
3663 if (.not. tables_are_initialized) then
3664
3665 ! master = (mpp_pe () .eq. mpp_root_pe ())
3666 ! if (master) print *, ' gfdl mp: initializing qs tables'
3667
3668 ! debug code
3669 ! print *, mpp_pe (), allocated (table), allocated (table2), &
3670 ! allocated (table3), allocated (tablew), allocated (des), &
3671 ! allocated (des2), allocated (des3), allocated (desw)
3672 ! end debug code
3673
3674 ! generate es table (dt = 0.1 deg. c)
3675
3676 allocate (table(length))
3677 allocate (table2(length))
3678 allocate (table3(length))
3679 allocate (tablew(length))
3680 allocate (des(length))
3681 allocate (des2(length))
3682 allocate (des3(length))
3683 allocate (desw(length))
3684
3685 call qs_table (length)
3686 call qs_table2 (length)
3687 call qs_table3 (length)
3688 call qs_tablew (length)
3689
3690 do i = 1, length - 1
3691 des(i) = max(0., table(i + 1) - table(i))
3692 des2(i) = max(0., table2(i + 1) - table2(i))
3693 des3(i) = max(0., table3(i + 1) - table3(i))
3694 desw(i) = max(0., tablew(i + 1) - tablew(i))
3695 enddo
3696 des(length) = des(length - 1)
3697 des2(length) = des2(length - 1)
3698 des3(length) = des3(length - 1)
3699 desw(length) = desw(length - 1)
3700
3701 tables_are_initialized = .true.
3702
3703 endif
3704
3705end subroutine qsmith_init
3706
3707! =======================================================================
3708! compute the saturated specific humidity for table ii
3712real function wqs1 (ta, den)
3713
3714 implicit none
3715
3718
3719 real, intent (in) :: ta, den
3720
3721 real :: es, ap1, tmin
3722
3723 integer :: it
3724
3725 tmin = table_ice - 160.
3726 ap1 = 10. * dim(ta, tmin) + 1.
3727 ap1 = min(2621., ap1)
3728 it = ap1
3729 es = tablew(it) + (ap1 - it) * desw(it)
3730 wqs1 = es / (rvgas * ta * den)
3731
3732end function wqs1
3733
3734! =======================================================================
3735! compute the gradient of saturated specific humidity for table ii
3739! =======================================================================
3740
3741real function wqs2 (ta, den, dqdt)
3742
3743 implicit none
3744
3745 ! pure water phase; universal dry / moist formular using air density
3746 ! input "den" can be either dry or moist air density
3747
3748 real, intent (in) :: ta, den
3749
3750 real, intent (out) :: dqdt
3751
3752 real :: es, ap1, tmin
3753
3754 integer :: it
3755
3756 tmin = table_ice - 160.
3757
3758 if (.not. tables_are_initialized) call qsmith_init
3759
3760 ap1 = 10. * dim(ta, tmin) + 1.
3761 ap1 = min(2621., ap1)
3762 it = ap1
3763 es = tablew(it) + (ap1 - it) * desw(it)
3764 wqs2 = es / (rvgas * ta * den)
3765 it = ap1 - 0.5
3766 ! finite diff, del_t = 0.1:
3767 dqdt = 10. * (desw(it) + (ap1 - it) * (desw(it + 1) - desw(it))) / (rvgas * ta * den)
3768
3769end function wqs2
3770
3771! =======================================================================
3772! compute wet buld temperature
3775! =======================================================================
3776
3777real function wet_bulb (q, t, den)
3778
3779 implicit none
3780
3781 real, intent (in) :: t, q, den
3782
3783 real :: qs, tp, dqdt
3784
3785 wet_bulb = t
3786 qs = wqs2(wet_bulb, den, dqdt)
3787 tp = 0.5 * (qs - q) / (1. + lcp * dqdt) * lcp
3788 wet_bulb = wet_bulb - tp
3789
3790 ! tp is negative if super - saturated
3791 if (tp > 0.01) then
3792 qs = wqs2(wet_bulb, den, dqdt)
3793 tp = (qs - q) / (1. + lcp * dqdt) * lcp
3794 wet_bulb = wet_bulb - tp
3795 endif
3796
3797end function wet_bulb
3798
3799! =======================================================================
3802! =======================================================================
3803
3804real function iqs1 (ta, den)
3805
3806 implicit none
3807
3810
3811 real, intent (in) :: ta, den
3812
3813 real :: es, ap1, tmin
3814
3815 integer :: it
3816
3817 tmin = table_ice - 160.
3818 ap1 = 10. * dim(ta, tmin) + 1.
3819 ap1 = min(2621., ap1)
3820 it = ap1
3821 es = table2(it) + (ap1 - it) * des2(it)
3822 iqs1 = es / (rvgas * ta * den)
3823
3824end function iqs1
3825
3826! =======================================================================
3829! =======================================================================
3830
3831real function iqs2 (ta, den, dqdt)
3832
3833 implicit none
3834
3835 ! water - ice phase; universal dry / moist formular using air density
3836 ! input "den" can be either dry or moist air density
3837
3838 real, intent (in) :: ta, den
3839
3840 real, intent (out) :: dqdt
3841
3842 real :: es, ap1, tmin
3843
3844 integer :: it
3845
3846 tmin = table_ice - 160.
3847 ap1 = 10. * dim(ta, tmin) + 1.
3848 ap1 = min(2621., ap1)
3849 it = ap1
3850 es = table2(it) + (ap1 - it) * des2(it)
3851 iqs2 = es / (rvgas * ta * den)
3852 it = ap1 - 0.5
3853 dqdt = 10. * (des2(it) + (ap1 - it) * (des2(it + 1) - des2(it))) / (rvgas * ta * den)
3854
3855end function iqs2
3856
3857! =======================================================================
3860! =======================================================================
3861
3862real function qs1d_moist (ta, qv, pa, dqdt)
3863
3864 implicit none
3865
3866 real, intent (in) :: ta, pa, qv
3867
3868 real, intent (out) :: dqdt
3869
3870 real :: es, ap1, tmin, eps10
3871
3872 integer :: it
3873
3874 tmin = table_ice - 160.
3875 eps10 = 10. * eps
3876 ap1 = 10. * dim(ta, tmin) + 1.
3877 ap1 = min(2621., ap1)
3878 it = ap1
3879 es = table2(it) + (ap1 - it) * des2(it)
3880 qs1d_moist = eps * es * (1. + zvir * qv) / pa
3881 it = ap1 - 0.5
3882 dqdt = eps10 * (des2(it) + (ap1 - it) * (des2(it + 1) - des2(it))) * (1. + zvir * qv) / pa
3883
3884end function qs1d_moist
3885
3886! =======================================================================
3887! compute the gradient of saturated specific humidity for table ii
3890! =======================================================================
3891
3892real function wqsat2_moist (ta, qv, pa, dqdt)
3893
3894 implicit none
3895
3896 real, intent (in) :: ta, pa, qv
3897
3898 real, intent (out) :: dqdt
3899
3900 real :: es, ap1, tmin, eps10
3901
3902 integer :: it
3903
3904 tmin = table_ice - 160.
3905 eps10 = 10. * eps
3906 ap1 = 10. * dim(ta, tmin) + 1.
3907 ap1 = min(2621., ap1)
3908 it = ap1
3909 es = tablew(it) + (ap1 - it) * desw(it)
3910 wqsat2_moist = eps * es * (1. + zvir * qv) / pa
3911 it = ap1 - 0.5
3912 dqdt = eps10 * (desw(it) + (ap1 - it) * (desw(it + 1) - desw(it))) * (1. + zvir * qv) / pa
3913
3914end function wqsat2_moist
3915
3916! =======================================================================
3917! compute the saturated specific humidity for table ii
3920! =======================================================================
3921
3922real function wqsat_moist (ta, qv, pa)
3923
3924 implicit none
3925
3926 real, intent (in) :: ta, pa, qv
3927
3928 real :: es, ap1, tmin
3929
3930 integer :: it
3931
3932 tmin = table_ice - 160.
3933 ap1 = 10. * dim(ta, tmin) + 1.
3934 ap1 = min(2621., ap1)
3935 it = ap1
3936 es = tablew(it) + (ap1 - it) * desw(it)
3937 wqsat_moist = eps * es * (1. + zvir * qv) / pa
3938
3939end function wqsat_moist
3940
3941! =======================================================================
3944! =======================================================================
3945
3946real function qs1d_m (ta, qv, pa)
3947
3948 implicit none
3949
3950 real, intent (in) :: ta, pa, qv
3951
3952 real :: es, ap1, tmin
3953
3954 integer :: it
3955
3956 tmin = table_ice - 160.
3957 ap1 = 10. * dim(ta, tmin) + 1.
3958 ap1 = min(2621., ap1)
3959 it = ap1
3960 es = table2(it) + (ap1 - it) * des2(it)
3961 qs1d_m = eps * es * (1. + zvir * qv) / pa
3962
3963end function qs1d_m
3964
3965! =======================================================================
3968! =======================================================================
3969
3970real function d_sat (ta, den)
3971
3972 implicit none
3973
3974 real, intent (in) :: ta, den
3975
3976 real :: es_w, es_i, ap1, tmin
3977
3978 integer :: it
3979
3980 tmin = table_ice - 160.
3981 ap1 = 10. * dim(ta, tmin) + 1.
3982 ap1 = min(2621., ap1)
3983 it = ap1
3984 es_w = tablew(it) + (ap1 - it) * desw(it)
3985 es_i = table2(it) + (ap1 - it) * des2(it)
3986 d_sat = dim(es_w, es_i) / (rvgas * ta * den) ! take positive difference
3987
3988end function d_sat
3989
3990! =======================================================================
3993! =======================================================================
3994
3995real function esw_table (ta)
3996
3997 implicit none
3998
3999 real, intent (in) :: ta
4000
4001 real :: ap1, tmin
4002
4003 integer :: it
4004
4005 tmin = table_ice - 160.
4006 ap1 = 10. * dim(ta, tmin) + 1.
4007 ap1 = min(2621., ap1)
4008 it = ap1
4009 esw_table = tablew(it) + (ap1 - it) * desw(it)
4010
4011end function esw_table
4012
4013! =======================================================================
4016! =======================================================================
4017
4018real function es2_table (ta)
4019
4020 implicit none
4021
4022 real, intent (in) :: ta
4023
4024 real :: ap1, tmin
4025
4026 integer :: it
4027
4028 tmin = table_ice - 160.
4029 ap1 = 10. * dim(ta, tmin) + 1.
4030 ap1 = min(2621., ap1)
4031 it = ap1
4032 es2_table = table2(it) + (ap1 - it) * des2(it)
4033
4034end function es2_table
4035
4036! =======================================================================
4040subroutine esw_table1d (ta, es, n)
4041
4042 implicit none
4043
4044 integer, intent (in) :: n
4045
4046 real, intent (in) :: ta (n)
4047
4048 real, intent (out) :: es (n)
4049
4050 real :: ap1, tmin
4051
4052 integer :: i, it
4053
4054 tmin = table_ice - 160.
4055
4056 do i = 1, n
4057 ap1 = 10. * dim(ta(i), tmin) + 1.
4058 ap1 = min(2621., ap1)
4059 it = ap1
4060 es(i) = tablew(it) + (ap1 - it) * desw(it)
4061 enddo
4062
4063end subroutine esw_table1d
4064
4065! =======================================================================
4069subroutine es2_table1d (ta, es, n)
4070
4071 implicit none
4072
4073 integer, intent (in) :: n
4074
4075 real, intent (in) :: ta (n)
4076
4077 real, intent (out) :: es (n)
4078
4079 real :: ap1, tmin
4080
4081 integer :: i, it
4082
4083 tmin = table_ice - 160.
4084
4085 do i = 1, n
4086 ap1 = 10. * dim(ta(i), tmin) + 1.
4087 ap1 = min(2621., ap1)
4088 it = ap1
4089 es(i) = table2(it) + (ap1 - it) * des2(it)
4090 enddo
4091
4092end subroutine es2_table1d
4093
4094! =======================================================================
4098subroutine es3_table1d (ta, es, n)
4099
4100 implicit none
4101
4102 integer, intent (in) :: n
4103
4104 real, intent (in) :: ta (n)
4105
4106 real, intent (out) :: es (n)
4107
4108 real :: ap1, tmin
4109
4110 integer :: i, it
4111
4112 tmin = table_ice - 160.
4113
4114 do i = 1, n
4115 ap1 = 10. * dim(ta(i), tmin) + 1.
4116 ap1 = min(2621., ap1)
4117 it = ap1
4118 es(i) = table3(it) + (ap1 - it) * des3(it)
4119 enddo
4120
4121end subroutine es3_table1d
4122
4123! =======================================================================
4126! 1 - phase table
4127subroutine qs_tablew (n)
4128
4129 implicit none
4130
4131 integer, intent (in) :: n
4132
4133 real :: delt = 0.1
4134 real :: tmin, tem, fac0, fac1, fac2
4135
4136 integer :: i
4137
4138 tmin = table_ice - 160.
4139
4140 ! -----------------------------------------------------------------------
4141 ! compute es over water
4142 ! -----------------------------------------------------------------------
4143
4144 do i = 1, n
4145 tem = tmin + delt * real(i - 1)
4146 fac0 = (tem - t_ice) / (tem * t_ice)
4147 fac1 = fac0 * lv0
4148 fac2 = (dc_vap * log(tem / t_ice) + fac1) / rvgas
4149 tablew(i) = e00 * exp(fac2)
4150 enddo
4151
4152end subroutine qs_tablew
4153
4154! =======================================================================
4157! 2 - phase table
4158subroutine qs_table2 (n)
4159
4160 implicit none
4161
4162 integer, intent (in) :: n
4163
4164 real :: delt = 0.1
4165 real :: tmin, tem0, tem1, fac0, fac1, fac2
4166
4167 integer :: i, i0, i1
4168
4169 tmin = table_ice - 160.
4170
4171 do i = 1, n
4172 tem0 = tmin + delt * real(i - 1)
4173 fac0 = (tem0 - t_ice) / (tem0 * t_ice)
4174 if (i <= 1600) then
4175 ! -----------------------------------------------------------------------
4176 ! compute es over ice between - 160 deg c and 0 deg c.
4177 ! -----------------------------------------------------------------------
4178 fac1 = fac0 * li2
4179 fac2 = (d2ice * log(tem0 / t_ice) + fac1) / rvgas
4180 else
4181 ! -----------------------------------------------------------------------
4182 ! compute es over water between 0 deg c and 102 deg c.
4183 ! -----------------------------------------------------------------------
4184 fac1 = fac0 * lv0
4185 fac2 = (dc_vap * log(tem0 / t_ice) + fac1) / rvgas
4186 endif
4187 table2(i) = e00 * exp(fac2)
4188 enddo
4189
4190 ! -----------------------------------------------------------------------
4191 ! smoother around 0 deg c
4192 ! -----------------------------------------------------------------------
4193
4194 i0 = 1600
4195 i1 = 1601
4196 tem0 = 0.25 * (table2(i0 - 1) + 2. * table(i0) + table2(i0 + 1))
4197 tem1 = 0.25 * (table2(i1 - 1) + 2. * table(i1) + table2(i1 + 1))
4198 table2(i0) = tem0
4199 table2(i1) = tem1
4200
4201end subroutine qs_table2
4202
4203! =======================================================================
4206! 2 - phase table with " - 2 c" as the transition point
4207subroutine qs_table3 (n)
4208
4209 implicit none
4210
4211 integer, intent (in) :: n
4212
4213 real :: delt = 0.1
4214 real :: esbasw, tbasw, esbasi, tmin, tem, aa, b, c, d, e
4215 real :: tem0, tem1
4216
4217 integer :: i, i0, i1
4218
4219 esbasw = 1013246.0
4220 tbasw = table_ice + 100.
4221 esbasi = 6107.1
4222 tmin = table_ice - 160.
4223
4224 do i = 1, n
4225 tem = tmin + delt * real(i - 1)
4226 ! if (i <= 1600) then
4227 if (i <= 1580) then ! change to - 2 c
4228 ! -----------------------------------------------------------------------
4229 ! compute es over ice between - 160 deg c and 0 deg c.
4230 ! see smithsonian meteorological tables page 350.
4231 ! -----------------------------------------------------------------------
4232 aa = - 9.09718 * (table_ice / tem - 1.)
4233 b = - 3.56654 * alog10(table_ice / tem)
4234 c = 0.876793 * (1. - tem / table_ice)
4235 e = alog10(esbasi)
4236 table3(i) = 0.1 * 10 ** (aa + b + c + e)
4237 else
4238 ! -----------------------------------------------------------------------
4239 ! compute es over water between - 2 deg c and 102 deg c.
4240 ! see smithsonian meteorological tables page 350.
4241 ! -----------------------------------------------------------------------
4242 aa = - 7.90298 * (tbasw / tem - 1.)
4243 b = 5.02808 * alog10(tbasw / tem)
4244 c = - 1.3816e-7 * (10 ** ((1. - tem / tbasw) * 11.344) - 1.)
4245 d = 8.1328e-3 * (10 ** ((tbasw / tem - 1.) * (- 3.49149)) - 1.)
4246 e = alog10(esbasw)
4247 table3(i) = 0.1 * 10 ** (aa + b + c + d + e)
4248 endif
4249 enddo
4250
4251 ! -----------------------------------------------------------------------
4252 ! smoother around - 2 deg c
4253 ! -----------------------------------------------------------------------
4254
4255 i0 = 1580
4256 i1 = 1581
4257 tem0 = 0.25 * (table3(i0 - 1) + 2. * table(i0) + table3(i0 + 1))
4258 tem1 = 0.25 * (table3(i1 - 1) + 2. * table(i1) + table3(i1 + 1))
4259 table3(i0) = tem0
4260 table3(i1) = tem1
4261
4262end subroutine qs_table3
4263
4264! =======================================================================
4265! compute the saturated specific humidity for table
4266! note: this routine is based on "moist" mixing ratio
4270real function qs_blend (t, p, q)
4271
4272 implicit none
4273
4274 real, intent (in) :: t, p, q
4275
4276 real :: es, ap1, tmin
4277
4278 integer :: it
4279
4280 tmin = table_ice - 160.
4281 ap1 = 10. * dim(t, tmin) + 1.
4282 ap1 = min(2621., ap1)
4283 it = ap1
4284 es = table(it) + (ap1 - it) * des(it)
4285 qs_blend = eps * es * (1. + zvir * q) / p
4286
4287end function qs_blend
4288
4289! =======================================================================
4292! 3 - phase table
4293subroutine qs_table (n)
4294
4295 implicit none
4296
4297 integer, intent (in) :: n
4298
4299 real :: delt = 0.1
4300 real :: tmin, tem, esh20
4301 real :: wice, wh2o, fac0, fac1, fac2
4302 real :: esupc (200)
4303
4304 integer :: i
4305
4306 tmin = table_ice - 160.
4307
4308 ! -----------------------------------------------------------------------
4309 ! compute es over ice between - 160 deg c and 0 deg c.
4310 ! -----------------------------------------------------------------------
4311
4312 do i = 1, 1600
4313 tem = tmin + delt * real(i - 1)
4314 fac0 = (tem - t_ice) / (tem * t_ice)
4315 fac1 = fac0 * li2
4316 fac2 = (d2ice * log(tem / t_ice) + fac1) / rvgas
4317 table(i) = e00 * exp(fac2)
4318 enddo
4319
4320 ! -----------------------------------------------------------------------
4321 ! compute es over water between - 20 deg c and 102 deg c.
4322 ! -----------------------------------------------------------------------
4323
4324 do i = 1, 1221
4325 tem = 253.16 + delt * real(i - 1)
4326 fac0 = (tem - t_ice) / (tem * t_ice)
4327 fac1 = fac0 * lv0
4328 fac2 = (dc_vap * log(tem / t_ice) + fac1) / rvgas
4329 esh20 = e00 * exp(fac2)
4330 if (i <= 200) then
4331 esupc(i) = esh20
4332 else
4333 table(i + 1400) = esh20
4334 endif
4335 enddo
4336
4337 ! -----------------------------------------------------------------------
4338 ! derive blended es over ice and supercooled water between - 20 deg c and 0 deg c
4339 ! -----------------------------------------------------------------------
4340
4341 do i = 1, 200
4342 tem = 253.16 + delt * real(i - 1)
4343 wice = 0.05 * (table_ice - tem)
4344 wh2o = 0.05 * (tem - 253.16)
4345 table(i + 1400) = wice * table(i + 1400) + wh2o * esupc(i)
4346 enddo
4347
4348end subroutine qs_table
4349
4350! =======================================================================
4351! compute the saturated specific humidity and the gradient of saturated specific humidity
4352! input t in deg k, p in pa; p = rho rdry tv, moist pressure
4356!@details It als oincludes the option for computing des/dT.
4357subroutine qsmith (im, km, ks, t, p, q, qs, dqdt)
4358
4359 implicit none
4360
4361 integer, intent (in) :: im, km, ks
4362
4363 real, intent (in), dimension (im, km) :: t, p, q
4364
4365 real, intent (out), dimension (im, km) :: qs
4366
4367 real, intent (out), dimension (im, km), optional :: dqdt
4368
4369 real :: eps10, ap1, tmin
4370
4371 real, dimension (im, km) :: es
4372
4373 integer :: i, k, it
4374
4375 tmin = table_ice - 160.
4376 eps10 = 10. * eps
4377
4378 if (.not. tables_are_initialized) then
4379 call qsmith_init
4380 endif
4381
4382 do k = ks, km
4383 do i = 1, im
4384 ap1 = 10. * dim(t(i, k), tmin) + 1.
4385 ap1 = min(2621., ap1)
4386 it = ap1
4387 es(i, k) = table(it) + (ap1 - it) * des(it)
4388 qs(i, k) = eps * es(i, k) * (1. + zvir * q(i, k)) / p(i, k)
4389 enddo
4390 enddo
4391
4392 if (present (dqdt)) then
4393 do k = ks, km
4394 do i = 1, im
4395 ap1 = 10. * dim(t(i, k), tmin) + 1.
4396 ap1 = min(2621., ap1) - 0.5
4397 it = ap1
4398 dqdt(i, k) = eps10 * (des(it) + (ap1 - it) * (des(it + 1) - des(it))) * (1. + zvir * q(i, k)) / p(i, k)
4399 enddo
4400 enddo
4401 endif
4402
4403end subroutine qsmith
4404
4405! =======================================================================
4409subroutine neg_adj (ktop, kbot, pt, dp, qv, ql, qr, qi, qs, qg)
4410
4411 implicit none
4412
4413 integer, intent (in) :: ktop, kbot
4414
4415 real, intent (in), dimension (ktop:kbot) :: dp
4416
4417 real, intent (inout), dimension (ktop:kbot) :: pt, qv, ql, qr, qi, qs, qg
4418
4419 real, dimension (ktop:kbot) :: lcpk, icpk
4420
4421 real :: dq, cvm
4422
4423 integer :: k
4424
4425 ! -----------------------------------------------------------------------
4426 ! define heat capacity and latent heat coefficient
4427 ! -----------------------------------------------------------------------
4428
4429 do k = ktop, kbot
4430 cvm = c_air + qv(k) * c_vap + (qr(k) + ql(k)) * c_liq + (qi(k) + qs(k) + qg(k)) * c_ice
4431 lcpk(k) = (lv00 + d0_vap * pt(k)) / cvm
4432 icpk(k) = (li00 + dc_ice * pt(k)) / cvm
4433 enddo
4434
4435 do k = ktop, kbot
4436
4437 ! -----------------------------------------------------------------------
4438 ! ice phase:
4439 ! -----------------------------------------------------------------------
4440
4441 ! if cloud ice < 0, borrow from snow
4442 if (qi(k) < 0.) then
4443 qs(k) = qs(k) + qi(k)
4444 qi(k) = 0.
4445 endif
4446 ! if snow < 0, borrow from graupel
4447 if (qs(k) < 0.) then
4448 qg(k) = qg(k) + qs(k)
4449 qs(k) = 0.
4450 endif
4451 ! if graupel < 0, borrow from rain
4452 if (qg(k) < 0.) then
4453 qr(k) = qr(k) + qg(k)
4454 pt(k) = pt(k) - qg(k) * icpk(k) ! heating
4455 qg(k) = 0.
4456 endif
4457
4458 ! -----------------------------------------------------------------------
4459 ! liquid phase:
4460 ! -----------------------------------------------------------------------
4461
4462 ! if rain < 0, borrow from cloud water
4463 if (qr(k) < 0.) then
4464 ql(k) = ql(k) + qr(k)
4465 qr(k) = 0.
4466 endif
4467 ! if cloud water < 0, borrow from water vapor
4468 if (ql(k) < 0.) then
4469 qv(k) = qv(k) + ql(k)
4470 pt(k) = pt(k) - ql(k) * lcpk(k) ! heating
4471 ql(k) = 0.
4472 endif
4473
4474 enddo
4475
4476 ! -----------------------------------------------------------------------
4477 ! fix water vapor; borrow from below
4478 ! -----------------------------------------------------------------------
4479
4480 do k = ktop, kbot - 1
4481 if (qv(k) < 0.) then
4482 qv(k + 1) = qv(k + 1) + qv(k) * dp(k) / dp(k + 1)
4483 qv(k) = 0.
4484 endif
4485 enddo
4486
4487 ! -----------------------------------------------------------------------
4488 ! bottom layer; borrow from above
4489 ! -----------------------------------------------------------------------
4490
4491 if (qv(kbot) < 0. .and. qv(kbot - 1) > 0.) then
4492 dq = min(- qv(kbot) * dp(kbot), qv(kbot - 1) * dp(kbot - 1))
4493 qv(kbot - 1) = qv(kbot - 1) - dq / dp(kbot - 1)
4494 qv(kbot) = qv(kbot) + dq / dp(kbot)
4495 endif
4496
4497end subroutine neg_adj
4498
4499! =======================================================================
4500! compute global sum
4502! =======================================================================
4503
4504!real function g_sum (p, ifirst, ilast, jfirst, jlast, area, mode)
4505!
4506! use mpp_mod, only: mpp_sum
4507!
4508! implicit none
4509!
4510! integer, intent (in) :: ifirst, ilast, jfirst, jlast
4511! integer, intent (in) :: mode ! if == 1 divided by area
4512!
4513! real, intent (in), dimension (ifirst:ilast, jfirst:jlast) :: p, area
4514!
4515! integer :: i, j
4516!
4517! real :: gsum
4518!
4519! if (global_area < 0.) then
4520! global_area = 0.
4521! do j = jfirst, jlast
4522! do i = ifirst, ilast
4523! global_area = global_area + area (i, j)
4524! enddo
4525! enddo
4526! call mpp_sum (global_area)
4527! endif
4528!
4529! gsum = 0.
4530! do j = jfirst, jlast
4531! do i = ifirst, ilast
4532! gsum = gsum + p (i, j) * area (i, j)
4533! enddo
4534! enddo
4535! call mpp_sum (gsum)
4536!
4537! if (mode == 1) then
4538! g_sum = gsum / global_area
4539! else
4540! g_sum = gsum
4541! endif
4542!
4543!end function g_sum
4544
4545! ==========================================================================
4548subroutine interpolate_z (is, ie, js, je, km, zl, hgt, a3, a2)
4549
4550 implicit none
4551
4552 integer, intent (in) :: is, ie, js, je, km
4553
4554 real, intent (in), dimension (is:ie, js:je, km) :: a3
4555
4556 real, intent (in), dimension (is:ie, js:je, km + 1) :: hgt ! hgt (k) > hgt (k + 1)
4557
4558 real, intent (in) :: zl
4559
4560 real, intent (out), dimension (is:ie, js:je) :: a2
4561
4562 real, dimension (km) :: zm
4563
4564 integer :: i, j, k
4565
4566 !$omp parallel do default (none) shared (is, ie, js, je, km, hgt, zl, a2, a3) private (zm)
4567
4568 do j = js, je
4569 do i = is, ie
4570 do k = 1, km
4571 zm(k) = 0.5 * (hgt(i, j, k) + hgt(i, j, k + 1))
4572 enddo
4573 if (zl >= zm(1)) then
4574 a2(i, j) = a3(i, j, 1)
4575 elseif (zl <= zm(km)) then
4576 a2(i, j) = a3(i, j, km)
4577 else
4578 do k = 1, km - 1
4579 if (zl <= zm(k) .and. zl >= zm(k + 1)) then
4580 a2(i, j) = a3(i, j, k) + (a3(i, j, k + 1) - a3(i, j, k)) * (zm(k) - zl) / (zm(k) - zm(k + 1))
4581 exit
4582 endif
4583 enddo
4584 endif
4585 enddo
4586 enddo
4587
4588end subroutine interpolate_z
4589
4590! =======================================================================
4595! =======================================================================
4596subroutine cloud_diagnosis (is, ie, ks, ke, den, delp, lsm, qmw, qmi, qmr, qms, qmg, t, &
4597 rew, rei, rer, res, reg)
4598
4599 implicit none
4600
4601 integer, intent (in) :: is, ie, ks, ke
4602 integer, intent (in), dimension (is:ie) :: lsm ! land sea mask, 0: ocean, 1: land, 2: sea ice
4603
4604 real, intent (in), dimension (is:ie, ks:ke) :: den, delp, t
4605 real, intent (in), dimension (is:ie, ks:ke) :: qmw, qmi, qmr, qms, qmg
4606
4607 real, intent (out), dimension (is:ie, ks:ke) :: rew, rei, rer, res, reg
4608
4609 real, dimension (is:ie, ks:ke) :: qcw, qci, qcr, qcs, qcg
4610
4611 integer :: i, k
4612
4613 real :: lambdar, lambdas, lambdag
4614 real :: dpg, rei_fac, mask, ccn, bw
4615 real, parameter :: rho_0 = 50.e-3
4616
4617 real :: rhow = 1.0e3, rhor = 1.0e3, rhos = 1.0e2, rhog = 4.0e2
4618 real :: n0r = 8.0e6, n0s = 3.0e6, n0g = 4.0e6
4619 real :: alphar = 0.8, alphas = 0.25, alphag = 0.5
4620 real :: gammar = 17.837789, gammas = 8.2850630, gammag = 11.631769
4621 real :: qmin = 1.0e-12, beta = 1.22, qmin1 = 9.e-6
4622
4623 do k = ks, ke
4624 do i = is, ie
4625
4626 dpg = abs(delp(i, k)) / grav
4627 mask = min(max(real(lsm(i)), 0.0), 2.0)
4628
4629 ! -----------------------------------------------------------------------
4630 ! cloud water (Martin et al., 1994)
4631 ! -----------------------------------------------------------------------
4632
4633 ccn = 0.80 * (- 1.15e-3 * (ccn_o ** 2) + 0.963 * ccn_o + 5.30) * abs(mask - 1.0) + &
4634 0.67 * (- 2.10e-4 * (ccn_l ** 2) + 0.568 * ccn_l - 27.9) * (1.0 - abs(mask - 1.0))
4635
4636 if (qmw(i, k) .gt. qmin) then
4637 qcw(i, k) = dpg * qmw(i, k) * 1.0e3
4638 rew(i, k) = exp(1.0 / 3.0 * log((3.0 * den(i, k) * qmw(i, k)) / (4.0 * pi * rhow * ccn))) * 1.0e4
4639 rew(i, k) = max(rewmin, min(rewmax, rew(i, k)))
4640 else
4641 qcw(i, k) = 0.0
4642 rew(i, k) = rewmin
4643 endif
4644
4645 if (reiflag .eq. 1) then
4646
4647 ! -----------------------------------------------------------------------
4648 ! cloud ice (Heymsfield and Mcfarquhar, 1996)
4649 ! -----------------------------------------------------------------------
4650
4651 if (qmi(i, k) .gt. qmin1) then
4652 qci(i, k) = dpg * qmi(i, k) * 1.0e3
4653 rei_fac = log(1.0e3 * qmi(i, k) * den(i, k))
4654 if (t(i, k) - tice .lt. - 50) then
4655 rei(i, k) = beta / 9.917 * exp(0.109 * rei_fac) * 1.0e3
4656 elseif (t(i, k) - tice .lt. - 40) then
4657 rei(i, k) = beta / 9.337 * exp(0.080 * rei_fac) * 1.0e3
4658 elseif (t(i, k) - tice .lt. - 30) then
4659 rei(i, k) = beta / 9.208 * exp(0.055 * rei_fac) * 1.0e3
4660 else
4661 rei(i, k) = beta / 9.387 * exp(0.031 * rei_fac) * 1.0e3
4662 endif
4663 rei(i, k) = max(reimin, min(reimax, rei(i, k)))
4664 else
4665 qci(i, k) = 0.0
4666 rei(i, k) = reimin
4667 endif
4668
4669 endif
4670
4671 if (reiflag .eq. 2) then
4672
4673 ! -----------------------------------------------------------------------
4674 ! cloud ice (Wyser, 1998)
4675 ! -----------------------------------------------------------------------
4676
4677 if (qmi(i, k) .gt. qmin1) then
4678 qci(i, k) = dpg * qmi(i, k) * 1.0e3
4679 bw = - 2. + 1.e-3 * log10(den(i, k) * qmi(i, k) / rho_0) * max(0.0, tice - t(i, k)) ** 1.5
4680 rei(i, k) = 377.4 + bw * (203.3 + bw * (37.91 + 2.3696 * bw))
4681 rei(i, k) = max(reimin, min(reimax, rei(i, k)))
4682 else
4683 qci(i, k) = 0.0
4684 rei(i, k) = reimin
4685 endif
4686
4687 endif
4688
4689 ! -----------------------------------------------------------------------
4690 ! rain (Lin et al., 1983)
4691 ! -----------------------------------------------------------------------
4692
4693 if (qmr(i, k) .gt. qmin) then
4694 qcr(i, k) = dpg * qmr(i, k) * 1.0e3
4695 lambdar = exp(0.25 * log(pi * rhor * n0r / qmr(i, k) / den(i, k)))
4696 rer(i, k) = 0.5 * exp(log(gammar / 6) / alphar) / lambdar * 1.0e6
4697 rer(i, k) = max(rermin, min(rermax, rer(i, k)))
4698 else
4699 qcr(i, k) = 0.0
4700 rer(i, k) = rermin
4701 endif
4702
4703 ! -----------------------------------------------------------------------
4704 ! snow (Lin et al., 1983)
4705 ! -----------------------------------------------------------------------
4706
4707 if (qms(i, k) .gt. qmin1) then
4708 qcs(i, k) = dpg * qms(i, k) * 1.0e3
4709 lambdas = exp(0.25 * log(pi * rhos * n0s / qms(i, k) / den(i, k)))
4710 res(i, k) = 0.5 * exp(log(gammas / 6) / alphas) / lambdas * 1.0e6
4711 res(i, k) = max(resmin, min(resmax, res(i, k)))
4712 else
4713 qcs(i, k) = 0.0
4714 res(i, k) = resmin
4715 endif
4716
4717 ! -----------------------------------------------------------------------
4718 ! graupel (Lin et al., 1983)
4719 ! -----------------------------------------------------------------------
4720
4721 if (qmg(i, k) .gt. qmin) then
4722 qcg(i, k) = dpg * qmg(i, k) * 1.0e3
4723 lambdag = exp(0.25 * log(pi * rhog * n0g / qmg(i, k) / den(i, k)))
4724 reg(i, k) = 0.5 * exp(log(gammag / 6) / alphag) / lambdag * 1.0e6
4725 reg(i, k) = max(regmin, min(regmax, reg(i, k)))
4726 else
4727 qcg(i, k) = 0.0
4728 reg(i, k) = regmin
4729 endif
4730
4731 enddo
4732 enddo
4733
4734end subroutine cloud_diagnosis
4735
4736!+---+-----------------------------------------------------------------+
4739 subroutine refl10cm_gfdl (qv1d, qr1d, qs1d, qg1d, &
4740 t1d, p1d, dBZ, kts, kte, ii, jj, melti)
4741
4742 IMPLICIT NONE
4743
4744!..Sub arguments
4745 INTEGER, INTENT(IN):: kts, kte, ii,jj
4746 REAL, DIMENSION(kts:kte), INTENT(IN):: &
4747 qv1d, qr1d, qs1d, qg1d, t1d, p1d
4748 REAL, DIMENSION(kts:kte), INTENT(INOUT):: dBZ
4749
4750!..Local variables
4751 REAL, DIMENSION(kts:kte):: temp, pres, qv, rho
4752 REAL, DIMENSION(kts:kte):: rr, rs, rg
4753! REAL:: temp_C
4754
4755 DOUBLE PRECISION, DIMENSION(kts:kte):: ilamr, ilams, ilamg
4756 DOUBLE PRECISION, DIMENSION(kts:kte):: N0_r, N0_s, N0_g
4757 DOUBLE PRECISION:: lamr, lams, lamg
4758 LOGICAL, DIMENSION(kts:kte):: L_qr, L_qs, L_qg
4759
4760 REAL, DIMENSION(kts:kte):: ze_rain, ze_snow, ze_graupel
4761 DOUBLE PRECISION:: fmelt_s, fmelt_g
4762
4763 INTEGER:: i, k, k_0, kbot, n
4764 LOGICAL, INTENT(IN):: melti
4765 DOUBLE PRECISION:: cback, x, eta, f_d
4766!+---+
4767
4768 do k = kts, kte
4769 dbz(k) = -35.0
4770 enddo
4771
4772!+---+-----------------------------------------------------------------+
4773!..Put column of data into local arrays.
4774!+---+-----------------------------------------------------------------+
4775 do k = kts, kte
4776 temp(k) = t1d(k)
4777! temp_C = min(-0.001, temp(K)-273.15)
4778 qv(k) = max(1.e-10, qv1d(k))
4779 pres(k) = p1d(k)
4780 rho(k) = 0.622*pres(k)/(rdgas*temp(k)*(qv(k)+0.622))
4781
4782 if (qr1d(k) .gt. 1.e-9) then
4783 rr(k) = qr1d(k)*rho(k)
4784 n0_r(k) = n0r
4785 lamr = (xam_r*xcrg(3)*n0_r(k)/rr(k))**(1./xcre(1))
4786 ilamr(k) = 1./lamr
4787 l_qr(k) = .true.
4788 else
4789 rr(k) = 1.e-12
4790 l_qr(k) = .false.
4791 endif
4792
4793 if (qs1d(k) .gt. 1.e-9) then
4794 rs(k) = qs1d(k)*rho(k)
4795 n0_s(k) = n0s
4796 lams = (xam_s*xcsg(3)*n0_s(k)/rs(k))**(1./xcse(1))
4797 ilams(k) = 1./lams
4798 l_qs(k) = .true.
4799 else
4800 rs(k) = 1.e-12
4801 l_qs(k) = .false.
4802 endif
4803
4804 if (qg1d(k) .gt. 1.e-9) then
4805 rg(k) = qg1d(k)*rho(k)
4806 n0_g(k) = n0g
4807 lamg = (xam_g*xcgg(3)*n0_g(k)/rg(k))**(1./xcge(1))
4808 ilamg(k) = 1./lamg
4809 l_qg(k) = .true.
4810 else
4811 rg(k) = 1.e-12
4812 l_qg(k) = .false.
4813 endif
4814 enddo
4815
4816!+---+-----------------------------------------------------------------+
4817!..Locate K-level of start of melting (k_0 is level above).
4818!+---+-----------------------------------------------------------------+
4819 k_0 = kts
4820 k_loop:do k = kte-1, kts, -1
4821 if ( melti .and. (temp(k).gt.273.15) .and. l_qr(k) &
4822 .and. (l_qs(k+1).or.l_qg(k+1)) ) then
4823 k_0 = max(k+1, k_0)
4824 EXIT k_loop
4825 endif
4826 enddo k_loop
4827!+---+-----------------------------------------------------------------+
4828!..Assume Rayleigh approximation at 10 cm wavelength. Rain (all temps)
4829!.. and non-water-coated snow and graupel when below freezing are
4830!.. simple. Integrations of m(D)*m(D)*N(D)*dD.
4831!+---+-----------------------------------------------------------------+
4832 do k = kts, kte
4833 ze_rain(k) = 1.e-22
4834 ze_snow(k) = 1.e-22
4835 ze_graupel(k) = 1.e-22
4836 if (l_qr(k)) ze_rain(k) = n0_r(k)*xcrg(4)*ilamr(k)**xcre(4)
4837 if (l_qs(k)) ze_snow(k) = (0.176/0.93) * (6.0/pi)*(6.0/pi) &
4838 * (xam_s/900.0)*(xam_s/900.0) &
4839 * n0_s(k)*xcsg(4)*ilams(k)**xcse(4)
4840 if (l_qg(k)) ze_graupel(k) = (0.176/0.93) * (6.0/pi)*(6.0/pi) &
4841 * (xam_g/900.0)*(xam_g/900.0) &
4842 * n0_g(k)*xcgg(4)*ilamg(k)**xcge(4)
4843 enddo
4844
4845
4846!+---+-----------------------------------------------------------------+
4847!..Special case of melting ice (snow/graupel) particles. Assume the
4848!.. ice is surrounded by the liquid water. Fraction of meltwater is
4849!.. extremely simple based on amount found above the melting level.
4850!.. Uses code from Uli Blahak (rayleigh_soak_wetgraupel and supporting
4851!.. routines).
4852!+---+-----------------------------------------------------------------+
4853
4854 if (melti .and. k_0.ge.kts+1) then
4855 do k = k_0-1, kts, -1
4856
4857!..Reflectivity contributed by melting snow
4858 if (l_qs(k) .and. l_qs(k_0) ) then
4859 fmelt_s = max(0.005d0, min(1.0d0-rs(k)/rs(k_0), 0.99d0))
4860 eta = 0.d0
4861 lams = 1./ilams(k)
4862 do n = 1, nrbins
4863 x = xam_s * xxds(n)**xbm_s
4864 call rayleigh_soak_wetgraupel (x,dble(xocms),dble(xobms), &
4865 fmelt_s, melt_outside_s, m_w_0, m_i_0, lamda_radar, &
4866 cback, mixingrulestring_s, matrixstring_s, &
4867 inclusionstring_s, hoststring_s, &
4868 hostmatrixstring_s, hostinclusionstring_s)
4869 f_d = n0_s(k)*xxds(n)**xmu_s * dexp(-lams*xxds(n))
4870 eta = eta + f_d * cback * simpson(n) * xdts(n)
4871 enddo
4872 ze_snow(k) = sngl(lamda4 / (pi5 * k_w) * eta)
4873 endif
4874
4875
4876!..Reflectivity contributed by melting graupel
4877
4878 if (l_qg(k) .and. l_qg(k_0) ) then
4879 fmelt_g = max(0.005d0, min(1.0d0-rg(k)/rg(k_0), 0.99d0))
4880 eta = 0.d0
4881 lamg = 1./ilamg(k)
4882 do n = 1, nrbins
4883 x = xam_g * xxdg(n)**xbm_g
4884 call rayleigh_soak_wetgraupel (x,dble(xocmg),dble(xobmg), &
4885 fmelt_g, melt_outside_g, m_w_0, m_i_0, lamda_radar, &
4886 cback, mixingrulestring_g, matrixstring_g, &
4887 inclusionstring_g, hoststring_g, &
4888 hostmatrixstring_g, hostinclusionstring_g)
4889 f_d = n0_g(k)*xxdg(n)**xmu_g * dexp(-lamg*xxdg(n))
4890 eta = eta + f_d * cback * simpson(n) * xdtg(n)
4891 enddo
4892 ze_graupel(k) = sngl(lamda4 / (pi5 * k_w) * eta)
4893 endif
4894
4895 enddo
4896 endif
4897
4898 do k = kte, kts, -1
4899 dbz(k) = 10.*log10((ze_rain(k)+ze_snow(k)+ze_graupel(k))*1.d18)
4900 enddo
4901
4902
4903 end subroutine refl10cm_gfdl
4904!+---+-----------------------------------------------------------------+
4905
4906end module gfdl_cloud_microphys_mod
real function acr3d(v1, v2, q1, q2, c, cac, rho)
The function is an accretion function (Lin et al.(1983) )
real function smlt(tc, dqs, qsrho, psacw, psacr, c, rho, rhofac)
Melting of snow function (Lin et al.(1983) ) note: psacw and psacr must be calc before smlt is called...
subroutine esw_table1d(ta, es, n)
The subroutine 'esw_table1d' computes the saturated water vapor pressure for table ii.
subroutine interpolate_z(is, ie, js, je, km, zl, hgt, a3, a2)
quick local sum algorithm
subroutine qs_table(n)
saturation water vapor pressure table i
subroutine qs_table3(n)
saturation water vapor pressure table iv
subroutine refl10cm_gfdl(qv1d, qr1d, qs1d, qg1d, t1d, p1d, dbz, kts, kte, ii, jj, melti)
This subroutine calculates radar reflectivity.
subroutine implicit_fall(dt, ktop, kbot, ze, vt, dp, q, precip, m1)
The subroutine computes the time-implicit monotonic fall scheme.
subroutine qsmith(im, km, ks, t, p, q, qs, dqdt)
The function 'qsmith' computes the saturated specific humidity with a blend of water and ice dependin...
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 cs_limiters(km, a4)
This subroutine perform positive definite constraint.
subroutine linear_prof(km, q, dm, z_var, h_var)
Definition of vertical subgrid variability used for cloud ice and cloud water autoconversion.
subroutine qs_table2(n)
saturation water vapor pressure table iii
subroutine fall_speed(ktop, kbot, den, qs, qi, qg, ql, tk, vts, vti, vtg)
The subroutine calculates vertical fall speed of snow/ice/graupel.
subroutine check_column(ktop, kbot, q, no_fall)
The subroutine 'check_column' checks if the water species is large enough to fall.
subroutine revap_racc(ktop, kbot, dt, tz, qv, ql, qr, qi, qs, qg, den, denfac, rh_rain, h_var)
This subroutine calculates evaporation of rain and accretion of rain.
subroutine icloud(ktop, kbot, tzk, p1, qvk, qlk, qrk, qik, qsk, qgk, dp1, den, denfac, vts, vtg, vtr, qak, rh_adj, rh_rain, dts, h_var)
This subroutine includes cloud ice microphysics processes.
real function wqs1(ta, den)
The function 'wqs1' returns the saturation vapor pressure over pure liquid water for a given temperat...
subroutine revap_rac1(hydrostatic, is, ie, dt, tz, qv, ql, qr, qi, qs, qg, den, hvar)
This subroutine calculates rain evaporation.
subroutine terminal_fall(dtm, ktop, kbot, tz, qv, ql, qr, qg, qs, qi, dz, dp, den, vtg, vts, vti, r1, g1, s1, i1, m1_sol, w1)
The subroutine 'terminal_fall' computes terminal fall speed.
subroutine neg_adj(ktop, kbot, pt, dp, qv, ql, qr, qi, qs, qg)
The subroutine 'neg_adj' fixes negative water species.
subroutine mpdrv(hydrostatic, uin, vin, w, delp, pt, qv, ql, qr, qi, qs, qg, qa, qn, dz, is, ie, js, je, ks, ke, ktop, kbot, j, dt_in, ntimes, rain, snow, graupel, ice, m2_rain, m2_sol, cond, area1, land, u_dt, v_dt, pt_dt, qv_dt, ql_dt, qr_dt, qi_dt, qs_dt, qg_dt, qa_dt, w_var, vt_r, vt_s, vt_g, vt_i, qn2)
GFDL cloud microphysics, major program, and is based on Lin et al.(1983) and Rutledge and Hobbs (198...
subroutine setupm
The subroutine sets up gfdl cloud microphysics parameters.
subroutine es3_table1d(ta, es, n)
The subroutine 'es3_table1d' computes the saturated water vapor pressure for table iv.
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 lagrangian_fall_ppm(ktop, kbot, zs, ze, zt, dp, q, precip, m1, mono)
Lagrangian scheme.
subroutine qsmith_init
The subroutine 'qsmith_init' initializes lookup tables for saturation water vapor pressure for the fo...
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.
subroutine warm_rain(dt, ktop, kbot, dp, dz, tz, qv, ql, qr, qi, qs, qg, den, denfac, ccn, c_praut, rh_rain, vtr, r1, m1_rain, w1, h_var)
This subroutine includes warm rain cloud microphysics.
subroutine qs_tablew(n)
saturation water vapor pressure table ii
subroutine sedi_heat(ktop, kbot, dm, m1, dz, tz, qv, ql, qr, qi, qs, qg, cw)
This subroutine calculates sedimentation of heat.
real function qs_blend(t, p, q)
The function 'qs_blend' computes the saturated specific humidity with a blend of water and ice depend...
subroutine setup_con
The subroutine 'setup_con' sets up constants and calls 'qsmith_init'.
subroutine cs_profile(a4, del, km, do_mono)
subroutine subgrid_z_proc(ktop, kbot, p1, den, denfac, dts, rh_adj, tz, qv, ql, qr, qi, qs, qg, qa, h_var, rh_rain)
This subroutine calculates temperature sentive high vertical resolution processes.
subroutine es2_table1d(ta, es, n)
The subroutine 'es3_table1d' computes the saturated water vapor pressure for table iii.
This module contains the column GFDL Cloud microphysics scheme.
This module is more library code whereas the individual microphysics schemes contains specific detail...