From 10e881799b8d598befbf605d11f342b2e5f3aa22 Mon Sep 17 00:00:00 2001 From: "Kate.Zhang" Date: Fri, 23 Aug 2024 23:58:24 +0000 Subject: [PATCH] Implement the GOCART aerosols as aero_aware into the Thompson scheme --- .../GFS_PBL_generic_common.F90 | 7 +- .../UFS_SCM_NEPTUNE/GFS_PBL_generic_post.F90 | 9 +- .../UFS_SCM_NEPTUNE/GFS_PBL_generic_post.meta | 7 + .../UFS_SCM_NEPTUNE/GFS_PBL_generic_pre.F90 | 9 +- .../UFS_SCM_NEPTUNE/GFS_PBL_generic_pre.meta | 7 + .../UFS_SCM_NEPTUNE/GFS_rrtmg_pre.F90 | 24 ++- .../UFS_SCM_NEPTUNE/GFS_rrtmg_pre.meta | 7 + .../UFS_SCM_NEPTUNE/GFS_rrtmgp_cloud_mp.F90 | 26 ++- .../UFS_SCM_NEPTUNE/GFS_rrtmgp_cloud_mp.meta | 56 ++++++ .../GFS_suite_interstitial_3.F90 | 6 +- .../GFS_suite_interstitial_3.meta | 7 + physics/MP/Thompson/module_mp_thompson.F90 | 116 ++++++++--- physics/MP/Thompson/mp_thompson.F90 | 187 +++++++++++++++--- physics/MP/Thompson/mp_thompson.meta | 127 ++++++++++++ physics/PBL/MYNN_EDMF/mynnedmf_wrapper.F90 | 9 +- physics/PBL/MYNN_EDMF/mynnedmf_wrapper.meta | 7 + physics/Radiation/radiation_aerosols.f | 3 +- physics/docs/pdftxt/suite_input.nml.txt | 1 + 18 files changed, 530 insertions(+), 85 deletions(-) diff --git a/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_PBL_generic_common.F90 b/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_PBL_generic_common.F90 index 5f09f5347..ff4b57f34 100644 --- a/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_PBL_generic_common.F90 +++ b/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_PBL_generic_common.F90 @@ -12,7 +12,8 @@ module GFS_PBL_generic_common contains subroutine set_aerosol_tracer_index(imp_physics, imp_physics_wsm6, & - imp_physics_thompson, ltaerosol,mraerosol, & + imp_physics_thompson,ltaerosol, & + mraerosol,gtaerosol, & imp_physics_mg, ntgl, imp_physics_gfdl, & imp_physics_zhao_carr, imp_physics_nssl,& nssl_hail_on, nssl_ccn_on, kk, & @@ -23,7 +24,7 @@ subroutine set_aerosol_tracer_index(imp_physics, imp_physics_wsm6, & imp_physics_thompson, & imp_physics_mg, ntgl, imp_physics_gfdl, & imp_physics_zhao_carr,imp_physics_nssl - logical, intent(in ) :: ltaerosol, mraerosol, nssl_hail_on, nssl_ccn_on + logical, intent(in ) :: ltaerosol, mraerosol, gtaerosol, nssl_hail_on, nssl_ccn_on integer, intent(out) :: kk character(len=*), intent(out) :: errmsg integer, intent(out) :: errflg @@ -38,7 +39,7 @@ subroutine set_aerosol_tracer_index(imp_physics, imp_physics_wsm6, & ! Thompson if(ltaerosol) then kk = 12 - else if(mraerosol) then + else if(mraerosol .or. gtaerosol) then kk = 10 else kk = 9 diff --git a/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_PBL_generic_post.F90 b/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_PBL_generic_post.F90 index 64ded0c37..dec67e5f8 100644 --- a/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_PBL_generic_post.F90 +++ b/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_PBL_generic_post.F90 @@ -12,7 +12,7 @@ subroutine GFS_PBL_generic_post_run (im, levs, nvdiff, ntrac, ntqv, ntcw, ntiw, ntrw, ntsw, ntlnc, ntinc, ntrnc, ntsnc, ntgnc, ntwa, ntia, ntgl, ntoz, ntke, ntkev,nqrimef, & trans_aero, ntchs, ntchm, ntccn, nthl, nthnc, ntgv, nthv, ntrz, ntgz, nthz, & imp_physics, imp_physics_gfdl, imp_physics_thompson, imp_physics_wsm6, imp_physics_zhao_carr, imp_physics_mg, & - imp_physics_fer_hires, imp_physics_nssl, nssl_ccn_on, ltaerosol, mraerosol, nssl_hail_on, nssl_3moment, & + imp_physics_fer_hires, imp_physics_nssl, nssl_ccn_on, ltaerosol, mraerosol, gtaerosol, nssl_hail_on, nssl_3moment, & cplflx, cplaqm, cplchm,cplchp, lssav, flag_for_pbl_generic_tend, ldiag3d, lsidea, hybedmf, do_shoc, satmedmf, & shinhong, do_ysu, dvdftra, dusfc1, dvsfc1, dtsfc1, dqsfc1, dtf, dudt, dvdt, dtdt, htrsw, htrlw, xmu, & dqdt, dusfc_cpl, dvsfc_cpl, dtsfc_cpl, dtend, dtidx, index_of_temperature, index_of_x_wind, index_of_y_wind, & @@ -36,7 +36,7 @@ subroutine GFS_PBL_generic_post_run (im, levs, nvdiff, ntrac, integer, intent(in) :: imp_physics_zhao_carr, imp_physics_mg, imp_physics_fer_hires integer, intent(in) :: imp_physics_nssl logical, intent(in) :: nssl_ccn_on, nssl_hail_on, nssl_3moment - logical, intent(in) :: ltaerosol, cplflx, cplaqm, cplchm,cplchp, lssav, ldiag3d, lsidea, use_med_flux, mraerosol + logical, intent(in) :: ltaerosol, cplflx, cplaqm, cplchm,cplchp, lssav, ldiag3d, lsidea, use_med_flux, mraerosol, gtaerosol logical, intent(in) :: hybedmf, do_shoc, satmedmf, shinhong, do_ysu logical, intent(in) :: flag_for_pbl_generic_tend @@ -105,7 +105,8 @@ subroutine GFS_PBL_generic_post_run (im, levs, nvdiff, ntrac, if (trans_aero) then ! Set kk if chemistry-aerosol tracers are diffused call set_aerosol_tracer_index(imp_physics, imp_physics_wsm6, & - imp_physics_thompson, ltaerosol,mraerosol, & + imp_physics_thompson, ltaerosol, & + mraerosol, gtaerosol, & imp_physics_mg, ntgl, imp_physics_gfdl, & imp_physics_zhao_carr, imp_physics_nssl,& nssl_hail_on, nssl_ccn_on, kk, & @@ -166,7 +167,7 @@ subroutine GFS_PBL_generic_post_run (im, levs, nvdiff, ntrac, dqdt(i,k,ntia) = dvdftra(i,k,12) enddo enddo - else if(mraerosol) then + else if(mraerosol .or. gtaerosol) then do k=1,levs do i=1,im dqdt(i,k,ntqv) = dvdftra(i,k,1) diff --git a/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_PBL_generic_post.meta b/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_PBL_generic_post.meta index 82ea4cab5..00dd66e1c 100644 --- a/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_PBL_generic_post.meta +++ b/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_PBL_generic_post.meta @@ -302,6 +302,13 @@ dimensions = () type = logical intent = in +[gtaerosol] + standard_name = do_gocart_aerosol_awareness + long_name = flag for gocart aerosol-aware physics for example the thompson microphysics + units = flag + dimensions = () + type = logical + intent = in [nssl_ccn_on] standard_name = nssl_ccn_on long_name = CCN activation flag in NSSL micro diff --git a/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_PBL_generic_pre.F90 b/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_PBL_generic_pre.F90 index 6e34a4b06..92b17a992 100644 --- a/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_PBL_generic_pre.F90 +++ b/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_PBL_generic_pre.F90 @@ -15,7 +15,7 @@ subroutine GFS_PBL_generic_pre_run (im, levs, nvdiff, ntrac, rtg_ozone_index, ntccn, nthl, nthnc, ntgv, nthv, ntrz, ntgz, nthz, & imp_physics, imp_physics_gfdl, imp_physics_thompson, imp_physics_wsm6, & imp_physics_zhao_carr, imp_physics_mg, imp_physics_fer_hires, imp_physics_nssl, & - ltaerosol, cplchp, mraerosol, nssl_ccn_on, nssl_hail_on, nssl_3moment, & + ltaerosol, cplchp, mraerosol, gtaerosol, nssl_ccn_on, nssl_hail_on, nssl_3moment,& hybedmf, do_shoc, satmedmf, qgrs, vdftra, save_u, save_v, save_t, save_q, & flag_for_pbl_generic_tend, ldiag3d, qdiag3d, lssav, ugrs, vgrs, tgrs, errmsg, errflg) @@ -33,7 +33,7 @@ subroutine GFS_PBL_generic_pre_run (im, levs, nvdiff, ntrac, rtg_ozone_index, logical, intent(in) :: trans_aero, ldiag3d, qdiag3d, lssav integer, intent(in) :: imp_physics, imp_physics_gfdl, imp_physics_thompson, imp_physics_wsm6 integer, intent(in) :: imp_physics_zhao_carr, imp_physics_mg, imp_physics_fer_hires - logical, intent(in) :: ltaerosol, hybedmf, do_shoc, satmedmf, flag_for_pbl_generic_tend, mraerosol + logical, intent(in) :: ltaerosol, hybedmf, do_shoc, satmedmf, flag_for_pbl_generic_tend, mraerosol, gtaerosol integer, intent(in) :: imp_physics_nssl logical, intent(in) :: nssl_hail_on, nssl_ccn_on, nssl_3moment logical, intent(in) :: cplchp @@ -108,7 +108,7 @@ subroutine GFS_PBL_generic_pre_run (im, levs, nvdiff, ntrac, rtg_ozone_index, enddo enddo rtg_ozone_index = 10 - elseif(mraerosol) then + elseif(mraerosol .or. gtaerosol) then do k=1,levs do i=1,im vdftra(i,k,1) = qgrs(i,k,ntqv) @@ -273,7 +273,8 @@ subroutine GFS_PBL_generic_pre_run (im, levs, nvdiff, ntrac, rtg_ozone_index, ! if (trans_aero) then call set_aerosol_tracer_index(imp_physics, imp_physics_wsm6, & - imp_physics_thompson, ltaerosol,mraerosol, & + imp_physics_thompson, ltaerosol, & + mraerosol, gtaerosol, & imp_physics_mg, ntgl, imp_physics_gfdl, & imp_physics_zhao_carr, imp_physics_nssl,& nssl_hail_on, nssl_ccn_on, kk, & diff --git a/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_PBL_generic_pre.meta b/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_PBL_generic_pre.meta index bae4fe05b..19ad0b9bd 100644 --- a/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_PBL_generic_pre.meta +++ b/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_PBL_generic_pre.meta @@ -308,6 +308,13 @@ dimensions = () type = logical intent = in +[gtaerosol] + standard_name = do_gocart_aerosol_awareness + long_name = flag for gocart aerosol-aware physics for example the thompson microphysics + units = flag + dimensions = () + type = logical + intent = in [nssl_ccn_on] standard_name = nssl_ccn_on long_name = CCN activation flag in NSSL micro diff --git a/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_rrtmg_pre.F90 b/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_rrtmg_pre.F90 index 767d3e534..51785a7eb 100644 --- a/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_rrtmg_pre.F90 +++ b/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_rrtmg_pre.F90 @@ -31,7 +31,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& imp_physics_fer_hires, iovr, iovr_rand, iovr_maxrand, iovr_max, & iovr_dcorr, iovr_exp, iovr_exprand, idcor, idcor_con, idcor_hogan, & idcor_oreopoulos, dcorr_con, julian, yearlen, lndp_var_list, lsswr, & - lslwr, ltaerosol, mraerosol, lgfdlmprad, uni_cld, effr_in, do_mynnedmf,& + lslwr, ltaerosol, mraerosol, gtaerosol, lgfdlmprad, uni_cld, effr_in, do_mynnedmf,& lmfshal, lcnorm, lmfdeep2, lcrick, fhswr, fhlwr, solhr, sup, con_eps, & epsm1, fvirt, rog, rocp, con_rd, xlat_d, xlat, xlon, coslat, sinlat, & tsfc, slmsk, prsi, prsl, prslk, tgrs, sfc_wts, mg_cld, effrr_in, & @@ -128,7 +128,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& logical, intent(in) :: lsswr, lslwr, ltaerosol, lgfdlmprad, & uni_cld, effr_in, do_mynnedmf, & lmfshal, lmfdeep2, pert_clds, lcrick,& - lcnorm, top_at_1, lextop, mraerosol + lcnorm, top_at_1, lextop, mraerosol, gtaerosol logical, intent(in) :: rrfs_sd, aero_dir_fdb, xr_cnvcld logical, intent(in) :: nssl_ccn_on, nssl_invertccn @@ -230,7 +230,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& ! for Thompson MP real(kind=kind_phys), dimension(im,lm+LTP) :: & qv_mp, qc_mp, qi_mp, qs_mp, & - nc_mp, ni_mp, nwfa + nc_mp, ni_mp, nwfa, gtnwfa real (kind=kind_phys), dimension(lm) :: cldfra1d, qv1d, & & qc1d, qi1d, qs1d, dz1d, p1d, t1d @@ -375,6 +375,16 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& tracer1(:,k1,j) = max(0.0, qgrs(:,k2,j)) enddo enddo + + if (gtaerosol) then + do k = 1, LM + k1 = k + kd + k2 = k + lsk + gtnwfa(:,k1)=((qgrs(:,k2,ntss1)/0.0045435214+qgrs(:,k2,ntss2)/0.2907854+qgrs(:,k2,ntss3)/12.91224+ & + qgrs(:,k2,ntss4)/206.2216+qgrs(:,k2,ntss5)/4326.23)*9.+qgrs(:,k2,ntsu)/0.3053104*5+ & + qgrs(:,k2,ntocl)/0.3232698*8)*1.e6 + enddo + endif ! if (top_at_1) then ! input data from toa to sfc if (lsk > 0) then @@ -736,7 +746,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 .and. (ltaerosol .or. mraerosol .or. gtaerosol)) then do k=1,LMK do i=1,IM qvs = qlyr(i,k) @@ -748,7 +758,11 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& qs_mp (i,k) = tracer1(i,k,ntsw)/(1.-qvs) nc_mp (i,k) = tracer1(i,k,ntlnc)/(1.-qvs) ni_mp (i,k) = tracer1(i,k,ntinc)/(1.-qvs) + if (gtaerosol) then + nwfa (i,k) = gtnwfa (i,k) + else nwfa (i,k) = tracer1(i,k,ntwa) + endif enddo enddo elseif (imp_physics == imp_physics_thompson) then @@ -884,7 +898,7 @@ subroutine GFS_rrtmg_pre_run (im, levs, lm, lmk, lmp, n_var_lndp, lextop,& ! 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 + if ((ltaerosol .or. mraerosol .or. gtaerosol) .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) endif if (qi_mp(i,k)>1.e-12 .and. ni_mp(i,k)<100.) then diff --git a/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_rrtmg_pre.meta b/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_rrtmg_pre.meta index 15039e822..0c13a2a35 100644 --- a/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_rrtmg_pre.meta +++ b/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_rrtmg_pre.meta @@ -646,6 +646,13 @@ dimensions = () type = logical intent = in +[gtaerosol] + standard_name = do_gocart_aerosol_awareness + long_name = flag for gocart aerosol-aware physics for example the thompson microphysics + units = flag + dimensions = () + type = logical + intent = in [lgfdlmprad] standard_name = flag_for_GFDL_microphysics_radiation_interaction long_name = flag for GFDL microphysics-radiation interaction diff --git a/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_rrtmgp_cloud_mp.F90 b/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_rrtmgp_cloud_mp.F90 index 79ae1559a..444e1b62e 100644 --- a/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_rrtmgp_cloud_mp.F90 +++ b/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_rrtmgp_cloud_mp.F90 @@ -45,8 +45,9 @@ module GFS_rrtmgp_cloud_mp subroutine GFS_rrtmgp_cloud_mp_run(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldice, & i_cldrain, i_cldsnow, i_cldgrpl, i_cldtot, i_cldliq_nc, i_cldice_nc, i_twa, kdt, & imfdeepcnv, imfdeepcnv_gf, imfdeepcnv_samf, doSWrad, doLWrad, effr_in, lmfshal, & - ltaerosol,mraerosol, icloud, imp_physics, imp_physics_thompson, imp_physics_gfdl, & + ltaerosol, mraerosol, gtaerosol, icloud, imp_physics, imp_physics_thompson, imp_physics_gfdl, & lgfdlmprad, do_mynnedmf, uni_cld, lmfdeep2, p_lev, p_lay, t_lay, qs_lay, q_lay, & + ntss1, ntss2,ntss3, ntss4,ntss5, ntsu, ntocl, & relhum, lsmask, xlon, xlat, dx, tv_lay, effrin_cldliq, effrin_cldice, & effrin_cldrain, effrin_cldsnow, tracer, cnv_mixratio, cld_cnv_frac, qci_conv, & deltaZ, deltaZc, deltaP, qc_mynn, qi_mynn, cld_pbl_frac, con_g, con_rd, con_eps, & @@ -63,7 +64,9 @@ subroutine GFS_rrtmgp_cloud_mp_run(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldic nCol, & ! Number of horizontal grid points nLev, & ! Number of vertical layers ncnd, & ! Number of cloud condensation types. - nTracers, & ! Number of tracers from model. + nTracers, & ! Number of tracers from model. + ntss1, ntss2,ntss3,ntss4, & ! gocart tracer number + ntss5, ntsu,ntocl, & ! gocart tracer number i_cldliq, & ! Index into tracer array for cloud liquid. i_cldice, & ! Index into tracer array for cloud ice. i_cldrain, & ! Index into tracer array for cloud rain. @@ -88,6 +91,7 @@ subroutine GFS_rrtmgp_cloud_mp_run(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldic lmfshal, & ! Flag for mass-flux shallow convection scheme used by Xu-Randall ltaerosol, & ! Flag for aerosol option mraerosol, & ! Flag for aerosol option + gtaerosol, & ! Flag for aerosol option lgfdlmprad, & ! Flag for GFDLMP radiation interaction do_mynnedmf, & ! Flag to activate MYNN-EDMF uni_cld, & ! Flag for unified cloud scheme @@ -258,7 +262,7 @@ subroutine GFS_rrtmgp_cloud_mp_run(nCol, nLev, nTracers, ncnd, i_cldliq, i_cldic ! Update particle size using modified mixing-ratios from Thompson. call cmp_reff_Thompson(nLev, nCol, i_cldliq, i_cldice, i_cldsnow, i_cldice_nc, & i_cldliq_nc, i_twa, q_lay, p_lay, t_lay, tracer, con_eps, con_rd, ltaerosol,& - mraerosol, lsmask, effrin_cldliq, effrin_cldice, effrin_cldsnow) + mraerosol, gtaerosol, lsmask, effrin_cldliq, effrin_cldice, effrin_cldsnow) cld_reliq = effrin_cldliq cld_reice = effrin_cldice cld_resnow = effrin_cldsnow @@ -842,13 +846,15 @@ function cld_frac_XuRandall(p_lay, qs_lay, relhum, cld_mr, alpha) ! ###################################################################################### subroutine cmp_reff_Thompson(nLev, nCol, i_cldliq, i_cldice, i_cldsnow, i_cldice_nc, & i_cldliq_nc, i_twa, q_lay, p_lay, t_lay, tracer, con_eps, con_rd, ltaerosol, & - mraerosol, lsmask, effrin_cldliq, effrin_cldice, effrin_cldsnow) + mraerosol, gtaerosol, lsmask, effrin_cldliq, effrin_cldice, effrin_cldsnow, & + ntss1, ntss2,ntss3,ntss4, ntss5, ntsu,ntocl) implicit none ! Inputs integer, intent(in) :: nLev, nCol, i_cldliq, i_cldice, i_cldsnow, i_cldice_nc, & i_cldliq_nc, i_twa - logical, intent(in) :: ltaerosol, mraerosol + integer, intent(in) :: ntss1, ntss2,ntss3,ntss4, ntss5, ntsu,ntocl + logical, intent(in) :: ltaerosol, mraerosol, gtaerosol real(kind_phys), intent(in) :: con_eps,con_rd real(kind_phys), dimension(:,:),intent(in) :: q_lay, p_lay, t_lay real(kind_phys), dimension(:,:,:),intent(in) :: tracer @@ -862,7 +868,7 @@ subroutine cmp_reff_Thompson(nLev, nCol, i_cldliq, i_cldice, i_cldsnow, i_cldice integer :: iCol, iLay real(kind_phys) :: rho, orho real(kind_phys),dimension(nCol,nLev) :: qv_mp, qc_mp, qi_mp, qs_mp, ni_mp, nc_mp, & - nwfa, re_cloud, re_ice, re_snow + nwfa,gtnwfa, re_cloud, re_ice, re_snow integer :: ilsmask ! Prepare cloud mixing-ratios and number concentrations for calc_effectRa @@ -875,9 +881,15 @@ subroutine cmp_reff_Thompson(nLev, nCol, i_cldliq, i_cldice, i_cldsnow, i_cldice qi_mp(iCol,iLay) = tracer(iCol,iLay,i_cldice) / (1.-q_lay(iCol,iLay)) qs_mp(iCol,iLay) = tracer(iCol,iLay,i_cldsnow) / (1.-q_lay(iCol,iLay)) ni_mp(iCol,iLay) = tracer(iCol,iLay,i_cldice_nc) / (1.-q_lay(iCol,iLay)) - if (ltaerosol .or. mraerosol) then + if (ltaerosol .or. mraerosol .or. gtaerosol,) then nc_mp(iCol,iLay) = tracer(iCol,iLay,i_cldliq_nc) / (1.-q_lay(iCol,iLay)) + if (gtaerosol) then + nwfa(iCol,iLay) = ((tracer(iCol,iLay,ntss1)/0.0045435214+tracer(iCol,iLay,ntss2)/0.2907854+tracer(iCol,iLay,ntss3)/12.91224+ & + tracer(iCol,iLay,ntss4)/206.2216+tracer(iCol,iLay,ntss5)/4326.23)*9.+tracer(iCol,iLay,ntsu)/0.3053104*5+ & + tracer(iCol,iLay,ntocl)/0.3232698*8)*1.e6 + else nwfa(iCol,iLay) = tracer(iCol,iLay,i_twa) + endif if (qc_mp(iCol,iLay) > 1.e-12 .and. nc_mp(iCol,iLay) < 100.) then nc_mp(iCol,iLay) = make_DropletNumber(qc_mp(iCol,iLay)*rho, nwfa(iCol,iLay)*rho) * orho endif diff --git a/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_rrtmgp_cloud_mp.meta b/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_rrtmgp_cloud_mp.meta index f67259b87..472b221e1 100644 --- a/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_rrtmgp_cloud_mp.meta +++ b/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_rrtmgp_cloud_mp.meta @@ -199,6 +199,13 @@ dimensions = () type = logical intent = in +[gtaerosol] + standard_name = do_gocart_aerosol_awareness + long_name = flag for gocart aerosol-aware physics for example the thompson microphysics + units = flag + dimensions = () + type = logical + intent = in [imfdeepcnv] standard_name = control_for_deep_convection_scheme long_name = flag for mass-flux deep convection scheme @@ -307,6 +314,55 @@ type = real kind = kind_phys intent = in +[ntss1] + standard_name = index_for_seasalt_bin1 + long_name = index for seasalt bin1 + units = index + dimensions = () + type = integer + intent = in +[ntss2] + standard_name = index_for_seasalt_bin2 + long_name = index for seasalt bin2 + units = index + dimensions = () + type = integer + intent = in +[ntss3] + standard_name = index_for_seasalt_bin3 + long_name = index for seasalt bin3 + units = index + dimensions = () + type = integer + intent = in +[ntss4] + standard_name = index_for_seasalt_bin4 + long_name = index for seasalt bin4 + units = index + dimensions = () + type = integer + intent = in +[ntss5] + standard_name = index_for_seasalt_bin5 + long_name = index for seasalt bin5 + units = index + dimensions = () + type = integer + intent = in +[ntsu] + standard_name = index_for_sulfate + long_name = index for sulfate + units = index + dimensions = () + type = integer + intent = in +[ntocl] + standard_name = index_for_ocphilic + long_name = index for ocphilic + units = index + dimensions = () + type = integer + intent = in [relhum] standard_name = relative_humidity long_name = layer relative humidity diff --git a/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_suite_interstitial_3.F90 b/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_suite_interstitial_3.F90 index 5ca20ffc1..dfafcb9d9 100644 --- a/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_suite_interstitial_3.F90 +++ b/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_suite_interstitial_3.F90 @@ -16,7 +16,7 @@ subroutine GFS_suite_interstitial_3_run (otsptflag, & satmedmf, trans_trac, do_shoc, ltaerosol, ntrac, ntcw, & ntiw, ntclamt, ntrw, ntsw, ntrnc, ntsnc, ntgl, ntgnc, & xlon, xlat, gt0, gq0, sigmain,sigmaout,qmicro, & - imp_physics, imp_physics_mg, & + imp_physics, imp_physics_mg,gtaerosol, & imp_physics_zhao_carr, imp_physics_zhao_carr_pdf, & imp_physics_gfdl, imp_physics_thompson, dtidx, ntlnc, & imp_physics_wsm6, imp_physics_fer_hires, prsi, ntinc, & @@ -37,7 +37,7 @@ subroutine GFS_suite_interstitial_3_run (otsptflag, & imp_physics_gfdl, imp_physics_thompson, imp_physics_wsm6,imp_physics_fer_hires, & imp_physics_nssl, me, index_of_process_conv_trans integer, intent(in ), dimension(:) :: islmsk, kpbl, kinver - logical, intent(in ) :: cscnv, satmedmf, trans_trac, do_shoc, ltaerosol, ras, progsigma + logical, intent(in ) :: cscnv, satmedmf, trans_trac, do_shoc, ltaerosol, gtaerosol, ras, progsigma logical, intent(in ) :: first_time_step, restart integer, intent(in ) :: imfshalcnv, imfdeepcnv, imfshalcnv_samf,imfdeepcnv_samf integer, intent(in ) :: imfshalcnv_c3,imfdeepcnv_c3 @@ -195,7 +195,7 @@ subroutine GFS_suite_interstitial_3_run (otsptflag, & save_tcp(i,k) = gt0(i,k) enddo enddo - if(ltaerosol) then + if(ltaerosol .or. gtaerosol) then save_qi(:,:) = clw(:,:,1) save_qc(:,:) = clw(:,:,2) else diff --git a/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_suite_interstitial_3.meta b/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_suite_interstitial_3.meta index 22f57e354..a3a59435b 100644 --- a/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_suite_interstitial_3.meta +++ b/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_suite_interstitial_3.meta @@ -134,6 +134,13 @@ dimensions = () type = logical intent = in +[gtaerosol] + standard_name = do_gocart_aerosol_awareness + long_name = flag for gocart aerosol-aware physics for example the thompson microphysics + units = flag + dimensions = () + type = logical + intent = in [ntrac] standard_name = number_of_tracers long_name = number of tracers diff --git a/physics/MP/Thompson/module_mp_thompson.F90 b/physics/MP/Thompson/module_mp_thompson.F90 index 664f95329..2fa2c4bec 100644 --- a/physics/MP/Thompson/module_mp_thompson.F90 +++ b/physics/MP/Thompson/module_mp_thompson.F90 @@ -72,6 +72,7 @@ MODULE module_mp_thompson LOGICAL, PARAMETER, PRIVATE:: iiwarm = .false. LOGICAL, PRIVATE:: is_aerosol_aware = .false. LOGICAL, PRIVATE:: merra2_aerosol_aware = .false. + LOGICAL, PRIVATE:: gocart_aerosol_aware = .false. LOGICAL, PRIVATE:: cplchp = .false. LOGICAL, PARAMETER, PRIVATE:: dustyIce = .true. LOGICAL, PARAMETER, PRIVATE:: homogIce = .true. @@ -450,6 +451,7 @@ MODULE module_mp_thompson !> @{ SUBROUTINE thompson_init(is_aerosol_aware_in, & merra2_aerosol_aware_in, & + gocart_aerosol_aware_in, & cplchp_in, & mpicomm, mpirank, mpiroot, & threads, errmsg, errflg) @@ -458,6 +460,7 @@ SUBROUTINE thompson_init(is_aerosol_aware_in, & LOGICAL, INTENT(IN) :: is_aerosol_aware_in LOGICAL, INTENT(IN) :: merra2_aerosol_aware_in + LOGICAL, INTENT(IN) :: gocart_aerosol_aware_in LOGICAL, INTENT(IN) :: cplchp_in TYPE(MPI_Comm), INTENT(IN) :: mpicomm INTEGER, INTENT(IN) :: mpirank, mpiroot @@ -473,8 +476,27 @@ SUBROUTINE thompson_init(is_aerosol_aware_in, & ! Set module variable is_aerosol_aware/merra2_aerosol_aware/cplchp is_aerosol_aware = is_aerosol_aware_in merra2_aerosol_aware = merra2_aerosol_aware_in + gocart_aerosol_aware = gocart_aerosol_aware_in cplchp = cplchp_in - if (is_aerosol_aware .and. merra2_aerosol_aware) then + if (is_aerosol_aware .and. merra2_aerosol_aware .and. gocart_aerosol_aware) then + errmsg = 'Logic error in thompson_init: only one of the two options can be true, ' // & + 'not both: is_aerosol_aware or merra2_aerosol_aware' + errflg = 1 + return + end if + if (is_aerosol_aware .and. merra2_aerosol_aware ) then + errmsg = 'Logic error in thompson_init: only one of the two options can be true, ' // & + 'not both: is_aerosol_aware or merra2_aerosol_aware' + errflg = 1 + return + end if + if (is_aerosol_aware .and. gocart_aerosol_aware) then + errmsg = 'Logic error in thompson_init: only one of the two options can be true, ' // & + 'not both: is_aerosol_aware or merra2_aerosol_aware' + errflg = 1 + return + end if + if (merra2_aerosol_aware .and. gocart_aerosol_aware) then errmsg = 'Logic error in thompson_init: only one of the two options can be true, ' // & 'not both: is_aerosol_aware or merra2_aerosol_aware' errflg = 1 @@ -485,6 +507,8 @@ SUBROUTINE thompson_init(is_aerosol_aware_in, & write (*,'(a)') 'Using aerosol-aware version of Thompson microphysics' else if(merra2_aerosol_aware) then write (*,'(a)') 'Using merra2 aerosol-aware version of Thompson microphysics' + else if(gocart_aerosol_aware) then + write (*,'(a)') 'Using gocart aerosol-aware version of Thompson microphysics' else write (*,'(a)') 'Using non-aerosol-aware version of Thompson microphysics' end if @@ -995,7 +1019,7 @@ END SUBROUTINE thompson_init !> @{ SUBROUTINE mp_gt_driver(qv, qc, qr, qi, qs, qg, ni, nr, nc, & nwfa, nifa, nwfa2d, nifa2d, & - aero3d, & + aero3d,aeroFF, & tt, th, pii, & p, w, dz, dt_in, dt_inner, & sedi_semi, decfl, lsm, & @@ -1054,7 +1078,7 @@ SUBROUTINE mp_gt_driver(qv, qc, qr, qi, qs, qg, ni, nr, nc, & REAL, DIMENSION(ims:ime, kms:kme, jms:jme), OPTIONAL, INTENT(INOUT):: & nc, nwfa, nifa REAL, DIMENSION(ims:ime, kms:kme, jms:jme, 1:num_aero), OPTIONAL,INTENT(INOUT):: & - aero3d + aero3d, aeroFF REAL, DIMENSION(ims:ime, jms:jme), OPTIONAL, INTENT(IN):: nwfa2d, nifa2d INTEGER, DIMENSION(ims:ime, jms:jme), INTENT(IN):: lsm REAL, DIMENSION(ims:ime, kms:kme, jms:jme), OPTIONAL, INTENT(INOUT):: & @@ -1138,6 +1162,7 @@ SUBROUTINE mp_gt_driver(qv, qc, qr, qi, qs, qg, ni, nr, nc, & #endif !lzhang REAL, DIMENSION(kts:kte,1:num_aero) :: naero1d + REAL, DIMENSION(kts:kte,1:num_aero) :: aeroRT REAL, DIMENSION(its:ite, jts:jte):: pcp_ra, pcp_sn, pcp_gr, pcp_ic REAL:: dt, pptrain, pptsnow, pptgraul, pptice REAL:: qc_max, qr_max, qs_max, qi_max, qg_max, ni_max, nr_max @@ -1205,9 +1230,26 @@ SUBROUTINE mp_gt_driver(qv, qc, qr, qi, qs, qg, ni, nr, nc, & ' for merra2 aerosol-aware version of Thompson microphysics' stop end if + else if (gocart_aerosol_aware .and. (.not. cplchp ) .and. & + ( .not.present(nc) .or. & + .not.present(nwfa) .or. & + .not.present(nifa) )) then + if (present(errmsg) .and. present(errflg)) then + write(errmsg, '(*(a))') 'Logic error in mp_gt_driver: provide nc, nwfa, and nifa', & + ' for merra2 aerosol-aware version of Thompson microphysics' + errflg = 1 + return + else + write(*, '(*(a))') 'Logic error in mp_gt_driver: provide nc, nwfa, and nifa', & + ' for merra2 aerosol-aware version of Thompson microphysics' + stop + end if + else if (.not.is_aerosol_aware .and. .not.merra2_aerosol_aware .and. & + .not.gocart_aerosol_aware .and. & (present(nwfa) .or. present(nifa) .or. present(nwfa2d) .or. present(nifa2d))) then - write(*,*) 'WARNING, nc/nwfa/nifa/nwfa2d/nifa2d present but is_aerosol_aware/merra2_aerosol_aware are FALSE' + write(*,*) 'WARNING, nc/nwfa/nifa/nwfa2d/nifa2d present but is_aerosol_aware/merra2_aerosol_aware/ & + gocart_aerosol_aware are FALSE' end if end if test_only_once @@ -1438,11 +1480,17 @@ SUBROUTINE mp_gt_driver(qv, qc, qr, qi, qs, qg, ni, nr, nc, & endif initialize_extended_diagnostics enddo lsml = lsm(i,j) - if (is_aerosol_aware .or. merra2_aerosol_aware) then + if (is_aerosol_aware .or. merra2_aerosol_aware .or. gocart_aerosol_aware) then do k = kts, kte nc1d(k) = nc(i,k,j) nwfa1d(k) = nwfa(i,k,j) nifa1d(k) = nifa(i,k,j) + if (cplchp) then + do nv = 1, num_aero + naero1d(k,nv)=aero3d(i,k,j,nv) + aeroRT(k,nv)=aeroFF(i,k,j,nv) + enddo + endif enddo else do k = kts, kte @@ -1456,6 +1504,7 @@ SUBROUTINE mp_gt_driver(qv, qc, qr, qi, qs, qg, ni, nr, nc, & if (cplchp) then do nv = 1, num_aero naero1d(k,nv)=aero3d(i,k,j,nv) + aeroRT(k,nv)=aeroFF(i,k,j,nv) enddo endif enddo @@ -1463,7 +1512,7 @@ SUBROUTINE mp_gt_driver(qv, qc, qr, qi, qs, qg, ni, nr, nc, & !> - Call mp_thompson() call mp_thompson(qv1d, qc1d, qi1d, qr1d, qs1d, qg1d, ni1d, & - nr1d, nc1d, nwfa1d, nifa1d, naero1d, & + nr1d, nc1d, nwfa1d, nifa1d, naero1d,aeroRT, & t1d, p1d, w1d, dz1d, & lsml, pptrain, pptsnow, pptgraul, pptice, & #if ( WRF_CHEM == 1 ) @@ -1550,6 +1599,14 @@ SUBROUTINE mp_gt_driver(qv, qc, qr, qi, qs, qg, ni, nr, nc, & aero3d(i,k,j,nv) = max(1.E-20, naero1d(k,nv)) enddo enddo + if (gocart_aerosol_aware) then + do k = kts, kte + nc(i,k,j) = nc1d(k) + nwfa(i,k,j) = nwfa1d(k) + nifa(i,k,j) = nifa1d(k) + enddo + endif + endif do k = kts, kte @@ -1894,7 +1951,7 @@ END SUBROUTINE thompson_finalize !>\section gen_mp_thompson mp_thompson General Algorithm !> @{ subroutine mp_thompson (qv1d, qc1d, qi1d, qr1d, qs1d, qg1d, ni1d, & - nr1d, nc1d, nwfa1d, nifa1d, naero1d, & + nr1d, nc1d, nwfa1d, nifa1d, naero1d, aeroRT, & t1d, p1d, w1d, dzq, & lsml, pptrain, pptsnow, pptgraul, pptice, & #if ( WRF_CHEM == 1 ) @@ -1931,6 +1988,7 @@ subroutine mp_thompson (qv1d, qc1d, qi1d, qr1d, qs1d, qg1d, ni1d, & qv1d, qc1d, qi1d, qr1d, qs1d, qg1d, ni1d, & nr1d, nc1d, nwfa1d, nifa1d, t1d REAL, DIMENSION(kts:kte,1:num_aero), INTENT(INOUT) :: naero1d + REAL, DIMENSION(kts:kte,1:num_aero), INTENT(IN) :: aeroRT REAL, DIMENSION(kts:kte), INTENT(OUT):: pfil1, pfll1 REAL, DIMENSION(kts:kte), INTENT(IN):: p1d, w1d, dzq REAL, INTENT(INOUT):: pptrain, pptsnow, pptgraul, pptice @@ -2295,7 +2353,7 @@ subroutine mp_thompson (qv1d, qc1d, qi1d, qr1d, qs1d, qg1d, ni1d, & endif nc(k) = MIN( DBLE(Nt_c_max), ccg(1,nu_c)*ocg2(nu_c)*rc(k) & / am_r*lamc**bm_r) - if (.NOT. (is_aerosol_aware .or. merra2_aerosol_aware)) then + if (.NOT. (is_aerosol_aware .or. merra2_aerosol_aware .or. gocart_aerosol_aware )) then if (lsml == 1) then nc(k) = Nt_c_l else @@ -2618,7 +2676,8 @@ subroutine mp_thompson (qv1d, qc1d, qi1d, qr1d, qs1d, qg1d, ni1d, & do nv=1, num_aero Ef_ra = Eff_aero(mvd_r(k),aero_diams(nv),visco(k),rho(k),temp(k),'r') lamr = 1./ilamr(k) - pnx_rcx(k,nv) = 100.0*rhof(k)*t1_qr_qc*Ef_ra*aero_comb(k,nv)*N0_r(k) & + !pnx_rcx(k,nv) = 100.0*rhof(k)*t1_qr_qc*Ef_ra*aero_comb(k,nv)*N0_r(k) & + pnx_rcx(k,nv) = aeroRT(k,nv)*rhof(k)*t1_qr_qc*Ef_ra*aero_comb(k,nv)*N0_r(k) & *((lamr+fv_r)**(-cre(9))) pnx_rcx(k,nv) = MIN(DBLE(aero_comb(k,nv)*odts), pnx_rcx(k,nv)) enddo @@ -2832,7 +2891,8 @@ subroutine mp_thompson (qv1d, qc1d, qi1d, qr1d, qs1d, qg1d, ni1d, & if (cplchp) then do nv=1, num_aero Ef_sa = Eff_aero(xDs,aero_diams(nv),visco(k),rho(k),temp(k),'s') - pnx_scx(k,nv) = 100.0*rhof(k)*t1_qs_qc*Ef_sa*aero_comb(k,nv)*smoe(k) + !pnx_scx(k,nv) = 100.0*rhof(k)*t1_qs_qc*Ef_sa*aero_comb(k,nv)*smoe(k) + pnx_scx(k,nv) = aeroRT(k,nv)*rhof(k)*t1_qs_qc*Ef_sa*aero_comb(k,nv)*smoe(k) pnx_scx(k,nv) = MIN(DBLE(aero_comb(k,nv)*odts), pnx_scx(k,nv)) enddo endif @@ -2853,7 +2913,8 @@ subroutine mp_thompson (qv1d, qc1d, qi1d, qr1d, qs1d, qg1d, ni1d, & if (cplchp) then do nv=1, num_aero Ef_ga = Eff_aero(xDg,aero_diams(nv),visco(k),rho(k),temp(k),'g') - pnx_gcx(k,nv) = 100.0*rhof(k)*t1_qg_qc*Ef_ga*aero_comb(k,nv)*N0_g(k) & + !pnx_gcx(k,nv) = 100.0*rhof(k)*t1_qg_qc*Ef_ga*aero_comb(k,nv)*N0_g(k) & + pnx_gcx(k,nv) = aeroRT(k,nv)*rhof(k)*t1_qg_qc*Ef_ga*aero_comb(k,nv)*N0_g(k) & *ilamg(k)**cge(9) pnx_gcx(k,nv) = MIN(DBLE(aero_comb(k,nv)*odts), pnx_gcx(k,nv)) enddo @@ -2984,7 +3045,7 @@ subroutine mp_thompson (qv1d, qc1d, qi1d, qr1d, qs1d, qg1d, ni1d, & !! Implemented by T. Eidhammer and G. Thompson 2012Dec18 !+---+-----------------------------------------------------------------+ - if (dustyIce .AND. (is_aerosol_aware .or. merra2_aerosol_aware)) then + if (dustyIce .AND. (is_aerosol_aware .or. merra2_aerosol_aware .or. gocart_aerosol_aware)) then xni = iceDeMott(tempc,qvs(k),qvs(k),qvsi(k),rho(k),nifa(k)) else xni = 1.0 *1000. ! Default is 1.0 per Liter @@ -3032,7 +3093,7 @@ subroutine mp_thompson (qv1d, qc1d, qi1d, qr1d, qs1d, qg1d, ni1d, & !! we may need to relax the temperature and ssati constraints. if ( (ssati(k).ge. 0.15) .or. (ssatw(k).gt. eps & .and. temp(k).lt.253.15) ) then - if (dustyIce .AND. (is_aerosol_aware .or. merra2_aerosol_aware)) then + if (dustyIce .AND. (is_aerosol_aware .or. merra2_aerosol_aware .or. gocart_aerosol_aware )) then xnc = iceDeMott(tempc,qv(k),qvs(k),qvsi(k),rho(k),nifa(k)) xnc = xnc*(1.0 + 50.*rand3) else @@ -3046,7 +3107,7 @@ subroutine mp_thompson (qv1d, qc1d, qi1d, qr1d, qs1d, qg1d, ni1d, & !> - Freezing of aqueous aerosols based on Koop et al (2001, Nature) xni = smo0(k)+ni(k) + (pni_rfz(k)+pni_wfz(k)+pni_inu(k))*dtsave - if ((is_aerosol_aware .or. merra2_aerosol_aware) .AND. homogIce .AND. (xni.le.4999.E3) & + if ((is_aerosol_aware .or. merra2_aerosol_aware .or. gocart_aerosol_aware) .AND. homogIce .AND. (xni.le.4999.E3) & & .AND.(temp(k).lt.238).AND.(ssati(k).ge.0.4) ) then xnc = iceKoop(temp(k),qv(k),qvs(k),nwfa(k), dtsave) pni_iha(k) = xnc*odts @@ -3299,7 +3360,7 @@ subroutine mp_thompson (qv1d, qc1d, qi1d, qr1d, qs1d, qg1d, ni1d, & lfus2 = lsub - lvap(k) !> - Aerosol number tendency - if (is_aerosol_aware) then + if (is_aerosol_aware .or. gocart_aerosol_aware ) then nwfaten(k) = nwfaten(k) - (pna_rca(k) + pna_sca(k) & + pna_gca(k) + pni_iha(k)) * orho nifaten(k) = nifaten(k) - (pnd_rcd(k) + pnd_scd(k) & @@ -3309,7 +3370,8 @@ subroutine mp_thompson (qv1d, qc1d, qi1d, qr1d, qs1d, qg1d, ni1d, & else nifaten(k) = 0. endif - else if ( cplchp ) then + endif + if ( cplchp ) then do nv=1,num_aero nchemten(k,nv) = nchemten(k,nv) - (pnx_rcx(k,nv) + pnx_scx(k,nv) & + pnx_gcx(k,nv) ) * orho @@ -3495,7 +3557,7 @@ subroutine mp_thompson (qv1d, qc1d, qi1d, qr1d, qs1d, qg1d, ni1d, & tcond(k) = (5.69 + 0.0168*tempc)*1.0E-5 * 418.936 ocp(k) = 1./(Cp*(1.+0.887*qv(k))) lvt2(k)=lvap(k)*lvap(k)*ocp(k)*oRv*otemp*otemp - if (is_aerosol_aware) & + if (is_aerosol_aware .or. gocart_aerosol_aware ) & nwfa(k) = MAX(11.1E6*rho(k), (nwfa1d(k) + nwfaten(k)*DT)*rho(k)) enddo @@ -3503,7 +3565,7 @@ subroutine mp_thompson (qv1d, qc1d, qi1d, qr1d, qs1d, qg1d, ni1d, & if ((qc1d(k) + qcten(k)*DT) .gt. R1) then rc(k) = (qc1d(k) + qcten(k)*DT)*rho(k) nc(k) = MAX(2., MIN((nc1d(k)+ncten(k)*DT)*rho(k), Nt_c_max)) - if (.NOT. (is_aerosol_aware .or. merra2_aerosol_aware)) then + if (.NOT. (is_aerosol_aware .or. merra2_aerosol_aware .or. gocart_aerosol_aware)) then if(lsml == 1) then nc(k) = Nt_c_l else @@ -3667,7 +3729,7 @@ subroutine mp_thompson (qv1d, qc1d, qi1d, qr1d, qs1d, qg1d, ni1d, & prw_vcd(k) = clap*odt !+---+-----------------------------------------------------------------+ ! DROPLET NUCLEATION if (clap .gt. eps) then - if (is_aerosol_aware .or. merra2_aerosol_aware) then + if (is_aerosol_aware .or. merra2_aerosol_aware .or. gocart_aerosol_aware) then xnc = MAX(2., activ_ncloud(temp(k), w1d(k)+rand3, nwfa(k), lsml)) else if(lsml == 1) then @@ -3680,7 +3742,8 @@ subroutine mp_thompson (qv1d, qc1d, qi1d, qr1d, qs1d, qg1d, ni1d, & !+---+-----------------------------------------------------------------+ ! EVAPORATION elseif (clap .lt. -eps .AND. ssatw(k).lt.-1.E-6 .AND. & - (is_aerosol_aware .or. merra2_aerosol_aware)) then + !(is_aerosol_aware .or. merra2_aerosol_aware .or. gocart_aerosol_aware)) then + (is_aerosol_aware .or. gocart_aerosol_aware )) then tempc = temp(k) - 273.15 otemp = 1./temp(k) rvs = rho(k)*qvs(k) @@ -3739,13 +3802,13 @@ subroutine mp_thompson (qv1d, qc1d, qi1d, qr1d, qs1d, qg1d, ni1d, & qvten(k) = qvten(k) - prw_vcd(k) qcten(k) = qcten(k) + prw_vcd(k) ncten(k) = ncten(k) + pnc_wcd(k) - if (is_aerosol_aware) & + if (is_aerosol_aware .or. gocart_aerosol_aware ) & nwfaten(k) = nwfaten(k) - pnc_wcd(k) tten(k) = tten(k) + lvap(k)*ocp(k)*prw_vcd(k)*(1-IFDRY) rc(k) = MAX(R1, (qc1d(k) + DT*qcten(k))*rho(k)) if (rc(k).eq.R1) L_qc(k) = .false. nc(k) = MAX(2., MIN((nc1d(k)+ncten(k)*DT)*rho(k), Nt_c_max)) - if (.NOT. (is_aerosol_aware .or. merra2_aerosol_aware)) then + if (.NOT. (is_aerosol_aware .or. merra2_aerosol_aware .or. gocart_aerosol_aware)) then if(lsml == 1) then nc(k) = Nt_c_l else @@ -3829,7 +3892,7 @@ subroutine mp_thompson (qv1d, qc1d, qi1d, qr1d, qs1d, qg1d, ni1d, & qrten(k) = qrten(k) - prv_rev(k) qvten(k) = qvten(k) + prv_rev(k) nrten(k) = nrten(k) - pnr_rev(k) - if (is_aerosol_aware) & + if (is_aerosol_aware .or. gocart_aerosol_aware) & nwfaten(k) = nwfaten(k) + pnr_rev(k) tten(k) = tten(k) - lvap(k)*ocp(k)*prv_rev(k)*(1-IFDRY) @@ -4319,7 +4382,7 @@ subroutine mp_thompson (qv1d, qc1d, qi1d, qr1d, qs1d, qg1d, ni1d, & qv1d(k) = MAX(1.E-10, qv1d(k) + qvten(k)*DT) qc1d(k) = qc1d(k) + qcten(k)*DT nc1d(k) = MAX(2./rho(k), MIN(nc1d(k) + ncten(k)*DT, Nt_c_max)) - if (is_aerosol_aware) then + if (is_aerosol_aware .or. gocart_aerosol_aware ) then nwfa1d(k) = MAX(11.1E6, MIN(9999.E6, & (nwfa1d(k)+nwfaten(k)*DT))) nifa1d(k) = MAX(naIN1*0.01, MIN(9999.E6, & @@ -5506,6 +5569,9 @@ real function activ_ncloud(Tt, Ww, NCCN, lsm_in) !.. sea salts. l = 3 m = 2 + !lzhang + !l = 5 + !m = 4 if (lsm_in .eq. 1) then ! land lower_lim_nuc_frac = 0. @@ -5923,7 +5989,7 @@ subroutine calc_effectRad (t1d, p1d, qv1d, qc1d, nc1d, qi1d, ni1d, qs1d, & rho(k) = 0.622*p1d(k)/(R*t1d(k)*(qv1d(k)+0.622)) rc(k) = MAX(R1, qc1d(k)*rho(k)) nc(k) = MAX(2., MIN(nc1d(k)*rho(k), Nt_c_max)) - if (.NOT. (is_aerosol_aware .or. merra2_aerosol_aware)) then + if (.NOT. (is_aerosol_aware .or. merra2_aerosol_aware .or. gocart_aerosol_aware)) then if( lsml == 1) then nc(k) = Nt_c_l else diff --git a/physics/MP/Thompson/mp_thompson.F90 b/physics/MP/Thompson/mp_thompson.F90 index a6ad3062d..88feb2c57 100644 --- a/physics/MP/Thompson/mp_thompson.F90 +++ b/physics/MP/Thompson/mp_thompson.F90 @@ -37,9 +37,13 @@ subroutine mp_thompson_init(ncol, nlev, con_g, con_rd, con_eps, & imp_physics_thompson, convert_dry_rho, & spechum, qc, qr, qi, qs, qg, ni, nr, & is_aerosol_aware, merra2_aerosol_aware, & + gocart_aerosol_aware, & cplchp, nc, nwfa2d, nifa2d, & nwfa, nifa, tgrs, prsl, phil, area, & - aerfld, mpicomm, mpirank, mpiroot, & + aerfld, gq0, ntdu1, ntdu2, ntdu3, ntdu4, & + ntdu5, ntss1, ntss2,ntss3, ntss4, & + ntss5, ntsu, ntbcb, ntbcl, ntocb, ntocl, & + mpicomm, mpirank, mpiroot, & threads, ext_diag, diag3d, & errmsg, errflg) @@ -65,13 +69,15 @@ subroutine mp_thompson_init(ncol, nlev, con_g, con_rd, con_eps, & ! Aerosols logical, intent(in ) :: is_aerosol_aware logical, intent(in ) :: merra2_aerosol_aware + logical, intent(in ) :: gocart_aerosol_aware logical, intent(in ) :: cplchp real(kind_phys), intent(inout) :: nc(:,:) real(kind_phys), intent(inout) :: nwfa(:,:) real(kind_phys), intent(inout) :: nifa(:,:) real(kind_phys), intent(inout) :: nwfa2d(:) real(kind_phys), intent(inout) :: nifa2d(:) - real(kind_phys), intent(in) :: aerfld(:,:,:) + real(kind_phys), intent(in ) :: aerfld(:,:,:) + real(kind_phys), intent(inout) :: gq0(:,:,:) ! State variables real(kind_phys), intent(in ) :: tgrs(:,:) real(kind_phys), intent(in ) :: prsl(:,:) @@ -89,7 +95,11 @@ subroutine mp_thompson_init(ncol, nlev, con_g, con_rd, con_eps, & ! CCPP error handling character(len=*), intent( out) :: errmsg integer, intent( out) :: errflg + integer, intent(in ) :: ntdu1, ntdu2, ntdu3, ntdu4, ntdu5, ntss1,ntss2, ntss3, & + ntss4, ntss5, ntsu, ntbcb, ntbcl, ntocb, ntocl + ! Local variables +! real(kind_phys) :: aero3d(1:ncol,1:nlev,1:num_aero) ! real(kind_phys) :: qv(1:ncol,1:nlev) ! kg kg-1 (water vapor mixing ratio) real(kind_phys) :: hgt(1:ncol,1:nlev) ! m @@ -121,15 +131,39 @@ subroutine mp_thompson_init(ncol, nlev, con_g, con_rd, con_eps, & end if end if - if ((is_aerosol_aware .and. merra2_aerosol_aware ) .and. (.not. cplchp) ) then - write(errmsg,'(*(a))') "Logic error: Only one Thompson aerosol option can be true, either is_aerosol_aware or merra2_aerosol_aware)" + if (is_aerosol_aware .and. merra2_aerosol_aware .and. gocart_aerosol_aware) then + write(errmsg,'(*(a))') "Logic error: Only one Thompson aerosol option can be true, either is_aerosol_aware or & + merra2_aerosol_aware or gocart_aerosol_aware)" + errflg = 1 + return + end if + + if (is_aerosol_aware .and. merra2_aerosol_aware ) then + write(errmsg,'(*(a))') "Logic error: Only one Thompson aerosol option can be true, either is_aerosol_aware or & + merra2_aerosol_aware or gocart_aerosol_aware)" + errflg = 1 + return + end if + + if (is_aerosol_aware .and. gocart_aerosol_aware) then + write(errmsg,'(*(a))') "Logic error: Only one Thompson aerosol option can be true, either is_aerosol_aware or & + merra2_aerosol_aware or gocart_aerosol_aware)" errflg = 1 return end if + if (merra2_aerosol_aware .and. gocart_aerosol_aware) then + write(errmsg,'(*(a))') "Logic error: Only one Thompson aerosol option can be true, either is_aerosol_aware or & + merra2_aerosol_aware or gocart_aerosol_aware)" + errflg = 1 + return + end if + + ! Call Thompson init call thompson_init(is_aerosol_aware_in=is_aerosol_aware, & merra2_aerosol_aware_in=merra2_aerosol_aware, & + gocart_aerosol_aware_in=gocart_aerosol_aware, & cplchp_in=cplchp, & mpicomm=mpicomm, mpirank=mpirank, mpiroot=mpiroot, & threads=threads, errmsg=errmsg, errflg=errflg) @@ -159,6 +193,11 @@ subroutine mp_thompson_init(ncol, nlev, con_g, con_rd, con_eps, & call get_niwfa(aerfld, nifa, nwfa, ncol, nlev) end if + if (gocart_aerosol_aware) then + call get_aero_int(gq0, nifa, nwfa,ncol, nlev, & + ntdu1, ntdu2, ntdu3, ntdu4, ntdu5, ntss1, ntss2,& + ntss3, ntss4, ntss5, ntsu, ntbcb, ntbcl, ntocb, ntocl) + end if qv = spechum/(1.0_kind_phys-spechum) @@ -171,7 +210,7 @@ subroutine mp_thompson_init(ncol, nlev, con_g, con_rd, con_eps, & ni = ni/(1.0_kind_phys-spechum) nr = nr/(1.0_kind_phys-spechum) - if ((is_aerosol_aware .or. merra2_aerosol_aware) .and. (.not. cplchp)) then + if (is_aerosol_aware .or. merra2_aerosol_aware .or. gocart_aerosol_aware) then nc = nc/(1.0_kind_phys-spechum) nwfa = nwfa/(1.0_kind_phys-spechum) nifa = nifa/(1.0_kind_phys-spechum) @@ -195,7 +234,7 @@ subroutine mp_thompson_init(ncol, nlev, con_g, con_rd, con_eps, & !..Check for existing aerosol data, both CCN and IN aerosols. If missing !.. fill in just a basic vertical profile, somewhat boundary-layer following. - if (is_aerosol_aware .and. (.not. cplchp) ) then + if (is_aerosol_aware ) then ! Potential cloud condensation nuclei (CCN) if (MAXVAL(nwfa) .lt. eps) then @@ -279,13 +318,14 @@ subroutine mp_thompson_init(ncol, nlev, con_g, con_rd, con_eps, & ! Copy to local array for calculating cloud effective radii below nc_local = nc - else if (merra2_aerosol_aware) then + else if (merra2_aerosol_aware .or. gocart_aerosol_aware) then ! Ensure we have 1st guess cloud droplet number where mass non-zero but no number. where(qc .LE. 0.0) nc=0.0 where(qc .GT. 0 .and. nc .LE. 0.0) nc = make_DropletNumber(qc*rho, nwfa*rho) * orho where(qc .EQ. 0.0 .and. nc .GT. 0.0) nc = 0.0 + else ! Constant droplet concentration for single moment cloud water as in @@ -303,7 +343,7 @@ subroutine mp_thompson_init(ncol, nlev, con_g, con_rd, con_eps, & ni = ni/(1.0_kind_phys+qv) nr = nr/(1.0_kind_phys+qv) - if ((is_aerosol_aware .or. merra2_aerosol_aware) .and. (.not. cplchp)) then + if ((is_aerosol_aware .or. merra2_aerosol_aware .or. gocart_aerosol_aware)) then nc = nc/(1.0_kind_phys+qv) nwfa = nwfa/(1.0_kind_phys+qv) nifa = nifa/(1.0_kind_phys+qv) @@ -325,7 +365,8 @@ subroutine 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,& + merra2_aerosol_aware, & + gocart_aerosol_aware, nc, nwfa, nifa,& nwfa2d, nifa2d, aero_ind_fdb, & tgrs, prsl, phii, omega, & sedi_semi, decfl, islmsk, dtp, & @@ -370,6 +411,7 @@ subroutine mp_thompson_run(ncol, nlev, con_g, con_rd, & ! Aerosols logical, intent(in) :: is_aerosol_aware, fullradar_diag logical, intent(in) :: merra2_aerosol_aware + logical, intent(in) :: gocart_aerosol_aware real(kind_phys), optional, intent(inout) :: nc(:,:) real(kind_phys), optional, intent(inout) :: nwfa(:,:) real(kind_phys), optional, intent(inout) :: nifa(:,:) @@ -432,6 +474,9 @@ subroutine mp_thompson_run(ncol, nlev, con_g, con_rd, & ! Local variables real(kind_phys) :: aero3d(1:ncol,1:nlev,1:num_aero) + real(kind_phys) :: aeroFF(1:ncol,1:nlev,1:num_aero) + real(kind_phys) :: gtnifa(1:ncol,1:nlev) + real(kind_phys) :: gtnwfa(1:ncol,1:nlev) real(kind_phys) :: aero3d_before(1:ncol,1:nlev,1:num_aero) ! Reduced time step if subcycling is used @@ -543,6 +588,14 @@ subroutine mp_thompson_run(ncol, nlev, con_g, con_rd, & ' following optional arguments: nc, nwfa, nifa' errflg = 1 return + else if (gocart_aerosol_aware .and. .not. (present(nc) .and. & + present(nwfa) .and. & + present(nifa) )) then + write(errmsg,fmt='(*(a))') 'Logic error in mp_thompson_run:', & + ' gocart aerosol-aware microphysics require the', & + ' following optional arguments: nc, nwfa, nifa' + errflg = 1 + return end if ! Consistency cheecks - subcycling and inner loop at the same time are not supported if (nsteps>1 .and. dt_inner < dtp) then @@ -577,9 +630,13 @@ subroutine mp_thompson_run(ncol, nlev, con_g, con_rd, & end if if (cplchp) then - call get_aero(aero3d,gq0, ncol, nlev, & + call get_aero(aero3d,aeroFF,gq0, gtnifa, gtnwfa, ncol, nlev, & ntdu1, ntdu2, ntdu3, ntdu4, ntdu5, ntss1, ntss2,& ntss3, ntss4, ntss5, ntsu, ntbcb, ntbcl, ntocb, ntocl) + if (gocart_aerosol_aware) then + nifa(:,:)=gtnifa(:,:) + nwfa(:,:)=gtnwfa(:,:) + endif aero3d_before (:,:,:)=aero3d(:,:,:) end if !> - Convert specific humidity to water vapor mixing ratio. @@ -600,7 +657,7 @@ subroutine mp_thompson_run(ncol, nlev, con_g, con_rd, & ni = ni/(1.0_kind_phys-spechum) nr = nr/(1.0_kind_phys-spechum) - if ((is_aerosol_aware .or. merra2_aerosol_aware) .and. (.not. cplchp)) then + if ((is_aerosol_aware .or. merra2_aerosol_aware .or. gocart_aerosol_aware ) ) then nc = nc/(1.0_kind_phys-spechum) nwfa = nwfa/(1.0_kind_phys-spechum) nifa = nifa/(1.0_kind_phys-spechum) @@ -708,7 +765,7 @@ subroutine mp_thompson_run(ncol, nlev, con_g, con_rd, & qcten3 => diag3d(:,:,37:37) end if set_extended_diagnostic_pointers !> - Call mp_gt_driver() with or without aerosols, with or without effective radii, ... - if ((is_aerosol_aware .or. merra2_aerosol_aware) .and. (.not. cplchp) ) then + if (((is_aerosol_aware .or. merra2_aerosol_aware)).and. (.not. cplchp)) then call mp_gt_driver(qv=qv, qc=qc, qr=qr, qi=qi, qs=qs, qg=qg, ni=ni, nr=nr, & nc=nc, nwfa=nwfa, nifa=nifa, nwfa2d=nwfa2d, nifa2d=nifa2d, & tt=tgrs, p=prsl, w=w, dz=dz, dt_in=dtstep, dt_inner=dt_inner, & @@ -750,10 +807,54 @@ subroutine mp_thompson_run(ncol, nlev, con_g, con_rd, & qvten3=qvten3, qrten3=qrten3, qsten3=qsten3, qgten3=qgten3, & qiten3=qiten3, niten3=niten3, nrten3=nrten3, ncten3=ncten3, & qcten3=qcten3, pfils=pfils, pflls=pflls) - else - if (cplchp) then + else if ((cplchp .and. (is_aerosol_aware .or. merra2_aerosol_aware .or. & + gocart_aerosol_aware))) then + call mp_gt_driver(qv=qv, qc=qc, qr=qr, qi=qi, qs=qs, qg=qg, ni=ni, nr=nr, & + aero3d=aero3d, aeroFF=aeroFF, & + nc=nc, nwfa=nwfa, nifa=nifa, nwfa2d=nwfa2d, nifa2d=nifa2d, & + tt=tgrs, p=prsl, w=w, dz=dz, dt_in=dtstep, dt_inner=dt_inner, & + sedi_semi=sedi_semi, decfl=decfl, lsm=islmsk, & + rainnc=rain_mp, rainncv=delta_rain_mp, & + snownc=snow_mp, snowncv=delta_snow_mp, & + icenc=ice_mp, icencv=delta_ice_mp, & + graupelnc=graupel_mp, graupelncv=delta_graupel_mp, sr=sr, & + refl_10cm=refl_10cm, & + diagflag=diagflag, do_radar_ref=do_radar_ref_mp, & + max_hail_diam_sfc=max_hail_diam_sfc, & + has_reqc=has_reqc, has_reqi=has_reqi, has_reqs=has_reqs, & + aero_ind_fdb=aero_ind_fdb, rand_perturb_on=spp_mp_opt, & + kme_stoch=kme_stoch, & + rand_pert=spp_wts_mp, spp_var_list=spp_var_list, & + spp_prt_list=spp_prt_list, n_var_spp=n_var_spp, & + spp_stddev_cutoff=spp_stddev_cutoff, & + ids=ids, ide=ide, jds=jds, jde=jde, kds=kds, kde=kde, & + ims=ims, ime=ime, jms=jms, jme=jme, kms=kms, kme=kme, & + its=its, ite=ite, jts=jts, jte=jte, kts=kts, kte=kte, & + fullradar_diag=fullradar_diag, istep=istep, nsteps=nsteps, & + first_time_step=first_time_step, errmsg=errmsg, errflg=errflg, & + ! Extended diagnostics + ext_diag=ext_diag, & + ! vts1=vts1, txri=txri, txrc=txrc, & + prw_vcdc=prw_vcdc, & + prw_vcde=prw_vcde, tpri_inu=tpri_inu, tpri_ide_d=tpri_ide_d, & + tpri_ide_s=tpri_ide_s, tprs_ide=tprs_ide, & + tprs_sde_d=tprs_sde_d, & + tprs_sde_s=tprs_sde_s, tprg_gde_d=tprg_gde_d, & + tprg_gde_s=tprg_gde_s, tpri_iha=tpri_iha, & + tpri_wfz=tpri_wfz, tpri_rfz=tpri_rfz, tprg_rfz=tprg_rfz, & + tprs_scw=tprs_scw, tprg_scw=tprg_scw, tprg_rcs=tprg_rcs, & + tprs_rcs=tprs_rcs, & + tprr_rci=tprr_rci, tprg_rcg=tprg_rcg, tprw_vcd_c=tprw_vcd_c, & + tprw_vcd_e=tprw_vcd_e, tprr_sml=tprr_sml, tprr_gml=tprr_gml, & + tprr_rcg=tprr_rcg, tprr_rcs=tprr_rcs, & + tprv_rev=tprv_rev, tten3=tten3, & + qvten3=qvten3, qrten3=qrten3, qsten3=qsten3, qgten3=qgten3, & + qiten3=qiten3, niten3=niten3, nrten3=nrten3, ncten3=ncten3, & + qcten3=qcten3, pfils=pfils, pflls=pflls) + else if (cplchp .and. ((.not. is_aerosol_aware) .and. (.not. merra2_aerosol_aware) & + .and.(.not. gocart_aerosol_aware)) ) then call mp_gt_driver(qv=qv, qc=qc, qr=qr, qi=qi, qs=qs, qg=qg, ni=ni, nr=nr, & - aero3d=aero3d, & + aero3d=aero3d, aeroFF=aeroFF, & tt=tgrs, p=prsl, w=w, dz=dz, dt_in=dtstep, dt_inner=dt_inner, & sedi_semi=sedi_semi, decfl=decfl, lsm=islmsk, & rainnc=rain_mp, rainncv=delta_rain_mp, & @@ -832,7 +933,6 @@ subroutine mp_thompson_run(ncol, nlev, con_g, con_rd, & qvten3=qvten3, qrten3=qrten3, qsten3=qsten3, qgten3=qgten3, & qiten3=qiten3, niten3=niten3, nrten3=nrten3, ncten3=ncten3, & qcten3=qcten3, pfils=pfils, pflls=pflls) - end if end if if (cplchp) then @@ -859,7 +959,7 @@ subroutine mp_thompson_run(ncol, nlev, con_g, con_rd, & ni = ni/(1.0_kind_phys+qv) nr = nr/(1.0_kind_phys+qv) - if ((is_aerosol_aware .or. merra2_aerosol_aware) .and. (.not. cplchp) ) then + if ((is_aerosol_aware .or. merra2_aerosol_aware .or. gocart_aerosol_aware)) then nc = nc/(1.0_kind_phys+qv) nwfa = nwfa/(1.0_kind_phys+qv) nifa = nifa/(1.0_kind_phys+qv) @@ -1001,7 +1101,27 @@ subroutine get_niwfa(aerfld, nifa, nwfa, ncol, nlev) end subroutine get_niwfa !lzhang - subroutine get_aero(aero3d,aerfld, ncol, nlev,& + + subroutine get_aero_int(aerfld, nifa, nwfa, ncol, nlev, & + ntdu1, ntdu2, ntdu3, ntdu4, ntdu5, ntss1, ntss2,& + ntss3, ntss4, ntss5, ntsu, ntbcb, ntbcl, ntocb, ntocl) + + implicit none + integer, intent(in)::ncol, nlev + real (kind=kind_phys), dimension(:,:,:), intent(in) :: aerfld + real (kind=kind_phys), dimension(:,:), intent(out ):: nifa, nwfa + integer, intent(in) :: ntdu1, ntdu2, ntdu3, ntdu4, ntdu5, ntss1, ntss2,ntss3, & + ntss4, ntss5, ntsu, ntbcb, ntbcl, ntocb, ntocl + + nifa(:,:)=(aerfld(:,:,ntdu1)/4.0737762+aerfld(:,:,ntdu2)/30.459203+aerfld(:,:,ntdu3)/153.45048+ & + aerfld(:,:,ntdu4)/1011.5142+ aerfld(:,:,ntdu5)/5683.3501)*1.e6 + + nwfa(:,:)=((aerfld(:,:,ntss1)/0.0045435214+aerfld(:,:,ntss2)/0.2907854+aerfld(:,:,ntss3)/12.91224+ & + aerfld(:,:,ntss4)/206.2216+ aerfld(:,:,ntss5)/4326.23)*9.+aerfld(:,:,ntsu)/0.3053104*5+ & + aerfld(:,:,ntocl)/0.3232698*8)*1.e6 + end subroutine get_aero_int + + subroutine get_aero(aero3d,aeroFF, aerfld, nifa, nwfa, ncol, nlev,& ntdu1, ntdu2, ntdu3, ntdu4, ntdu5, ntss1, ntss2,& ntss3, ntss4, ntss5, ntsu, ntbcb, ntbcl, ntocb, ntocl) ! To calculate nifa and nwfa from bins of aerosols. @@ -1044,24 +1164,22 @@ subroutine get_aero(aero3d,aerfld, ncol, nlev,& integer, intent(in)::ncol, nlev real (kind=kind_phys), dimension(:,:,:), intent(in) :: aerfld real (kind=kind_phys), dimension(ncol, nlev,num_aero), intent(out) :: aero3d - !real (kind=kind_phys), dimension(:,:), intent(out ):: nifa, nwfa + real (kind=kind_phys), dimension(ncol, nlev,num_aero), intent(out) :: aeroFF + real (kind=kind_phys), dimension(:,:), intent(out ):: nifa, nwfa integer, intent(in) :: ntdu1, ntdu2, ntdu3, ntdu4, ntdu5, ntss1, ntss2,ntss3, & ntss4, ntss5, ntsu, ntbcb, ntbcl, ntocb, ntocl - integer i,k + integer i,k, nt do k=1,nlev do i=1,ncol - !nifa(i,k)=(aerfld(i,k,ntdu1)/4.0737762+aerfld(i,k,ntdu2)/30.459203+aerfld(i,k,ntdu3)/153.45048+ - !& - ! aerfld(i,k,ntdu4)/1011.5142+ aerfld(i,k,ntdu5)/5683.3501)*1.e6 + nifa(i,k)=(aerfld(i,k,ntdu1)/4.0737762+aerfld(i,k,ntdu2)/30.459203+aerfld(i,k,ntdu3)/153.45048+ & + aerfld(i,k,ntdu4)/1011.5142+ aerfld(i,k,ntdu5)/5683.3501)*1.e6 - !nwfa(i,k)=((aerfld(i,k,ntss1)/0.0045435214+aerfld(i,k,ntss2)/0.2907854+aerfld(i,k,ntss3)/12.91224+ - !& - ! aerfld(i,k,ntss4)/206.2216+ - ! aerfld(i,k,ntss5)/4326.23)*9.+aerfld(i,k,ntsu)/0.3053104*5+ & - ! aerfld(i,k,ntocl)/0.3232698*8)*1.e6 + nwfa(i,k)=((aerfld(i,k,ntss1)/0.0045435214+aerfld(i,k,ntss2)/0.2907854+aerfld(i,k,ntss3)/12.91224+ & + aerfld(i,k,ntss4)/206.2216+aerfld(i,k,ntss5)/4326.23)*9.+aerfld(i,k,ntsu)/0.3053104*5+ & + aerfld(i,k,ntocl)/0.3232698*8)*1.e6 aero3d(i,k,1)=aerfld(i,k,ntdu1)/4.0737762*1.e6 aero3d(i,k,2)=aerfld(i,k,ntdu2)/30.459203*1.e6 @@ -1078,9 +1196,20 @@ subroutine get_aero(aero3d,aerfld, ncol, nlev,& aero3d(i,k,13)=aerfld(i,k,ntbcl)/0.3232698*8*1.e6 aero3d(i,k,14)=aerfld(i,k,ntocb)/0.3232698*8*1.e6 aero3d(i,k,15)=aerfld(i,k,ntocl)/0.3232698*8*1.e6 + + do nt =1, 15 + if (aero3d(i,k,nt) >=1.e-15) then + aeroFF(i,k,nt)=nifa(i,k)/aero3d(i,k,nt) + else + aero3d(i,k,nt) =100. + endif + enddo + aeroFF(i,k,12)=100. + aeroFF(i,k,13)=100. + aeroFF(i,k,14)=100. enddo enddo - + aeroFF=100. ! lzhang, removal factor end subroutine get_aero subroutine update_aero(aero3d,aerfld,ncol, nlev, & diff --git a/physics/MP/Thompson/mp_thompson.meta b/physics/MP/Thompson/mp_thompson.meta index 356b6ee60..3c3f08018 100644 --- a/physics/MP/Thompson/mp_thompson.meta +++ b/physics/MP/Thompson/mp_thompson.meta @@ -153,6 +153,13 @@ dimensions = () type = logical intent = in +[gocart_aerosol_aware] + standard_name = do_gocart_aerosol_awareness + long_name = flag for gocart aerosol-aware physics for example the thompson microphysics + units = flag + dimensions = () + type = logical + intent = in [cplchp] standard_name = flag_for_chemistry_package_coupling long_name = flag controlling cplchp collection (default off) @@ -240,6 +247,119 @@ type = real kind = kind_phys intent = in +[gq0] + standard_name = tracer_concentration_of_new_state + long_name = tracer concentration updated by physics + units = kg kg-1 + dimensions = (horizontal_dimension,vertical_layer_dimension,number_of_tracers) + type = real + kind = kind_phys + intent = inout +[ntdu1] + standard_name = index_for_dust_bin1 + long_name = index for dust bin1 + units = index + dimensions = () + type = integer + intent = in +[ntdu2] + standard_name = index_for_dust_bin2 + long_name = index for dust bin2 + units = index + dimensions = () + type = integer + intent = in +[ntdu3] + standard_name = index_for_dust_bin3 + long_name = index for dust bin3 + units = index + dimensions = () + type = integer + intent = in +[ntdu4] + standard_name = index_for_dust_bin4 + long_name = index for dust bin4 + units = index + dimensions = () + type = integer + intent = in +[ntdu5] + standard_name = index_for_dust_bin5 + long_name = index for dust bin5 + units = index + dimensions = () + type = integer + intent = in +[ntss1] + standard_name = index_for_seasalt_bin1 + long_name = index for seasalt bin1 + units = index + dimensions = () + type = integer + intent = in +[ntss2] + standard_name = index_for_seasalt_bin2 + long_name = index for seasalt bin2 + units = index + dimensions = () + type = integer + intent = in +[ntss3] + standard_name = index_for_seasalt_bin3 + long_name = index for seasalt bin3 + units = index + dimensions = () + type = integer + intent = in +[ntss4] + standard_name = index_for_seasalt_bin4 + long_name = index for seasalt bin4 + units = index + dimensions = () + type = integer + intent = in +[ntss5] + standard_name = index_for_seasalt_bin5 + long_name = index for seasalt bin5 + units = index + dimensions = () + type = integer + intent = in +[ntsu] + standard_name = index_for_sulfate + long_name = index for sulfate + units = index + dimensions = () + type = integer + intent = in +[ntbcb] + standard_name = index_for_bcphobic + long_name = index for bcphobic + units = index + dimensions = () + type = integer + intent = in +[ntbcl] + standard_name = index_for_bcphilic + long_name = index for bcphilic + units = index + dimensions = () + type = integer + intent = in +[ntocb] + standard_name = index_for_ocphobic + long_name = index for ocphobic + units = index + dimensions = () + type = integer + intent = in +[ntocl] + standard_name = index_for_ocphilic + long_name = index for ocphilic + units = index + dimensions = () + type = integer + intent = in [mpicomm] standard_name = mpi_communicator long_name = MPI communicator @@ -426,6 +546,13 @@ dimensions = () type = logical intent = in +[gocart_aerosol_aware] + standard_name = do_gocart_aerosol_awareness + long_name = flag for gocart aerosol-aware physics for example the thompson microphysics + units = flag + dimensions = () + type = logical + intent = in [nc] standard_name = mass_number_concentration_of_cloud_liquid_water_particles_in_air_of_new_state long_name = cloud droplet number concentration diff --git a/physics/PBL/MYNN_EDMF/mynnedmf_wrapper.F90 b/physics/PBL/MYNN_EDMF/mynnedmf_wrapper.F90 index 487753027..87f7f0c25 100644 --- a/physics/PBL/MYNN_EDMF/mynnedmf_wrapper.F90 +++ b/physics/PBL/MYNN_EDMF/mynnedmf_wrapper.F90 @@ -159,8 +159,8 @@ SUBROUTINE mynnedmf_wrapper_run( & & chem3d, frp, mix_chem, rrfs_sd, enh_mix, & & nchem, ndvel, vdep, smoke_dbg, & & imp_physics_nssl, nssl_ccn_on, & - & ltaerosol, mraerosol, spp_wts_pbl, spp_pbl, & - & lprnt, huge, errmsg, errflg ) + & ltaerosol, mraerosol, gtaerosol, spp_wts_pbl, & + & spp_pbl, lprnt, huge, errmsg, errflg ) ! should be moved to inside the mynn: use machine, only: kind_phys @@ -189,6 +189,7 @@ SUBROUTINE mynnedmf_wrapper_run( & & bl_mynn_tkeadvect, & & ltaerosol, & & mraerosol, & + & gtaerosol, & & lprnt, & & do_mynnsfclay, & & flag_for_pbl_generic_tend, & @@ -440,7 +441,7 @@ SUBROUTINE mynnedmf_wrapper_run( & qnbca(i,k) = 0. enddo enddo - else if(mraerosol) then + else if(mraerosol .or. gtaerosol) then FLAG_QI = .true. FLAG_QNI= .true. FLAG_QC = .true. @@ -864,7 +865,7 @@ SUBROUTINE mynnedmf_wrapper_run( & ! !qgrs_ice_aer_num_conc(i,k) = qgrs_ice_aer_num_conc(i,k) + RQNIFABLTEN(i,k)*delt ! enddo !enddo - else if(mraerosol) then + else if(mraerosol .or. gtaerosol) then do k=1,levs do i=1,im dqdt_water_vapor(i,k) = RQVBLTEN(i,k) !/(1.0 + qv(i,k)) diff --git a/physics/PBL/MYNN_EDMF/mynnedmf_wrapper.meta b/physics/PBL/MYNN_EDMF/mynnedmf_wrapper.meta index 00589dfe5..011712f2d 100644 --- a/physics/PBL/MYNN_EDMF/mynnedmf_wrapper.meta +++ b/physics/PBL/MYNN_EDMF/mynnedmf_wrapper.meta @@ -1463,6 +1463,13 @@ dimensions = () type = logical intent = in +[gtaerosol] + standard_name = do_gocart_aerosol_awareness + long_name = flag for gocart aerosol-aware physics for example the thompson microphysics + units = flag + dimensions = () + type = logical + intent = in [spp_wts_pbl] standard_name = spp_weights_for_pbl_scheme long_name = spp weights for pbl scheme diff --git a/physics/Radiation/radiation_aerosols.f b/physics/Radiation/radiation_aerosols.f index bbd2f25cb..b4fcd75f7 100644 --- a/physics/Radiation/radiation_aerosols.f +++ b/physics/Radiation/radiation_aerosols.f @@ -158,7 +158,8 @@ module module_radiation_aerosols ! !> total+species integer, parameter, public :: NSPC1 = NSPC + 1 - real (kind=kind_phys), parameter :: f_zero = 0.0 + !real (kind=kind_phys), parameter :: f_zero = 0.0 + real (kind=kind_phys), parameter :: f_zero = 1.0e-10 real (kind=kind_phys), parameter :: f_one = 1.0 ! --- module control parameters set in subroutine "aer_init" diff --git a/physics/docs/pdftxt/suite_input.nml.txt b/physics/docs/pdftxt/suite_input.nml.txt index 47dcc6970..29c6fdc77 100644 --- a/physics/docs/pdftxt/suite_input.nml.txt +++ b/physics/docs/pdftxt/suite_input.nml.txt @@ -389,6 +389,7 @@ show some variables in the namelist that must match the SDF. mp_print gfdl_cloud_microphys \a .true. to turn on GFDL cloud microphysics debugging print out. (not supported in GFS physics) .false. ltaerosol mp_thompson flag for using aerosol climotology in Thompson MP scheme .false. mraerosol flag for merra2 aerosol aware .false. +gtaerosol flag for gocart aerosol aware .false. lradar flag for radar reflectivity .false. nsfullradar_diag seconds between resetting radar reflectivity calculation .-999.0 ttendlim mp_thompson temperature tendency limiter per time step in K/s, set to < 0 to deactivate -999.0