FV3 Bundle
lin_cloud_microphys_nlm.F90
Go to the documentation of this file.
1 !
2 ! Cloud micro-physics package for GFDL global cloud resolving model
3 ! The algorithms are originally based on Lin et al 1983. Many key
4 ! elements have been changed/improved based on several other publications
5 ! Developer: Shian-Jiann Lin
6 !
8  use mpp_mod, only: stdlog, mpp_pe, mpp_root_pe, mpp_clock_id, &
9  mpp_clock_begin, mpp_clock_end, clock_routine, &
13  use constants_mod, only: grav, rdgas, rvgas, cp_air, cp_vapor, hlv, hlf, kappa, pi !=>pi_8
14  use fms_mod, only: write_version_number, open_namelist_file, &
15  check_nml_error, file_exist, close_file, &
16  error_mesg, fatal
17  use fv_arrays_nlm_mod, only: fvprc
18 
19  implicit none
20  private
21 
24  public setup_con, wet_bulb
25  real :: missing_value = -1.e10
26  logical :: module_is_initialized = .false.
27  logical :: qsmith_tables_initialized = .false.
28  character(len=17) :: mod_name = 'lin_cld_microphys'
29 
30 !==== fms constants ====================
31 !!! real, parameter :: latv = hlv ! = 2.500e6
32 !!! real, parameter:: cv_air = 717.56 ! Satoh value
33 !!! real, parameter :: lati = hlf ! = 3.34e5
34 !!! real, parameter :: lats = latv+lati ! = 2.834E6
35 ! rdgas = 287.04; rvgas = 461.50
36 ! cp_air =rdgas * 7./2. = 1006.64 ! heat capacity at constant pressure (j/kg/k)
37 ! The following two are from Emanuel's book "Atmospheric Convection"
38 !!! real, parameter :: c_liq = 4190. ! heat capacity of water at 0C
39  !
40  real, parameter :: eps = rdgas/rvgas ! = 0.621971831
41  real, parameter :: zvir = rvgas/rdgas-1. ! = 0.607789855
42  real, parameter :: table_ice = 273.16 ! freezing point for qs table
43  real, parameter :: cv_air = cp_air - rdgas ! = rdgas * (7/2-1) = 2.5*rdgas=717.68
44 
45  real, parameter:: e00 = 610.71 ! saturation vapor pressure at T0
46  real, parameter:: c_liq = 4190. ! heat capacity of water at 0C
47  real, parameter:: c_ice = 2106. ! heat capacity of ice at 0C: c=c_ice+7.3*(T-Tice)
48  real, parameter:: cp_vap = cp_vapor ! 1846.
49 ! real, parameter:: cv_vap = 1410.0 ! Emanuel value
50 ! For consistency, cv_vap derived FMS constants:
51  real, parameter:: cv_vap = cp_vap - rvgas ! 1384.5
52  real, parameter:: dc_vap = cp_vap - c_liq ! = -2344. isobaric heating/cooling
53  real, parameter:: dc_ice = c_liq - c_ice ! = 2084
54 
55 ! Values at 0 Deg C
56  real, parameter:: hlv0 = 2.501e6 ! Emanuel Appendix-2
57  real, parameter:: hlf0 = 3.337e5 ! Emanuel
58  real, parameter:: t_ice = 273.16
59  real, parameter:: lv0 = hlv0 - dc_vap*t_ice ! = 3.141264e6
60  real, parameter:: li00 = hlf0 - dc_ice *t_ice ! = -2.355446e5
61 
62  real, parameter:: d2ice = cp_vap - c_ice
63  real, parameter:: li2 = hlv0+hlf0 - d2ice*t_ice
64 !==== fms constants ====================
65 
66  real, parameter :: qrmin = 1.e-9
67  real, parameter :: qvmin = 1.e-22 ! min value for water vapor (treated as zero)
68  real, parameter :: qcmin = 1.e-12 ! min value for cloud condensates
69  real, parameter :: sfcrho = 1.20 ! surface air density
70  real, parameter :: vmin = 1.e-3 ! minimum fall speed for rain/graupel
71  real, parameter :: rhor = 1.0e3 ! LFO83
72  real, parameter :: dz_min = 1.e-2
73  real :: cracs, csacr, cgacr, cgacs, acco(3,4), csacw, &
74  craci, csaci, cgacw, cgaci, cracw, cssub(5), cgsub(5), &
75  crevp(5), cgfr(2), csmlt(5), cgmlt(5)
76  real :: es0, ces0
77  real :: pie, rgrav, fac_rc
78  real :: lcp, icp, tcp
79  real :: lv00, c_air, c_vap
80 
81  logical :: de_ice = .true. !
82  logical :: sedi_transport = .false. !
83  logical :: do_sedi_w = .false.
84  logical :: do_sedi_heat = .false. !
85  logical :: prog_ccn = .false. ! do prognostic CCN (Yi Ming's method)
86  logical :: do_qa = .false. ! do inline cloud fraction
87  logical :: rad_snow =.false.
88  logical :: rad_graupel =.false.
89  logical :: rad_rain =.false.
90  logical :: fix_negative =.false.
91  logical :: do_setup=.true.
92  logical :: master
93  logical :: p_nonhydro = .false.
94 
95  real, allocatable:: table(:), table2(:), table3(:), tablew(:), des(:), des2(:), des3(:), desw(:)
96  logical :: tables_are_initialized = .false.
97 
100  real :: lati, latv, lats
101 
102  real, parameter :: dt_fr = 8. ! homogeneous freezing of all cloud water at t_wfr - dt_fr
103  ! minimum temperature water can exist (Moore & Molinero Nov. 2011, Nature)
104  ! dt_fr can be considered as the error bar
105  integer :: lin_cld_mp_clock ! clock for timing of driver routine
106 
107  real :: t_snow_melt = 12. ! snow melt tempearture scale factor
108  real :: t_grau_melt = 15. ! graupel melt tempearture scale factor
109  real :: p_min = 100. ! minimum pressure (Pascal) for MP to operate
110 
111 ! The defaults are good for 25-50 km simulation
112 ! For cloud-resolving: 1-5 km
113 ! qi0_crt = 0.8E-4
114 ! qs0_crt = 0.6E-3
115 ! c_psaci = 0.1
116 ! c_pgacs = 0.1
117 !----------------------
118 ! namelist parameters:
119 !----------------------
120  real :: cld_min = 0.05
121  real :: tice = 273.16 ! set tice = 165. to trun off ice-phase phys (Kessler emulator)
122 
123  real :: qc_crt = 5.0e-8 ! minimum condensate mixing ratio to allow partial cloudiness
124  real :: t_min = 180. ! Min temp to freeze-dry all water vapor
125  real :: t_sub = 184. ! Min temp for sublimation of cloud ice
126  real :: mp_time = 150. ! maximum micro-physics time step (sec)
127 
128  real :: rh_inc = 0.10 ! rh increment for complete evap of ql and qi
129  real :: rh_inr = 0.25
130  real :: rh_ins = 0.25 ! rh increment for sublimation of snow
131 
132  real :: tau_r = 120. ! rain freezing time scale during fast_sat
133 ! The following 3 time scales are for melting during terminal falls
134  real :: tau_s = 120. ! snow melt
135  real :: tau_g = 180. ! graupel melt
136  real :: tau_mlt = 10. ! ice melting time-scale
137 
138 ! Fast MP:
139  real :: tau_i2s = 150. !
140 ! cloud water
141  real :: tau_v2l = 600. ! vapor --> cloud water (condensation) time scale
142  real :: tau_l2v = 600. ! cloud water --> vapor (evaporation) time scale
143 ! Graupel
144  real :: tau_g2v = 900. ! Grapuel sublimation time scale
145  real :: tau_v2g =21600. ! Grapuel deposition -- make it a slow process
146 
147  real :: dw_land = 0.20 ! base value for subgrid deviation/variability over land
148  real :: dw_ocean = 0.15 ! base value for ocean
149  real :: ccn_o = 100.
150  real :: ccn_l = 250.
151  real :: rthresh = 10.0e-6 ! critical cloud drop radius (micro m)
152 
153 !-------------------------------------------------------------
154 ! WRF/WSM6 scheme: qi_gen = 4.92e-11 * (1.e3*exp(0.1*tmp))**1.33
155 ! optimized: qi_gen = 4.92e-11 * exp( 1.33*log(1.e3*exp(0.1*tmp)) )
156 ! qi_gen ~ 4.808e-7 at 0 C; 1.818e-6 at -10 C, 9.82679e-5 at -40C
157 ! the following value is constructed such that qc_crt = 0 at zero C and @ -10C matches
158 ! WRF/WSM6 ice initiation scheme; qi_crt = qi_gen*min(qi_lim, 0.1*tmp) / den
159  real :: qi_gen = 1.818e-6
160  real :: qi_lim = 1.
161  real :: ql_mlt = 4.0e-3 ! max value of cloud water allowed from melted cloud ice
162  real :: ql_gen = 1.0e-3 ! max ql generation during remapping step if fast_sat_adj = .T.
163  real :: sat_adj0 = 0.99 ! adjustment factor (0: no, 1: full) during fast_sat_adj
164 
165 ! Cloud condensate upper bounds: "safety valves" for ql & qi
166  real :: ql0_max = 2.0e-3 ! max ql value (converted to rain)
167  real :: qi0_max = 3.0e-6 ! max qi value (by other sources)
168 
169  real :: qi0_crt = 1.0e-4 ! ice --> snow autocon threshold (was 1.E-4)
170  ! qi0_crt is highly dependent on horizontal resolution
171  real :: qr0_crt = 1.0e-4 ! rain --> snow or graupel/hail threshold
172  ! LFO used *mixing ratio* = 1.E-4 (hail in LFO)
173  real :: c_paut = 0.55 ! autoconversion ql --> qr (use 0.5 to reduce autoconversion)
174  real :: c_psaut = 1.0e-3 ! autoconversion rate: cloud_ice -> snow
175  real :: c_psaci = 0.01 ! accretion: cloud ice --> snow (was 0.1 in Zetac)
176  real :: c_piacr = 5.0 ! accretion: rain --> ice:
177  real :: c_cracw = 0.9 ! rain accretion efficiency
178 
179 ! Decreasing clin to reduce csacw (so as to reduce cloud water ---> snow)
180  real :: alin = 842.0
181  real :: clin = 4.8 ! 4.8 --> 6. (to ehance ql--> qs)
182 
183 !-----------------
184 ! Graupel control:
185 !-----------------
186  real :: qs0_crt = 2.0e-3 ! snow --> graupel density threshold (0.6e-3 in Purdue Lin scheme)
187  real :: c_pgacs = 2.0e-3 ! snow --> graupel "accretion" eff. (was 0.1 in Zetac)
188 
189 ! fall velocity tuning constants:
190  real :: den_ref = sfcrho ! Reference (surface) density for fall speed
191  ! Larger value produce larger fall speed
192  real :: vr_fac = 1.
193  real :: vs_fac = 1.
194  real :: vg_fac = 1.
195  real :: vi_fac = 1.
196 
197  logical :: fast_sat_adj = .false.
198  logical :: z_slope_liq = .true. ! use linear mono slope for autocconversions
199  logical :: z_slope_ice = .false. ! use linear mono slope for autocconversions
200  logical :: use_deng_mace = .true. ! Helmfield-Donner ice speed
201  logical :: do_subgrid_z = .false. ! 2X resolution sub-grid saturation/cloud scheme
202  logical :: use_ccn = .false.
203  logical :: use_ppm = .true.
204  logical :: ppm_rain_fall = .true.
205  logical :: mono_prof = .true. ! perform terminal fall with mono ppm scheme
206  logical :: mp_debug = .false.
207  logical :: mp_print = .false.
208 
209  real :: global_area = -1.
210 
211  real :: tice0, t_wfr
212  real :: p_crt = 100.e2 !
213  integer:: k_moist = 100
214 
215  namelist /lin_cld_microphys_nml/mp_time, t_min, t_sub, tau_s, tau_g, dw_land, dw_ocean, &
225 
226  contains
227 
228 
229  subroutine lin_cld_microphys_driver(qv, ql, qr, qi, qs, qg, qa, qn, &
230  qv_dt, ql_dt, qr_dt, qi_dt, qs_dt, qg_dt, qa_dt, &
231  pt_dt, pt, w, uin, vin, udt, vdt, dz, delp, area, dt_in, &
232  land, rain, snow, ice, graupel, &
233  hydrostatic, phys_hydrostatic, &
234  iis,iie, jjs,jje, kks,kke, ktop, kbot, time)
235 ! kks == 1; kke == kbot == npz
236  type(time_type), intent(in):: time
237  logical, intent(in):: hydrostatic, phys_hydrostatic
238  integer, intent(in):: iis,iie, jjs,jje ! physics window
239  integer, intent(in):: kks,kke ! vertical dimension
240  integer, intent(in):: ktop, kbot ! vertical compute domain
241  real, intent(in):: dt_in
242 
243  real, intent(in ), dimension(:,:) :: area
244  real, intent(in ), dimension(:,:) :: land !land fraction
245  real, intent(out ), dimension(:,:) :: rain, snow, ice, graupel
246  real, intent(in ), dimension(:,:,:):: delp, dz, uin, vin
247  real, intent(in ), dimension(:,:,:):: pt, qv, ql, qr, qg, qa, qn
248  real, intent(inout), dimension(:,:,:):: qi, qs
249  real, intent(inout), dimension(:,:,:):: pt_dt, qa_dt, udt, vdt, w
250  real, intent(inout), dimension(:,:,:):: qv_dt, ql_dt, qr_dt, qi_dt, &
251  qs_dt, qg_dt
252 
253 
254 ! local:
255  logical used
256  real :: mpdt, rdt, dts, convt, tot_prec
257  integer :: i,j,k
258  integer :: is,ie, js,je ! physics window
259  integer :: ks,ke ! vertical dimension
260  integer :: seconds, days, ntimes
261 
262  real, dimension(iie-iis+1,jje-jjs+1) :: prec1, prec_mp, cond, w_var, rh0, maxdbz
263  real, dimension(iie-iis+1,jje-jjs+1,kke-kks+1) :: vt_r, vt_s, vt_g, vt_i, qn2, dbz
264  real, dimension(size(pt,1), size(pt,3)) :: m2_rain, m2_sol
265 
266  real :: allmax
267 
268  is = 1
269  js = 1
270  ks = 1
271  ie = iie-iis+1
272  je = jje-jjs+1
273  ke = kke-kks+1
274 
275  call mpp_clock_begin (lin_cld_mp_clock)
276 
277  if ( phys_hydrostatic .or. hydrostatic ) then
278  lv00 = lv0
279  c_air = cp_air
280  c_vap = cp_vapor
281  p_nonhydro = .false.
282  else
283  lv00 = lv0
284  c_air = cv_air
285  c_vap = cv_vap
286  p_nonhydro = .true.
287  endif
288  if ( hydrostatic ) do_sedi_w = .false.
289  latv = hlv
290  lati = hlf
291  lats = latv + lati
292  lcp = latv / cp_air
293  icp = lati / cp_air
294  tcp = (latv+lati) / cp_air
295 
296 ! tendency zero out for am moist processes should be done outside the driver
297  mpdt = min(dt_in, mp_time)
298  rdt = 1. / dt_in
299  ntimes = nint( dt_in/mpdt )
300 ! small time step:
301  dts = dt_in / real(ntimes)
302 
303  call get_time (time, seconds, days)
304 
305 
306  do j=js, je
307  do i=is, ie
308  graupel(i,j) = 0.
309  rain(i,j) = 0.
310  snow(i,j) = 0.
311  ice(i,j) = 0.
312  cond(i,j) = 0.
313  enddo
314  enddo
315  do j=js,je
316  call mpdrv( hydrostatic, uin, vin, w, delp, pt, qv, ql, qr, qi, qs, qg, qa, qn, dz, &
317  is, ie, js, je, ks, ke, ktop, kbot, j, dt_in, &
318  ntimes, rain(:,j), snow(:,j), graupel(:,j), &
319  ice(:,j), m2_rain, m2_sol, cond(:,j), area(:,j), land(:,j), &
320  udt, vdt, pt_dt, qv_dt, ql_dt, qr_dt, qi_dt, &
321  qs_dt, qg_dt, qa_dt, &
322  w_var, vt_r, vt_s, vt_g, vt_i, qn2 )
323 
324  enddo
325 
326 ! no clouds allowed above ktop
327  if ( ks < ktop ) then
328  do k=ks, ktop
329  if ( do_qa ) then
330  do j=js,je
331  do i=is,ie
332  qa_dt(i,j,k) = 0.
333  enddo
334  enddo
335  else
336  do j=js,je
337  do i=is,ie
338  qa_dt(i,j,k) = -qa(i,j,k) * rdt
339  enddo
340  enddo
341  endif
342  enddo
343  endif
344 
345 #ifndef MAPL_MODE
346  if ( id_vtr> 0 ) then
347  used=send_data(id_vtr, vt_r, time, is_in=iis, js_in=jjs)
348  endif
349 
350  if ( id_vts> 0 ) then
351  used=send_data(id_vts, vt_s, time, is_in=iis, js_in=jjs)
352  endif
353 
354  if ( id_vtg> 0 ) then
355  used=send_data(id_vtg, vt_g, time, is_in=iis, js_in=jjs)
356  endif
357 
358  if ( id_vti> 0 ) then
359  used=send_data(id_vti, vt_i, time, is_in=iis, js_in=jjs)
360  endif
361 
362  if ( id_droplets> 0 ) then
363  used=send_data(id_droplets, qn2, time, is_in=iis, js_in=jjs)
364  endif
365 
366  if ( id_var> 0 ) then
367  used=send_data(id_var, w_var, time, is_in=iis, js_in=jjs)
368  endif
369 #endif
370 
371 ! Convert to mm/day
372  convt = 86400.*rdt*rgrav
373  do j=js,je
374  do i=is,ie
375  rain(i,j) = rain(i,j) * convt
376  snow(i,j) = snow(i,j) * convt
377  ice(i,j) = ice(i,j) * convt
378  graupel(i,j) = graupel(i,j) * convt
379  prec_mp(i,j) = rain(i,j) + snow(i,j) + ice(i,j) + graupel(i,j)
380  enddo
381  enddo
382 
383 #ifndef MAPL_MODE
384  if ( id_cond>0 ) then
385  do j=js,je
386  do i=is,ie
387  cond(i,j) = cond(i,j)*rgrav
388  enddo
389  enddo
390  used=send_data(id_cond, cond, time, is_in=iis, js_in=jjs)
391  endif
392 
393  if ( id_snow>0 ) then
394 ! used=send_data(id_snow, snow, time, iis, jjs)
395  used=send_data(id_snow, snow, time, is_in=iis, js_in=jjs)
396  if ( mp_print .and. seconds==0 ) then
397  tot_prec = g_sum(snow, is, ie, js, je, area, 1)
398  if(master) write(*,*) 'mean snow=', tot_prec
399  endif
400  endif
401 
402  if ( id_graupel>0 ) then
403 ! used=send_data(id_graupel, graupel, time, iis, jjs)
404  used=send_data(id_graupel, graupel, time, is_in=iis, js_in=jjs)
405  if ( mp_print .and. seconds==0 ) then
406  tot_prec = g_sum(graupel, is, ie, js, je, area, 1)
407  if(master) write(*,*) 'mean graupel=', tot_prec
408  endif
409  endif
410 
411  if ( id_ice>0 ) then
412 ! used=send_data(id_ice, ice, time, iis, jjs)
413  used=send_data(id_ice, ice, time, is_in=iis, js_in=jjs)
414  if ( mp_print .and. seconds==0 ) then
415  tot_prec = g_sum(ice, is, ie, js, je, area, 1)
416  if(master) write(*,*) 'mean ice_mp=', tot_prec
417  endif
418  endif
419 
420  if ( id_rain>0 ) then
421 ! used=send_data(id_rain, rain, time, iis, jjs)
422  used=send_data(id_rain, rain, time, is_in=iis, js_in=jjs)
423  if ( mp_print .and. seconds==0 ) then
424  tot_prec = g_sum(rain, is, ie, js, je, area, 1)
425  if(master) write(*,*) 'mean rain=', tot_prec
426  endif
427  endif
428 
429  if ( id_rh>0 ) then !Not used?
430 ! used=send_data(id_rh, rh0, time, iis, jjs)
431  used=send_data(id_rh, rh0, time, is_in=iis, js_in=jjs)
432  endif
433 
434 
435  if ( id_prec>0 ) then
436 ! used=send_data(id_prec, prec_mp, time, iis, jjs)
437  used=send_data(id_prec, prec_mp, time, is_in=iis, js_in=jjs)
438  endif
439 
440  if ( id_dbz>0 .or. id_maxdbz>0 .or. id_basedbz>0) then
441  call dbzcalc(qv, qr, qs, qg, pt, delp, dz, &
442  dbz, maxdbz, allmax, is, ie, js, je, ks, ke, .true., .true., .true., .true.)
443  if (id_dbz > 0) then
444  used=send_data(id_dbz, dbz, time, is_in=iis, js_in=jjs)
445  endif
446  if (id_maxdbz > 0) then
447  used=send_data(id_maxdbz, maxdbz, time, is_in=iis, js_in=jjs)
448  endif
449  if (id_basedbz > 0) then
450  !interpolate to 1km dbz
451  !Reusing maxdbz
452  do j=js,je
453  do i=is,ie
454  maxdbz(i,j) = dbz(i,j,ke)
455  enddo
456  enddo
457  used=send_data(id_basedbz, maxdbz, time, is_in=iis, js_in=jjs)
458  endif
459 
460  if (mp_print .and. seconds == 0) then
461  call mpp_max(allmax)
462  if (master) write(*,*) 'max reflectivity = ', allmax, ' dBZ'
463  endif
464 
465  endif
466 
467 !----------------------------------------------------------------------------
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 #endif
480 
481 
482  call mpp_clock_end (lin_cld_mp_clock)
483 
484  end subroutine lin_cld_microphys_driver
485 
486 
487 
488  subroutine mpdrv( hydrostatic, uin, vin, w, delp, pt, qv, ql, qr, qi, qs, qg, qa, qn, dz, &
489  is, ie, js, je, ks, ke, ktop, kbot, j, dt_in, ntimes, &
490  rain, snow, graupel, ice, m2_rain, m2_sol, &
491  cond, area1, land, u_dt, v_dt, pt_dt, qv_dt, ql_dt, qr_dt, qi_dt, &
492  qs_dt, qg_dt, qa_dt, &
493  w_var, vt_r, vt_s, vt_g, vt_i, qn2 )
495 !-------------------------------------------------------------------
496 ! lin et al., 1983, jam, 1065-1092, and
497 ! rutledge and hobbs, 1984, jas, 2949-2972
498 !-------------------------------------------------------------------
499 ! terminal fall is handled lagrangianly by conservative fv algorithm
500 !
501 ! pt: temperature (k)
502 ! 6 water species:
503 ! 1) qv: water vapor (kg/kg)
504 ! 2) ql: cloud water (kg/kg)
505 ! 3) qr: rain (kg/kg)
506 ! 4) qi: cloud ice (kg/kg)
507 ! 5) qs: snow (kg/kg)
508 ! 6) qg: graupel (kg/kg)
509 
510  logical, intent(in):: hydrostatic
511  integer, intent(in):: j, is,ie, js,je, ks,ke
512  integer, intent(in):: ntimes, ktop, kbot
513  real, intent(in):: dt_in
514 
515  real, intent(in), dimension(is:):: area1, land
516  real, intent(in), dimension(is:,js:,ks:):: uin, vin, delp, pt, qv, ql, qr, qg, qa, qn, dz
517  real, intent(inout), dimension(is:,js:,ks:):: qi, qs
518  real, intent(inout), dimension(is:,js:,ks:):: u_dt, v_dt, w, pt_dt, qa_dt, &
519  qv_dt, ql_dt, qr_dt, qi_dt, qs_dt, qg_dt
520  real, intent(inout), dimension(is:):: rain, snow, ice, graupel, cond
521  real, intent(out), dimension(is:,js:) :: w_var
522  real, intent(out), dimension(is:,js:,ks:) :: vt_r, vt_s, vt_g, vt_i, qn2
523  real, intent(out), dimension(is:,ks:):: m2_rain, m2_sol
524 
525 !----------
526 ! local var
527 !----------
528  real, dimension(ktop:kbot):: qvz, qlz, qrz, qiz, qsz, qgz, qaz, &
529  vtiz, vtsz, vtgz, vtrz, dp0, &
530  dp1, qv0, ql0, qr0, qi0, qs0, qg0, qa0, t0, den, &
531  den0, tz, p1, dz0, dz1, denfac
532  real, dimension(ktop:kbot):: ccn, c_praut, m1_rain, m1_sol, m1, u0, v0, u1, v1, w1
533  real :: cpaut, rh_adj, rh_rain
534  real :: r1, s1, i1, g1, rdt, ccn0
535  real :: dt_rain, dts, fac_sno, fac_gra
536  real :: s_leng, t_land, t_ocean, h_var
537  real :: cvm, tmp, omq
538  real :: dqi, qio, qin
539  integer :: i,k,n
540 
541  dts = dt_in / real(ntimes)
542  dt_rain = dts * 0.5
543 
544  fac_sno = 1. - exp( -0.5*dts/tau_s )
545  fac_gra = 1. - exp( -0.5*dts/tau_g )
546 
547  rdt = 1. / dt_in
548 
549 ! SJL: 20150210
550  cpaut = c_paut*0.104*grav/1.717e-5
551 
552  do 2000 i=is, ie
553  do k=ktop, kbot
554  qiz(k) = qi(i,j,k)
555  qsz(k) = qs(i,j,k)
556  enddo
557  if ( de_ice ) then
558 ! This is to prevent excessive build-up of cloud ice from external sources
559  do k=ktop, kbot
560  qio = qiz(k) - dt_in*qi_dt(i,j,k) ! original qi before phys
561  qin = max(qio, qi0_max) ! Adjusted value
562  if ( qiz(k) > qin ) then
563  qsz(k) = qsz(k) + qiz(k) - qin
564  qiz(k) = qin
565  dqi = (qin - qio)*rdt ! modified qi tendency
566  qs_dt(i,j,k) = qs_dt(i,j,k) + qi_dt(i,j,k) - dqi
567  qi_dt(i,j,k) = dqi
568  qi(i,j,k) = qiz(k)
569  qs(i,j,k) = qsz(k)
570  endif
571  enddo
572  endif
573 
574  do k=ktop, kbot
575  t0(k) = pt(i,j,k)
576  tz(k) = t0(k)
577  dp1(k) = delp(i,j,k)
578  dp0(k) = dp1(k) ! moist air mass * grav
579 !-- Moist mixing ratios ------------
580  qvz(k) = qv(i,j,k)
581  qlz(k) = ql(i,j,k)
582  qrz(k) = qr(i,j,k)
583  qgz(k) = qg(i,j,k)
584 !-- dp1: Dry air_mass
585  dp1(k) = dp1(k)*(1. -(qvz(k)+qlz(k)+qrz(k)+qiz(k)+qsz(k)+qgz(k)))
586 !-- Convert to dry mixing ratios
587  omq = dp0(k) / dp1(k)
588  qvz(k) = qvz(k)*omq
589  qlz(k) = qlz(k)*omq
590  qrz(k) = qrz(k)*omq
591  qiz(k) = qiz(k)*omq
592  qsz(k) = qsz(k)*omq
593  qgz(k) = qgz(k)*omq
594 !-----------------------------------
595  qa0(k) = qa(i,j,k)
596  qaz(k) = 0.
597  dz0(k) = dz(i,j,k)
598 !--------------------------
599  den0(k) = -dp1(k)/(grav*dz0(k)) ! density of dry air
600  p1(k) = den0(k)*rdgas*t0(k) ! dry air pressure
601 !------------------------------
602 ! Save a copy of old value for computing tendencies
603  qv0(k) = qvz(k)
604  ql0(k) = qlz(k)
605  qr0(k) = qrz(k)
606  qi0(k) = qiz(k)
607  qs0(k) = qsz(k)
608  qg0(k) = qgz(k)
609 ! *** For sedi_momentum ***
610  m1(k) = 0.
611  u0(k) = uin(i,j,k)
612  v0(k) = vin(i,j,k)
613  u1(k) = u0(k)
614  v1(k) = v0(k)
615 ! *** For sedi_momentum ***
616  enddo
617 
618  if ( do_sedi_w ) then
619  do k=ktop, kbot
620  w1(k) = w(i,j,k)
621  enddo
622  endif
623 ! Based on Klein Eq. 15
624 
625  if ( prog_ccn ) then
626  do k=ktop, kbot
627 !convert #/cc to #/m^3
628  ccn(k) = qn(i,j,k) * 1.e6
629  c_praut(k) = cpaut * (ccn(k)*rhor)**(-1./3.)
630  enddo
631  use_ccn = .false.
632  else
633  ccn0 = (ccn_l*land(i) + ccn_o*(1.-land(i))) * 1.e6
634  if ( use_ccn ) then
635 ! *** CCN is formulted as CCN = CCN_surface * (den/den_surface) ***
636  ccn0 = ccn0 * rdgas*tz(kbot)/p1(kbot)
637  endif
638  tmp = cpaut * (ccn0*rhor)**(-1./3.)
639  do k=ktop, kbot
640  c_praut(k) = tmp
641  ccn(k) = ccn0
642  enddo
643  endif
644 
645 !--------------------------------------------------------
646 ! Total water subgrid deviation in horizontal direction
647 !--------------------------------------------------------
648 ! default area dependent form: use dx ~ 100 km as the base
649  s_leng = sqrt(sqrt(area1(i)/1.e10))
650  t_land = dw_land * s_leng
651  t_ocean = dw_ocean * s_leng
652  h_var = t_land*land(i) + t_ocean*(1.-land(i))
653  h_var = min(0.20, max(0.01, h_var)) ! cap:
654  if ( id_var>0 ) w_var(i,j) = h_var
655 
656  rh_adj = 1. - h_var - rh_inc
657  rh_rain = max(0.35, rh_adj - rh_inr)
658 
659 !-------------------------
660 ! * fix all negatives
661 !-------------------------
662 
663  if ( fix_negative ) &
664  call neg_adj(ktop, kbot, p1, tz, dp1, qvz, qlz, qrz, qiz, qsz, qgz)
665 
666  m2_rain(:,:) = 0.
667  m2_sol(:,:) = 0.
668  do 1000 n=1,ntimes
669 
670  if ( p_nonhydro ) then
671  do k=ktop, kbot
672  dz1(k) = dz0(k)
673  den(k) = den0(k) ! dry air density remains the same
674  denfac(k) = sqrt(sfcrho/den(k))
675  enddo
676  else
677  do k=ktop, kbot
678  dz1(k) = dz0(k)*tz(k)/t0(k) ! hydrostatic balance
679  den(k) = den0(k)*dz0(k)/dz1(k)
680  denfac(k) = sqrt(sfcrho/den(k))
681  enddo
682  endif
683 
684 !-------------------------------------------
685 ! Time-split warm rain processes: first pass
686 !-------------------------------------------
687  call warm_rain(dt_rain, ktop, kbot, p1, dp1, dz1, tz, qvz, qlz, qrz, qiz, qsz, qgz, p1, den, denfac, ccn, &
688  c_praut, rh_rain, vtrz, r1, m1_rain, w1, h_var)
689  rain(i) = rain(i) + r1
690  do k=ktop, kbot
691  m2_rain(i,k) = m2_rain(i,k) + m1_rain(k)
692  m1(k) = m1(k) + m1_rain(k)
693  enddo
694 
695 !------------------------------------------------
696 ! * sedimentation of cloud ice, snow, and graupel
697 !------------------------------------------------
698  call fall_speed(ktop, kbot, den, qsz, qiz, qgz, qlz, tz, vtsz, vtiz, vtgz)
699 
700  call terminal_fall ( dts, ktop, kbot, tz, qvz, qlz, qrz, qgz, qsz, qiz, p1, &
701  dz1, dp1, den, vtgz, vtsz, vtiz, fac_sno, fac_gra, &
702  r1, g1, s1, i1, m1_sol, w1 )
703 
704  rain(i) = rain(i) + r1 ! from melted snow & ice that reached the ground
705  snow(i) = snow(i) + s1
706  graupel(i) = graupel(i) + g1
707  ice(i) = ice(i) + i1
708  if ( do_sedi_heat ) &
709  call sedi_heat(ktop, kbot, dp1, m1_sol, dz1, tz, qvz, qlz, qrz, qiz, qsz, qgz, c_ice)
710 
711 !-------------------------------------------
712 ! Time-split warm rain processes: 2nd pass
713 !-------------------------------------------
714  call warm_rain(dt_rain, ktop, kbot, p1, dp1, dz1, tz, qvz, qlz, qrz, qiz, qsz, qgz, p1, den, denfac, ccn, &
715  c_praut, rh_rain, vtrz, r1, m1_rain, w1, h_var)
716  rain(i) = rain(i) + r1
717  do k=ktop, kbot
718  m2_rain(i,k) = m2_rain(i,k) + m1_rain(k)
719  m2_sol(i,k) = m2_sol(i,k) + m1_sol(k)
720  m1(k) = m1(k) + m1_rain(k) + m1_sol(k)
721  enddo
722 
723 !-------------------------
724 ! * ice-phase microphysics
725 !-------------------------
726 
727  call icloud( ktop, kbot, tz, p1, qvz, qlz, qrz, qiz, qsz, qgz, &
728  dp1, den, denfac, vtsz, vtgz, vtrz, qaz, rh_adj, rh_rain, dts, fac_sno, fac_gra, h_var )
729 
730 1000 continue ! sub-cycle
731  if ( sedi_transport ) then
732 ! Note: dp1 is dry mass; dp0 is the old moist (total) mass
733  do k = ktop+1, kbot
734  u1(k) = (dp0(k)*u1(k) + m1(k-1)*u1(k-1))/(dp0(k)+m1(k-1))
735  v1(k) = (dp0(k)*v1(k) + m1(k-1)*v1(k-1))/(dp0(k)+m1(k-1))
736  u_dt(i,j,k) = u_dt(i,j,k) + (u1(k)-u0(k))*rdt
737  v_dt(i,j,k) = v_dt(i,j,k) + (v1(k)-v0(k))*rdt
738  enddo
739  endif
740  if ( do_sedi_w ) then
741  do k = ktop, kbot
742  w(i,j,k) = w1(k)
743  enddo
744  endif
745 
746  do k = ktop, kbot
747 ! update moist air mass (actually hydrostatic pressure)
748 !-- Convert to dry mixing ratios
749  omq = dp1(k) / dp0(k)
750  qv_dt(i,j,k) = qv_dt(i,j,k) + rdt*(qvz(k)-qv0(k))*omq
751  ql_dt(i,j,k) = ql_dt(i,j,k) + rdt*(qlz(k)-ql0(k))*omq
752  qr_dt(i,j,k) = qr_dt(i,j,k) + rdt*(qrz(k)-qr0(k))*omq
753  qi_dt(i,j,k) = qi_dt(i,j,k) + rdt*(qiz(k)-qi0(k))*omq
754  qs_dt(i,j,k) = qs_dt(i,j,k) + rdt*(qsz(k)-qs0(k))*omq
755  qg_dt(i,j,k) = qg_dt(i,j,k) + rdt*(qgz(k)-qg0(k))*omq
756  cvm = c_air + qvz(k)*c_vap + (qrz(k)+qlz(k))*c_liq + (qiz(k)+qsz(k)+qgz(k))*c_ice
757  pt_dt(i,j,k) = pt_dt(i,j,k) + rdt*(tz(k)- t0(k))*cvm/cp_air
758  enddo
759 
760  do k = ktop, kbot
761  if ( do_qa ) then
762  qa_dt(i,j,k) = 0.
763  else
764  qa_dt(i,j,k) = qa_dt(i,j,k) + rdt*( qaz(k)/real(ntimes)-qa0(k))
765  endif
766  enddo
767 
768 !-----------------
769 ! fms diagnostics:
770 !-----------------
771 
772  if ( id_cond>0 ) then
773  do k=ktop,kbot ! total condensate
774  cond(i) = cond(i) + dp1(k)*(qlz(k)+qrz(k)+qsz(k)+qiz(k)+qgz(k))
775  enddo
776  endif
777 
778  if ( id_vtr> 0 ) then
779  do k=ktop, kbot
780  vt_r(i,j,k) = vtrz(k)
781  enddo
782  endif
783  if ( id_vts> 0 ) then
784  do k=ktop, kbot
785  vt_s(i,j,k) = vtsz(k)
786  enddo
787  endif
788  if ( id_vtg> 0 ) then
789  do k=ktop, kbot
790  vt_g(i,j,k) = vtgz(k)
791  enddo
792  endif
793  if ( id_vts> 0 ) then
794  do k=ktop, kbot
795  vt_i(i,j,k) = vtiz(k)
796  enddo
797  endif
798 
799  if ( id_droplets> 0 ) then
800  do k=ktop, kbot
801  qn2(i,j,k) = ccn(k)
802  enddo
803  endif
804 
805 2000 continue
806 
807  end subroutine mpdrv
808 
809 
810 
811  subroutine sedi_heat(ktop, kbot, dm, m1, dz, tz, qv, ql, qr, qi, qs, qg, cw)
812  integer, intent(in):: ktop, kbot
813 ! Input q fields are dry mixing ratios, and dm is dry air mass
814  real, intent(in ), dimension(ktop:kbot):: dm, m1, dz, qv, ql, qr, qi, qs, qg
815  real, intent(inout), dimension(ktop:kbot):: tz
816  real, intent(in):: cw
817 !
818  real,dimension(ktop:kbot):: dgz, cvm, cvn
819  real :: tmp
820  integer:: k
821 
822 
823  do k=ktop, kbot
824  dgz(k) = -0.5*grav*dz(k) ! > 0
825  cvn(k) = dm(k)*(cv_air + qv(k)*cv_vap + (qr(k)+ql(k))*c_liq + (qi(k)+qs(k)+qg(k))*c_ice)
826  enddo
827 
828 ! SJL July 2014
829 ! Assumption: the KE in the falling condensates is negligible compared to the potential energy
830 ! that was unaccounted for. Local thermal equilibrium is assumed, and the loss in PE is transformed
831 ! into internal energy (to heat the whole grid box)
832 ! Backward time-implicit upwind transport scheme:
833 ! dm here is dry air mass
834 
835  k = ktop
836  tmp = cvn(k) + m1(k)*cw
837  tz(k) = (tmp*tz(k) + m1(k)*dgz(k) ) / tmp
838 
839  do k=ktop+1, kbot
840  tz(k) = ( (cvn(k)+cw*(m1(k)-m1(k-1)))*tz(k) + m1(k-1)*cw*tz(k-1) + dgz(k)*(m1(k-1)+m1(k)) ) &
841  / ( cvn(k)+cw*m1(k) )
842  enddo
843 
844  end subroutine sedi_heat
845 
846 
847  subroutine warm_rain( dt, ktop, kbot, p1, dp, dz, tz, qv, ql, qr, qi, qs, qg, pm, &
848  den, denfac, ccn, c_praut, rh_rain, vtr, r1, m1_rain, w1, h_var)
850  integer, intent(in):: ktop, kbot
851  real, intent(in):: dt ! time step (s)
852  real, intent(in), dimension(ktop:kbot):: dp, p1, dz, pm, den, denfac, ccn, c_praut
853  real, intent(in):: rh_rain, h_var
854  real, intent(inout), dimension(ktop:kbot):: tz, qv, ql, qr, qi, qs, qg, vtr
855  real, intent(out):: r1
856  real, intent(inout), dimension(ktop:kbot):: m1_rain, w1
857 
858 ! local:
859  real, parameter:: so3 = 7./3.
860  real, dimension(ktop:kbot):: dl, dm
861  real, dimension(ktop:kbot+1):: ze, zt
862  real :: sink, dq, qc0, qc
863  real :: rho0, qden
864  real :: zs = 0.
865  real :: dt5
866  integer k
867 !-----------------------------------------------------------------------
868 ! fall velocity constants:
869 !-----------------------------------------------------------------------
870  real, parameter :: vconr = 2503.23638966667
871  real, parameter :: normr = 25132741228.7183
872  real, parameter :: thr=1.e-10
873  logical no_fall
874 
875 !---------------------
876 ! warm-rain processes:
877 !---------------------
878 
879  dt5 = 0.5*dt
880 
881 !------------------------
882 ! Terminal speed of rain:
883 !------------------------
884 
885  m1_rain(:) = 0.
886  call check_column(ktop, kbot, qr, no_fall)
887  if ( no_fall ) then
888  vtr(:) = vmin
889  r1 = 0.
890  go to 999 ! jump to auto-conversion
891  endif
892 
893  if ( den_ref < 0. ) then
894  rho0 = -den_ref*den(kbot)
895  else
896  rho0 = den_ref ! default=1.2
897  endif
898 
899  do k=ktop, kbot
900  qden = qr(k)*den(k)
901  if ( qr(k) < thr ) then
902  vtr(k) = vmin
903  else
904  vtr(k) = max(vmin, vr_fac*vconr*sqrt(min(10., rho0/den(k)))*exp(0.2*log(qden/normr)))
905  endif
906  enddo
907 
908  ze(kbot+1) = zs
909  do k=kbot, ktop, -1
910  ze(k) = ze(k+1) - dz(k) ! dz<0
911  enddo
912  zt(ktop) = ze(ktop)
913 
914 
915  do k=ktop+1,kbot
916  zt(k) = ze(k) - dt5*(vtr(k-1)+vtr(k))
917  enddo
918  zt(kbot+1) = zs - dt*vtr(kbot)
919 
920  do k=ktop,kbot
921  if( zt(k+1)>=zt(k) ) zt(k+1) = zt(k) - dz_min
922  enddo
923 
924 ! Evap_acc of rain for 1/2 time step
925  if ( .not. fast_sat_adj ) &
926  call revap_racc( ktop, kbot, dt5, tz, qv, ql, qr, qi, qs, qg, den, denfac, rh_rain, h_var )
927 
928  if ( do_sedi_w ) then
929  do k=ktop, kbot
930  dm(k) = dp(k)*(1.+qv(k)+ql(k)+qr(k)+qi(k)+qs(k)+qg(k))
931  enddo
932  endif
933 
934  if ( ppm_rain_fall ) then
935  call lagrangian_fall_ppm(ktop, kbot, zs, ze, zt, dp, qr, r1, m1_rain, mono_prof)
936  else
937  call lagrangian_fall_pcm(ktop, kbot, zs, ze, zt, dp, qr, r1, m1_rain)
938  endif
939 
940  if ( do_sedi_w ) then
941  w1(ktop) = (dm(ktop)*w1(ktop)+m1_rain(ktop)*vtr(ktop)) /(dm(ktop)-m1_rain(ktop))
942  do k=ktop+1, kbot
943  w1(k) = (dm(k)*w1(k)-m1_rain(k-1)*vtr(k-1)+m1_rain(k)*vtr(k)) &
944  / (dm(k) +m1_rain(k-1) -m1_rain(k))
945  enddo
946  endif
947  if ( do_sedi_heat ) &
948  call sedi_heat(ktop, kbot, dp, m1_rain, dz, tz, qv, ql, qr, qi, qs, qg, c_liq)
949 ! Finish the remaing 1/2 time step
950  call revap_racc( ktop, kbot, dt5, tz, qv, ql, qr, qi, qs, qg, den, denfac, rh_rain, h_var )
951 
952 999 continue
953 
954 !-------------------
955 ! * auto-conversion
956 !-------------------
957 ! Assuming linear subgrid vertical distribution of cloud water
958 ! following Lin et al. 1994, MWR
959 
960  call linear_prof( kbot-ktop+1, p1(ktop), ql(ktop), dl(ktop), z_slope_liq, h_var )
961 
962 
963 
964  do k=ktop,kbot
965  qc0 = fac_rc*ccn(k)
966  if ( tz(k) > t_wfr + dt_fr ) then
967  dl(k) = min(max(1.e-5, dl(k)), 0.5*ql(k))
968 
969 !--------------------------------------------------------------------
970 ! As in Klein's GFDL AM2 stratiform scheme (with subgrid variations)
971 !--------------------------------------------------------------------
972  if ( use_ccn ) then
973 ! CCN is formulted as CCN = CCN_surface * (den/den_surface)
974  qc = qc0
975  else
976  qc = qc0/den(k)
977  endif
978 
979  dq = 0.5*(ql(k) + dl(k) - qc) ! dq = dl if qc==q_minus = ql - dl
980  ! dq = 0 if qc==q_plus = ql + dl
981  if ( dq > 0. ) then ! q_plus > qc
982 ! Revised continuous form: linearly decays (with subgrid dl) to zero at qc == ql + dl
983  sink = min(1.,dq/dl(k)) * dt*c_praut(k)*den(k)*exp(so3*log(ql(k)))
984  ql(k) = ql(k) - sink
985  qr(k) = qr(k) + sink
986  endif
987  endif
988  enddo
989 
990 
991  end subroutine warm_rain
992 
993  subroutine revap_racc( ktop, kbot, dt, tz, qv, ql, qr, qi, qs, qg, den, denfac, rh_rain, h_var)
994  integer, intent(in):: ktop, kbot
995  real, intent(in):: dt ! time step (s)
996  real, intent(in), dimension(ktop:kbot):: den, denfac
997  real, intent(in) :: rh_rain, h_var
998  real, intent(inout), dimension(ktop:kbot):: tz, qv, qr, ql, qi, qs, qg
999 ! local:
1000  real :: dqv, qsat, dqsdt, evap, t2, qden, q_plus, q_minus, sink
1001  real :: qpz, dq, dqh, tin, lcpk
1002  integer k
1003 
1004  do k=ktop,kbot
1005  if ( tz(k) > t_wfr .and. qr(k) > qrmin ) then
1006 
1007  lcpk = (lv00+dc_vap*tz(k)) / (c_air + qv(k)*c_vap + (qr(k)+ql(k))*c_liq + &
1008  (qi(k)+qs(k)+qg(k))*c_ice)
1009 
1010  tin = tz(k) - lcpk*ql(k) ! presence of clouds suppresses the rain evap
1011  qpz = qv(k) + ql(k)
1012  qsat = wqs2(tin, den(k), dqsdt)
1013  dqh = max(ql(k), h_var*max(qpz, qcmin))
1014  dqv = qsat - qv(k) ! use this to prevent super-sat the gird box
1015  q_minus = qpz - dqh
1016  q_plus = qpz + dqh
1017 
1018 ! qsat must be > q_minus to activate evaporation
1019 ! qsat must be < q_plus to activate accretion
1020 
1021 !-------------------
1022 ! * Rain evaporation
1023 !-------------------
1024  if ( dqv>qvmin .and. qsat > q_minus ) then
1025  if ( qsat > q_plus ) then
1026  dq = qsat - qpz
1027  else
1028 ! q_minus < qsat < q_plus
1029 ! dq == dqh if qsat == q_minus
1030  dq = 0.25*(q_minus-qsat)**2 / dqh
1031  endif
1032  qden = qr(k)*den(k)
1033  t2 = tin*tin
1034  evap = crevp(1)*t2*dq*(crevp(2)*sqrt(qden)+crevp(3)*exp(0.725*log(qden))) &
1035  / (crevp(4)*t2 + crevp(5)*qsat*den(k))
1036  evap = min( qr(k), dt*evap, dqv/(1.+lcpk*dqsdt) )
1037 ! Alternative Minimum Evap in dry environmental air
1038  sink = min( qr(k), dim(rh_rain*qsat, qv(k))/(1.+lcpk*dqsdt) )
1039  evap = max( evap, sink )
1040  qr(k) = qr(k) - evap
1041  qv(k) = qv(k) + evap
1042  tz(k) = tz(k) - evap*lcpk
1043  endif
1044 
1045  if ( qr(k)>qrmin .and. ql(k)>1.e-8 .and. qsat<q_plus ) then
1046 !-------------------
1047 ! * Accretion: pracc
1048 !-------------------
1049  sink = dt*denfac(k)*cracw * exp(0.95*log(qr(k)*den(k)))
1050  sink = sink/(1.+sink)*ql(k)
1051  ql(k) = ql(k) - sink
1052  qr(k) = qr(k) + sink
1053  endif
1054 
1055  endif ! warm-rain
1056  enddo
1057 
1058  end subroutine revap_racc
1059 
1060 
1061  subroutine linear_prof(km, p1, q, dm, z_var, h_var)
1062 ! Used for cloud ice and cloud water autoconversion
1063 ! qi --> ql & ql --> qr
1064 ! Edges: qE == qbar +/- dm
1065  integer, intent(in):: km
1066  real, intent(in ):: p1(km), q(km), h_var
1067  real, intent(out):: dm(km)
1068  logical, intent(in):: z_var
1069 !
1070  real :: dq(km)
1071  integer:: k
1072 
1073  if ( z_var ) then
1074  do k=2,km
1075  dq(k) = 0.5*(q(k) - q(k-1))
1076  enddo
1077  dm(1) = 0.
1078  do k=2, km-1
1079 ! Use twice the strength of the positive definiteness limiter (Lin et al 1994)
1080  dm(k) = 0.5*min(abs(dq(k) + dq(k+1)), 0.5*q(k))
1081  if ( dq(k)*dq(k+1) <= 0. ) then
1082  if ( dq(k) > 0. ) then ! Local max
1083  dm(k) = min( dm(k), dq(k), -dq(k+1) )
1084  else
1085  dm(k) = 0.
1086  endif
1087  endif
1088  enddo
1089  dm(km) = 0.
1090 ! impose a presumed background horizontal variability that is proportional to the value itself
1091  do k=1, km
1092  dm(k) = max( dm(k), qvmin, h_var*q(k) )
1093  enddo
1094  else
1095  do k=1, km
1096  dm(k) = max( qvmin, h_var*q(k) )
1097  enddo
1098  endif
1099 
1100  end subroutine linear_prof
1101 
1102 
1103  subroutine icloud(ktop, kbot, tzk, p1, qvk, qlk, qrk, qik, qsk, qgk, dp1, &
1104  den, denfac, vts, vtg, vtr, qak, rh_adj, rh_rain, dts, fac_sno, fac_gra, h_var)
1106 !----------------------------------------------------
1107 ! Bulk cloud micro-physics; processes splitting
1108 ! with some un-split sub-grouping
1109 ! Time implicit (when possible) accretion and autoconversion
1110 ! Author: Shian-Jiann Lin, GFDL
1111 !-------------------------------------------------------
1112 
1113  integer, intent(in) :: ktop, kbot
1114  real, intent(in), dimension(ktop:kbot):: p1, dp1, den, denfac, vts, vtg, vtr
1115  real, intent(inout), dimension(ktop:kbot):: tzk, qvk, qlk, qrk, qik, qsk, qgk, qak
1116  real, intent(in) :: rh_adj, rh_rain, dts, fac_sno, fac_gra, h_var
1117 ! local:
1118  real, parameter:: rhos = 0.1e3 ! snow density (1/10 of water)
1119  real, dimension(2*(kbot-ktop-1)):: p2, den2, tz2, qv2, ql2, qr2, qi2, qs2, qg2, qa2
1120  real, dimension(ktop:kbot) :: lcpk, icpk, tcpk, di
1121 !!! real :: rh_sno, rh_gra
1122  real :: rdts, fac_g2v, fac_v2g, fac_i2s
1123  real :: tz, qv, ql, qr, qi, qs, qg, melt
1124  real :: pracw, pracs, psacw, pgacw, pgmlt, &
1125  psmlt, prevp, psacr, pgacr, pgfr, pgacs, &
1126  pgaut, pgaci, praci, psaut, psaci, piacr, pgsub
1127  real :: tc, tsq, dqs0, qden, qim, qsm, pssub
1128  real :: factor, sink
1129  real :: tmp1, qsw, qsi, dqsdt, dq
1130  real :: dtmp, qc, q_plus, q_minus, cvm
1131  integer:: km, kn
1132  integer:: i, j, k, k1
1133 
1134 ! rh_sno = max(0.3, rh_adj - rh_ins)
1135 ! rh_gra = rh_sno - 0.05
1136 
1137  fac_i2s = 1. - exp( -dts/tau_i2s )
1138  fac_g2v = 1. - exp( -dts/tau_g2v )
1139  fac_v2g = 1. - exp( -dts/tau_v2g )
1140 
1141  rdts = 1./dts
1142 
1143  do k=ktop,kbot
1144  cvm = c_air + qvk(k)*c_vap + (qlk(k)+qrk(k))*c_liq + (qik(k)+qsk(k)+qgk(k))*c_ice
1145  lcpk(k) = (lv00+dc_vap*tzk(k)) / cvm
1146  icpk(k) = (li00+dc_ice*tzk(k)) / cvm
1147  tcpk(k) = lcpk(k) + icpk(k)
1148  enddo
1149 
1150 ! Sources of cloud ice: pihom, cold rain, and the sat_adj
1151 ! (initiation plus deposition)
1152 
1153 ! Sources of snow: cold rain, auto conversion + accretion (from cloud ice)
1154 ! sat_adj (deposition; requires pre-existing snow); initial snow comes from auto conversion
1155 
1156  do k=ktop, kbot
1157 !--------------------------------------
1158 ! * pimlt: instant melting of cloud ice
1159 !--------------------------------------
1160  if( tzk(k) > tice .and. qik(k) > qcmin ) then
1161  melt = min( qik(k), (tzk(k)-tice)/icpk(k) )
1162  tmp1 = min( melt, dim(ql_mlt, qlk(k)) ) ! max ql amount
1163  qlk(k) = qlk(k) + tmp1
1164  qrk(k) = qrk(k) + melt - tmp1
1165  qik(k) = qik(k) - melt
1166  tzk(k) = tzk(k) - melt*icpk(k)
1167  endif
1168  enddo
1169 
1170  call linear_prof( kbot-ktop+1, p1(ktop), qik(ktop), di(ktop), z_slope_ice, h_var )
1171 
1172  do 3000 k=ktop, kbot
1173 
1174  if( tzk(k) < t_min .or. p1(k) < p_min ) goto 3000
1175 
1176  tz = tzk(k)
1177  qv = qvk(k)
1178  ql = qlk(k)
1179  qi = qik(k)
1180  qr = qrk(k)
1181  qs = qsk(k)
1182  qg = qgk(k)
1183 
1184 !--------------------------------------
1185 ! *** Split-micro_physics_processes ***
1186 !--------------------------------------
1187 
1188  pgacr = 0.
1189  pgacw = 0.
1190 
1191  tc = tz-tice
1192 if ( tc > 0. ) then
1193 
1194 !-----------------------------
1195 !* Melting of snow and graupel
1196 !-----------------------------
1197  dqs0 = ces0/p1(k) - qv
1198 
1199 ! The following is needed after the terminal fall
1200  if ( qs>qvmin ) then
1201 ! Melting of snow into rain ( half time step )
1202  factor = min( 1., tc/t_snow_melt )
1203  sink = min( fac_sno*qs, factor*tc/icpk(k) )
1204  qs = qs - sink
1205  qr = qr + sink
1206  tz = tz - sink*icpk(k) ! cooling due to snow melting
1207  tc = tz-tice
1208  endif
1209 
1210  if( qs>qcmin ) then
1211 
1212 ! * accretion: cloud water --> snow
1213 ! only rate is used (for snow melt) since tc > 0.
1214  if( ql>qrmin ) then
1215  factor = denfac(k)*csacw*exp(0.8125*log(qs*den(k)))
1216  psacw = factor/(1.+dts*factor)*ql ! rate
1217  else
1218  psacw = 0.
1219  endif
1220 
1221  if ( qr>qrmin ) then
1222 ! * accretion: melted snow --> rain:
1223  psacr = min(acr3d(vts(k), vtr(k), qr, qs, csacr, acco(1,2), den(k)), qr*rdts)
1224 ! * accretion: snow --> rain
1225  pracs = acr3d(vtr(k), vts(k), qs, qr, cracs, acco(1,1), den(k))
1226  else
1227  psacr = 0.
1228  pracs = 0.
1229  endif
1230 
1231 ! Total snow sink:
1232 ! * Snow melt (due to rain accretion): snow --> rain
1233  psmlt = max(0., smlt(tc, dqs0, qs*den(k), psacw, psacr, csmlt, den(k), denfac(k)))
1234  sink = min(qs, dts*(psmlt+pracs), tc/icpk(k))
1235 
1236  qs = qs - sink
1237  qr = qr + sink
1238  tz = tz - sink*icpk(k) ! cooling due to snow melting
1239  tc = tz-tice
1240  endif
1241 
1242  if ( qg>qcmin .and. tc>0. ) then
1243 
1244 ! *Temperature-dependent* Melting of graupel into rain ( half time step )
1245  factor = min( 1., tc/t_grau_melt ) ! smoother !!
1246  sink = min( fac_gra*qg, factor*tc/icpk(k) )
1247  qg = qg - sink
1248  qr = qr + sink
1249  tz = tz - sink*icpk(k) ! cooling due to melting
1250  tc = tz-tice
1251 
1252  if ( qr>qrmin ) then
1253 ! * accretion: rain --> graupel
1254  pgacr = min(acr3d(vtg(k), vtr(k), qr, qg, cgacr, acco(1,3), den(k)), rdts*qr)
1255  endif
1256 
1257  qden = qg*den(k)
1258  if( ql>qrmin ) then
1259 ! * accretion: cloud water --> graupel
1260 ! factor = cgacw/sqrt(den(k))*(qg*den(k))**0.875
1261  factor = cgacw*qden/sqrt(den(k)*sqrt(sqrt(qden)))
1262  pgacw = factor/(1.+dts*factor) * ql ! rate
1263  endif
1264 
1265 ! * melting: graupel --> rain
1266  pgmlt = dts*gmlt(tc, dqs0, qden, pgacw, pgacr, cgmlt, den(k))
1267  pgmlt = min( max(0., pgmlt), qg, tc/icpk(k) )
1268  qg = qg - pgmlt
1269  qr = qr + pgmlt
1270  tz = tz - pgmlt*icpk(k)
1271 
1272  endif ! graupel existed
1273 
1274 elseif( tc < 0.0 ) then
1275 
1276 !------------------
1277 ! Cloud ice proc:
1278 !------------------
1279  if ( qi>1.e-8 ) then
1280 
1281 !----------------------------------------
1282 ! * accretion (pacr): cloud ice --> snow
1283 !----------------------------------------
1284  if ( qs>1.e-8 ) then
1285 ! The following is originally from the "Lin Micro-physics" in Zetac
1286 ! SJL added (following Lin Eq. 23) the temperature dependency
1287 ! To reduce accretion, use Esi = exp(0.05*tc) as in Hong et al 2004
1288 ! To increase ice/reduce snow: exp(0.025*tc)
1289  factor = dts*denfac(k)*csaci*exp(0.05*tc + 0.8125*log(qs*den(k)))
1290  psaci = factor/(1.+factor) * qi
1291  else
1292  psaci = 0.
1293  endif
1294 
1295 !-------------------------------------
1296 ! * autoconversion: cloud ice --> snow
1297 !-------------------------------------
1298 ! Similar to LFO 1983: Eq. 21 solved implicitly
1299 ! Threshold from WSM6 scheme, Hong et al 2004, Eq(13) : qi0_crt ~0.8E-4
1300  qim = qi0_crt / den(k)
1301 
1302 ! Assuming linear subgrid vertical distribution of cloud ice
1303 ! The mismatch computation following Lin et al. 1994, MWR
1304  di(k) = max( di(k), qrmin )
1305  q_plus = qi + di(k)
1306  if ( q_plus > (qim+qrmin) ) then
1307  if ( qim > (qi - di(k)) ) then
1308  dq = 0.25*(q_plus-qim)**2 / di(k)
1309  else
1310  dq = qi - qim
1311  endif
1312 ! factor = dts*c_psaut*exp(0.025*tc)
1313 ! psaut = factor/(1.+factor) * dq
1314 ! Since mv2.10
1315  psaut = fac_i2s * dq
1316  else
1317  psaut = 0.
1318  endif
1319 
1320  sink = min( qi, psaci+psaut )
1321  qi = qi - sink
1322  qs = qs + sink
1323 
1324 !-----------------------------------
1325 ! * accretion: cloud ice --> graupel
1326 !-----------------------------------
1327  if ( qg>qrmin .and. qi>1.e-7 ) then
1328 ! factor = dts*cgaci/sqrt(den(k))*(qg*den(k))**0.875
1329 !----------------------------------------------------------------------------
1330 ! SJL added exp(0.025*tc) efficiency factor
1331  factor = dts*cgaci/sqrt(den(k))*exp(0.025*tc + 0.875*log(qg*den(k)))
1332 !----------------------------------------------------------------------------
1333  pgaci = factor/(1.+factor)*qi
1334  qi = qi - pgaci
1335  qg = qg + pgaci
1336  endif
1337 
1338  endif ! cloud ice existed
1339 
1340 !----------------------------------
1341 ! * sublimation/deposition of snow:
1342 !----------------------------------
1343  if ( qs>qrmin ) then
1344  qsi = iqs2(tz, den(k), dqsdt)
1345  qden = qs*den(k)
1346  tmp1 = exp(0.65625*log(qden))
1347  tsq = tz**2
1348  dq = (qsi-qv)/(1.+tcpk(k)*dqsdt)
1349  pssub = cssub(1)*tsq*(cssub(2)*sqrt(qden) + cssub(3)*tmp1*sqrt(denfac(k))) &
1350  / (cssub(4)*tsq+cssub(5)*qsi*den(k))
1351  pssub = (qsi-qv)*dts*pssub
1352  if ( pssub > 0. ) then ! qs --> qv, sublimation
1353  pssub = min(pssub*min(1.,dim(tz,t_sub)*0.2), qs)
1354 ! Enforce minimum sublimation:
1355 ! sink = min( qs, dim(rh_sno*qsi, qv)/(1.+tcpk(k)*dqsdt) )
1356 ! pssub = max( pssub, sink )
1357  else
1358  if ( tz > tice ) then
1359  pssub = 0.
1360  else
1361  pssub = max( pssub, 0.05*dq, (tz-tice)/tcpk(k) )
1362  endif
1363  endif
1364  qs = qs - pssub
1365  qv = qv + pssub
1366  tz = tz - pssub*tcpk(k)
1367  endif
1368 
1369 !----------------
1370 ! Cold-Rain proc:
1371 !----------------
1372 ! rain to ice, snow, graupel processes:
1373 
1374  tc = tz-tice
1375 
1376  if ( qr>qrmin .and. tc < 0. ) then
1377 
1378 #ifndef NOT_USE_PRACI
1379 ! * accretion: accretion of cloud ice by rain to produce snow or graupel
1380 ! (LFO: produces snow or graupel; cloud ice sink.. via psacr & pgfr)
1381 ! ice --> snow OR graupel (due to falling rain)
1382 ! No change to qr and tz
1383  if ( qi > 1.e-5 ) then
1384  factor = dts*denfac(k)*craci*exp(0.95*log(qr*den(k)))
1385  praci = factor/(1.+factor)*qi
1386  if ( qr > qr0_crt ) then
1387  qg = qg + praci
1388  else
1389  qs = qs + praci
1390  endif
1391  qi = qi - praci
1392  endif
1393 #endif
1394 
1395 ! *sink* terms to qr: psacr + piacr + pgfr
1396 ! source terms to qs: psacr
1397 ! source terms to qi: piacr
1398 ! source terms to qg: pgfr
1399 
1400 ! * accretion of rain by snow
1401  if ( qs > 1.e-8 ) then ! if snow exists
1402  psacr = dts*acr3d(vts(k), vtr(k), qr, qs, csacr, acco(1,2), den(k))
1403  else
1404  psacr = 0.
1405  endif
1406 
1407 ! The following added by SJL (missing from Zetac)
1408 ! * piacr: accretion of rain by cloud ice [simplified from lfo 26]
1409 ! The value of c_piacr needs to be near order(1) to have significant effect
1410 !-------------------------------------------------------------------
1411 ! rain --> ice
1412  if ( qi > qrmin ) then
1413  factor = dts*denfac(k)*qi * c_piacr
1414  piacr = factor/(1.+factor)*qr
1415  else
1416  piacr = 0.
1417  endif
1418 
1419 !-------------------------------------------------------------------
1420 ! * rain freezing --> graupel
1421 !-----------------------------------------------------------------------------------
1422  pgfr = dts*cgfr(1)/den(k)*(exp(-cgfr(2)*tc)-1.)*exp( 1.75*log(qr*den(k)) )
1423 
1424 !--- Total sink to qr
1425  sink = psacr + piacr + pgfr
1426  factor = min( sink, qr, -tc/icpk(k) ) / max( sink, qrmin )
1427 
1428  psacr = factor * psacr
1429  piacr = factor * piacr
1430  pgfr = factor * pgfr
1431 
1432  sink = psacr + piacr + pgfr
1433  tz = tz + sink*icpk(k)
1434  qr = qr - sink
1435  qs = qs + psacr
1436  qi = qi + piacr
1437  qg = qg + pgfr
1438  tc = tz - tice
1439  endif ! qr existed
1440 
1441 !------------------
1442 ! Cloud water sink:
1443 !------------------
1444  if( ql>qcmin ) then
1445 
1446 ! * pihom * homogeneous Freezing of cloud water into cloud ice:
1447 ! This is the 1st occurance of liquid water freezing in the split MP process
1448 ! done here to prevent excessive snow production
1449  dtmp = t_wfr - tz
1450  if( dtmp > 0. ) then
1451  factor = min( 1., dtmp/dt_fr )
1452  sink = min( ql*factor, dtmp/icpk(k) )
1453  ql = ql - sink
1454  qi = qi + sink
1455  tz = tz + sink*icpk(k)
1456  tc = tz - tice
1457  endif
1458 
1459 ! * super-cooled cloud water --> Snow
1460  if ( .not. fast_sat_adj ) then
1461  if( qs>1.e-8 .and. ql>1.e-8 .and. tc<-0.01 ) then
1462 ! The following originally from Zetac: PSACW
1463  factor = dts*denfac(k)*csacw*exp(0.8125*log(qs*den(k)))
1464  psacw = min( factor/(1.+factor)*ql, -tc/icpk(k) )
1465  qs = qs + psacw
1466  ql = ql - psacw
1467  tz = tz + psacw*icpk(k)
1468  endif
1469  endif
1470 
1471  endif ! (significant) cloud water existed
1472 
1473 !--------------------------
1474 ! Graupel production terms:
1475 !--------------------------
1476 
1477  if( qs > qrmin ) then
1478 ! * accretion: snow --> graupel
1479  if ( qg > qrmin ) then
1480  sink = dts*acr3d(vtg(k), vts(k), qs, qg, cgacs, acco(1,4), den(k))
1481  else
1482  sink = 0.
1483  endif
1484 
1485  qsm = qs0_crt / den(k)
1486  if ( qs > qsm ) then
1487 ! * Autoconversion Snow --> graupel
1488  factor = dts*1.e-3*exp(0.09*(tz-tice))
1489  sink = sink + factor/(1.+factor)*(qs-qsm)
1490  endif
1491  sink = min( qs, sink )
1492  qs = qs - sink
1493  qg = qg + sink
1494 
1495  endif ! snow existed
1496 
1497  if ( qg>qrmin .and. tz < tice0 ) then
1498 
1499 ! * accretion: cloud water --> graupel
1500  if( ql>1.e-8 ) then
1501 ! factor = dts*cgacw/sqrt(den(k))*(qg*den(k))**0.875
1502  qden = qg*den(k)
1503  factor = dts*cgacw*qden/sqrt(den(k)*sqrt(sqrt(qden)))
1504  pgacw = factor/(1.+factor)*ql
1505  else
1506  pgacw = 0.
1507  endif
1508 
1509 ! * accretion: rain --> graupel
1510  if ( qr>qrmin ) then
1511  pgacr = min(dts*acr3d(vtg(k), vtr(k), qr, qg, cgacr, acco(1,3), den(k)), qr)
1512  else
1513  pgacr = 0.
1514  endif
1515 
1516  sink = pgacr + pgacw
1517  factor = min( sink, dim(tice,tz)/icpk(k) ) / max( sink, qrmin )
1518  pgacr = factor * pgacr
1519  pgacw = factor * pgacw
1520 
1521  sink = pgacr + pgacw
1522  tz = tz + sink*icpk(k)
1523  qg = qg + sink
1524  qr = qr - pgacr
1525  ql = ql - pgacw
1526 
1527 !------------------------------------------------------------
1528 ! * Simplified 2-way grapuel sublimation-deposition mechanism
1529 !------------------------------------------------------------
1530  qsi = iqs2(tz, den(k), dqsdt)
1531  dq = qv - qsi
1532  pgsub = (qv/qsi-1.) * qg
1533  if ( pgsub > 0. ) then ! deposition
1534  pgsub = min( fac_v2g*pgsub, 0.01*dq, dim(tice,tz)/tcpk(k) )
1535  else ! submilation
1536  pgsub = max( fac_g2v*pgsub, dq/(1.+tcpk(k)*dqsdt) )*min(1.,dim(tz,t_sub)*0.1)
1537 ! Minimum sublimation to maintain rh > rh_gra
1538 ! sink = min( qg, dim(rh_gra*qsi, qv)/(1.+tcpk(k)*dqsdt) )
1539 ! pgsub = min( pgsub, -sink)
1540  endif
1541  qg = qg + pgsub
1542  qv = qv - pgsub
1543  tz = tz + pgsub*tcpk(k)
1544  endif ! graupel existed
1545 
1546 endif ! end ice-physics
1547 
1548 !!!#ifdef RAIN_RH_MIN
1549 ! Minimum Evap of rain in dry environmental air
1550  if( qr>qcmin) then
1551  qsw = wqs2(tz, den(k), dqsdt)
1552  sink = min(qr, dim(rh_rain*qsw, qv)/(1.+lcpk(k)*dqsdt))
1553  qv = qv + sink
1554  qr = qr - sink
1555  tz = tz - sink*lcpk(k)
1556  endif
1557 !!!#endif
1558 
1559  tzk(k) = tz
1560  qvk(k) = qv
1561  qlk(k) = ql
1562  qik(k) = qi
1563  qrk(k) = qr
1564  qsk(k) = qs
1565  qgk(k) = qg
1566 
1567 3000 continue ! k-loop
1568 
1569  if ( do_subgrid_z ) then
1570 
1571 ! Except top 2 and bottom 2 layers (4 layers total), using subgrid PPM distribution
1572 ! to perform saturation adjustment at 2X the vertical resolution
1573 
1574  kn = kbot - ktop + 1
1575  km = 2*(kbot-ktop-1)
1576 
1577  p2(1) = p1(ktop )
1578  p2(2) = p1(ktop+1)
1579  do k=3,km-3,2
1580  k1 = ktop+1 + k/2
1581  p2(k ) = p1(k1) - 0.25*dp1(k1)
1582  p2(k+1) = p1(k1) + 0.25*dp1(k1)
1583  enddo
1584 
1585  if ( mp_debug ) then
1586  if (k1 /= (kbot-2)) then
1587  write(*,*) 'FATAL: k1=', k1
1588  call error_mesg ('LIN_CLD_MICROPHYS:', 'DO_MAP2_SAT', fatal)
1589  endif
1590  endif
1591 
1592  p2(km-1) = p1(kbot-1)
1593  p2(km ) = p1(kbot)
1594 
1595  call remap2(ktop, kbot, kn, km, dp1, tzk, tz2, 1)
1596  call remap2(ktop, kbot, kn, km, dp1, qvk, qv2, 1)
1597  call remap2(ktop, kbot, kn, km, dp1, qlk, ql2, 1)
1598  call remap2(ktop, kbot, kn, km, dp1, qik, qi2, 1)
1599 
1600 if( rad_snow .or. rad_rain ) then
1601  call remap2(ktop, kbot, kn, km, dp1, qrk, qr2, 1)
1602  call remap2(ktop, kbot, kn, km, dp1, qsk, qs2, 1)
1603 else
1604  qr2(:) = 1.e30
1605  qs2(:) = 1.e30
1606 endif
1607 
1608  do k=1,km
1609  den2(k) = p2(k)/(rdgas*tz2(k))
1610  qa2(k) = 0.
1611  enddo
1612 
1613  qg2(:) = 0. ! need to fix this hack
1614  call subgrid_z_proc(1, km, p2, den2, dts, rh_adj, tz2, qv2, ql2, qr2, qi2, qs2, qg2, qa2, h_var)
1615 
1616 ! Remap back to original larger volumes:
1617  qak(ktop ) = qak(ktop ) + qa2(1)
1618  qak(ktop+1) = qak(ktop+1) + qa2(2)
1619 
1620  tzk(ktop ) = tz2(1)
1621  tzk(ktop+1) = tz2(2)
1622 
1623  qvk(ktop ) = qv2(1)
1624  qvk(ktop+1) = qv2(2)
1625 
1626  qlk(ktop ) = ql2(1)
1627  qlk(ktop+1) = ql2(2)
1628 
1629  qik(ktop ) = qi2(1)
1630  qik(ktop+1) = qi2(2)
1631 
1632 if( rad_snow .or. rad_rain ) then
1633  qrk(ktop ) = qr2(1)
1634  qrk(ktop+1) = qr2(2)
1635 
1636  qsk(ktop ) = qs2(1)
1637  qsk(ktop+1) = qs2(2)
1638 endif
1639 
1640  do k=3,km-3,2
1641  k1 = ktop+1 + k/2
1642  qak(k1) = qak(k1) + max(qa2(k), qa2(k+1)) ! Maximum only
1643 ! Subgrid overlap schemes: max and random parts weighted by subgrid horizontal deviation
1644 !-------------------------------------------------------------------------------------
1645 ! Random cloud fraction = 1 - (1-a1)*(1-a2) = a1 + a2 - a1*a2
1646 ! RAND_CLOUD
1647 ! qak(k1) = qak(k1) + (1.-h_var)*max(qa2(k), qa2(k+1)) & ! Maximum fraction
1648 ! + h_var*(qa2(k)+qa2(k+1)-qa2(k)*qa2(k+1)) ! Random fraction
1649 !-------------------------------------------------------------------------------------
1650  tzk(k1) = 0.5*(tz2(k) + tz2(k+1))
1651  qvk(k1) = 0.5*(qv2(k) + qv2(k+1))
1652  qlk(k1) = 0.5*(ql2(k) + ql2(k+1))
1653  qik(k1) = 0.5*(qi2(k) + qi2(k+1))
1654  enddo
1655 
1656  qak(kbot-1) = qak(kbot-1) + qa2(km-1)
1657  qak(kbot ) = qak(kbot ) + qa2(km )
1658 
1659  tzk(kbot-1) = tz2(km-1)
1660  tzk(kbot ) = tz2(km )
1661 
1662  qvk(kbot-1) = qv2(km-1)
1663  qvk(kbot ) = qv2(km )
1664 
1665  qlk(kbot-1) = ql2(km-1)
1666  qlk(kbot ) = ql2(km )
1667 
1668  qik(kbot-1) = qi2(km-1)
1669  qik(kbot ) = qi2(km )
1670 
1671  else
1672  call subgrid_z_proc(ktop, kbot, p1, den, dts, rh_adj, tzk, qvk, qlk, qrk, qik, qsk, qgk, qak, h_var)
1673  endif
1674 
1675  end subroutine icloud
1676 
1677 
1678  subroutine remap2(ktop, kbot, kn, km, dp, q1, q2, id)
1679  integer, intent(in):: ktop, kbot, kn, km , id
1680 ! constant distribution if id ==0
1681  real, intent(in), dimension(ktop:kbot):: q1, dp
1682  real, intent(out):: q2(km)
1683 ! local
1684  real :: a4(4,ktop:kbot)
1685  real :: tmp
1686  integer:: k, k1
1687 
1688  q2(1) = q1(ktop )
1689  q2(2) = q1(ktop+1)
1690 
1691  if ( id==1 ) then
1692 
1693  do k=ktop,kbot
1694  a4(1,k) = q1(k)
1695  enddo
1696  call cs_profile( a4(1,ktop), dp(ktop), kn, mono_prof ) ! non-monotonic
1697 
1698  do k=3,km-3,2
1699  k1 = ktop+1 + k/2
1700  q2(k ) = min( 2.*q1(k1), max( qvmin, a4(1,k1) + 0.25*(a4(2,k1)-a4(3,k1)) ) )
1701  q2(k+1) = 2.*q1(k1) - q2(k)
1702  enddo
1703 
1704  else
1705  do k=3,km-3,2
1706  k1 = ktop+1 + k/2
1707  q2(k ) = q1(k1)
1708  q2(k+1) = q1(k1)
1709  enddo
1710  endif
1711 
1712  q2(km-1) = q1(kbot-1)
1713  q2(km ) = q1(kbot)
1714 
1715  end subroutine remap2
1716 
1717 
1718 
1719  subroutine subgrid_z_proc(ktop, kbot, p1, den, dts, rh_adj, tz, qv, ql, qr, qi, qs, qg, qa, h_var)
1721 ! Temperature sentive high vertical resolution processes:
1722 
1723  integer, intent(in):: ktop, kbot
1724  real, intent(in), dimension(ktop:kbot):: p1, den
1725  real, intent(in) :: dts, rh_adj, h_var
1726  real, intent(inout), dimension(ktop:kbot):: tz, qv, ql, qr, qi, qs, qg, qa
1727 ! local:
1728  real, dimension(ktop:kbot):: lcpk, icpk, tcpk, tcp3
1729  real :: fac_v2l, fac_l2v
1730  real :: pidep, qi_crt
1731 ! qstar over water may be accurate only down to -80 C with ~10% uncertainty
1732 ! must not be too large to allow PSC
1733  real :: rh, clouds, rqi, tin, qsw, qsi, qpz, qstar
1734  real :: dqsdt, dwsdt, dq, dq0, cond0, factor, tmp, cvm
1735  real :: q_plus, q_minus, dt_pisub
1736  real :: evap, sink, tc, pisub, iwt, q_adj, dtmp, lat2
1737  integer :: k
1738 
1739  fac_v2l = 1. - exp( -0.5*dts/tau_v2l ) !
1740  fac_l2v = 1. - exp( -0.5*dts/tau_l2v ) !
1741 
1742  lat2 = lats * lats
1743 
1744  do k=ktop, kbot
1745 ! Moist heat capacity
1746  cvm = c_air + qv(k)*c_vap + (ql(k)+qr(k))*c_liq + (qi(k)+qs(k)+qg(k))*c_ice
1747  lcpk(k) = (lv00+dc_vap*tz(k)) / cvm
1748  icpk(k) = (li00+dc_ice*tz(k)) / cvm
1749  tcpk(k) = lcpk(k) + icpk(k)
1750  tcp3(k) = lcpk(k) + icpk(k)*min(1., dim(tice,tz(k))/(tice-t_wfr))
1751  enddo
1752 
1753  do 4000 k=ktop,kbot
1754 
1755  if ( p1(k) < p_min ) goto 4000
1756 
1757  if ( tz(k) < t_min ) then
1758  sink = dim(qv(k), 1.e-7)
1759  qv(k) = qv(k) - sink
1760  qi(k) = qi(k) + sink
1761  tz(k) = tz(k) + sink*tcpk(k)
1762  if ( .not.do_qa ) qa(k) = qa(k) + 1. ! Air fully saturated; 100 % cloud cover
1763  goto 4000
1764  endif
1765 
1766 ! Instant evaporation/sublimation of all clouds if RH<rh_adj --> cloud free
1767  iwt = qi(k)
1768  clouds = ql(k) + iwt
1769 
1770  tin = tz(k) - ( lcpk(k)*clouds + icpk(k)*iwt ) ! minimum temperature
1771  if ( tin>t_sub+6. ) then
1772  qpz = qv(k) + clouds
1773  rh = qpz / iqs1(tin, den(k))
1774 
1775  if ( rh < rh_adj ) then ! qpz / rh_adj < qs
1776  tz(k) = tin
1777  qv(k) = qpz
1778  ql(k) = 0.
1779  qi(k) = 0.
1780  goto 4000 ! cloud free
1781  endif
1782  endif
1783 
1784 ! cloud water <--> vapor adjustment:
1785  qsw = wqs2(tz(k), den(k), dwsdt)
1786  dq0 = qsw - qv(k)
1787  if ( dq0 > 0. ) then
1788  evap = min( ql(k), fac_l2v*dq0/(1.+tcp3(k)*dwsdt) )
1789  else ! condensate all excess vapor into cloud water
1790  ! this should take care of most of the super-sat due to phys.
1791  evap = dq0/(1.+tcp3(k)*dwsdt)
1792  endif
1793  qv(k) = qv(k) + evap
1794  ql(k) = ql(k) - evap
1795  tz(k) = tz(k) - evap*lcpk(k)
1796 
1797 ! Enforce complete freezing below -48 C
1798  dtmp = t_wfr - tz(k) ! [-40,-48]
1799  if( dtmp>0. .and. ql(k) > qcmin ) then
1800  sink = min( ql(k), ql(k)*dtmp*0.125, dtmp/icpk(k) )
1801  ql(k) = ql(k) - sink
1802  qi(k) = qi(k) + sink
1803  tz(k) = tz(k) + sink*icpk(k)
1804  endif
1805 
1806  if ( fast_sat_adj ) then
1807  dt_pisub = 0.5*dts
1808  else
1809  dt_pisub = dts
1810  tc = tice - tz(k)
1811  if( ql(k) > qcmin .and. tc> 0.1 ) then
1812 ! Bigg mechanism
1813  sink = dts*3.3333e-10*(exp(0.66*tc)-1.)*den(k)*ql(k)*ql(k)
1814  sink = min(ql(k), tc/icpk(k), sink)
1815  ql(k) = ql(k) - sink
1816  qi(k) = qi(k) + sink
1817  tz(k) = tz(k) + sink*icpk(k)
1818  endif ! significant ql existed
1819  endif
1820 
1821  cvm = c_air + qv(k)*c_vap + (ql(k)+qr(k))*c_liq + (qi(k)+qs(k)+qg(k))*c_ice
1822  lcpk(k) = (lv00+dc_vap*tz(k)) / cvm
1823  icpk(k) = (li00+dc_ice*tz(k)) / cvm
1824  tcpk(k) = lcpk(k) + icpk(k)
1825 !------------------------------------------
1826 ! * pidep: sublimation/deposition of ice:
1827 !------------------------------------------
1828  if ( tz(k) < tice ) then
1829  qsi = iqs2(tz(k), den(k), dqsdt)
1830  dq = qv(k) - qsi
1831  sink = dq/(1.+tcpk(k)*dqsdt)
1832 
1833  if ( qi(k) > qrmin ) then
1834 ! Eq 9, Hong et al. 2004, MWR
1835 ! For A and B, see Dudhia 1989: page 3103 Eq (B7) and (B8)
1836  pidep = dt_pisub*dq*349138.78*exp(0.875*log(qi(k)*den(k))) &
1837  / (qsi*den(k)*lat2/(0.0243*rvgas*tz(k)**2) + 4.42478e4)
1838  else
1839  pidep = 0.
1840  endif
1841 
1842  if ( dq > 0. ) then ! vapor -> ice
1843  tmp = tice - tz(k)
1844  qi_crt = qi_gen*min(qi_lim, 0.1*tmp) / den(k)
1845  sink = min(sink, max(qi_crt-qi(k),pidep), tmp/tcpk(k))
1846  else ! ice --> vapor
1847  pidep = pidep * min(1., dim(tz(k),t_sub)*0.2)
1848  sink = max(pidep, sink, -qi(k))
1849  endif
1850  qv(k) = qv(k) - sink
1851  qi(k) = qi(k) + sink
1852  tz(k) = tz(k) + sink*tcpk(k)
1853  endif
1854 
1855  if ( do_qa ) goto 4000
1856 
1857  if ( rad_snow ) then
1858  iwt = qi(k) + qs(k)
1859  else
1860  iwt = qi(k)
1861  endif
1862  if ( rad_rain ) then
1863  clouds = ql(k) + qr(k) + iwt
1864  else
1865  clouds = ql(k) + iwt
1866  endif
1867 
1868  qpz = qv(k) + clouds ! qpz is conserved
1869  tin = tz(k) - ( lcpk(k)*clouds + icpk(k)*iwt ) ! minimum temperature
1870 
1871 !--------------------
1872 ! * determine qstar
1873 !--------------------
1874 ! Using the "liquid-frozen water temperature": tin
1875  if( tin <= t_wfr ) then
1876  qstar = iqs1(tin, den(k))
1877  elseif ( tin >= tice ) then
1878  qstar = wqs1(tin, den(k))
1879  else
1880 ! mixed phase:
1881  qsi = iqs1(tin, den(k))
1882  qsw = wqs1(tin, den(k))
1883  if( clouds > 3.e-6 ) then
1884  rqi = iwt / clouds
1885  else
1886 ! Mostly liquid water clouds at initial cloud development stage
1887  rqi = (tice-tin)/(tice-t_wfr)
1888  endif
1889  qstar = rqi*qsi + (1.-rqi)*qsw
1890  endif
1891 
1892 !-------------------------
1893 ! * cloud fraction
1894 !-------------------------
1895 ! Assuming subgrid linear distribution in horizontal; this is effectively a smoother for the
1896 ! binary cloud scheme
1897 
1898  if ( qpz > qrmin ) then
1899 ! Partial cloudiness by PDF:
1900  dq = max(qcmin, h_var*qpz)
1901  q_plus = qpz + dq ! cloud free if qstar > q_plus
1902  q_minus = qpz - dq
1903  if ( qstar < q_minus ) then
1904  qa(k) = qa(k) + 1. ! Air fully saturated; 100 % cloud cover
1905  elseif ( qstar<q_plus .and. clouds>qc_crt ) then
1906  qa(k) = qa(k) + (q_plus-qstar)/(dq+dq) ! partial cloud cover
1907  endif
1908  endif
1909 
1910 4000 continue
1911 
1912  end subroutine subgrid_z_proc
1913 
1914 
1915  subroutine sat_adj2(mdt, is, ie, js, je, ng, hydrostatic, consv_te, &
1916  te0, qv, ql, qi, qr, qs, qg, qa, area, dpeln, delz, pt, dp, &
1917  q_con, &
1918 #ifdef MOIST_CAPPA
1919  cappa, &
1920 #endif
1921  dtdt, out_dt, last_step)
1922 ! This is designed for 6-class micro-physics schemes
1923 ! input pt is T_vir
1924  real, intent(in):: mdt ! remapping time step
1925  integer, intent(in):: is, ie, js, je, ng
1926  logical, intent(in):: hydrostatic, last_step, consv_te, out_dt
1927  real, intent(in), dimension(is-ng:ie+ng,js-ng:je+ng):: dp, area, delz
1928 
1929  real, intent(in):: dpeln(is:ie,js:je) ! ln(pe)
1930  real, intent(inout), dimension(is-ng:ie+ng,js-ng:je+ng):: pt, qv, ql, qi, qr, qs, qg, qa
1931  real, intent(inout), dimension(is-ng:,js-ng:):: q_con
1932 #ifdef MOIST_CAPPA
1933  real, intent(inout), dimension(is-ng:,js-ng:):: cappa
1934 #endif
1935  real, intent(inout)::dtdt(is:ie,js:je)
1936  real, intent(out):: te0(is:ie,js:je)
1937 ! Local:
1938  real, dimension(is:ie):: cpm, t0, pt1, icp2, lcp2, tcp2, tcp3, den, q_liq, q_sol, hvar, src, p1
1939  real :: sink, qsw, rh, fac_v2l, fac_l2v, cond0
1940  real :: tc, qsi, dqsdt, dq, dq0, pidep, qi_crt, tmp, dtmp, lat2
1941  real :: condensates, qpz, tin, qstar, rqi, q_plus, q_minus
1942  real :: sdt, rh_ql, adj_fac, fac_s, fac_r, fac_i2s
1943  real :: factor, psacw, qim
1944  integer i,j
1945 
1946  sdt = 0.5 * mdt
1947 
1948  fac_i2s = 1. - exp( -mdt/tau_i2s ) !
1949  fac_v2l = 1. - exp( -sdt/tau_v2l )
1950  fac_l2v = 1. - exp( -sdt/tau_l2v ) !
1951  fac_l2v = min(sat_adj0, 0.5, fac_l2v)
1952  fac_r = 1. - exp( -sdt/tau_r )
1953  fac_s = 1. - exp( -sdt/tau_s )
1954 
1955  latv = hlv
1956  lati = hlf
1957  lats = latv + lati
1958  lat2 = lats * lats
1959 
1960  do j=js, je
1961 
1962  do i=is, ie
1963 #ifdef USE_COND
1964  q_con(i,j) = ql(i,j) + qr(i,j) + qi(i,j) + qs(i,j) + qg(i,j)
1965  pt1(i) = pt(i,j) / ((1.+zvir*qv(i,j))*(1-q_con(i,j)))
1966 #else
1967  pt1(i) = pt(i,j) / (1.+zvir*qv(i,j))
1968 #endif
1969  t0(i) = pt1(i)
1970  q_liq(i) = ql(i,j) + qr(i,j)
1971  q_sol(i) = qi(i,j) + qs(i,j) + qg(i,j)
1972  hvar(i) = min(0.2, max(0.01, dw_ocean*sqrt(sqrt(area(i,j)/1.e10))) )
1973  enddo
1974 ! Perform terminal fall & momentum transport???
1975 
1976  if ( hydrostatic ) then
1977  do i=is, ie
1978 ! Need to fix the following for consistency:
1979  den(i) = dp(i,j)/(dpeln(i,j)*rdgas*pt(i,j))
1980  cpm(i) = (1.-(qv(i,j)+q_liq(i)+q_sol(i)))*cp_air + qv(i,j)*cp_vap + &
1981  q_liq(i)*c_liq + q_sol(i)*c_ice
1982  lcp2(i) = (lv0 +dc_vap*t0(i)) / cpm(i)
1983  icp2(i) = (li00+dc_ice*t0(i)) / cpm(i)
1984  enddo
1985  else
1986  do i=is, ie
1987 ! Moist mixing ratios:
1988  den(i) = -dp(i,j)/(grav*delz(i,j))
1989  cpm(i) = (1.-(qv(i,j)+q_liq(i)+q_sol(i)))*cv_air + qv(i,j)*cv_vap + &
1990  q_liq(i)*c_liq + q_sol(i)*c_ice
1991  lcp2(i) = (lv0+dc_vap*t0(i)) / cpm(i)
1992  icp2(i) = (li00+dc_ice*t0(i)) / cpm(i)
1993  enddo
1994  endif
1995 
1996  do i=is, ie
1997  tcp2(i) = lcp2(i) + icp2(i)
1998 ! Compute special heat capacity for qv --> ql (dqsdt term)
1999  tcp3(i) = lcp2(i) + icp2(i)*min(1., dim(tice,t0(i))/40.)
2000  src(i) = 0.
2001  enddo
2002  if ( consv_te ) then
2003  if ( hydrostatic ) then
2004  do i=is, ie
2005  te0(i,j) = -cp_air*dp(i,j)*t0(i)*(1.+zvir*qv(i,j))
2006  enddo
2007  else
2008  do i=is, ie
2009 #if defined(USE_COND) && defined(MOIST_CAPPA)
2010  te0(i,j) = -cpm(i)*dp(i,j)*t0(i)
2011 #else
2012  te0(i,j) = -cv_air*dp(i,j)*t0(i)
2013 #endif
2014  enddo
2015  endif
2016  endif
2017 
2018 !********************
2019 ! Fast moist physics:
2020 !********************
2021  do i=is, ie
2022  if( qi(i,j) < 0. ) then
2023 ! Fix negative cloud ice with snow
2024  qs(i,j) = qs(i,j) + qi(i,j)
2025  qi(i,j) = 0.
2026  elseif ( qi(i,j)>qcmin .and. pt1(i) > tice ) then
2027 ! Melting of cloud ice into cloud water ********
2028 ! Cooling via melting of cloud ice
2029  sink = min( qi(i,j), (pt1(i)-tice)/icp2(i) )
2030 ! Maximum amount of melted ice converted to ql
2031  tmp = min( sink, dim(ql_mlt, ql(i,j)) ) ! max ql amount
2032  ql(i,j) = ql(i,j) + tmp
2033  qr(i,j) = qr(i,j) + sink - tmp
2034  qi(i,j) = qi(i,j) - sink
2035  pt1(i) = pt1(i) - sink*icp2(i)
2036  endif
2037 ! -----------------------
2038 ! Melting of snow --> qr
2039 ! -----------------------
2040  dtmp = pt1(i) - (tice + 1.)
2041  if ( qs(i,j)>qcmin .and. dtmp>0. ) then
2042  tmp = min( 1., fac_s*(dtmp*0.2)**2 ) * qs(i,j)
2043  sink = min( tmp, dtmp/icp2(i) )
2044  qr(i,j) = qr(i,j) + sink
2045  qs(i,j) = qs(i,j) - sink
2046  pt1(i) = pt1(i) - sink*icp2(i)
2047  endif
2048  enddo
2049 
2050  do i=is, ie
2051  if( qs(i,j) < 0. ) then
2052 ! Fix negative snow with graupel
2053  qg(i,j) = qg(i,j) + qs(i,j)
2054  qs(i,j) = 0.
2055  elseif( qg(i,j) < 0. ) then
2056 ! Fix negative graupel with available snow
2057  tmp = min( -qg(i,j), max(0., qs(i,j)) )
2058  qg(i,j) = qg(i,j) + tmp
2059  qs(i,j) = qs(i,j) - tmp
2060  endif
2061  enddo
2062 ! At this point cloud ice & snow are positive definite
2063 
2064  do i=is, ie
2065  if( ql(i,j) < 0. ) then
2066 ! Fix negative cloud water if rain exists
2067  tmp = min( -ql(i,j), max(0., qr(i,j)) )
2068  ql(i,j) = ql(i,j) + tmp
2069  qr(i,j) = qr(i,j) - tmp
2070  elseif( qr(i,j) < 0. ) then
2071 ! Fix negative rain water with available cloud water
2072  tmp = min( -qr(i,j), max(0., ql(i,j)) )
2073  ql(i,j) = ql(i,j) - tmp
2074  qr(i,j) = qr(i,j) + tmp
2075  endif
2076  enddo
2077 
2078 ! Enforce complete freezing below -48 C
2079 ! (do this before ql has a chance to evap)
2080  do i=is, ie
2081  dtmp = tice - 48. - pt1(i)
2082  if( ql(i,j)>0. .and. dtmp > 0. ) then
2083  sink = min( ql(i,j), dtmp/icp2(i) )
2084  ql(i,j) = ql(i,j) - sink
2085  qi(i,j) = qi(i,j) + sink
2086  pt1(i) = pt1(i) + sink*icp2(i)
2087  endif
2088  enddo
2089  if ( last_step ) then
2090 ! Enforce upper (no super_sat) & lower (critical RH) bounds
2091  do i=is, ie
2092  qsw = wqs2(pt1(i), den(i), dqsdt)
2093  dq0 = qv(i,j) - qsw
2094  if ( dq0 > 0. ) then ! remove super-saturation
2095 ! Prevent super saturation over water:
2096  src(i) = dq0/(1.+tcp3(i)*dqsdt)
2097  else
2098 ! Evaporation of ql
2099  src(i) = -min( ql(i,j), -fac_l2v*dq0/(1.+tcp3(i)*dqsdt) )
2100  endif
2101  enddo
2102  adj_fac = 1.
2103  else
2104  adj_fac = sat_adj0
2105  do i=is, ie
2106  qsw = wqs2(pt1(i), den(i), dqsdt)
2107  dq0 = qv(i,j) - qsw
2108  if ( dq0 > 0. ) then ! whole grid-box saturated
2109  tmp = dq0/(1.+tcp3(i)*dqsdt)
2110  src(i) = min(adj_fac*tmp, max(ql_gen-ql(i,j), fac_v2l*tmp))
2111 
2112  else
2113 ! Evaporation of ql
2114  src(i) = -min( ql(i,j), -fac_l2v*dq0/(1.+tcp3(i)*dqsdt) )
2115  endif
2116  enddo
2117  endif
2118 
2119  do i=is, ie
2120  qv(i,j) = qv(i,j) - src(i)
2121  ql(i,j) = ql(i,j) + src(i)
2122  pt1(i) = pt1(i) + src(i)*lcp2(i)
2123  enddo
2124 
2125 ! *********** freezing of cloud water ********
2126 ! Enforce complete freezing below -48 C
2127  do i=is, ie
2128  dtmp = t_wfr - pt1(i) ! [-40,-48]
2129  if( ql(i,j)>0. .and. dtmp > 0. ) then
2130  sink = min( ql(i,j), ql(i,j)*dtmp*0.125, dtmp/icp2(i) )
2131  ql(i,j) = ql(i,j) - sink
2132  qi(i,j) = qi(i,j) + sink
2133  pt1(i) = pt1(i) + sink*icp2(i)
2134  endif
2135  enddo
2136  do i=is, ie
2137  tc = tice0 - pt1(i)
2138  if( ql(i,j)>qcmin .and. tc > 0. ) then
2139 ! Bigg mechanism
2140  sink = mdt*3.3333e-10*(exp(0.66*tc)-1.)*den(i)*ql(i,j)*ql(i,j)
2141  sink = min(ql(i,j), tc/icp2(i), sink)
2142  ql(i,j) = ql(i,j) - sink
2143  qi(i,j) = qi(i,j) + sink
2144  pt1(i) = pt1(i) + sink*icp2(i)
2145  endif
2146  enddo
2147 ! *********** freezing of rain water qr-->qg ********
2148  do i=is, ie
2149  dtmp = (tice - 1.) - pt1(i)
2150  if( qr(i,j)>qcmin .and. dtmp > 0. ) then
2151  tmp = min( 1., fac_r*(dtmp*0.025)**2 ) * qr(i,j)
2152  sink = min( tmp, dtmp/icp2(i) )
2153  qr(i,j) = qr(i,j) - sink
2154  qg(i,j) = qg(i,j) + sink
2155  pt1(i) = pt1(i) + sink*icp2(i)
2156  endif
2157  enddo
2158 
2159 ! Update after freezing & before ice-phase adjustment
2160  do i=is, ie
2161  q_liq(i) = max(0., ql(i,j) + qr(i,j))
2162  q_sol(i) = max(0., qi(i,j) + qs(i,j) + qg(i,j))
2163  enddo
2164 
2165 ! Enforce upper bounds on ql (can be regarded as autoconversion)
2166  do i=is, ie
2167  if ( ql(i,j) > ql0_max ) then
2168  qr(i,j) = q_liq(i) - ql0_max
2169  ql(i,j) = ql0_max
2170  endif
2171  enddo
2172 
2173  if ( hydrostatic ) then
2174  do i=is, ie
2175  cpm(i) = (1.-(qv(i,j)+q_liq(i)+q_sol(i)))*cp_air + qv(i,j)*cp_vap + &
2176  q_liq(i)*c_liq + q_sol(i)*c_ice
2177  lcp2(i) = (lv0+ dc_vap*pt1(i)) / cpm(i)
2178  icp2(i) = (li00+dc_ice*pt1(i)) / cpm(i)
2179  enddo
2180  else
2181  do i=is, ie
2182  cpm(i) = (1.-(qv(i,j)+q_liq(i)+q_sol(i)))*cv_air + qv(i,j)*cv_vap + &
2183  q_liq(i)*c_liq + q_sol(i)*c_ice
2184  lcp2(i) = (lv0+dc_vap*pt1(i)) / cpm(i)
2185  icp2(i) = (li00+dc_ice*pt1(i)) / cpm(i)
2186  enddo
2187  endif
2188 
2189  do i=is, ie
2190  tcp2(i) = lcp2(i) + icp2(i)
2191  src(i) = 0.
2192  enddo
2193 
2194 ! Ice-phase
2195 !------------------------------------------
2196 ! * pidep: sublimation/deposition of ice:
2197 !------------------------------------------
2198  do i=is, ie
2199  p1(i) = dp(i,j)/dpeln(i,j)
2200  if ( p1(i) > p_min ) then
2201  if ( pt1(i) < t_min ) then ! Too cold to be accurate; freeze qv as a fix
2202  src(i) = dim(qv(i,j), 1.e-7 )
2203  elseif ( pt1(i) < tice0 ) then
2204  qsi = iqs2(pt1(i), den(i), dqsdt)
2205  dq = qv(i,j) - qsi
2206  sink = adj_fac*dq/(1.+tcp2(i)*dqsdt)
2207  if ( qi(i,j) > qrmin ) then
2208 ! Eq 9, Hong et al. 2004, MWR; For A and B, see Dudhia 1989: page 3103 Eq (B7)-(B8)
2209  pidep = sdt*dq*349138.78*exp(0.875*log(qi(i,j)*den(i))) &
2210  / (qsi*den(i)*lat2/(0.0243*rvgas*pt1(i)**2) + 4.42478e4)
2211  else
2212  pidep = 0.
2213  endif
2214  if ( dq > 0. ) then ! vapor -> ice
2215  tmp = tice - pt1(i)
2216  qi_crt = qi_gen*min(qi_lim, 0.1*tmp) / den(i)
2217  src(i) = min(sink, max(qi_crt-qi(i,j),pidep), tmp/tcp2(i))
2218  else
2219  pidep = pidep * min(1., dim(pt1(i),t_sub)*0.2)
2220  src(i) = max(pidep, sink, -qi(i,j))
2221  endif
2222  endif
2223  endif
2224  enddo
2225  do i=is, ie
2226  qv(i,j) = qv(i,j) - src(i)
2227  qi(i,j) = qi(i,j) + src(i)
2228  pt1(i) = pt1(i) + src(i)*tcp2(i)
2229  enddo
2230 
2231 ! Enforce upper bounds on qi (autoconversion to qs)
2232  do i=is, ie
2233  qim = qi0_crt / den(i)
2234  if ( qi(i,j) > qim ) then
2235  sink = fac_i2s*(qi(i,j)-qim)
2236  qi(i,j) = qi(i,j) - sink
2237  qs(i,j) = qs(i,j) + sink
2238  endif
2239  enddo
2240 
2241 !--- TESTING the ql-->qs process
2242  do i=is, ie
2243  tc = pt1(i) - tice
2244  if( tc<-1.0 .and. qs(i,j)>1.e-7 .and. ql(i,j)>1.e-7 ) then
2245  factor = mdt*sqrt(sfcrho/den(i))*csacw*exp(0.8125*log(qs(i,j)*den(i)))
2246  psacw = min( factor/(1.+factor)*ql(i,j), -tc/icp2(i) )
2247  qs(i,j) = qs(i,j) + psacw
2248  ql(i,j) = ql(i,j) - psacw
2249  pt1(i) = pt1(i) + psacw*icp2(i)
2250  endif
2251  enddo
2252 !--- TESTING
2253  do i=is, ie
2254  if( qg(i,j) < 0. ) then
2255 ! Fix negative graupel with available ice
2256  tmp = min( -qg(i,j), max(0., qi(i,j)) )
2257  qg(i,j) = qg(i,j) + tmp
2258  qi(i,j) = qi(i,j) - tmp
2259  endif
2260  enddo
2261 ! At this point cloud ice & snow are positive definite
2262 
2263 ! rain re-evap
2264  call revap_rac1(hydrostatic, is, ie, sdt, pt1, qv(is,j), ql(is,j), qr(is,j), qi(is,j), qs(is,j), qg(is,j), den, hvar)
2265 
2266 ! Virtual temp updated !!!
2267  do i=is, ie
2268 #ifdef USE_COND
2269  q_liq(i) = ql(i,j) + qr(i,j)
2270  q_sol(i) = qi(i,j) + qs(i,j) + qg(i,j)
2271  q_con(i,j) = q_liq(i) + q_sol(i)
2272  pt(i,j) = pt1(i)*(1.+zvir*qv(i,j))*(1.-q_con(i,j))
2273 #ifdef MOIST_CAPPA
2274  cpm(i) = (1.-(qv(i,j)+q_con(i,j)))*cv_air + qv(i,j)*cv_vap + q_liq(i)*c_liq + q_sol(i)*c_ice
2275  cappa(i,j) = rdgas/(rdgas + cpm(i)/(1.+zvir*qv(i,j)))
2276 #endif
2277 #else
2278  pt(i,j) = pt1(i)*(1.+zvir*qv(i,j))
2279 #endif
2280  enddo
2281 
2282  if ( out_dt ) then
2283  do i=is, ie
2284  dtdt(i,j) = dtdt(i,j) + pt1(i) - t0(i)
2285  enddo
2286  endif
2287 
2288  if ( consv_te ) then
2289  if ( hydrostatic ) then
2290  do i=is, ie
2291  te0(i,j) = te0(i,j) + cp_air*dp(i,j)*pt1(i)*(1.+zvir*qv(i,j))
2292  enddo
2293  else
2294  do i=is, ie
2295 #if defined(USE_COND) && defined(MOIST_CAPPA)
2296  te0(i,j) = te0(i,j) + cpm(i)*dp(i,j)*pt1(i)
2297 #else
2298  te0(i,j) = te0(i,j) + cv_air*dp(i,j)*pt1(i)
2299 #endif
2300  enddo
2301  endif
2302  endif
2303 
2304 if ( do_qa .and. last_step ) then
2305 
2306  do i=is, ie
2307  qa(i,j) = 0.
2308  enddo
2309 
2310  if ( rad_snow ) then
2311  if ( rad_graupel ) then
2312  do i=is, ie
2313  q_sol(i) = qi(i,j) + qs(i,j) + qg(i,j)
2314  enddo
2315  else
2316  do i=is, ie
2317  q_sol(i) = qi(i,j) + qs(i,j)
2318  enddo
2319  endif
2320  else
2321  do i=is, ie
2322  q_sol(i) = qi(i,j)
2323  enddo
2324  endif
2325 
2326  do i=is, ie
2327  if ( p1(i) > p_min ) then
2328  if ( rad_rain) then
2329  condensates = q_sol(i) + ql(i,j) + qr(i,j)
2330  else
2331  condensates = q_sol(i) + ql(i,j)
2332  endif
2333  qpz = qv(i,j) + condensates
2334 ! Using the "liquid-frozen water temperature": tin
2335  tin = pt1(i) - ( lcp2(i)*condensates + icp2(i)*q_sol(i) ) ! minimum temperature
2336  if( tin <= t_wfr ) then
2337  qstar = iqs1(tin, den(i))
2338  elseif ( tin > tice ) then
2339  qstar = wqs1(tin, den(i))
2340  else
2341 ! mixed phase:
2342  qsi = iqs1(tin, den(i))
2343  qsw = wqs1(tin, den(i))
2344  if( condensates > 3.e-6 ) then
2345  rqi = q_sol(i) / condensates
2346  else
2347 ! Mostly liquid water clouds at initial cloud development stage
2348  rqi = (tice-tin)/(tice-t_wfr)
2349  endif
2350  qstar = rqi*qsi + (1.-rqi)*qsw
2351  endif
2352 
2353 ! Partial cloudiness by PDF:
2354 ! Assuming subgrid linear distribution in horizontal; this is effectively a smoother for the
2355 ! binary cloud scheme; qa=0.5 if qstar==qpz
2356 
2357  rh = qpz / qstar
2358  if ( rh > 0.75 .and. qpz > qrmin ) then
2359  dq = hvar(i)*qpz
2360  q_plus = qpz + dq
2361  q_minus = qpz - dq
2362  if ( qstar < q_minus ) then
2363  qa(i,j) = 1.
2364  else
2365  if ( qstar<q_plus ) then
2366  qa(i,j) = (q_plus-qstar)/(dq+dq) ! partial cloud cover
2367  endif
2368 ! Impose minimum cloudiness if substantial condensates exist
2369  if ( condensates > 1.0e-6 ) qa(i,j) = max(cld_min, qa(i,j))
2370  endif
2371  endif
2372  endif
2373  enddo
2374 endif
2375 
2376  enddo
2377 
2378  end subroutine sat_adj2
2379 
2380 
2381  subroutine revap_rac1(hydrostatic, is, ie, dt, tz, qv, ql, qr, qi, qs, qg, den, hvar)
2382  logical, intent(in):: hydrostatic
2383  integer, intent(in):: is, ie
2384  real, intent(in):: dt ! time step (s)
2385  real, intent(in), dimension(is:ie):: den, hvar, qi, qs, qg
2386  real, intent(inout), dimension(is:ie):: tz, qv, qr, ql
2387 ! local:
2388  real, dimension(is:ie):: lcp2, denfac
2389  real :: dqv, qsat, dqsdt, evap, qden, q_plus, q_minus, sink
2390  real :: tin, t2, qpz, dq, dqh, q_liq, q_sol
2391  integer i
2392 
2393  if ( hydrostatic ) then
2394  do i=is, ie
2395  q_liq = ql(i) + qr(i)
2396  q_sol = qi(i) + qs(i) + qg(i)
2397  lcp2(i) = (lv0+dc_vap*tz(i))/((1.-(qv(i)+q_liq+q_sol))*cp_air+qv(i)*cp_vap+q_liq*c_liq+q_sol*c_ice)
2398 ! denfac(i) = sqrt(sfcrho/den(i))
2399  enddo
2400  else
2401  do i=is, ie
2402  q_liq = ql(i) + qr(i)
2403  q_sol = qi(i) + qs(i) + qg(i)
2404  lcp2(i) = (lv0+dc_vap*tz(i))/((1.-(qv(i)+q_liq+q_sol))*cv_air+qv(i)*cv_vap+q_liq*c_liq+q_sol*c_ice)
2405 ! denfac(i) = sqrt(sfcrho/den(i))
2406  enddo
2407  endif
2408 
2409  do i=is, ie
2410  if ( qr(i) > qrmin .and. tz(i) > t_wfr ) then
2411  qpz = qv(i) + ql(i)
2412  tin = tz(i) - lcp2(i)*ql(i) ! presence of clouds suppresses the rain evap
2413  qsat = wqs2(tin, den(i), dqsdt)
2414  dqh = max(ql(i), hvar(i)*max(qpz, qcmin))
2415  dqv = qsat - qv(i)
2416  q_minus = qpz - dqh
2417  q_plus = qpz + dqh
2418 
2419 ! qsat must be > q_minus to activate evaporation
2420 ! qsat must be < q_plus to activate accretion
2421 
2422 !-------------------
2423 ! * Rain evaporation
2424 !-------------------
2425  if ( dqv > qvmin .and. qsat > q_minus ) then
2426  if ( qsat > q_plus ) then
2427  dq = qsat - qpz
2428  else
2429 ! q_minus < qsat < q_plus
2430 ! dq == dqh if qsat == q_minus
2431  dq = 0.25*(q_minus-qsat)**2 / dqh
2432  endif
2433  qden = qr(i)*den(i)
2434  t2 = tin * tin
2435  evap = crevp(1)*t2*dq*(crevp(2)*sqrt(qden)+crevp(3)*exp(0.725*log(qden))) &
2436  / (crevp(4)*t2 + crevp(5)*qsat*den(i))
2437  evap = min( qr(i), dt*evap, dqv/(1.+lcp2(i)*dqsdt) )
2438  qr(i) = qr(i) - evap
2439  qv(i) = qv(i) + evap
2440  tz(i) = tz(i) - evap*lcp2(i)
2441  endif
2442 
2443  if ( qr(i)>qrmin .and. ql(i)>1.e-8 .and. qsat<q_plus ) then
2444 !-------------------
2445 ! * Accretion: pracc
2446 !-------------------
2447  denfac(i) = sqrt(sfcrho/den(i))
2448  sink = dt*denfac(i)*cracw*exp(0.95*log(qr(i)*den(i)))
2449  sink = sink/(1.+sink)*ql(i)
2450  ql(i) = ql(i) - sink
2451  qr(i) = qr(i) + sink
2452  endif
2453  endif
2454  enddo
2455 
2456  end subroutine revap_rac1
2457 
2458  subroutine terminal_fall(dtm, ktop, kbot, tz, qv, ql, qr, qg, qs, qi, pm, dz, dp, &
2459  den, vtg, vts, vti, fac_sno, fac_gra, r1, g1, s1, i1, m1_sol, w1)
2461 ! lagrangian control-volume method:
2462 
2463  real, intent(in):: dtm ! time step (s)
2464  integer, intent(in):: ktop, kbot
2465  real, intent(in):: fac_sno, fac_gra
2466  real, intent(in), dimension(ktop:kbot):: vtg, vts, vti, pm, den, dp, dz
2467  real, intent(inout), dimension(ktop:kbot):: qv, ql, qr, qg, qs, qi, tz, m1_sol, w1
2468  real, intent(out):: r1, g1, s1, i1
2469 ! local:
2470  real, dimension(ktop:kbot+1):: ze, zt
2471  real :: qsat, dqsdt, dt5, melt, evap, dtime
2472  real :: factor, frac
2473  real :: tmp1, precip, tc, sink
2474  real, dimension(ktop:kbot):: lcpk, icpk
2475  real, dimension(ktop:kbot):: m1, dm
2476  real :: zs = 0.
2477  real :: cvm
2478  integer k, k0, m
2479  logical no_fall
2480 
2481 
2482  do k=ktop,kbot
2483  m1_sol(k) = 0.
2484  cvm = c_air + qv(k)*c_vap + (qr(k)+ql(k))*c_liq + (qi(k)+qs(k)+qg(k))*c_ice
2485  lcpk(k) = (lv00+dc_vap*tz(k)) / cvm
2486  icpk(k) = (li00+dc_ice*tz(k)) / cvm
2487  enddo
2488 
2489  dt5 = 0.5*dtm
2490 
2491 
2492 ! Melting of cloud_ice and snow (before fall):
2493 
2494 ! find significant melting level
2495  k0 = kbot
2496  do k=ktop, kbot-1
2497  if ( tz(k) > tice ) then
2498  k0 = k
2499  go to 11
2500  endif
2501  enddo
2502 11 continue
2503 
2504  do k=k0, kbot
2505 !------
2506 ! * ice
2507 !------
2508  tc = tz(k) - tice
2509  if( qi(k) > qcmin .and. tc>0. ) then
2510  melt = min( qi(k), tc/icpk(k) )
2511  tmp1 = min( melt, dim(ql_mlt, ql(k)) )
2512  ql(k) = ql(k) + tmp1
2513  qr(k) = qr(k) + melt - tmp1
2514  qi(k) = qi(k) - melt
2515  tz(k) = tz(k) - melt*icpk(k)
2516  tc = tz(k) - tice
2517  endif
2518 !------
2519 ! Snow
2520 !------
2521 !!!#ifdef MORE_SNOW_MLT
2522  if ( qs(k)>qvmin .and. tc>0. ) then
2523  factor = min( 1., tc/t_snow_melt)
2524  sink = min(fac_sno*qs(k), factor*tc/icpk(k))
2525  qs(k) = qs(k) - sink
2526  qr(k) = qr(k) + sink
2527  tz(k) = tz(k) - sink*icpk(k) ! cooling due to snow melting
2528  tc = tz(k) - tice
2529  endif
2530 
2531 !------
2532 ! Graupel
2533 !------
2534  if ( qg(k)>qcmin .and. tc>0.01 ) then
2535  factor = min( 1., tc/t_grau_melt )
2536  sink = min( fac_gra*qg(k), factor*tc/icpk(k) )
2537  qg(k) = qg(k) - sink
2538  qr(k) = qr(k) + sink
2539  tz(k) = tz(k) - sink*icpk(k)
2540  endif
2541 !!!#endif
2542  enddo
2543 
2544  if ( dtm < 60. ) k0 = kbot
2545  k0 = kbot
2546 
2547 !-----
2548 ! ice:
2549 !-----
2550 
2551  ze(kbot+1) = zs
2552  do k=kbot, ktop, -1
2553  ze(k) = ze(k+1) - dz(k) ! dz<0
2554  enddo
2555 
2556  zt(ktop) = ze(ktop)
2557 
2558  call check_column(ktop, kbot, qi, no_fall)
2559 
2560  if ( vi_fac < 1.e-5 .or. no_fall ) then
2561  i1 = 0.
2562  else
2563 
2564  do k=ktop+1,kbot
2565  zt(k) = ze(k) - dt5*(vti(k-1)+vti(k))
2566  enddo
2567  zt(kbot+1) = zs - dtm*vti(kbot)
2568 
2569  do k=ktop,kbot
2570  if( zt(k+1)>=zt(k) ) zt(k+1) = zt(k) - dz_min
2571  enddo
2572 
2573  if ( k0 < kbot ) then
2574  do k=kbot-1,k0,-1
2575  if ( qi(k) > qrmin ) then
2576  do m=k+1, kbot
2577  if ( zt(k+1)>=ze(m) ) exit
2578  if ( zt(k)<ze(m+1) .and. tz(m)>tice ) then
2579  dtime = min( 1.0, (ze(m)-ze(m+1))/(max(vmin,vti(k))*tau_mlt) )
2580  melt = min( qi(k)*dp(k)/dp(m), dtime*(tz(m)-tice)/icpk(m) )
2581  tmp1 = min( melt, dim(ql_mlt, ql(m)) )
2582  ql(m) = ql(m) + tmp1
2583  qr(m) = qr(m) - tmp1 + melt
2584  tz(m) = tz(m) - melt*icpk(m)
2585  qi(k) = qi(k) - melt*dp(m)/dp(k)
2586  endif
2587  enddo
2588  endif
2589  enddo
2590  endif
2591 
2592  if ( do_sedi_w ) then
2593  do k=ktop, kbot
2594  dm(k) = dp(k)*(1.+qv(k)+ql(k)+qr(k)+qi(k)+qs(k)+qg(k))
2595  enddo
2596  endif
2597  if ( use_ppm ) then
2598  call lagrangian_fall_ppm(ktop, kbot, zs, ze, zt, dp, qi, i1, m1_sol, mono_prof)
2599  else
2600  call lagrangian_fall_pcm(ktop, kbot, zs, ze, zt, dp, qi, i1, m1_sol)
2601  endif
2602 
2603  if ( do_sedi_w ) then
2604  w1(ktop) = (dm(ktop)*w1(ktop)+m1_sol(ktop)*vti(ktop)) /(dm(ktop)-m1_sol(ktop))
2605  do k=ktop+1, kbot
2606  w1(k) = (dm(k)*w1(k)-m1_sol(k-1)*vti(k-1)+m1_sol(k)*vti(k)) &
2607  / (dm(k) +m1_sol(k-1) -m1_sol(k))
2608  enddo
2609  endif
2610 
2611  endif
2612 
2613 !--------------------------------------------
2614 ! melting of falling snow (qs) into rain(qr)
2615 !--------------------------------------------
2616  r1 = 0.
2617 
2618  call check_column(ktop, kbot, qs, no_fall)
2619 
2620  if ( no_fall ) then
2621  s1 = 0.
2622  else
2623 
2624  do k=ktop+1,kbot
2625  zt(k) = ze(k) - dt5*(vts(k-1)+vts(k))
2626  enddo
2627  zt(kbot+1) = zs - dtm*vts(kbot)
2628 
2629  do k=ktop,kbot
2630  if( zt(k+1)>=zt(k) ) zt(k+1) = zt(k) - dz_min
2631  enddo
2632 
2633  if ( k0 < kbot ) then
2634  do k=kbot-1,k0,-1
2635  if ( qs(k) > qrmin ) then
2636  do m=k+1, kbot
2637  if ( zt(k+1)>=ze(m) ) exit
2638  dtime = min( dtm, (ze(m)-ze(m+1))/(vmin+vts(k)) )
2639  if ( zt(k)<ze(m+1) .and. tz(m)>tice ) then
2640  dtime = min(1., dtime/tau_s)
2641  melt = min(qs(k)*dp(k)/dp(m), dtime*(tz(m)-tice)/icpk(m))
2642  tz(m) = tz(m) - melt*icpk(m)
2643  qs(k) = qs(k) - melt*dp(m)/dp(k)
2644  if ( zt(k)<zs ) then
2645  r1 = r1 + melt*dp(m) ! precip as rain
2646  else
2647 ! qr source here will fall next time step (therefore, can evap)
2648  qr(m) = qr(m) + melt
2649  endif
2650  endif
2651  if ( qs(k) < qrmin ) exit
2652  enddo
2653  endif
2654  enddo
2655  endif
2656 
2657  if ( do_sedi_w ) then
2658  do k=ktop, kbot
2659  dm(k) = dp(k)*(1.+qv(k)+ql(k)+qr(k)+qi(k)+qs(k)+qg(k))
2660  enddo
2661  endif
2662  if ( use_ppm ) then
2663  call lagrangian_fall_ppm(ktop, kbot, zs, ze, zt, dp, qs, s1, m1, mono_prof)
2664  else
2665  call lagrangian_fall_pcm(ktop, kbot, zs, ze, zt, dp, qs, s1, m1)
2666  endif
2667  do k=ktop,kbot
2668  m1_sol(k) = m1_sol(k) + m1(k)
2669  enddo
2670  if ( do_sedi_w ) then
2671  w1(ktop) = (dm(ktop)*w1(ktop)+m1(ktop)*vts(ktop)) /(dm(ktop)-m1(ktop))
2672  do k=ktop+1, kbot
2673  w1(k) = (dm(k)*w1(k) - m1(k-1)*vts(k-1) + m1(k)*vts(k)) &
2674  / (dm(k) + m1(k-1) - m1(k))
2675  enddo
2676  endif
2677  endif
2678 
2679 !----------------------------------------------
2680 ! melting of falling graupel (qg) into rain(qr)
2681 !----------------------------------------------
2682 
2683  call check_column(ktop, kbot, qg, no_fall)
2684 
2685  if ( no_fall ) then
2686  g1 = 0.
2687  else
2688  do k=ktop+1,kbot
2689  zt(k) = ze(k) - dt5*(vtg(k-1)+vtg(k))
2690  enddo
2691  zt(kbot+1) = zs - dtm*vtg(kbot)
2692 
2693  do k=ktop,kbot
2694  if( zt(k+1)>=zt(k) ) zt(k+1) = zt(k) - dz_min
2695  enddo
2696 
2697  if ( k0 < kbot ) then
2698  do k=kbot-1,k0,-1
2699  if ( qg(k) > qrmin ) then
2700  do m=k+1, kbot
2701  if ( zt(k+1)>=ze(m) ) exit
2702  dtime = min( dtm, (ze(m)-ze(m+1))/vtg(k) )
2703  if ( zt(k)<ze(m+1) .and. tz(m)>tice ) then
2704  dtime = min(1., dtime/tau_g)
2705  melt = min(qg(k)*dp(k)/dp(m), dtime*(tz(m)-tice)/icpk(m))
2706  tz(m) = tz(m) - melt*icpk(m)
2707  qg(k) = qg(k) - melt*dp(m)/dp(k)
2708  if ( zt(k)<zs ) then
2709  r1 = r1 + melt*dp(m)
2710  else
2711  qr(m) = qr(m) + melt
2712  endif
2713  endif
2714  if ( qg(k) < qrmin ) exit
2715  enddo
2716  endif
2717  enddo
2718  endif
2719 
2720  if ( do_sedi_w ) then
2721  do k=ktop, kbot
2722  dm(k) = dp(k)*(1.+qv(k)+ql(k)+qr(k)+qi(k)+qs(k)+qg(k))
2723  enddo
2724  endif
2725  if ( use_ppm ) then
2726  call lagrangian_fall_ppm(ktop, kbot, zs, ze, zt, dp, qg, g1, m1, mono_prof)
2727  else
2728  call lagrangian_fall_pcm(ktop, kbot, zs, ze, zt, dp, qg, g1, m1)
2729  endif
2730  do k=ktop,kbot
2731  m1_sol(k) = m1_sol(k) + m1(k)
2732  enddo
2733  if ( do_sedi_w ) then
2734  w1(ktop) = (dm(ktop)*w1(ktop)+m1(ktop)*vtg(ktop)) /(dm(ktop)-m1(ktop))
2735  do k=ktop+1, kbot
2736  w1(k) = (dm(k)*w1(k) - m1(k-1)*vtg(k-1) + m1(k)*vtg(k)) &
2737  / (dm(k) + m1(k-1) - m1(k))
2738  enddo
2739  endif
2740  endif
2741 
2742 
2743  end subroutine terminal_fall
2744 
2745 
2746  subroutine check_column(ktop, kbot, q, no_fall)
2747  integer, intent(in):: ktop, kbot
2748  real, intent(in):: q(ktop:kbot)
2749  logical, intent(out):: no_fall
2750 ! local:
2751  integer k
2752 
2753  no_fall = .true.
2754  do k=ktop, kbot
2755  if ( q(k) > qrmin ) then
2756  no_fall = .false.
2757  exit
2758  endif
2759  enddo
2760 
2761  end subroutine check_column
2762 
2763 
2764  subroutine lagrangian_fall_pcm(ktop, kbot, zs, ze, zt, dp, q, precip, m1)
2765  real, intent(in):: zs
2766  integer, intent(in):: ktop, kbot
2767  real, intent(in), dimension(ktop:kbot+1):: ze, zt
2768  real, intent(in), dimension(ktop:kbot):: dp
2769  real, intent(inout), dimension(ktop:kbot):: q, m1
2770  real, intent(out):: precip
2771 ! local:
2772  real, dimension(ktop:kbot):: qm
2773  integer k, k0, n, m
2774 
2775 ! density:
2776  do k=ktop,kbot
2777  q(k) = q(k)*dp(k) / (zt(k)-zt(k+1))
2778  qm(k) = 0.
2779  enddo
2780 
2781  k0 = ktop
2782  do k=ktop,kbot
2783  do n=k0,kbot
2784  if(ze(k) <= zt(n) .and. ze(k) >= zt(n+1)) then
2785  if(ze(k+1) >= zt(n+1)) then
2786 ! entire new grid is within the original grid
2787  qm(k) = q(n)*(ze(k)-ze(k+1))
2788  k0 = n
2789  goto 555
2790  else
2791  qm(k) = q(n)*(ze(k)-zt(n+1)) ! fractional area
2792  do m=n+1,kbot
2793 ! locate the bottom edge: ze(k+1)
2794  if(ze(k+1) < zt(m+1) ) then
2795  qm(k) = qm(k) + q(m)
2796  else
2797  qm(k) = qm(k) + q(m)*(zt(m)-ze(k+1))
2798  k0 = m
2799  goto 555
2800  endif
2801  enddo
2802  goto 555
2803  endif
2804  endif
2805  enddo
2806 555 continue
2807  enddo
2808 
2809  m1(ktop) = q(ktop) - qm(ktop)
2810  do k=ktop+1,kbot
2811  m1(k) = m1(k-1) + q(k) - qm(k)
2812  enddo
2813 
2814 #ifdef DO_DIRECT_PRECIP
2815  precip = 0.
2816 ! direct algorithm (prevent small negatives)
2817  do k=ktop,kbot
2818  if ( zt(k+1) < zs ) then
2819  precip = q(k)*(zs-zt(k+1))
2820  if ( (k+1) > kbot ) goto 777
2821  do m=k+1,kbot
2822  precip = precip + q(m)
2823  enddo
2824  goto 777
2825  endif
2826  enddo
2827 777 continue
2828 #else
2829  precip = m1(kbot)
2830 #endif
2831 
2832 ! Convert back to *dry* mixing ratio:
2833 ! dp must be dry air_mass (because moist air mass will be changed due to terminal fall).
2834  do k=ktop,kbot
2835  q(k) = qm(k)/dp(k)
2836  enddo
2837 
2838  end subroutine lagrangian_fall_pcm
2839 
2840 
2841 
2842  subroutine lagrangian_fall_ppm(ktop, kbot, zs, ze, zt, dp, q, precip, m1, mono)
2843  integer, intent(in):: ktop, kbot
2844  real, intent(in):: zs
2845  logical, intent(in):: mono
2846  real, intent(in), dimension(ktop:kbot+1):: ze, zt
2847  real, intent(in), dimension(ktop:kbot):: dp
2848 ! m1: flux
2849  real, intent(inout), dimension(ktop:kbot):: q, m1
2850  real, intent(out):: precip
2851 ! local:
2852  real, dimension(ktop:kbot):: qm, dz
2853  real:: a4(4,ktop:kbot)
2854  real:: pl, pr, delz, esl
2855  integer k, k0, n, m
2856  real, parameter:: r3 = 1./3., r23 = 2./3.
2857 
2858 ! density:
2859  do k=ktop,kbot
2860  dz(k) = zt(k) - zt(k+1) ! note: dz is positive
2861  q(k) = q(k) * dp(k)
2862  a4(1,k) = q(k) / dz(k)
2863  qm(k) = 0.
2864  enddo
2865 
2866 ! Construct vertical profile with zt as coordinate
2867 
2868  call cs_profile(a4(1,ktop), dz(ktop), kbot-ktop+1, mono)
2869 
2870  k0 = ktop
2871  do k=ktop,kbot
2872  do n=k0,kbot
2873  if(ze(k) <= zt(n) .and. ze(k) >= zt(n+1)) then
2874  pl = (zt(n)-ze(k)) / dz(n)
2875  if( zt(n+1) <= ze(k+1) ) then
2876 ! entire new grid is within the original grid
2877  pr = (zt(n)-ze(k+1)) / dz(n)
2878  qm(k) = a4(2,n) + 0.5*(a4(4,n)+a4(3,n)-a4(2,n))*(pr+pl) - &
2879  a4(4,n)*r3*(pr*(pr+pl)+pl**2)
2880  qm(k) = qm(k)*(ze(k)-ze(k+1))
2881  k0 = n
2882  goto 555
2883  else
2884  qm(k) = (ze(k)-zt(n+1)) * (a4(2,n)+0.5*(a4(4,n)+ &
2885  a4(3,n)-a4(2,n))*(1.+pl) - a4(4,n)*( r3*(1.+pl*(1.+pl))) )
2886  if ( n<kbot ) then
2887  do m=n+1,kbot
2888 ! locate the bottom edge: ze(k+1)
2889  if( ze(k+1) < zt(m+1) ) then
2890  qm(k) = qm(k) + q(m)
2891  else
2892  delz = zt(m) - ze(k+1)
2893  esl = delz / dz(m)
2894  qm(k) = qm(k) + delz*( a4(2,m) + 0.5*esl* &
2895  (a4(3,m)-a4(2,m)+a4(4,m)*(1.-r23*esl)) )
2896  k0 = m
2897  goto 555
2898  endif
2899  enddo
2900  endif
2901  goto 555
2902  endif
2903  endif
2904  enddo
2905 555 continue
2906  enddo
2907 
2908  m1(ktop) = q(ktop) - qm(ktop)
2909  do k=ktop+1,kbot
2910  m1(k) = m1(k-1) + q(k) - qm(k)
2911  enddo
2912  precip = m1(kbot)
2913 
2914 ! Convert back to *dry* mixing ratio:
2915 ! dp must be dry air_mass (because moist air mass will be changed due to terminal fall).
2916  do k=ktop,kbot
2917  q(k) = qm(k)/dp(k)
2918  enddo
2919 
2920  end subroutine lagrangian_fall_ppm
2921 
2922 
2923  subroutine cs_profile(a4, del, km, do_mono)
2924  integer, intent(in):: km ! vertical dimension
2925  real , intent(in):: del(km)
2926  logical, intent(in):: do_mono
2927  real , intent(inout):: a4(4,km)
2928 !-----------------------------------------------------------------------
2929  real, parameter:: qp_min = 1.e-6
2930  real gam(km)
2931  real q(km+1)
2932  real d4, bet, a_bot, grat, pmp, lac
2933  real pmp_1, lac_1, pmp_2, lac_2
2934  real da1, da2, a6da
2935  integer k
2936  logical extm(km)
2937 
2938  grat = del(2) / del(1) ! grid ratio
2939  bet = grat*(grat+0.5)
2940  q(1) = (2.*grat*(grat+1.)*a4(1,1)+a4(1,2)) / bet
2941  gam(1) = ( 1. + grat*(grat+1.5) ) / bet
2942 
2943  do k=2,km
2944  d4 = del(k-1) / del(k)
2945  bet = 2. + 2.*d4 - gam(k-1)
2946  q(k) = (3.*(a4(1,k-1)+d4*a4(1,k))-q(k-1))/bet
2947  gam(k) = d4 / bet
2948  enddo
2949 
2950  a_bot = 1. + d4*(d4+1.5)
2951  q(km+1) = (2.*d4*(d4+1.)*a4(1,km)+a4(1,km-1)-a_bot*q(km)) &
2952  / ( d4*(d4+0.5) - a_bot*gam(km) )
2953 
2954  do k=km,1,-1
2955  q(k) = q(k) - gam(k)*q(k+1)
2956  enddo
2957 
2958 !------------------
2959 ! Apply constraints
2960 !------------------
2961  do k=2,km
2962  gam(k) = a4(1,k) - a4(1,k-1)
2963  enddo
2964 
2965 ! Apply large-scale constraints to ALL fields if not local max/min
2966 
2967 ! Top:
2968  q(1) = max( q(1), 0. )
2969  q(2) = min( q(2), max(a4(1,1), a4(1,2)) )
2970  q(2) = max( q(2), min(a4(1,1), a4(1,2)), 0. )
2971 
2972 ! Interior:
2973  do k=3,km-1
2974  if ( gam(k-1)*gam(k+1)>0. ) then
2975  q(k) = min( q(k), max(a4(1,k-1),a4(1,k)) )
2976  q(k) = max( q(k), min(a4(1,k-1),a4(1,k)) )
2977  else
2978  if ( gam(k-1) > 0. ) then
2979 ! There exists a local max
2980  q(k) = max( q(k), min(a4(1,k-1),a4(1,k)) )
2981  else
2982 ! There exists a local min
2983  q(k) = min( q(k), max(a4(1,k-1),a4(1,k)) )
2984  q(k) = max( q(k), 0.0 )
2985  endif
2986  endif
2987  enddo
2988 
2989  q(km ) = min( q(km), max(a4(1,km-1), a4(1,km)) )
2990  q(km ) = max( q(km), min(a4(1,km-1), a4(1,km)), 0. )
2991 ! q(km+1) = max( q(km+1), 0.)
2992 
2993 !-----------------------------------------------------------
2994 ! f(s) = AL + s*[(AR-AL) + A6*(1-s)] ( 0 <= s <= 1 )
2995 !-----------------------------------------------------------
2996  do k=1,km-1
2997  a4(2,k) = q(k )
2998  a4(3,k) = q(k+1)
2999  enddo
3000 
3001  do k=2,km-1
3002  if ( gam(k)*gam(k+1) > 0.0 ) then
3003  extm(k) = .false.
3004  else
3005  extm(k) = .true.
3006  endif
3007  enddo
3008 
3009  if ( do_mono ) then
3010  do k=3,km-2
3011  if ( extm(k) ) then
3012 ! positive definite constraint ONLY if true local extrema
3013  if ( a4(1,k)<qp_min .or. extm(k-1) .or. extm(k+1) ) then
3014  a4(2,k) = a4(1,k)
3015  a4(3,k) = a4(1,k)
3016  endif
3017  else
3018  a4(4,k) = 6.*a4(1,k) - 3.*(a4(2,k)+a4(3,k))
3019  if( abs(a4(4,k)) > abs(a4(2,k)-a4(3,k)) ) then
3020 ! Check within the smooth region if subgrid profile is non-monotonic
3021  pmp_1 = a4(1,k) - 2.0*gam(k+1)
3022  lac_1 = pmp_1 + 1.5*gam(k+2)
3023  a4(2,k) = min( max(a4(2,k), min(a4(1,k), pmp_1, lac_1)), &
3024  max(a4(1,k), pmp_1, lac_1) )
3025  pmp_2 = a4(1,k) + 2.0*gam(k)
3026  lac_2 = pmp_2 - 1.5*gam(k-1)
3027  a4(3,k) = min( max(a4(3,k), min(a4(1,k), pmp_2, lac_2)), &
3028  max(a4(1,k), pmp_2, lac_2) )
3029  endif
3030  endif
3031  enddo
3032  else
3033  do k=3,km-2
3034  if ( extm(k) .and. (extm(k-1).or.extm(k+1).or.a4(1,k)<qp_min) ) then
3035  a4(2,k) = a4(1,k)
3036  a4(3,k) = a4(1,k)
3037  endif
3038  enddo
3039  endif
3040 
3041  do k=1,km-1
3042  a4(4,k) = 6.*a4(1,k) - 3.*(a4(2,k)+a4(3,k))
3043  enddo
3044 
3045  k = km-1
3046  if( extm(k) ) then
3047  a4(2,k) = a4(1,k)
3048  a4(3,k) = a4(1,k)
3049  a4(4,k) = 0.
3050  else
3051  da1 = a4(3,k) - a4(2,k)
3052  da2 = da1**2
3053  a6da = a4(4,k)*da1
3054  if(a6da < -da2) then
3055  a4(4,k) = 3.*(a4(2,k)-a4(1,k))
3056  a4(3,k) = a4(2,k) - a4(4,k)
3057  elseif(a6da > da2) then
3058  a4(4,k) = 3.*(a4(3,k)-a4(1,k))
3059  a4(2,k) = a4(3,k) - a4(4,k)
3060  endif
3061  endif
3062 
3063  call cs_limiters(km-1, a4)
3064 
3065 ! Bottom layer:
3066  a4(2,km) = a4(1,km)
3067  a4(3,km) = a4(1,km)
3068  a4(4,km) = 0.
3069 
3070  end subroutine cs_profile
3071 
3072 
3073 
3074  subroutine cs_limiters(km, a4)
3075  integer, intent(in) :: km
3076  real, intent(inout) :: a4(4,km) ! PPM array
3077 ! !LOCAL VARIABLES:
3078  real, parameter:: r12 = 1./12.
3079  integer k
3080 
3081 ! Positive definite constraint
3082 
3083  do k=1,km
3084  if( abs(a4(3,k)-a4(2,k)) < -a4(4,k) ) then
3085  if( (a4(1,k)+0.25*(a4(3,k)-a4(2,k))**2/a4(4,k)+a4(4,k)*r12) < 0. ) then
3086  if( a4(1,k)<a4(3,k) .and. a4(1,k)<a4(2,k) ) then
3087  a4(3,k) = a4(1,k)
3088  a4(2,k) = a4(1,k)
3089  a4(4,k) = 0.
3090  elseif( a4(3,k) > a4(2,k) ) then
3091  a4(4,k) = 3.*(a4(2,k)-a4(1,k))
3092  a4(3,k) = a4(2,k) - a4(4,k)
3093  else
3094  a4(4,k) = 3.*(a4(3,k)-a4(1,k))
3095  a4(2,k) = a4(3,k) - a4(4,k)
3096  endif
3097  endif
3098  endif
3099  enddo
3100 
3101  end subroutine cs_limiters
3102 
3103 
3104 
3105  subroutine fall_speed(ktop, kbot, den, qs, qi, qg, ql, tk, vts, vti, vtg)
3106  integer, intent(in) :: ktop, kbot
3107  real, intent(in ), dimension(ktop:kbot) :: den, qs, qi, qg, ql, tk
3108  real, intent(out), dimension(ktop:kbot) :: vts, vti, vtg
3109 ! fall velocity constants:
3110  real, parameter :: thi = 1.0e-9 ! cloud ice threshold for terminal fall
3111  real, parameter :: thg = 1.0e-9
3112  real, parameter :: ths = 1.0e-9
3113  real, parameter :: vf_min = 1.0e-5
3114  real, parameter :: vs_max = 7. ! max fall speed for snow
3115 !-----------------------------------------------------------------------
3116 ! marshall-palmer constants
3117 !-----------------------------------------------------------------------
3118  real :: vcons = 6.6280504, vcong = 87.2382675, vconi = 3.29
3119  real :: norms = 942477796.076938, &
3120  normg = 5026548245.74367
3121  real, dimension(ktop:kbot) :: ri, qden, tc, rhof
3122  real :: aa = -4.14122e-5, bb = -0.00538922, cc = -0.0516344, dd = 0.00216078, ee = 1.9714
3123 
3124  real :: rho0, vconf
3125  integer:: k
3126 !-----------------------------------------------------------------------
3127 ! marshall-palmer formula
3128 !-----------------------------------------------------------------------
3129 
3130 ! try the local air density -- for global model; the true value could be
3131 ! much smaller than sfcrho over high mountains
3132 
3133  if ( den_ref < 0. ) then
3134  rho0 = -den_ref*den(kbot)
3135  else
3136  rho0 = den_ref ! default=1.2
3137  endif
3138 
3139  do k=ktop, kbot
3140  rhof(k) = sqrt( min(100., rho0/den(k)) )
3141  enddo
3142 
3143  do k=ktop, kbot
3144 ! snow:
3145  if ( qs(k) < ths ) then
3146  vts(k) = vf_min
3147  else
3148  vts(k) = max(vf_min, vcons*rhof(k)*exp(0.0625*log(qs(k)*den(k)/norms)))
3149  vts(k) = min(vs_max, vs_fac*vts(k) )
3150  endif
3151 
3152 ! graupel:
3153  if ( qg(k) < thg ) then
3154  vtg(k) = vf_min
3155  else
3156  vtg(k) = max(vf_min, max(vmin, vg_fac*vcong*rhof(k)*sqrt(sqrt(sqrt(qg(k)*den(k)/normg)))))
3157  endif
3158  enddo
3159 
3160 ! ice:
3161  if ( use_deng_mace ) then
3162 ! ice use Deng and Mace (2008, GRL), which gives smaller fall speed than HD90 formula
3163  do k=ktop, kbot
3164  if ( qi(k) < thi ) then
3165  vti(k) = vf_min
3166  else
3167  qden(k) = log10( 1000.*qi(k)*den(k) ) !--- used in DM formula, in g/m^-3
3168  tc(k) = tk(k) - tice
3169  vti(k) = qden(k)*( tc(k)*(aa*tc(k) + bb) + cc ) + dd*tc(k) + ee
3170  vti(k) = max( vf_min, vi_fac*0.01*10.**vti(k) )
3171  endif
3172  enddo
3173  else
3174 ! HD90 ice speed:
3175  vconf = vi_fac*vconi
3176  do k=ktop, kbot
3177  if ( qi(k) < thi ) then
3178  vti(k) = vf_min
3179  else
3180 ! vti = vconi*rhof*(qi*den)**0.16
3181  vti(k) = max( vf_min, vconf*rhof(k)*exp(0.16*log(qi(k)*den(k))) )
3182  endif
3183  enddo
3184  endif
3185 
3186  end subroutine fall_speed
3187 
3188 
3189  subroutine setupm
3191  real :: gcon, cd, scm3, pisq, act(8), acc(3)
3192  real :: vdifu, tcond
3193  real :: visk
3194  real :: ch2o, hltf
3195  real :: hlts, hltc, ri50
3196 
3197  real :: gam263, gam275, gam290, &
3198  gam325, gam350, gam380, &
3199  gam425, gam450, gam480, &
3200  gam625, gam680
3201 
3202  data gam263/1.456943/, gam275/1.608355/, gam290/1.827363/ &
3203  gam325/2.54925/, gam350/3.323363/, gam380/4.694155/ &
3204  gam425/8.285063/, gam450/11.631769/, gam480/17.837789/ &
3205  gam625/184.860962/, gam680/496.604067/
3206 !
3207 ! physical constants (mks)
3208 !
3209  real :: rnzr, rnzs, rnzg, rhos, rhog
3210  data rnzr /8.0e6/ ! lin83
3211  data rnzs /3.0e6/ ! lin83
3212  data rnzg /4.0e6/ ! rh84
3213  data rhos /0.1e3/ ! lin83 (snow density; 1/10 of water)
3214  data rhog /0.4e3/ ! rh84 (graupel density)
3215  data acc/5.0,2.0,0.5/
3216 
3217  real den_rc
3218  integer :: k, i
3219 
3220  pie = 4.*atan(1.0)
3221 
3222 ! S. Klein's formular (EQ 16) from AM2
3223  fac_rc = (4./3.)*pie*rhor*rthresh**3
3224 
3225  if ( prog_ccn ) then
3226  if(master) write(*,*) 'prog_ccn option is .T.'
3227  else
3228  den_rc = fac_rc * ccn_o*1.e6
3229  if(master) write(*,*) 'MP: rthresh=', rthresh, 'vi_fac=', vi_fac
3230  if(master) write(*,*) 'MP: for ccn_o=', ccn_o, 'ql_rc=', den_rc
3231  den_rc = fac_rc * ccn_l*1.e6
3232  if(master) write(*,*) 'MP: for ccn_l=', ccn_l, 'ql_rc=', den_rc
3233  endif
3234 
3235  vdifu=2.11e-5
3236  tcond=2.36e-2
3237 
3238  visk=1.259e-5
3239  hlts=2.8336e6
3240  hltc=2.5e6
3241  hltf=3.336e5
3242 
3243  ch2o=4.1855e3
3244  ri50=1.e-4
3245 
3246  pisq = pie*pie
3247  scm3 = (visk/vdifu)**(1./3.)
3248 !
3249  cracs = pisq*rnzr*rnzs*rhos
3250  csacr = pisq*rnzr*rnzs*rhor
3251  cgacr = pisq*rnzr*rnzg*rhor
3252  cgacs = pisq*rnzg*rnzs*rhos
3253  cgacs = cgacs*c_pgacs
3254 !
3255 ! act: 1-2:racs(s-r); 3-4:sacr(r-s);
3256 ! 5-6:gacr(r-g); 7-8:gacs(s-g)
3257 !
3258  act(1) = pie * rnzs * rhos
3259  act(2) = pie * rnzr * rhor
3260  act(6) = pie * rnzg * rhog
3261  act(3) = act(2)
3262  act(4) = act(1)
3263  act(5) = act(2)
3264  act(7) = act(1)
3265  act(8) = act(6)
3266 
3267  do i=1,3
3268  do k=1,4
3269  acco(i,k) = acc(i)/(act(2*k-1)**((7-i)*0.25)*act(2*k)**(i*0.25))
3270  enddo
3271  enddo
3272 !
3273  gcon = 40.74 * sqrt( sfcrho ) ! 44.628
3274 !
3275  csacw = pie*rnzs*clin*gam325/(4.*act(1)**0.8125)
3276 ! Decreasing csacw to reduce cloud water ---> snow
3277 
3278  craci = pie*rnzr*alin*gam380/(4.*act(2)**0.95)
3279  csaci = csacw * c_psaci
3280 !
3281  cgacw = pie*rnzg*gam350*gcon/(4.*act(6)**0.875)
3282 ! cgaci = cgacw*0.1
3283 ! SJL, May 28, 2012
3284  cgaci = cgacw*0.05
3285 !
3286  cracw = craci ! cracw= 3.27206196043822
3287  cracw = c_cracw * cracw
3288 !
3289 ! subl and revp: five constants for three separate processes
3290 !
3291  cssub(1) = 2.*pie*vdifu*tcond*rvgas*rnzs
3292  cgsub(1) = 2.*pie*vdifu*tcond*rvgas*rnzg
3293  crevp(1) = 2.*pie*vdifu*tcond*rvgas*rnzr
3294  cssub(2) = 0.78/sqrt(act(1))
3295  cgsub(2) = 0.78/sqrt(act(6))
3296  crevp(2) = 0.78/sqrt(act(2))
3297  cssub(3) = 0.31*scm3*gam263*sqrt(clin/visk)/act(1)**0.65625
3298  cgsub(3) = 0.31*scm3*gam275*sqrt(gcon/visk)/act(6)**0.6875
3299  crevp(3) = 0.31*scm3*gam290*sqrt(alin/visk)/act(2)**0.725
3300  cssub(4) = tcond*rvgas
3301  cssub(5) = hlts**2*vdifu
3302  cgsub(4) = cssub(4)
3303  crevp(4) = cssub(4)
3304  cgsub(5) = cssub(5)
3305  crevp(5) = hltc**2*vdifu
3306 !
3307  cgfr(1) = 20.e2*pisq*rnzr*rhor/act(2)**1.75
3308  cgfr(2) = 0.66
3309 !
3310 !sk ********************************************************************
3311 !sk smlt: five constants ( lin et al. 1983 )
3312  csmlt(1) = 2.*pie*tcond*rnzs/hltf
3313  csmlt(2) = 2.*pie*vdifu*rnzs*hltc/hltf
3314  csmlt(3) = cssub(2)
3315  csmlt(4) = cssub(3)
3316  csmlt(5) = ch2o/hltf
3317 !sk ********************************************************************
3318 ! gmlt: five constants
3319  cgmlt(1) = 2.*pie*tcond*rnzg/hltf
3320  cgmlt(2) = 2.*pie*vdifu*rnzg*hltc/hltf
3321  cgmlt(3) = cgsub(2)
3322  cgmlt(4) = cgsub(3)
3323  cgmlt(5) = ch2o/hltf
3324 !sk ********************************************************************
3325  es0 = 6.107799961e2 ! ~6.1 mb
3326  ces0 = eps*es0
3327 
3328  end subroutine setupm
3329 
3330 
3331  subroutine lin_cld_microphys_init(id, jd, kd, axes, time)
3333  integer, intent(in) :: id, jd, kd
3334  integer, intent(in) :: axes(4)
3335  type(time_type), intent(in) :: time
3336 
3337  integer :: unit, io, ierr, k, logunit
3338  logical :: flag
3339  real :: tmp, q1, q2
3340 
3341  master = (mpp_pe().eq.mpp_root_pe())
3342 
3343 #ifdef INTERNAL_FILE_NML
3344  read( input_nml_file, nml = lin_cld_microphys_nml, iostat = io )
3345  ierr = check_nml_error(io,'lin_cloud_microphys_nml')
3346 #else
3347  if( file_exist( 'input.nml' ) ) then
3348  unit = open_namelist_file()
3349  io = 1
3350  do while ( io .ne. 0 )
3351  read( unit, nml = lin_cld_microphys_nml, iostat = io, end = 10 )
3352  ierr = check_nml_error(io,'lin_cloud_microphys_nml')
3353  end do
3354 10 call close_file ( unit )
3355  end if
3356 #endif
3357  call write_version_number ('0.0', 'fv3-jedi-lm')
3358  logunit = stdlog()
3359 
3360  if ( do_setup ) then
3361  call setup_con
3362  call setupm
3363  do_setup = .false.
3364  endif
3365 
3366  tice0 = tice - 0.1
3367  t_wfr = tice - 40. ! supercooled water can exist down to -48 C, which is the "absolute"
3368 
3369  if (master) write( logunit, nml = lin_cld_microphys_nml )
3370 #ifndef MAPL_MODE
3371  id_vtr = register_diag_field( mod_name, 'vt_r', axes(1:3), time, &
3372  'rain fall speed', 'm/sec', missing_value=missing_value )
3373  id_vts = register_diag_field( mod_name, 'vt_s', axes(1:3), time, &
3374  'snow fall speed', 'm/sec', missing_value=missing_value )
3375  id_vtg = register_diag_field( mod_name, 'vt_g', axes(1:3), time, &
3376  'graupel fall speed', 'm/sec', missing_value=missing_value )
3377  id_vti = register_diag_field( mod_name, 'vt_i', axes(1:3), time, &
3378  'ice fall speed', 'm/sec', missing_value=missing_value )
3379  id_droplets = register_diag_field( mod_name, 'droplets', axes(1:3), time, &
3380  'droplet number concentration', '#/m3', missing_value=missing_value )
3381  id_rh = register_diag_field( mod_name, 'rh_lin', axes(1:2), time, &
3382  'relative humidity', 'n/a', missing_value=missing_value )
3383 
3384  id_rain = register_diag_field( mod_name, 'rain_lin', axes(1:2), time, &
3385  'rain_lin', 'mm/day', missing_value=missing_value )
3386  id_snow = register_diag_field( mod_name, 'snow_lin', axes(1:2), time, &
3387  'snow_lin', 'mm/day', missing_value=missing_value )
3388  id_graupel = register_diag_field( mod_name, 'graupel_lin', axes(1:2), time, &
3389  'graupel_lin', 'mm/day', missing_value=missing_value )
3390  id_ice = register_diag_field( mod_name, 'ice_lin', axes(1:2), time, &
3391  'ice_lin', 'mm/day', missing_value=missing_value )
3392  id_prec = register_diag_field( mod_name, 'prec_lin', axes(1:2), time, &
3393  'prec_lin', 'mm/day', missing_value=missing_value )
3394 ! if ( master ) write(*,*) 'prec_lin diagnostics initialized.', id_prec
3395 
3396  id_cond = register_diag_field( mod_name, 'cond_lin', axes(1:2), time, &
3397  'total condensate', 'kg/m**2', missing_value=missing_value )
3398 
3399  id_var = register_diag_field( mod_name, 'var_lin', axes(1:2), time, &
3400  'subgrid variance', 'n/a', missing_value=missing_value )
3401 
3402  id_dbz = register_diag_field( mod_name, 'reflectivity', axes(1:3), time, &
3403  'Stoelinga simulated reflectivity', 'dBz', missing_value=missing_value)
3404 
3405  id_maxdbz = register_diag_field( mod_name, 'max_reflectivity', axes(1:2), time, &
3406  'Stoelinga simulated maximum (composite) reflectivity', 'dBz', missing_value=missing_value)
3407 
3408  id_basedbz = register_diag_field( mod_name, 'base_reflectivity', axes(1:2), time, &
3409  'Stoelinga simulated base reflectivity', 'dBz', missing_value=missing_value)
3410 ! call qsmith_init
3411 #endif
3412 
3413 ! TESTING the water vapor tables
3414  if ( mp_debug .and. master ) then
3415  write(*,*) 'TESTING water vapor tables in lin_cld_microphys'
3416  tmp = tice - 90.
3417  do k=1,25
3418  q1 = wqsat_moist(tmp, real(0,kind=FVPRC), real(10000,kind=fvprc))
3419  q2 = qs1d_m(tmp, real(0,kind=FVPRC), real(100000,kind=fvprc))
3420  write(*,*) nint(tmp-tice), q1, q2, 'dq=', q1-q2
3421  tmp = tmp + 5.
3422  enddo
3423  endif
3424 
3425  if ( master ) write(*,*) 'lin_cld_micrphys diagnostics initialized.'
3426 
3427  lin_cld_mp_clock = mpp_clock_id('Lin_cld_microphys', grain=clock_routine)
3428 
3429  module_is_initialized = .true.
3430 
3431  end subroutine lin_cld_microphys_init
3432 
3433 
3434 
3435  subroutine lin_cld_microphys_end
3437  deallocate ( table )
3438  deallocate ( table2 )
3439  deallocate ( table3 )
3440  deallocate ( tablew )
3441  deallocate ( des )
3442  deallocate ( des2 )
3443  deallocate ( des3 )
3444  deallocate ( desw )
3445 
3446  tables_are_initialized = .false.
3447 
3448  end subroutine lin_cld_microphys_end
3449 
3450 
3451 
3452  subroutine setup_con
3454  master = (mpp_pe().eq.mpp_root_pe())
3455  rgrav = 1./ grav
3456 
3457  if ( .not. qsmith_tables_initialized ) call qsmith_init
3458  qsmith_tables_initialized = .true.
3459 
3460  end subroutine setup_con
3461 
3462 
3463 
3464  real function acr3d(v1, v2, q1, q2, c, cac, rho)
3465  real, intent(in) :: v1, v2, c, rho
3466  real, intent(in) :: q1, q2 ! mixing ratio!!!
3467  real, intent(in) :: cac(3)
3468  real :: t1, s1, s2
3469 !integer :: k
3470 ! real :: a
3471 ! a=0.0
3472 ! do k=1,3
3473 ! a = a + cac(k)*( (q1*rho)**((7-k)*0.25) * (q2*rho)**(k*0.25) )
3474 ! enddo
3475 ! acr3d = c * abs(v1-v2) * a/rho
3476 !----------
3477 ! Optimized
3478 !----------
3479  t1 = sqrt(q1*rho)
3480  s1 = sqrt(q2*rho)
3481  s2 = sqrt(s1) ! s1 = s2**2
3482  acr3d = c*abs(v1-v2)*q1*s2*(cac(1)*t1 + cac(2)*sqrt(t1)*s2 + cac(3)*s1)
3483 
3484  end function acr3d
3485 
3486 
3487 
3488 
3489  real function smlt(tc, dqs, qsrho,psacw,psacr,c,rho, rhofac)
3490  real, intent(in):: tc,dqs,qsrho,psacw,psacr,c(5),rho, rhofac
3491 
3492  smlt = (c(1)*tc/rho-c(2)*dqs) * (c(3)*sqrt(qsrho)+ &
3493  c(4)*qsrho**0.65625*sqrt(rhofac)) + c(5)*tc*(psacw+psacr)
3494 
3495  end function smlt
3496 
3497 
3498  real function gmlt(tc, dqs,qgrho,pgacw,pgacr,c, rho)
3499  real, intent(in):: tc,dqs,qgrho,pgacw,pgacr,c(5),rho
3500 
3501 ! note: pgacw and pgacr must be calc before gmlt is called
3502 !
3503  gmlt = (c(1)*tc/rho-c(2)*dqs) * (c(3)*sqrt(qgrho)+ &
3504  c(4)*qgrho**0.6875/rho**0.25) + c(5)*tc*(pgacw+pgacr)
3505  end function gmlt
3506 
3507 
3508  subroutine qsmith_init
3509  integer, parameter:: length=2621
3510  integer i
3511 
3512  if( .not. tables_are_initialized ) then
3513 
3514  master = (mpp_pe().eq.mpp_root_pe())
3515  if (master) print*, ' lin MP: initializing qs tables'
3516 !!! DEBUG CODE
3517 ! print*, mpp_pe(), allocated(table), allocated(table2), allocated(table3), allocated(tablew), allocated(des), allocated(des2), allocated(des3), allocated(desw)
3518 !!! END DEBUG CODE
3519 
3520 ! generate es table (dt = 0.1 deg. c)
3521  allocate ( table( length) )
3522  allocate ( table2(length) )
3523  allocate ( table3(length) )
3524  allocate ( tablew(length) )
3525  allocate ( des(length) )
3526  allocate ( des2(length) )
3527  allocate ( des3(length) )
3528  allocate ( desw(length) )
3529 
3530  call qs_table (length )
3531  call qs_table2(length )
3532  call qs_table3(length )
3533  call qs_tablew(length )
3534 
3535  do i=1,length-1
3536  des(i) = max(0., table(i+1) - table(i))
3537  des2(i) = max(0., table2(i+1) - table2(i))
3538  des3(i) = max(0., table3(i+1) - table3(i))
3539  desw(i) = max(0., tablew(i+1) - tablew(i))
3540  enddo
3541  des(length) = des(length-1)
3542  des2(length) = des2(length-1)
3543  des3(length) = des3(length-1)
3544  desw(length) = desw(length-1)
3545 
3546  tables_are_initialized = .true.
3547  endif
3548 
3549  end subroutine qsmith_init
3550 
3551  real function wqs1(ta, den)
3552 ! Pure water phase; universal dry/moist formular using air density
3553 ! Input "den" can be either dry or moist air density
3554  real, intent(in):: ta, den
3555 ! local:
3556  real es, ap1
3557  real, parameter:: tmin=table_ice - 160.
3558  integer it
3559 
3560  ap1 = 10.*dim(ta, tmin) + 1.
3561  ap1 = min(2621., ap1)
3562  it = ap1
3563  es = tablew(it) + (ap1-it)*desw(it)
3564  wqs1 = es / (rvgas*ta*den)
3565 
3566  end function wqs1
3567 
3568  real function wqs2(ta, den, dqdt)
3569 ! Pure water phase; universal dry/moist formular using air density
3570 ! Input "den" can be either dry or moist air density
3571  real, intent(in):: ta, den
3572  real, intent(out):: dqdt
3573 ! local:
3574  real :: es, ap1
3575  real, parameter:: tmin=table_ice - 160.
3576  integer it
3577 
3578  if (.not. tables_are_initialized) call qsmith_init
3579 
3580  ap1 = 10.*dim(ta, tmin) + 1.
3581  ap1 = min(2621., ap1)
3582  it = ap1
3583  es = tablew(it) + (ap1-it)*desw(it)
3584  wqs2 = es / (rvgas*ta*den)
3585  it = ap1 - 0.5
3586 ! Finite diff, del_T = 0.1:
3587  dqdt = 10.*(desw(it) + (ap1-it)*(desw(it+1)-desw(it))) / (rvgas*ta*den)
3588 
3589  end function wqs2
3590 
3591  real function wet_bulb(q, t, den)
3592 ! Liquid phase only
3593  real, intent(in):: t, q, den
3594  real :: qs, tp, dqdt
3595 
3596  wet_bulb = t
3597  qs = wqs2(wet_bulb, den, dqdt)
3598  tp = 0.5*(qs-q)/(1.+lcp*dqdt)*lcp
3599  wet_bulb = wet_bulb - tp
3600 ! tp is negative if super-saturated
3601  if ( tp > 0.01 ) then
3602  qs = wqs2(wet_bulb, den, dqdt)
3603  tp = (qs-q)/(1.+lcp*dqdt)*lcp
3604  wet_bulb = wet_bulb - tp
3605  endif
3606 
3607  end function wet_bulb
3608  real function iqs1(ta, den)
3609 ! water-ice phase; universal dry/moist formular using air density
3610 ! Input "den" can be either dry or moist air density
3611  real, intent(in):: ta, den
3612 ! local:
3613  real es, ap1
3614  real, parameter:: tmin=table_ice - 160.
3615  integer it
3616 
3617  ap1 = 10.*dim(ta, tmin) + 1.
3618  ap1 = min(2621., ap1)
3619  it = ap1
3620  es = table2(it) + (ap1-it)*des2(it)
3621  iqs1 = es / (rvgas*ta*den)
3622 
3623  end function iqs1
3624 
3625  real function iqs2(ta, den, dqdt)
3626 ! water-ice phase; universal dry/moist formular using air density
3627 ! Input "den" can be either dry or moist air density
3628  real, intent(in):: ta, den
3629  real, intent(out):: dqdt
3630 ! local:
3631  real es, ap1
3632  real, parameter:: tmin=table_ice - 160.
3633  integer it
3634 
3635  ap1 = 10.*dim(ta, tmin) + 1.
3636  ap1 = min(2621., ap1)
3637  it = ap1
3638  es = table2(it) + (ap1-it)*des2(it)
3639  iqs2 = es / (rvgas*ta*den)
3640  it = ap1 - 0.5
3641  dqdt = 10.*(des2(it) + (ap1-it)*(des2(it+1)-des2(it))) / (rvgas*ta*den)
3642 
3643  end function iqs2
3644 
3645  real function qs1d_moist(ta, qv, pa, dqdt)
3646 ! 2-phase tabel
3647  real, intent(in):: ta, pa, qv
3648  real, intent(out):: dqdt
3649 ! local:
3650  real :: es, ap1
3651  real, parameter:: tmin=table_ice - 160.
3652  real, parameter:: eps10 = 10.*eps
3653  integer it
3654 
3655  ap1 = 10.*dim(ta, tmin) + 1.
3656  ap1 = min(2621., ap1)
3657  it = ap1
3658  es = table2(it) + (ap1-it)*des2(it)
3659  qs1d_moist = eps*es*(1.+zvir*qv)/pa
3660  it = ap1 - 0.5
3661  dqdt = eps10*(des2(it) + (ap1-it)*(des2(it+1)-des2(it)))*(1.+zvir*qv)/pa
3662 
3663  end function qs1d_moist
3664 
3665  real function wqsat2_moist(ta, qv, pa, dqdt)
3666 ! Pure water phase
3667  real, intent(in):: ta, pa, qv
3668  real, intent(out):: dqdt
3669 ! local:
3670  real es, ap1
3671  real, parameter:: tmin=table_ice - 160.
3672  real, parameter:: eps10 = 10.*eps
3673  integer it
3674 
3675  ap1 = 10.*dim(ta, tmin) + 1.
3676  ap1 = min(2621., ap1)
3677  it = ap1
3678  es = tablew(it) + (ap1-it)*desw(it)
3679  wqsat2_moist = eps*es*(1.+zvir*qv)/pa
3680  dqdt = eps10*(desw(it) + (ap1-it)*(desw(it+1)-desw(it)))*(1.+zvir*qv)/pa
3681 
3682  end function wqsat2_moist
3683 
3684  real function wqsat_moist(ta, qv, pa)
3685 ! Pure water phase
3686  real, intent(in):: ta, pa, qv
3687 ! local:
3688  real :: es, ap1
3689  real, parameter:: tmin=table_ice - 160.
3690  integer it
3691 
3692  ap1 = 10.*dim(ta, tmin) + 1.
3693  ap1 = min(2621., ap1)
3694  it = ap1
3695  es = tablew(it) + (ap1-it)*desw(it)
3696  wqsat_moist = eps*es*(1.+zvir*qv)/pa
3697 
3698  end function wqsat_moist
3699 
3700  real function qs1d_m(ta, qv, pa)
3701 ! 2-phase tabel
3702  real, intent(in):: ta, pa, qv
3703 ! local:
3704  real es, ap1
3705  real, parameter:: tmin=table_ice - 160.
3706  real, parameter:: eps10 = 10.*eps
3707  integer it
3708 
3709  ap1 = 10.*dim(ta, tmin) + 1.
3710  ap1 = min(2621., ap1)
3711  it = ap1
3712  es = table2(it) + (ap1-it)*des2(it)
3713  qs1d_m = eps*es*(1.+zvir*qv)/pa
3714 
3715  end function qs1d_m
3716 
3717  real function d_sat(ta)
3718 ! Computes the difference in saturation vapor *density* between water and ice
3719  real, intent(in):: ta
3720  real, parameter:: tmin=table_ice - 160.
3721  real es_w, es_i, ap1
3722  integer it
3723 
3724  ap1 = 10.*dim(ta, tmin) + 1.
3725  ap1 = min(2621., ap1)
3726  it = ap1
3727 ! over Water:
3728  es_w = tablew(it) + (ap1-it)*desw(it)
3729 ! over Ice:
3730  es_i = table2(it) + (ap1-it)*des2(it)
3731  d_sat = dim(es_w, es_i)/(rvgas*ta) ! Take positive difference
3732 
3733  end function d_sat
3734 
3735 
3736  real function esw_table(ta)
3737 ! pure water phase table
3738  real, intent(in):: ta
3739  real, parameter:: tmin=table_ice - 160.
3740  real ap1
3741  integer it
3742  ap1 = 10.*dim(ta, tmin) + 1.
3743  ap1 = min(2621., ap1)
3744  it = ap1
3745  esw_table = tablew(it) + (ap1-it)*desw(it)
3746  end function esw_table
3747 
3748 
3749  real function es2_table(ta)
3750 ! two-phase table
3751  real, intent(in):: ta
3752  real, parameter:: tmin=table_ice - 160.
3753  real ap1
3754  integer it
3755  ap1 = 10.*dim(ta, tmin) + 1.
3756  ap1 = min(2621., ap1)
3757  it = ap1
3758  es2_table = table2(it) + (ap1-it)*des2(it)
3759  end function es2_table
3760 
3761 
3762  subroutine esw_table1d(ta, es, n)
3763  integer, intent(in):: n
3764 ! For waterphase only
3765  real, intent(in):: ta(n)
3766  real, intent(out):: es(n)
3767  real, parameter:: tmin=table_ice - 160.
3768  real ap1
3769  integer i, it
3770 
3771  do i=1, n
3772  ap1 = 10.*dim(ta(i), tmin) + 1.
3773  ap1 = min(2621., ap1)
3774  it = ap1
3775  es(i) = tablew(it) + (ap1-it)*desw(it)
3776  enddo
3777  end subroutine esw_table1d
3778 
3779 
3780 
3781  subroutine es2_table1d(ta, es, n)
3782  integer, intent(in):: n
3783 ! two-phase table with -2C as the transition point for ice-water phase
3784 ! For sea ice model
3785  real, intent(in):: ta(n)
3786  real, intent(out):: es(n)
3787  real, parameter:: tmin=table_ice - 160.
3788  real ap1
3789  integer i, it
3790 
3791  do i=1, n
3792  ap1 = 10.*dim(ta(i), tmin) + 1.
3793  ap1 = min(2621., ap1)
3794  it = ap1
3795  es(i) = table2(it) + (ap1-it)*des2(it)
3796  enddo
3797  end subroutine es2_table1d
3798 
3799 
3800  subroutine es3_table1d(ta, es, n)
3801  integer, intent(in):: n
3802 ! two-phase table with -2C as the transition point for ice-water phase
3803  real, intent(in):: ta(n)
3804  real, intent(out):: es(n)
3805  real, parameter:: tmin=table_ice - 160.
3806  real ap1
3807  integer i, it
3808 
3809  do i=1, n
3810  ap1 = 10.*dim(ta(i), tmin) + 1.
3811  ap1 = min(2621., ap1)
3812  it = ap1
3813  es(i) = table3(it) + (ap1-it)*des3(it)
3814  enddo
3815  end subroutine es3_table1d
3816 
3817 
3818 
3819  subroutine qs_tablew(n)
3820 ! Over water
3821  integer, intent(in):: n
3822  real :: delt=0.1
3823  real esbasw, tbasw, esbasi, tbasi, tmin, tem, aa, b, c, d, e
3824  integer i
3825 
3826 ! constants
3827  esbasw = 1013246.0
3828  tbasw = 373.16
3829  esbasi = 6107.1
3830  tbasi = 273.16
3831  tmin = tbasi - 160.
3832 
3833  do i=1,n
3834  tem = tmin+delt*real(i-1)
3835 ! compute es over water
3836 #ifdef SMITHSONIAN_TABLE
3837 ! see smithsonian meteorological tables page 350.
3838  aa = -7.90298*(tbasw/tem-1.)
3839  b = 5.02808*alog10(tbasw/tem)
3840  c = -1.3816e-07*(10**((1.-tem/tbasw)*11.344)-1.)
3841  d = 8.1328e-03*(10**((tbasw/tem-1.)*(-3.49149))-1.)
3842  e = alog10(esbasw)
3843  tablew(i) = 0.1 * 10**(aa+b+c+d+e)
3844 #else
3845  tablew(i) = e00*exp((dc_vap*log(tem/t_ice)+lv0*(tem-t_ice)/(tem*t_ice))/rvgas)
3846 #endif
3847  enddo
3848 
3849  end subroutine qs_tablew
3850 
3851 
3852  subroutine qs_table2(n)
3853 ! 2-phase table
3854  integer, intent(in):: n
3855  real :: delt=0.1
3856  real esbasw, tbasw, esbasi, tbasi, tmin, tem, aa, b, c, d, e
3857  integer :: i0, i1
3858  real :: tem0, tem1
3859  integer i
3860 
3861 ! constants
3862  esbasw = 1013246.0
3863  tbasw = 373.16
3864  esbasi = 6107.1
3865  tbasi = 273.16
3866  tmin = tbasi - 160.
3867 
3868  do i=1,n
3869  tem = tmin+delt*real(i-1)
3870  if ( i<= 1600 ) then
3871 ! compute es over ice between -160c and 0 c.
3872 #ifdef SMITHSONIAN_TABLE
3873 ! see smithsonian meteorological tables page 350.
3874  aa = -9.09718 *(tbasi/tem-1.)
3875  b = -3.56654 *alog10(tbasi/tem)
3876  c = 0.876793*(1.-tem/tbasi)
3877  e = alog10(esbasi)
3878  table2(i) = 0.1 * 10**(aa+b+c+e)
3879 #else
3880  table2(i) = e00*exp((d2ice*log(tem/t_ice)+li2*(tem-t_ice)/(tem*t_ice))/rvgas)
3881 #endif
3882  else
3883 ! compute es over water between 0c and 102c.
3884 #ifdef SMITHSONIAN_TABLE
3885 ! see smithsonian meteorological tables page 350.
3886  aa = -7.90298*(tbasw/tem-1.)
3887  b = 5.02808*alog10(tbasw/tem)
3888  c = -1.3816e-07*(10**((1.-tem/tbasw)*11.344)-1.)
3889  d = 8.1328e-03*(10**((tbasw/tem-1.)*(-3.49149))-1.)
3890  e = alog10(esbasw)
3891  table2(i) = 0.1 * 10**(aa+b+c+d+e)
3892 #else
3893  table2(i) = e00*exp((dc_vap*log(tem/t_ice)+lv0*(tem-t_ice)/(tem*t_ice))/rvgas)
3894 #endif
3895  endif
3896  enddo
3897 
3898 !----------
3899 ! smoother
3900 !----------
3901  i0 = 1600; i1 = 1601
3902  tem0 = 0.25*(table2(i0-1) + 2.*table(i0) + table2(i0+1))
3903  tem1 = 0.25*(table2(i1-1) + 2.*table(i1) + table2(i1+1))
3904  table2(i0) = tem0
3905  table2(i1) = tem1
3906 
3907  end subroutine qs_table2
3908 
3909 
3910 
3911  subroutine qs_table3(n)
3912 ! 2-phase table with "-2 C" as the transition point
3913  integer, intent(in):: n
3914  real :: delt=0.1
3915  real esbasw, tbasw, esbasi, tbasi, tmin, tem, aa, b, c, d, e
3916  integer :: i0, i1
3917  real :: tem0, tem1
3918  integer i
3919 
3920 ! constants
3921  esbasw = 1013246.0
3922  tbasw = 373.16
3923  esbasi = 6107.1
3924  tbasi = 273.16
3925  tmin = tbasi - 160.
3926 
3927  do i=1,n
3928  tem = tmin+delt*real(i-1)
3929 ! if ( i<= 1600 ) then
3930  if ( i<= 1580 ) then ! to -2 C
3931 ! compute es over ice between -160c and 0 c.
3932 ! see smithsonian meteorological tables page 350.
3933  aa = -9.09718 *(tbasi/tem-1.)
3934  b = -3.56654 *alog10(tbasi/tem)
3935  c = 0.876793*(1.-tem/tbasi)
3936  e = alog10(esbasi)
3937  table3(i) = 0.1 * 10**(aa+b+c+e)
3938  else
3939 ! compute es over water between -2c and 102c.
3940 ! see smithsonian meteorological tables page 350.
3941  aa = -7.90298*(tbasw/tem-1.)
3942  b = 5.02808*alog10(tbasw/tem)
3943  c = -1.3816e-07*(10**((1.-tem/tbasw)*11.344)-1.)
3944  d = 8.1328e-03*(10**((tbasw/tem-1.)*(-3.49149))-1.)
3945  e = alog10(esbasw)
3946  table3(i) = 0.1 * 10**(aa+b+c+d+e)
3947  endif
3948  enddo
3949 
3950 !----------
3951 ! smoother
3952 !----------
3953  i0 = 1580
3954  tem0 = 0.25*(table3(i0-1) + 2.*table(i0) + table3(i0+1))
3955  i1 = 1581
3956  tem1 = 0.25*(table3(i1-1) + 2.*table(i1) + table3(i1+1))
3957  table3(i0) = tem0
3958  table3(i1) = tem1
3959 
3960  end subroutine qs_table3
3961 
3962 
3963  real function qs_blend(t, p, q)
3964 ! Note: this routine is based on "moist" mixing ratio
3965 ! Blended mixed phase table
3966  real, intent(in):: t, p, q
3967  real es, ap1
3968  real, parameter:: tmin=table_ice - 160.
3969  integer it
3970 
3971  ap1 = 10.*dim(t, tmin) + 1.
3972  ap1 = min(2621., ap1)
3973  it = ap1
3974  es = table(it) + (ap1-it)*des(it)
3975  qs_blend = eps*es*(1.+zvir*q)/p
3976 
3977  end function qs_blend
3978 
3979  subroutine qs_table(n)
3980  integer, intent(in):: n
3981  real esupc(200)
3982  real :: delt=0.1
3983  real esbasw, tbasw, esbasi, tbasi, tmin, tem, aa, b, c, d, e, esh20
3984  real wice, wh2o
3985  integer i
3986 
3987 ! constants
3988  esbasw = 1013246.0
3989  tbasw = 373.16
3990  esbasi = 6107.1
3991  tbasi = 273.16
3992 
3993 ! compute es over ice between -160c and 0 c.
3994  tmin = tbasi - 160.
3995 ! see smithsonian meteorological tables page 350.
3996  do i=1,1600
3997  tem = tmin+delt*real(i-1)
3998 #ifdef SMITHSONIAN_TABLE
3999  aa = -9.09718 *(tbasi/tem-1.)
4000  b = -3.56654 *alog10(tbasi/tem)
4001  c = 0.876793*(1.-tem/tbasi)
4002  e = alog10(esbasi)
4003  table(i)= 0.1 * 10**(aa+b+c+e)
4004 #else
4005  table(i) = e00*exp((d2ice*log(tem/t_ice)+li2*(tem-t_ice)/(tem*t_ice))/rvgas)
4006 #endif
4007  enddo
4008 
4009 ! compute es over water between -20c and 102c.
4010 ! see smithsonian meteorological tables page 350.
4011  do i=1,1221
4012  tem = 253.16+delt*real(i-1)
4013 #ifdef SMITHSONIAN_TABLE
4014  aa = -7.90298*(tbasw/tem-1.)
4015  b = 5.02808*alog10(tbasw/tem)
4016  c = -1.3816e-07*(10**((1.-tem/tbasw)*11.344)-1.)
4017  d = 8.1328e-03*(10**((tbasw/tem-1.)*(-3.49149))-1.)
4018  e = alog10(esbasw)
4019  esh20 = 0.1 * 10**(aa+b+c+d+e)
4020 #else
4021  esh20 = e00*exp((dc_vap*log(tem/t_ice)+lv0*(tem-t_ice)/(tem*t_ice))/rvgas)
4022 #endif
4023  if (i <= 200) then
4024  esupc(i) = esh20
4025  else
4026  table(i+1400) = esh20
4027  endif
4028  enddo
4029 
4030 ! derive blended es over ice and supercooled water between -20c and 0c
4031  do i=1,200
4032  tem = 253.16+delt*real(i-1)
4033  wice = 0.05*(273.16-tem)
4034  wh2o = 0.05*(tem-253.16)
4035  table(i+1400) = wice*table(i+1400)+wh2o*esupc(i)
4036  enddo
4037 
4038  end subroutine qs_table
4039 
4040 
4041  subroutine qsmith(im, km, ks, t, p, q, qs, dqdt)
4042 ! input t in deg k; p (pa) : moist pressure
4043  integer, intent(in):: im, km, ks
4044  real, intent(in),dimension(im,km):: t, p, q
4045  real, intent(out),dimension(im,km):: qs
4046  real, intent(out), optional:: dqdt(im,km)
4047 ! local:
4048  real, parameter:: eps10 = 10.*eps
4049  real es(im,km)
4050  real ap1
4051  real, parameter:: tmin=table_ice - 160.
4052  integer i, k, it
4053 
4054  if( .not. tables_are_initialized ) then
4055  call qsmith_init
4056  endif
4057 
4058  do k=ks,km
4059  do i=1,im
4060  ap1 = 10.*dim(t(i,k), tmin) + 1.
4061  ap1 = min(2621., ap1)
4062  it = ap1
4063  es(i,k) = table(it) + (ap1-it)*des(it)
4064  qs(i,k) = eps*es(i,k)*(1.+zvir*q(i,k))/p(i,k)
4065  enddo
4066  enddo
4067 
4068  if ( present(dqdt) ) then
4069  do k=ks,km
4070  do i=1,im
4071  ap1 = 10.*dim(t(i,k), tmin) + 1.
4072  ap1 = min(2621., ap1) - 0.5
4073  it = ap1
4074  dqdt(i,k) = eps10*(des(it)+(ap1-it)*(des(it+1)-des(it)))*(1.+zvir*q(i,k))/p(i,k)
4075  enddo
4076  enddo
4077  endif
4078 
4079  end subroutine qsmith
4080 
4081 
4082  subroutine neg_adj(ktop, kbot, p1, pt, dp, qv, ql, qr, qi, qs, qg)
4083 ! 1d version:
4084 ! this is designed for 6-class micro-physics schemes
4085  integer, intent(in):: ktop, kbot
4086  real, intent(in):: dp(ktop:kbot), p1(ktop:kbot)
4087  real, intent(inout), dimension(ktop:kbot):: &
4088  pt, qv, ql, qr, qi, qs, qg
4089 ! local:
4090  real lcpk(ktop:kbot), icpk(ktop:kbot)
4091  real dq, tmp1, cvm
4092  integer k
4093 
4094  do k=ktop,kbot
4095  cvm = c_air + qv(k)*c_vap + (qr(k)+ql(k))*c_liq + (qi(k)+qs(k)+qg(k))*c_ice
4096  lcpk(k) = (lv00+dc_vap*pt(k)) / cvm
4097  icpk(k) = (li00+dc_ice*pt(k)) / cvm
4098  enddo
4099 
4100  do k=ktop, kbot
4101 !-----------
4102 ! ice-phase:
4103 !-----------
4104 ! if ice<0 borrow from snow
4105  if( qi(k) < 0. ) then
4106  qs(k) = qs(k) + qi(k)
4107  qi(k) = 0.
4108  endif
4109 ! if snow<0 borrow from graupel
4110  if( qs(k) < 0. ) then
4111  qg(k) = qg(k) + qs(k)
4112  qs(k) = 0.
4113  endif
4114 ! if graupel < 0 then borrow from rain
4115  if ( qg(k) < 0. ) then
4116  qr(k) = qr(k) + qg(k)
4117  pt(k) = pt(k) - qg(k)*icpk(k) ! heating
4118  qg(k) = 0.
4119  endif
4120 
4121 ! liquid phase:
4122 ! fix negative rain by borrowing from cloud water
4123  if ( qr(k) < 0. ) then
4124  ql(k) = ql(k) + qr(k)
4125  qr(k) = 0.
4126  endif
4127 ! fix negative cloud water with vapor
4128  if ( ql(k) < 0. ) then
4129  qv(k) = qv(k) + ql(k)
4130  pt(k) = pt(k) - ql(k)*lcpk(k)
4131  ql(k) = 0.
4132  endif
4133  enddo
4134 
4135 !-----------------------------------
4136 ! fix water vapor; borrow from below
4137 !-----------------------------------
4138  do k=ktop,kbot-1
4139  if( qv(k) < 0. ) then
4140  qv(k+1) = qv(k+1) + qv(k)*dp(k)/dp(k+1)
4141  qv(k ) = 0.
4142  endif
4143  enddo
4144 
4145 ! bottom layer; borrow from above
4146  if( qv(kbot) < 0. .and. qv(kbot-1)>0.) then
4147  dq = min(-qv(kbot)*dp(kbot), qv(kbot-1)*dp(kbot-1))
4148  qv(kbot-1) = qv(kbot-1) - dq/dp(kbot-1)
4149  qv(kbot ) = qv(kbot ) + dq/dp(kbot )
4150  endif
4151 ! if qv is still < 0
4152 
4153  end subroutine neg_adj
4154 
4155 
4156  subroutine sg_conv(is, ie, js, je, isd, ied, jsd, jed, &
4157  km, nq, dt, tau, &
4158  delp, phalf, pm, zfull, zhalf, ta, qa, ua, va, w, &
4159  u_dt, v_dt, t_dt, q_dt, nqv, nql, nqi, nqr, nqs, nqg, &
4160  hydrostatic, phys_hydrostatic)
4161 ! Non-precipitating sub-grid scale convective adjustment-mixing
4162 !-------------------------------------------
4163  logical, intent(in):: hydrostatic, phys_hydrostatic
4164  integer, intent(in):: is, ie, js, je, km, nq
4165  integer, intent(in):: isd, ied, jsd, jed
4166  integer, intent(in):: tau ! Relaxation time scale
4167  integer, intent(in):: nqv, nql, nqi ! vapor, liquid, ice
4168  integer, intent(in):: nqr, nqs, nqg !
4169  real, intent(in):: dt ! model time step
4170  real, intent(in):: phalf(is:ie,js:je,km+1)
4171  real, intent(in):: pm(is:ie,js:je,km)
4172  real, intent(in):: zfull(is:ie,js:je,km)
4173  real, intent(in):: zhalf(is:ie,js:je,km+1)
4174  real, intent(in):: delp(isd:ied,jsd:jed,km) ! Delta p at each model level
4175 ! Output:
4176  real, intent(inout), dimension(is:ie,js:je,km):: ta, ua, va
4177  real, intent(inout):: qa(is:ie,js:je,km,nq) ! Specific humidity & tracers
4178  real, intent(inout):: w(isd:ied,jsd:jed,km)
4179  real, intent(inout):: u_dt(isd:ied,jsd:jed,km) ! updated u-wind field
4180  real, intent(inout):: v_dt(isd:ied,jsd:jed,km) ! v-wind
4181  real, intent(inout):: t_dt(is:ie,js:je,km) ! temperature
4182  real, intent(inout):: q_dt(is:ie,js:je,km,nq) !
4183 !---------------------------Local variables-----------------------------
4184  real, dimension(is:ie,km):: tvm, u0, v0, w0, t0, gz, hd, pkz, qcon
4185  real, dimension(is:ie,km+1):: pk, peln
4186  real:: q0(is:ie,km,nq)
4187  real:: gzh(is:ie)
4188  real:: pbot, ri, pt1, pt2, lf, ratio
4189  real:: rdt, dh, dh0, dhs, dq, tv, h0, mc, mx, fra, rk, rz, rcp
4190  real:: qsw
4191  integer:: mcond
4192  integer kcond
4193  integer i, j, k, n, m, iq, kk
4194  real, parameter:: ustar2 = 1.e-6
4195  real, parameter:: dh_min = 1.e-4
4196 
4197  if ( nqv /= 1 ) then
4198  call error_mesg ('sg_conv', 'Tracer indexing error', fatal)
4199  endif
4200 
4201  rz = rvgas - rdgas ! rz = zvir * rdgas
4202  rk = cp_air/rdgas + 1.
4203  rcp = 1./cp_air
4204 
4205  m = 3
4206  rdt = 1. / dt
4207  fra = dt/real(tau)
4208 
4209 !------------
4210 ! Compute gz: center
4211 !------------
4212  mcond = 1
4213  do 1000 j=js,je ! this main loop can be OpneMPed in j
4214 
4215  do k=mcond,km+1
4216  do i=is,ie
4217  peln(i,k) = log(phalf(i,j,k))
4218  pk(i,k) = exp(kappa*peln(i,k))
4219  enddo
4220  enddo
4221 
4222  do k=mcond,km
4223  do i=is,ie
4224  u0(i,k) = ua(i,j,k)
4225  v0(i,k) = va(i,j,k)
4226  t0(i,k) = ta(i,j,k)
4227  pkz(i,k) = (pk(i,k+1)-pk(i,k))/(kappa*(peln(i,k+1)-peln(i,k)))
4228  enddo
4229  enddo
4230 
4231  if ( .not.hydrostatic ) then
4232  do k=mcond,km
4233  do i=is,ie
4234  w0(i,k) = w(i,j,k)
4235  enddo
4236  enddo
4237  endif
4238 
4239  do iq=1,nq
4240  do k=mcond,km
4241  do i=is,ie
4242  q0(i,k,iq) = qa(i,j,k,iq)
4243  enddo
4244  enddo
4245  enddo
4246 
4247 
4248 !-----------------
4249 ! K-H instability:
4250 !-----------------
4251  kcond = mcond
4252 
4253  do n=1,m
4254  ratio = real(n)/real(m)
4255 
4256  if( phys_hydrostatic ) then
4257  do i=is,ie
4258  gzh(i) = 0.
4259  enddo
4260  do k=km, mcond,-1
4261  do i=is,ie
4262  tvm(i,k) = t0(i,k)*(1.+zvir*q0(i,k,nqv))
4263  tv = rdgas*tvm(i,k)
4264  gz(i,k) = gzh(i) + tv*(1.-phalf(i,j,k)/pm(i,j,k))
4265  hd(i,k) = cp_air*tvm(i,k)+gz(i,k)+0.5*(u0(i,k)**2+v0(i,k)**2)
4266  gzh(i) = gzh(i) + tv*(peln(i,k+1)-peln(i,k))
4267  enddo
4268  enddo
4269  do i=is,ie
4270  gzh(i) = 0.
4271  enddo
4272  else
4273  do k=mcond,km
4274  do i=is,ie
4275  gz(i,k) = grav*zfull(i,j,k)
4276  hd(i,k) = cp_air*t0(i,k)+gz(i,k)+0.5*(u0(i,k)**2+v0(i,k)**2+w0(i,k)**2)
4277  enddo
4278  enddo
4279  endif
4280 
4281 ! PBL: ---------------------------------------
4282 #ifdef USE_PBL
4283  do 123 i=is,ie
4284  do k=km-1,km/2,-1
4285 ! Richardson number = g*delz * theta / ( del_theta * (del_u**2 + del_v**2) )
4286  pt1 = t0(i,k)/pkz(i,k)*(1.+zvir*q0(i,k,nqv)-q0(i,k,nql)-q0(i,k,nqi))
4287  pt2 = t0(i,km)/pkz(i,km)*(1.+zvir*q0(i,km,nqv)-q0(i,km,nql)-q0(i,km,nqi))
4288  ri = (gz(i,k)-gz(i,km))*(pt1-pt2)/( 0.5*(pt1+pt2)* &
4289  ((u0(i,k)-u0(i,km))**2+(v0(i,k)-v0(i,km))**2+ustar2) )
4290  if ( ri < 1. ) then
4291 ! Mix the lowest two layers completely
4292  mc = delp(i,j,km-1)*delp(i,j,km)/(delp(i,j,km-1)+delp(i,j,km))
4293  do iq=1,nq
4294  h0 = mc*(q0(i,km,iq)-q0(i,km-1,iq))
4295  q0(i,km-1,iq) = q0(i,km-1,iq) + h0/delp(i,j,km-1)
4296  q0(i,km ,iq) = q0(i,km ,iq) - h0/delp(i,j,km )
4297  enddo
4298 ! u:
4299  h0 = mc*(u0(i,km)-u0(i,km-1))
4300  u0(i,km-1) = u0(i,km-1) + h0/delp(i,j,km-1)
4301  u0(i,km ) = u0(i,km ) - h0/delp(i,j,km )
4302 ! v:
4303  h0 = mc*(v0(i,km)-v0(i,km-1))
4304  v0(i,km-1) = v0(i,km-1) + h0/delp(i,j,km-1)
4305  v0(i,km ) = v0(i,km ) - h0/delp(i,j,km )
4306 ! h:
4307  h0 = mc*(hd(i,km)-hd(i,km-1))
4308  hd(i,km-1) = hd(i,km-1) + h0/delp(i,j,km-1)
4309  hd(i,km ) = hd(i,km ) - h0/delp(i,j,km )
4310  if ( .not.hydrostatic ) then
4311  h0 = mc*(w0(i,km)-w0(i,km-1))
4312  w0(i,km-1) = w0(i,km-1) + h0/delp(i,j,km-1)
4313  w0(i,km ) = w0(i,km ) - h0/delp(i,j,km )
4314  endif
4315  goto 123
4316  endif
4317  enddo
4318 123 continue
4319 #endif
4320 ! PBL: ---------------------------------------
4321 
4322  do k=km,kcond+1,-1
4323  do i=is,ie
4324  qcon(i,k-1) = q0(i,k-1,nql) + q0(i,k-1,nqi) + q0(i,k-1,nqs) + q0(i,k-1,nqr) + q0(i,k-1,nqg)
4325  qcon(i,k) = q0(i,k,nql) + q0(i,k,nqi) + q0(i,k,nqs) + q0(i,k,nqr) + q0(i,k,nqg)
4326 ! Richardson number = g*delz * theta / ( del_theta * (del_u**2 + del_v**2) )
4327  pt1 = t0(i,k-1)/pkz(i,k-1)*(1.+zvir*q0(i,k-1,nqv)-qcon(i,k-1))
4328  pt2 = t0(i,k )/pkz(i,k )*(1.+zvir*q0(i,k ,nqv)-qcon(i,k))
4329  ri = (gz(i,k-1)-gz(i,k))*(pt1-pt2)/( 0.5*(pt1+pt2)* &
4330  ((u0(i,k-1)-u0(i,k))**2+(v0(i,k-1)-v0(i,k))**2+ustar2) )
4331 ! Dry convective mixing for K-H instability & CAT (Clear Air Turbulence):
4332  if ( ri < 1. ) then
4333 ! Compute equivalent mass flux: mc
4334  mc = ratio * (1.-max(0.0, ri)) ** 2
4335  mc = mc*delp(i,j,k-1)*delp(i,j,k)/(delp(i,j,k-1)+delp(i,j,k))
4336  do iq=1,nq
4337  h0 = mc*(q0(i,k,iq)-q0(i,k-1,iq))
4338  q0(i,k-1,iq) = q0(i,k-1,iq) + h0/delp(i,j,k-1)
4339  q0(i,k ,iq) = q0(i,k ,iq) - h0/delp(i,j,k )
4340  enddo
4341 ! u:
4342  h0 = mc*(u0(i,k)-u0(i,k-1))
4343  u0(i,k-1) = u0(i,k-1) + h0/delp(i,j,k-1)
4344  u0(i,k ) = u0(i,k ) - h0/delp(i,j,k )
4345 ! v:
4346  h0 = mc*(v0(i,k)-v0(i,k-1))
4347  v0(i,k-1) = v0(i,k-1) + h0/delp(i,j,k-1)
4348  v0(i,k ) = v0(i,k ) - h0/delp(i,j,k )
4349 ! h:
4350  h0 = mc*(hd(i,k)-hd(i,k-1))
4351  hd(i,k-1) = hd(i,k-1) + h0/delp(i,j,k-1)
4352  hd(i,k ) = hd(i,k ) - h0/delp(i,j,k )
4353  if ( .not.hydrostatic ) then
4354  h0 = mc*(w0(i,k)-w0(i,k-1))
4355  w0(i,k-1) = w0(i,k-1) + h0/delp(i,j,k-1)
4356  w0(i,k ) = w0(i,k ) - h0/delp(i,j,k )
4357  endif
4358  endif
4359  enddo
4360 !--------------
4361 ! Retrive Temp:
4362 !--------------
4363  if ( phys_hydrostatic ) then
4364  kk = k
4365  do i=is,ie
4366  t0(i,kk) = (hd(i,kk)-gzh(i)-0.5*(u0(i,kk)**2+v0(i,kk)**2)) &
4367  / ( rk - phalf(i,j,kk)/pm(i,j,kk) )
4368  gzh(i) = gzh(i) + t0(i,kk)*(peln(i,kk+1)-peln(i,kk))
4369  t0(i,kk) = t0(i,kk) / ( rdgas + rz*q0(i,kk,nqv) )
4370  enddo
4371  kk = k-1
4372  do i=is,ie
4373  t0(i,kk) = (hd(i,kk)-gzh(i)-0.5*(u0(i,kk)**2+v0(i,kk)**2)) &
4374  / ((rk-phalf(i,j,kk)/pm(i,j,kk))*(rdgas+rz*q0(i,kk,nqv)))
4375  enddo
4376  else
4377 ! Non-hydrostatic under constant volume heating/cooling
4378  do kk=k-1,k
4379  do i=is,ie
4380  t0(i,kk) = rcp*(hd(i,kk)-gz(i,kk)-0.5*(u0(i,kk)**2+v0(i,kk)**2+w0(i,kk)**2))
4381  enddo
4382  enddo
4383  endif
4384  enddo
4385  enddo ! n-loop
4386 
4387 
4388 !-------------------------
4389 ! Moist adjustment/mixing:
4390 !-------------------------
4391  m = 4
4392 
4393  if( km>k_moist+1 ) then
4394  do n=1,m
4395 
4396  ratio = real(n)/real(m)
4397 
4398  if ( phys_hydrostatic ) then
4399  do i=is,ie
4400  gzh(i) = 0.
4401  enddo
4402  endif
4403 
4404 ! do k=km,max(kcond,k_moist)+1,-1
4405  do k=km, kcond+1, -1
4406  do i=is,ie
4407  if ( phalf(i,j,k) > p_crt ) then
4408  qsw = wqsat_moist(t0(i,k-1), q0(i,k-1,nqv), pm(i,j,k-1))
4409 
4410  dh0 = hd(i,k) - hd(i,k-1) - lati*(q0(i,k,nqi)-q0(i,k-1,nqi))
4411  dhs = dh0 + latv*(q0(i,k,nqv)-qsw )
4412  dh = dh0 + latv*(q0(i,k,nqv)-q0(i,k-1,nqv))
4413 
4414  if ( dhs>0.0 .and. dh>dh_min .and. q0(i,k,nqv)>q0(i,k-1,nqv) ) then
4415  mc = ratio*min(1.0, dhs/dh)* &
4416  delp(i,j,k-1)*delp(i,j,k)/(delp(i,j,k-1)+delp(i,j,k))
4417  h0 = mc*(hd(i,k) - hd(i,k-1))
4418  hd(i,k-1) = hd(i,k-1) + h0/delp(i,j,k-1)
4419  hd(i,k ) = hd(i,k ) - h0/delp(i,j,k )
4420 ! Perform local mixing of all advected tracers:
4421  do iq=1,nq
4422  h0 = mc*(q0(i,k,iq)-q0(i,k-1,iq))
4423  q0(i,k-1,iq) = q0(i,k-1,iq) + h0/delp(i,j,k-1)
4424  q0(i,k ,iq) = q0(i,k ,iq) - h0/delp(i,j,k )
4425  enddo
4426 ! u:
4427  h0 = mc*(u0(i,k)-u0(i,k-1))
4428  u0(i,k-1) = u0(i,k-1) + h0/delp(i,j,k-1)
4429  u0(i,k ) = u0(i,k ) - h0/delp(i,j,k )
4430 ! v:
4431  h0 = mc*(v0(i,k)-v0(i,k-1))
4432  v0(i,k-1) = v0(i,k-1) + h0/delp(i,j,k-1)
4433  v0(i,k ) = v0(i,k ) - h0/delp(i,j,k )
4434 ! *** Non-hydrostatic:
4435  if ( .not.hydrostatic ) then
4436  h0 = mc*(w0(i,k)-w0(i,k-1))
4437  w0(i,k-1) = w0(i,k-1) + h0/delp(i,j,k-1)
4438  w0(i,k ) = w0(i,k ) - h0/delp(i,j,k )
4439  endif
4440  endif ! dh check
4441  endif ! p_crt check
4442  enddo
4443 !--------------
4444 ! Retrive Temp:
4445 !--------------
4446  if ( phys_hydrostatic ) then
4447  kk = k
4448  do i=is,ie
4449  t0(i,kk) = (hd(i,kk)-gzh(i)-0.5*(u0(i,kk)**2+v0(i,kk)**2)) &
4450  / ( rk - phalf(i,j,kk)/pm(i,j,kk) )
4451  gzh(i) = gzh(i) + t0(i,kk)*(peln(i,kk+1)-peln(i,kk))
4452  t0(i,kk) = t0(i,kk) / ( rdgas + rz*q0(i,kk,nqv) )
4453  enddo
4454  kk = k-1
4455  do i=is,ie
4456  t0(i,kk) = (hd(i,kk)-gzh(i)-0.5*(u0(i,kk)**2+v0(i,kk)**2)) &
4457  / ((rk-phalf(i,j,kk)/pm(i,j,kk))*(rdgas+rz*q0(i,kk,nqv)))
4458  enddo
4459  else
4460 ! Non-hydrostatic under constant volume heating/cooling
4461  do kk=k-1,k
4462  do i=is,ie
4463  t0(i,kk) = rcp*(hd(i,kk)-gz(i,kk)-0.5*(u0(i,kk)**2+v0(i,kk)**2+w0(i,kk)**2))
4464  enddo
4465  enddo
4466  endif
4467  enddo
4468  enddo ! n-loop
4469  endif ! k_moist check
4470 
4471  if ( fra < 1. ) then
4472  do k=mcond,km
4473  do i=is,ie
4474  t0(i,k) = ta(i,j,k) + (t0(i,k) - ta(i,j,k))*fra
4475  u0(i,k) = ua(i,j,k) + (u0(i,k) - ua(i,j,k))*fra
4476  v0(i,k) = va(i,j,k) + (v0(i,k) - va(i,j,k))*fra
4477  enddo
4478  enddo
4479 
4480  if ( .not.hydrostatic ) then
4481  do k=mcond,km
4482  do i=is,ie
4483  w0(i,k) = w(i,j,k) + (w0(i,k) - w(i,j,k))*fra
4484  enddo
4485  enddo
4486  endif
4487 
4488  do iq=1,nq
4489  do k=mcond,km
4490  do i=is,ie
4491  q0(i,k,iq) = qa(i,j,k,iq) + (q0(i,k,iq) - qa(i,j,k,iq))*fra
4492  enddo
4493  enddo
4494  enddo
4495  endif
4496 
4497 !---
4498  do k=mcond, km
4499  do i=is, ie
4500  u_dt(i,j,k) = u_dt(i,j,k) + rdt*(u0(i,k) - ua(i,j,k))
4501  v_dt(i,j,k) = v_dt(i,j,k) + rdt*(v0(i,k) - va(i,j,k))
4502  t_dt(i,j,k) = t_dt(i,j,k) + rdt*(t0(i,k) - ta(i,j,k))
4503 ! Updates:
4504 ! ua(i,j,k) = u0(i,k)
4505 ! va(i,j,k) = v0(i,k)
4506  ta(i,j,k) = t0(i,k)
4507  enddo
4508  enddo
4509 
4510  do iq=1,nq
4511  do k=mcond, km
4512  do i=is, ie
4513  q_dt(i,j,k,iq) = q_dt(i,j,k,iq) + rdt*(q0(i,k,iq)-qa(i,j,k,iq))
4514 ! q updated
4515  qa(i,j,k,iq) = q0(i,k,iq)
4516  enddo
4517  enddo
4518  enddo
4519 
4520  if ( .not. hydrostatic ) then
4521  do k=mcond,km
4522  do i=is,ie
4523  w(i,j,k) = w0(i,k) ! w updated
4524  enddo
4525  enddo
4526  endif
4527 
4528 1000 continue
4529 
4530  end subroutine sg_conv
4531 
4532  subroutine dbzcalc(qv, qr, qs, qg, pt, delp, dz, &
4533  dbz, maxdbz, allmax, is, ie, js, je, ks, ke, &
4534  in0r, in0s, in0g, iliqskin)
4536  !Code from Mark Stoelinga's dbzcalc.f from the RIP package.
4537  !Currently just using values taken directly from that code, which is
4538  ! consistent for the MM5 Reisner-2 microphysics. From that file:
4539 
4540 ! This routine computes equivalent reflectivity factor (in dBZ) at
4541 ! each model grid point. In calculating Ze, the RIP algorithm makes
4542 ! assumptions consistent with those made in an early version
4543 ! (ca. 1996) of the bulk mixed-phase microphysical scheme in the MM5
4544 ! model (i.e., the scheme known as "Resiner-2"). For each species:
4545 !
4546 ! 1. Particles are assumed to be spheres of constant density. The
4547 ! densities of rain drops, snow particles, and graupel particles are
4548 ! taken to be rho_r = rho_l = 1000 kg m^-3, rho_s = 100 kg m^-3, and
4549 ! rho_g = 400 kg m^-3, respectively. (l refers to the density of
4550 ! liquid water.)
4551 !
4552 ! 2. The size distribution (in terms of the actual diameter of the
4553 ! particles, rather than the melted diameter or the equivalent solid
4554 ! ice sphere diameter) is assumed to follow an exponential
4555 ! distribution of the form N(D) = N_0 * exp( lambda*D ).
4556 !
4557 ! 3. If in0X=0, the intercept parameter is assumed constant (as in
4558 ! early Reisner-2), with values of 8x10^6, 2x10^7, and 4x10^6 m^-4,
4559 ! for rain, snow, and graupel, respectively. Various choices of
4560 ! in0X are available (or can be added). Currently, in0X=1 gives the
4561 ! variable intercept for each species that is consistent with
4562 ! Thompson, Rasmussen, and Manning (2004, Monthly Weather Review,
4563 ! Vol. 132, No. 2, pp. 519-542.)
4564 !
4565 ! 4. If iliqskin=1, frozen particles that are at a temperature above
4566 ! freezing are assumed to scatter as a liquid particle.
4567 !
4568 ! More information on the derivation of simulated reflectivity in RIP
4569 ! can be found in Stoelinga (2005, unpublished write-up). Contact
4570 ! Mark Stoelinga (stoeling@atmos.washington.edu) for a copy.
4571 
4572  integer, intent(IN) :: is, ie, js, je, ks, ke
4573  real, intent(IN), dimension(is:, js:, ks:) :: qv, qr, qs, qg, pt, delp, dz
4574  real, intent(OUT), dimension(is:, js:, ks:) :: dbz
4575  real, intent(OUT), dimension(is:, js:) :: maxdbz
4576  logical, intent(IN) :: in0r, in0s, in0g, iliqskin
4577  real, intent(OUT) :: allmax
4578 
4579  !Parameters for constant intercepts (in0[rsg] = .false.)
4580  real, parameter :: rn0_r = 8.e6 ! m^-4
4581  real, parameter :: rn0_s = 2.e7 ! m^-4
4582  real, parameter :: rn0_g = 4.e6 ! m^-4
4583 
4584  !Constants for variable intercepts
4585  real, parameter :: r1=1.e-15
4586  real, parameter :: ron=8.e6
4587  real, parameter :: ron2=1.e10
4588  real, parameter :: son=2.e7
4589  real, parameter :: gon=5.e7
4590  real, parameter :: ron_min = 8.e6
4591  real, parameter :: ron_qr0 = 0.00010
4592  real, parameter :: ron_delqr0 = 0.25*ron_qr0
4593  real, parameter :: ron_const1r = (ron2-ron_min)*0.5
4594  real, parameter :: ron_const2r = (ron2+ron_min)*0.5
4595 
4596  !Other constants
4597  real, parameter :: gamma_seven = 720.
4598  real, parameter :: rho_r = rhor ! 1000. kg m^-3
4599  real, parameter :: rho_s = 100. ! kg m^-3
4600  real, parameter :: rho_g = 400. ! kg m^-3
4601  real, parameter :: alpha = 0.224
4602  real, parameter :: factor_r = gamma_seven * 1.e18 * (1./(pi*rho_r))**1.75
4603  real, parameter :: factor_s = gamma_seven * 1.e18 * (1./(pi*rho_s))**1.75 &
4604  * (rho_s/rho_r)**2 * alpha
4605  real, parameter :: factor_g = gamma_seven * 1.e18 * (1./(pi*rho_g))**1.75 &
4606  * (rho_g/rho_r)**2 * alpha
4607 
4608  integer :: i,j,k
4609  real :: factorb_s, factorb_g, rhoair
4610  real :: temp_c, pres, sonv, gonv, ronv, z_e
4611  real :: q1, q2, q3
4612 
4613  maxdbz = 0.
4614  allmax = 0.
4615 
4616  do k=ks, ke
4617  do j=js, je
4618  do i=is, ie
4619 
4620  rhoair = -delp(i,j,k)/(grav*dz(i,j,k)) ! air density
4621 
4622  ! Adjust factor for brightband, where snow or graupel particle
4623  ! scatters like liquid water (alpha=1.0) because it is assumed to
4624  ! have a liquid skin.
4625 
4626  !lmh: celkel in dbzcalc.f presumably freezing temperature
4627  if (iliqskin .and. pt(i,j,k) .gt. tice) then
4628  factorb_s=factor_s/alpha
4629  factorb_g=factor_g/alpha
4630  else
4631  factorb_s=factor_s
4632  factorb_g=factor_g
4633  endif
4634 
4635  !Calculate variable intercept parameters if necessary
4636  ! using definitions from Thompson et al
4637  if (in0s) then
4638  temp_c = min(-0.001, pt(i,j,k) - tice)
4639  sonv = min(2.0e8, 2.0e6*exp(-0.12*temp_c))
4640  else
4641  sonv = rn0_s
4642  end if
4643 
4644  q1 = max(0., qg(i,j,k))
4645  q2 = max(0., qr(i,j,k))
4646  q3 = max(0., qs(i,j,k))
4647 
4648  if (in0g) then
4649  gonv = gon
4650  if ( qg(i,j,k) > r1) then
4651  gonv = 2.38 * (pi * rho_g / (rhoair*q1))**0.92
4652  gonv = max(1.e4, min(gonv,gon))
4653  end if
4654  else
4655  gonv = rn0_g
4656  end if
4657 
4658  if (in0r) then
4659  ronv = ron2
4660  if (qr(i,j,k) > r1 ) then
4661  ronv = ron_const1r * tanh((ron_qr0-q2)/ron_delqr0) + ron_const2r
4662  end if
4663  else
4664  ronv = rn0_r
4665  end if
4666 
4667  !Total equivalent reflectivity: mm^6 m^-3
4668  z_e = factor_r * (rhoair*q2)**1.75 / ronv**.75 & ! rain
4669  + factorb_s * (rhoair*q3)**1.75 / sonv**.75 & ! snow
4670  + factorb_g * (rhoair*q1)**1.75 / gonv**.75 ! graupel
4671 
4672  z_e = max(z_e,0.01)
4673  dbz(i,j,k) = 10. * log10(z_e)
4674 
4675  maxdbz(i,j) = max(dbz(i,j,k), maxdbz(i,j))
4676  allmax = max(dbz(i,j,k), allmax)
4677 
4678  enddo
4679  enddo
4680  enddo
4681 
4682  end subroutine dbzcalc
4683 
4684  real function g_sum(p, ifirst, ilast, jfirst, jlast, area, mode)
4685 !-------------------------
4686 ! Quick local sum algorithm
4687 !-------------------------
4688  use mpp_mod, only: mpp_sum
4689  integer, intent(IN) :: ifirst, ilast
4690  integer, intent(IN) :: jfirst, jlast
4691  integer, intent(IN) :: mode ! if ==1 divided by area
4692  real, intent(IN) :: p(ifirst:ilast,jfirst:jlast) ! field to be summed
4693  real, intent(IN) :: area(ifirst:ilast,jfirst:jlast)
4694  integer :: i,j
4695  real gsum
4696 
4697  if( global_area < 0. ) then
4698  global_area = 0.
4699  do j=jfirst,jlast
4700  do i=ifirst,ilast
4701  global_area = global_area + area(i,j)
4702  enddo
4703  enddo
4704  call mpp_sum(global_area)
4705  end if
4706 
4707  gsum = 0.
4708  do j=jfirst,jlast
4709  do i=ifirst,ilast
4710  gsum = gsum + p(i,j)*area(i,j)
4711  enddo
4712  enddo
4713  call mpp_sum(gsum)
4714 
4715  if ( mode==1 ) then
4716  g_sum = gsum / global_area
4717  else
4718  g_sum = gsum
4719  endif
4720 
4721  end function g_sum
4722 
4723  subroutine interpolate_z(is, ie, js, je, km, zl, hght, a3, a2)
4725  integer, intent(in):: is, ie, js, je, km
4726  real, intent(in):: hght(is:ie,js:je,km+1) ! hght(k) > hght(k+1)
4727  real, intent(in):: a3(is:ie,js:je,km)
4728  real, intent(in):: zl
4729  real, intent(out):: a2(is:ie,js:je)
4730 ! local:
4731  real zm(km)
4732  integer i,j,k
4733 
4734 
4735 !$OMP parallel do default(none) shared(is,ie,js,je,km,hght,zl,a2,a3) private(zm)
4736  do j=js,je
4737  do 1000 i=is,ie
4738  do k=1,km
4739  zm(k) = 0.5*(hght(i,j,k)+hght(i,j,k+1))
4740  enddo
4741  if( zl >= zm(1) ) then
4742  a2(i,j) = a3(i,j,1)
4743  elseif ( zl <= zm(km) ) then
4744  a2(i,j) = a3(i,j,km)
4745  else
4746  do k=1,km-1
4747  if( zl <= zm(k) .and. zl >= zm(k+1) ) then
4748  a2(i,j) = a3(i,j,k) + (a3(i,j,k+1)-a3(i,j,k))*(zm(k)-zl)/(zm(k)-zm(k+1))
4749  go to 1000
4750  endif
4751  enddo
4752  endif
4753 1000 continue
4754  enddo
4755 
4756  end subroutine interpolate_z
4757 
4758 end module lin_cld_microphys_mod
Definition: fms.F90:20
real function, public wqs2(ta, den, dqdt)
subroutine, public es2_table1d(ta, es, n)
real function, public wqs1(ta, den)
real function, public qs_blend(t, p, q)
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)
subroutine linear_prof(km, p1, q, dm, z_var, h_var)
real function, public wet_bulb(q, t, den)
subroutine, public es3_table1d(ta, es, n)
real, dimension(:), allocatable table3
subroutine dbzcalc(qv, qr, qs, qg, pt, delp, dz, dbz, maxdbz, allmax, is, ie, js, je, ks, ke, in0r, in0s, in0g, iliqskin)
subroutine, public lin_cld_microphys_end
subroutine terminal_fall(dtm, ktop, kbot, tz, qv, ql, qr, qg, qs, qi, pm, dz, dp, den, vtg, vts, vti, fac_sno, fac_gra, r1, g1, s1, i1, m1_sol, w1)
real function qs1d_moist(ta, qv, pa, dqdt)
real, parameter, public hlv
Latent heat of evaporation [J/kg].
Definition: constants.F90:80
real, dimension(:), allocatable des3
real function acr3d(v1, v2, q1, q2, c, cac, rho)
real function, public g_sum(p, ifirst, ilast, jfirst, jlast, area, mode)
subroutine interpolate_z(is, ie, js, je, km, zl, hght, a3, a2)
real function smlt(tc, dqs, qsrho, psacw, psacr, c, rho, rhofac)
subroutine cs_profile(a4, del, km, do_mono)
real, parameter, public rdgas
Gas constant for dry air [J/kg/deg].
Definition: constants.F90:77
subroutine icloud(ktop, kbot, tzk, p1, qvk, qlk, qrk, qik, qsk, qgk, dp1, den, denfac, vts, vtg, vtr, qak, rh_adj, rh_rain, dts, fac_sno, fac_gra, h_var)
subroutine, public sat_adj2(mdt, is, ie, js, je, ng, hydrostatic, consv_te, te0, qv, ql, qi, qr, qs, qg, qa, area, dpeln, delz, pt, dp, q_con, ifdef MOIST_CAPPA
subroutine revap_racc(ktop, kbot, dt, tz, qv, ql, qr, qi, qs, qg, den, denfac, rh_rain, h_var)
real, parameter, public cp_vapor
Specific heat capacity of water vapor at constant pressure [J/kg/deg].
Definition: constants.F90:89
real function gmlt(tc, dqs, qgrho, pgacw, pgacr, c, rho)
real, dimension(:), allocatable table
Definition: mpp.F90:39
integer function, public check_nml_error(IOSTAT, NML_NAME)
Definition: fms.F90:658
subroutine warm_rain(dt, ktop, kbot, p1, dp, dz, tz, qv, ql, qr, qi, qs, qg, pm, den, denfac, ccn, c_praut, rh_rain, vtr, r1, m1_rain, w1, h_var)
character(len=input_str_length), dimension(:), allocatable, target, public input_nml_file
Definition: mpp.F90:1378
subroutine, public lin_cld_microphys_init(id, jd, kd, axes, time)
real, parameter, public rvgas
Gas constant for water vapor [J/kg/deg].
Definition: constants.F90:78
subroutine subgrid_z_proc(ktop, kbot, p1, den, dts, rh_adj, tz, qv, ql, qr, qi, qs, qg, qa, h_var)
real, dimension(:), allocatable desw
subroutine sedi_heat(ktop, kbot, dm, m1, dz, tz, qv, ql, qr, qi, qs, qg, cw)
real function qs1d_m(ta, qv, pa)
subroutine lagrangian_fall_ppm(ktop, kbot, zs, ze, zt, dp, q, precip, m1, mono)
real, parameter, public cp_air
Specific heat capacity of dry air at constant pressure [J/kg/deg].
Definition: constants.F90:83
real function, public wqsat_moist(ta, qv, pa)
subroutine check_column(ktop, kbot, q, no_fall)
subroutine neg_adj(ktop, kbot, p1, pt, dp, qv, ql, qr, qi, qs, qg)
subroutine fall_speed(ktop, kbot, den, qs, qi, qg, ql, tk, vts, vti, vtg)
subroutine revap_rac1(hydrostatic, is, ie, dt, tz, qv, ql, qr, qi, qs, qg, den, hvar)
subroutine, public esw_table1d(ta, es, n)
subroutine, public lin_cld_microphys_driver(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, iis, iie, jjs, jje, kks, kke, ktop, kbot, time)
real, dimension(:), allocatable des
real, parameter, public hlf
Latent heat of fusion [J/kg].
Definition: constants.F90:81
real, parameter, public grav
Acceleration due to gravity [m/s^2].
Definition: constants.F90:76
real function iqs2(ta, den, dqdt)
real, dimension(:), allocatable tablew
subroutine lagrangian_fall_pcm(ktop, kbot, zs, ze, zt, dp, q, precip, m1)
#define max(a, b)
Definition: mosaic_util.h:33
subroutine remap2(ktop, kbot, kn, km, dp, q1, q2, id)
real, dimension(:), allocatable des2
subroutine, public qsmith(im, km, ks, t, p, q, qs, dqdt)
real, dimension(:), allocatable table2
#define min(a, b)
Definition: mosaic_util.h:32
real function, public wqsat2_moist(ta, qv, pa, dqdt)
subroutine, public get_time(Time, seconds, days, ticks, err_msg)
subroutine, public error_mesg(routine, message, level)
Definition: fms.F90:529
integer, parameter fvprc
real, parameter, public kappa
RDGAS / CP_AIR [dimensionless].
Definition: constants.F90:82
The namespace for the qg model.
subroutine, public sg_conv(is, ie, js, je, isd, ied, jsd, jed, km, nq, dt, tau, delp, phalf, pm, zfull, zhalf, ta, qa, ua, va, w, u_dt, v_dt, t_dt, q_dt, nqv, nql, nqi, nqr, nqs, nqg, hydrostatic, phys_hydrostatic)
real, dimension(3, 4) acco
real(fp), parameter, public pi