CCPP SciDoc v7.0.0  v7.0.0
Common Community Physics Package Developed at DTC
 
Loading...
Searching...
No Matches
mp_thompson.F90
1
3
4
6
9
10 use mpi_f08
11 use machine, only : kind_phys
12
14 use module_mp_thompson, only : nain0, nain1, naccn0, naccn1, eps, nt_c_l, nt_c_o
15 use module_mp_thompson, only : re_qc_min, re_qc_max, re_qi_min, re_qi_max, re_qs_min, re_qs_max
16
18
19 implicit none
20
21 public :: mp_thompson_init, mp_thompson_run, mp_thompson_finalize
22
23 private
24
25 logical :: is_initialized = .false.
26
27 integer, parameter :: ext_ndiag3d = 37
28
29 contains
30
35 subroutine mp_thompson_init(ncol, nlev, con_g, con_rd, con_eps, &
36 restart, imp_physics, &
37 imp_physics_thompson, convert_dry_rho, &
38 spechum, qc, qr, qi, qs, qg, ni, nr, &
39 is_aerosol_aware, merra2_aerosol_aware, &
40 nc, nwfa2d, nifa2d, &
41 nwfa, nifa, tgrs, prsl, phil, area, &
42 aerfld, mpicomm, mpirank, mpiroot, &
43 threads, ext_diag, diag3d, &
44 errmsg, errflg)
45
46 implicit none
47
48 ! Interface variables
49 integer, intent(in ) :: ncol
50 integer, intent(in ) :: nlev
51 real(kind_phys), intent(in ) :: con_g, con_rd, con_eps
52 logical, intent(in ) :: restart
53 integer, intent(in ) :: imp_physics
54 integer, intent(in ) :: imp_physics_thompson
55 ! Hydrometeors
56 logical, intent(in ) :: convert_dry_rho
57 real(kind_phys), intent(inout) :: spechum(:,:)
58 real(kind_phys), intent(inout) :: qc(:,:)
59 real(kind_phys), intent(inout) :: qr(:,:)
60 real(kind_phys), intent(inout) :: qi(:,:)
61 real(kind_phys), intent(inout) :: qs(:,:)
62 real(kind_phys), intent(inout) :: qg(:,:)
63 real(kind_phys), intent(inout) :: ni(:,:)
64 real(kind_phys), intent(inout) :: nr(:,:)
65 ! Aerosols
66 logical, intent(in ) :: is_aerosol_aware
67 logical, intent(in ) :: merra2_aerosol_aware
68 real(kind_phys), intent(inout), optional :: nc(:,:)
69 real(kind_phys), intent(inout), optional :: nwfa(:,:)
70 real(kind_phys), intent(inout), optional :: nifa(:,:)
71 real(kind_phys), intent(inout), optional :: nwfa2d(:)
72 real(kind_phys), intent(inout), optional :: nifa2d(:)
73 real(kind_phys), intent(in) :: aerfld(:,:,:)
74 ! State variables
75 real(kind_phys), intent(in ) :: tgrs(:,:)
76 real(kind_phys), intent(in ) :: prsl(:,:)
77 real(kind_phys), intent(in ) :: phil(:,:)
78 real(kind_phys), intent(in ) :: area(:)
79 ! MPI information
80 type(mpi_comm), intent(in ) :: mpicomm
81 integer, intent(in ) :: mpirank
82 integer, intent(in ) :: mpiroot
83 ! Threading/blocking information
84 integer, intent(in ) :: threads
85 ! Extended diagnostics
86 logical, intent(in ) :: ext_diag
87 real(kind_phys), intent(in ), optional :: diag3d(:,:,:)
88 ! CCPP error handling
89 character(len=*), intent( out) :: errmsg
90 integer, intent( out) :: errflg
91
92 !
93 real(kind_phys) :: qv(1:ncol,1:nlev) ! kg kg-1 (water vapor mixing ratio)
94 real(kind_phys) :: hgt(1:ncol,1:nlev) ! m
95 real(kind_phys) :: rho(1:ncol,1:nlev) ! kg m-3
96 real(kind_phys) :: orho(1:ncol,1:nlev) ! m3 kg-1
97 real(kind_phys) :: nc_local(1:ncol,1:nlev) ! needed because nc is only allocated if is_aerosol_aware is true
98 !
99 real (kind=kind_phys) :: h_01, z1, niin3, niccn3
100 integer :: i, k
101
102 ! Initialize the CCPP error handling variables
103 errmsg = ''
104 errflg = 0
105
106 if (is_initialized) return
107
108 ! Consistency checks
109 if (imp_physics/=imp_physics_thompson) then
110 write(errmsg,'(*(a))') "Logic error: namelist choice of microphysics is different from Thompson MP"
111 errflg = 1
112 return
113 end if
114
115 if (ext_diag) then
116 if (size(diag3d,dim=3) /= ext_ndiag3d) then
117 write(errmsg,'(*(a))') "Logic error: number of diagnostic 3d arrays from model does not match requirements"
118 errflg = 1
119 return
120 end if
121 end if
122
123 if (is_aerosol_aware .and. merra2_aerosol_aware) then
124 write(errmsg,'(*(a))') "Logic error: Only one Thompson aerosol option can be true, either is_aerosol_aware or merra2_aerosol_aware)"
125 errflg = 1
126 return
127 end if
128
129 ! Call Thompson init
130 call thompson_init(is_aerosol_aware_in=is_aerosol_aware, &
131 merra2_aerosol_aware_in=merra2_aerosol_aware, &
132 mpicomm=mpicomm, mpirank=mpirank, mpiroot=mpiroot, &
133 threads=threads, errmsg=errmsg, errflg=errflg)
134 if (errflg /= 0) return
135
136 ! For restart runs, the init is done here
137 if (restart) then
138 is_initialized = .true.
139 return
140 end if
141
142 ! Geopotential height in m2 s-2 to height in m
143 hgt = phil/con_g
144
145 ! Ensure non-negative mass mixing ratios of all water variables
146 where(spechum<0) spechum = 1.0e-10 ! COMMENT, gthompsn, spechum should *never* be identically zero.
147 where(qc<0) qc = 0.0
148 where(qr<0) qr = 0.0
149 where(qi<0) qi = 0.0
150 where(qs<0) qs = 0.0
151 where(qg<0) qg = 0.0
152
156 if (merra2_aerosol_aware) then
157 call get_niwfa(aerfld, nifa, nwfa, ncol, nlev)
158 end if
159
160
161 qv = spechum/(1.0_kind_phys-spechum)
162
163 if (convert_dry_rho) then
164 qc = qc/(1.0_kind_phys-spechum)
165 qr = qr/(1.0_kind_phys-spechum)
166 qi = qi/(1.0_kind_phys-spechum)
167 qs = qs/(1.0_kind_phys-spechum)
168 qg = qg/(1.0_kind_phys-spechum)
169
170 ni = ni/(1.0_kind_phys-spechum)
171 nr = nr/(1.0_kind_phys-spechum)
172 if (is_aerosol_aware .or. merra2_aerosol_aware) then
173 nc = nc/(1.0_kind_phys-spechum)
174 nwfa = nwfa/(1.0_kind_phys-spechum)
175 nifa = nifa/(1.0_kind_phys-spechum)
176 end if
177 end if
178
179 ! Density of moist air in kg m-3 and inverse density of air
180 rho = con_eps*prsl/(con_rd*tgrs*(qv+con_eps))
181 orho = 1.0/rho
182
183 ! Ensure we have 1st guess ice number where mass non-zero but no number.
184 where(qi .LE. 0.0) ni=0.0
185 where(qi .GT. 0 .and. ni .LE. 0.0) ni = make_icenumber(qi*rho, tgrs) * orho
186 where(qi .EQ. 0.0 .and. ni .GT. 0.0) ni=0.0
187
188 ! Ensure we have 1st guess rain number where mass non-zero but no number.
189 where(qr .LE. 0.0) nr=0.0
190 where(qr .GT. 0 .and. nr .LE. 0.0) nr = make_rainnumber(qr*rho, tgrs) * orho
191 where(qr .EQ. 0.0 .and. nr .GT. 0.0) nr=0.0
192
193
194 !..Check for existing aerosol data, both CCN and IN aerosols. If missing
195 !.. fill in just a basic vertical profile, somewhat boundary-layer following.
196 if (is_aerosol_aware) then
197
198 ! Potential cloud condensation nuclei (CCN)
199 if (maxval(nwfa) .lt. eps) then
200 if (mpirank==mpiroot) write(*,*) ' Apparently there are no initial CCN aerosols.'
201 do i = 1, ncol
202 if (hgt(i,1).le.1000.0) then
203 h_01 = 0.8
204 elseif (hgt(i,1).ge.2500.0) then
205 h_01 = 0.01
206 else
207 h_01 = 0.8*cos(hgt(i,1)*0.001 - 1.0)
208 endif
209 niccn3 = -1.0*alog(naccn1/naccn0)/h_01
210 nwfa(i,1) = naccn1+naccn0*exp(-((hgt(i,2)-hgt(i,1))/1000.)*niccn3)
211 z1 = hgt(i,2)-hgt(i,1)
212 nwfa2d(i) = nwfa(i,1) * 0.000196 * (50./z1)
213 do k = 2, nlev
214 nwfa(i,k) = naccn1+naccn0*exp(-((hgt(i,k)-hgt(i,1))/1000.)*niccn3)
215 enddo
216 enddo
217 else
218 if (mpirank==mpiroot) write(*,*) ' Apparently initial CCN aerosols are present.'
219 if (maxval(nwfa2d) .lt. eps) then
220 !+---+-----------------------------------------------------------------+
221 !..Scale the lowest level aerosol data into an emissions rate. This is
222 !.. very far from ideal, but need higher emissions where larger amount
223 !.. of (climo) existing and lesser emissions where there exists fewer to
224 !.. begin as a first-order simplistic approach. Later, proper connection to
225 !.. emission inventory would be better, but, for now, scale like this:
226 !.. where: Nwfa=50 per cc, emit 0.875E4 aerosols per second per grid box unit
227 !.. that was tested as ~(20kmx20kmx50m = 2.E10 m**-3)
228 !+---+-----------------------------------------------------------------+
229 if (mpirank==mpiroot) write(*,*) ' Apparently there are no initial CCN aerosol surface emission rates.'
230 do i = 1, ncol
231 z1 = hgt(i,2)-hgt(i,1)
232 nwfa2d(i) = nwfa(i,1) * 0.000196 * (50./z1)
233 enddo
234 else
235 if (mpirank==mpiroot) write(*,*) ' Apparently initial CCN aerosol surface emission rates are present.'
236 endif
237 endif
238
239 ! Potential ice nuclei (IN)
240 if (maxval(nifa) .lt. eps) then
241 if (mpirank==mpiroot) write(*,*) ' Apparently there are no initial IN aerosols.'
242 do i = 1, ncol
243 if (hgt(i,1).le.1000.0) then
244 h_01 = 0.8
245 elseif (hgt(i,1).ge.2500.0) then
246 h_01 = 0.01
247 else
248 h_01 = 0.8*cos(hgt(i,1)*0.001 - 1.0)
249 endif
250 niin3 = -1.0*alog(nain1/nain0)/h_01
251 nifa(i,1) = nain1+nain0*exp(-((hgt(i,2)-hgt(i,1))/1000.)*niin3)
252 nifa2d(i) = 0.
253 do k = 2, nlev
254 nifa(i,k) = nain1+nain0*exp(-((hgt(i,k)-hgt(i,1))/1000.)*niin3)
255 enddo
256 enddo
257 else
258 if (mpirank==mpiroot) write(*,*) ' Apparently initial IN aerosols are present.'
259 if (maxval(nifa2d) .lt. eps) then
260 if (mpirank==mpiroot) write(*,*) ' Apparently there are no initial IN aerosol surface emission rates, set to zero.'
261 ! calculate IN surface flux here, right now just set to zero
262 nifa2d = 0.
263 else
264 if (mpirank==mpiroot) write(*,*) ' Apparently initial IN aerosol surface emission rates are present.'
265 endif
266 endif
267
268 ! Ensure we have 1st guess cloud droplet number where mass non-zero but no number.
269 where(qc .LE. 0.0) nc=0.0
270 where(qc .GT. 0 .and. nc .LE. 0.0) nc = make_dropletnumber(qc*rho, nwfa*rho) * orho
271 where(qc .EQ. 0.0 .and. nc .GT. 0.0) nc = 0.0
272
273 ! Ensure non-negative aerosol number concentrations.
274 where(nwfa .LE. 0.0) nwfa = 1.1e6
275 where(nifa .LE. 0.0) nifa = nain1*0.01
276
277 ! Copy to local array for calculating cloud effective radii below
278 nc_local = nc
279
280 else if (merra2_aerosol_aware) then
281
282 ! Ensure we have 1st guess cloud droplet number where mass non-zero but no number.
283 where(qc .LE. 0.0) nc=0.0
284 where(qc .GT. 0 .and. nc .LE. 0.0) nc = make_dropletnumber(qc*rho, nwfa*rho) * orho
285 where(qc .EQ. 0.0 .and. nc .GT. 0.0) nc = 0.0
286
287 else
288
289 ! Constant droplet concentration for single moment cloud water as in
290 ! module_mp_thompson.F90, only needed for effective radii calculation
291 nc_local = nt_c_l/rho
292
293 end if
294
295 if (convert_dry_rho) then
296 !qc = qc/(1.0_kind_phys+qv)
297 !qr = qr/(1.0_kind_phys+qv)
298 !qi = qi/(1.0_kind_phys+qv)
299 !qs = qs/(1.0_kind_phys+qv)
300 !qg = qg/(1.0_kind_phys+qv)
301
302 ni = ni/(1.0_kind_phys+qv)
303 nr = nr/(1.0_kind_phys+qv)
304 if (is_aerosol_aware .or. merra2_aerosol_aware) then
305 nc = nc/(1.0_kind_phys+qv)
306 nwfa = nwfa/(1.0_kind_phys+qv)
307 nifa = nifa/(1.0_kind_phys+qv)
308 end if
309 end if
310
311 is_initialized = .true.
312
313 end subroutine mp_thompson_init
314
315
322 subroutine mp_thompson_run(ncol, nlev, con_g, con_rd, &
323 con_eps, convert_dry_rho, &
324 spechum, qc, qr, qi, qs, qg, ni, nr, &
325 is_aerosol_aware, &
326 merra2_aerosol_aware, nc, nwfa, nifa,&
327 nwfa2d, nifa2d, aero_ind_fdb, &
328 tgrs, prsl, phii, omega, &
329 sedi_semi, decfl, islmsk, dtp, &
330 dt_inner, &
331 first_time_step, istep, nsteps, &
332 prcp, rain, graupel, ice, snow, sr, &
333 refl_10cm, fullradar_diag, &
334 max_hail_diam_sfc, &
335 do_radar_ref, aerfld, &
336 mpicomm, mpirank, mpiroot, blkno, &
337 ext_diag, diag3d, reset_diag3d, &
338 spp_wts_mp, spp_mp, n_var_spp, &
339 spp_prt_list, spp_var_list, &
340 spp_stddev_cutoff, &
341 cplchm, pfi_lsan, pfl_lsan, &
342 errmsg, errflg)
343
344 implicit none
345
346 ! Interface variables
347
348 ! Dimensions and constants
349 integer, intent(in ) :: ncol
350 integer, intent(in ) :: nlev
351 real(kind_phys), intent(in ) :: con_g
352 real(kind_phys), intent(in ) :: con_rd
353 real(kind_phys), intent(in ) :: con_eps
354 ! Hydrometeors
355 logical, intent(in ) :: convert_dry_rho
356 real(kind_phys), intent(inout) :: spechum(:,:)
357 real(kind_phys), intent(inout) :: qc(:,:)
358 real(kind_phys), intent(inout) :: qr(:,:)
359 real(kind_phys), intent(inout) :: qi(:,:)
360 real(kind_phys), intent(inout) :: qs(:,:)
361 real(kind_phys), intent(inout) :: qg(:,:)
362 real(kind_phys), intent(inout) :: ni(:,:)
363 real(kind_phys), intent(inout) :: nr(:,:)
364 ! Aerosols
365 logical, intent(in) :: is_aerosol_aware, fullradar_diag
366 logical, intent(in) :: merra2_aerosol_aware
367 real(kind_phys), optional, intent(inout) :: nc(:,:)
368 real(kind_phys), optional, intent(inout) :: nwfa(:,:)
369 real(kind_phys), optional, intent(inout) :: nifa(:,:)
370 real(kind_phys), optional, intent(in ) :: nwfa2d(:)
371 real(kind_phys), optional, intent(in ) :: nifa2d(:)
372 real(kind_phys), intent(in) :: aerfld(:,:,:)
373 logical, optional, intent(in ) :: aero_ind_fdb
374 ! State variables and timestep information
375 real(kind_phys), intent(inout) :: tgrs(:,:)
376 real(kind_phys), intent(in ) :: prsl(:,:)
377 real(kind_phys), intent(in ) :: phii(:,:)
378 real(kind_phys), intent(in ) :: omega(:,:)
379 integer, intent(in ) :: islmsk(:)
380 real(kind_phys), intent(in ) :: dtp
381 logical, intent(in ) :: first_time_step
382 integer, intent(in ) :: istep, nsteps
383 real, intent(in ) :: dt_inner
384 ! Precip/rain/snow/graupel fall amounts and fraction of frozen precip
385 real(kind_phys), intent(inout) :: prcp(:)
386 real(kind_phys), intent(inout), optional :: rain(:)
387 real(kind_phys), intent(inout), optional :: graupel(:)
388 real(kind_phys), intent(inout), optional :: ice(:)
389 real(kind_phys), intent(inout), optional :: snow(:)
390 real(kind_phys), intent( out) :: sr(:)
391 ! Radar reflectivity
392 real(kind_phys), intent(inout) :: refl_10cm(:,:)
393 real(kind_phys), intent(inout) :: max_hail_diam_sfc(:)
394 logical, intent(in ) :: do_radar_ref
395 logical, intent(in) :: sedi_semi
396 integer, intent(in) :: decfl
397 ! MPI and block information
398 integer, intent(in) :: blkno
399 type(mpi_comm), intent(in) :: mpicomm
400 integer, intent(in) :: mpirank
401 integer, intent(in) :: mpiroot
402 ! Extended diagnostic output
403 logical, intent(in) :: ext_diag
404 real(kind_phys), target, intent(inout), optional :: diag3d(:,:,:)
405 logical, intent(in) :: reset_diag3d
406
407 ! CCPP error handling
408 character(len=*), intent( out) :: errmsg
409 integer, intent( out) :: errflg
410
411 ! SPP
412 integer, intent(in) :: spp_mp
413 integer, intent(in) :: n_var_spp
414 real(kind_phys), intent(in), optional :: spp_wts_mp(:,:)
415 real(kind_phys), intent(in), optional :: spp_prt_list(:)
416 character(len=10), intent(in), optional :: spp_var_list(:)
417 real(kind_phys), intent(in) :: spp_stddev_cutoff(:)
418
419 logical, intent (in) :: cplchm
420 ! ice and liquid water 3d precipitation fluxes - only allocated if cplchm is .true.
421 real(kind=kind_phys), intent(inout), dimension(:,:), optional :: pfi_lsan
422 real(kind=kind_phys), intent(inout), dimension(:,:), optional :: pfl_lsan
423
424 ! Local variables
425
426 ! Reduced time step if subcycling is used
427 real(kind_phys) :: dtstep
428 integer :: ndt
429 ! Air density
430 real(kind_phys) :: rho(1:ncol,1:nlev)
431 ! Water vapor mixing ratio (instead of specific humidity)
432 real(kind_phys) :: qv(1:ncol,1:nlev)
433 ! Vertical velocity and level width
434 real(kind_phys) :: w(1:ncol,1:nlev)
435 real(kind_phys) :: dz(1:ncol,1:nlev)
436 ! Rain/snow/graupel fall amounts
437 real(kind_phys) :: rain_mp(1:ncol) ! mm, dummy, not used
438 real(kind_phys) :: graupel_mp(1:ncol) ! mm, dummy, not used
439 real(kind_phys) :: ice_mp(1:ncol) ! mm, dummy, not used
440 real(kind_phys) :: snow_mp(1:ncol) ! mm, dummy, not used
441 real(kind_phys) :: delta_rain_mp(1:ncol) ! mm
442 real(kind_phys) :: delta_graupel_mp(1:ncol) ! mm
443 real(kind_phys) :: delta_ice_mp(1:ncol) ! mm
444 real(kind_phys) :: delta_snow_mp(1:ncol) ! mm
445
446 real(kind_phys) :: pfils(1:ncol,1:nlev,1)
447 real(kind_phys) :: pflls(1:ncol,1:nlev,1)
448 ! Radar reflectivity
449 logical :: diagflag ! must be true if do_radar_ref is true, not used otherwise
450 integer :: do_radar_ref_mp ! integer instead of logical do_radar_ref
451 ! Effective cloud radii - turned off in CCPP (taken care off in radiation)
452 logical, parameter :: do_effective_radii = .false.
453 integer, parameter :: has_reqc = 0
454 integer, parameter :: has_reqi = 0
455 integer, parameter :: has_reqs = 0
456 integer, parameter :: kme_stoch = 1
457 integer :: spp_mp_opt
458 ! Dimensions used in mp_gt_driver
459 integer :: ids,ide, jds,jde, kds,kde, &
460 ims,ime, jms,jme, kms,kme, &
461 its,ite, jts,jte, kts,kte
462 ! Pointer arrays for extended diagnostics
463 !real(kind_phys), dimension(:,:,:), pointer :: vts1 => null()
464 !real(kind_phys), dimension(:,:,:), pointer :: txri => null()
465 !real(kind_phys), dimension(:,:,:), pointer :: txrc => null()
466 real(kind_phys), dimension(:,:,:), pointer :: prw_vcdc => null()
467 real(kind_phys), dimension(:,:,:), pointer :: prw_vcde => null()
468 real(kind_phys), dimension(:,:,:), pointer :: tpri_inu => null()
469 real(kind_phys), dimension(:,:,:), pointer :: tpri_ide_d => null()
470 real(kind_phys), dimension(:,:,:), pointer :: tpri_ide_s => null()
471 real(kind_phys), dimension(:,:,:), pointer :: tprs_ide => null()
472 real(kind_phys), dimension(:,:,:), pointer :: tprs_sde_d => null()
473 real(kind_phys), dimension(:,:,:), pointer :: tprs_sde_s => null()
474 real(kind_phys), dimension(:,:,:), pointer :: tprg_gde_d => null()
475 real(kind_phys), dimension(:,:,:), pointer :: tprg_gde_s => null()
476 real(kind_phys), dimension(:,:,:), pointer :: tpri_iha => null()
477 real(kind_phys), dimension(:,:,:), pointer :: tpri_wfz => null()
478 real(kind_phys), dimension(:,:,:), pointer :: tpri_rfz => null()
479 real(kind_phys), dimension(:,:,:), pointer :: tprg_rfz => null()
480 real(kind_phys), dimension(:,:,:), pointer :: tprs_scw => null()
481 real(kind_phys), dimension(:,:,:), pointer :: tprg_scw => null()
482 real(kind_phys), dimension(:,:,:), pointer :: tprg_rcs => null()
483 real(kind_phys), dimension(:,:,:), pointer :: tprs_rcs => null()
484 real(kind_phys), dimension(:,:,:), pointer :: tprr_rci => null()
485 real(kind_phys), dimension(:,:,:), pointer :: tprg_rcg => null()
486 real(kind_phys), dimension(:,:,:), pointer :: tprw_vcd_c => null()
487 real(kind_phys), dimension(:,:,:), pointer :: tprw_vcd_e => null()
488 real(kind_phys), dimension(:,:,:), pointer :: tprr_sml => null()
489 real(kind_phys), dimension(:,:,:), pointer :: tprr_gml => null()
490 real(kind_phys), dimension(:,:,:), pointer :: tprr_rcg => null()
491 real(kind_phys), dimension(:,:,:), pointer :: tprr_rcs => null()
492 real(kind_phys), dimension(:,:,:), pointer :: tprv_rev => null()
493 real(kind_phys), dimension(:,:,:), pointer :: tten3 => null()
494 real(kind_phys), dimension(:,:,:), pointer :: qvten3 => null()
495 real(kind_phys), dimension(:,:,:), pointer :: qrten3 => null()
496 real(kind_phys), dimension(:,:,:), pointer :: qsten3 => null()
497 real(kind_phys), dimension(:,:,:), pointer :: qgten3 => null()
498 real(kind_phys), dimension(:,:,:), pointer :: qiten3 => null()
499 real(kind_phys), dimension(:,:,:), pointer :: niten3 => null()
500 real(kind_phys), dimension(:,:,:), pointer :: nrten3 => null()
501 real(kind_phys), dimension(:,:,:), pointer :: ncten3 => null()
502 real(kind_phys), dimension(:,:,:), pointer :: qcten3 => null()
503
504 ! Initialize the CCPP error handling variables
505 errmsg = ''
506 errflg = 0
507
508 if (first_time_step .and. istep==1 .and. blkno==1) then
509 ! Check initialization state
510 if (.not.is_initialized) then
511 write(errmsg, fmt='((a))') 'mp_thompson_run called before mp_thompson_init'
512 errflg = 1
513 return
514 end if
515 ! Check forr optional arguments of aerosol-aware microphysics
516 if (is_aerosol_aware .and. .not. (present(nc) .and. &
517 present(nwfa) .and. &
518 present(nifa) .and. &
519 present(nwfa2d) .and. &
520 present(nifa2d) )) then
521 write(errmsg,fmt='(*(a))') 'Logic error in mp_thompson_run:', &
522 ' aerosol-aware microphysics require all of the', &
523 ' following optional arguments:', &
524 ' nc, nwfa, nifa, nwfa2d, nifa2d'
525 errflg = 1
526 return
527 else if (merra2_aerosol_aware .and. .not. (present(nc) .and. &
528 present(nwfa) .and. &
529 present(nifa) )) then
530 write(errmsg,fmt='(*(a))') 'Logic error in mp_thompson_run:', &
531 ' merra2 aerosol-aware microphysics require the', &
532 ' following optional arguments: nc, nwfa, nifa'
533 errflg = 1
534 return
535 end if
536 ! Consistency cheecks - subcycling and inner loop at the same time are not supported
537 if (nsteps>1 .and. dt_inner < dtp) then
538 write(errmsg,'(*(a))') "Logic error: Subcycling and inner loop cannot be used at the same time"
539 errflg = 1
540 return
541 else if (mpirank==mpiroot .and. nsteps>1) then
542 write(*,'(a,i0,a,a,f6.2,a)') 'Thompson MP is using ', nsteps, ' substep(s) per time step with an ', &
543 'effective time step of ', dtp/real(nsteps, kind=kind_phys), ' seconds'
544 else if (mpirank==mpiroot .and. dt_inner < dtp) then
545 ndt = max(nint(dtp/dt_inner),1)
546 write(*,'(a,i0,a,a,f6.2,a)') 'Thompson MP is using ', ndt, ' inner loops per time step with an ', &
547 'effective time step of ', dtp/real(ndt, kind=kind_phys), ' seconds'
548 end if
549 end if
550
551 ! Set stochastic physics selection to apply all perturbations
552 if ( spp_mp==7 ) then
553 spp_mp_opt=7
554 else
555 spp_mp_opt=0
556 endif
557
558 ! Set reduced time step if subcycling is used
559 if (nsteps>1) then
560 dtstep = dtp/real(nsteps, kind=kind_phys)
561 else
562 dtstep = dtp
563 end if
564 if (merra2_aerosol_aware) then
565 call get_niwfa(aerfld, nifa, nwfa, ncol, nlev)
566 end if
567
571
572 ! DH* - do this only if istep == 1? Would be ok if it was
573 ! guaranteed that nothing else in the same subcycle group
574 ! was using these arrays, but it is somewhat dangerous.
575 qv = spechum/(1.0_kind_phys-spechum)
576
577 if (convert_dry_rho) then
578 qc = qc/(1.0_kind_phys-spechum)
579 qr = qr/(1.0_kind_phys-spechum)
580 qi = qi/(1.0_kind_phys-spechum)
581 qs = qs/(1.0_kind_phys-spechum)
582 qg = qg/(1.0_kind_phys-spechum)
583
584 ni = ni/(1.0_kind_phys-spechum)
585 nr = nr/(1.0_kind_phys-spechum)
586 if (is_aerosol_aware .or. merra2_aerosol_aware) then
587 nc = nc/(1.0_kind_phys-spechum)
588 nwfa = nwfa/(1.0_kind_phys-spechum)
589 nifa = nifa/(1.0_kind_phys-spechum)
590 end if
591 end if
592 ! *DH
593
595 rho = con_eps*prsl/(con_rd*tgrs*(qv+con_eps))
596
598 w = -omega/(rho*con_g)
599
601 dz = (phii(:,2:nlev+1) - phii(:,1:nlev)) / con_g
602
603 ! Accumulated values inside Thompson scheme, not used;
604 ! only use delta and add to inout variables (different units)
605 rain_mp = 0
606 graupel_mp = 0
607 ice_mp = 0
608 snow_mp = 0
609 delta_rain_mp = 0
610 delta_graupel_mp = 0
611 delta_ice_mp = 0
612 delta_snow_mp = 0
613
614 ! Flags for calculating radar reflectivity; diagflag is redundant
615 if (do_radar_ref) then
616 diagflag = .true.
617 do_radar_ref_mp = 1
618 else
619 diagflag = .false.
620 do_radar_ref_mp = 0
621 end if
622
623 ! Set internal dimensions
624 ids = 1
625 ims = 1
626 its = 1
627 ide = ncol
628 ime = ncol
629 ite = ncol
630 jds = 1
631 jms = 1
632 jts = 1
633 jde = 1
634 jme = 1
635 jte = 1
636 kds = 1
637 kms = 1
638 kts = 1
639 kde = nlev
640 kme = nlev
641 kte = nlev
642 if(cplchm) then
643 pfi_lsan = 0.0
644 pfl_lsan = 0.0
645 end if
646
647 ! Set pointers for extended diagnostics
648 set_extended_diagnostic_pointers: if (ext_diag) then
649 if (reset_diag3d) then
650 diag3d = 0.0
651 end if
652 !vts1 => diag3d(:,:,X:X)
653 !txri => diag3d(:,:,X:X)
654 !txrc => diag3d(:,:,X:X)
655 prw_vcdc => diag3d(:,:,1:1)
656 prw_vcde => diag3d(:,:,2:2)
657 tpri_inu => diag3d(:,:,3:3)
658 tpri_ide_d => diag3d(:,:,4:4)
659 tpri_ide_s => diag3d(:,:,5:5)
660 tprs_ide => diag3d(:,:,6:6)
661 tprs_sde_d => diag3d(:,:,7:7)
662 tprs_sde_s => diag3d(:,:,8:8)
663 tprg_gde_d => diag3d(:,:,9:9)
664 tprg_gde_s => diag3d(:,:,10:10)
665 tpri_iha => diag3d(:,:,11:11)
666 tpri_wfz => diag3d(:,:,12:12)
667 tpri_rfz => diag3d(:,:,13:13)
668 tprg_rfz => diag3d(:,:,14:14)
669 tprs_scw => diag3d(:,:,15:15)
670 tprg_scw => diag3d(:,:,16:16)
671 tprg_rcs => diag3d(:,:,17:17)
672 tprs_rcs => diag3d(:,:,18:18)
673 tprr_rci => diag3d(:,:,19:19)
674 tprg_rcg => diag3d(:,:,20:20)
675 tprw_vcd_c => diag3d(:,:,21:21)
676 tprw_vcd_e => diag3d(:,:,22:22)
677 tprr_sml => diag3d(:,:,23:23)
678 tprr_gml => diag3d(:,:,24:24)
679 tprr_rcg => diag3d(:,:,25:25)
680 tprr_rcs => diag3d(:,:,26:26)
681 tprv_rev => diag3d(:,:,27:27)
682 tten3 => diag3d(:,:,28:28)
683 qvten3 => diag3d(:,:,29:29)
684 qrten3 => diag3d(:,:,30:30)
685 qsten3 => diag3d(:,:,31:31)
686 qgten3 => diag3d(:,:,32:32)
687 qiten3 => diag3d(:,:,33:33)
688 niten3 => diag3d(:,:,34:34)
689 nrten3 => diag3d(:,:,35:35)
690 ncten3 => diag3d(:,:,36:36)
691 qcten3 => diag3d(:,:,37:37)
692 end if set_extended_diagnostic_pointers
694 if (is_aerosol_aware) then
695 call mp_gt_driver(qv=qv, qc=qc, qr=qr, qi=qi, qs=qs, qg=qg, ni=ni, nr=nr, &
696 nc=nc, nwfa=nwfa, nifa=nifa, nwfa2d=nwfa2d, nifa2d=nifa2d, &
697 tt=tgrs, p=prsl, w=w, dz=dz, dt_in=dtstep, dt_inner=dt_inner, &
698 sedi_semi=sedi_semi, decfl=decfl, lsm=islmsk, &
699 rainnc=rain_mp, rainncv=delta_rain_mp, &
700 snownc=snow_mp, snowncv=delta_snow_mp, &
701 icenc=ice_mp, icencv=delta_ice_mp, &
702 graupelnc=graupel_mp, graupelncv=delta_graupel_mp, sr=sr, &
703 refl_10cm=refl_10cm, &
704 diagflag=diagflag, do_radar_ref=do_radar_ref_mp, &
705 max_hail_diam_sfc=max_hail_diam_sfc, &
706 has_reqc=has_reqc, has_reqi=has_reqi, has_reqs=has_reqs, &
707 aero_ind_fdb=aero_ind_fdb, rand_perturb_on=spp_mp_opt, &
708 kme_stoch=kme_stoch, &
709 rand_pert=spp_wts_mp, spp_var_list=spp_var_list, &
710 spp_prt_list=spp_prt_list, n_var_spp=n_var_spp, &
711 spp_stddev_cutoff=spp_stddev_cutoff, &
712 ids=ids, ide=ide, jds=jds, jde=jde, kds=kds, kde=kde, &
713 ims=ims, ime=ime, jms=jms, jme=jme, kms=kms, kme=kme, &
714 its=its, ite=ite, jts=jts, jte=jte, kts=kts, kte=kte, &
715 fullradar_diag=fullradar_diag, istep=istep, nsteps=nsteps, &
716 first_time_step=first_time_step, errmsg=errmsg, errflg=errflg, &
717 ! Extended diagnostics
718 ext_diag=ext_diag, &
719 ! vts1=vts1, txri=txri, txrc=txrc, &
720 prw_vcdc=prw_vcdc, &
721 prw_vcde=prw_vcde, tpri_inu=tpri_inu, tpri_ide_d=tpri_ide_d, &
722 tpri_ide_s=tpri_ide_s, tprs_ide=tprs_ide, &
723 tprs_sde_d=tprs_sde_d, &
724 tprs_sde_s=tprs_sde_s, tprg_gde_d=tprg_gde_d, &
725 tprg_gde_s=tprg_gde_s, tpri_iha=tpri_iha, &
726 tpri_wfz=tpri_wfz, tpri_rfz=tpri_rfz, tprg_rfz=tprg_rfz, &
727 tprs_scw=tprs_scw, tprg_scw=tprg_scw, tprg_rcs=tprg_rcs, &
728 tprs_rcs=tprs_rcs, &
729 tprr_rci=tprr_rci, tprg_rcg=tprg_rcg, tprw_vcd_c=tprw_vcd_c, &
730 tprw_vcd_e=tprw_vcd_e, tprr_sml=tprr_sml, tprr_gml=tprr_gml, &
731 tprr_rcg=tprr_rcg, tprr_rcs=tprr_rcs, &
732 tprv_rev=tprv_rev, tten3=tten3, &
733 qvten3=qvten3, qrten3=qrten3, qsten3=qsten3, qgten3=qgten3, &
734 qiten3=qiten3, niten3=niten3, nrten3=nrten3, ncten3=ncten3, &
735 qcten3=qcten3, pfils=pfils, pflls=pflls)
736 else if (merra2_aerosol_aware) then
737 call mp_gt_driver(qv=qv, qc=qc, qr=qr, qi=qi, qs=qs, qg=qg, ni=ni, nr=nr, &
738 nc=nc, nwfa=nwfa, nifa=nifa, &
739 tt=tgrs, p=prsl, w=w, dz=dz, dt_in=dtstep, dt_inner=dt_inner, &
740 sedi_semi=sedi_semi, decfl=decfl, lsm=islmsk, &
741 rainnc=rain_mp, rainncv=delta_rain_mp, &
742 snownc=snow_mp, snowncv=delta_snow_mp, &
743 icenc=ice_mp, icencv=delta_ice_mp, &
744 graupelnc=graupel_mp, graupelncv=delta_graupel_mp, sr=sr, &
745 refl_10cm=refl_10cm, &
746 diagflag=diagflag, do_radar_ref=do_radar_ref_mp, &
747 max_hail_diam_sfc=max_hail_diam_sfc, &
748 has_reqc=has_reqc, has_reqi=has_reqi, has_reqs=has_reqs, &
749 aero_ind_fdb=aero_ind_fdb, rand_perturb_on=spp_mp_opt, &
750 kme_stoch=kme_stoch, &
751 rand_pert=spp_wts_mp, spp_var_list=spp_var_list, &
752 spp_prt_list=spp_prt_list, n_var_spp=n_var_spp, &
753 spp_stddev_cutoff=spp_stddev_cutoff, &
754 ids=ids, ide=ide, jds=jds, jde=jde, kds=kds, kde=kde, &
755 ims=ims, ime=ime, jms=jms, jme=jme, kms=kms, kme=kme, &
756 its=its, ite=ite, jts=jts, jte=jte, kts=kts, kte=kte, &
757 fullradar_diag=fullradar_diag, istep=istep, nsteps=nsteps, &
758 first_time_step=first_time_step, errmsg=errmsg, errflg=errflg, &
759 ! Extended diagnostics
760 ext_diag=ext_diag, &
761 ! vts1=vts1, txri=txri, txrc=txrc, &
762 prw_vcdc=prw_vcdc, &
763 prw_vcde=prw_vcde, tpri_inu=tpri_inu, tpri_ide_d=tpri_ide_d, &
764 tpri_ide_s=tpri_ide_s, tprs_ide=tprs_ide, &
765 tprs_sde_d=tprs_sde_d, &
766 tprs_sde_s=tprs_sde_s, tprg_gde_d=tprg_gde_d, &
767 tprg_gde_s=tprg_gde_s, tpri_iha=tpri_iha, &
768 tpri_wfz=tpri_wfz, tpri_rfz=tpri_rfz, tprg_rfz=tprg_rfz, &
769 tprs_scw=tprs_scw, tprg_scw=tprg_scw, tprg_rcs=tprg_rcs, &
770 tprs_rcs=tprs_rcs, &
771 tprr_rci=tprr_rci, tprg_rcg=tprg_rcg, tprw_vcd_c=tprw_vcd_c, &
772 tprw_vcd_e=tprw_vcd_e, tprr_sml=tprr_sml, tprr_gml=tprr_gml, &
773 tprr_rcg=tprr_rcg, tprr_rcs=tprr_rcs, &
774 tprv_rev=tprv_rev, tten3=tten3, &
775 qvten3=qvten3, qrten3=qrten3, qsten3=qsten3, qgten3=qgten3, &
776 qiten3=qiten3, niten3=niten3, nrten3=nrten3, ncten3=ncten3, &
777 qcten3=qcten3, pfils=pfils, pflls=pflls)
778 else
779 call mp_gt_driver(qv=qv, qc=qc, qr=qr, qi=qi, qs=qs, qg=qg, ni=ni, nr=nr, &
780 tt=tgrs, p=prsl, w=w, dz=dz, dt_in=dtstep, dt_inner=dt_inner, &
781 sedi_semi=sedi_semi, decfl=decfl, lsm=islmsk, &
782 rainnc=rain_mp, rainncv=delta_rain_mp, &
783 snownc=snow_mp, snowncv=delta_snow_mp, &
784 icenc=ice_mp, icencv=delta_ice_mp, &
785 graupelnc=graupel_mp, graupelncv=delta_graupel_mp, sr=sr, &
786 refl_10cm=refl_10cm, &
787 diagflag=diagflag, do_radar_ref=do_radar_ref_mp, &
788 max_hail_diam_sfc=max_hail_diam_sfc, &
789 has_reqc=has_reqc, has_reqi=has_reqi, has_reqs=has_reqs, &
790 rand_perturb_on=spp_mp_opt, kme_stoch=kme_stoch, &
791 rand_pert=spp_wts_mp, spp_var_list=spp_var_list, &
792 spp_prt_list=spp_prt_list, n_var_spp=n_var_spp, &
793 spp_stddev_cutoff=spp_stddev_cutoff, &
794 ids=ids, ide=ide, jds=jds, jde=jde, kds=kds, kde=kde, &
795 ims=ims, ime=ime, jms=jms, jme=jme, kms=kms, kme=kme, &
796 its=its, ite=ite, jts=jts, jte=jte, kts=kts, kte=kte, &
797 fullradar_diag=fullradar_diag, istep=istep, nsteps=nsteps, &
798 first_time_step=first_time_step, errmsg=errmsg, errflg=errflg, &
799 ! Extended diagnostics
800 ext_diag=ext_diag, &
801 ! vts1=vts1, txri=txri, txrc=txrc, &
802 prw_vcdc=prw_vcdc, &
803 prw_vcde=prw_vcde, tpri_inu=tpri_inu, tpri_ide_d=tpri_ide_d, &
804 tpri_ide_s=tpri_ide_s, tprs_ide=tprs_ide, &
805 tprs_sde_d=tprs_sde_d, &
806 tprs_sde_s=tprs_sde_s, tprg_gde_d=tprg_gde_d, &
807 tprg_gde_s=tprg_gde_s, tpri_iha=tpri_iha, &
808 tpri_wfz=tpri_wfz, tpri_rfz=tpri_rfz, tprg_rfz=tprg_rfz, &
809 tprs_scw=tprs_scw, tprg_scw=tprg_scw, tprg_rcs=tprg_rcs, &
810 tprs_rcs=tprs_rcs, &
811 tprr_rci=tprr_rci, tprg_rcg=tprg_rcg, tprw_vcd_c=tprw_vcd_c, &
812 tprw_vcd_e=tprw_vcd_e, tprr_sml=tprr_sml, tprr_gml=tprr_gml, &
813 tprr_rcg=tprr_rcg, tprr_rcs=tprr_rcs, &
814 tprv_rev=tprv_rev, tten3=tten3, &
815 qvten3=qvten3, qrten3=qrten3, qsten3=qsten3, qgten3=qgten3, &
816 qiten3=qiten3, niten3=niten3, nrten3=nrten3, ncten3=ncten3, &
817 qcten3=qcten3, pfils=pfils, pflls=pflls)
818 end if
819 if (errflg/=0) return
820
821 ! DH* - do this only if istep == nsteps? Would be ok if it was
822 ! guaranteed that nothing else in the same subcycle group
823 ! was using these arrays, but it is somewhat dangerous.
824
826 spechum = qv/(1.0_kind_phys+qv)
827
828 if (convert_dry_rho) then
829 qc = qc/(1.0_kind_phys+qv)
830 qr = qr/(1.0_kind_phys+qv)
831 qi = qi/(1.0_kind_phys+qv)
832 qs = qs/(1.0_kind_phys+qv)
833 qg = qg/(1.0_kind_phys+qv)
834
835 ni = ni/(1.0_kind_phys+qv)
836 nr = nr/(1.0_kind_phys+qv)
837 if (is_aerosol_aware .or. merra2_aerosol_aware) then
838 nc = nc/(1.0_kind_phys+qv)
839 nwfa = nwfa/(1.0_kind_phys+qv)
840 nifa = nifa/(1.0_kind_phys+qv)
841 end if
842 end if
843 ! *DH
844
846 ! "rain" in Thompson MP refers to precipitation (total of liquid rainfall+snow+graupel+ice)
847 prcp = prcp + max(0.0, delta_rain_mp/1000.0_kind_phys)
848 graupel = graupel + max(0.0, delta_graupel_mp/1000.0_kind_phys)
849 ice = ice + max(0.0, delta_ice_mp/1000.0_kind_phys)
850 snow = snow + max(0.0, delta_snow_mp/1000.0_kind_phys)
851 rain = rain + max(0.0, (delta_rain_mp - (delta_graupel_mp + delta_ice_mp + delta_snow_mp))/1000.0_kind_phys)
852
853 ! Recompute sr at last subcycling step
854 if (nsteps>1 .and. istep == nsteps) then
855 ! Unlike inside mp_gt_driver, rain does not contain frozen precip
856 sr = (snow + graupel + ice)/(rain + snow + graupel + ice +1.e-12)
857 end if
858
859 ! output instantaneous ice/snow and rain water 3d precipitation fluxes
860 if(cplchm) then
861 pfi_lsan(:,:) = pfils(:,:,1)
862 pfl_lsan(:,:) = pflls(:,:,1)
863 end if
864
865 ! DH* Not really needed because they go out of scope ...
866 ! But having them in here seems to cause problems with Intel?
867 ! It looked like this is also nullifying the pointers passed
868 ! from the CCPP caps.
869 !unset_extended_diagnostic_pointers: if (ext_diag) then
870 ! !vts1 => null()
871 ! !txri => null()
872 ! !txrc => null()
873 ! prw_vcdc => null()
874 ! prw_vcde => null()
875 ! tpri_inu => null()
876 ! tpri_ide_d => null()
877 ! tpri_ide_s => null()
878 ! tprs_ide => null()
879 ! tprs_sde_d => null()
880 ! tprs_sde_s => null()
881 ! tprg_gde_d => null()
882 ! tprg_gde_s => null()
883 ! tpri_iha => null()
884 ! tpri_wfz => null()
885 ! tpri_rfz => null()
886 ! tprg_rfz => null()
887 ! tprs_scw => null()
888 ! tprg_scw => null()
889 ! tprg_rcs => null()
890 ! tprs_rcs => null()
891 ! tprr_rci => null()
892 ! tprg_rcg => null()
893 ! tprw_vcd_c => null()
894 ! tprw_vcd_e => null()
895 ! tprr_sml => null()
896 ! tprr_gml => null()
897 ! tprr_rcg => null()
898 ! tprr_rcs => null()
899 ! tprv_rev => null()
900 ! tten3 => null()
901 ! qvten3 => null()
902 ! qrten3 => null()
903 ! qsten3 => null()
904 ! qgten3 => null()
905 ! qiten3 => null()
906 ! niten3 => null()
907 ! nrten3 => null()
908 ! ncten3 => null()
909 ! qcten3 => null()
910 !end if unset_extended_diagnostic_pointers
911 ! *DH
912
913 end subroutine mp_thompson_run
915
919 subroutine mp_thompson_finalize(errmsg, errflg)
920
921 implicit none
922
923 character(len=*), intent( out) :: errmsg
924 integer, intent( out) :: errflg
925
926 ! Initialize the CCPP error handling variables
927 errmsg = ''
928 errflg = 0
929
930 if (.not.is_initialized) return
931
932 call thompson_finalize()
933
934 is_initialized = .false.
935
936 end subroutine mp_thompson_finalize
937
938 subroutine get_niwfa(aerfld, nifa, nwfa, ncol, nlev)
939 ! To calculate nifa and nwfa from bins of aerosols.
940 ! In GOCART and MERRA2, aerosols are given as mixing ratio (kg/kg). To
941 ! convert from kg/kg to #/kg, the "unit mass" (mass of one particle)
942 ! within the mass bins is calculated. A lognormal size distribution
943 ! within aerosol bins is used to find the size based upon the median
944 ! mass. NIFA is mainly summarized over five dust bins and NWFA over the
945 ! other 10 bins. The parameters besides each bins are carefully tuned
946 ! for a good performance of the scheme.
947 !
948 ! The fields for the last index of the aerfld array
949 ! are specified as below.
950 ! 1: dust bin 1, 0.1 to 1.0 micrometers
951 ! 2: dust bin 2, 1.0 to 1.8 micrometers
952 ! 3: dust bin 3, 1.8 to 3.0 micrometers
953 ! 4: dust bin 4, 3.0 to 6.0 micrometers
954 ! 5: dust bin 5, 6.0 to 10.0 micrometers
955 ! 6: sea salt bin 1, 0.03 to 0.1 micrometers
956 ! 7: sea salt bin 2, 0.1 to 0.5 micrometers
957 ! 8: sea salt bin 3, 0.5 to 1.5 micrometers
958 ! 9: sea salt bin 4, 1.5 to 5.0 micrometers
959 ! 10: sea salt bin 5, 5.0 to 10.0 micrometers
960 ! 11: Sulfate, 0.35 (mean) micrometers
961 ! 15: water-friendly organic carbon, 0.35 (mean) micrometers
962 !
963 ! Bin densities are as follows:
964 ! 1: dust bin 1: 2500 kg/m2
965 ! 2-5: dust bin 2-5: 2650 kg/m2
966 ! 6-10: sea salt bins 6-10: 2200 kg/m2
967 ! 11: sulfate: 1700 kg/m2
968 ! 15: organic carbon: 1800 kg/m2
969
970 implicit none
971 integer, intent(in)::ncol, nlev
972 real (kind=kind_phys), dimension(:,:,:), intent(in) :: aerfld
973 real (kind=kind_phys), dimension(:,:), intent(out ):: nifa, nwfa
974
975 nifa=(aerfld(:,:,1)/4.0737762+aerfld(:,:,2)/30.459203+aerfld(:,:,3)/153.45048+ &
976 aerfld(:,:,4)/1011.5142+ aerfld(:,:,5)/5683.3501)*1.e15
977
978 nwfa=((aerfld(:,:,6)/0.0045435214+aerfld(:,:,7)/0.2907854+aerfld(:,:,8)/12.91224+ &
979 aerfld(:,:,9)/206.2216+ aerfld(:,:,10)/4326.23)*9.+aerfld(:,:,11)/0.3053104*5+ &
980 aerfld(:,:,15)/0.3232698*8)*1.e15
981 end subroutine get_niwfa
982
983end module mp_thompson
subroutine thompson_init(is_aerosol_aware_in, merra2_aerosol_aware_in, mpicomm, mpirank, mpiroot, threads, errmsg, errflg)
This subroutine calculates simplified cloud species equations and create lookup tables in Thomspson s...
subroutine mp_gt_driver(wrf_chem)
This is a wrapper routine designed to transfer values from 3D to 1D.
subroutine, public mp_thompson_run(ncol, nlev, con_g, con_rd, con_eps, convert_dry_rho, spechum, qc, qr, qi, qs, qg, ni, nr, is_aerosol_aware, merra2_aerosol_aware, nc, nwfa, nifa, nwfa2d, nifa2d, aero_ind_fdb, tgrs, prsl, phii, omega, sedi_semi, decfl, islmsk, dtp, dt_inner, first_time_step, istep, nsteps, prcp, rain, graupel, ice, snow, sr, refl_10cm, fullradar_diag, max_hail_diam_sfc, do_radar_ref, aerfld, mpicomm, mpirank, mpiroot, blkno, ext_diag, diag3d, reset_diag3d, spp_wts_mp, spp_mp, n_var_spp, spp_prt_list, spp_var_list, spp_stddev_cutoff, cplchm, pfi_lsan, pfl_lsan, errmsg, errflg)
subroutine calc_effectrad(t1d, p1d, qv1d, qc1d, nc1d, qi1d, ni1d, qs1d, re_qc1d, re_qi1d, re_qs1d, lsml, kts, kte)
Compute radiation effective radii of cloud water, ice, and snow. These are entirely consistent with m...
elemental real function, public make_icenumber(q_ice, temp)
Table of lookup values of radiative effective radius of ice crystals as a function of Temperature fro...
This module ocntains lookup tables of radiative effective radius of cloud ice, rain and water.
This module computes the moisture tendencies of water vapor, cloud droplets, rain,...
This module contains the aerosol-aware Thompson microphysics scheme.