CCPP SciDoc v7.0.x  v7.0.0
Common Community Physics Package Developed at DTC
 
Loading...
Searching...
No Matches
mp_nssl.F90
1
3
4
6
8module mp_nssl
9
10 use machine, only : kind_phys
12
13 implicit none
14
15 public :: mp_nssl_init, mp_nssl_run
16
17 private
18 logical :: is_initialized = .false.
19 logical :: missing_vars_global = .false.
20 real :: nssl_qccn
21
22 contains
23
30 subroutine mp_nssl_init(ncol, nlev, errflg, errmsg, threads, restart, &
31 fn_nml, input_nml_file, mpirank, mpiroot, &
32 mpicomm, qc, qr, qi, qs, qh, &
33 ccw, crw, cci, csw, chw, vh, &
34 con_g, con_rd, con_cp, con_rv, &
35 con_t0c, con_cliq, con_csol, con_eps, &
36 imp_physics, imp_physics_nssl, &
37 nssl_cccn, nssl_alphah, nssl_alphahl, &
38 nssl_alphar, nssl_ehw0, nssl_ehlw0, &
39 nssl_ccn_on, nssl_hail_on, nssl_invertccn, nssl_3moment )
40
41
43 use mpi_f08
44
45 implicit none
46
47 integer, intent(in) :: ncol
48 integer, intent(in) :: nlev
49 character(len=*), intent( out) :: errmsg
50 integer, intent( out) :: errflg
51 integer, intent(in) :: threads
52 logical, intent(in) :: restart
53 character(len=*), intent(in) :: fn_nml
54 character(len=*), intent(in) :: input_nml_file(:)
55 real(kind_phys), intent(in) :: con_g, con_rd, con_cp, con_rv, &
56 con_t0c, con_cliq, con_csol, con_eps
57
58 integer, intent(in) :: mpirank
59 integer, intent(in) :: mpiroot
60 type(mpi_comm), intent(in) :: mpicomm
61 integer, intent(in) :: imp_physics
62 integer, intent(in) :: imp_physics_nssl
63 real(kind_phys), intent(in) :: nssl_cccn, nssl_alphah, nssl_alphahl
64 real(kind_phys), intent(in) :: nssl_alphar, nssl_ehw0, nssl_ehlw0
65 logical, intent(in) :: nssl_ccn_on, nssl_hail_on, nssl_invertccn, nssl_3moment
66
67 real(kind_phys), intent(inout) :: qc (:,:) !(1:ncol,1:nlev)
68 real(kind_phys), intent(inout) :: qr (:,:) !(1:ncol,1:nlev)
69 real(kind_phys), intent(inout) :: qi (:,:) !(1:ncol,1:nlev)
70 real(kind_phys), intent(inout) :: qs (:,:) !(1:ncol,1:nlev)
71 real(kind_phys), intent(inout) :: qh (:,:) !(1:ncol,1:nlev) graupel
72 real(kind_phys), intent(inout) :: ccw(:,:) !(1:ncol,1:nlev)
73 real(kind_phys), intent(inout) :: crw(:,:) !(1:ncol,1:nlev)
74 real(kind_phys), intent(inout) :: cci(:,:) !(1:ncol,1:nlev)
75 real(kind_phys), intent(inout) :: csw(:,:) !(1:ncol,1:nlev)
76 real(kind_phys), intent(inout) :: chw(:,:) !(1:ncol,1:nlev) graupel number
77 real(kind_phys), intent(inout) :: vh (:,:) !(1:ncol,1:nlev) graupel volume
78
79 ! Local variables: dimensions used in nssl_init
80 integer :: ims,ime, jms,jme, kms,kme, nx, nz, i,k
81 real(kind_phys) :: nssl_params(20)
82 integer :: ihailv,ipc
83 real(kind_phys), parameter :: qmin = 1.e-12
84 integer :: ierr
85 logical :: missing_vars = .false.
86
87 ! Initialize the CCPP error handling variables
88 errflg = 0
89 errmsg = ''
90
91! write(0,*) 'nssl_init: nlev,ncol,rank = ',nlev,ncol,mpirank
92
93 if ( is_initialized ) return
94
95 IF ( .not. is_initialized ) THEN ! only do this on first call
96 if (mpirank==mpiroot) then
97 write(0,*) ' ----------------------------------------------------------------------------------------------------------------'
98 write(0,*) ' --- CCPP NSSL MP scheme init ---'
99 write(0,*) ' ----------------------------------------------------------------------------------------------------------------'
100 write(6,*) ' ----------------------------------------------------------------------------------------------------------------'
101 write(6,*) ' --- CCPP NSSL MP scheme init ---'
102 write(6,*) ' ----------------------------------------------------------------------------------------------------------------'
103 end if
104
105! update this when ccn_flag is active?
106 if ( imp_physics /= imp_physics_nssl ) then
107 write(errmsg,'(*(a))') "Logic error: namelist choice of microphysics is different from NSSL"
108 errflg = 1
109 return
110 end if
111
112 ! set some physical constants in NSSL microphysics to be consistent with parent model
114 con_g, con_rd, con_cp, con_rv, con_t0c, con_cliq, con_csol, con_eps )
115
116
117 ! Set internal dimensions
118 ims = 1
119 ime = ncol
120 nx = ncol
121 jms = 1
122 jme = 1
123 kms = 1
124 kme = nlev
125 nz = nlev
126
127
128 nssl_params(:) = 0.0
129 ! nssl_params(1) = nssl_cccn ! use direct interface instead
130 ! nssl_params(2) = nssl_alphah ! use direct interface instead
131 ! nssl_params(3) = nssl_alphahl ! use direct interface instead
132 nssl_params(4) = 4.e5 ! nssl_cnoh -- not used for 2-moment
133 nssl_params(5) = 4.e4 ! nssl_cnohl-- not used for 2-moment
134 nssl_params(6) = 4.e5 ! nssl_cnor-- not used for 2-moment
135 nssl_params(7) = 4.e6 ! nssl_cnos-- not used for 2-moment
136 nssl_params(8) = 500. ! nssl_rho_qh
137 nssl_params(9) = 800. ! nssl_rho_qhl
138 nssl_params(10) = 100. ! nssl_rho_qs
139
140 nssl_qccn = nssl_cccn/1.225
141 ! if (mpirank==mpiroot) then
142 ! write(*,*) 'nssl_init: nssl_qccn = ',nssl_qccn
143 ! endif
144
145 IF ( nssl_hail_on ) THEN
146 ihailv = 1
147 ELSE
148 ihailv = -1
149 ENDIF
150
151 IF ( nssl_3moment ) THEN
152 ipc = 8
153 ELSE
154 ipc = 5
155 ENDIF
156
157! write(0,*) 'call nssl_2mom_init'
158 CALL nssl_2mom_init(ims,ime, jms,jme, kms,kme,nssl_params,ipctmp=ipc,mixphase=0, &
159 namelist_filename=fn_nml,internal_nml=input_nml_file, &
160 ihvol=ihailv,nssl_ehw0=nssl_ehw0, &
161 nssl_ehlw0=nssl_ehlw0,errmsg=errmsg, &
162 nssl_alphar=nssl_alphar, &
163 nssl_alphah=nssl_alphah, &
164 nssl_alphahl=nssl_alphahl, &
165 nssl_cccn=nssl_cccn, &
166 nssl_ccn_on=nssl_ccn_on, &
167 errflg=errflg,myrank=mpirank,mpiroot=mpiroot)
168
169 ! For restart runs, the init is done here
170 if (restart) then
171
172 ! For restart, check if the IC is from a different scheme that does not have all the needed variables
173 missing_vars = .false.
174 IF ( any( qc > qmin .and. ccw == 0.0 ) ) missing_vars = .true.
175 IF ( .not. missing_vars .and. any( qi > qmin .and. cci == 0.0 ) ) missing_vars = .true.
176 IF ( .not. missing_vars .and. any( qs > qmin .and. csw == 0.0 ) ) missing_vars = .true.
177 IF ( .not. missing_vars .and. any( qr > qmin .and. crw == 0.0 ) ) missing_vars = .true.
178 IF ( .not. missing_vars .and. any( qh > qmin .and. (chw == 0.0 .or. vh == 0.0) ) ) missing_vars = .true.
179
180 call mpi_allreduce(missing_vars, missing_vars_global, 1, mpi_logical, mpi_lor, mpicomm, ierr)
181
182 is_initialized = .true.
183 return
184 end if
185
186! Other initialization operation here....
187
188 is_initialized = .true.
189
190 ENDIF ! .not. is_initialized
191
192 return
193
194 end subroutine mp_nssl_init
196
203 subroutine mp_nssl_run(ncol, nlev, con_g, con_rd, mpirank, &
204 spechum, cccn, cccna, qc, qr, qi, qs, qh, qhl, &
205 ccw, crw, cci, csw, chw, chl, vh, vhl, &
206 zrw, zhw, zhl, &
207 tgrs, prslk, prsl, phii, omega, dtp, &
208 prcp, rain, graupel, ice, snow, sr, &
209 refl_10cm, do_radar_ref, first_time_step, restart, &
210 re_cloud, re_ice, re_snow, re_rain, &
211 nleffr, nieffr, nseffr, nreffr, &
212 imp_physics, convert_dry_rho, &
213 imp_physics_nssl, nssl_ccn_on, &
214 nssl_hail_on, nssl_invertccn, nssl_3moment, &
215 ntccn, ntccna, &
216 errflg, errmsg)
217
218 use module_mp_nssl_2mom, only: calcnfromq, na
219
220 implicit none
221 integer, intent(in) :: ncol, nlev
222 real(kind_phys), intent(in ) :: con_g
223 real(kind_phys), intent(in ) :: con_rd
224 integer, intent(in) :: mpirank
225 ! Hydrometeors
226 logical, intent(in ) :: convert_dry_rho
227 real(kind_phys), intent(inout) :: spechum(:,:) !(1:ncol,1:nlev)
228 real(kind_phys), intent(inout), optional :: cccn(:,:) !(1:ncol,1:nlev)
229 real(kind_phys), intent(inout), optional :: cccna(:,:) !(1:ncol,1:nlev)
230 real(kind_phys), intent(inout) :: qc (:,:) !(1:ncol,1:nlev)
231 real(kind_phys), intent(inout) :: qr (:,:) !(1:ncol,1:nlev)
232 real(kind_phys), intent(inout) :: qi (:,:) !(1:ncol,1:nlev)
233 real(kind_phys), intent(inout) :: qs (:,:) !(1:ncol,1:nlev)
234 real(kind_phys), intent(inout) :: qh (:,:) !(1:ncol,1:nlev) graupel
235 real(kind_phys), intent(inout), optional :: qhl(:,:) !(1:ncol,1:nlev) hail
236 real(kind_phys), intent(inout) :: ccw(:,:) !(1:ncol,1:nlev)
237 real(kind_phys), intent(inout) :: crw(:,:) !(1:ncol,1:nlev)
238 real(kind_phys), intent(inout) :: cci(:,:) !(1:ncol,1:nlev)
239 real(kind_phys), intent(inout) :: csw(:,:) !(1:ncol,1:nlev)
240 real(kind_phys), intent(inout) :: chw(:,:) !(1:ncol,1:nlev) graupel number
241 real(kind_phys), intent(inout), optional :: chl(:,:) !(1:ncol,1:nlev) hail number
242 real(kind_phys), intent(inout) :: vh (:,:) !(1:ncol,1:nlev) graupel volume
243 real(kind_phys), intent(inout), optional :: vhl(:,:) !(1:ncol,1:nlev) hail volume
244 real(kind_phys), intent(inout), optional :: zrw(:,:) !(1:ncol,1:nlev) rain reflectivity
245 real(kind_phys), intent(inout), optional :: zhw(:,:) !(1:ncol,1:nlev) graupel reflectivity
246 real(kind_phys), intent(inout), optional :: zhl(:,:) !(1:ncol,1:nlev) hail reflectivity
247 ! State variables and timestep information
248 real(kind_phys), intent(inout) :: tgrs (:,:) !(1:ncol,1:nlev)
249 real(kind_phys), intent(in ) :: prsl (:,:) !(1:ncol,1:nlev)
250 real(kind_phys), intent(in ) :: prslk(:,:) !(1:ncol,1:nlev)
251 real(kind_phys), intent(in ) :: phii (:,:) !(1:ncol,1:nlev+1)
252 real(kind_phys), intent(in ) :: omega(:,:) !(1:ncol,1:nlev)
253 real(kind_phys), intent(in ) :: dtp
254 ! Precip/rain/snow/graupel fall amounts and fraction of frozen precip
255 real(kind_phys), intent( out) :: prcp (:) !(1:ncol)
256 real(kind_phys), intent( out) :: rain (:) !(1:ncol)
257 real(kind_phys), intent( out) :: graupel(:) !(1:ncol)
258 real(kind_phys), intent( out) :: ice (:) !(1:ncol)
259 real(kind_phys), intent( out) :: snow (:) !(1:ncol)
260 real(kind_phys), intent( out) :: sr (:) !(1:ncol)
261 ! Radar reflectivity
262 real(kind_phys), intent(inout) :: refl_10cm(:,:) !(1:ncol,1:nlev)
263 logical, intent(in ) :: do_radar_ref, first_time_step
264 logical, intent(in) :: restart
265 ! Cloud effective radii
266 real(kind_phys), intent(inout), optional :: re_cloud(:,:) ! (1:ncol,1:nlev)
267 real(kind_phys), intent(inout), optional :: re_ice(:,:) ! (1:ncol,1:nlev)
268 real(kind_phys), intent(inout), optional :: re_snow(:,:) ! (1:ncol,1:nlev)
269 real(kind_phys), intent(inout), optional :: re_rain(:,:) ! (1:ncol,1:nlev)
270 integer, intent(in) :: nleffr, nieffr, nseffr, nreffr
271 integer, intent(in) :: imp_physics
272 integer, intent(in) :: imp_physics_nssl
273 logical, intent(in) :: nssl_ccn_on, nssl_hail_on, nssl_invertccn, nssl_3moment
274 integer, intent(in) :: ntccn, ntccna
275
276 integer, intent(out) :: errflg
277 character(len=*), intent(out) :: errmsg
278
279
280 ! Local variables
281
282 ! Air density
283 real(kind_phys) :: rho(1:ncol,1:nlev)
284 ! Hydrometeors
285 real(kind_phys) :: qv_mp(1:ncol,1:nlev)
286 real(kind_phys) :: qc_mp(1:ncol,1:nlev)
287 real(kind_phys) :: qr_mp(1:ncol,1:nlev)
288 real(kind_phys) :: qi_mp(1:ncol,1:nlev)
289 real(kind_phys) :: qs_mp(1:ncol,1:nlev)
290 real(kind_phys) :: qh_mp(1:ncol,1:nlev)
291 real(kind_phys) :: qhl_mp(1:ncol,1:nlev)
292 real(kind_phys) :: nc_mp(1:ncol,1:nlev)
293 real(kind_phys) :: nr_mp(1:ncol,1:nlev)
294 real(kind_phys) :: ni_mp(1:ncol,1:nlev)
295 real(kind_phys) :: ns_mp(1:ncol,1:nlev)
296 real(kind_phys) :: nh_mp(1:ncol,1:nlev)
297 real(kind_phys) :: nhl_mp(1:ncol,1:nlev)
298 real(kind_phys) :: cn_mp(1:ncol,1:nlev)
299 real(kind_phys) :: cna_mp(1:ncol,1:nlev)
300 real(kind_phys) :: cccn_mp(1:ncol,1:nlev)
301 real(kind_phys) :: cccna_mp(1:ncol,1:nlev)
302 real(kind_phys) :: vh_mp(1:ncol,1:nlev)
303 ! create temporaries for hail in case it does not exist
304 !real(kind_phys) :: chl_mp(1:ncol,1:nlev) !< kg-1 (number mixing ratio)
305 real(kind_phys) :: vhl_mp(1:ncol,1:nlev)
306 real(kind_phys) :: zrw_mp(1:ncol,1:nlev)
307 real(kind_phys) :: zhw_mp(1:ncol,1:nlev)
308 real(kind_phys) :: zhl_mp(1:ncol,1:nlev)
309 ! Vertical velocity and level width
310 real(kind_phys) :: w(1:ncol,1:nlev)
311 real(kind_phys) :: dz(1:ncol,1:nlev)
312
313 ! Rain/snow/graupel fall amounts
314 real(kind_phys) :: rain_mp(1:ncol) ! mm, dummy, not used
315 real(kind_phys) :: graupel_mp(1:ncol) ! mm, dummy, not used
316 real(kind_phys) :: ice_mp(1:ncol) ! mm, dummy, not used
317 real(kind_phys) :: snow_mp(1:ncol) ! mm, dummy, not used
318 real(kind_phys) :: delta_rain_mp(1:ncol) ! mm
319 real(kind_phys) :: delta_graupel_mp(1:ncol) ! mm
320 real(kind_phys) :: delta_ice_mp(1:ncol) ! mm
321 real(kind_phys) :: delta_snow_mp(1:ncol) ! mm
322
323 real(kind_phys) :: xrain_mp(1:ncol) ! mm, dummy, not used
324 real(kind_phys) :: xgraupel_mp(1:ncol) ! mm, dummy, not used
325 real(kind_phys) :: xice_mp(1:ncol) ! mm, dummy, not used
326 real(kind_phys) :: xsnow_mp(1:ncol) ! mm, dummy, not used
327 real(kind_phys) :: xdelta_rain_mp(1:ncol) ! mm
328 real(kind_phys) :: xdelta_graupel_mp(1:ncol) ! mm
329 real(kind_phys) :: xdelta_ice_mp(1:ncol) ! mm
330 real(kind_phys) :: xdelta_snow_mp(1:ncol) ! mm
331
332 ! Radar reflectivity
333 logical :: diagflag ! must be true if do_radar_ref is true, not used otherwise
334 integer :: do_radar_ref_mp ! integer instead of logical do_radar_ref
335 ! Effective cloud radii
336 logical :: do_effective_radii
337 real(kind_phys) :: re_cloud_mp(1:ncol,1:nlev) ! m
338 real(kind_phys) :: re_ice_mp(1:ncol,1:nlev) ! m
339 real(kind_phys) :: re_snow_mp(1:ncol,1:nlev) ! m
340 real(kind_phys) :: re_rain_mp(1:ncol,1:nlev) ! m
341 integer :: has_reqc
342 integer :: has_reqi
343 integer :: has_reqs
344 integer :: has_reqr
345 ! Dimensions used in driver
346 integer :: ids,ide, jds,jde, kds,kde, &
347 ims,ime, jms,jme, kms,kme, &
348 its,ite, jts,jte, kts,kte, i,j,k
349 integer :: itimestep ! timestep counter
350 integer :: ntmul, n
351 real(kind_phys), parameter :: dtpmax = 60. ! allow up to dt=75 (1.25*60)
352 real(kind_phys) :: dtptmp
353 integer, parameter :: ndebug = 0
354 logical :: invertccn
355 real(kind_phys) :: cwmas
356
357 real(kind_phys), allocatable :: an(:,:,:,:) ! temporary scalar array
358
359
360
361 errflg = 0
362 errmsg = ''
363
364! write(0,*) 'nssl_run: nlev,ncol,rank = ',nlev,ncol,mpirank
365
366 IF ( ndebug >= 1 ) write(0,*) 'In physics nssl_run'
367
368
369 ! Check initialization state
370 if (.not.is_initialized) then
371 write(errmsg, fmt='((a))') 'mp_nssl_run called before mp_nssl_init'
372 errflg = 1
373 return
374 end if
375
376 invertccn = nssl_invertccn
377
379 ! NOTE: Implied loops!
380 qv_mp = spechum/(1.0_kind_phys-spechum)
381 IF ( convert_dry_rho ) THEN
382 qc_mp = qc/(1.0_kind_phys-spechum)
383 qr_mp = qr/(1.0_kind_phys-spechum)
384 qi_mp = qi/(1.0_kind_phys-spechum)
385 qs_mp = qs/(1.0_kind_phys-spechum)
386 qh_mp = qh/(1.0_kind_phys-spechum)
387
388 IF ( nssl_ccn_on ) cccn_mp = cccn/(1.0_kind_phys-spechum)
389! cccna_mp = cccna/(1.0_kind_phys-spechum)
390 nc_mp = ccw/(1.0_kind_phys-spechum)
391 nr_mp = crw/(1.0_kind_phys-spechum)
392 ni_mp = cci/(1.0_kind_phys-spechum)
393 ns_mp = csw/(1.0_kind_phys-spechum)
394 nh_mp = chw/(1.0_kind_phys-spechum)
395 vh_mp = vh/(1.0_kind_phys-spechum)
396 IF ( nssl_3moment ) THEN
397 zrw_mp = zrw/(1.0_kind_phys-spechum)
398 zhw_mp = zhw/(1.0_kind_phys-spechum)
399 ENDIF
400 IF ( nssl_hail_on ) THEN
401 qhl_mp = qhl/(1.0_kind_phys-spechum)
402 nhl_mp = chl/(1.0_kind_phys-spechum)
403 vhl_mp = vhl/(1.0_kind_phys-spechum)
404 IF ( nssl_3moment ) THEN
405 zhl_mp = zhl/(1.0_kind_phys-spechum)
406 ENDIF
407 ENDIF
408 ELSE
409! qv_mp = spechum ! /(1.0_kind_phys-spechum)
410 qc_mp = qc ! /(1.0_kind_phys-spechum)
411 qr_mp = qr ! /(1.0_kind_phys-spechum)
412 qi_mp = qi ! /(1.0_kind_phys-spechum)
413 qs_mp = qs ! /(1.0_kind_phys-spechum)
414 qh_mp = qh ! /(1.0_kind_phys-spechum)
415 IF ( nssl_ccn_on ) cccn_mp = cccn
416! cccna_mp = cccna
417 nc_mp = ccw
418 nr_mp = crw
419 ni_mp = cci
420 ns_mp = csw
421 nh_mp = chw
422 vh_mp = vh
423 IF ( nssl_3moment ) THEN
424 zrw_mp = zrw
425 zhw_mp = zhw
426 ENDIF
427 IF ( nssl_hail_on ) THEN
428 qhl_mp = qhl ! /(1.0_kind_phys-spechum)
429 nhl_mp = chl
430 vhl_mp = vhl
431 IF ( nssl_3moment ) THEN
432 zhl_mp = zhl
433 ENDIF
434 ENDIF
435
436 ENDIF
437
438 IF ( nssl_hail_on ) THEN
439! nhl_mp = chl
440! vhl_mp = vhl
441 ELSE
442 qhl_mp = 0
443 nhl_mp = 0
444 vhl_mp = 0
445 ENDIF
446
447 IF ( .false. ) THEN
448 write(6,*) 'nsslrun: qc,max ccw = ',mpirank,maxval(qc_mp),maxval(nc_mp),sum(nc_mp)
449 IF ( mpirank == 1 ) THEN
450 DO k=1,nlev
451 DO i=1,ncol
452 IF ( qc_mp(i,k) > 1.e-6 .and. nc_mp(i,k) <= 1.e-9 ) THEN
453 write(6,*) 'i,k,qc,nc,ccn = ',i,k,qc_mp(i,k),nc_mp(i,k),cccn_mp(i,k)
454 ENDIF
455 ENDDO
456 ENDDO
457 ENDIF
458 ENDIF
459
460 ! IF ( first_time_step ) THEN
461 ! write(0,*) 'mp_nssl_run: qi,qs,qh maxval: ',maxval(qi),maxval(qs),maxval(qh)
462 ! write(0,*) 'mp_nssl_run: ni,ns,nh maxval: ',maxval(ni_mp),maxval(ns_mp),maxval(nh_mp)
463 ! ENDIF
464
465
467 rho = prsl/(con_rd*tgrs)
468
470 w = -omega/(rho*con_g)
471
473 dz = (phii(:,2:nlev+1) - phii(:,1:nlev)) / con_g
474
475 ! Accumulated values inside scheme, not used;
476 ! only use delta and add to inout variables (different units)
477 rain_mp = 0
478 graupel_mp = 0
479 ice_mp = 0
480 snow_mp = 0
481 delta_rain_mp = 0
482 delta_graupel_mp = 0
483 delta_ice_mp = 0
484 delta_snow_mp = 0
485 xrain_mp = 0
486 xgraupel_mp = 0
487 xice_mp = 0
488 xsnow_mp = 0
489 xdelta_rain_mp = 0
490 xdelta_graupel_mp = 0
491 xdelta_ice_mp = 0
492 xdelta_snow_mp = 0
493 IF ( ndebug > 1 ) THEN
494 write(*,*) 'Max q before micro'
495 write(*,*) 'qc = ',1000.*maxval(qc_mp)
496 write(*,*) 'qr = ',1000.*maxval(qr_mp)
497 write(*,*) 'qi = ',1000.*maxval(qi_mp)
498 write(*,*) 'qs = ',1000.*maxval(qs_mp)
499 write(*,*) 'qh = ',1000.*maxval(qh_mp)
500 IF ( nssl_hail_on ) write(*,*) 'qhl = ',1000.*maxval(qhl_mp)
501 write(*,*) 'ccw = ',1.e-6*maxval(ccw*rho)
502 ENDIF
503
504 ! Flags for calculating radar reflectivity; diagflag is redundant
505 if (do_radar_ref) then
506 diagflag = .true.
507 do_radar_ref_mp = 1
508 else
509 diagflag = .false.
510 do_radar_ref_mp = 0
511 end if
512
513 do_effective_radii = .false.
514 IF ( nleffr > 0 .and. nieffr > 0 .and. nseffr > 0 .and. nreffr > 0 ) THEN
515 ! if (present(re_cloud) .and. present(re_ice) .and. present(re_snow)) then
516 do_effective_radii = .true.
517 has_reqc = 1
518 has_reqi = 1
519 has_reqs = 1
520 has_reqr = 1
521 else if (nleffr < 1 .and. nieffr < 1 .and. nseffr < 1 .and. nreffr < 1 ) then
522 do_effective_radii = .false.
523 has_reqc = 0
524 has_reqi = 0
525 has_reqs = 0
526 has_reqr = 0
527 else
528 write(errmsg,fmt='(*(a))') 'Logic error in mp_nssl_run:', &
529 ' hydrometeor radius calculation logic problem'
530 errflg = 1
531 return
532 end if
533 ! Initialize to zero, intent(out) variables
534 re_cloud_mp = 0
535 re_ice_mp = 0
536 re_snow_mp = 0
537 re_rain_mp = 0
538
539 ! Set internal dimensions
540 ids = 1
541 ims = 1
542 its = 1
543 ide = ncol
544 ime = ncol
545 ite = ncol
546 jds = 1
547 jms = 1
548 jts = 1
549 jde = 1
550 jme = 1
551 jte = 1
552 kds = 1
553 kms = 1
554 kts = 1
555 kde = nlev
556 kme = nlev
557 kte = nlev
558
559
560 IF ( ndebug >= 1 ) write(0,*) 'call nssl_2mom_driver'
561
562 IF ( dtp > 1.25001*dtpmax ) THEN
563 ntmul = max(2, nint( dtp/dtpmax ) )
564 dtptmp = dtp/ntmul
565 ELSE
566 dtptmp = dtp
567 ntmul = 1
568 ENDIF
569
570 IF ( first_time_step .and. ( .not. restart .or. missing_vars_global ) ) THEN
571 itimestep = 0 ! gets incremented to 1 in call loop
572 IF ( nssl_ccn_on ) THEN
573 IF ( invertccn ) THEN
574 cccn_mp = 0
575 !cccn = nssl_qccn
576 ELSE
577 cccn_mp = nssl_qccn
578 ENDIF
579 ENDIF
580 ELSE
581 itimestep = 2
582 ENDIF
583
584 IF ( .false. ) THEN ! disable for now, as logic in the NSSL driver does this, but may switch back to here
585 ! incoming droplet field may have some inconsistent number concentrations (e.g., from PBL)
586 ! so check for that, otherwise mass may be zapped into vapor
587 allocate( an(ncol,1,nlev,na) )
588 an(:,:,:,:) = 0.0 ! needed for workspace in routine
589
590 cwmas = 1000.*0.523599*(2.*9.e-6)**3
591
592 call calcnfromq(nx=ncol,ny=1,nz=nlev,an=an,na=na,nor=0,norz=0,dn=rho, &
593 & qcw=qc_mp,qci=qi_mp, &
594 & ccw=nc_mp,cci=ni_mp, &
595 & cccn=cccn_mp,qv=qv_mp, invertccn_flag=nssl_invertccn, cwmasin=cwmas )
596
597 IF ( .false. ) THEN
598 write(6,*) 'nsslrun2: qc,max ccw = ',mpirank,maxval(qc_mp),maxval(nc_mp),sum(nc_mp)
599 IF ( mpirank == 1 ) THEN
600 DO k=1,nlev
601 DO i=1,ncol
602 IF ( qc_mp(i,k) > 1.e-6 .and. nc_mp(i,k) <= 1.e-9 ) THEN
603 write(6,*) 'i2,k,qc,nc,ccn = ',i,k,qc_mp(i,k),nc_mp(i,k),cccn_mp(i,k)
604 ENDIF
605 ENDDO
606 ENDDO
607 ENDIF
608 ENDIF
609
610
611 deallocate( an )
612 ENDIF
613
614 IF ( nssl_ccn_on ) THEN
615 IF ( invertccn ) THEN
616 ! cn_mp = Max(0.0, nssl_qccn - Max(0.0,cccn_mp))
617 ! Flip CCN concentrations from 'activated' to 'unactivated' (allows BC condition to be zero)
618 cn_mp = nssl_qccn - cccn_mp
619 cn_mp = max(0.0_kind_phys, cn_mp)
620
621 ELSE
622 cn_mp = cccn_mp
623 ENDIF
624 IF ( ntccna > 0 ) THEN
625 ! not in use yet
626! cna_mp = cccna
627 ELSE
628 cna_mp = 0
629 ENDIF
630 ENDIF
631
632 IF ( .true. ) THEN
633 DO n = 1,ntmul
634
635 itimestep = itimestep + 1
636
637
638
639 IF ( nssl_ccn_on ) THEN
640
641 CALL nssl_2mom_driver( &
642 itimestep=itimestep, &
643 ! TH=th, &
644 tt=tgrs, &
645 qv=qv_mp, &
646 qc=qc_mp, &
647 qr=qr_mp, &
648 qi=qi_mp, &
649 qs=qs_mp, &
650 qh=qh_mp, &
651 qhl=qhl_mp, &
652 ccw=nc_mp, &
653 crw=nr_mp, &
654 cci=ni_mp, &
655 csw=ns_mp, &
656 chw=nh_mp, &
657 chl=nhl_mp, &
658 vhw=vh_mp, &
659 vhl=vhl_mp, &
660 cn=cn_mp, &
661 zrw=zrw_mp, &
662 zhw=zhw_mp, &
663 zhl=zhl_mp, &
664! cna=cna_mp, f_cna=( ntccna > 0 ), & ! for future use
665 cna=cna_mp, f_cna=.false. , &
666 pii=prslk, &
667 p=prsl, &
668 w=w, &
669 dz=dz, &
670 dtp=dtptmp, &
671 dn=rho, &
672 rainnc=xrain_mp, rainncv=xdelta_rain_mp, &
673 snownc=xsnow_mp, snowncv=xdelta_snow_mp, &
674 grplnc=xgraupel_mp, &
675 grplncv=xdelta_graupel_mp, &
676 sr=sr, &
677 dbz = refl_10cm, &
678 diagflag = diagflag, &
679 errmsg=errmsg,errflg=errflg, &
680 re_cloud=re_cloud_mp, &
681 re_ice=re_ice_mp, &
682 re_snow=re_snow_mp, &
683 re_rain=re_rain_mp, &
684 has_reqc=has_reqc, &
685 has_reqi=has_reqi, &
686 has_reqs=has_reqs, &
687 has_reqr=has_reqr, &
688 ids=ids,ide=ide, jds=jds,jde=jde, kds=kds,kde=kde, &
689 ims=ims,ime=ime, jms=jms,jme=jme, kms=kms,kme=kme, &
690 its=its,ite=ite, jts=jts,jte=jte, kts=kts,kte=kte &
691 )
692
693 ELSE
694
695 CALL nssl_2mom_driver( &
696 itimestep=itimestep, &
697 ! TH=th, &
698 tt=tgrs, &
699 qv=qv_mp, &
700 qc=qc_mp, &
701 qr=qr_mp, &
702 qi=qi_mp, &
703 qs=qs_mp, &
704 qh=qh_mp, &
705 qhl=qhl_mp, &
706 ccw=nc_mp, &
707 crw=nr_mp, &
708 cci=ni_mp, &
709 csw=ns_mp, &
710 chw=nh_mp, &
711 chl=nhl_mp, &
712 vhw=vh_mp, &
713 vhl=vhl_mp, &
714! cn=cn_mp, &
715 zrw=zrw_mp, &
716 zhw=zhw_mp, &
717 zhl=zhl_mp, &
718! cna=cna_mp, f_cna=( ntccna > 0 ), & ! for future use
719! cna=cna_mp, f_cna=.false. , &
720 pii=prslk, &
721 p=prsl, &
722 w=w, &
723 dz=dz, &
724 dtp=dtptmp, &
725 dn=rho, &
726 rainnc=xrain_mp, rainncv=xdelta_rain_mp, &
727 snownc=xsnow_mp, snowncv=xdelta_snow_mp, &
728 grplnc=xgraupel_mp, &
729 grplncv=xdelta_graupel_mp, &
730 sr=sr, &
731 dbz = refl_10cm, &
732 diagflag = diagflag, &
733 errmsg=errmsg,errflg=errflg, &
734 re_cloud=re_cloud_mp, &
735 re_ice=re_ice_mp, &
736 re_snow=re_snow_mp, &
737 re_rain=re_rain_mp, &
738 has_reqc=has_reqc, &
739 has_reqi=has_reqi, &
740 has_reqs=has_reqs, &
741 has_reqr=has_reqr, &
742 ids=ids,ide=ide, jds=jds,jde=jde, kds=kds,kde=kde, &
743 ims=ims,ime=ime, jms=jms,jme=jme, kms=kms,kme=kme, &
744 its=its,ite=ite, jts=jts,jte=jte, kts=kts,kte=kte &
745 )
746
747 ENDIF
748
749 DO i = 1,ncol
750 delta_rain_mp(i) = delta_rain_mp(i) + xdelta_rain_mp(i) ! this is liquid equivalent of all precip
751 delta_graupel_mp(i) = delta_graupel_mp(i) + xdelta_graupel_mp(i) ! this is liquid equivalent of graupel
752 delta_ice_mp(i) = delta_ice_mp(i) + xdelta_ice_mp(i)
753 delta_snow_mp(i) = delta_snow_mp(i) + xdelta_snow_mp(i)
754 ENDDO
755
756 ENDDO
757
758 ENDIF
759
760
761 IF ( nssl_ccn_on ) THEN
762 IF ( invertccn ) THEN
763 cccn_mp = max(0.0_kind_phys, nssl_qccn - cn_mp )
764! cccn_mp = nssl_qccn - cn_mp
765 ELSE
766 cccn_mp = cn_mp
767 ENDIF
768! cccna = cna_mp ! cna not in use yet for ccpp
769 ENDIF
770
771! test code
772! IF ( ntccna > 1 .and. do_effective_radii ) THEN
773! cccna = re_ice_mp*1.0E6_kind_phys
774! ENDIF
775
776 IF ( ndebug > 1 ) write(0,*) 'done nssl_2mom_driver'
777
778 if (errflg/=0) return
779
780 IF ( ndebug > 1 ) THEN
781 write(*,*) 'Max q after micro'
782 write(*,*) 'qc = ',1000.*maxval(qc_mp)
783 write(*,*) 'qr = ',1000.*maxval(qr_mp)
784 write(*,*) 'qi = ',1000.*maxval(qi_mp)
785 write(*,*) 'qs = ',1000.*maxval(qs_mp)
786 write(*,*) 'qh = ',1000.*maxval(qh_mp)
787 IF ( nssl_hail_on ) THEN
788 write(*,*) 'qhl = ',1000.*maxval(qhl_mp)
789 ENDIF
790 write(*,*) 'ccw = ',1.e-6*maxval(ccw*rho)
791 IF ( 1000.*maxval(qc_mp) > 0.5 .or. 1000.*maxval(qi_mp) > 0.09 .or. 1000.*maxval(qs_mp) > 0.1 ) THEN
792 IF ( nssl_ccn_on ) THEN
793 write(*,*) 'qc, ccn, ccw, tt, qi+qs by height'
794 DO k = 1,nlev
795 write(*,*) qc_mp(1,k)*1000., cccn(1,k)*rho(1,k)*1.e-6, ccw(1,k)*rho(1,k)*1.e-6, tgrs(1,k), (qs_mp(1,k)+qi_mp(1,k))*1000. ! cccn(1,k)*1.e-6
796 ENDDO
797 ELSE
798 write(*,*) 'qc, ccn, ccw, tt, qi+qs by height'
799 DO k = 1,nlev
800 write(*,*) qc_mp(1,k)*1000., cccn(1,k)*rho(1,k)*1.e-6, 0.0, tgrs(1,k), (qs_mp(1,k)+qi_mp(1,k))*1000. ! cccn(1,k)*1.e-6
801 ENDDO
802 ENDIF
803 ENDIF
804 ENDIF
805
806
808 spechum = qv_mp/(1.0_kind_phys+qv_mp)
809 IF ( convert_dry_rho ) THEN
810 qc = qc_mp/(1.0_kind_phys+qv_mp)
811 qr = qr_mp/(1.0_kind_phys+qv_mp)
812 qi = qi_mp/(1.0_kind_phys+qv_mp)
813 qs = qs_mp/(1.0_kind_phys+qv_mp)
814 qh = qh_mp/(1.0_kind_phys+qv_mp)
815 IF ( nssl_ccn_on ) cccn = cccn_mp/(1.0_kind_phys+qv_mp)
816! cccna = cccna_mp/(1.0_kind_phys+qv_mp)
817 ccw = nc_mp/(1.0_kind_phys+qv_mp)
818 crw = nr_mp/(1.0_kind_phys+qv_mp)
819 cci = ni_mp/(1.0_kind_phys+qv_mp)
820 csw = ns_mp/(1.0_kind_phys+qv_mp)
821 chw = nh_mp/(1.0_kind_phys+qv_mp)
822 vh = vh_mp/(1.0_kind_phys+qv_mp)
823 IF ( nssl_3moment ) THEN
824 zrw = zrw_mp/(1.0_kind_phys+qv_mp)
825 zhw = zhw_mp/(1.0_kind_phys+qv_mp)
826 ENDIF
827 IF ( nssl_hail_on ) THEN
828 qhl = qhl_mp/(1.0_kind_phys+qv_mp)
829 chl = nhl_mp/(1.0_kind_phys+qv_mp)
830 vhl = vhl_mp/(1.0_kind_phys+qv_mp)
831 IF ( nssl_3moment ) THEN
832 zhl = zhl_mp/(1.0_kind_phys+qv_mp)
833 ENDIF
834 ENDIF
835 ELSE
836! spechum = qv_mp ! /(1.0_kind_phys+qv_mp)
837 qc = qc_mp ! /(1.0_kind_phys+qv_mp)
838 qr = qr_mp ! /(1.0_kind_phys+qv_mp)
839 qi = qi_mp ! /(1.0_kind_phys+qv_mp)
840 qs = qs_mp ! /(1.0_kind_phys+qv_mp)
841 qh = qh_mp ! /(1.0_kind_phys+qv_mp)
842 IF ( nssl_ccn_on ) cccn = cccn_mp
843! cccna = cccna_mp
844 ccw = nc_mp
845 crw = nr_mp
846 cci = ni_mp
847 csw = ns_mp
848 chw = nh_mp
849 vh = vh_mp
850 IF ( nssl_3moment ) THEN
851 zrw = zrw_mp
852 zhw = zhw_mp
853 ENDIF
854 IF ( nssl_hail_on ) THEN
855 qhl = qhl_mp ! /(1.0_kind_phys+qv_mp)
856 chl = nhl_mp
857 vhl = vhl_mp
858 IF ( nssl_3moment ) THEN
859 zhl = zhl_mp
860 ENDIF
861 ENDIF
862
863 ENDIF
864
865! write(0,*) 'mp_nssl: done q'
866
868 ! "rain" in NSSL MP refers to precipitation (total of liquid rainfall+snow+graupel+ice)
869
870 prcp = max(0.0, delta_rain_mp/1000.0_kind_phys)
871 graupel = max(0.0, delta_graupel_mp/1000.0_kind_phys)
872 ice = max(0.0, delta_ice_mp/1000.0_kind_phys)
873 snow = max(0.0, delta_snow_mp/1000.0_kind_phys)
874 rain = max(0.0, (delta_rain_mp - (delta_graupel_mp + delta_ice_mp + delta_snow_mp))/1000.0_kind_phys)
875
876! write(0,*) 'mp_nssl: done precip'
877
878 if (do_effective_radii) then
879 ! Convert m to micron
880 re_cloud = re_cloud_mp*1.0e6_kind_phys
881 re_ice = re_ice_mp*1.0e6_kind_phys
882 re_snow = re_snow_mp*1.0e6_kind_phys
883 re_rain = re_rain_mp*1.0e6_kind_phys
884 end if
885
886 IF ( ndebug >= 1 ) write(0,*) 'mp_nssl: end'
887
888 end subroutine mp_nssl_run
890
891end module mp_nssl
subroutine, public calcnfromq(nx, ny, nz, an, na, nor, norz, dn, qcw, qci, qsw, qrw, qhw, qhl, ccw, cci, csw, crw, chw, chl, cccn, cccna, vhw, vhl, qv, spechum, invertccn_flag, cwmasin)
Subroutine to calculate number concentrations from initial state that has only mixing ratio.
subroutine, public nssl_2mom_init(ims, ime, jms, jme, kms, kme, nssl_params, ipctmp, mixphase, ihvol, idoniconlytmp, namelist_filename, internal_nml, nssl_graupelfallfac, nssl_hailfallfac, nssl_ehw0, nssl_ehlw0, nssl_icdx, nssl_icdxhl, nssl_icefallfac, nssl_snowfallfac, nssl_cccn, nssl_ufccn, nssl_alphah, nssl_alphahl, nssl_alphar, nssl_density_on, nssl_hail_on, nssl_ccn_on, nssl_icecrystals_on, ccn_is_ccna, nssl_ccn_opt, errmsg, errflg, infileunit, myrank, mpiroot)
NSSL MP setup routine (sets local options and array indices)
subroutine, public nssl_2mom_init_const(con_g, con_rd, con_cp, con_rv, con_t0c, con_cliq, con_csol, con_eps)
NSSL MP subroutine to initialize physical constants provided by host model.
subroutine, public nssl_2mom_driver(qv, qc, qr, qi, qs, qh, qhl, ccw, crw, cci, csw, chw, chl, cn, vhw, vhl, cna, cni, f_cn, f_cna, f_cina, f_qc, f_qr, f_qi, f_qs, f_qh, f_qhl, cn_nu, cn_co, cinp, f_cnnu, f_cnco, f_cinp, cna_co, cna_nu, f_cnaco, f_cnanu, cnuf, f_cnuf, cn_ac, f_cnac, zrw, zhw, zhl, f_zrw, f_zhw, f_zhl, f_vhw, f_vhl, qsw, qhw, qhlw, tt, th, pii, p, w, dn, dz, dtp, itimestep, is_theta_or_temp, ntmul, ntcnt, lastloop, rainnc, rainncv, dx, dy, axtra, snownc, snowncv, grplnc, grplncv, sr, hailnc, hailncv, hail_maxk1, hail_max2d, nwp_diagnostics, tkediss, re_cloud, re_ice, re_snow, re_rain, re_graup, re_hail, has_reqc, has_reqi, has_reqs, has_reqr, has_reqg, has_reqh, rainncw2, rainnci2, dbz, vzf, compdbz, rscghis_2d, rscghis_2dp, rscghis_2dn, scr, scw, sci, scs, sch, schl, sctot, elec_physics, induc, elecz, scion, sciona, f_scion, f_sciona, noninduc, noninducp, noninducn, ssat3d, ssati, nssl_ssat_output, pcc2, pre2, depsubr, mnucf2, melr2, ctr2, rim1_2, rim2_2, rim3_2, nctr2, nnuccd2, nnucf2, effc2, effr2, effi2, effs2, effg2, fc2, fr2, fi2, fs2, fg2, fnc2, fnr2, fni2, fns2, fng2, ipelectmp, isedonly_in, diagflag, ke_diag, errmsg, errflg, nssl_progn, wetscav_on, rainprod, evapprod, cu_used, qrcuten, qscuten, qicuten, qccuten, ids, ide, jds, jde, kds, kde, ims, ime, jms, jme, kms, kme, its, ite, jts, jte, kts, kte)
Driver subroutine that copies state data to local 2D arrays for microphysics calls.
subroutine, public mp_nssl_init(ncol, nlev, errflg, errmsg, threads, restart, fn_nml, input_nml_file, mpirank, mpiroot, mpicomm, qc, qr, qi, qs, qh, ccw, crw, cci, csw, chw, vh, con_g, con_rd, con_cp, con_rv, con_t0c, con_cliq, con_csol, con_eps, imp_physics, imp_physics_nssl, nssl_cccn, nssl_alphah, nssl_alphahl, nssl_alphar, nssl_ehw0, nssl_ehlw0, nssl_ccn_on, nssl_hail_on, nssl_invertccn, nssl_3moment)
This subroutine is a wrapper around the nssl_2mom_init().
Definition mp_nssl.F90:40
subroutine, public mp_nssl_run(ncol, nlev, con_g, con_rd, mpirank, spechum, cccn, cccna, qc, qr, qi, qs, qh, qhl, ccw, crw, cci, csw, chw, chl, vh, vhl, zrw, zhw, zhl, tgrs, prslk, prsl, phii, omega, dtp, prcp, rain, graupel, ice, snow, sr, refl_10cm, do_radar_ref, first_time_step, restart, re_cloud, re_ice, re_snow, re_rain, nleffr, nieffr, nseffr, nreffr, imp_physics, convert_dry_rho, imp_physics_nssl, nssl_ccn_on, nssl_hail_on, nssl_invertccn, nssl_3moment, ntccn, ntccna, errflg, errmsg)
Definition mp_nssl.F90:217
This module contains 1/2/3-moment bulk microphysics scheme based on a combination of Straka and Manse...
This module contains the front end to NSSL microphysics scheme.
Definition mp_nssl.F90:8