diff --git a/Externals_CAM.cfg b/Externals_CAM.cfg index 9d094dd257..adb3814857 100644 --- a/Externals_CAM.cfg +++ b/Externals_CAM.cfg @@ -37,7 +37,7 @@ required = True local_path = src/physics/pumas protocol = git repo_url = https://github.com/ESCOMP/PUMAS -tag = pumas_cam-release_v1.16 +tag = pumas_cam-release_v1.17 required = True [atmos_phys] diff --git a/bld/build-namelist b/bld/build-namelist index 31b888ac29..8408af37bb 100755 --- a/bld/build-namelist +++ b/bld/build-namelist @@ -2881,11 +2881,28 @@ if ($cfg->get('microphys') =~ /^mg/) { add_default($nl, 'micro_mg_do_graupel'); add_default($nl, 'graupel_in_rad'); add_default($nl, 'micro_do_massless_droplet_destroyer'); + add_default($nl, 'micro_mg_accre_enhan_fact'); + add_default($nl, 'micro_mg_autocon_fact'); + add_default($nl, 'micro_mg_autocon_nd_exp'); + add_default($nl, 'micro_mg_autocon_lwp_exp'); + add_default($nl, 'micro_mg_homog_size'); + add_default($nl, 'micro_mg_vtrmi_factor'); + add_default($nl, 'micro_mg_effi_factor'); + add_default($nl, 'micro_mg_iaccr_factor'); + add_default($nl, 'micro_mg_max_nicons'); # For CESM2, the decision was made to set micro_do_sb_physics to false add_default($nl, 'micro_do_sb_physics', 'val'=>'.false.'); } +# Aerosol Namelist options +add_default($nl, 'microp_aero_bulk_scale'); +add_default($nl, 'microp_aero_npccn_scale'); +add_default($nl, 'microp_aero_wsub_scale'); +add_default($nl, 'microp_aero_wsubi_scale'); +add_default($nl, 'microp_aero_wsub_min'); +add_default($nl, 'microp_aero_wsubi_min'); + # Ice nucleation options if (!$simple_phys) { if ($chem =~ /_mam/) { @@ -3002,6 +3019,12 @@ if ($clubb_sgs =~ /$TRUE/io) { add_default($nl, 'clubb_C2thl'); add_default($nl, 'clubb_C2rtthl'); add_default($nl, 'clubb_C4'); + add_default($nl, 'clubb_c6rt'); + add_default($nl, 'clubb_c6rtb'); + add_default($nl, 'clubb_c6rtc'); + add_default($nl, 'clubb_c6thl'); + add_default($nl, 'clubb_c6thlb'); + add_default($nl, 'clubb_c6thlc'); add_default($nl, 'clubb_C7'); add_default($nl, 'clubb_C7b'); add_default($nl, 'clubb_C8'); @@ -3020,6 +3043,10 @@ if ($clubb_sgs =~ /$TRUE/io) { add_default($nl, 'clubb_skw_max_mag'); add_default($nl, 'clubb_up2_vp2_factor'); add_default($nl, 'clubb_C_wp2_splat'); + add_default($nl, 'clubb_wpxp_L_thresh'); + add_default($nl, 'clubb_detliq_rad'); + add_default($nl, 'clubb_detice_rad'); + add_default($nl, 'clubb_detphase_lowtemp'); add_default($nl, 'clubb_l_brunt_vaisala_freq_moist'); add_default($nl, 'clubb_l_call_pdf_closure_twice'); @@ -3135,6 +3162,9 @@ if (!$simple_phys) { add_default($nl, 'zmconv_org'); add_default($nl, 'zmconv_microp'); add_default($nl, 'zmconv_num_cin'); + add_default($nl, 'zmconv_dmpdz'); + add_default($nl, 'zmconv_tiedke_add'); + add_default($nl, 'zmconv_capelmt'); } # moist convection rainwater coefficients diff --git a/bld/namelist_files/namelist_defaults_cam.xml b/bld/namelist_files/namelist_defaults_cam.xml index fa7b36bf1a..6ede7a988f 100644 --- a/bld/namelist_files/namelist_defaults_cam.xml +++ b/bld/namelist_files/namelist_defaults_cam.xml @@ -1794,6 +1794,12 @@ 1.0 1.3 5.2 + 4.0 + 6.0 + 1.0 + 4.0 + 6.0 + 1.0 0.5 0.5 4.2 @@ -1807,6 +1813,7 @@ 0.5 0.3 .false. + 60.0 0.308 0.280 0.270 @@ -1819,6 +1826,9 @@ 4.5 2.0 0.0 + 8.0D-6 + 25.0D-6 + 238.15D0 .false. .true. @@ -1931,8 +1941,49 @@ max_overlap in_cloud - 1.0D0 - 1.0D0 + 1.D0 + 1.D0 + + 1.D0 + 1.D0 + + 0.01D0 + 0.01D0 + + -1.1D0 + -1.1D0 + + 2.47D0 + 2.47D0 + + 2.D0 + + 1.D0 + 1.D0 + + 1.D0 + + 1.D0 + + 0.2D0 + + 0.001D0 + + 25.D-6 + 25.D-6 + + 1.D0 + 1.D0 + + 1.D0 + 1.D0 + + 1.D0 + 1.D0 + + 1.D8 + 1.D8 + 1 3 @@ -2383,6 +2434,10 @@ 5 1 + -1.0E-3 + 0.5 + 70.0 + 1.0D0 diff --git a/bld/namelist_files/namelist_definition.xml b/bld/namelist_files/namelist_definition.xml index 37ff4d14dd..ac4d3d11de 100644 --- a/bld/namelist_files/namelist_definition.xml +++ b/bld/namelist_files/namelist_definition.xml @@ -2539,6 +2539,60 @@ Efficiency factor for berg Default: 1 + +Unitless ratio to increase the accretion process in microphysics as a method of accounting for unrepresented subgridscale variability. +Default: 1 + + + +Unitless ratio to directly scale the autoconversion process in microphysics as a method of accounting for unrepresented subgridscale variability. +Default: 0.01 + + + +Unitless exponent of cloud number condensation in the KK autoconversion parameterization equation. See Khairoutdinov and Kogan, 2002. +Default: -1.1 + + + +Unitless exponent of liquid water path in the KK autoconversion parameterization equation. See Khairoutdinov and Kogan, 2002. +Default: 2.47 + + + +Mean volume radius of droplets used in the process of homogeneously freezing below -40C in (m). Default value is currently the previously assumed 25 microns. +Default: 25.e-6 m + + + +Unitless scaling factor for ice fall speed to account for sub-grid scale ice crystal shape variability. +Default: 1.0 + + + +Unitless scaling factor for ice effective radius as seen by radiation. This scaling factor adjusts for sub-grid scale ice crystal shape variability. +Default: 1.0 + + + +Ice accrete cloud droplet factor +Default: 1 + + + +Maximum allowed ice number concentration +Default: 1.0e8 + +x Do Seifert and Behang (2001) autoconversion and accretion physics when set to true. @@ -2684,6 +2738,36 @@ prescribed aerosol bulk sulfur scale factor Default: 2 + +Unitless scaling factor for the activated number concentration of cloud condensation nuclei. +Default: 1.0 + + + +Unitless scaling factor for the liquid droplet subgrid scale vertical velocity during aerosol activation. +Default: 1.0 + + + +Unitless scaling factor for ice droplet subgrid scale vertical velocity during aerosol activation. +Default: 1.0 + + + +Minimum subgrid vertical velocity for liquid droplets during aerosol activation with units of (m s-1). +Default: 0.2 m s-1 + + + +Minimum subgrid vertical velocity for ice droplets during aerosol activation with units of (m s-1). +Default: 0.001 m s-1 + + Switch to turn on heterogeneous freezing code. @@ -2945,6 +3029,23 @@ Default: => 1 for CAM6; => 5 for all other + +Tunable entrainment rate in ZM deep convection scheme in units of (m-1). +Default: -1.0e-3 m-1 + + + +Tunable parcel temperature perturbation in ZM deep convection scheme in units of (K). +Default: 0.5K perturbation + + + +Tunable triggering threshold for convection in ZM deep scheme in units of (J kg-1). +Default: 70.0 J kg-1 + @@ -3414,6 +3515,36 @@ C2 coef. for the thlp2_dp1 term C2 coef. for the rtpthlp_dp1 term + +CLUBB tunable parameter - Low Skewness in C6rt Skw. Function + + + +CLUBB tunable parameter - High Skewness in C6rt Skw. Function + + + +CLUBB tunable parameter - Degree of Slope of C6rt Skw. Function + + + +CLUBB tunable parameter - Low Skewness in C6thl Skw. Function + + + +CLUBB tunable parameter - High Skewness in C6thl Skw. Function + + + +CLUBB tunable parameter - Degree of Slope of C6thl Skw. Function + + C4 coefficient in the wp2 return-to-isotropy term. A higher value of C4 @@ -3468,6 +3599,11 @@ Thermo of Kh_zm Default: 0.3 + +CLUBB tunable parameter - Lscale threshold: damp C6 and C7 (units: m) + + Apply liquid supersaturation adjustment code @@ -3529,6 +3665,24 @@ clubb_up2_vp2_factor increases the values of up2 and vp2 at the surface. Coefficient for gustiness near ground. + +Radius of detrained liquid drops as they are used in the CLUBB parameterization in units of (m). +Default: 8.0e-6 m + + + +Radius of detrained ice drops as they are used in the CLUBB parameterization in units of (m). +Default: 25.0e-6 m + + + +Temperature at which detrained water is classified as entirely ice (no liquid) +in the CLUBB parameterization in units of (K). +Default: 238.15 K + = meltpt_temp) & + call endrun(sub//": ERROR: clubb_detphase_lowtemp must be less than 268.15 K") #endif end subroutine clubb_readnl @@ -774,15 +822,12 @@ subroutine clubb_ini_cam(pbuf2d) use rad_constituents, only: rad_cnst_get_info, rad_cnst_get_mode_num_idx, rad_cnst_get_mam_mmr_idx use cam_abortutils, only: endrun - ! From the CLUBB libraries - use clubb_api_module, only: core_rknd, & - iC11, iC11b, ibeta, iSkw_denom_coef, & ! Constant(s) - em_min, & - iC1, iC1b, iC2rt, iC2thl, iC2rtthl, igamma_coef, igamma_coefb, & - imult_coef, ic_K10, iskw_max_mag, & - iC8, iC8b, iC11, iC11b, iC4, iC14, iup2_vp2_factor, params_list - - + ! These are needed to set parameters + use clubb_api_module, only: & + ilambda0_stability_coef, ic_K10, ic_K10h, iC7, iC7b, iC8, iC8b, iC11, iC11b, iC4, & + iC1, iC1b, iC6rt, iC6rtb, iC6rtc, iC6thl, iC6thlb, iC6thlc, iup2_vp2_factor, iwpxp_L_thresh, & + iC14, igamma_coef, igamma_coefb, imult_coef, ilmin_coef, iSkw_denom_coef, ibeta, iskw_max_mag, & + iC2rt, iC2thl, iC2rtthl, ic_K9, inu9, iC_wp2_splat, params_list use clubb_api_module, only: & print_clubb_config_flags_api, & @@ -816,12 +861,6 @@ subroutine clubb_ini_cam(pbuf2d) iiedsclr_thl, & iiedsclr_CO2 - ! These are needed to set parameters - use clubb_api_module, only: & - ilambda0_stability_coef, ic_K10, ic_K10h, iC2rtthl, iC7, iC7b, iC8, iC8b, iC11, iC11b, & - iC14, igamma_coef, imult_coef, ilmin_coef, iSkw_denom_coef, ibeta, iskw_max_mag, & - iC2rt, iC2thl, iC2rtthl, ic_K9, inu9, iC_wp2_splat - use time_manager, only: is_first_step use clubb_api_module, only: hydromet_dim use constituents, only: cnst_get_ind @@ -1022,6 +1061,13 @@ subroutine clubb_ini_cam(pbuf2d) clubb_params(iC2rt) = clubb_C2rt clubb_params(iC2thl) = clubb_C2thl clubb_params(ibeta) = clubb_beta + clubb_params(iC6rt) = clubb_c6rt + clubb_params(iC6rtb) = clubb_c6rtb + clubb_params(iC6rtc) = clubb_c6rtc + clubb_params(iC6thl) = clubb_c6thl + clubb_params(iC6thlb) = clubb_c6thlb + clubb_params(iC6thlc) = clubb_c6thlc + clubb_params(iwpxp_L_thresh) = clubb_wpxp_L_thresh clubb_params(iC7) = clubb_C7 clubb_params(iC7b) = clubb_C7b clubb_params(igamma_coef) = clubb_gamma_coef @@ -1680,6 +1726,7 @@ subroutine clubb_tend_cam( & real(r8) :: qrl_zm(pverp+1-top_lev) real(r8) :: thlp2_rad_out(pverp+1-top_lev) real(r8) :: apply_const, rtm_test + real(r8) :: dl_rad, di_rad, dt_low real(r8), dimension(nparams) :: clubb_params ! These adjustable CLUBB parameters (C1, C2 ...) real(r8), dimension(sclr_dim) :: sclr_tol ! Tolerance on passive scalar [units vary] @@ -1837,6 +1884,10 @@ subroutine clubb_tend_cam( & pdfp_rtp2 = 0._r8 wm_zt_out = 0._r8 + dl_rad = clubb_detliq_rad + di_rad = clubb_detice_rad + dt_low = clubb_detphase_lowtemp + frac_limit = 0.01_r8 ic_limit = 1.e-12_r8 @@ -3075,12 +3126,12 @@ subroutine clubb_tend_cam( & do k=1,pver do i=1,ncol - if( state1%t(i,k) > 268.15_r8 ) then + if( state1%t(i,k) > meltpt_temp ) then dum1 = 0.0_r8 - elseif ( state1%t(i,k) < 238.15_r8 ) then + elseif ( state1%t(i,k) < dt_low ) then dum1 = 1.0_r8 else - dum1 = ( 268.15_r8 - state1%t(i,k) ) / 30._r8 + dum1 = ( meltpt_temp - state1%t(i,k) ) / ( meltpt_temp - dt_low ) endif if (zmconv_microp) then @@ -3088,20 +3139,20 @@ subroutine clubb_tend_cam( & ptend_loc%q(i,k,ixcldice) = difzm(i,k) + dlf2(i,k) * dum1 ptend_loc%q(i,k,ixnumliq) = dnlfzm(i,k) + 3._r8 * ( dlf2(i,k) * ( 1._r8 - dum1 ) ) & - / (4._r8*3.14_r8*10.e-6_r8**3*997._r8) ! Shallow Convection + / (4._r8*3.14_r8*dl_rad**3*997._r8) ! Shallow Convection ptend_loc%q(i,k,ixnumice) = dnifzm(i,k) + 3._r8 * ( dlf2(i,k) * dum1 ) & - / (4._r8*3.14_r8*50.e-6_r8**3*500._r8) ! Shallow Convection + / (4._r8*3.14_r8*di_rad**3*500._r8) ! Shallow Convection ptend_loc%s(i,k) = dlf2(i,k) * dum1 * latice else ptend_loc%q(i,k,ixcldliq) = dlf(i,k) * ( 1._r8 - dum1 ) ptend_loc%q(i,k,ixcldice) = dlf(i,k) * dum1 ptend_loc%q(i,k,ixnumliq) = 3._r8 * ( max(0._r8, ( dlf(i,k) - dlf2(i,k) )) * ( 1._r8 - dum1 ) ) & - / (4._r8*3.14_r8* 8.e-6_r8**3*997._r8) + & ! Deep Convection + / (4._r8*3.14_r8*dl_rad**3*997._r8) + & ! Deep Convection 3._r8 * ( dlf2(i,k) * ( 1._r8 - dum1 ) ) & / (4._r8*3.14_r8*10.e-6_r8**3*997._r8) ! Shallow Convection ptend_loc%q(i,k,ixnumice) = 3._r8 * ( max(0._r8, ( dlf(i,k) - dlf2(i,k) )) * dum1 ) & - / (4._r8*3.14_r8*25.e-6_r8**3*500._r8) + & ! Deep Convection + / (4._r8*3.14_r8*di_rad**3*500._r8) + & ! Deep Convection 3._r8 * ( dlf2(i,k) * dum1 ) & / (4._r8*3.14_r8*50.e-6_r8**3*500._r8) ! Shallow Convection ptend_loc%s(i,k) = dlf(i,k) * dum1 * latice @@ -3238,7 +3289,7 @@ subroutine clubb_tend_cam( & ! deep convective mass flux, read in from pbuf. Since shallow convection is never ! called, the shallow convective mass flux will ALWAYS be zero, ensuring that this cloud ! fraction is purely from deep convection scheme. - deepcu(i,k) = max(0.0_r8,min(0.1_r8*log(1.0_r8+500.0_r8*(cmfmc(i,k+1)-cmfmc_sh(i,k+1))),0.6_r8)) + deepcu(i,k) = max(0.0_r8,min(dp1*log(1.0_r8+dp2*(cmfmc(i,k+1)-cmfmc_sh(i,k+1))),0.6_r8)) shalcu(i,k) = 0._r8 if (deepcu(i,k) <= frac_limit .or. dp_icwmr(i,k) < ic_limit) then diff --git a/src/physics/cam/micro_mg_cam.F90 b/src/physics/cam/micro_mg_cam.F90 index adcafa8305..e2111d1545 100644 --- a/src/physics/cam/micro_mg_cam.F90 +++ b/src/physics/cam/micro_mg_cam.F90 @@ -121,7 +121,20 @@ module micro_mg_cam character(len=16) :: micro_mg_precip_frac_method = 'max_overlap' ! type of precipitation fraction method -real(r8) :: micro_mg_berg_eff_factor = 1.0_r8 ! berg efficiency factor +real(r8), parameter :: unset_r8 = huge(1.0_r8) + +! Tunable namelist parameters (set in atm_in) +real(r8) :: micro_mg_berg_eff_factor = unset_r8 ! berg efficiency factor +real(r8) :: micro_mg_accre_enhan_fact = unset_r8 ! accretion enhancment factor +real(r8) :: micro_mg_autocon_fact = unset_r8 ! autoconversion prefactor +real(r8) :: micro_mg_autocon_nd_exp = unset_r8 ! autoconversion nd exponent +real(r8) :: micro_mg_autocon_lwp_exp = unset_r8 ! autoconversion lwp exponent +real(r8) :: micro_mg_homog_size = unset_r8 ! size of freezing homogeneous ice +real(r8) :: micro_mg_vtrmi_factor = unset_r8 ! ice fall speed factor +real(r8) :: micro_mg_effi_factor = unset_r8 ! ice effective radius factor +real(r8) :: micro_mg_iaccr_factor = unset_r8 ! ice accretion of cloud droplet +real(r8) :: micro_mg_max_nicons = unset_r8 ! max allowed ice number concentration + logical, public :: do_cldliq ! Prognose cldliq flag logical, public :: do_cldice ! Prognose cldice flag @@ -308,12 +321,15 @@ subroutine micro_mg_cam_readnl(nlfile) namelist /micro_mg_nl/ micro_mg_version, micro_mg_sub_version, & micro_mg_do_cldice, micro_mg_do_cldliq, micro_mg_num_steps, & - microp_uniform, micro_mg_dcs, micro_mg_precip_frac_method, & + microp_uniform, micro_mg_dcs, micro_mg_precip_frac_method, & micro_mg_berg_eff_factor, micro_do_sb_physics, micro_mg_adjust_cpt, & - micro_mg_do_hail, micro_mg_do_graupel,micro_mg_ngcons, micro_mg_ngnst,& - micro_mg_nccons, micro_mg_nicons, micro_mg_ncnst, micro_mg_ninst,& - micro_mg_nrcons, micro_mg_nscons, micro_mg_nrnst, micro_mg_nsnst,& - micro_do_massless_droplet_destroyer,& + micro_mg_do_hail, micro_mg_do_graupel, micro_mg_ngcons, micro_mg_ngnst, & + micro_mg_vtrmi_factor, micro_mg_effi_factor, micro_mg_iaccr_factor, & + micro_mg_max_nicons, micro_mg_accre_enhan_fact, & + micro_mg_autocon_fact, micro_mg_autocon_nd_exp, micro_mg_autocon_lwp_exp, micro_mg_homog_size, & + micro_mg_nccons, micro_mg_nicons, micro_mg_ncnst, micro_mg_ninst, & + micro_mg_nrcons, micro_mg_nscons, micro_mg_nrnst, micro_mg_nsnst, & + micro_do_massless_droplet_destroyer, & micro_mg_evap_sed_off, micro_mg_icenuc_rh_off, micro_mg_icenuc_use_meyers, & micro_mg_evap_scl_ifs, micro_mg_evap_rhthrsh_ifs, & micro_mg_rainfreeze_ifs, micro_mg_ifs_sed, micro_mg_precip_fall_corr @@ -412,6 +428,33 @@ subroutine micro_mg_cam_readnl(nlfile) call mpi_bcast(micro_mg_berg_eff_factor, 1, mpi_real8, mstrid, mpicom, ierr) if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: micro_mg_berg_eff_factor") + call mpi_bcast(micro_mg_accre_enhan_fact, 1, mpi_real8, mstrid, mpicom, ierr) + if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: micro_mg_accre_enhan_fact") + + call mpi_bcast(micro_mg_autocon_fact, 1, mpi_real8, mstrid, mpicom, ierr) + if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: micro_mg_autocon_fact") + + call mpi_bcast(micro_mg_autocon_nd_exp, 1, mpi_real8, mstrid, mpicom, ierr) + if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: micro_mg_autocon_nd_exp") + + call mpi_bcast(micro_mg_autocon_lwp_exp, 1, mpi_real8, mstrid, mpicom, ierr) + if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: micro_mg_autocon_lwp_exp") + + call mpi_bcast(micro_mg_homog_size, 1, mpi_real8, mstrid, mpicom, ierr) + if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: micro_mg_homog_size") + + call mpi_bcast(micro_mg_vtrmi_factor, 1, mpi_real8, mstrid, mpicom, ierr) + if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: micro_mg_vtrmi_factor") + + call mpi_bcast(micro_mg_effi_factor, 1, mpi_real8, mstrid, mpicom, ierr) + if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: micro_mg_effi_factor") + + call mpi_bcast(micro_mg_iaccr_factor, 1, mpi_real8, mstrid, mpicom, ierr) + if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: micro_mg_iaccr_factor") + + call mpi_bcast(micro_mg_max_nicons, 1, mpi_real8, mstrid, mpicom, ierr) + if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: micro_mg_max_nicons") + call mpi_bcast(micro_mg_precip_frac_method, 16, mpi_character, mstrid, mpicom, ierr) if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: micro_mg_precip_frac_method") @@ -484,6 +527,17 @@ subroutine micro_mg_cam_readnl(nlfile) call mpi_bcast(micro_mg_precip_fall_corr, 1, mpi_logical, mstrid, mpicom, ierr) if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: micro_mg_precip_fall_corr") + if(micro_mg_berg_eff_factor == unset_r8) call endrun(sub//": FATAL: micro_mg_berg_eff_factor is not set") + if(micro_mg_accre_enhan_fact == unset_r8) call endrun(sub//": FATAL: micro_mg_accre_enhan_fact is not set") + if(micro_mg_autocon_fact == unset_r8) call endrun(sub//": FATAL: micro_mg_autocon_fact is not set") + if(micro_mg_autocon_nd_exp == unset_r8) call endrun(sub//": FATAL: micro_mg_autocon_nd_exp is not set") + if(micro_mg_autocon_lwp_exp == unset_r8) call endrun(sub//": FATAL: micro_mg_autocon_lwp_exp is not set") + if(micro_mg_homog_size == unset_r8) call endrun(sub//": FATAL: micro_mg_homog_size is not set") + if(micro_mg_vtrmi_factor == unset_r8) call endrun(sub//": FATAL: micro_mg_vtrmi_factor is not set") + if(micro_mg_effi_factor == unset_r8) call endrun(sub//": FATAL: micro_mg_effi_factor is not set") + if(micro_mg_iaccr_factor == unset_r8) call endrun(sub//": FATAL: micro_mg_iaccr_factor is not set") + if(micro_mg_max_nicons == unset_r8) call endrun(sub//": FATAL: micro_mg_max_nicons is not set") + if (masterproc) then write(iulog,*) 'MG microphysics namelist:' @@ -495,6 +549,15 @@ subroutine micro_mg_cam_readnl(nlfile) write(iulog,*) ' microp_uniform = ', microp_uniform write(iulog,*) ' micro_mg_dcs = ', micro_mg_dcs write(iulog,*) ' micro_mg_berg_eff_factor = ', micro_mg_berg_eff_factor + write(iulog,*) ' micro_mg_accre_enhan_fact = ', micro_mg_accre_enhan_fact + write(iulog,*) ' micro_mg_autocon_fact = ' , micro_mg_autocon_fact + write(iulog,*) ' micro_mg_autocon_nd_exp = ' , micro_mg_autocon_nd_exp + write(iulog,*) ' micro_mg_autocon_lwp_exp = ' , micro_mg_autocon_lwp_exp + write(iulog,*) ' micro_mg_homog_size = ', micro_mg_homog_size + write(iulog,*) ' micro_mg_vtrmi_factor = ', micro_mg_vtrmi_factor + write(iulog,*) ' micro_mg_effi_factor = ', micro_mg_effi_factor + write(iulog,*) ' micro_mg_iaccr_factor = ', micro_mg_iaccr_factor + write(iulog,*) ' micro_mg_max_nicons = ', micro_mg_max_nicons write(iulog,*) ' micro_mg_precip_frac_method = ', micro_mg_precip_frac_method write(iulog,*) ' micro_do_sb_physics = ', micro_do_sb_physics write(iulog,*) ' micro_mg_adjust_cpt = ', micro_mg_adjust_cpt @@ -897,6 +960,10 @@ subroutine micro_mg_cam_init(pbuf2d) micro_mg_do_hail,micro_mg_do_graupel, & microp_uniform, do_cldice, use_hetfrz_classnuc, & micro_mg_precip_frac_method, micro_mg_berg_eff_factor, & + micro_mg_accre_enhan_fact , & + micro_mg_autocon_fact , micro_mg_autocon_nd_exp, micro_mg_autocon_lwp_exp, micro_mg_homog_size, & + micro_mg_vtrmi_factor, micro_mg_effi_factor, micro_mg_iaccr_factor, & + micro_mg_max_nicons, & allow_sed_supersat, micro_do_sb_physics, & micro_mg_evap_sed_off, micro_mg_icenuc_rh_off, micro_mg_icenuc_use_meyers, & micro_mg_evap_scl_ifs, micro_mg_evap_rhthrsh_ifs, & @@ -2575,9 +2642,9 @@ subroutine micro_mg_cam_tend_pack(state, ptend, dtime, pbuf, mgncol, mgcols, nle packed_pra, packed_prc, & packed_mnuccc, packed_mnucct, packed_msacwi, & packed_psacws, packed_bergs, packed_berg, & - packed_melt, packed_meltstot, packed_meltgtot, packed_homo, & + packed_melt, packed_meltstot,packed_meltgtot, packed_homo, & packed_qcres, packed_prci, packed_prai, & - packed_qires, packed_mnuccr, packed_mnudeptot, packed_mnuccri, packed_pracs, & + packed_qires, packed_mnuccr, packed_mnudeptot, packed_mnuccri, packed_pracs, & packed_meltsdt, packed_frzrdt, packed_mnuccd, & packed_pracg, packed_psacwg, packed_pgsacw, & packed_pgracs, packed_prdg, & diff --git a/src/physics/cam/microp_aero.F90 b/src/physics/cam/microp_aero.F90 index d6d2468214..047eec819b 100644 --- a/src/physics/cam/microp_aero.F90 +++ b/src/physics/cam/microp_aero.F90 @@ -54,8 +54,8 @@ module microp_aero public :: microp_aero_init, microp_aero_run, microp_aero_readnl, microp_aero_register ! Private module data - character(len=16) :: eddy_scheme +real(r8), parameter :: unset_r8 = huge(1.0_r8) ! contact freezing due to dust ! dust number mean radius (m), Zender et al JGR 2003 assuming number mode radius of 0.6 micron, sigma=2 @@ -64,7 +64,13 @@ module microp_aero real(r8), parameter :: rn_dst3 = 1.576e-6_r8 real(r8), parameter :: rn_dst4 = 3.026e-6_r8 +! Namelist parameters real(r8) :: bulk_scale ! prescribed aerosol bulk sulfur scale factor +real(r8) :: npccn_scale ! scaling for activated number +real(r8) :: wsub_scale ! scaling for sub-grid vertical velocity (liquid) +real(r8) :: wsubi_scale ! scaling for sub-grid vertical velocity (ice) +real(r8) :: wsub_min ! minimum sub-grid vertical velocity (liquid) +real(r8) :: wsubi_min ! minimum sub-grid vertical velocity (ice) ! smallest mixing ratio considered in microphysics real(r8), parameter :: qsmall = 1.e-18_r8 @@ -311,18 +317,26 @@ subroutine microp_aero_readnl(nlfile) use namelist_utils, only: find_group_name use units, only: getunit, freeunit - use mpishorthand + use spmd_utils, only: mpicom, mstrid=>masterprocid, mpi_integer, mpi_real8, & + mpi_logical, mpi_character character(len=*), intent(in) :: nlfile ! filepath for file containing namelist input ! Namelist variables - real(r8) :: microp_aero_bulk_scale = 2._r8 ! prescribed aerosol bulk sulfur scale factor - + real(r8) :: microp_aero_bulk_scale = unset_r8 ! prescribed aerosol bulk sulfur scale factor + real(r8) :: microp_aero_npccn_scale = unset_r8 ! prescribed aerosol bulk sulfur scale factor + real(r8) :: microp_aero_wsub_scale = unset_r8 ! subgrid vertical velocity (liquid) scale factor + real(r8) :: microp_aero_wsubi_scale = unset_r8 ! subgrid vertical velocity (ice) scale factor + real(r8) :: microp_aero_wsub_min = unset_r8 ! subgrid vertical velocity (liquid) minimum + real(r8) :: microp_aero_wsubi_min = unset_r8 ! subgrid vertical velocity (ice) minimum + + ! Local variables integer :: unitn, ierr character(len=*), parameter :: subname = 'microp_aero_readnl' - namelist /microp_aero_nl/ microp_aero_bulk_scale + namelist /microp_aero_nl/ microp_aero_bulk_scale, microp_aero_npccn_scale, microp_aero_wsub_min, & + microp_aero_wsubi_min, microp_aero_wsub_scale, microp_aero_wsubi_scale !----------------------------------------------------------------------------- if (masterproc) then @@ -339,13 +353,34 @@ subroutine microp_aero_readnl(nlfile) call freeunit(unitn) end if -#ifdef SPMD - ! Broadcast namelist variable - call mpibcast(microp_aero_bulk_scale, 1, mpir8, 0, mpicom) -#endif + ! Broadcast namelist variables + call mpi_bcast(microp_aero_bulk_scale, 1, mpi_real8, mstrid, mpicom, ierr) + if (ierr /= 0) call endrun(subname//": FATAL: mpi_bcast: microp_aero_bulk_scale") + call mpi_bcast(microp_aero_npccn_scale, 1, mpi_real8, mstrid, mpicom, ierr) + if (ierr /= 0) call endrun(subname//": FATAL: mpi_bcast: microp_aero_npccn_scale") + call mpi_bcast(microp_aero_wsub_scale, 1, mpi_real8, mstrid, mpicom, ierr) + if (ierr /= 0) call endrun(subname//": FATAL: mpi_bcast: microp_aero_wsub_scale") + call mpi_bcast(microp_aero_wsubi_scale, 1, mpi_real8, mstrid, mpicom, ierr) + if (ierr /= 0) call endrun(subname//": FATAL: mpi_bcast: microp_aero_wsubi_scale") + call mpi_bcast(microp_aero_wsub_min, 1, mpi_real8, mstrid, mpicom, ierr) + if (ierr /= 0) call endrun(subname//": FATAL: mpi_bcast: microp_aero_wsub_min") + call mpi_bcast(microp_aero_wsubi_min, 1, mpi_real8, mstrid, mpicom, ierr) + if (ierr /= 0) call endrun(subname//": FATAL: mpi_bcast: microp_aero_wsubi_min") ! set local variables bulk_scale = microp_aero_bulk_scale + npccn_scale = microp_aero_npccn_scale + wsub_scale = microp_aero_wsub_scale + wsubi_scale = microp_aero_wsubi_scale + wsub_min = microp_aero_wsub_min + wsubi_min = microp_aero_wsubi_min + + if(bulk_scale == unset_r8) call endrun(subname//": FATAL: bulk_scale is not set") + if(npccn_scale == unset_r8) call endrun(subname//": FATAL: npccn_scale is not set") + if(wsub_scale == unset_r8) call endrun(subname//": FATAL: wsub_scale is not set") + if(wsubi_scale == unset_r8) call endrun(subname//": FATAL: wsubi_scale is not set") + if(wsub_min == unset_r8) call endrun(subname//": FATAL: wsub_min is not set") + if(wsubi_min == unset_r8) call endrun(subname//": FATAL: wsubi_min is not set") call nucleate_ice_cam_readnl(nlfile) call hetfrz_classnuc_cam_readnl(nlfile) @@ -523,8 +558,8 @@ subroutine microp_aero_run ( & end select ! Set minimum values above top_lev. - wsub(:ncol,:top_lev-1) = 0.20_r8 - wsubi(:ncol,:top_lev-1) = 0.001_r8 + wsub(:ncol,:top_lev-1) = wsub_min + wsubi(:ncol,:top_lev-1) = wsubi_min do k = top_lev, pver do i = 1, ncol @@ -544,12 +579,12 @@ subroutine microp_aero_run ( & wsub(i,k) = dum end select - wsubi(i,k) = max(0.001_r8, wsub(i,k)) + wsubi(i,k) = max(wsubi_min, wsub(i,k)) * wsubi_scale if (.not. use_preexisting_ice) then wsubi(i,k) = min(wsubi(i,k), 0.2_r8) endif - wsub(i,k) = max(0.20_r8, wsub(i,k)) + wsub(i,k) = max(wsub_min, wsub(i,k)) * wsub_scale end do end do @@ -615,6 +650,8 @@ subroutine microp_aero_run ( & npccn(:ncol,:) = nctend_mixnuc(:ncol,:) + npccn(:ncol,:) = npccn(:ncol,:) * npccn_scale + else ! for bulk aerosol diff --git a/src/physics/cam/ndrop.F90 b/src/physics/cam/ndrop.F90 index aa545c8032..d7e853c61f 100644 --- a/src/physics/cam/ndrop.F90 +++ b/src/physics/cam/ndrop.F90 @@ -508,6 +508,7 @@ subroutine dropmixnuc( & factnum = 0._r8 wtke = 0._r8 + tendnd = 0._r8 if (prog_modal_aero) then ! aerosol tendencies diff --git a/src/physics/cam/zm_conv.F90 b/src/physics/cam/zm_conv.F90 index 390d342bf5..fbf01a3f1e 100644 --- a/src/physics/cam/zm_conv.F90 +++ b/src/physics/cam/zm_conv.F90 @@ -40,7 +40,8 @@ module zm_conv ! real(r8) rl ! wg latent heat of vaporization. real(r8) cpres ! specific heat at constant pressure in j/kg-degk. - real(r8), parameter :: capelmt = 70._r8 ! threshold value for cape for deep convection. + real(r8) :: capelmt ! namelist configurable: + ! threshold value for cape for deep convection. real(r8) :: ke ! Tunable evaporation efficiency set from namelist input zmconv_ke real(r8) :: ke_lnd real(r8) :: c0_lnd ! set from namelist input zmconv_c0_lnd @@ -72,14 +73,16 @@ module zm_conv integer limcnv ! top interface level limit for convection - real(r8),parameter :: tiedke_add = 0.5_r8 + real(r8) :: tiedke_add ! namelist configurable + real(r8) :: dmpdz_param ! namelist configurable contains subroutine zm_convi(limcnv_in, zmconv_c0_lnd, zmconv_c0_ocn, zmconv_ke, zmconv_ke_lnd, & zmconv_momcu, zmconv_momcd, zmconv_num_cin, zmconv_org, & - zmconv_microp_in, no_deep_pbl_in) + zmconv_microp_in, no_deep_pbl_in, zmconv_tiedke_add, & + zmconv_capelmt, zmconv_dmpdz) integer, intent(in) :: limcnv_in ! top interface level limit for convection integer, intent(in) :: zmconv_num_cin ! Number negative buoyancy regions that are allowed @@ -92,7 +95,10 @@ subroutine zm_convi(limcnv_in, zmconv_c0_lnd, zmconv_c0_ocn, zmconv_ke, zmconv_k real(r8),intent(in) :: zmconv_momcd logical :: zmconv_org logical, intent(in) :: zmconv_microp_in - logical, intent(in), optional :: no_deep_pbl_in ! no_deep_pbl = .true. eliminates ZM convection entirely within PBL + logical, intent(in) :: no_deep_pbl_in ! no_deep_pbl = .true. eliminates ZM convection entirely within PBL + real(r8),intent(in) :: zmconv_tiedke_add + real(r8),intent(in) :: zmconv_capelmt + real(r8),intent(in) :: zmconv_dmpdz ! Initialization of ZM constants @@ -117,11 +123,10 @@ subroutine zm_convi(limcnv_in, zmconv_c0_lnd, zmconv_c0_ocn, zmconv_ke, zmconv_k zmconv_microp = zmconv_microp_in - if ( present(no_deep_pbl_in) ) then - no_deep_pbl = no_deep_pbl_in - else - no_deep_pbl = .false. - endif + tiedke_add = zmconv_tiedke_add + capelmt = zmconv_capelmt + dmpdz_param = zmconv_dmpdz + no_deep_pbl = no_deep_pbl_in tau = 3600._r8 @@ -131,6 +136,9 @@ subroutine zm_convi(limcnv_in, zmconv_c0_lnd, zmconv_c0_ocn, zmconv_ke, zmconv_k write(iulog,*) 'tuning parameters zm_convi: num_cin', num_cin write(iulog,*) 'tuning parameters zm_convi: ke',ke write(iulog,*) 'tuning parameters zm_convi: no_deep_pbl',no_deep_pbl + write(iulog,*) 'tuning parameters zm_convi: zm_capelmt', capelmt + write(iulog,*) 'tuning parameters zm_convi: zm_dmpdz', dmpdz_param + write(iulog,*) 'tuning parameters zm_convi: zm_tiedke_add', tiedke_add endif if (masterproc) write(iulog,*)'**** ZM: DILUTE Buoyancy Calculation ****' @@ -4325,7 +4333,7 @@ subroutine parcel_dilute (lchnk, ncol, msg, klaunch, p, t, q, & org2Tpert = 0._r8 endif nit_lheat = 2 ! iterations for ds,dq changes from condensation freezing. -dmpdz=-1.e-3_r8 ! Entrainment rate. (-ve for /m) +dmpdz=dmpdz_param ! Entrainment rate. (-ve for /m) dmpdz_lnd=-1.e-3_r8 !dmpdpc = 3.e-2_r8 ! In cloud entrainment rate (/mb). lwmax = 1.e-3_r8 ! Need to put formula in for this. diff --git a/src/physics/cam/zm_conv_intr.F90 b/src/physics/cam/zm_conv_intr.F90 index 336f5e464d..61f22756cb 100644 --- a/src/physics/cam/zm_conv_intr.F90 +++ b/src/physics/cam/zm_conv_intr.F90 @@ -11,6 +11,7 @@ module zm_conv_intr use physconst, only: cpair use ppgrid, only: pver, pcols, pverp, begchunk, endchunk use zm_conv, only: zm_conv_evap, zm_convr, convtran, momtran + use zm_microphysics, only: zm_aero_t, zm_conv_t use rad_constituents, only: rad_cnst_get_info, rad_cnst_get_mode_num, rad_cnst_get_aer_mmr, & rad_cnst_get_aer_props, rad_cnst_get_mode_props !, & @@ -72,6 +73,9 @@ module zm_conv_intr logical :: zmconv_org ! Parameterization for sub-grid scale convective organization for the ZM deep ! convective scheme based on Mapes and Neale (2011) logical :: zmconv_microp = .false. ! switch for microphysics + real(r8) :: zmconv_dmpdz = unset_r8 ! Parcel fractional mass entrainment rate + real(r8) :: zmconv_tiedke_add = unset_r8 ! Convective parcel temperature perturbation + real(r8) :: zmconv_capelmt = unset_r8 ! Triggering thereshold for ZM convection ! indices for fields in the physics buffer @@ -178,7 +182,8 @@ subroutine zm_conv_readnl(nlfile) namelist /zmconv_nl/ zmconv_c0_lnd, zmconv_c0_ocn, zmconv_num_cin, & zmconv_ke, zmconv_ke_lnd, zmconv_org, & - zmconv_momcu, zmconv_momcd, zmconv_microp + zmconv_momcu, zmconv_momcd, zmconv_microp, & + zmconv_dmpdz, zmconv_tiedke_add, zmconv_capelmt !----------------------------------------------------------------------------- if (masterproc) then @@ -215,6 +220,12 @@ subroutine zm_conv_readnl(nlfile) if (ierr /= 0) call endrun("zm_conv_readnl: FATAL: mpi_bcast: zmconv_org") call mpi_bcast(zmconv_microp, 1, mpi_logical, masterprocid, mpicom, ierr) if (ierr /= 0) call endrun("zm_conv_readnl: FATAL: mpi_bcast: zmconv_microp") + call mpi_bcast(zmconv_dmpdz, 1, mpi_real8, masterprocid, mpicom, ierr) + if (ierr /= 0) call endrun("zm_conv_readnl: FATAL: mpi_bcast: zmconv_dmpdz") + call mpi_bcast(zmconv_tiedke_add, 1, mpi_real8, masterprocid, mpicom, ierr) + if (ierr /= 0) call endrun("zm_conv_readnl: FATAL: mpi_bcast: zmconv_tiedke_add") + call mpi_bcast(zmconv_capelmt, 1, mpi_real8, masterprocid, mpicom, ierr) + if (ierr /= 0) call endrun("zm_conv_readnl: FATAL: mpi_bcast: zmconv_capelmt") end subroutine zm_conv_readnl @@ -352,7 +363,8 @@ subroutine zm_conv_init(pref_edge) no_deep_pbl = phys_deepconv_pbl() call zm_convi(limcnv,zmconv_c0_lnd, zmconv_c0_ocn, zmconv_ke, zmconv_ke_lnd, & zmconv_momcu, zmconv_momcd, zmconv_num_cin, zmconv_org, & - zmconv_microp, no_deep_pbl_in = no_deep_pbl) + zmconv_microp, no_deep_pbl, zmconv_tiedke_add, & + zmconv_capelmt, zmconv_dmpdz) cld_idx = pbuf_get_index('CLD') fracis_idx = pbuf_get_index('FRACIS')