-
Notifications
You must be signed in to change notification settings - Fork 35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tempo microphysics to CCPP #245
base: ufs/dev
Are you sure you want to change the base?
Changes from all commits
aec5804
6a39cb8
a11085b
fe8b6da
dbe9774
41d2030
576da96
9c67aae
630122b
4d3e724
b9be2d9
a5981bc
3d92c8d
6f8c3eb
83fd7be
f743cdb
0b13e50
35aaeab
0f15c7c
be684f0
2f44810
7931eec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,6 +26,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& | |
ntdu1, ntdu2, ntdu3, ntdu4, ntdu5, ntss1, ntss2, & | ||
ntss3, ntss4, ntss5, ntsu, ntbcb, ntbcl, ntocb, ntocl, ntchm, & | ||
imp_physics,imp_physics_nssl, nssl_ccn_on, nssl_invertccn, & | ||
imp_physics_tempo, & | ||
imp_physics_thompson, imp_physics_gfdl, imp_physics_zhao_carr, & | ||
imp_physics_zhao_carr_pdf, imp_physics_mg, imp_physics_wsm6, & | ||
imp_physics_fer_hires, iovr, iovr_rand, iovr_maxrand, iovr_max, & | ||
|
@@ -45,7 +46,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& | |
gasvmr_ccl4, gasvmr_cfc113, aerodp,ext550, clouds6, clouds7, clouds8, & | ||
clouds9, cldsa, cldfra, cldfra2d, lwp_ex,iwp_ex, lwp_fc,iwp_fc, & | ||
faersw1, faersw2, faersw3, faerlw1, faerlw2, faerlw3, alpha, rrfs_sd, & | ||
aero_dir_fdb, fdb_coef, spp_wts_rad, spp_rad, ico2, ozphys, & | ||
aero_dir_fdb, fdb_coef, spp_wts_rad, spp_rad, ico2, ozphys, tempo_cfg, & | ||
errmsg, errflg) | ||
|
||
use machine, only: kind_phys | ||
|
@@ -72,15 +73,37 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& | |
use surface_perturbation, only: cdfnor,ppfbet | ||
|
||
! For Thompson MP | ||
use module_mp_thompson, only: calc_effectRad, & | ||
Nt_c_l, Nt_c_o, & | ||
re_qc_min, re_qc_max, & | ||
re_qi_min, re_qi_max, & | ||
re_qs_min, re_qs_max | ||
use module_mp_thompson, only: calc_effectRad_thmpsn => calc_effectRad, & | ||
Nt_c_l_thmpsn => Nt_c_l, & | ||
Nt_c_o_thmpsn => Nt_c_o, & | ||
re_qc_min_thmpsn => re_qc_min, & | ||
re_qc_max_thmpsn => re_qc_max, & | ||
re_qi_min_thmpsn => re_qi_min, & | ||
re_qi_max_thmpsn => re_qi_max, & | ||
re_qs_min_thmpsn => re_qs_min, & | ||
re_qs_max_thmpsn => re_qs_max | ||
use module_mp_thompson_make_number_concentrations, only: & | ||
make_IceNumber, & | ||
make_DropletNumber, & | ||
make_RainNumber | ||
make_IceNumber_thmpsn => make_IceNumber, & | ||
make_DropletNumber_thmpsn => make_DropletNumber, & | ||
make_RainNumber_thmpsn => make_RainNumber | ||
|
||
! For TEMPO MP | ||
! DJS to Anders: Change from Thompson -> TEMPO in submodule, propogate change here. | ||
use module_mp_tempo_params, only: Nt_c_l_tempo => Nt_c_l, & | ||
Nt_c_o_tempo => Nt_c_o, & | ||
re_qc_min_tempo => re_qc_min, & | ||
re_qc_max_tempo => re_qc_max, & | ||
re_qi_min_tempo => re_qi_min, & | ||
re_qi_max_tempo => re_qi_max, & | ||
re_qs_min_tempo => re_qs_min, & | ||
re_qs_max_tempo => re_qs_max | ||
use module_mp_tempo_utils, only: calc_effectRad_tempo => calc_effectRad, & | ||
make_IceNumber_tempo => make_IceNumber, & | ||
make_DropletNumber_tempo => make_DropletNumber, & | ||
make_RainNumber_tempo => make_RainNumber | ||
|
||
use module_mp_tempo_params, only: ty_tempo_cfg | ||
|
||
! For NRL Ozone | ||
use module_ozphys, only: ty_ozphys | ||
implicit none | ||
|
@@ -98,6 +121,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& | |
lndp_type, & | ||
kdt, imp_physics, & | ||
imp_physics_thompson, & | ||
imp_physics_tempo, & | ||
imp_physics_gfdl, & | ||
imp_physics_zhao_carr, & | ||
imp_physics_zhao_carr_pdf, & | ||
|
@@ -233,7 +257,9 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& | |
qv_mp, qc_mp, qi_mp, qs_mp, & | ||
nc_mp, ni_mp, nwfa | ||
real (kind=kind_phys), dimension(lm) :: cldfra1d, qv1d, & | ||
& qc1d, qi1d, qs1d, dz1d, p1d, t1d | ||
qc1d, qi1d, qs1d, dz1d, p1d, t1d | ||
! For TEMPO MP | ||
type(ty_tempo_cfg), intent(in) :: tempo_cfg | ||
|
||
! for F-A MP | ||
real(kind=kind_phys), dimension(im,lm+LTP+1) :: tem2db, hz | ||
|
@@ -276,7 +302,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& | |
|
||
LP1 = LM + 1 ! num of in/out levels | ||
|
||
if (imp_physics == imp_physics_thompson) then | ||
if (imp_physics == imp_physics_thompson .or. imp_physics == imp_physics_tempo) then | ||
max_relh = 1.5 | ||
else | ||
max_relh = 1.1 | ||
|
@@ -737,7 +763,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& | |
enddo | ||
enddo | ||
! for Thompson MP - prepare variables for calc_effr | ||
if_thompson: if (imp_physics == imp_physics_thompson .and. (ltaerosol .or. mraerosol)) then | ||
if_thompson: if ((imp_physics == imp_physics_thompson .or. imp_physics == imp_physics_tempo) .and. (ltaerosol .or. mraerosol)) then | ||
do k=1,LMK | ||
do i=1,IM | ||
qvs = qlyr(i,k) | ||
|
@@ -752,7 +778,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& | |
nwfa (i,k) = tracer1(i,k,ntwa) | ||
enddo | ||
enddo | ||
elseif (imp_physics == imp_physics_thompson) then | ||
elseif (imp_physics == imp_physics_thompson .or. imp_physics == imp_physics_tempo) then | ||
do k=1,LMK | ||
do i=1,IM | ||
qvs = qlyr(i,k) | ||
|
@@ -763,9 +789,19 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& | |
qi_mp (i,k) = tracer1(i,k,ntiw)/(1.-qvs) | ||
qs_mp (i,k) = tracer1(i,k,ntsw)/(1.-qvs) | ||
if(nint(slmsk(i)) == 1) then | ||
nc_mp (i,k) = Nt_c_l*orho(i,k) | ||
if (imp_physics == imp_physics_thompson) then | ||
nc_mp (i,k) = Nt_c_l_thmpsn*orho(i,k) | ||
endif | ||
if (imp_physics == imp_physics_tempo) then | ||
nc_mp (i,k) = Nt_c_l_tempo*orho(i,k) | ||
endif | ||
else | ||
nc_mp (i,k) = Nt_c_o*orho(i,k) | ||
if (imp_physics == imp_physics_thompson) then | ||
nc_mp (i,k) = Nt_c_o_thmpsn*orho(i,k) | ||
endif | ||
if (imp_physics == imp_physics_tempo) then | ||
nc_mp (i,k) = Nt_c_o_tempo*orho(i,k) | ||
endif | ||
endif | ||
ni_mp (i,k) = tracer1(i,k,ntinc)/(1.-qvs) | ||
enddo | ||
|
@@ -878,18 +914,28 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& | |
! not used yet -- effr_in should always be true for now | ||
endif | ||
|
||
elseif (imp_physics == imp_physics_thompson) then ! Thompson MP | ||
elseif (imp_physics == imp_physics_thompson .or. imp_physics == imp_physics_tempo) then ! Thompson MP | ||
! | ||
! Compute effective radii for QC, QI, QS with (GF, MYNN) or without (all others) sub-grid clouds | ||
! | ||
! Update number concentration, consistent with sub-grid clouds (GF, MYNN) or without (all others) | ||
do k=1,lm | ||
do i=1,im | ||
if ((ltaerosol .or. mraerosol) .and. qc_mp(i,k)>1.e-12 .and. nc_mp(i,k)<100.) then | ||
nc_mp(i,k) = make_DropletNumber(qc_mp(i,k)*rho(i,k), nwfa(i,k)*rho(i,k)) * orho(i,k) | ||
if ((ltaerosol .or. mraerosol) .and. qc_mp(i,k)>1.e-12 .and. nc_mp(i,k)<100.) then | ||
if (imp_physics == imp_physics_thompson) then | ||
nc_mp(i,k) = make_DropletNumber_thmpsn(qc_mp(i,k)*rho(i,k), nwfa(i,k)*rho(i,k)) * orho(i,k) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's harder to make the same change when calling a subroutine like this, although you could still pull the 'if imp_physics' statement out and have multiple loop sections. There's already one 'if' statement being executed inside the loop, but still. |
||
endif | ||
if (imp_physics == imp_physics_tempo) then | ||
nc_mp(i,k) = make_DropletNumber_tempo(qc_mp(i,k)*rho(i,k), nwfa(i,k)*rho(i,k)) * orho(i,k) | ||
endif | ||
endif | ||
if (qi_mp(i,k)>1.e-12 .and. ni_mp(i,k)<100.) then | ||
ni_mp(i,k) = make_IceNumber(qi_mp(i,k)*rho(i,k), tlyr(i,k)) * orho(i,k) | ||
if (imp_physics == imp_physics_thompson) then | ||
ni_mp(i,k) = make_IceNumber_thmpsn(qi_mp(i,k)*rho(i,k), tlyr(i,k)) * orho(i,k) | ||
endif | ||
if (imp_physics == imp_physics_tempo) then | ||
ni_mp(i,k) = make_IceNumber_tempo(qi_mp(i,k)*rho(i,k), tlyr(i,k)) * orho(i,k) | ||
endif | ||
endif | ||
end do | ||
end do | ||
|
@@ -900,18 +946,38 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& | |
!tgs: progclduni has different limits for ice radii (10.0-150.0) than | ||
! calc_effectRad (4.99-125.0 for WRFv3.8.1; 2.49-125.0 for WRFv4+) | ||
! it will raise the low limit from 5 to 10, but the high limit will remain 125. | ||
call calc_effectRad (tlyr(i,:), plyr(i,:)*100., qv_mp(i,:), qc_mp(i,:), & | ||
nc_mp(i,:), qi_mp(i,:), ni_mp(i,:), qs_mp(i,:), & | ||
effrl(i,:), effri(i,:), effrs(i,:), islmsk, 1, lm ) | ||
! Scale Thompson's effective radii from meter to micron | ||
do k=1,lm | ||
effrl(i,k) = MAX(re_qc_min, MIN(effrl(i,k), re_qc_max))*1.e6 | ||
effri(i,k) = MAX(re_qi_min, MIN(effri(i,k), re_qi_max))*1.e6 | ||
effrs(i,k) = MAX(re_qs_min, MIN(effrs(i,k), re_qs_max))*1.e6 | ||
end do | ||
effrl(i,lmk) = re_qc_min*1.e6 | ||
effri(i,lmk) = re_qi_min*1.e6 | ||
effrs(i,lmk) = re_qs_min*1.e6 | ||
if (imp_physics == imp_physics_thompson) then | ||
call calc_effectRad_thmpsn (tlyr(i,:), plyr(i,:)*100., qv_mp(i,:), qc_mp(i,:), & | ||
nc_mp(i,:), qi_mp(i,:), ni_mp(i,:), qs_mp(i,:), & | ||
effrl(i,:), effri(i,:), effrs(i,:), islmsk, 1, lm ) | ||
endif | ||
if (imp_physics == imp_physics_tempo) then | ||
call calc_effectRad_tempo (t1d=tlyr(i,:), p1d=plyr(i,:)*100., qv1d=qv_mp(i,:), qc1d=qc_mp(i,:), & | ||
nc1d=nc_mp(i,:), qi1d=qi_mp(i,:), ni1d=ni_mp(i,:), qs1d=qs_mp(i,:), & | ||
re_qc1d=effrl(i,:), re_qi1d=effri(i,:), re_qs1d=effrs(i,:), kts=1, kte=lm, & | ||
lsml=islmsk, configs=tempo_cfg) | ||
end if | ||
! Scale Thompson/TEMPO's effective radii from meter to micron | ||
if (imp_physics == imp_physics_thompson) then | ||
do k=1,lm | ||
effrl(i,k) = MAX(re_qc_min_thmpsn, MIN(effrl(i,k), re_qc_max_thmpsn))*1.e6 | ||
effri(i,k) = MAX(re_qi_min_thmpsn, MIN(effri(i,k), re_qi_max_thmpsn))*1.e6 | ||
effrs(i,k) = MAX(re_qs_min_thmpsn, MIN(effrs(i,k), re_qs_max_thmpsn))*1.e6 | ||
end do | ||
effrl(i,lmk) = re_qc_min_thmpsn*1.e6 | ||
effri(i,lmk) = re_qi_min_thmpsn*1.e6 | ||
effrs(i,lmk) = re_qs_min_thmpsn*1.e6 | ||
end if | ||
if (imp_physics == imp_physics_tempo) then | ||
do k=1,lm | ||
effrl(i,k) = MAX(re_qc_min_tempo, MIN(effrl(i,k), re_qc_max_tempo))*1.e6 | ||
effri(i,k) = MAX(re_qi_min_tempo, MIN(effri(i,k), re_qi_max_tempo))*1.e6 | ||
effrs(i,k) = MAX(re_qs_min_tempo, MIN(effrs(i,k), re_qs_max_tempo))*1.e6 | ||
end do | ||
effrl(i,lmk) = re_qc_min_tempo*1.e6 | ||
effri(i,lmk) = re_qi_min_tempo*1.e6 | ||
effrs(i,lmk) = re_qs_min_tempo*1.e6 | ||
end if | ||
end do | ||
effrr(:,:) = 1000. ! rrain_def=1000. | ||
! Update global arrays | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,10 +12,11 @@ module GFS_rrtmgp_cloud_mp | |
use rrtmgp_lw_cloud_optics, only: & | ||
radliq_lwr => radliq_lwrLW, radliq_upr => radliq_uprLW,& | ||
radice_lwr => radice_lwrLW, radice_upr => radice_uprLW | ||
use module_mp_thompson, only: calc_effectRad, Nt_c_l, Nt_c_o, re_qc_min, re_qc_max, & | ||
re_qi_min, re_qi_max, re_qs_min, re_qs_max | ||
use module_mp_thompson_make_number_concentrations, only: make_IceNumber, & | ||
use module_mp_tempo_utils, only: calc_effectRad, make_IceNumber, & | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dustinswales Are you OK switching from Thompson's subroutines to TEMPO's permanently? There's no need to import both (Thompson and TEMPO) and use if statements in this scheme as done for RRTMG? |
||
make_DropletNumber, make_RainNumber | ||
use module_mp_tempo_params, only: Nt_c_l, Nt_c_o, re_qc_min, re_qc_max, & | ||
re_qi_min, re_qi_max, re_qs_min, re_qs_max, configs | ||
|
||
|
||
real (kind_phys), parameter :: & | ||
cld_limit_lower = 0.001, & | ||
|
@@ -901,10 +902,11 @@ subroutine cmp_reff_Thompson(nLev, nCol, i_cldliq, i_cldice, i_cldsnow, i_cldice | |
! Compute effective radii for liquid/ice/snow. | ||
do iCol=1,nCol | ||
ilsmask = nint(lsmask(iCol)) | ||
call calc_effectRad (t_lay(iCol,:), p_lay(iCol,:), qv_mp(iCol,:), qc_mp(iCol,:), & | ||
nc_mp(iCol,:), qi_mp(iCol,:), ni_mp(iCol,:), qs_mp(iCol,:), & | ||
re_cloud(iCol,:), re_ice(iCol,:), re_snow(iCol,:), ilsmask, & | ||
1, nLev ) | ||
call calc_effectRad (t1d=t_lay(iCol,:), p1d=p_lay(iCol,:), qv1d=qv_mp(iCol,:), qc1d=qc_mp(iCol,:), & | ||
nc1d=nc_mp(iCol,:), qi1d=qi_mp(iCol,:), ni1d=ni_mp(iCol,:), qs1d=qs_mp(iCol,:), & | ||
re_qc1d=re_cloud(iCol,:), re_qi1d=re_ice(iCol,:), re_qs1d=re_snow(iCol,:), kts=1, kte=nLev, & | ||
lsml=ilsmask, configs=configs) | ||
|
||
do iLay = 1, nLev | ||
re_cloud(iCol,iLay) = MAX(re_qc_min, MIN(re_cloud(iCol,iLay), re_qc_max)) | ||
re_ice(iCol,iLay) = MAX(re_qi_min, MIN(re_ice(iCol,iLay), re_qi_max)) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm concerned about the addition of 'if' statements within the spatial loops for performance reasons. As an example for this section, couldn't one keep a Nt_c_l (generic) and set it from Nt_c_l_thmpsn/tempo as needed above the loop?