diff --git a/components/eamxx/cime_config/namelist_defaults_scream.xml b/components/eamxx/cime_config/namelist_defaults_scream.xml index 7e92482e676..1af05590da4 100644 --- a/components/eamxx/cime_config/namelist_defaults_scream.xml +++ b/components/eamxx/cime_config/namelist_defaults_scream.xml @@ -214,6 +214,7 @@ be lost if SCREAM_HACK_XML is not enabled. 0.304 1.0 0.00028 + true diff --git a/components/eamxx/src/physics/p3/disp/p3_main_impl_disp.cpp b/components/eamxx/src/physics/p3/disp/p3_main_impl_disp.cpp index 424bd8424f1..a4df2e6bbf7 100644 --- a/components/eamxx/src/physics/p3/disp/p3_main_impl_disp.cpp +++ b/components/eamxx/src/physics/p3/disp/p3_main_impl_disp.cpp @@ -123,6 +123,8 @@ ::p3_main_internal_disp( const Int kbot = kdir == -1 ? nk-1 : 0; constexpr bool debug_ABORT = false; + const bool do_ice_production = runtime_options.p3_do_ice_production; + // per-column bools view_1d nucleationPossible("nucleationPossible", nj); view_1d hydrometeorsPresent("hydrometeorsPresent", nj); @@ -294,9 +296,11 @@ ::p3_main_internal_disp( lookup_tables.ice_table_vals, diagnostic_outputs.precip_ice_surf, nucleationPossible, hydrometeorsPresent, runtime_options); // homogeneous freezing f cloud and rain - homogeneous_freezing_disp( - T_atm, inv_exner, nj, nk, ktop, kbot, kdir, qc, nc, qr, nr, qi, - ni, qm, bm, th, nucleationPossible, hydrometeorsPresent); + if(do_ice_production) { + homogeneous_freezing_disp(T_atm, inv_exner, nj, nk, ktop, kbot, kdir, qc, + nc, qr, nr, qi, ni, qm, bm, th, + nucleationPossible, hydrometeorsPresent); + } // // final checks to ensure consistency of mass/number @@ -334,4 +338,3 @@ ::p3_main_internal_disp( } // namespace p3 } // namespace scream - diff --git a/components/eamxx/src/physics/p3/eamxx_p3_process_interface.cpp b/components/eamxx/src/physics/p3/eamxx_p3_process_interface.cpp index 7285e699246..e822435d870 100644 --- a/components/eamxx/src/physics/p3/eamxx_p3_process_interface.cpp +++ b/components/eamxx/src/physics/p3/eamxx_p3_process_interface.cpp @@ -233,6 +233,7 @@ void P3Microphysics::initialize_impl (const RunType /* run_type */) runtime_options.p3_dep_nucleation_exponent = m_params.get("p3_dep_nucleation_exponent", 0.304); runtime_options.p3_ice_sed_knob = m_params.get("p3_ice_sed_knob", 1.0); runtime_options.p3_d_breakup_cutoff = m_params.get("p3_d_breakup_cutoff", 0.00028); + runtime_options.p3_do_ice_production = m_params.get("p3_do_ice_production", true); // Set property checks for fields in this process add_invariant_check(get_field_out("T_mid"),m_grid,100.0,500.0,false); diff --git a/components/eamxx/src/physics/p3/impl/p3_main_impl.hpp b/components/eamxx/src/physics/p3/impl/p3_main_impl.hpp index e5d47c34584..3503f9e5adb 100644 --- a/components/eamxx/src/physics/p3/impl/p3_main_impl.hpp +++ b/components/eamxx/src/physics/p3/impl/p3_main_impl.hpp @@ -99,6 +99,8 @@ ::p3_main_internal( const Int kbot = kdir == -1 ? nk-1 : 0; constexpr bool debug_ABORT = false; + const bool do_ice_production = runtime_options.p3_do_ice_production; + // we do not want to measure init stuff auto start = std::chrono::steady_clock::now(); @@ -287,9 +289,10 @@ ::p3_main_internal( lookup_tables.ice_table_vals, diagnostic_outputs.precip_ice_surf(i), runtime_options); // homogeneous freezing of cloud and rain - homogeneous_freezing( - T_atm, oinv_exner, team, nk, ktop, kbot, kdir, oqc, onc, oqr, onr, oqi, - oni, oqm, obm, oth); + if(do_ice_production) { + homogeneous_freezing(T_atm, oinv_exner, team, nk, ktop, kbot, kdir, oqc, + onc, oqr, onr, oqi, oni, oqm, obm, oth); + } // // final checks to ensure consistency of mass/number diff --git a/components/eamxx/src/physics/p3/impl/p3_main_impl_part2.hpp b/components/eamxx/src/physics/p3/impl/p3_main_impl_part2.hpp index 372c83f3d1f..823d74399c8 100644 --- a/components/eamxx/src/physics/p3/impl/p3_main_impl_part2.hpp +++ b/components/eamxx/src/physics/p3/impl/p3_main_impl_part2.hpp @@ -104,6 +104,8 @@ ::p3_main_part2( constexpr Scalar latvap = C::LatVap; constexpr Scalar latice = C::LatIce; + const bool do_ice_production = runtime_options.p3_do_ice_production; + team.team_barrier(); hydrometeorsPresent = false; team.team_barrier(); @@ -266,61 +268,77 @@ ::p3_main_part2( // ice processes // ...................................................................... - // collection of droplets - ice_cldliq_collection( - rho(k), T_atm(k), rhofaci(k), table_val_qc2qi_collect, qi_incld(k), qc_incld(k), ni_incld(k), nc_incld(k), - qc2qi_collect_tend, nc_collect_tend, qc2qr_ice_shed_tend, ncshdc, runtime_options, not_skip_micro); - - // collection of rain - ice_rain_collection( - rho(k), T_atm(k), rhofaci(k), logn0r(k), table_val_nr_collect, table_val_qr2qi_collect, qi_incld(k), ni_incld(k), qr_incld(k), - qr2qi_collect_tend, nr_collect_tend, runtime_options, not_skip_micro); - - // collection between ice categories - - // PMC nCat deleted lots of stuff here. - - // self-collection of ice - ice_self_collection( - rho(k), rhofaci(k), table_val_ni_self_collect, eii, qm_incld(k), qi_incld(k), ni_incld(k), - ni_selfcollect_tend, not_skip_micro); + if(do_ice_production) { + // collection of droplets + ice_cldliq_collection(rho(k), T_atm(k), rhofaci(k), + table_val_qc2qi_collect, qi_incld(k), qc_incld(k), + ni_incld(k), nc_incld(k), qc2qi_collect_tend, + nc_collect_tend, qc2qr_ice_shed_tend, ncshdc, + runtime_options, not_skip_micro); + + // collection of rain + ice_rain_collection(rho(k), T_atm(k), rhofaci(k), logn0r(k), + table_val_nr_collect, table_val_qr2qi_collect, + qi_incld(k), ni_incld(k), qr_incld(k), + qr2qi_collect_tend, nr_collect_tend, + runtime_options, not_skip_micro); + + // collection between ice categories + + // PMC nCat deleted lots of stuff here. + + // self-collection of ice + ice_self_collection(rho(k), rhofaci(k), table_val_ni_self_collect, eii, + qm_incld(k), qi_incld(k), ni_incld(k), + ni_selfcollect_tend, not_skip_micro); + } // melting - ice_melting( - rho(k), T_atm(k), pres(k), rhofaci(k), table_val_qi2qr_melting, table_val_qi2qr_vent_melt, dv, sc, mu, kap, qv(k), qi_incld(k), ni_incld(k), - qi2qr_melt_tend, ni2nr_melt_tend, not_skip_micro); - - // calculate wet growth - ice_cldliq_wet_growth( - rho(k), T_atm(k), pres(k), rhofaci(k), table_val_qi2qr_melting, table_val_qi2qr_vent_melt, - dv, kap, mu, sc, qv(k), qc_incld(k), qi_incld(k), ni_incld(k), qr_incld(k), - wetgrowth, qr2qi_collect_tend, qc2qi_collect_tend, qc_growth_rate, nr_ice_shed_tend, qc2qr_ice_shed_tend, not_skip_micro); - - // calculate total inverse ice relaxation timescale combined for all ice categories - // note 'f1pr' values are normalized, so we need to multiply by N + ice_melting(rho(k), T_atm(k), pres(k), rhofaci(k), + table_val_qi2qr_melting, table_val_qi2qr_vent_melt, dv, sc, + mu, kap, qv(k), qi_incld(k), ni_incld(k), qi2qr_melt_tend, + ni2nr_melt_tend, not_skip_micro); + + if(do_ice_production) { + // calculate wet growth + ice_cldliq_wet_growth( + rho(k), T_atm(k), pres(k), rhofaci(k), table_val_qi2qr_melting, + table_val_qi2qr_vent_melt, dv, kap, mu, sc, qv(k), qc_incld(k), + qi_incld(k), ni_incld(k), qr_incld(k), wetgrowth, + qr2qi_collect_tend, qc2qi_collect_tend, qc_growth_rate, + nr_ice_shed_tend, qc2qr_ice_shed_tend, not_skip_micro); + } + + // calculate total inverse ice relaxation timescale combined for all ice + // categories note 'f1pr' values are normalized, so we need to multiply + // by N ice_relaxation_timescale( - rho(k), T_atm(k), rhofaci(k), table_val_qi2qr_melting, table_val_qi2qr_vent_melt, dv, mu, sc, qi_incld(k), ni_incld(k), - epsi, epsi_tot, not_skip_micro); + rho(k), T_atm(k), rhofaci(k), table_val_qi2qr_melting, + table_val_qi2qr_vent_melt, dv, mu, sc, qi_incld(k), ni_incld(k), epsi, + epsi_tot, not_skip_micro); // calculate rime density - calc_rime_density( - T_atm(k), rhofaci(k), table_val_qi_fallspd, acn(k), lamc(k), mu_c(k), qc_incld(k), qc2qi_collect_tend, - vtrmi1, rho_qm_cloud, not_skip_micro); - - // contact and immersion freezing droplets - cldliq_immersion_freezing( - T_atm(k), lamc(k), mu_c(k), cdist1(k), qc_incld(k), inv_qc_relvar(k), - qc2qi_hetero_freeze_tend, nc2ni_immers_freeze_tend, runtime_options, not_skip_micro); - - // for future: get rid of log statements below for rain freezing - rain_immersion_freezing( - T_atm(k), lamr(k), mu_r(k), cdistr(k), qr_incld(k), - qr2qi_immers_freeze_tend, nr2ni_immers_freeze_tend, runtime_options, not_skip_micro); - - // rime splintering (Hallet-Mossop 1974) - // PMC comment: Morrison and Milbrandt 2015 part 1 and 2016 part 3 both say - // that Hallet-Mossop should be neglected if 1 category to compensate for - // artificial smearing out of ice DSD + calc_rime_density(T_atm(k), rhofaci(k), table_val_qi_fallspd, acn(k), + lamc(k), mu_c(k), qc_incld(k), qc2qi_collect_tend, + vtrmi1, rho_qm_cloud, not_skip_micro); + + if(do_ice_production) { + // contact and immersion freezing droplets + cldliq_immersion_freezing( + T_atm(k), lamc(k), mu_c(k), cdist1(k), qc_incld(k), + inv_qc_relvar(k), qc2qi_hetero_freeze_tend, + nc2ni_immers_freeze_tend, runtime_options, not_skip_micro); + + // for future: get rid of log statements below for rain freezing + rain_immersion_freezing(T_atm(k), lamr(k), mu_r(k), cdistr(k), + qr_incld(k), qr2qi_immers_freeze_tend, + nr2ni_immers_freeze_tend, runtime_options, + not_skip_micro); + // rime splintering (Hallet-Mossop 1974) + // PMC comment: Morrison and Milbrandt 2015 part 1 and 2016 part 3 both + // say that Hallet-Mossop should be neglected if 1 category to + // compensate for artificial smearing out of ice DSD + } // ................................................ // condensation/evaporation/deposition/sublimation @@ -336,15 +354,22 @@ ::p3_main_part2( ab,abi,epsr,epsi_tot,T_atm(k),t_prev(k),dqsdt,dt, qr2qv_evap_tend,nr_evap_tend, not_skip_micro); - ice_deposition_sublimation( - qi_incld(k), ni_incld(k), T_atm(k), qv_sat_l(k), qv_sat_i(k), epsi, abi, qv(k), inv_dt, - qv2qi_vapdep_tend, qi2qv_sublim_tend, ni_sublim_tend, qc2qi_berg_tend, not_skip_micro); + if(do_ice_production) { + ice_deposition_sublimation( + qi_incld(k), ni_incld(k), T_atm(k), qv_sat_l(k), qv_sat_i(k), epsi, + abi, qv(k), inv_dt, qv2qi_vapdep_tend, qi2qv_sublim_tend, + ni_sublim_tend, qc2qi_berg_tend, not_skip_micro); + } + } // deposition/condensation-freezing nucleation - ice_nucleation( - T_atm(k), inv_rho(k), ni(k), ni_activated(k), qv_supersat_i(k), inv_dt, predictNc, do_prescribed_CCN, - qv2qi_nucleat_tend, ni_nucleat_tend, runtime_options, not_skip_all); + if(do_ice_production) { + ice_nucleation(T_atm(k), inv_rho(k), ni(k), ni_activated(k), + qv_supersat_i(k), inv_dt, predictNc, do_prescribed_CCN, + qv2qi_nucleat_tend, ni_nucleat_tend, runtime_options, + not_skip_all); + } // cloud water autoconversion // NOTE: cloud_water_autoconversion must be called before droplet_self_collection diff --git a/components/eamxx/src/physics/p3/p3_functions.hpp b/components/eamxx/src/physics/p3/p3_functions.hpp index 18a1e42782d..24e8dd7998c 100644 --- a/components/eamxx/src/physics/p3/p3_functions.hpp +++ b/components/eamxx/src/physics/p3/p3_functions.hpp @@ -122,6 +122,7 @@ struct Functions Scalar p3_dep_nucleation_exponent = 0.304; Scalar p3_ice_sed_knob = 1.0; Scalar p3_d_breakup_cutoff = 0.00028; + bool p3_do_ice_production = true; }; // This struct stores prognostic variables evolved by P3.