diff --git a/components/eamxx/cime_config/namelist_defaults_scream.xml b/components/eamxx/cime_config/namelist_defaults_scream.xml index 9a06de10e1ec..ecda96b7162e 100644 --- a/components/eamxx/cime_config/namelist_defaults_scream.xml +++ b/components/eamxx/cime_config/namelist_defaults_scream.xml @@ -192,6 +192,7 @@ be lost if SCREAM_HACK_XML is not enabled. true + false false true false diff --git a/components/eamxx/src/physics/p3/CMakeLists.txt b/components/eamxx/src/physics/p3/CMakeLists.txt index 0d3bc962fdef..48c1ac2fb4fc 100644 --- a/components/eamxx/src/physics/p3/CMakeLists.txt +++ b/components/eamxx/src/physics/p3/CMakeLists.txt @@ -26,6 +26,7 @@ if (NOT EAMXX_ENABLE_GPU OR Kokkos_ENABLE_CUDA_RELOCATABLE_DEVICE_CODE OR Kokkos eti/p3_back_to_cell_average.cpp eti/p3_cloud_rain_acc.cpp eti/p3_calc_rime_density.cpp + eti/p3_ice_classical_nucleation_impl.cpp eti/p3_cldliq_imm_freezing.cpp eti/p3_rain_imm_freezing.cpp eti/p3_droplet_self_coll.cpp 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 99a2381ca23d..d4c3d5300bb1 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 @@ -163,6 +163,11 @@ ::p3_main_internal_disp( auto nevapr = diagnostic_outputs.nevapr; auto qv_prev = diagnostic_inputs.qv_prev; auto t_prev = diagnostic_inputs.t_prev; + // Inputs for the heteogeneous freezing + auto hetfrz_immersion_nucleation_tend = diagnostic_inputs.hetfrz_immersion_nucleation_tend; + auto hetfrz_contact_nucleation_tend = diagnostic_inputs.hetfrz_contact_nucleation_tend; + auto hetfrz_deposition_nucleation_tend = diagnostic_inputs.hetfrz_deposition_nucleation_tend; + auto liq_ice_exchange = history_only.liq_ice_exchange; auto vap_liq_exchange = history_only.vap_liq_exchange; auto vap_ice_exchange = history_only.vap_ice_exchange; @@ -252,6 +257,7 @@ ::p3_main_internal_disp( p3_main_part2_disp( nj, nk, runtime_options.max_total_ni, infrastructure.predictNc, infrastructure.prescribedCCN, infrastructure.dt, inv_dt, + hetfrz_immersion_nucleation_tend, hetfrz_contact_nucleation_tend, hetfrz_deposition_nucleation_tend, lookup_tables.dnu_table_vals, lookup_tables.ice_table_vals, lookup_tables.collect_table_vals, lookup_tables.revap_table_vals, pres, dpres, dz, nc_nuceat_tend, inv_exner, exner, inv_cld_frac_l, inv_cld_frac_i, inv_cld_frac_r, ni_activated, inv_qc_relvar, cld_frac_i, diff --git a/components/eamxx/src/physics/p3/disp/p3_main_impl_part2_disp.cpp b/components/eamxx/src/physics/p3/disp/p3_main_impl_part2_disp.cpp index 9f7987abbb59..0063a84fb7f0 100644 --- a/components/eamxx/src/physics/p3/disp/p3_main_impl_part2_disp.cpp +++ b/components/eamxx/src/physics/p3/disp/p3_main_impl_part2_disp.cpp @@ -23,6 +23,9 @@ ::p3_main_part2_disp( const bool& do_prescribed_CCN, const Scalar& dt, const Scalar& inv_dt, + const uview_2d& hetfrz_immersion_nucleation_tend, + const uview_2d& hetfrz_contact_nucleation_tend, + const uview_2d& hetfrz_deposition_nucleation_tend, const view_dnu_table& dnu_table_vals, const view_ice_table& ice_table_vals, const view_collect_table& collect_table_vals, @@ -111,6 +114,8 @@ ::p3_main_part2_disp( // main k-loop (for processes): p3_main_part2( team, nk_pack, max_total_ni, predictNc, do_prescribed_CCN, dt, inv_dt, + ekat::subview(hetfrz_immersion_nucleation_tend, i), + ekat::subview(hetfrz_contact_nucleation_tend, i),ekat::subview(hetfrz_deposition_nucleation_tend, i), dnu_table_vals, ice_table_vals, collect_table_vals, revap_table_vals, ekat::subview(pres, i), ekat::subview(dpres, i), ekat::subview(dz, i), ekat::subview(nc_nuceat_tend, i), ekat::subview(inv_exner, i), ekat::subview(exner, i), ekat::subview(inv_cld_frac_l, i), ekat::subview(inv_cld_frac_i, i), ekat::subview(inv_cld_frac_r, i), 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 15437fd567a9..730a7dafab3a 100644 --- a/components/eamxx/src/physics/p3/eamxx_p3_process_interface.cpp +++ b/components/eamxx/src/physics/p3/eamxx_p3_process_interface.cpp @@ -35,6 +35,9 @@ void P3Microphysics::set_grids(const std::shared_ptr grids_m m_num_cols = m_grid->get_num_local_dofs(); // Number of columns on this rank m_num_levs = m_grid->get_num_vertical_levels(); // Number of levels per column + // Gather runtime options from file + runtime_options.load_runtime_options_from_file(m_params); + // --Infrastructure // dt is passed as an argument to run_impl infrastructure.it = 0; @@ -91,6 +94,25 @@ void P3Microphysics::set_grids(const std::shared_ptr grids_m add_field ("qv_prev_micro_step", scalar3d_layout_mid, kg/kg, grid_name, ps); add_field ("T_prev_micro_step", scalar3d_layout_mid, K, grid_name, ps); + // Input from MAM4xx-ACI for heterogeneous freezing calculations + if (runtime_options.use_hetfrz_classnuc){ + constexpr auto cm = m / 100; + + // units of number mixing ratios of tracers + constexpr auto frz_unit = 1 / (cm * cm * cm * s); + // heterogeneous freezing by immersion nucleation [cm^-3 s^-1] + add_field("hetfrz_immersion_nucleation_tend", scalar3d_layout_mid, + frz_unit, grid_name, ps); + + // heterogeneous freezing by contact nucleation [cm^-3 s^-1] + add_field("hetfrz_contact_nucleation_tend", scalar3d_layout_mid, frz_unit, + grid_name, ps); + + // heterogeneous freezing by deposition nucleation [cm^-3 s^-1] + add_field("hetfrz_deposition_nucleation_tend", scalar3d_layout_mid, + frz_unit, grid_name, ps); + } + // Diagnostic Outputs: (all fields are just outputs w.r.t. P3) add_field("precip_liq_surf_mass", scalar2d_layout, kg/m2, grid_name, "ACCUMULATED"); add_field("precip_ice_surf_mass", scalar2d_layout, kg/m2, grid_name, "ACCUMULATED"); @@ -217,8 +239,6 @@ void P3Microphysics::init_buffers(const ATMBufferManager &buffer_manager) // ========================================================================================= void P3Microphysics::initialize_impl (const RunType /* run_type */) { - // Gather runtime options from file - runtime_options.load_runtime_options_from_file(m_params); // Set property checks for fields in this process add_invariant_check(get_field_out("T_mid"),m_grid,100.0,500.0,false); @@ -313,6 +333,20 @@ void P3Microphysics::initialize_impl (const RunType /* run_type */) diag_inputs.cld_frac_r = p3_preproc.cld_frac_r; diag_inputs.dz = p3_preproc.dz; diag_inputs.inv_exner = p3_preproc.inv_exner; + + // Inputs for the heteogeneous freezing + if (runtime_options.use_hetfrz_classnuc){ + diag_inputs.hetfrz_immersion_nucleation_tend = get_field_in("hetfrz_immersion_nucleation_tend").get_view(); + diag_inputs.hetfrz_contact_nucleation_tend = get_field_in("hetfrz_contact_nucleation_tend").get_view(); + diag_inputs.hetfrz_deposition_nucleation_tend = get_field_in("hetfrz_deposition_nucleation_tend").get_view(); + } + else { + // set to unused, double check if this has any side effects (testing should catch this) + diag_inputs.hetfrz_immersion_nucleation_tend = m_buffer.unused; + diag_inputs.hetfrz_contact_nucleation_tend = m_buffer.unused; + diag_inputs.hetfrz_deposition_nucleation_tend = m_buffer.unused; + } + // --Diagnostic Outputs diag_outputs.diag_eff_radius_qc = get_field_out("eff_radius_qc").get_view(); diag_outputs.diag_eff_radius_qi = get_field_out("eff_radius_qi").get_view(); diff --git a/components/eamxx/src/physics/p3/eti/p3_ice_classical_nucleation_impl.cpp b/components/eamxx/src/physics/p3/eti/p3_ice_classical_nucleation_impl.cpp new file mode 100644 index 000000000000..4b8fe4a74215 --- /dev/null +++ b/components/eamxx/src/physics/p3/eti/p3_ice_classical_nucleation_impl.cpp @@ -0,0 +1,14 @@ +#include "p3_ice_classical_nucleation_impl.hpp" + +namespace scream { +namespace p3 { + +/* + * Explicit instantiation for doing conservation functions on Reals using the + * default device. + */ + +template struct Functions; + +} // namespace p3 +} // namespace scream diff --git a/components/eamxx/src/physics/p3/impl/p3_back_to_cell_average_impl.hpp b/components/eamxx/src/physics/p3/impl/p3_back_to_cell_average_impl.hpp index 0ba2e8b412af..9ffe137a37a0 100644 --- a/components/eamxx/src/physics/p3/impl/p3_back_to_cell_average_impl.hpp +++ b/components/eamxx/src/physics/p3/impl/p3_back_to_cell_average_impl.hpp @@ -27,7 +27,8 @@ ::back_to_cell_average( Spack& nr_collect_tend, Spack& ni_selfcollect_tend, Spack& qv2qi_vapdep_tend, Spack& nr2ni_immers_freeze_tend, Spack& ni_sublim_tend, Spack& qv2qi_nucleat_tend, Spack& ni_nucleat_tend, Spack& qc2qi_berg_tend, - const Smask& context) + Spack& ncheti_cnt, Spack& qcheti_cnt, Spack& nicnt, Spack& qicnt, Spack& ninuc_cnt, + Spack& qinuc_cnt, const Smask& context) { Spack ir_cldm, il_cldm, lr_cldm; ir_cldm = min(cld_frac_i,cld_frac_r); // Intersection of ICE and RAIN cloud @@ -70,6 +71,13 @@ ::back_to_cell_average( ni_sublim_tend.set(context, ni_sublim_tend * cld_frac_i); // Number change due to sublimation of ice qc2qi_berg_tend.set(context, qc2qi_berg_tend * il_cldm); // Bergeron process + ncheti_cnt.set(context,ncheti_cnt*cld_frac_l); + qcheti_cnt.set(context, qcheti_cnt*cld_frac_l); + nicnt.set(context, nicnt*cld_frac_l); + qicnt.set(context, qicnt*cld_frac_l); + ninuc_cnt.set(context, ninuc_cnt*cld_frac_l); + qinuc_cnt.set(context, qinuc_cnt*cld_frac_l); + // AaronDonahue: These variables are related to aerosol activation and their usage will be changed in a later PR. //qv2qi_nucleat_tend = qv2qi_nucleat_tend; // Deposition and condensation-freezing nucleation, already cell-averaged //ni_nucleat_tend = ni_nucleat_tend; // Number change due to deposition and condensation-freezing, already cell-averaged diff --git a/components/eamxx/src/physics/p3/impl/p3_conservation_impl.hpp b/components/eamxx/src/physics/p3/impl/p3_conservation_impl.hpp index c21d587d0a0c..e71ee628474d 100644 --- a/components/eamxx/src/physics/p3/impl/p3_conservation_impl.hpp +++ b/components/eamxx/src/physics/p3/impl/p3_conservation_impl.hpp @@ -13,9 +13,16 @@ void Functions ::cloud_water_conservation(const Spack& qc, const Scalar dt, Spack& qc2qr_autoconv_tend, Spack& qc2qr_accret_tend, Spack &qc2qi_collect_tend, Spack& qc2qi_hetero_freeze_tend, Spack& qc2qr_ice_shed_tend, Spack& qc2qi_berg_tend, Spack& qi2qv_sublim_tend, Spack& qv2qi_vapdep_tend, - const Smask& context) + Spack& qcheti_cnt, Spack& qicnt, const bool& use_hetfrz_classnuc, const Smask& context) { - const auto sinks = (qc2qr_autoconv_tend+qc2qr_accret_tend+qc2qi_collect_tend+qc2qi_hetero_freeze_tend+qc2qr_ice_shed_tend+qc2qi_berg_tend)*dt; // Sinks of cloud water + + Spack sinks; + if(use_hetfrz_classnuc){ + sinks = (qc2qr_autoconv_tend+qc2qr_accret_tend+qc2qi_collect_tend+qcheti_cnt+qc2qr_ice_shed_tend+qc2qi_berg_tend)*dt; // Sinks of cloud water + } + else{ + sinks = (qc2qr_autoconv_tend+qc2qr_accret_tend+qc2qi_collect_tend+qc2qi_hetero_freeze_tend+qc2qr_ice_shed_tend+qc2qi_berg_tend)*dt; // Sinks of cloud water + } const auto sources = qc; // Source of cloud water Spack ratio; @@ -28,7 +35,13 @@ ::cloud_water_conservation(const Spack& qc, const Scalar dt, qc2qr_autoconv_tend.set(enforce_conservation, qc2qr_autoconv_tend*ratio); qc2qr_accret_tend.set(enforce_conservation, qc2qr_accret_tend*ratio); qc2qi_collect_tend.set(enforce_conservation, qc2qi_collect_tend*ratio); - qc2qi_hetero_freeze_tend.set(enforce_conservation, qc2qi_hetero_freeze_tend*ratio); + if(use_hetfrz_classnuc){ + qcheti_cnt.set(enforce_conservation, qcheti_cnt*ratio); + qicnt.set(enforce_conservation, qicnt*ratio); + } + else{ + qc2qi_hetero_freeze_tend.set(enforce_conservation, qc2qi_hetero_freeze_tend*ratio); + } qc2qr_ice_shed_tend.set(enforce_conservation, qc2qr_ice_shed_tend*ratio); qc2qi_berg_tend.set(enforce_conservation, qc2qi_berg_tend*ratio); } @@ -78,13 +91,21 @@ void Functions ::ice_water_conservation( const Spack& qi,const Spack& qv2qi_vapdep_tend,const Spack& qv2qi_nucleat_tend,const Spack& qc2qi_berg_tend, const Spack &qr2qi_collect_tend,const Spack &qc2qi_collect_tend,const Spack& qr2qi_immers_freeze_tend, - const Spack& qc2qi_hetero_freeze_tend,const Scalar dt, - Spack& qi2qv_sublim_tend, Spack& qi2qr_melt_tend, + const Spack& qc2qi_hetero_freeze_tend,const Scalar dt, Spack &qinuc_cnt, Spack &qcheti_cnt, Spack &qicnt, + Spack& qi2qv_sublim_tend, Spack& qi2qr_melt_tend, const bool& use_hetfrz_classnuc, const Smask& context) { const auto sinks = (qi2qv_sublim_tend+qi2qr_melt_tend)*dt; // Sinks of ice water - const auto sources = qi + (qv2qi_vapdep_tend+qv2qi_nucleat_tend+qr2qi_collect_tend+qc2qi_collect_tend + + Spack sources; + if(use_hetfrz_classnuc){ + sources = qi + (qv2qi_vapdep_tend+qv2qi_nucleat_tend+qr2qi_collect_tend+qc2qi_collect_tend + + qr2qi_immers_freeze_tend+qc2qi_berg_tend+qinuc_cnt+qcheti_cnt+qicnt)*dt; // Sources of ice water + } + else{ + sources = qi + (qv2qi_vapdep_tend+qv2qi_nucleat_tend+qr2qi_collect_tend+qc2qi_collect_tend + qr2qi_immers_freeze_tend+qc2qi_hetero_freeze_tend+qc2qi_berg_tend)*dt; // Sources of ice water + } Spack ratio; constexpr Scalar qtendsmall = C::QTENDSMALL; Smask enforce_conservation = sinks > sources && sinks >= qtendsmall && context; // determine if conservation corrction is necessary diff --git a/components/eamxx/src/physics/p3/impl/p3_ice_classical_nucleation_impl.hpp b/components/eamxx/src/physics/p3/impl/p3_ice_classical_nucleation_impl.hpp new file mode 100644 index 000000000000..9673252d957c --- /dev/null +++ b/components/eamxx/src/physics/p3/impl/p3_ice_classical_nucleation_impl.hpp @@ -0,0 +1,62 @@ +#ifndef P3_ICE_CLASSICAL_NUCLEATION_IMPL_HPP +#define P3_ICE_CLASSICAL_NUCLEATION_IMPL_HPP + +#include "p3_functions.hpp" // for ETI only but harmless for GPU + +namespace scream { +namespace p3 { + +/* + */ + +template +KOKKOS_FUNCTION +void Functions +::ice_classical_nucleation( + const Spack& frzimm, const Spack& frzcnt, + const Spack& frzdep, const Spack& rho, + const Spack& qc_incld, const Spack& nc_incld, + const int Iflag, + Spack& ncheti_cnt, Spack& qcheti_cnt, + Spack& nicnt, Spack& qicnt, + Spack& ninuc_cnt, Spack& qinuc_cnt) +{ + constexpr Scalar pi = C::Pi; + constexpr Scalar rho_h2o = C::RHO_H2O; + + // TODO: Verify if qsmall can be unified with other "small" numeric literals + constexpr Scalar qsmall = 1.0e-18; + constexpr Scalar piov3 = pi/3.0; + + // TODO: Verify if 1.0e-18 can be unified with other "small" numeric literals + constexpr Scalar mi0 = 4.0*piov3*900.0*1.0e-18; // BAD_CONSTANT! + + const Spack Zero(0.0); + // minimum mass of new crystal due to freezing of cloud droplets done + // externally (kg) + + const Scalar mi0l_min = (4.0/3.0)*pi*rho_h2o*(4.0e-6)*(4.0e-6)*(4.0e-6); + Spack mi0l = qc_incld/ekat::max(nc_incld,1.0e6/rho); + mi0l = ekat::max(mi0l_min, mi0l); + + const auto mask = qc_incld > qsmall; + switch (Iflag) { + case 1: // cloud droplet immersion freezing + ncheti_cnt.set(mask, frzimm*1.0e6/rho /* frzimm input is in [#/cm3] */ , Zero); + qcheti_cnt.set(mask, ncheti_cnt*mi0l, Zero); + break; + case 2: // deposition freezing / contact freezing + nicnt.set(mask, frzcnt*1.0e6/rho, Zero); + qicnt.set(mask, nicnt*mi0l, Zero); + ninuc_cnt.set(mask, frzdep*1.0e6/rho, Zero); + qinuc_cnt.set(mask, ninuc_cnt*mi0, Zero); + break; + default: + EKAT_KERNEL_ERROR_MSG("Error! Unhandled case in switch statement for Iflag in p3_CNT_couple_impl.hpp .\n"); + break; + } +} +} // namespace p3 +} // namespace scream + +#endif diff --git a/components/eamxx/src/physics/p3/impl/p3_ice_supersat_conservation_impl.hpp b/components/eamxx/src/physics/p3/impl/p3_ice_supersat_conservation_impl.hpp index 091aa20f58d4..78775c3426fe 100644 --- a/components/eamxx/src/physics/p3/impl/p3_ice_supersat_conservation_impl.hpp +++ b/components/eamxx/src/physics/p3/impl/p3_ice_supersat_conservation_impl.hpp @@ -13,7 +13,7 @@ namespace p3 { template KOKKOS_FUNCTION -void Functions::ice_supersat_conservation(Spack& qv2qi_vapdep_tend, Spack& qv2qi_nucleat_tend, const Spack& cld_frac_i, const Spack& qv, const Spack& qv_sat_i, const Spack& t_atm, const Real& dt, const Spack& qi2qv_sublim_tend, const Spack& qr2qv_evap_tend, const Smask& context) +void Functions::ice_supersat_conservation(Spack& qv2qi_vapdep_tend, Spack& qv2qi_nucleat_tend, Spack& qinuc_cnt, const Spack& cld_frac_i, const Spack& qv, const Spack& qv_sat_i, const Spack& t_atm, const Real& dt, const Spack& qi2qv_sublim_tend, const Spack& qr2qv_evap_tend, const bool& use_hetfrz_classnuc, const Smask& context) { constexpr Scalar qsmall = C::QSMALL; constexpr Scalar cp = C::CP; @@ -22,7 +22,13 @@ void Functions::ice_supersat_conservation(Spack& qv2qi_vapdep_tend, Spack& constexpr Scalar latice = C::LatIce; constexpr Scalar latsublim2 = (latvap+latice)*(latvap+latice); - const auto qv_sink = qv2qi_vapdep_tend + qv2qi_nucleat_tend; // in [kg/kg] cell-avg values + Spack qv_sink; + if(use_hetfrz_classnuc){ + qv_sink = qv2qi_vapdep_tend + qv2qi_nucleat_tend + qinuc_cnt; // in [kg/kg] cell-avg values + } + else{ + qv_sink = qv2qi_vapdep_tend + qv2qi_nucleat_tend; // in [kg/kg] cell-avg values + } const auto mask = qv_sink > qsmall && cld_frac_i > 1e-20 && context; if (mask.any()) { @@ -36,6 +42,9 @@ void Functions::ice_supersat_conservation(Spack& qv2qi_vapdep_tend, Spack& const auto sink_gt_avail = qv_sink > qv_avail && mask; if (sink_gt_avail.any()) { const auto fract = qv_avail / qv_sink; + if(use_hetfrz_classnuc){ + qinuc_cnt.set(sink_gt_avail, qinuc_cnt * fract); + } qv2qi_nucleat_tend.set(sink_gt_avail, qv2qi_nucleat_tend * fract); qv2qi_vapdep_tend.set(sink_gt_avail, qv2qi_vapdep_tend * fract); } 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 fb76ac0290e8..24998e824f90 100644 --- a/components/eamxx/src/physics/p3/impl/p3_main_impl.hpp +++ b/components/eamxx/src/physics/p3/impl/p3_main_impl.hpp @@ -201,6 +201,11 @@ ::p3_main_internal( const auto oqv_prev = ekat::subview(diagnostic_inputs.qv_prev, i); const auto ot_prev = ekat::subview(diagnostic_inputs.t_prev, i); + // Inputs for the heteogeneous freezing + const auto ohetfrz_immersion_nucleation_tend = ekat::subview(diagnostic_inputs.hetfrz_immersion_nucleation_tend, i); + const auto ohetfrz_contact_nucleation_tend = ekat::subview(diagnostic_inputs.hetfrz_contact_nucleation_tend, i); + const auto ohetfrz_deposition_nucleation_tend = ekat::subview(diagnostic_inputs.hetfrz_deposition_nucleation_tend, i); + // Use Kokkos' scratch pad for allocating 2 bools // per team to determine early exits ScratchViewType bools(team.team_scratch(0), 2); @@ -243,6 +248,7 @@ ::p3_main_internal( p3_main_part2( team, nk_pack, runtime_options.max_total_ni, infrastructure.predictNc, infrastructure.prescribedCCN, infrastructure.dt, inv_dt, + ohetfrz_immersion_nucleation_tend, ohetfrz_contact_nucleation_tend, ohetfrz_deposition_nucleation_tend, lookup_tables.dnu_table_vals, lookup_tables.ice_table_vals, lookup_tables.collect_table_vals, lookup_tables.revap_table_vals, opres, odpres, odz, onc_nuceat_tend, oinv_exner, exner, inv_cld_frac_l, inv_cld_frac_i, inv_cld_frac_r, oni_activated, oinv_qc_relvar, ocld_frac_i, ocld_frac_l, ocld_frac_r, oqv_prev, ot_prev, T_atm, rho, inv_rho, qv_sat_l, qv_sat_i, qv_supersat_i, rhofacr, rhofaci, acn, 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 3214549a3b65..f3310a5a4c5e 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 @@ -26,6 +26,9 @@ ::p3_main_part2( const bool& do_prescribed_CCN, const Scalar& dt, const Scalar& inv_dt, + const uview_1d& hetfrz_immersion_nucleation_tend, + const uview_1d& hetfrz_contact_nucleation_tend, + const uview_1d& hetfrz_deposition_nucleation_tend, const view_dnu_table& dnu, const view_ice_table& ice_table_vals, const view_collect_table& collect_table_vals, @@ -104,7 +107,8 @@ ::p3_main_part2( constexpr Scalar latvap = C::LatVap; constexpr Scalar latice = C::LatIce; - const bool do_ice_production = runtime_options.do_ice_production; + const bool do_ice_production = runtime_options.do_ice_production; + const bool use_hetfrz_classnuc = runtime_options.use_hetfrz_classnuc; team.team_barrier(); hydrometeorsPresent = false; @@ -175,6 +179,9 @@ ::p3_main_part2( kap (0), // TODO(doc) eii (0), // temperature dependent aggregation efficiency + //Hetreogeneous freezing + ncheti_cnt(0), qcheti_cnt(0), nicnt(0), qicnt(0), ninuc_cnt(0), qinuc_cnt(0), + // quantities related to process rates/parameters, interpolated from lookup tables: // For a more in depth reference to where these came from consult the file // "create_p3_lookupTable_1.F90-v4.1". All line numbers below reference this @@ -324,10 +331,20 @@ ::p3_main_part2( 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); + if (use_hetfrz_classnuc){ + ice_classical_nucleation(hetfrz_immersion_nucleation_tend(k), hetfrz_contact_nucleation_tend(k), + hetfrz_deposition_nucleation_tend(k), rho(k), qc_incld(k), nc_incld(k), 1, + ncheti_cnt, qcheti_cnt, nicnt, qicnt, ninuc_cnt, qinuc_cnt); + ice_classical_nucleation(hetfrz_immersion_nucleation_tend(k), hetfrz_contact_nucleation_tend(k), + hetfrz_deposition_nucleation_tend(k), rho(k), qc_incld(k), nc_incld(k), 2, + ncheti_cnt, qcheti_cnt, nicnt, qicnt, ninuc_cnt, qinuc_cnt); + } + else{ + 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), @@ -400,7 +417,8 @@ ::p3_main_part2( nc_accret_tend, nc_selfcollect_tend, nc2nr_autoconv_tend, nr_selfcollect_tend, nr_evap_tend, ncautr, qi2qv_sublim_tend, nr_ice_shed_tend, qc2qi_hetero_freeze_tend, qr2qi_collect_tend, qc2qr_ice_shed_tend, qi2qr_melt_tend, qc2qi_collect_tend, qr2qi_immers_freeze_tend, ni2nr_melt_tend, nc_collect_tend, ncshdc, nc2ni_immers_freeze_tend, nr_collect_tend, ni_selfcollect_tend, - qv2qi_vapdep_tend, nr2ni_immers_freeze_tend, ni_sublim_tend, qv2qi_nucleat_tend, ni_nucleat_tend, qc2qi_berg_tend, not_skip_all); + qv2qi_vapdep_tend, nr2ni_immers_freeze_tend, ni_sublim_tend, qv2qi_nucleat_tend, ni_nucleat_tend, qc2qi_berg_tend, + ncheti_cnt, qcheti_cnt, nicnt, qicnt, ninuc_cnt, qinuc_cnt, not_skip_all); // // conservation of water @@ -414,7 +432,7 @@ ::p3_main_part2( // cloud cloud_water_conservation( qc(k), dt, - qc2qr_autoconv_tend, qc2qr_accret_tend, qc2qi_collect_tend, qc2qi_hetero_freeze_tend, qc2qr_ice_shed_tend, qc2qi_berg_tend, qi2qv_sublim_tend, qv2qi_vapdep_tend, not_skip_all); + qc2qr_autoconv_tend, qc2qr_accret_tend, qc2qi_collect_tend, qc2qi_hetero_freeze_tend, qc2qr_ice_shed_tend, qc2qi_berg_tend, qi2qv_sublim_tend, qv2qi_vapdep_tend, qcheti_cnt, qicnt, use_hetfrz_classnuc, not_skip_all); // rain rain_water_conservation( @@ -425,18 +443,19 @@ ::p3_main_part2( ice_water_conservation( qi(k), qv2qi_vapdep_tend, qv2qi_nucleat_tend, qc2qi_berg_tend, qr2qi_collect_tend, qc2qi_collect_tend, qr2qi_immers_freeze_tend, qc2qi_hetero_freeze_tend, dt, - qi2qv_sublim_tend, qi2qr_melt_tend, not_skip_all); + qinuc_cnt, qcheti_cnt, qicnt, + qi2qv_sublim_tend, qi2qr_melt_tend, use_hetfrz_classnuc, not_skip_all); nc_conservation(nc(k), nc_selfcollect_tend, dt, nc_collect_tend, nc2ni_immers_freeze_tend, - nc_accret_tend, nc2nr_autoconv_tend, not_skip_all); + nc_accret_tend, nc2nr_autoconv_tend, ncheti_cnt, nicnt, use_hetfrz_classnuc, not_skip_all); nr_conservation(nr(k),ni2nr_melt_tend,nr_ice_shed_tend,ncshdc,nc2nr_autoconv_tend,dt,nmltratio,nr_collect_tend, nr2ni_immers_freeze_tend,nr_selfcollect_tend,nr_evap_tend, not_skip_all); - ni_conservation(ni(k),ni_nucleat_tend,nr2ni_immers_freeze_tend,nc2ni_immers_freeze_tend,dt,ni2nr_melt_tend, - ni_sublim_tend,ni_selfcollect_tend, not_skip_all); + ni_conservation(ni(k),ni_nucleat_tend,nr2ni_immers_freeze_tend,nc2ni_immers_freeze_tend, ncheti_cnt, nicnt, ninuc_cnt, dt,ni2nr_melt_tend, + ni_sublim_tend,ni_selfcollect_tend, use_hetfrz_classnuc, not_skip_all); // make sure procs don't inappropriately push qv beyond ice saturation - ice_supersat_conservation(qv2qi_vapdep_tend,qv2qi_nucleat_tend,cld_frac_i(k),qv(k),qv_sat_i(k), - th_atm(k)/inv_exner(k),dt,qi2qv_sublim_tend,qr2qv_evap_tend, not_skip_all); + ice_supersat_conservation(qv2qi_vapdep_tend,qv2qi_nucleat_tend,qinuc_cnt,cld_frac_i(k),qv(k),qv_sat_i(k), + th_atm(k)/inv_exner(k),dt,qi2qv_sublim_tend,qr2qv_evap_tend, use_hetfrz_classnuc, not_skip_all); // make sure procs don't inappropriately push qv beyond liquid saturation prevent_liq_supersaturation(pres(k), T_atm(k), qv(k), dt, qv2qi_vapdep_tend, qv2qi_nucleat_tend, qi2qv_sublim_tend,qr2qv_evap_tend, @@ -451,8 +470,8 @@ ::p3_main_part2( qc2qi_hetero_freeze_tend, qc2qi_collect_tend, qc2qr_ice_shed_tend, nc_collect_tend, nc2ni_immers_freeze_tend, ncshdc, qr2qi_collect_tend, nr_collect_tend, qr2qi_immers_freeze_tend, nr2ni_immers_freeze_tend, nr_ice_shed_tend, qi2qr_melt_tend, ni2nr_melt_tend, qi2qv_sublim_tend, qv2qi_vapdep_tend, qv2qi_nucleat_tend, ni_nucleat_tend, ni_selfcollect_tend, ni_sublim_tend, qc2qi_berg_tend, inv_exner(k), predictNc, wetgrowth, dt, nmltratio, - rho_qm_cloud, th_atm(k), qv(k), qi(k), ni(k), qm(k), bm(k), qc(k), - nc(k), qr(k), nr(k), not_skip_all); + rho_qm_cloud, ncheti_cnt, nicnt, ninuc_cnt, qcheti_cnt, qicnt, qinuc_cnt, th_atm(k), qv(k), qi(k), ni(k), qm(k), bm(k), qc(k), + nc(k), qr(k), nr(k), use_hetfrz_classnuc, not_skip_all); //-- warm-phase only processes: update_prognostic_liquid( @@ -461,7 +480,12 @@ ::p3_main_part2( qr(k), nr(k), not_skip_all); // AaronDonahue - Add extra variables needed from microphysics by E3SM: - qv2qi_depos_tend(k) .set(not_skip_all, qv2qi_vapdep_tend - qi2qv_sublim_tend + qv2qi_nucleat_tend); + if(use_hetfrz_classnuc){ + qv2qi_depos_tend(k) .set(not_skip_all, qv2qi_vapdep_tend - qi2qv_sublim_tend + qv2qi_nucleat_tend + qinuc_cnt); + } + else{ + qv2qi_depos_tend(k) .set(not_skip_all, qv2qi_vapdep_tend - qi2qv_sublim_tend + qv2qi_nucleat_tend); + } precip_total_tend(k) .set(not_skip_all, qc2qr_accret_tend + qc2qr_autoconv_tend + qc2qr_ice_shed_tend + qc2qi_collect_tend); nevapr(k) .set(not_skip_all, qi2qv_sublim_tend + qr2qv_evap_tend); qr_evap_tend(k) .set(not_skip_all, qr2qv_evap_tend); diff --git a/components/eamxx/src/physics/p3/impl/p3_nc_conservation_impl.hpp b/components/eamxx/src/physics/p3/impl/p3_nc_conservation_impl.hpp index 025b2546776c..32bb6646ab1c 100644 --- a/components/eamxx/src/physics/p3/impl/p3_nc_conservation_impl.hpp +++ b/components/eamxx/src/physics/p3/impl/p3_nc_conservation_impl.hpp @@ -13,15 +13,29 @@ namespace p3 { template KOKKOS_FUNCTION -void Functions::nc_conservation(const Spack& nc, const Spack& nc_selfcollect_tend, const Real& dt, Spack& nc_collect_tend, Spack& nc2ni_immers_freeze_tend, Spack& nc_accret_tend, Spack& nc2nr_autoconv_tend, const Smask& context) +void Functions::nc_conservation(const Spack& nc, const Spack& nc_selfcollect_tend, const Real& dt, Spack& nc_collect_tend, +Spack& nc2ni_immers_freeze_tend, Spack& nc_accret_tend, Spack& nc2nr_autoconv_tend, Spack& ncheti_cnt, Spack& nicnt, +const bool& use_hetfrz_classnuc, const Smask& context) { - const auto sink_nc = (nc_collect_tend + nc2ni_immers_freeze_tend + nc_accret_tend + nc2nr_autoconv_tend)*dt; + Spack sink_nc; + if (use_hetfrz_classnuc){ + sink_nc = (nc_collect_tend + ncheti_cnt + nc_accret_tend + nc2nr_autoconv_tend + nicnt)*dt; + } + else{ + sink_nc = (nc_collect_tend + nc2ni_immers_freeze_tend + nc_accret_tend + nc2nr_autoconv_tend)*dt; + } const auto source_nc = nc + nc_selfcollect_tend*dt; const auto mask = sink_nc > source_nc && context; if (mask.any()) { const auto ratio = source_nc/sink_nc; nc_collect_tend.set(mask, nc_collect_tend*ratio); - nc2ni_immers_freeze_tend.set(mask, nc2ni_immers_freeze_tend*ratio); + if (use_hetfrz_classnuc){ + ncheti_cnt.set(mask, ncheti_cnt*ratio); + nicnt.set(mask, nicnt*ratio); + } + else{ + nc2ni_immers_freeze_tend.set(mask, nc2ni_immers_freeze_tend*ratio); + } nc_accret_tend.set(mask, nc_accret_tend*ratio); nc2nr_autoconv_tend.set(mask, nc2nr_autoconv_tend*ratio); } diff --git a/components/eamxx/src/physics/p3/impl/p3_ni_conservation_impl.hpp b/components/eamxx/src/physics/p3/impl/p3_ni_conservation_impl.hpp index c02437ee6116..9f36eb87f19f 100644 --- a/components/eamxx/src/physics/p3/impl/p3_ni_conservation_impl.hpp +++ b/components/eamxx/src/physics/p3/impl/p3_ni_conservation_impl.hpp @@ -13,10 +13,19 @@ namespace p3 { template KOKKOS_FUNCTION -void Functions::ni_conservation(const Spack& ni, const Spack& ni_nucleat_tend, const Spack& nr2ni_immers_freeze_tend, const Spack& nc2ni_immers_freeze_tend, const Real& dt, Spack& ni2nr_melt_tend, Spack& ni_sublim_tend, Spack& ni_selfcollect_tend, const Smask& context) +void Functions::ni_conservation(const Spack& ni, const Spack& ni_nucleat_tend, const Spack& nr2ni_immers_freeze_tend, +const Spack& nc2ni_immers_freeze_tend, const Spack& ncheti_cnt, const Spack& nicnt, const Spack& ninuc_cnt, const Real& dt, + Spack& ni2nr_melt_tend, Spack& ni_sublim_tend, Spack& ni_selfcollect_tend, const bool& use_hetfrz_classnuc, const Smask& context) { const auto sink_ni = (ni2nr_melt_tend + ni_sublim_tend + ni_selfcollect_tend)*dt; - const auto source_ni = ni + (ni_nucleat_tend+nr2ni_immers_freeze_tend+nc2ni_immers_freeze_tend)*dt; + + Spack source_ni; + if(use_hetfrz_classnuc){ + source_ni = ni + (ni_nucleat_tend+nr2ni_immers_freeze_tend+ncheti_cnt+nicnt+ninuc_cnt)*dt; + } + else { + source_ni = ni + (ni_nucleat_tend+nr2ni_immers_freeze_tend+nc2ni_immers_freeze_tend)*dt; + } const auto mask = sink_ni > source_ni && context; if (mask.any()) { const auto ratio = source_ni/sink_ni; diff --git a/components/eamxx/src/physics/p3/impl/p3_update_prognostics_impl.hpp b/components/eamxx/src/physics/p3/impl/p3_update_prognostics_impl.hpp index 86feaa04f499..3f8893ba50da 100644 --- a/components/eamxx/src/physics/p3/impl/p3_update_prognostics_impl.hpp +++ b/components/eamxx/src/physics/p3/impl/p3_update_prognostics_impl.hpp @@ -17,8 +17,9 @@ ::update_prognostic_ice( const Spack& ni_nucleat_tend, const Spack& ni_selfcollect_tend, const Spack& ni_sublim_tend, const Spack& qc2qi_berg_tend, const Spack& inv_exner, const bool do_predict_nc, const Smask& log_wetgrowth, const Scalar dt, const Scalar& nmltratio, const Spack& rho_qm_cloud, + Spack& ncheti_cnt, Spack& nicnt, Spack& ninuc_cnt, Spack& qcheti_cnt, Spack& qicnt, Spack& qinuc_cnt, Spack& th_atm, Spack& qv, Spack& qi, Spack& ni, Spack& qm, Spack& bm, Spack& qc, - Spack& nc, Spack& qr, Spack& nr, + Spack& nc, Spack& qr, Spack& nr, const bool& use_hetfrz_classnuc, const Smask& context) { constexpr Scalar QSMALL = C::QSMALL; @@ -26,9 +27,21 @@ ::update_prognostic_ice( constexpr Scalar latvap = C::LatVap; constexpr Scalar latice = C::LatIce; - qc.set(context, qc + (-qc2qi_hetero_freeze_tend-qc2qi_collect_tend-qc2qr_ice_shed_tend-qc2qi_berg_tend)*dt); + if(use_hetfrz_classnuc){ + qc.set(context, qc + (-qcheti_cnt-qicnt-qc2qi_collect_tend-qc2qr_ice_shed_tend-qc2qi_berg_tend)*dt); + } + else{ + qc.set(context, qc + (-qc2qi_hetero_freeze_tend-qc2qi_collect_tend-qc2qr_ice_shed_tend-qc2qi_berg_tend)*dt); + } + + if ( do_predict_nc ){ - nc.set(context, nc + (-nc_collect_tend-nc2ni_immers_freeze_tend)*dt); + if(use_hetfrz_classnuc){ + nc.set(context, nc + (-nc_collect_tend-ncheti_cnt-nicnt)*dt); + } + else{ + nc.set(context, nc + (-nc_collect_tend-nc2ni_immers_freeze_tend)*dt); + } } qr.set(context, qr + (-qr2qi_collect_tend+qi2qr_melt_tend-qr2qi_immers_freeze_tend+qc2qr_ice_shed_tend)*dt); @@ -45,14 +58,22 @@ ::update_prognostic_ice( qi.set(qi_not_small, qi - (qi2qv_sublim_tend + qi2qr_melt_tend) * dt); } - const auto dum = (qr2qi_collect_tend + qc2qi_collect_tend + qr2qi_immers_freeze_tend + qc2qi_hetero_freeze_tend) * dt; - qi.set(context, qi + (qv2qi_vapdep_tend + qv2qi_nucleat_tend + qc2qi_berg_tend) * dt + dum); - qm.set(context, qm + dum); - - bm.set(context, bm + (qr2qi_collect_tend * INV_RHO_RIMEMAX + qc2qi_collect_tend / rho_qm_cloud + (qr2qi_immers_freeze_tend + - qc2qi_hetero_freeze_tend) * INV_RHO_RIMEMAX) * dt); - - ni.set(context, ni + (ni_nucleat_tend - ni2nr_melt_tend - ni_sublim_tend - ni_selfcollect_tend + nr2ni_immers_freeze_tend + nc2ni_immers_freeze_tend) * dt); + if(use_hetfrz_classnuc){ + const auto dum = (qr2qi_collect_tend + qc2qi_collect_tend + qr2qi_immers_freeze_tend + qcheti_cnt+qicnt) * dt; + qi.set(context, qi + (qv2qi_vapdep_tend + qv2qi_nucleat_tend + qc2qi_berg_tend+qinuc_cnt)*dt + dum); + qm.set(context, qm + dum); + bm.set(context, bm + (qr2qi_collect_tend * INV_RHO_RIMEMAX + qc2qi_collect_tend / rho_qm_cloud + (qr2qi_immers_freeze_tend + + qcheti_cnt+qicnt) * INV_RHO_RIMEMAX) * dt); + ni.set(context, ni + (ni_nucleat_tend - ni2nr_melt_tend - ni_sublim_tend - ni_selfcollect_tend + nr2ni_immers_freeze_tend +ncheti_cnt+nicnt+ninuc_cnt)*dt); + } + else{ + const auto dum = (qr2qi_collect_tend + qc2qi_collect_tend + qr2qi_immers_freeze_tend + qc2qi_hetero_freeze_tend) * dt; + qi.set(context, qi + (qv2qi_vapdep_tend + qv2qi_nucleat_tend + qc2qi_berg_tend) * dt + dum); + qm.set(context, qm + dum); + bm.set(context, bm + (qr2qi_collect_tend * INV_RHO_RIMEMAX + qc2qi_collect_tend / rho_qm_cloud + (qr2qi_immers_freeze_tend + + qc2qi_hetero_freeze_tend) * INV_RHO_RIMEMAX) * dt); + ni.set(context, ni + (ni_nucleat_tend - ni2nr_melt_tend - ni_sublim_tend - ni_selfcollect_tend + nr2ni_immers_freeze_tend + nc2ni_immers_freeze_tend) * dt); + } //PMC nCat deleted interactions_loop @@ -75,12 +96,20 @@ ::update_prognostic_ice( // Alternatively, it can be simplified by tending qm -- qi // and bm such that rho_rim (qm/bm) --> rho_liq during melting. // == - qv.set(context, qv + (-qv2qi_vapdep_tend+qi2qv_sublim_tend-qv2qi_nucleat_tend)*dt); constexpr Scalar INV_CP = C::INV_CP; - th_atm.set(context, th_atm + inv_exner * ((qv2qi_vapdep_tend - qi2qv_sublim_tend + qv2qi_nucleat_tend) * (latvap+latice) * INV_CP + + if(use_hetfrz_classnuc){ + qv.set(context, qv + (-qv2qi_vapdep_tend+qi2qv_sublim_tend-qv2qi_nucleat_tend-qinuc_cnt)*dt); + th_atm.set(context, th_atm + inv_exner * ((qv2qi_vapdep_tend - qi2qv_sublim_tend + qv2qi_nucleat_tend+qinuc_cnt) * (latvap+latice) * INV_CP + + (qr2qi_collect_tend + qc2qi_collect_tend + qcheti_cnt+qicnt + qr2qi_immers_freeze_tend - + qi2qr_melt_tend + qc2qi_berg_tend) * latice * INV_CP) * dt); + } + else{ + qv.set(context, qv + (-qv2qi_vapdep_tend+qi2qv_sublim_tend-qv2qi_nucleat_tend)*dt); + th_atm.set(context, th_atm + inv_exner * ((qv2qi_vapdep_tend - qi2qv_sublim_tend + qv2qi_nucleat_tend) * (latvap+latice) * INV_CP + (qr2qi_collect_tend + qc2qi_collect_tend + qc2qi_hetero_freeze_tend + qr2qi_immers_freeze_tend - qi2qr_melt_tend + qc2qi_berg_tend) * latice * INV_CP) * dt); + } } template diff --git a/components/eamxx/src/physics/p3/p3_functions.hpp b/components/eamxx/src/physics/p3/p3_functions.hpp index f91c08da93c3..c6d69f9f081c 100644 --- a/components/eamxx/src/physics/p3/p3_functions.hpp +++ b/components/eamxx/src/physics/p3/p3_functions.hpp @@ -134,6 +134,7 @@ struct Functions bool set_cld_frac_l_to_one = false; bool set_cld_frac_i_to_one = false; bool set_cld_frac_r_to_one = false; + bool use_hetfrz_classnuc = false; void load_runtime_options_from_file(ekat::ParameterList& params) { max_total_ni = params.get("max_total_ni", max_total_ni); @@ -159,6 +160,7 @@ struct Functions set_cld_frac_l_to_one = params.get("set_cld_frac_l_to_one", set_cld_frac_l_to_one); set_cld_frac_i_to_one = params.get("set_cld_frac_i_to_one", set_cld_frac_i_to_one); set_cld_frac_r_to_one = params.get("set_cld_frac_r_to_one", set_cld_frac_r_to_one); + use_hetfrz_classnuc = params.get("use_hetfrz_classnuc", use_hetfrz_classnuc); } }; @@ -217,6 +219,12 @@ struct Functions view_2d qv_prev; // T from previous step [K] view_2d t_prev; + // Heterogeneous freezing by immersion nucleation [cm^-3 s^-1] + view_2d hetfrz_immersion_nucleation_tend; + // Heterogeneous freezing by contact nucleation [cm^-3 s^-1] + view_2d hetfrz_contact_nucleation_tend; + // Heterogeneous freezing by deposition nucleation [cm^-3 s^-1] + view_2d hetfrz_deposition_nucleation_tend; }; // This struct stores diagnostic outputs computed by P3. @@ -385,7 +393,8 @@ struct Functions Spack& nc_collect_tend, Spack& ncshdc, Spack& nc2ni_immers_freeze_tend, Spack& nr_collect_tend, Spack& ni_selfcollect_tend, Spack& qv2qi_vapdep_tend, Spack& nr2ni_immers_freeze_tend, Spack& ni_sublim_tend, Spack& qv2qi_nucleat_tend, - Spack& ni_nucleat_tend, Spack& qc2qi_berg_tend, + Spack& ni_nucleat_tend, Spack& qc2qi_berg_tend, Spack& ncheti_cnt, Spack& qcheti_cnt, + Spack& nicnt, Spack& qicnt, Spack& ninuc_cnt, Spack& qinuc_cnt, const Smask& context = Smask(true) ); //------------------------------------------------------------------------------------------! @@ -692,7 +701,7 @@ struct Functions static void cloud_water_conservation(const Spack& qc, const Scalar dt, Spack& qc2qr_autoconv_tend, Spack& qc2qr_accret_tend, Spack &qc2qi_collect_tend, Spack& qc2qi_hetero_freeze_tend, Spack& qc2qr_ice_shed_tend, Spack& qc2qi_berg_tend, Spack& qi2qv_sublim_tend, Spack& qv2qi_vapdep_tend, - const Smask& context = Smask(true) ); + Spack& qcheti_cnt, Spack& qicnt, const bool& use_hetfrz_classnuc, const Smask& context = Smask(true) ); KOKKOS_FUNCTION static void rain_water_conservation( @@ -704,7 +713,8 @@ struct Functions static void ice_water_conservation( const Spack& qi,const Spack& qv2qi_vapdep_tend,const Spack& qv2qi_nucleat_tend,const Spack& qc2qi_berg_tend, const Spack &qr2qi_collect_tend, const Spack &qc2qi_collect_tend,const Spack& qr2qi_immers_freeze_tend,const Spack& qc2qi_hetero_freeze_tend,const Scalar dt, - Spack& qi2qv_sublim_tend, Spack& qi2qr_melt_tend, + Spack &qinuc_cnt, Spack &qcheti_cnt, Spack &qicnt, + Spack& qi2qv_sublim_tend, Spack& qi2qr_melt_tend, const bool& use_hetfrz_classnuc, const Smask& context = Smask(true) ); // TODO: comment @@ -753,6 +763,16 @@ struct Functions const P3Runtime& runtime_options, const Smask& context = Smask(true) ); + // + KOKKOS_FUNCTION + static void ice_classical_nucleation(const Spack& frzimm, const Spack& frzcnt, + const Spack& frzdep, const Spack& rho, + const Spack& qc_incld, const Spack& nc_incld, + const int Iflag, + Spack& ncheti_cnt, Spack& qcheti_cnt, + Spack& nicnt, Spack& qucnt, + Spack& ninuc_cnt, Spack& qinuc_cnt); + // Computes droplet self collection KOKKOS_FUNCTION static void droplet_self_collection(const Spack& rho, const Spack& inv_rho, @@ -819,8 +839,10 @@ struct Functions const Spack& qv2qi_vapdep_tend, const Spack& qv2qi_nucleat_tend, const Spack& ni_nucleat_tend, const Spack& ni_selfcollect_tend, const Spack& ni_sublim_tend, const Spack& qc2qi_berg_tend, const Spack& inv_exner, const bool do_predict_nc, const Smask& log_wetgrowth, const Scalar dt, - const Scalar& nmltratio, const Spack& rho_qm_cloud, Spack& th_atm, Spack& qv, Spack& qi, - Spack& ni, Spack& qm, Spack& bm, Spack& qc, Spack& nc, Spack& qr, Spack& nr, + const Scalar& nmltratio, const Spack& rho_qm_cloud, + Spack& ncheti_cnt, Spack& nicnt, Spack& ninuc_cnt, Spack& qcheti_cnt, Spack& qicnt, Spack& qinuc_cnt, + Spack& th_atm, Spack& qv, Spack& qi, + Spack& ni, Spack& qm, Spack& bm, Spack& qc, Spack& nc, Spack& qr, Spack& nr, const bool& use_hetfrz_classnuc, const Smask& context = Smask(true)); // TODO (comments) @@ -1128,6 +1150,9 @@ struct Functions const bool& do_prescribed_CCN, const Scalar& dt, const Scalar& inv_dt, + const uview_1d& ohetfrz_immersion_nucleation_tend, + const uview_1d& ohetfrz_contact_nucleation_tend, + const uview_1d& ohetfrz_deposition_nucleation_tend, const view_dnu_table& dnu, const view_ice_table& ice_table_vals, const view_collect_table& collect_table_vals, @@ -1206,6 +1231,9 @@ struct Functions const bool& do_prescribed_CCN, const Scalar& dt, const Scalar& inv_dt, + const uview_2d& hetfrz_immersion_nucleation_tend, + const uview_2d& hetfrz_contact_nucleation_tend, + const uview_2d& hetfrz_deposition_nucleation_tend, const view_dnu_table& dnu, const view_ice_table& ice_table_vals, const view_collect_table& collect_table_vals, @@ -1405,16 +1433,16 @@ struct Functions #endif KOKKOS_FUNCTION - static void ice_supersat_conservation(Spack& qidep, Spack& qinuc, const Spack& cld_frac_i, const Spack& qv, const Spack& qv_sat_i, const Spack& t_atm, const Real& dt, const Spack& qi2qv_sublim_tend, const Spack& qr2qv_evap_tend, const Smask& context = Smask(true)); + static void ice_supersat_conservation(Spack& qidep, Spack& qinuc, Spack& qinuc_cnt, const Spack& cld_frac_i, const Spack& qv, const Spack& qv_sat_i, const Spack& t_atm, const Real& dt, const Spack& qi2qv_sublim_tend, const Spack& qr2qv_evap_tend, const bool& use_hetfrz_classnuc, const Smask& context = Smask(true)); KOKKOS_FUNCTION - static void nc_conservation(const Spack& nc, const Spack& nc_selfcollect_tend, const Real& dt, Spack& nc_collect_tend, Spack& nc2ni_immers_freeze_tend, Spack& nc_accret_tend, Spack& nc2nr_autoconv_tend, const Smask& context = Smask(true)); + static void nc_conservation(const Spack& nc, const Spack& nc_selfcollect_tend, const Real& dt, Spack& nc_collect_tend, Spack& nc2ni_immers_freeze_tend, Spack& nc_accret_tend, Spack& nc2nr_autoconv_tend, Spack& ncheti_cnt, Spack& nicnt, const bool& use_hetfrz_classnuc, const Smask& context = Smask(true)); KOKKOS_FUNCTION static void nr_conservation(const Spack& nr, const Spack& ni2nr_melt_tend, const Spack& nr_ice_shed_tend, const Spack& ncshdc, const Spack& nc2nr_autoconv_tend, const Real& dt, const Real& nmltratio, Spack& nr_collect_tend, Spack& nr2ni_immers_freeze_tend, Spack& nr_selfcollect_tend, Spack& nr_evap_tend, const Smask& context = Smask(true)); KOKKOS_FUNCTION - static void ni_conservation(const Spack& ni, const Spack& ni_nucleat_tend, const Spack& nr2ni_immers_freeze_tend, const Spack& nc2ni_immers_freeze_tend, const Real& dt, Spack& ni2nr_melt_tend, Spack& ni_sublim_tend, Spack& ni_selfcollect_tend, const Smask& context = Smask(true)); + static void ni_conservation(const Spack& ni, const Spack& ni_nucleat_tend, const Spack& nr2ni_immers_freeze_tend, const Spack& nc2ni_immers_freeze_tend, const Spack& ncheti_cnt, const Spack& nicnt, const Spack& ninuc_cnt, const Real& dt, Spack& ni2nr_melt_tend, Spack& ni_sublim_tend, Spack& ni_selfcollect_tend, const bool& use_hetfrz_classnuc, const Smask& context = Smask(true)); KOKKOS_FUNCTION static void prevent_liq_supersaturation(const Spack& pres, const Spack& t_atm, const Spack& qv, const Scalar& dt, const Spack& qidep, const Spack& qinuc, Spack& qi2qv_sublim_tend, Spack& qr2qv_evap_tend, const Smask& context = Smask(true) ); @@ -1441,6 +1469,7 @@ constexpr ScalarT Functions::P3C::lookup_table_1a_dum1_c; # include "p3_rain_self_collection_impl.hpp" # include "p3_impose_max_total_ni_impl.hpp" # include "p3_calc_rime_density_impl.hpp" +# include "p3_ice_classical_nucleation_impl.hpp" # include "p3_cldliq_imm_freezing_impl.hpp" # include "p3_droplet_self_coll_impl.hpp" # include "p3_cloud_sed_impl.hpp" diff --git a/components/eamxx/src/physics/p3/tests/infra/p3_data.cpp b/components/eamxx/src/physics/p3/tests/infra/p3_data.cpp index 24fd6529f22d..e745a5eed1b0 100644 --- a/components/eamxx/src/physics/p3/tests/infra/p3_data.cpp +++ b/components/eamxx/src/physics/p3/tests/infra/p3_data.cpp @@ -54,6 +54,9 @@ P3Data::P3Data (Int ncol_, Int nlev_) liq_ice_exchange = Array2("sum of liq-ice phase change tendenices", ncol, nlev); vap_liq_exchange = Array2("sum of vap-liq phase change tendenices", ncol, nlev); vap_ice_exchange = Array2("sum of vap-ice phase change tendenices", ncol, nlev); + hetfrz_immersion_nucleation_tend = Array2("hetfrz_immersion_nucleation_tend", ncol, nlev); + hetfrz_contact_nucleation_tend = Array2("hetfrz_contact_nucleation_tend", ncol, nlev); + hetfrz_deposition_nucleation_tend = Array2("hetfrz_deposition_nucleation_tend", ncol, nlev); } P3DataIterator::P3DataIterator (const P3Data::Ptr& d) { diff --git a/components/eamxx/src/physics/p3/tests/infra/p3_data.hpp b/components/eamxx/src/physics/p3/tests/infra/p3_data.hpp index 55e74300215c..1a5c232df9d0 100644 --- a/components/eamxx/src/physics/p3/tests/infra/p3_data.hpp +++ b/components/eamxx/src/physics/p3/tests/infra/p3_data.hpp @@ -22,6 +22,7 @@ struct P3Data { bool do_predict_nc; bool do_prescribed_CCN; + bool use_hetfrz_classnuc; const Int ncol, nlev; // In @@ -29,6 +30,7 @@ struct P3Data { Int it; Array2 qv, th_atm, pres, dz, nc_nuceat_tend, nccn_prescribed, ni_activated, inv_qc_relvar, qc, nc, qr, nr, qi, ni, qm, bm, dpres, inv_exner, qv_prev, t_prev; + Array2 hetfrz_immersion_nucleation_tend, hetfrz_contact_nucleation_tend, hetfrz_deposition_nucleation_tend; // Out Array1 precip_liq_surf, precip_ice_surf; Array2 diag_eff_radius_qc, diag_eff_radius_qi, diag_eff_radius_qr, rho_qi, qv2qi_depos_tend, diff --git a/components/eamxx/src/physics/p3/tests/infra/p3_ic_cases.cpp b/components/eamxx/src/physics/p3/tests/infra/p3_ic_cases.cpp index 66659a802f9f..977d70b62153 100644 --- a/components/eamxx/src/physics/p3/tests/infra/p3_ic_cases.cpp +++ b/components/eamxx/src/physics/p3/tests/infra/p3_ic_cases.cpp @@ -114,6 +114,11 @@ P3Data::Ptr make_mixed (const Int ncol, const Int nlev) { const auto dpres = phi - plo; d.dz(i,k) = consts::RD*T_atm(k)/(g*d.pres(i,k))*dpres; } + for (k = 0; k < nk; ++k) { + d.hetfrz_immersion_nucleation_tend(i,k) = 0.01; + d.hetfrz_contact_nucleation_tend(i,k) = 0.02; + d.hetfrz_deposition_nucleation_tend(i,k) = 0.03; + } } return dp; diff --git a/components/eamxx/src/physics/p3/tests/infra/p3_main_wrap.cpp b/components/eamxx/src/physics/p3/tests/infra/p3_main_wrap.cpp index d4faa4c70527..1e28160797c6 100644 --- a/components/eamxx/src/physics/p3/tests/infra/p3_main_wrap.cpp +++ b/components/eamxx/src/physics/p3/tests/infra/p3_main_wrap.cpp @@ -19,12 +19,13 @@ Int p3_main_wrap(const P3Data& d) { d.bm.data(), d.pres.data(), d.dz.data(), d.nc_nuceat_tend.data(), d.nccn_prescribed.data(), d.ni_activated.data(), d.inv_qc_relvar.data(), d.it, d.precip_liq_surf.data(), d.precip_ice_surf.data(), 1, d.ncol, 1, d.nlev, d.diag_eff_radius_qc.data(), - d.diag_eff_radius_qi.data(), d.diag_eff_radius_qr.data(), d.rho_qi.data(), d.do_predict_nc, d.do_prescribed_CCN, + d.diag_eff_radius_qi.data(), d.diag_eff_radius_qr.data(), d.rho_qi.data(), d.do_predict_nc, d.do_prescribed_CCN, d.use_hetfrz_classnuc, d.dpres.data(), d.inv_exner.data(), d.qv2qi_depos_tend.data(), d.precip_liq_flux.data(), d.precip_ice_flux.data(), d.cld_frac_r.data(), d.cld_frac_l.data(), d.cld_frac_i.data(), d.liq_ice_exchange.data(), d.vap_liq_exchange.data(), - d.vap_ice_exchange.data(),d.qv_prev.data(),d.t_prev.data() ); + d.vap_ice_exchange.data(),d.qv_prev.data(),d.t_prev.data(), + d.hetfrz_immersion_nucleation_tend.data(), d.hetfrz_contact_nucleation_tend.data(), d.hetfrz_deposition_nucleation_tend.data()); } int test_p3_init () { diff --git a/components/eamxx/src/physics/p3/tests/infra/p3_test_data.cpp b/components/eamxx/src/physics/p3/tests/infra/p3_test_data.cpp index 2dff7183ec61..3dcbdc8c29d4 100644 --- a/components/eamxx/src/physics/p3/tests/infra/p3_test_data.cpp +++ b/components/eamxx/src/physics/p3/tests/infra/p3_test_data.cpp @@ -19,6 +19,7 @@ void BackToCellAverageData::randomize(std::mt19937_64& engine) { // Populate the struct with numbers between 0 and 1. std::uniform_real_distribution data_dist(0.0, 1.0); + std::uniform_int_distribution bool_dist(0, 1); cld_frac_l = data_dist(engine); cld_frac_r = data_dist(engine); cld_frac_i = data_dist(engine); @@ -53,6 +54,13 @@ void BackToCellAverageData::randomize(std::mt19937_64& engine) qv2qi_nucleat_tend = data_dist(engine); ni_nucleat_tend = data_dist(engine); qc2qi_berg_tend = data_dist(engine); + ncheti_cnt = data_dist(engine); + qcheti_cnt = data_dist(engine); + nicnt = data_dist(engine); + qicnt = data_dist(engine); + ninuc_cnt = data_dist(engine); + qinuc_cnt = data_dist(engine); + context = bool_dist(engine); } void CalcLiqRelaxationData::randomize(std::mt19937_64& engine) @@ -159,8 +167,9 @@ P3MainPart1Data::P3MainPart1Data( P3MainPart2Data::P3MainPart2Data( Int kts_, Int kte_, Int kbot_, Int ktop_, Int kdir_, - bool do_predict_nc_, bool do_prescribed_CCN_, Real dt_, Real, bool) : + bool do_predict_nc_, bool do_prescribed_CCN_, bool use_hetfrz_classnuc_, Real dt_, Real, bool) : PhysicsTestData( { {(kte_ - kts_) + 1} }, { { + &hetfrz_immersion_nucleation_tend, &hetfrz_contact_nucleation_tend, &hetfrz_deposition_nucleation_tend, &pres, &dpres, &dz, &nc_nuceat_tend, &inv_exner, &exner, &inv_cld_frac_l, &inv_cld_frac_i, &inv_cld_frac_r, &ni_activated, &inv_qc_relvar, &cld_frac_i, &cld_frac_l, &cld_frac_r, &qv_prev, &t_prev, &T_atm, &rho, &inv_rho, &qv_sat_l, &qv_sat_i, &qv_supersat_i, &rhofacr, &rhofaci, &acn, &qv, &th_atm, &qc, &nc, &qr, &nr, &qi, &ni, &qm, &bm, &latent_heat_vapor, &latent_heat_sublim, &latent_heat_fusion, &qc_incld, &qr_incld, @@ -168,7 +177,7 @@ P3MainPart2Data::P3MainPart2Data( &cdistr, &mu_r, &lamr, &logn0r, &qv2qi_depos_tend, &precip_total_tend, &nevapr, &qr_evap_tend, &vap_liq_exchange, &vap_ice_exchange, &liq_ice_exchange, &pratot, &prctot} }), kts(kts_), kte(kte_), kbot(kbot_), ktop(ktop_), kdir(kdir_), - do_predict_nc(do_predict_nc_), do_prescribed_CCN(do_prescribed_CCN_), dt(dt_), inv_dt(1 / dt) + do_predict_nc(do_predict_nc_), do_prescribed_CCN(do_prescribed_CCN_), use_hetfrz_classnuc(use_hetfrz_classnuc_), dt(dt_) {} /////////////////////////////////////////////////////////////////////////////// @@ -189,36 +198,43 @@ P3MainPart3Data::P3MainPart3Data( /////////////////////////////////////////////////////////////////////////////// P3MainData::P3MainData( - Int its_, Int ite_, Int kts_, Int kte_, Int it_, Real dt_, bool do_predict_nc_, bool do_prescribed_CCN_, Real) : + Int its_, Int ite_, Int kts_, Int kte_, Int it_, Real dt_, bool do_predict_nc_, bool do_prescribed_CCN_, bool use_hetfrz_classnuc_, Real) : PhysicsTestData( { {(ite_ - its_) + 1, (kte_ - kts_) + 1}, {(ite_ - its_) + 1, (kte_ - kts_) + 2} }, { { &pres, &dz, &nc_nuceat_tend, &nccn_prescribed, &ni_activated, &dpres, &inv_exner, &cld_frac_i, &cld_frac_l, &cld_frac_r, - &inv_qc_relvar, &qc, &nc, &qr, &nr, &qi, &qm, &ni, &bm, &qv, &th_atm, &qv_prev, &t_prev, + &inv_qc_relvar, &qc, &nc, &qr, &nr, &qi, &qm, &ni, &bm, &qv, &th_atm, &qv_prev, &t_prev, &hetfrz_immersion_nucleation_tend, + &hetfrz_contact_nucleation_tend, &hetfrz_deposition_nucleation_tend, &diag_eff_radius_qc, &diag_eff_radius_qi, &diag_eff_radius_qr, &rho_qi, &mu_c, &lamc, &qv2qi_depos_tend, &precip_total_tend, &nevapr, &qr_evap_tend, &liq_ice_exchange, &vap_liq_exchange, &vap_ice_exchange, &precip_liq_flux, &precip_ice_flux}, {&precip_liq_surf, &precip_ice_surf} }), // these two are (ni, nk+1) - its(its_), ite(ite_), kts(kts_), kte(kte_), it(it_), dt(dt_), do_predict_nc(do_predict_nc_), do_prescribed_CCN(do_prescribed_CCN_) + its(its_), ite(ite_), kts(kts_), kte(kte_), it(it_), dt(dt_), do_predict_nc(do_predict_nc_), do_prescribed_CCN(do_prescribed_CCN_), + use_hetfrz_classnuc(use_hetfrz_classnuc_) {} void IceSupersatConservationData::randomize(std::mt19937_64& engine) { std::uniform_real_distribution data_dist(0.0, 1.0); - - cld_frac_i = data_dist(engine); - qv = data_dist(engine); - qv_sat_i = data_dist(engine); - latent_heat_sublim = data_dist(engine); - t_atm = data_dist(engine); - dt = data_dist(engine); - qi2qv_sublim_tend = data_dist(engine); - qr2qv_evap_tend = data_dist(engine); - qidep = data_dist(engine); - qinuc = data_dist(engine); + std::uniform_int_distribution bool_dist(0, 1); + + cld_frac_i = data_dist(engine); + qv = data_dist(engine); + qv_sat_i = data_dist(engine); + latent_heat_sublim = data_dist(engine); + t_atm = data_dist(engine); + dt = data_dist(engine); + qi2qv_sublim_tend = data_dist(engine); + qr2qv_evap_tend = data_dist(engine); + qidep = data_dist(engine); + qinuc = data_dist(engine); + qinuc_cnt = data_dist(engine); + context = bool_dist(engine); + use_hetfrz_classnuc = bool_dist(engine); } void NcConservationData::randomize(std::mt19937_64& engine) { std::uniform_real_distribution data_dist(0.0, 1.0); + std::uniform_int_distribution bool_dist(0, 1); nc = data_dist(engine); nc_selfcollect_tend = data_dist(engine); @@ -227,6 +243,10 @@ void NcConservationData::randomize(std::mt19937_64& engine) nc2ni_immers_freeze_tend = data_dist(engine); nc_accret_tend = data_dist(engine); nc2nr_autoconv_tend = data_dist(engine); + ncheti_cnt = data_dist(engine); + nicnt = data_dist(engine); + use_hetfrz_classnuc = bool_dist(engine); + context = bool_dist(engine); } void NrConservationData::randomize(std::mt19937_64& engine) @@ -249,15 +269,21 @@ void NrConservationData::randomize(std::mt19937_64& engine) void NiConservationData::randomize(std::mt19937_64& engine) { std::uniform_real_distribution data_dist(0.0, 1.0); + std::uniform_int_distribution bool_dist(0, 1); ni = data_dist(engine); ni_nucleat_tend = data_dist(engine); nr2ni_immers_freeze_tend = data_dist(engine); nc2ni_immers_freeze_tend = data_dist(engine); + ncheti_cnt = data_dist(engine); + nicnt = data_dist(engine); + ninuc_cnt = data_dist(engine); dt = data_dist(engine); ni2nr_melt_tend = data_dist(engine); ni_sublim_tend = data_dist(engine); ni_selfcollect_tend = data_dist(engine); + use_hetfrz_classnuc = bool_dist(engine); + context = bool_dist(engine); } void PreventLiqSupersaturationData::randomize(std::mt19937_64& engine) @@ -947,6 +973,7 @@ void p3_main_part1_host( void p3_main_part2_host( Int kts, Int kte, Int kbot, Int ktop, Int kdir, bool do_predict_nc, bool do_prescribed_CCN, Real dt, Real inv_dt, + Real *hetfrz_immersion_nucleation_tend, Real *hetfrz_contact_nucleation_tend, Real *hetfrz_deposition_nucleation_tend, Real* pres, Real* dpres, Real* dz, Real* nc_nuceat_tend, Real* inv_exner, Real* exner, Real* inv_cld_frac_l, Real* inv_cld_frac_i, Real* inv_cld_frac_r, Real* ni_activated, Real* inv_qc_relvar, Real* cld_frac_i, Real* cld_frac_l, Real* cld_frac_r, Real* qv_prev, Real* t_prev, Real* T_atm, Real* rho, Real* inv_rho, Real* qv_sat_l, Real* qv_sat_i, Real* qv_supersat_i, Real* rhofacr, Real* rhofaci, @@ -980,7 +1007,8 @@ void p3_main_part2_host( // Set up views std::vector temp_d(P3MainPart2Data::NUM_ARRAYS-3); - ekat::host_to_device({pres, dpres, dz, nc_nuceat_tend, inv_exner, exner, inv_cld_frac_l, inv_cld_frac_i, inv_cld_frac_r, ni_activated, inv_qc_relvar, cld_frac_i, cld_frac_l, cld_frac_r, + ekat::host_to_device({hetfrz_immersion_nucleation_tend, hetfrz_contact_nucleation_tend, hetfrz_deposition_nucleation_tend, + pres, dpres, dz, nc_nuceat_tend, inv_exner, exner, inv_cld_frac_l, inv_cld_frac_i, inv_cld_frac_r, ni_activated, inv_qc_relvar, cld_frac_i, cld_frac_l, cld_frac_r, T_atm, rho, inv_rho, qv_sat_l, qv_sat_i, qv_supersat_i, rhofacr, rhofaci, acn, qv, th_atm, qc, nc, qr, nr, qi, ni, qm, bm, qc_incld, qr_incld, qi_incld, qm_incld, nc_incld, nr_incld, ni_incld, bm_incld, mu_c, nu, lamc, cdist, cdist1, @@ -991,6 +1019,9 @@ void p3_main_part2_host( int current_index = 0; view_1d + hetfrz_immersion_nucleation_tend_d(temp_d[current_index++]), + hetfrz_contact_nucleation_tend_d(temp_d[current_index++]), + hetfrz_deposition_nucleation_tend_d(temp_d[current_index++]), pres_d (temp_d[current_index++]), dpres_d (temp_d[current_index++]), dz_d (temp_d[current_index++]), @@ -1064,7 +1095,9 @@ void p3_main_part2_host( Kokkos::parallel_for(policy, KOKKOS_LAMBDA(const MemberType& team) { P3F::p3_main_part2( - team, nk_pack, max_total_ni, do_predict_nc, do_prescribed_CCN, dt, inv_dt, dnu, ice_table_vals, collect_table_vals, revap_table_vals, + team, nk_pack, max_total_ni, do_predict_nc, do_prescribed_CCN, dt, inv_dt, + hetfrz_immersion_nucleation_tend_d, hetfrz_contact_nucleation_tend_d, hetfrz_deposition_nucleation_tend_d, + dnu, ice_table_vals, collect_table_vals, revap_table_vals, pres_d, dpres_d, dz_d, nc_nuceat_tend_d, inv_exner_d, exner_d, inv_cld_frac_l_d, inv_cld_frac_i_d, inv_cld_frac_r_d, ni_activated_d, inv_qc_relvar_d, cld_frac_i_d, cld_frac_l_d, cld_frac_r_d, qv_prev_d, t_prev_d, t_d, rho_d, inv_rho_d, qv_sat_l_d, qv_sat_i_d, qv_supersat_i_d, rhofacr_d, rhofaci_d, acn_d, @@ -1216,9 +1249,10 @@ Int p3_main_host( Real* qi, Real* qm, Real* ni, Real* bm, Real* pres, Real* dz, Real* nc_nuceat_tend, Real* nccn_prescribed, Real* ni_activated, Real* inv_qc_relvar, Int it, Real* precip_liq_surf, Real* precip_ice_surf, Int its, Int ite, Int kts, Int kte, Real* diag_eff_radius_qc, - Real* diag_eff_radius_qi, Real* diag_eff_radius_qr, Real* rho_qi, bool do_predict_nc, bool do_prescribed_CCN, Real* dpres, Real* inv_exner, + Real* diag_eff_radius_qi, Real* diag_eff_radius_qr, Real* rho_qi, bool do_predict_nc, bool do_prescribed_CCN, bool use_hetfrz_classnuc, Real* dpres, Real* inv_exner, Real* qv2qi_depos_tend, Real* precip_liq_flux, Real* precip_ice_flux, Real* cld_frac_r, Real* cld_frac_l, Real* cld_frac_i, - Real* liq_ice_exchange, Real* vap_liq_exchange, Real* vap_ice_exchange, Real* qv_prev, Real* t_prev) + Real* liq_ice_exchange, Real* vap_liq_exchange, Real* vap_ice_exchange, Real* qv_prev, Real* t_prev, + Real* hetfrz_immersion_nucleation_tend, Real* hetfrz_contact_nucleation_tend, Real* hetfrz_deposition_nucleation_tend) { using P3F = Functions; @@ -1248,7 +1282,10 @@ Int p3_main_host( pres, dz, nc_nuceat_tend, nccn_prescribed, ni_activated, dpres, inv_exner, cld_frac_i, cld_frac_l, cld_frac_r, inv_qc_relvar, qc, nc, qr, nr, qi, qm, ni, bm, qv, th_atm, qv_prev, t_prev, diag_eff_radius_qc, diag_eff_radius_qi, diag_eff_radius_qr, rho_qi, qv2qi_depos_tend, - liq_ice_exchange, vap_liq_exchange, vap_ice_exchange, precip_liq_flux, precip_ice_flux, precip_liq_surf, precip_ice_surf + liq_ice_exchange, vap_liq_exchange, vap_ice_exchange, + hetfrz_immersion_nucleation_tend, hetfrz_contact_nucleation_tend, hetfrz_deposition_nucleation_tend, + precip_liq_flux, precip_ice_flux, + precip_liq_surf, precip_ice_surf }; int dim_sizes_len = dim1_sizes.size(); @@ -1274,7 +1311,7 @@ Int p3_main_host( nccn_prescribed_d (temp_d[counter++]), ni_activated_d (temp_d[counter++]), dpres_d (temp_d[counter++]), //5 - inv_exner_d (temp_d[counter++]), + inv_exner_d (temp_d[counter++]), cld_frac_i_d (temp_d[counter++]), cld_frac_l_d (temp_d[counter++]), cld_frac_r_d (temp_d[counter++]), @@ -1299,10 +1336,13 @@ Int p3_main_host( liq_ice_exchange_d (temp_d[counter++]), vap_liq_exchange_d (temp_d[counter++]), vap_ice_exchange_d (temp_d[counter++]), //30 + hetfrz_immersion_nucleation_tend_d(temp_d[counter++]), + hetfrz_contact_nucleation_tend_d(temp_d[counter++]), + hetfrz_deposition_nucleation_tend_d(temp_d[counter++]), precip_liq_flux_d (temp_d[counter++]), - precip_ice_flux_d (temp_d[counter++]), + precip_ice_flux_d (temp_d[counter++]), // 35 precip_liq_surf_temp_d (temp_d[counter++]), - precip_ice_surf_temp_d (temp_d[counter++]); //34 + precip_ice_surf_temp_d (temp_d[counter++]); // Special cases: precip_liq_surf=1d(ni), precip_ice_surf=1d(ni), col_location=2d(nj, 3) sview_1d precip_liq_surf_d("precip_liq_surf_d", nj), precip_ice_surf_d("precip_ice_surf_d", nj); @@ -1328,7 +1368,7 @@ Int p3_main_host( ni_d, bm_d, qv_d, th_atm_d}; P3F::P3DiagnosticInputs diag_inputs{nc_nuceat_tend_d, nccn_prescribed_d, ni_activated_d, inv_qc_relvar_d, cld_frac_i_d, cld_frac_l_d, cld_frac_r_d, pres_d, dz_d, dpres_d, - inv_exner_d, qv_prev_d, t_prev_d}; + inv_exner_d, qv_prev_d, t_prev_d, hetfrz_immersion_nucleation_tend_d, hetfrz_contact_nucleation_tend_d, hetfrz_deposition_nucleation_tend_d}; P3F::P3DiagnosticOutputs diag_outputs{qv2qi_depos_tend_d, precip_liq_surf_d, precip_ice_surf_d, diag_eff_radius_qc_d, diag_eff_radius_qi_d, diag_eff_radius_qr_d, rho_qi_d,precip_liq_flux_d, precip_ice_flux_d, precip_total_tend_d, nevapr_d}; @@ -1395,8 +1435,8 @@ Int p3_main_host( liq_ice_exchange_d, vap_liq_exchange_d, vap_ice_exchange_d, precip_liq_flux_d, precip_ice_flux_d, precip_liq_surf_temp_d, precip_ice_surf_temp_d }; - std::vector dim1_sizes_out(P3MainData::NUM_ARRAYS - 13, nj); - std::vector dim2_sizes_out(P3MainData::NUM_ARRAYS - 13, nk); + std::vector dim1_sizes_out(P3MainData::NUM_ARRAYS - 16, nj); + std::vector dim2_sizes_out(P3MainData::NUM_ARRAYS - 16, nk); int dim_sizes_out_len = dim1_sizes_out.size(); dim2_sizes_out[dim_sizes_out_len-4] = nk+1; // precip_liq_flux dim2_sizes_out[dim_sizes_out_len-3] = nk+1; // precip_ice_flux diff --git a/components/eamxx/src/physics/p3/tests/infra/p3_test_data.hpp b/components/eamxx/src/physics/p3/tests/infra/p3_test_data.hpp index 775120e080dc..998913f58d71 100644 --- a/components/eamxx/src/physics/p3/tests/infra/p3_test_data.hpp +++ b/components/eamxx/src/physics/p3/tests/infra/p3_test_data.hpp @@ -86,7 +86,8 @@ struct BackToCellAverageData Real qc2qr_accret_tend, qr2qv_evap_tend, qc2qr_autoconv_tend, nc_accret_tend, nc_selfcollect_tend, nc2nr_autoconv_tend, nr_selfcollect_tend, nr_evap_tend, ncautr, qcnuc, nc_nuceat_tend, qi2qv_sublim_tend, nr_ice_shed_tend, qc2qi_hetero_freeze_tend, qr2qi_collect_tend, qc2qr_ice_shed_tend, qi2qr_melt_tend, qc2qi_collect_tend, qr2qi_immers_freeze_tend, ni2nr_melt_tend, nc_collect_tend, ncshdc, nc2ni_immers_freeze_tend, nr_collect_tend, ni_selfcollect_tend, qv2qi_vapdep_tend, nr2ni_immers_freeze_tend, ni_sublim_tend, qv2qi_nucleat_tend, ni_nucleat_tend, - qc2qi_berg_tend; + qc2qi_berg_tend, ncheti_cnt, qcheti_cnt, nicnt, qicnt, ninuc_cnt, qinuc_cnt; + bool context; // This populates all fields with test data within [0,1]. void randomize(std::mt19937_64& engine); @@ -105,9 +106,11 @@ struct CloudWaterConservationData Real qc, dt; //output - Real qc2qr_autoconv_tend, qc2qr_accret_tend, qc2qi_collect_tend, qc2qi_hetero_freeze_tend, qc2qr_ice_shed_tend, qc2qi_berg_tend, qi2qv_sublim_tend, qv2qi_vapdep_tend; + Real qc2qr_autoconv_tend, qc2qr_accret_tend, qc2qi_collect_tend, qc2qi_hetero_freeze_tend, qc2qr_ice_shed_tend, qc2qi_berg_tend, qi2qv_sublim_tend, qv2qi_vapdep_tend, + qcheti_cnt, qicnt; + bool use_hetfrz_classnuc, context; - PTD_RW_SCALARS_ONLY(8, qc2qr_autoconv_tend, qc2qr_accret_tend, qc2qi_collect_tend, qc2qi_hetero_freeze_tend, qc2qr_ice_shed_tend, qc2qi_berg_tend, qi2qv_sublim_tend, qv2qi_vapdep_tend); + PTD_RW_SCALARS_ONLY(10, qc2qr_autoconv_tend, qc2qr_accret_tend, qc2qi_collect_tend, qc2qi_hetero_freeze_tend, qc2qr_ice_shed_tend, qc2qi_berg_tend, qi2qv_sublim_tend, qv2qi_vapdep_tend, qcheti_cnt, qicnt); }; struct RainWaterConservationData @@ -124,7 +127,8 @@ struct RainWaterConservationData struct IceWaterConservationData { //inputs - Real qi, qv2qi_vapdep_tend, qv2qi_nucleat_tend, qc2qi_berg_tend, qr2qi_collect_tend, qc2qi_collect_tend, qr2qi_immers_freeze_tend, qc2qi_hetero_freeze_tend, dt; + Real qi, qv2qi_vapdep_tend, qv2qi_nucleat_tend, qc2qi_berg_tend, qr2qi_collect_tend, qc2qi_collect_tend, qr2qi_immers_freeze_tend, qc2qi_hetero_freeze_tend, dt, qinuc_cnt, qcheti_cnt, qicnt; + bool use_hetfrz_classnuc, context; //output Real qi2qv_sublim_tend, qi2qr_melt_tend; @@ -472,10 +476,11 @@ struct P3UpdatePrognosticIceData Real qc2qi_hetero_freeze_tend, qc2qi_collect_tend, qc2qr_ice_shed_tend, nc_collect_tend, nc2ni_immers_freeze_tend, ncshdc, qr2qi_collect_tend, nr_collect_tend, qr2qi_immers_freeze_tend, nr2ni_immers_freeze_tend, nr_ice_shed_tend, qi2qr_melt_tend, ni2nr_melt_tend, qi2qv_sublim_tend, qv2qi_vapdep_tend, qv2qi_nucleat_tend, ni_nucleat_tend, ni_selfcollect_tend, ni_sublim_tend, qc2qi_berg_tend, inv_exner, latent_heat_sublim, latent_heat_fusion; bool do_predict_nc, log_wetgrowth; - Real dt, nmltratio, rho_qm_cloud; + Real dt, nmltratio, rho_qm_cloud, ncheti_cnt, nicnt, ninuc_cnt, qcheti_cnt, qicnt, qinuc_cnt; // In/outs Real th_atm, qv, qi, ni, qm, bm, qc, nc, qr, nr; + bool use_hetfrz_classnuc, context; PTD_RW_SCALARS_ONLY(10, th_atm, qv, qi, ni, qm, bm, qc, nc, qr, nr); }; @@ -679,13 +684,13 @@ struct P3MainPart1Data : public PhysicsTestData struct P3MainPart2Data : public PhysicsTestData { - static constexpr size_t NUM_ARRAYS = 64; + static constexpr size_t NUM_ARRAYS = 67; // Inputs Int kts, kte, kbot, ktop, kdir; - bool do_predict_nc, do_prescribed_CCN; + bool do_predict_nc, do_prescribed_CCN, use_hetfrz_classnuc; Real dt, inv_dt; - Real* pres, *dpres, *dz, *nc_nuceat_tend, *inv_exner, *exner, *inv_cld_frac_l, *inv_cld_frac_i, *inv_cld_frac_r, *ni_activated, *inv_qc_relvar, *cld_frac_i, *cld_frac_l, *cld_frac_r, *qv_prev, *t_prev; + Real *hetfrz_immersion_nucleation_tend, *hetfrz_contact_nucleation_tend, *hetfrz_deposition_nucleation_tend, *pres, *dpres, *dz, *nc_nuceat_tend, *inv_exner, *exner, *inv_cld_frac_l, *inv_cld_frac_i, *inv_cld_frac_r, *ni_activated, *inv_qc_relvar, *cld_frac_i, *cld_frac_l, *cld_frac_r, *qv_prev, *t_prev; // In/out Real* T_atm, *rho, *inv_rho, *qv_sat_l, *qv_sat_i, *qv_supersat_i, *rhofacr, *rhofaci, *acn, @@ -697,7 +702,7 @@ struct P3MainPart2Data : public PhysicsTestData bool is_hydromet_present; P3MainPart2Data(Int kts_, Int kte_, Int kbot_, Int ktop_, Int kdir_, - bool do_predict_nc_, bool do_prescribed_CCN, Real dt_, Real=0., bool=false); + bool do_predict_nc_, bool do_prescribed_CCN, bool use_hetfrz_classnuc, Real dt_, Real=0., bool=false); PTD_STD_DEF(P3MainPart2Data, 10, kts, kte, kbot, ktop, kdir, do_predict_nc, do_prescribed_CCN, dt, inv_dt, is_hydromet_present); @@ -733,14 +738,15 @@ struct P3MainPart3Data : public PhysicsTestData struct P3MainData : public PhysicsTestData { - static constexpr size_t NUM_ARRAYS = 35; - static constexpr size_t NUM_INPUT_ARRAYS = 24; + static constexpr size_t NUM_ARRAYS = 38; + static constexpr size_t NUM_INPUT_ARRAYS = 27; // Inputs Int its, ite, kts, kte, it; Real* pres, *dz, *nc_nuceat_tend, *nccn_prescribed, *ni_activated, *dpres, *inv_exner, *cld_frac_i, *cld_frac_l, *cld_frac_r, *inv_qc_relvar, *qv_prev, *t_prev; + Real* hetfrz_immersion_nucleation_tend, *hetfrz_contact_nucleation_tend, *hetfrz_deposition_nucleation_tend; Real dt; - bool do_predict_nc, do_prescribed_CCN; + bool do_predict_nc, do_prescribed_CCN, use_hetfrz_classnuc; // In/out Real* qc, *nc, *qr, *nr, *qi, *qm, *ni, *bm, *qv, *th_atm; @@ -751,17 +757,17 @@ struct P3MainData : public PhysicsTestData *precip_liq_flux, *precip_ice_flux, *precip_liq_surf, *precip_ice_surf; Real elapsed_s; - P3MainData(Int its_, Int ite_, Int kts_, Int kte_, Int it_, Real dt_, bool do_predict_nc_, bool do_prescribed_CCN_, Real=0.); + P3MainData(Int its_, Int ite_, Int kts_, Int kte_, Int it_, Real dt_, bool do_predict_nc_, bool do_prescribed_CCN_, bool=false, Real=0.); - PTD_STD_DEF(P3MainData, 9, its, ite, kts, kte, it, dt, do_predict_nc, do_prescribed_CCN, elapsed_s); + PTD_STD_DEF(P3MainData, 10, its, ite, kts, kte, it, dt, do_predict_nc, do_prescribed_CCN, use_hetfrz_classnuc, elapsed_s); }; struct IceSupersatConservationData { // Inputs Real cld_frac_i, qv, qv_sat_i, latent_heat_sublim, t_atm, dt, qi2qv_sublim_tend, qr2qv_evap_tend; - + bool context, use_hetfrz_classnuc; // Inputs/Outputs - Real qidep, qinuc; + Real qidep, qinuc, qinuc_cnt; void randomize(std::mt19937_64& engine); @@ -773,7 +779,8 @@ struct NcConservationData { Real nc, nc_selfcollect_tend, dt; // Inputs/Outputs - Real nc_collect_tend, nc2ni_immers_freeze_tend, nc_accret_tend, nc2nr_autoconv_tend; + Real nc_collect_tend, nc2ni_immers_freeze_tend, nc_accret_tend, nc2nr_autoconv_tend, ncheti_cnt, nicnt; + bool use_hetfrz_classnuc, context; void randomize(std::mt19937_64& engine); @@ -794,7 +801,8 @@ struct NrConservationData { struct NiConservationData { // Inputs - Real ni, ni_nucleat_tend, nr2ni_immers_freeze_tend, nc2ni_immers_freeze_tend, dt; + Real ni, ni_nucleat_tend, nr2ni_immers_freeze_tend, nc2ni_immers_freeze_tend, ncheti_cnt, nicnt, ninuc_cnt, dt; + bool use_hetfrz_classnuc, context; // Inputs/Outputs Real ni2nr_melt_tend, ni_sublim_tend, ni_selfcollect_tend; @@ -871,6 +879,7 @@ void p3_main_part1_host( void p3_main_part2_host( Int kts, Int kte, Int kbot, Int ktop, Int kdir, bool do_predict_nc, bool do_prescribed_CCN, Real dt, Real inv_dt, + Real *hetfrz_immersion_nucleation_tend, Real *hetfrz_contact_nucleation_tend, Real *hetfrz_deposition_nucleation_tend, Real* pres, Real* dpres, Real* dz, Real* nc_nuceat_tend, Real* inv_exner, Real* exner, Real* inv_cld_frac_l, Real* inv_cld_frac_i, Real* inv_cld_frac_r, Real* ni_activated, Real* inv_qc_relvar, Real* cld_frac_i, Real* cld_frac_l, Real* cld_frac_r, Real* qv_prev, Real* t_prev, Real* T_atm, Real* rho, Real* inv_rho, Real* qv_sat_l, Real* qv_sat_i, Real* qv_supersat_i, Real* rhofacr, Real* rhofaci, Real* acn, Real* qv, Real* th_atm, Real* qc, Real* nc, Real* qr, Real* nr, Real* qi, Real* ni, Real* qm, Real* bm, Real* qc_incld, Real* qr_incld, Real* qi_incld, Real* qm_incld, Real* nc_incld, Real* nr_incld, @@ -890,9 +899,10 @@ Int p3_main_host( Real* qi, Real* qm, Real* ni, Real* bm, Real* pres, Real* dz, Real* nc_nuceat_tend, Real* nccn_prescribed, Real* ni_activated, Real* inv_qc_relvar, Int it, Real* precip_liq_surf, Real* precip_ice_surf, Int its, Int ite, Int kts, Int kte, Real* diag_eff_radius_qc, - Real* diag_eff_radius_qi, Real* diag_eff_radius_qr, Real* rho_qi, bool do_predict_nc, bool do_prescribed_CCN, Real* dpres, Real* inv_exner, + Real* diag_eff_radius_qi, Real* diag_eff_radius_qr, Real* rho_qi, bool do_predict_nc, bool do_prescribed_CCN, bool use_hetfrz_classnuc, Real* dpres, Real* inv_exner, Real* qv2qi_depos_tend, Real* precip_liq_flux, Real* precip_ice_flux, Real* cld_frac_r, Real* cld_frac_l, Real* cld_frac_i, - Real* liq_ice_exchange, Real* vap_liq_exchange, Real* vap_ice_exchange, Real* qv_prev, Real* t_prev); + Real* liq_ice_exchange, Real* vap_liq_exchange, Real* vap_ice_exchange, Real* qv_prev, Real* t_prev, + Real* hetfrz_immersion_nucleation_tend, Real* hetfrz_contact_nucleation_tend, Real* hetfrz_deposition_nucleation_tend); } // namespace p3 } // namespace scream diff --git a/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp index b108ce329d3e..121ef2664544 100644 --- a/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp @@ -59,7 +59,9 @@ void run_bfb() nr_evap_tend, ncautr, qi2qv_sublim_tend, nr_ice_shed_tend, qc2qi_hetero_freeze_tend, qr2qi_collect_tend, qc2qr_ice_shed_tend, qi2qr_melt_tend, qc2qi_collect_tend, qr2qi_immers_freeze_tend, ni2nr_melt_tend, nc_collect_tend, ncshdc, nc2ni_immers_freeze_tend, nr_collect_tend, ni_selfcollect_tend, qv2qi_vapdep_tend, nr2ni_immers_freeze_tend, - ni_sublim_tend, qv2qi_nucleat_tend, ni_nucleat_tend, qc2qi_berg_tend; + ni_sublim_tend, qv2qi_nucleat_tend, ni_nucleat_tend, qc2qi_berg_tend, + ncheti_cnt, qcheti_cnt, nicnt, qicnt, ninuc_cnt, qinuc_cnt; + Smask context; for (Int s = 0, vs = offset; s < Spack::n; ++s, ++vs) { cld_frac_l[s] = device_data[s].cld_frac_l; cld_frac_r[s] = device_data[s].cld_frac_r; @@ -93,13 +95,20 @@ void run_bfb() qv2qi_nucleat_tend[s] = device_data[s].qv2qi_nucleat_tend; ni_nucleat_tend[s] = device_data[s].ni_nucleat_tend; qc2qi_berg_tend[s] = device_data[s].qc2qi_berg_tend; + ncheti_cnt[s] = device_data[s].ncheti_cnt; + qcheti_cnt[s] = device_data[s].qcheti_cnt; + nicnt[s] = device_data[s].nicnt; + qicnt[s] = device_data[s].qicnt; + ninuc_cnt[s] = device_data[s].ninuc_cnt; + qinuc_cnt[s] = device_data[s].qinuc_cnt; + context.set(s, device_data[s].context); } - Functions::back_to_cell_average(cld_frac_l, cld_frac_r, cld_frac_i, qc2qr_accret_tend, qr2qv_evap_tend, qc2qr_autoconv_tend, nc_accret_tend, nc_selfcollect_tend, nc2nr_autoconv_tend, nr_selfcollect_tend, nr_evap_tend, ncautr, qi2qv_sublim_tend, nr_ice_shed_tend, qc2qi_hetero_freeze_tend, qr2qi_collect_tend, qc2qr_ice_shed_tend, qi2qr_melt_tend, qc2qi_collect_tend, qr2qi_immers_freeze_tend, ni2nr_melt_tend, nc_collect_tend, ncshdc, nc2ni_immers_freeze_tend, - nr_collect_tend, ni_selfcollect_tend, qv2qi_vapdep_tend, nr2ni_immers_freeze_tend, ni_sublim_tend, qv2qi_nucleat_tend, ni_nucleat_tend, qc2qi_berg_tend); + nr_collect_tend, ni_selfcollect_tend, qv2qi_vapdep_tend, nr2ni_immers_freeze_tend, ni_sublim_tend, qv2qi_nucleat_tend, ni_nucleat_tend, qc2qi_berg_tend, + ncheti_cnt, qcheti_cnt, nicnt, qicnt, ninuc_cnt, qinuc_cnt, context); // Copy results back into views for (Int s = 0, vs = offset; s < Spack::n; ++s, ++vs) { @@ -195,5 +204,4 @@ TEST_CASE("p3_back_to_cell_average", "[p3_functions]") t.run_phys(); t.run_bfb(); } - } // namespace diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp index dcbdfc618263..90a761e74575 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp @@ -29,7 +29,6 @@ struct UnitWrap::UnitTest::TestIceSupersatConservation : public UnitWrap::Uni for (auto& d : baseline_data) { d.randomize(engine); d.dt = baseline_data[0].dt; // hold this fixed, it is not packed data - // C++ impl uses constants for latent_heat values. Manually set here // so F90 can match d.latent_heat_sublim = latvap+latice; @@ -54,24 +53,28 @@ struct UnitWrap::UnitTest::TestIceSupersatConservation : public UnitWrap::Uni const Int offset = i * Spack::n; // Init pack inputs - Spack cld_frac_i, qidep, qinuc, qv, qv_sat_i, t_atm, qi2qv_sublim_tend, qr2qv_evap_tend; + Spack cld_frac_i, qidep, qinuc, qinuc_cnt, qv, qv_sat_i, t_atm, qi2qv_sublim_tend, qr2qv_evap_tend; + Smask context; for (Int s = 0, vs = offset; s < Spack::n; ++s, ++vs) { - cld_frac_i[s] = cxx_device(vs).cld_frac_i; - qidep[s] = cxx_device(vs).qidep; - qinuc[s] = cxx_device(vs).qinuc; - qv[s] = cxx_device(vs).qv; - qv_sat_i[s] = cxx_device(vs).qv_sat_i; - t_atm[s] = cxx_device(vs).t_atm; + cld_frac_i[s] = cxx_device(vs).cld_frac_i; + qidep[s] = cxx_device(vs).qidep; + qinuc[s] = cxx_device(vs).qinuc; + qinuc_cnt[s] = cxx_device(vs).qinuc_cnt; + qv[s] = cxx_device(vs).qv; + qv_sat_i[s] = cxx_device(vs).qv_sat_i; + t_atm[s] = cxx_device(vs).t_atm; qi2qv_sublim_tend[s] = cxx_device(vs).qi2qv_sublim_tend; - qr2qv_evap_tend[s] = cxx_device(vs).qr2qv_evap_tend; + qr2qv_evap_tend[s] = cxx_device(vs).qr2qv_evap_tend; + context.set(s, cxx_device(vs).context); } - - Functions::ice_supersat_conservation(qidep, qinuc, cld_frac_i, qv, qv_sat_i, t_atm, cxx_device(offset).dt, qi2qv_sublim_tend, qr2qv_evap_tend); + const bool use_hetfrz_classnuc = cxx_device(offset).use_hetfrz_classnuc; + Functions::ice_supersat_conservation(qidep, qinuc, qinuc_cnt, cld_frac_i, qv, qv_sat_i, t_atm, cxx_device(offset).dt, qi2qv_sublim_tend, qr2qv_evap_tend, use_hetfrz_classnuc, context); // Copy spacks back into cxx_device view for (Int s = 0, vs = offset; s < Spack::n; ++s, ++vs) { cxx_device(vs).qidep = qidep[s]; cxx_device(vs).qinuc = qinuc[s]; + cxx_device(vs).qinuc_cnt = qinuc_cnt[s]; } }); @@ -84,6 +87,7 @@ struct UnitWrap::UnitTest::TestIceSupersatConservation : public UnitWrap::Uni IceSupersatConservationData& d_cxx = cxx_host[i]; REQUIRE(d_f90.qidep == d_cxx.qidep); REQUIRE(d_f90.qinuc == d_cxx.qinuc); + REQUIRE(d_f90.qinuc_cnt == d_cxx.qinuc_cnt); } } else if (this->m_baseline_action == GENERATE) { diff --git a/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp index c60efd2b8824..0d4fd3aa03dd 100644 --- a/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp @@ -168,11 +168,11 @@ void run_bfb_p3_main_part2() constexpr Scalar latice = C::LatIce; P3MainPart2Data isds_baseline[] = { - // kts, kte, ktop, kbot, kdir, do_predict_nc, do_prescribed_CCN, dt - P3MainPart2Data(1, 72, 1, 72, 1, false, true, 1.800E+03), - P3MainPart2Data(1, 72, 1, 72, 1, true, true, 1.800E+03), - P3MainPart2Data(1, 72, 72, 1, -1, false, false, 1.800E+03), - P3MainPart2Data(1, 72, 72, 1, -1, true, false, 1.800E+03), + // kts, kte, ktop, kbot, kdir, do_predict_nc, do_prescribed_CCN, use_hetfrz_classnuc, dt + P3MainPart2Data(1, 72, 1, 72, 1, false, true, true, 1.800E+03), + P3MainPart2Data(1, 72, 1, 72, 1, true, true, false, 1.800E+03), + P3MainPart2Data(1, 72, 72, 1, -1, false, false, true, 1.800E+03), + P3MainPart2Data(1, 72, 72, 1, -1, true, false, false, 1.800E+03), }; static constexpr Int num_runs = sizeof(isds_baseline) / sizeof(P3MainPart2Data); @@ -212,15 +212,16 @@ void run_bfb_p3_main_part2() // Get data from cxx for (auto& d : isds_cxx) { - p3_main_part2_host( + p3_main_part2_host( d.kts, d.kte, d.kbot, d.ktop, d.kdir, d.do_predict_nc, d.do_prescribed_CCN, d.dt, d.inv_dt, + d.hetfrz_immersion_nucleation_tend, d.hetfrz_contact_nucleation_tend, d.hetfrz_deposition_nucleation_tend, d.pres, d.dpres, d.dz, d.nc_nuceat_tend, d.inv_exner, d.exner, d.inv_cld_frac_l, d.inv_cld_frac_i, d.inv_cld_frac_r, d.ni_activated, d.inv_qc_relvar, d.cld_frac_i, d.cld_frac_l, d.cld_frac_r, d.qv_prev, d.t_prev, d.T_atm, d.rho, d.inv_rho, d.qv_sat_l, d.qv_sat_i, d.qv_supersat_i, d.rhofacr, d.rhofaci, d.acn, d.qv, d.th_atm, d.qc, d.nc, d.qr, d.nr, d.qi, d.ni, d.qm, d.bm, d.qc_incld, d.qr_incld, d.qi_incld, d.qm_incld, d.nc_incld, d.nr_incld, d.ni_incld, d.bm_incld, d.mu_c, d.nu, d.lamc, d.cdist, d.cdist1, d.cdistr, d.mu_r, d.lamr, d.logn0r, d.qv2qi_depos_tend, d.precip_total_tend, d.nevapr, d.qr_evap_tend, d.vap_liq_exchange, d.vap_ice_exchange, d.liq_ice_exchange, d.pratot, - d.prctot, &d.is_hydromet_present); + d.prctot, &d.is_hydromet_present); } if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { @@ -394,9 +395,9 @@ void run_bfb_p3_main() auto engine = Base::get_engine(); P3MainData isds_baseline[] = { - // its, ite, kts, kte, it, dt, do_predict_nc, do_prescribed_CCN - P3MainData(1, 10, 1, 72, 1, 1.800E+03, false, true), - P3MainData(1, 10, 1, 72, 1, 1.800E+03, true, false), + // its, ite, kts, kte, it, dt, do_predict_nc, do_prescribed_CCN, use_hetfrz_classnuc + P3MainData(1, 10, 1, 72, 1, 1.800E+03, false, true, true, 0), + P3MainData(1, 10, 1, 72, 1, 1.800E+03, true, false, false, 0), }; static constexpr Int num_runs = sizeof(isds_baseline) / sizeof(P3MainData); @@ -426,6 +427,9 @@ void run_bfb_p3_main() {d.qv_prev , {0 , 5.00000000E-02}}, {d.th_atm , {6.72653866E+02 , 1.07954335E+03}}, //PMC - this range seems insane {d.t_prev , {1.50000000E+02 , 3.50000000E+02}}, + {d.hetfrz_immersion_nucleation_tend , {1.50000000E-02 , 3.50000000E-02}}, + {d.hetfrz_contact_nucleation_tend , {1.50000000E-02 , 3.50000000E-02}}, + {d.hetfrz_deposition_nucleation_tend , {1.50000000E-02 , 3.50000000E-02}}, }); } @@ -449,9 +453,10 @@ void run_bfb_p3_main() d.qc, d.nc, d.qr, d.nr, d.th_atm, d.qv, d.dt, d.qi, d.qm, d.ni, d.bm, d.pres, d.dz, d.nc_nuceat_tend, d.nccn_prescribed, d.ni_activated, d.inv_qc_relvar, d.it, d.precip_liq_surf, d.precip_ice_surf, d.its, d.ite, d.kts, d.kte, d.diag_eff_radius_qc, d.diag_eff_radius_qi, d.diag_eff_radius_qr, - d.rho_qi, d.do_predict_nc, d.do_prescribed_CCN, d.dpres, d.inv_exner, d.qv2qi_depos_tend, + d.rho_qi, d.do_predict_nc, d.do_prescribed_CCN, d.use_hetfrz_classnuc, d.dpres, d.inv_exner, d.qv2qi_depos_tend, d.precip_liq_flux, d.precip_ice_flux, d.cld_frac_r, d.cld_frac_l, d.cld_frac_i, - d.liq_ice_exchange, d.vap_liq_exchange, d.vap_ice_exchange, d.qv_prev, d.t_prev); + d.liq_ice_exchange, d.vap_liq_exchange, d.vap_ice_exchange, d.qv_prev, d.t_prev, + d.hetfrz_immersion_nucleation_tend, d.hetfrz_contact_nucleation_tend, d.hetfrz_deposition_nucleation_tend); } if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { diff --git a/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp index 175247bb501d..77429b86ac75 100644 --- a/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp @@ -47,7 +47,9 @@ struct UnitWrap::UnitTest::TestNcConservation : public UnitWrap::UnitTest: const Int offset = i * Spack::n; // Init pack inputs - Spack nc, nc2ni_immers_freeze_tend, nc2nr_autoconv_tend, nc_accret_tend, nc_collect_tend, nc_selfcollect_tend; + Spack nc, nc2ni_immers_freeze_tend, nc2nr_autoconv_tend, nc_accret_tend, nc_collect_tend, nc_selfcollect_tend, + ncheti_cnt, nicnt; + Smask context; for (Int s = 0, vs = offset; s < Spack::n; ++s, ++vs) { nc[s] = cxx_device(vs).nc; nc2ni_immers_freeze_tend[s] = cxx_device(vs).nc2ni_immers_freeze_tend; @@ -55,9 +57,13 @@ struct UnitWrap::UnitTest::TestNcConservation : public UnitWrap::UnitTest: nc_accret_tend[s] = cxx_device(vs).nc_accret_tend; nc_collect_tend[s] = cxx_device(vs).nc_collect_tend; nc_selfcollect_tend[s] = cxx_device(vs).nc_selfcollect_tend; + ncheti_cnt[s] = cxx_device(vs).ncheti_cnt; + nicnt[s] = cxx_device(vs).nicnt; + context.set(s, cxx_device(vs).context); } - - Functions::nc_conservation(nc, nc_selfcollect_tend, cxx_device(offset).dt, nc_collect_tend, nc2ni_immers_freeze_tend, nc_accret_tend, nc2nr_autoconv_tend); + const bool use_hetfrz_classnuc = cxx_device(offset).use_hetfrz_classnuc; + Functions::nc_conservation(nc, nc_selfcollect_tend, cxx_device(offset).dt, nc_collect_tend, nc2ni_immers_freeze_tend, nc_accret_tend, nc2nr_autoconv_tend, + ncheti_cnt, nicnt, use_hetfrz_classnuc, context); // Copy spacks back into cxx_device view for (Int s = 0, vs = offset; s < Spack::n; ++s, ++vs) { diff --git a/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp index b8cfdf4333a1..dd2ca05eb481 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp @@ -47,18 +47,25 @@ struct UnitWrap::UnitTest::TestNiConservation : public UnitWrap::UnitTest: const Int offset = i * Spack::n; // Init pack inputs - Spack nc2ni_immers_freeze_tend, ni, ni2nr_melt_tend, ni_nucleat_tend, ni_selfcollect_tend, ni_sublim_tend, nr2ni_immers_freeze_tend; + Spack nc2ni_immers_freeze_tend, ni, ni2nr_melt_tend, ni_nucleat_tend, ni_selfcollect_tend, ni_sublim_tend, nr2ni_immers_freeze_tend, + ncheti_cnt, nicnt, ninuc_cnt; + Smask context; for (Int s = 0, vs = offset; s < Spack::n; ++s, ++vs) { nc2ni_immers_freeze_tend[s] = cxx_device(vs).nc2ni_immers_freeze_tend; - ni[s] = cxx_device(vs).ni; - ni2nr_melt_tend[s] = cxx_device(vs).ni2nr_melt_tend; - ni_nucleat_tend[s] = cxx_device(vs).ni_nucleat_tend; - ni_selfcollect_tend[s] = cxx_device(vs).ni_selfcollect_tend; - ni_sublim_tend[s] = cxx_device(vs).ni_sublim_tend; + ni[s] = cxx_device(vs).ni; + ni2nr_melt_tend[s] = cxx_device(vs).ni2nr_melt_tend; + ni_nucleat_tend[s] = cxx_device(vs).ni_nucleat_tend; + ni_selfcollect_tend[s] = cxx_device(vs).ni_selfcollect_tend; + ni_sublim_tend[s] = cxx_device(vs).ni_sublim_tend; nr2ni_immers_freeze_tend[s] = cxx_device(vs).nr2ni_immers_freeze_tend; + ncheti_cnt[s] = cxx_device(vs).ncheti_cnt; + nicnt[s] = cxx_device(vs).nicnt; + ninuc_cnt[s] = cxx_device(vs).ninuc_cnt; + context.set(s, cxx_device(vs).context); } - - Functions::ni_conservation(ni, ni_nucleat_tend, nr2ni_immers_freeze_tend, nc2ni_immers_freeze_tend, cxx_device(offset).dt, ni2nr_melt_tend, ni_sublim_tend, ni_selfcollect_tend); + const bool use_hetfrz_classnuc = cxx_device(offset).use_hetfrz_classnuc; + Functions::ni_conservation(ni, ni_nucleat_tend, nr2ni_immers_freeze_tend, nc2ni_immers_freeze_tend, ncheti_cnt, nicnt, ninuc_cnt, cxx_device(offset).dt, ni2nr_melt_tend, ni_sublim_tend, + ni_selfcollect_tend, use_hetfrz_classnuc, context); // Copy spacks back into cxx_device view for (Int s = 0, vs = offset; s < Spack::n; ++s, ++vs) { diff --git a/components/eamxx/src/physics/p3/tests/p3_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_unit_tests.cpp index 91e3db2f2976..092d5839c96d 100644 --- a/components/eamxx/src/physics/p3/tests/p3_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_unit_tests.cpp @@ -28,7 +28,7 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: using KTH = KokkosTypes; - CloudWaterConservationData cwdc[1] = {{sp(1e-5), sp(1.1), sp(1e-4), 0.0, 0.0, 0.0, 0.0, 0.0, sp(1.0), sp(1.0)}}; + CloudWaterConservationData cwdc[1] = {{sp(1e-5), sp(1.1), sp(1e-4), 0.0, 0.0, 0.0, 0.0, 0.0, sp(1.0), sp(1.0), sp(1.0), sp(1.0), false, true}}; // Sync to device KTH::view_1d cwdc_host("cwdc_host", 1); @@ -49,8 +49,12 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: Spack qc2qi_berg_tend(cwdc_device(0).qc2qi_berg_tend); Spack qi2qv_sublim_tend(cwdc_device(0).qi2qv_sublim_tend); Spack qv2qi_vapdep_tend(cwdc_device(0).qv2qi_vapdep_tend); - - Functions::cloud_water_conservation(qc, cwdc_device(0).dt, qc2qr_autoconv_tend, qc2qr_accret_tend, qc2qi_collect_tend, qc2qi_hetero_freeze_tend, qc2qr_ice_shed_tend, qc2qi_berg_tend, qi2qv_sublim_tend, qv2qi_vapdep_tend); + Spack qcheti_cnt(cwdc_device(0).qcheti_cnt); + Spack qicnt(cwdc_device(0).qicnt); + const bool use_hetfrz_classnuc = cwdc_device(0).use_hetfrz_classnuc; + const Smask context(cwdc_device(0).context); + Functions::cloud_water_conservation(qc, cwdc_device(0).dt, qc2qr_autoconv_tend, qc2qr_accret_tend, qc2qi_collect_tend, qc2qi_hetero_freeze_tend, qc2qr_ice_shed_tend, qc2qi_berg_tend, qi2qv_sublim_tend, qv2qi_vapdep_tend, + qcheti_cnt, qicnt, use_hetfrz_classnuc, context); cwdc_device(0).qc = qc[0]; cwdc_device(0).qc2qr_autoconv_tend = qc2qr_autoconv_tend[0]; @@ -61,6 +65,8 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: cwdc_device(0).qc2qi_berg_tend = qc2qi_berg_tend[0]; cwdc_device(0).qi2qv_sublim_tend = qi2qv_sublim_tend[0]; cwdc_device(0).qv2qi_vapdep_tend = qv2qi_vapdep_tend[0]; + cwdc_device(0).qcheti_cnt = qcheti_cnt[0]; + cwdc_device(0).qicnt = qicnt[0]; }); // Sync back to host @@ -133,8 +139,7 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: void ice_water_conservation_tests_device() { using KTH = KokkosTypes; - - IceWaterConservationData iwdc[1] = {{sp(1e-5), 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, sp(1.1), sp(1e-4), 0.0}}; + IceWaterConservationData iwdc[1] = {{sp(1e-5), 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, sp(1.1), sp(1e-4), 0.0, 0.0, false, true}}; // Sync to device KTH::view_1d iwdc_host("iwdc_host", 1); @@ -156,8 +161,14 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: Spack qc2qi_berg_tend(iwdc_device(0).qc2qi_berg_tend); Spack qi2qv_sublim_tend(iwdc_device(0).qi2qv_sublim_tend); Spack qi2qr_melt_tend(iwdc_device(0).qi2qr_melt_tend); + Spack qinuc_cnt(iwdc_device(0).qinuc_cnt); + Spack qcheti_cnt(iwdc_device(0).qcheti_cnt); + Spack qicnt(iwdc_device(0).qicnt); + const bool use_hetfrz_classnuc = iwdc_device(0).use_hetfrz_classnuc; + const Smask context(iwdc_device(0).context); - Functions::ice_water_conservation(qi, qv2qi_vapdep_tend, qv2qi_nucleat_tend, qr2qi_collect_tend, qc2qi_collect_tend, qr2qi_immers_freeze_tend, qc2qi_hetero_freeze_tend, qc2qi_berg_tend, iwdc_device(0).dt, qi2qv_sublim_tend, qi2qr_melt_tend); + Functions::ice_water_conservation(qi, qv2qi_vapdep_tend, qv2qi_nucleat_tend, qc2qi_berg_tend, qr2qi_collect_tend, qc2qi_collect_tend, qr2qi_immers_freeze_tend, qc2qi_hetero_freeze_tend, iwdc_device(0).dt, qinuc_cnt, qcheti_cnt, qicnt, qi2qv_sublim_tend, qi2qr_melt_tend, + use_hetfrz_classnuc, context); iwdc_device(0).qi = qi[0]; iwdc_device(0).qv2qi_vapdep_tend = qv2qi_vapdep_tend[0]; @@ -169,6 +180,9 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: iwdc_device(0).qc2qi_berg_tend = qc2qi_berg_tend[0]; iwdc_device(0).qi2qv_sublim_tend = qi2qv_sublim_tend[0]; iwdc_device(0).qi2qr_melt_tend = qi2qr_melt_tend[0]; + iwdc_device(0).qinuc_cnt = qinuc_cnt[0]; + iwdc_device(0).qcheti_cnt = qcheti_cnt[0]; + iwdc_device(0).qicnt = qicnt[0]; }); } @@ -192,26 +206,26 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: static_assert(max_pack_size % Spack::n == 0, "Unit testing infrastructure does not support this pack size (does not evenly divide 16)"); CloudWaterConservationData cwdc[max_pack_size] = { - //qc, cwdc_device(0).dt, qc2qr_autoconv_tend, qc2qr_accret_tend, qc2qi_collect_tend, qc2qi_hetero_freeze_tend, qc2qr_ice_shed_tend, qc2qi_berg_tend, qi2qv_sublim_tend, qv2qi_vapdep_tend - {9.9999999999999995e-7, 1800.0, 1.5832574016248739e-12, 1.0630996907148179e-12, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {6.4285714285714288e-5, 1800.0, 5.0577951315583066e-7, 7.7585489624948031e-4, 1.5683327213659326E-4, 1.2893174331809564e-14, 0.0, 5.0463073442953805e-6, 0.0, 5.1387602886199180e-7}, - {0.0, 1800.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {7.1428571428571434e-5, 1800.0, 5.1480988828550771e-7, 7.7585489624948031e-4, 1.5597668529004373e-4, 4.9926620576534573e-14, 0.0, 6.7718890050008472e-6, 0.0, 7.1052455549903861e-7}, - - {9.9999999999999995e-7, 1800.0, 1.5832574016248739e-12, 1.0630996907148179e-12, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {6.4285714285714288e-5, 1800.0, 5.0577951315583066e-7, 7.7585489624948031e-4, 1.5683327213659326E-4, 1.2893174331809564e-14, 0.0, 5.0463073442953805e-6, 0.0, 5.1387602886199180e-7}, - {0.0, 1800.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {7.1428571428571434e-5, 1800.0, 5.1480988828550771e-7, 7.7585489624948031e-4, 1.5597668529004373e-4, 4.9926620576534573e-14, 0.0, 6.7718890050008472e-6, 0.0, 7.1052455549903861e-7}, - - {9.9999999999999995e-7, 1800.0, 1.5832574016248739e-12, 1.0630996907148179e-12, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {6.4285714285714288e-5, 1800.0, 5.0577951315583066e-7, 7.7585489624948031e-4, 1.5683327213659326E-4, 1.2893174331809564e-14, 0.0, 5.0463073442953805e-6, 0.0, 5.1387602886199180e-7}, - {0.0, 1800.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {7.1428571428571434e-5, 1800.0, 5.1480988828550771e-7, 7.7585489624948031e-4, 1.5597668529004373e-4, 4.9926620576534573e-14, 0.0, 6.7718890050008472e-6, 0.0, 7.1052455549903861e-7}, - - {9.9999999999999995e-7, 1800.0, 1.5832574016248739e-12, 1.0630996907148179e-12, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {6.4285714285714288e-5, 1800.0, 5.0577951315583066e-7, 7.7585489624948031e-4, 1.5683327213659326E-4, 1.2893174331809564e-14, 0.0, 5.0463073442953805e-6, 0.0, 5.1387602886199180e-7}, - {0.0, 1800.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {7.1428571428571434e-5, 1800.0, 5.1480988828550771e-7, 7.7585489624948031e-4, 1.5597668529004373e-4, 4.9926620576534573e-14, 0.0, 6.7718890050008472e-6, 0.0, 7.1052455549903861e-7} + //qc, cwdc_device(0).dt, qc2qr_autoconv_tend, qc2qr_accret_tend, qc2qi_collect_tend, qc2qi_hetero_freeze_tend, qc2qr_ice_shed_tend, qc2qi_berg_tend, qi2qv_sublim_tend, qv2qi_vapdep_tend, qcheti_cnt, qicnt, use_hetfrz_classnuc, context + {9.9999999999999995e-7, 1800.0, 1.5832574016248739e-12, 1.0630996907148179e-12, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, true, true}, + {6.4285714285714288e-5, 1800.0, 5.0577951315583066e-7, 7.7585489624948031e-4, 1.5683327213659326e-4, 1.2893174331809564e-14, 0.0, 5.0463073442953805e-6, 0.0, 5.1387602886199180e-7, 5.0463073442953805e-6, 0.0, true, true}, + {0.0, 1800.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false, false}, + {7.1428571428571434e-5, 1800.0, 5.1480988828550771e-7, 7.7585489624948031e-4, 1.5597668529004373e-4, 4.9926620576534573e-14, 0.0, 6.7718890050008472e-6, 0.0, 7.1052455549903861e-7, 0.0, 5.0463073442953805e-6, true, true}, + + {9.9999999999999995e-7, 1800.0, 1.5832574016248739e-12, 1.0630996907148179e-12, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, true, true}, + {6.4285714285714288e-5, 1800.0, 5.0577951315583066e-7, 7.7585489624948031e-4, 1.5683327213659326e-4, 1.2893174331809564e-14, 0.0, 5.0463073442953805e-6, 0.0, 5.1387602886199180e-7, 5.0463073442953805e-6, 0.0, true, false}, + {0.0, 1800.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, true, true}, + {7.1428571428571434e-5, 1800.0, 5.1480988828550771e-7, 7.7585489624948031e-4, 1.5597668529004373e-4, 4.9926620576534573e-14, 0.0, 6.7718890050008472e-6, 0.0, 7.1052455549903861e-7, 0.0, 5.0463073442953805e-6, false, true}, + + {9.9999999999999995e-7, 1800.0, 1.5832574016248739e-12, 1.0630996907148179e-12, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, true, true}, + {6.4285714285714288e-5, 1800.0, 5.0577951315583066e-7, 7.7585489624948031e-4, 1.5683327213659326e-4, 1.2893174331809564e-14, 0.0, 5.0463073442953805e-6, 0.0, 5.1387602886199180e-7, 5.0463073442953805e-6, 0.0, true, false}, + {0.0, 1800.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, true, true}, + {7.1428571428571434e-5, 1800.0, 5.1480988828550771e-7, 7.7585489624948031e-4, 1.5597668529004373e-4, 4.9926620576534573e-14, 0.0, 6.7718890050008472e-6, 0.0, 7.1052455549903861e-7, 0.0, 5.0463073442953805e-6, false, true}, + + {9.9999999999999995e-7, 1800.0, 1.5832574016248739e-12, 1.0630996907148179e-12, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, true, true}, + {6.4285714285714288e-5, 1800.0, 5.0577951315583066e-7, 7.7585489624948031e-4, 1.5683327213659326e-4, 1.2893174331809564e-14, 0.0, 5.0463073442953805e-6, 0.0, 5.1387602886199180e-7, 5.0463073442953805e-6, 7.1052455549903861e-7, true, true}, + {0.0, 1800.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, true, true}, + {7.1428571428571434e-5, 1800.0, 5.1480988828550771e-7, 7.7585489624948031e-4, 1.5597668529004373e-4, 4.9926620576534573e-14, 0.0, 6.7718890050008472e-6, 0.0, 7.1052455549903861e-7, 5.0463073442953805e-6, 7.1052455549903861e-7, true, true} }; // Sync to device @@ -234,7 +248,8 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: const Int offset = i * Spack::n; // Init pack inputs - Spack qc, qc2qr_autoconv_tend, qc2qr_accret_tend, qc2qi_collect_tend, qc2qi_hetero_freeze_tend, qc2qr_ice_shed_tend, qc2qi_berg_tend, qi2qv_sublim_tend, qv2qi_vapdep_tend; + Spack qc, qc2qr_autoconv_tend, qc2qr_accret_tend, qc2qi_collect_tend, qc2qi_hetero_freeze_tend, qc2qr_ice_shed_tend, qc2qi_berg_tend, qi2qv_sublim_tend, qv2qi_vapdep_tend, qcheti_cnt, qicnt; + Smask context; for (Int s = 0, vs = offset; s < Spack::n; ++s, ++vs) { qc[s] = cwdc_device(vs).qc; qc2qr_autoconv_tend[s] = cwdc_device(vs).qc2qr_autoconv_tend; @@ -245,9 +260,14 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: qc2qi_berg_tend[s] = cwdc_device(vs).qc2qi_berg_tend; qi2qv_sublim_tend[s] = cwdc_device(vs).qi2qv_sublim_tend; qv2qi_vapdep_tend[s] = cwdc_device(vs).qv2qi_vapdep_tend; + qcheti_cnt[s] = cwdc_device(vs).qcheti_cnt; + qicnt[s] = cwdc_device(vs).qicnt; + context.set(s, cwdc_device(vs).context); } + const bool use_hetfrz_classnuc = cwdc_device(offset).use_hetfrz_classnuc; - Functions::cloud_water_conservation(qc, cwdc_device(0).dt, qc2qr_autoconv_tend, qc2qr_accret_tend, qc2qi_collect_tend, qc2qi_hetero_freeze_tend, qc2qr_ice_shed_tend, qc2qi_berg_tend, qi2qv_sublim_tend, qv2qi_vapdep_tend); + Functions::cloud_water_conservation(qc, cwdc_device(0).dt, qc2qr_autoconv_tend, qc2qr_accret_tend, qc2qi_collect_tend, qc2qi_hetero_freeze_tend, qc2qr_ice_shed_tend, qc2qi_berg_tend, qi2qv_sublim_tend, qv2qi_vapdep_tend, + qcheti_cnt, qicnt, use_hetfrz_classnuc, context); // Copy results back into views for (Int s = 0, vs = offset; s < Spack::n; ++s, ++vs) { cwdc_device(vs).qc = qc[s]; @@ -258,6 +278,8 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: cwdc_device(vs).qc2qi_berg_tend = qc2qi_berg_tend[s]; cwdc_device(vs).qi2qv_sublim_tend = qi2qv_sublim_tend[s]; cwdc_device(vs).qv2qi_vapdep_tend = qv2qi_vapdep_tend[s]; + cwdc_device(vs).qcheti_cnt = qcheti_cnt[0]; + cwdc_device(vs).qicnt = qicnt[0]; } }); @@ -275,6 +297,8 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: REQUIRE(cwdc[s].qc2qi_berg_tend == cwdc_host(s).qc2qi_berg_tend); REQUIRE(cwdc[s].qi2qv_sublim_tend == cwdc_host(s).qi2qv_sublim_tend); REQUIRE(cwdc[s].qv2qi_vapdep_tend == cwdc_host(s).qv2qi_vapdep_tend); + REQUIRE(cwdc[s].qcheti_cnt == cwdc_host(s).qcheti_cnt); + REQUIRE(cwdc[s].qicnt == cwdc_host(s).qicnt); } } else if (this->m_baseline_action == GENERATE) { @@ -289,26 +313,26 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: using KTH = KokkosTypes; IceWaterConservationData iwdc[max_pack_size] = { - // qi, qv2qi_vapdep_tend, qv2qi_nucleat_tend, qc2qi_berg_tend, qr2qi_collect_tend, qc2qi_collect_tend, qr2qi_immers_freeze_tend, qc2qi_hetero_freeze_tend, iwdc_device(0).dt, qi2qv_sublim_tend, qi2qr_melt_tend - {1.0e-4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 0.0, 1.9205467584100191e-4}, - {5.0e-8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 1.8234653652173277e-7, 0.0}, - {1.0e-4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 0.0, 2.3237448636383435e-3}, - {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 0.0, 0.0}, - - {1.0e-4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 0.0, 1.9205467584100191e-4}, - {5.0e-8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 1.8234653652173277e-7, 0.0}, - {1.0e-4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 0.0, 2.3237448636383435e-3}, - {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 0.0, 0.0}, - - {1.0e-4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 0.0, 1.9205467584100191e-4}, - {5.0e-8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 1.8234653652173277e-7, 0.0}, - {1.0e-4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 0.0, 2.3237448636383435e-3}, - {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 0.0, 0.0}, - - {1.0e-4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 0.0, 1.9205467584100191e-4}, - {5.0e-8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 1.8234653652173277e-7, 0.0}, - {1.0e-4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 0.0, 2.3237448636383435e-3}, - {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 0.0, 0.0} + //qi, qv2qi_vapdep_tend, qv2qi_nucleat_tend, qc2qi_berg_tend, qr2qi_collect_tend, qc2qi_collect_tend, qr2qi_immers_freeze_tend, qc2qi_hetero_freeze_tend, dt, qinuc_cnt, qcheti_cnt, qicnt, use_hetfrz_classnuc, context + {1.0e-4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 0.0, 1.9205467584100191e-4, 0.0, true, true}, + {5.0e-8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 1.8234653652173277e-7, 0.0, 0.0, true, true}, + {1.0e-4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 0.0, 2.3237448636383435e-3, 0.0, true, true}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 0.0, 0.0, 0.0, true, true}, + + {1.0e-4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 0.0, 1.9205467584100191e-4, 0.0, true, true}, + {5.0e-8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 1.8234653652173277e-7, 0.0, 0.0, true, true}, + {1.0e-4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 0.0, 2.3237448636383435e-3, 0.0, true, true}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 0.0, 0.0, 0.0, true, true}, + + {1.0e-4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 0.0, 1.9205467584100191e-4, 0.0, true, true}, + {5.0e-8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 1.8234653652173277e-7, 0.0, 0.0, true, true}, + {1.0e-4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 0.0, 2.3237448636383435e-3, 0.0, true, true}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 0.0, 0.0, 0.0, true, true}, + + {1.0e-4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 0.0, 1.9205467584100191e-4, 0.0, true, true}, + {5.0e-8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 1.8234653652173277e-7, 0.0, 0.0, true, true}, + {1.0e-4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 0.0, 2.3237448636383435e-3, 0.0, true, true}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1800.0, 0.0, 0.0, 0.0, true, true} }; // Sync to device @@ -331,7 +355,8 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: const Int offset = i * Spack::n; // Init pack inputs - Spack qi,qv2qi_vapdep_tend,qv2qi_nucleat_tend,qc2qi_berg_tend,qr2qi_collect_tend,qc2qi_collect_tend,qr2qi_immers_freeze_tend,qc2qi_hetero_freeze_tend,qi2qv_sublim_tend,qi2qr_melt_tend; + Spack qi,qv2qi_vapdep_tend,qv2qi_nucleat_tend,qc2qi_berg_tend,qr2qi_collect_tend,qc2qi_collect_tend,qr2qi_immers_freeze_tend,qc2qi_hetero_freeze_tend,qi2qv_sublim_tend,qi2qr_melt_tend,qinuc_cnt,qcheti_cnt,qicnt; + Smask context; for (Int s = 0, vs = offset; s < Spack::n; ++s, ++vs) { qi[s] = iwdc_device(vs).qi; qv2qi_vapdep_tend[s] = iwdc_device(vs).qv2qi_vapdep_tend; @@ -343,9 +368,14 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: qc2qi_hetero_freeze_tend[s] = iwdc_device(vs).qc2qi_hetero_freeze_tend; qi2qv_sublim_tend[s] = iwdc_device(vs).qi2qv_sublim_tend; qi2qr_melt_tend[s] = iwdc_device(vs).qi2qr_melt_tend; + qinuc_cnt[s] = iwdc_device(vs).qinuc_cnt; + qcheti_cnt[s] = iwdc_device(vs).qcheti_cnt; + qicnt[s] = iwdc_device(vs).qicnt; + context.set(s, iwdc_device(vs).context); } - - Functions::ice_water_conservation(qi, qv2qi_vapdep_tend, qv2qi_nucleat_tend, qc2qi_berg_tend, qr2qi_collect_tend, qc2qi_collect_tend, qr2qi_immers_freeze_tend, qc2qi_hetero_freeze_tend, iwdc_device(0).dt, qi2qv_sublim_tend, qi2qr_melt_tend); + const bool use_hetfrz_classnuc = iwdc_device(offset).use_hetfrz_classnuc; + Functions::ice_water_conservation(qi, qv2qi_vapdep_tend, qv2qi_nucleat_tend, qc2qi_berg_tend, qr2qi_collect_tend, qc2qi_collect_tend, qr2qi_immers_freeze_tend, qc2qi_hetero_freeze_tend, iwdc_device(0).dt, qinuc_cnt, qcheti_cnt, qicnt, qi2qv_sublim_tend, qi2qr_melt_tend, + use_hetfrz_classnuc, context); // Copy results back into views for (Int s = 0, vs = offset; s < Spack::n; ++s, ++vs) { iwdc_device(vs).qi = qi[s]; @@ -510,98 +540,98 @@ struct UnitWrap::UnitTest::TestP3UpdatePrognosticIce : public UnitWrap::UnitT {4.9078E-19, 1.5312E-09, 4.4387E-09, 3.7961E+06, 1.7737E-04, 0.0000E+00, 3.8085E-08, 5.1281E+04, 1.9251E-15, 3.4778E-04, 3.5801E+03, 0.0000E+00, 0.0000E+00, 0.0000E+00, 5.1386E-07, 0.0000E+00, 0.0000E+00, 2.7053E-02, 0.0000E+00, 1.9209E-10, 1.0686E+00, latvap+latice, latice, do_predict_nc, true, dt, nmltratio, - 4.5312E+02, 2.8720E+02, 5.0000E-03, 6.4286E-05, 1.2344E+08, 7.3684E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, - 6.4286E-05, 1.0000E-02}, + 4.5312E+02, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.8720E+02, 5.0000E-03, 6.4286E-05, 1.2344E+08, 7.3684E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, + 6.4286E-05, 1.0000E-02, true, true}, {2.1097E-18, 2.7648E-09, 3.8261E-09, 3.7754E+06, 6.8685E-04, 0.0000E+00, 4.1018E-08, 5.1227E+04, 4.8876E-15, 1.3468E-03, 2.8059E+03, 0.0000E+00, 0.0000E+00, 0.0000E+00, 7.1049E-07, 0.0000E+00, 0.0000E+00, 2.4547E-02, 0.0000E+00, 2.8615E-10, 1.0741E+00, latvap+latice, latice, do_predict_nc, true, dt, nmltratio, - 3.4890E+02, 2.8642E+02, 5.0000E-03, 7.1429E-05, 1.2345E+08, 7.8947E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, - 7.1429E-05, 1.0000E-02}, + 3.4890E+02, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.8642E+02, 5.0000E-03, 7.1429E-05, 1.2345E+08, 7.8947E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, + 7.1429E-05, 1.0000E-02, true, true}, {8.9820E-18, 4.2529E-09, 2.9520E-09, 3.7537E+06, 2.6598E-03, 0.0000E+00, 4.3700E-08, 5.1171E+04, 1.4266E-14, 5.2153E-03, 1.9880E+03, 0.0000E+00, 0.0000E+00, 0.0000E+00, 9.0244E-07, 0.0000E+00, 0.0000E+00, 2.1083E-02, 0.0000E+00, 3.7631E-10, 1.0796E+00, latvap+latice, latice, do_predict_nc, true, dt, nmltratio, - 2.8656E+02, 2.8565E+02, 5.0000E-03, 7.8571E-05, 1.2345E+08, 8.4211E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, - 7.8571E-05, 1.0000E-02}, + 2.8656E+02, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.8565E+02, 5.0000E-03, 7.8571E-05, 1.2345E+08, 8.4211E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, + 7.8571E-05, 1.0000E-02, true, false}, {3.7942E-17, 6.0115E-09, 1.8004E-09, 3.7310E+06, 1.0300E-02, 0.0000E+00, 4.6119E-08, 5.1112E+04, 4.4518E-14, 2.0196E-02, 1.1226E+03, 0.0000E+00, 0.0000E+00, 0.0000E+00, 1.0879E-06, 0.0000E+00, 0.0000E+00, 1.7646E-02, 0.0000E+00, 4.5891E-10, 1.0853E+00, latvap+latice, latice, do_predict_nc, true, dt, nmltratio, - 2.4570E+02, 2.8489E+02, 5.0000E-03, 8.5714E-05, 1.2345E+08, 8.9474E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, - 8.5714E-05, 1.0000E-02}, + 2.4570E+02, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.8489E+02, 5.0000E-03, 8.5714E-05, 1.2345E+08, 8.9474E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, + 8.5714E-05, 1.0000E-02, false, true}, {4.9078E-19, 1.5312E-09, 4.4387E-09, 3.7961E+06, 1.7737E-04, 0.0000E+00, 3.8085E-08, 5.1281E+04, 1.9251E-15, 3.4778E-04, 3.5801E+03, 0.0000E+00, 0.0000E+00, 0.0000E+00, 5.1386E-07, 0.0000E+00, 0.0000E+00, 2.7053E-02, 0.0000E+00, 1.9209E-10, 1.0686E+00, latvap+latice, latice, do_predict_nc, true, dt, nmltratio, - 4.5312E+02, 2.8720E+02, 5.0000E-03, 6.4286E-05, 1.2344E+08, 7.3684E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, - 6.4286E-05, 1.0000E-02}, + 4.5312E+02, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.8720E+02, 5.0000E-03, 6.4286E-05, 1.2344E+08, 7.3684E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, + 6.4286E-05, 1.0000E-02, false, true}, {2.1097E-18, 2.7648E-09, 3.8261E-09, 3.7754E+06, 6.8685E-04, 0.0000E+00, 4.1018E-08, 5.1227E+04, 4.8876E-15, 1.3468E-03, 2.8059E+03, 0.0000E+00, 0.0000E+00, 0.0000E+00, 7.1049E-07, 0.0000E+00, 0.0000E+00, 2.4547E-02, 0.0000E+00, 2.8615E-10, 1.0741E+00, latvap+latice, latice, do_predict_nc, true, dt, nmltratio, - 3.4890E+02, 2.8642E+02, 5.0000E-03, 7.1429E-05, 1.2345E+08, 7.8947E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, - 7.1429E-05, 1.0000E-02}, + 3.4890E+02, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.8642E+02, 5.0000E-03, 7.1429E-05, 1.2345E+08, 7.8947E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, + 7.1429E-05, 1.0000E-02, true, true}, {8.9820E-18, 4.2529E-09, 2.9520E-09, 3.7537E+06, 2.6598E-03, 0.0000E+00, 4.3700E-08, 5.1171E+04, 1.4266E-14, 5.2153E-03, 1.9880E+03, 0.0000E+00, 0.0000E+00, 0.0000E+00, 9.0244E-07, 0.0000E+00, 0.0000E+00, 2.1083E-02, 0.0000E+00, 3.7631E-10, 1.0796E+00, latvap+latice, latice, do_predict_nc, true, dt, nmltratio, - 2.8656E+02, 2.8565E+02, 5.0000E-03, 7.8571E-05, 1.2345E+08, 8.4211E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, - 7.8571E-05, 1.0000E-02}, + 2.8656E+02, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.8565E+02, 5.0000E-03, 7.8571E-05, 1.2345E+08, 8.4211E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, + 7.8571E-05, 1.0000E-02, true, true}, {3.7942E-17, 6.0115E-09, 1.8004E-09, 3.7310E+06, 1.0300E-02, 0.0000E+00, 4.6119E-08, 5.1112E+04, 4.4518E-14, 2.0196E-02, 1.1226E+03, 0.0000E+00, 0.0000E+00, 0.0000E+00, 1.0879E-06, 0.0000E+00, 0.0000E+00, 1.7646E-02, 0.0000E+00, 4.5891E-10, 1.0853E+00, latvap+latice, latice, do_predict_nc, true, dt, nmltratio, - 2.4570E+02, 2.8489E+02, 5.0000E-03, 8.5714E-05, 1.2345E+08, 8.9474E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, - 8.5714E-05, 1.0000E-02}, + 2.4570E+02, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.8489E+02, 5.0000E-03, 8.5714E-05, 1.2345E+08, 8.9474E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, + 8.5714E-05, 1.0000E-02, true, true}, {4.9078E-19, 1.5312E-09, 4.4387E-09, 3.7961E+06, 1.7737E-04, 0.0000E+00, 3.8085E-08, 5.1281E+04, 1.9251E-15, 3.4778E-04, 3.5801E+03, 0.0000E+00, 0.0000E+00, 0.0000E+00, 5.1386E-07, 0.0000E+00, 0.0000E+00, 2.7053E-02, 0.0000E+00, 1.9209E-10, 1.0686E+00, latvap+latice, latice, do_predict_nc, true, dt, nmltratio, - 4.5312E+02, 2.8720E+02, 5.0000E-03, 6.4286E-05, 1.2344E+08, 7.3684E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, - 6.4286E-05, 1.0000E-02}, + 4.5312E+02, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.8720E+02, 5.0000E-03, 6.4286E-05, 1.2344E+08, 7.3684E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, + 6.4286E-05, 1.0000E-02, false, true}, {2.1097E-18, 2.7648E-09, 3.8261E-09, 3.7754E+06, 6.8685E-04, 0.0000E+00, 4.1018E-08, 5.1227E+04, 4.8876E-15, 1.3468E-03, 2.8059E+03, 0.0000E+00, 0.0000E+00, 0.0000E+00, 7.1049E-07, 0.0000E+00, 0.0000E+00, 2.4547E-02, 0.0000E+00, 2.8615E-10, 1.0741E+00, latvap+latice, latice, do_predict_nc, true, dt, nmltratio, - 3.4890E+02, 2.8642E+02, 5.0000E-03, 7.1429E-05, 1.2345E+08, 7.8947E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, - 7.1429E-05, 1.0000E-02}, + 3.4890E+02, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.8642E+02, 5.0000E-03, 7.1429E-05, 1.2345E+08, 7.8947E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, + 7.1429E-05, 1.0000E-02, true, false}, {8.9820E-18, 4.2529E-09, 2.9520E-09, 3.7537E+06, 2.6598E-03, 0.0000E+00, 4.3700E-08, 5.1171E+04, 1.4266E-14, 5.2153E-03, 1.9880E+03, 0.0000E+00, 0.0000E+00, 0.0000E+00, 9.0244E-07, 0.0000E+00, 0.0000E+00, 2.1083E-02, 0.0000E+00, 3.7631E-10, 1.0796E+00, latvap+latice, latice, do_predict_nc, true, dt, nmltratio, - 2.8656E+02, 2.8565E+02, 5.0000E-03, 7.8571E-05, 1.2345E+08, 8.4211E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, - 7.8571E-05, 1.0000E-02}, + 2.8656E+02, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.8565E+02, 5.0000E-03, 7.8571E-05, 1.2345E+08, 8.4211E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, + 7.8571E-05, 1.0000E-02, true, true}, {3.7942E-17, 6.0115E-09, 1.8004E-09, 3.7310E+06, 1.0300E-02, 0.0000E+00, 4.6119E-08, 5.1112E+04, 4.4518E-14, 2.0196E-02, 1.1226E+03, 0.0000E+00, 0.0000E+00, 0.0000E+00, 1.0879E-06, 0.0000E+00, 0.0000E+00, 1.7646E-02, 0.0000E+00, 4.5891E-10, 1.0853E+00, latvap+latice, latice, do_predict_nc, true, dt, nmltratio, - 2.4570E+02, 2.8489E+02, 5.0000E-03, 8.5714E-05, 1.2345E+08, 8.9474E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, - 8.5714E-05, 1.0000E-02}, + 2.4570E+02, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.8489E+02, 5.0000E-03, 8.5714E-05, 1.2345E+08, 8.9474E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, + 8.5714E-05, 1.0000E-02, true, true}, {4.9078E-19, 1.5312E-09, 4.4387E-09, 3.7961E+06, 1.7737E-04, 0.0000E+00, 3.8085E-08, 5.1281E+04, 1.9251E-15, 3.4778E-04, 3.5801E+03, 0.0000E+00, 0.0000E+00, 0.0000E+00, 5.1386E-07, 0.0000E+00, 0.0000E+00, 2.7053E-02, 0.0000E+00, 1.9209E-10, 1.0686E+00, latvap+latice, latice, do_predict_nc, true, dt, nmltratio, - 4.5312E+02, 2.8720E+02, 5.0000E-03, 6.4286E-05, 1.2344E+08, 7.3684E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, - 6.4286E-05, 1.0000E-02}, + 4.5312E+02, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.8720E+02, 5.0000E-03, 6.4286E-05, 1.2344E+08, 7.3684E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, + 6.4286E-05, 1.0000E-02, true, true}, {2.1097E-18, 2.7648E-09, 3.8261E-09, 3.7754E+06, 6.8685E-04, 0.0000E+00, 4.1018E-08, 5.1227E+04, 4.8876E-15, 1.3468E-03, 2.8059E+03, 0.0000E+00, 0.0000E+00, 0.0000E+00, 7.1049E-07, 0.0000E+00, 0.0000E+00, 2.4547E-02, 0.0000E+00, 2.8615E-10, 1.0741E+00, latvap+latice, latice, do_predict_nc, true, dt, nmltratio, - 3.4890E+02, 2.8642E+02, 5.0000E-03, 7.1429E-05, 1.2345E+08, 7.8947E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, - 7.1429E-05, 1.0000E-02}, + 3.4890E+02, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.8642E+02, 5.0000E-03, 7.1429E-05, 1.2345E+08, 7.8947E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, + 7.1429E-05, 1.0000E-02, false, true}, {8.9820E-18, 4.2529E-09, 2.9520E-09, 3.7537E+06, 2.6598E-03, 0.0000E+00, 4.3700E-08, 5.1171E+04, 1.4266E-14, 5.2153E-03, 1.9880E+03, 0.0000E+00, 0.0000E+00, 0.0000E+00, 9.0244E-07, 0.0000E+00, 0.0000E+00, 2.1083E-02, 0.0000E+00, 3.7631E-10, 1.0796E+00, latvap+latice, latice, do_predict_nc, true, dt, nmltratio, - 2.8656E+02, 2.8565E+02, 5.0000E-03, 7.8571E-05, 1.2345E+08, 8.4211E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, - 7.8571E-05, 1.0000E-02}, + 2.8656E+02, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.8565E+02, 5.0000E-03, 7.8571E-05, 1.2345E+08, 8.4211E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, + 7.8571E-05, 1.0000E-02, false, true}, {3.7942E-17, 6.0115E-09, 1.8004E-09, 3.7310E+06, 1.0300E-02, 0.0000E+00, 4.6119E-08, 5.1112E+04, 4.4518E-14, 2.0196E-02, 1.1226E+03, 0.0000E+00, 0.0000E+00, 0.0000E+00, 1.0879E-06, 0.0000E+00, 0.0000E+00, 1.7646E-02, 0.0000E+00, 4.5891E-10, 1.0853E+00, latvap+latice, latice, do_predict_nc, true, dt, nmltratio, - 2.4570E+02, 2.8489E+02, 5.0000E-03, 8.5714E-05, 1.2345E+08, 8.9474E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, - 8.5714E-05, 1.0000E-02}, + 2.4570E+02, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.8489E+02, 5.0000E-03, 8.5714E-05, 1.2345E+08, 8.9474E-06, 1.0000E+06, 1.0000E-04, 1.0000E+06, + 8.5714E-05, 1.0000E-02, false, true}, }; // Sync to device @@ -627,14 +657,13 @@ struct UnitWrap::UnitTest::TestP3UpdatePrognosticIce : public UnitWrap::UnitT Spack qc2qi_hetero_freeze_tend, qc2qi_collect_tend, qc2qr_ice_shed_tend, nc_collect_tend, nc2ni_immers_freeze_tend, ncshdc, qr2qi_collect_tend, nr_collect_tend, qr2qi_immers_freeze_tend, nr2ni_immers_freeze_tend, nr_ice_shed_tend, qi2qr_melt_tend, ni2nr_melt_tend, qi2qv_sublim_tend, qv2qi_vapdep_tend, qv2qi_nucleat_tend, ni_nucleat_tend, ni_selfcollect_tend, ni_sublim_tend, qc2qi_berg_tend, inv_exner, - rho_qm_cloud, th_atm, qv, qc, nc, qr, nr, qi, ni, qm, bm; + rho_qm_cloud, ncheti_cnt, nicnt, ninuc_cnt, qcheti_cnt, qicnt, qinuc_cnt, th_atm, qv, qc, nc, qr, nr, qi, ni, qm, bm; Scalar dt; - bool do_predict_nc; - Smask log_wetgrowth; + Smask log_wetgrowth, context; // variables with single values assigned outside of the for loop dt = pupidc_device(0).dt; - do_predict_nc = pupidc_device(0).do_predict_nc; + const bool do_predict_nc = pupidc_device(0).do_predict_nc; for (Int s = 0, vs = offset; s < Spack::n; ++s, ++vs) { qc2qi_hetero_freeze_tend[s] = pupidc_device(vs).qc2qi_hetero_freeze_tend; @@ -660,6 +689,13 @@ struct UnitWrap::UnitTest::TestP3UpdatePrognosticIce : public UnitWrap::UnitT inv_exner[s] = pupidc_device(vs).inv_exner; rho_qm_cloud[s] = pupidc_device(vs).rho_qm_cloud; + ncheti_cnt[s] = pupidc_device(vs).ncheti_cnt; + nicnt[s] = pupidc_device(vs).nicnt; + ninuc_cnt[s] = pupidc_device(vs).ninuc_cnt; + qcheti_cnt[s] = pupidc_device(vs).qcheti_cnt; + qicnt[s] = pupidc_device(vs).qicnt; + qinuc_cnt[s] = pupidc_device(vs).qinuc_cnt; + context.set(s, pupidc_device(vs).context); th_atm[s] = pupidc_device(vs).th_atm; qv[s] = pupidc_device(vs).qv; qc[s] = pupidc_device(vs).qc; @@ -673,14 +709,14 @@ struct UnitWrap::UnitTest::TestP3UpdatePrognosticIce : public UnitWrap::UnitT log_wetgrowth.set(s, pupidc_device(vs).log_wetgrowth); } - + const bool use_hetfrz_classnuc = pupidc_device(offset).use_hetfrz_classnuc; Functions::update_prognostic_ice(qc2qi_hetero_freeze_tend, qc2qi_collect_tend, qc2qr_ice_shed_tend, nc_collect_tend, nc2ni_immers_freeze_tend,ncshdc, qr2qi_collect_tend, nr_collect_tend, qr2qi_immers_freeze_tend, nr2ni_immers_freeze_tend, nr_ice_shed_tend, qi2qr_melt_tend, ni2nr_melt_tend, qi2qv_sublim_tend, qv2qi_vapdep_tend, qv2qi_nucleat_tend, ni_nucleat_tend, ni_selfcollect_tend, ni_sublim_tend, qc2qi_berg_tend, inv_exner, do_predict_nc, log_wetgrowth, dt, pupidc_device(0).nmltratio, - rho_qm_cloud, th_atm, qv, qi, ni, qm, - bm, qc, nc, qr, nr); + rho_qm_cloud, ncheti_cnt, nicnt, ninuc_cnt, qcheti_cnt, qicnt, qinuc_cnt, th_atm, qv, qi, ni, qm, + bm, qc, nc, qr, nr, use_hetfrz_classnuc, context); // Copy results back into views for (Int s = 0, vs = offset; s < Spack::n; ++s, ++vs) { diff --git a/components/eamxx/tests/multi-process/dynamics_physics/homme_shoc_cld_p3_rrtmgp/input.yaml b/components/eamxx/tests/multi-process/dynamics_physics/homme_shoc_cld_p3_rrtmgp/input.yaml index 15b8f8572b82..565979abe64d 100644 --- a/components/eamxx/tests/multi-process/dynamics_physics/homme_shoc_cld_p3_rrtmgp/input.yaml +++ b/components/eamxx/tests/multi-process/dynamics_physics/homme_shoc_cld_p3_rrtmgp/input.yaml @@ -19,6 +19,9 @@ initial_conditions: surf_sens_flux: 0.0 precip_liq_surf_mass: 0.0 precip_ice_surf_mass: 0.0 + hetfrz_immersion_nucleation_tend: 0.1 + hetfrz_contact_nucleation_tend: 0.1 + hetfrz_deposition_nucleation_tend: 0.1 atmosphere_processes: atm_procs_list: [homme,physics] diff --git a/components/eamxx/tests/multi-process/dynamics_physics/homme_shoc_cld_p3_rrtmgp_pg2/input.yaml b/components/eamxx/tests/multi-process/dynamics_physics/homme_shoc_cld_p3_rrtmgp_pg2/input.yaml index c9f0bdaa8b85..c065dce655f5 100644 --- a/components/eamxx/tests/multi-process/dynamics_physics/homme_shoc_cld_p3_rrtmgp_pg2/input.yaml +++ b/components/eamxx/tests/multi-process/dynamics_physics/homme_shoc_cld_p3_rrtmgp_pg2/input.yaml @@ -15,6 +15,9 @@ initial_conditions: surf_sens_flux: 0.0 precip_liq_surf_mass: 0.0 precip_ice_surf_mass: 0.0 + hetfrz_immersion_nucleation_tend: 0.1 + hetfrz_contact_nucleation_tend: 0.1 + hetfrz_deposition_nucleation_tend: 0.1 surf_lw_flux_up: 400.0 eddy_diff_mom: 0.02 sgs_buoy_flux: -0.001 diff --git a/components/eamxx/tests/multi-process/dynamics_physics/homme_shoc_cld_spa_p3_rrtmgp/input.yaml b/components/eamxx/tests/multi-process/dynamics_physics/homme_shoc_cld_spa_p3_rrtmgp/input.yaml index d8dc6182ae4f..1892cea749ac 100644 --- a/components/eamxx/tests/multi-process/dynamics_physics/homme_shoc_cld_spa_p3_rrtmgp/input.yaml +++ b/components/eamxx/tests/multi-process/dynamics_physics/homme_shoc_cld_spa_p3_rrtmgp/input.yaml @@ -15,6 +15,9 @@ initial_conditions: surf_sens_flux: 0.0 precip_liq_surf_mass: 0.0 precip_ice_surf_mass: 0.0 + hetfrz_immersion_nucleation_tend: 0.1 + hetfrz_contact_nucleation_tend: 0.1 + hetfrz_deposition_nucleation_tend: 0.1 atmosphere_processes: atm_procs_list: [homme,physics] diff --git a/components/eamxx/tests/multi-process/dynamics_physics/homme_shoc_cld_spa_p3_rrtmgp_128levels/input.yaml b/components/eamxx/tests/multi-process/dynamics_physics/homme_shoc_cld_spa_p3_rrtmgp_128levels/input.yaml index 3fd2b41cd310..51e81e9637b6 100644 --- a/components/eamxx/tests/multi-process/dynamics_physics/homme_shoc_cld_spa_p3_rrtmgp_128levels/input.yaml +++ b/components/eamxx/tests/multi-process/dynamics_physics/homme_shoc_cld_spa_p3_rrtmgp_128levels/input.yaml @@ -15,6 +15,9 @@ initial_conditions: surf_sens_flux: 0.0 precip_ice_surf_mass: 0.0 precip_liq_surf_mass: 0.0 + hetfrz_immersion_nucleation_tend: 0.1 + hetfrz_contact_nucleation_tend: 0.1 + hetfrz_deposition_nucleation_tend: 0.1 atmosphere_processes: atm_procs_list: [homme,physics] diff --git a/components/eamxx/tests/multi-process/dynamics_physics/homme_shoc_cld_spa_p3_rrtmgp_pg2_dp/input.yaml b/components/eamxx/tests/multi-process/dynamics_physics/homme_shoc_cld_spa_p3_rrtmgp_pg2_dp/input.yaml index fdd46617bd59..874ee0be09ec 100644 --- a/components/eamxx/tests/multi-process/dynamics_physics/homme_shoc_cld_spa_p3_rrtmgp_pg2_dp/input.yaml +++ b/components/eamxx/tests/multi-process/dynamics_physics/homme_shoc_cld_spa_p3_rrtmgp_pg2_dp/input.yaml @@ -27,6 +27,9 @@ initial_conditions: surf_sens_flux: 0.0 precip_liq_surf_mass: 0.0 precip_ice_surf_mass: 0.0 + hetfrz_immersion_nucleation_tend: 0.1 + hetfrz_contact_nucleation_tend: 0.1 + hetfrz_deposition_nucleation_tend: 0.1 perturbed_fields: [T_mid] perturbation_limit: 0.001 perturbation_minimum_pressure: 900.0 # in millibar diff --git a/components/eamxx/tests/multi-process/dynamics_physics/mam/homme_shoc_cld_mam_aci_p3_mam_optics_rrtmgp_mam_drydep/input.yaml b/components/eamxx/tests/multi-process/dynamics_physics/mam/homme_shoc_cld_mam_aci_p3_mam_optics_rrtmgp_mam_drydep/input.yaml index ab0f1a3fe408..f8d0d9935b81 100644 --- a/components/eamxx/tests/multi-process/dynamics_physics/mam/homme_shoc_cld_mam_aci_p3_mam_optics_rrtmgp_mam_drydep/input.yaml +++ b/components/eamxx/tests/multi-process/dynamics_physics/mam/homme_shoc_cld_mam_aci_p3_mam_optics_rrtmgp_mam_drydep/input.yaml @@ -25,6 +25,9 @@ initial_conditions: #variables required for p3 precip_ice_surf_mass: 0.0 precip_liq_surf_mass: 0.0 + hetfrz_immersion_nucleation_tend: 0.1 + hetfrz_contact_nucleation_tend: 0.1 + hetfrz_deposition_nucleation_tend: 0.1 #variables required for mam4_aci dgnum: 1e-3 diff --git a/components/eamxx/tests/multi-process/dynamics_physics/mam/homme_shoc_cld_p3_mam_optics_rrtmgp/input.yaml b/components/eamxx/tests/multi-process/dynamics_physics/mam/homme_shoc_cld_p3_mam_optics_rrtmgp/input.yaml index 21791e3391e6..c8c7a91ca2df 100644 --- a/components/eamxx/tests/multi-process/dynamics_physics/mam/homme_shoc_cld_p3_mam_optics_rrtmgp/input.yaml +++ b/components/eamxx/tests/multi-process/dynamics_physics/mam/homme_shoc_cld_p3_mam_optics_rrtmgp/input.yaml @@ -19,6 +19,9 @@ initial_conditions: surf_sens_flux: 0.0 precip_liq_surf_mass: 0.0 precip_ice_surf_mass: 0.0 + hetfrz_immersion_nucleation_tend: 0.1 + hetfrz_contact_nucleation_tend: 0.1 + hetfrz_deposition_nucleation_tend: 0.1 pbl_height : 1.0 phis : 1.0 diff --git a/components/eamxx/tests/multi-process/dynamics_physics/mam/homme_shoc_cld_spa_p3_rrtmgp_mam4_wetscav/input.yaml b/components/eamxx/tests/multi-process/dynamics_physics/mam/homme_shoc_cld_spa_p3_rrtmgp_mam4_wetscav/input.yaml index a95d2677fe46..9d86f069a126 100644 --- a/components/eamxx/tests/multi-process/dynamics_physics/mam/homme_shoc_cld_spa_p3_rrtmgp_mam4_wetscav/input.yaml +++ b/components/eamxx/tests/multi-process/dynamics_physics/mam/homme_shoc_cld_spa_p3_rrtmgp_mam4_wetscav/input.yaml @@ -17,6 +17,10 @@ initial_conditions: surf_sens_flux: 0.0 precip_liq_surf_mass: 0.0 precip_ice_surf_mass: 0.0 + hetfrz_immersion_nucleation_tend: 0.1 + hetfrz_contact_nucleation_tend: 0.1 + hetfrz_deposition_nucleation_tend: 0.1 + #variables needed by mam4_wetscav #--surface fluxes wetdep_hydrophilic_bc: 1e-5 # wet deposition of hydrophilic black carbon [kg/m2/s] diff --git a/components/eamxx/tests/multi-process/dynamics_physics/model_restart/input_baseline.yaml b/components/eamxx/tests/multi-process/dynamics_physics/model_restart/input_baseline.yaml index b5d749bfeff4..ee80f9a98fe9 100644 --- a/components/eamxx/tests/multi-process/dynamics_physics/model_restart/input_baseline.yaml +++ b/components/eamxx/tests/multi-process/dynamics_physics/model_restart/input_baseline.yaml @@ -17,6 +17,9 @@ initial_conditions: surf_sens_flux: 0.0 precip_liq_surf_mass: 0.0 precip_ice_surf_mass: 0.0 + hetfrz_immersion_nucleation_tend: 0.1 + hetfrz_contact_nucleation_tend: 0.1 + hetfrz_deposition_nucleation_tend: 0.1 aero_g_sw: 0.0 aero_ssa_sw: 0.0 aero_tau_sw: 0.0 diff --git a/components/eamxx/tests/multi-process/dynamics_physics/model_restart/input_initial.yaml b/components/eamxx/tests/multi-process/dynamics_physics/model_restart/input_initial.yaml index 4ab3bdc369d8..ffaf3aff9f2f 100644 --- a/components/eamxx/tests/multi-process/dynamics_physics/model_restart/input_initial.yaml +++ b/components/eamxx/tests/multi-process/dynamics_physics/model_restart/input_initial.yaml @@ -17,6 +17,9 @@ initial_conditions: surf_sens_flux: 0.0 precip_liq_surf_mass: 0.0 precip_ice_surf_mass: 0.0 + hetfrz_immersion_nucleation_tend: 0.1 + hetfrz_contact_nucleation_tend: 0.1 + hetfrz_deposition_nucleation_tend: 0.1 aero_g_sw: 0.0 aero_ssa_sw: 0.0 aero_tau_sw: 0.0 diff --git a/components/eamxx/tests/multi-process/physics_only/atm_proc_subcycling/input.yaml b/components/eamxx/tests/multi-process/physics_only/atm_proc_subcycling/input.yaml index b23046cf2d15..3cee63f5138a 100644 --- a/components/eamxx/tests/multi-process/physics_only/atm_proc_subcycling/input.yaml +++ b/components/eamxx/tests/multi-process/physics_only/atm_proc_subcycling/input.yaml @@ -47,6 +47,9 @@ initial_conditions: surf_sens_flux: 0.0 precip_ice_surf_mass: 0.0 precip_liq_surf_mass: 0.0 + hetfrz_immersion_nucleation_tend: 0.1 + hetfrz_contact_nucleation_tend: 0.1 + hetfrz_deposition_nucleation_tend: 0.1 # The parameters for I/O control Scorpio: diff --git a/components/eamxx/tests/multi-process/physics_only/mam/p3_mam4_wetscav/input.yaml b/components/eamxx/tests/multi-process/physics_only/mam/p3_mam4_wetscav/input.yaml index f0d9b7c89a3b..98e19fa9662c 100644 --- a/components/eamxx/tests/multi-process/physics_only/mam/p3_mam4_wetscav/input.yaml +++ b/components/eamxx/tests/multi-process/physics_only/mam/p3_mam4_wetscav/input.yaml @@ -50,6 +50,9 @@ initial_conditions: #variable required for p3 precip_ice_surf_mass: 0.0 precip_liq_surf_mass: 0.0 + hetfrz_immersion_nucleation_tend: 0.1 + hetfrz_contact_nucleation_tend: 0.1 + hetfrz_deposition_nucleation_tend: 0.1 # The parameters for I/O control Scorpio: diff --git a/components/eamxx/tests/multi-process/physics_only/mam/shoc_cldfrac_mam4_aci_p3/input.yaml b/components/eamxx/tests/multi-process/physics_only/mam/shoc_cldfrac_mam4_aci_p3/input.yaml index e4379768814b..a4d99cd20141 100644 --- a/components/eamxx/tests/multi-process/physics_only/mam/shoc_cldfrac_mam4_aci_p3/input.yaml +++ b/components/eamxx/tests/multi-process/physics_only/mam/shoc_cldfrac_mam4_aci_p3/input.yaml @@ -51,7 +51,7 @@ initial_conditions: # The name of the file containing the initial conditions for this test. Filename: ${SCREAM_DATA_DIR}/init/${EAMxx_tests_IC_FILE_MAM4xx_72lev} topography_filename: ${TOPO_DATA_DIR}/${EAMxx_tests_TOPO_FILE} - + #variable required for shoc surf_sens_flux: 0.0 surf_evap: 0.0 @@ -59,6 +59,9 @@ initial_conditions: #variable required for p3 precip_ice_surf_mass: 0.0 precip_liq_surf_mass: 0.0 + hetfrz_immersion_nucleation_tend: 0.1 + hetfrz_contact_nucleation_tend: 0.1 + hetfrz_deposition_nucleation_tend: 0.1 #variables required for mam4_aci dgnum: 1e-3 diff --git a/components/eamxx/tests/multi-process/physics_only/mam/shoc_cldfrac_mam4_aci_p3_mam4_optics_rrtmgp/input.yaml b/components/eamxx/tests/multi-process/physics_only/mam/shoc_cldfrac_mam4_aci_p3_mam4_optics_rrtmgp/input.yaml index 8a5d2d1fb5b9..d55655245fa6 100644 --- a/components/eamxx/tests/multi-process/physics_only/mam/shoc_cldfrac_mam4_aci_p3_mam4_optics_rrtmgp/input.yaml +++ b/components/eamxx/tests/multi-process/physics_only/mam/shoc_cldfrac_mam4_aci_p3_mam4_optics_rrtmgp/input.yaml @@ -77,10 +77,13 @@ initial_conditions: #variables required for shoc surf_sens_flux: 0.0 surf_evap: 0.0 - + #variables required for p3 precip_ice_surf_mass: 0.0 precip_liq_surf_mass: 0.0 + hetfrz_immersion_nucleation_tend: 0.1 + hetfrz_contact_nucleation_tend: 0.1 + hetfrz_deposition_nucleation_tend: 0.1 #variables required for mam4_aci dgnum: 1e-3 diff --git a/components/eamxx/tests/multi-process/physics_only/mam/shoc_cldfrac_mam4_aci_p3_rrtmgp/input.yaml b/components/eamxx/tests/multi-process/physics_only/mam/shoc_cldfrac_mam4_aci_p3_rrtmgp/input.yaml index 71462d2ea290..3a742c8b68e7 100644 --- a/components/eamxx/tests/multi-process/physics_only/mam/shoc_cldfrac_mam4_aci_p3_rrtmgp/input.yaml +++ b/components/eamxx/tests/multi-process/physics_only/mam/shoc_cldfrac_mam4_aci_p3_rrtmgp/input.yaml @@ -68,7 +68,10 @@ initial_conditions: #variables required for p3 precip_ice_surf_mass: 0.0 precip_liq_surf_mass: 0.0 - + hetfrz_immersion_nucleation_tend: 0.1 + hetfrz_contact_nucleation_tend: 0.1 + hetfrz_deposition_nucleation_tend: 0.1 + #variables required for rrtmgp aero_g_sw: 0.0 aero_ssa_sw: 0.0 diff --git a/components/eamxx/tests/multi-process/physics_only/mam/shoc_cldfrac_p3_wetscav/input.yaml b/components/eamxx/tests/multi-process/physics_only/mam/shoc_cldfrac_p3_wetscav/input.yaml index d970765d2bd9..cee1f9308c69 100644 --- a/components/eamxx/tests/multi-process/physics_only/mam/shoc_cldfrac_p3_wetscav/input.yaml +++ b/components/eamxx/tests/multi-process/physics_only/mam/shoc_cldfrac_p3_wetscav/input.yaml @@ -58,7 +58,7 @@ initial_conditions: wetdep_dust_bin2: 1e-5 # wet deposition of dust (bin2) [kg/m2/s] wetdep_dust_bin3: 1e-5 # wet deposition of dust (bin3) [kg/m2/s] wetdep_dust_bin4: 1e-5 # wet deposition of dust (bin4) [kg/m2/s] - + #variable required for shoc surf_sens_flux: 0.0 surf_evap: 0.0 @@ -66,6 +66,9 @@ initial_conditions: #variable required for p3 precip_ice_surf_mass: 0.0 precip_liq_surf_mass: 0.0 + hetfrz_immersion_nucleation_tend: 0.1 + hetfrz_contact_nucleation_tend: 0.1 + hetfrz_deposition_nucleation_tend: 0.1 # The parameters for I/O control Scorpio: diff --git a/components/eamxx/tests/multi-process/physics_only/shoc_cld_p3_rrtmgp/input.yaml b/components/eamxx/tests/multi-process/physics_only/shoc_cld_p3_rrtmgp/input.yaml index 529a075b10dc..2670762be3dd 100644 --- a/components/eamxx/tests/multi-process/physics_only/shoc_cld_p3_rrtmgp/input.yaml +++ b/components/eamxx/tests/multi-process/physics_only/shoc_cld_p3_rrtmgp/input.yaml @@ -60,6 +60,9 @@ initial_conditions: surf_evap: 0.0 precip_ice_surf_mass: 0.0 precip_liq_surf_mass: 0.0 + hetfrz_immersion_nucleation_tend: 0.1 + hetfrz_contact_nucleation_tend: 0.1 + hetfrz_deposition_nucleation_tend: 0.1 aero_g_sw: 0.0 aero_ssa_sw: 0.0 aero_tau_sw: 0.0 diff --git a/components/eamxx/tests/multi-process/physics_only/shoc_cld_spa_p3_rrtmgp/input.yaml b/components/eamxx/tests/multi-process/physics_only/shoc_cld_spa_p3_rrtmgp/input.yaml index a98cbe30e85c..c343772eecee 100644 --- a/components/eamxx/tests/multi-process/physics_only/shoc_cld_spa_p3_rrtmgp/input.yaml +++ b/components/eamxx/tests/multi-process/physics_only/shoc_cld_spa_p3_rrtmgp/input.yaml @@ -60,6 +60,9 @@ initial_conditions: surf_sens_flux: 0.0 precip_liq_surf_mass: 0.0 precip_ice_surf_mass: 0.0 + hetfrz_immersion_nucleation_tend: 0.1 + hetfrz_contact_nucleation_tend: 0.1 + hetfrz_deposition_nucleation_tend: 0.1 # The parameters for I/O control Scorpio: diff --git a/components/eamxx/tests/multi-process/physics_only/shoc_p3_nudging/input_nudging.yaml b/components/eamxx/tests/multi-process/physics_only/shoc_p3_nudging/input_nudging.yaml index 12acd670ad91..51a3453c2741 100644 --- a/components/eamxx/tests/multi-process/physics_only/shoc_p3_nudging/input_nudging.yaml +++ b/components/eamxx/tests/multi-process/physics_only/shoc_p3_nudging/input_nudging.yaml @@ -53,6 +53,9 @@ initial_conditions: surf_sens_flux: 0.0 precip_ice_surf_mass: 0.0 precip_liq_surf_mass: 0.0 + hetfrz_immersion_nucleation_tend: 0.1 + hetfrz_contact_nucleation_tend: 0.1 + hetfrz_deposition_nucleation_tend: 0.1 # The parameters for I/O control Scorpio: diff --git a/components/eamxx/tests/multi-process/physics_only/shoc_p3_nudging/input_nudging_glob_novert.yaml b/components/eamxx/tests/multi-process/physics_only/shoc_p3_nudging/input_nudging_glob_novert.yaml index 68e8841586db..1c7ddecd8534 100644 --- a/components/eamxx/tests/multi-process/physics_only/shoc_p3_nudging/input_nudging_glob_novert.yaml +++ b/components/eamxx/tests/multi-process/physics_only/shoc_p3_nudging/input_nudging_glob_novert.yaml @@ -54,6 +54,9 @@ initial_conditions: surf_sens_flux: 0.0 precip_ice_surf_mass: 0.0 precip_liq_surf_mass: 0.0 + hetfrz_immersion_nucleation_tend: 0.1 + hetfrz_contact_nucleation_tend: 0.1 + hetfrz_deposition_nucleation_tend: 0.1 # The parameters for I/O control Scorpio: diff --git a/components/eamxx/tests/multi-process/physics_only/shoc_p3_nudging/input_source_data.yaml b/components/eamxx/tests/multi-process/physics_only/shoc_p3_nudging/input_source_data.yaml index c6ec0e361c65..7de196bf3b0e 100644 --- a/components/eamxx/tests/multi-process/physics_only/shoc_p3_nudging/input_source_data.yaml +++ b/components/eamxx/tests/multi-process/physics_only/shoc_p3_nudging/input_source_data.yaml @@ -45,6 +45,9 @@ initial_conditions: surf_sens_flux: 0.0 precip_ice_surf_mass: 0.0 precip_liq_surf_mass: 0.0 + hetfrz_immersion_nucleation_tend: 0.1 + hetfrz_contact_nucleation_tend: 0.1 + hetfrz_deposition_nucleation_tend: 0.1 # The parameters for I/O control Scorpio: diff --git a/components/eamxx/tests/single-process/p3/input.yaml b/components/eamxx/tests/single-process/p3/input.yaml index 1af25d382704..44b1be0e0a3c 100644 --- a/components/eamxx/tests/single-process/p3/input.yaml +++ b/components/eamxx/tests/single-process/p3/input.yaml @@ -14,6 +14,7 @@ atmosphere_processes: max_total_ni: 740.0e3 compute_tendencies: [T_mid,qc] do_prescribed_ccn: false + use_hetfrz_classnuc: false grids_manager: Type: Mesh Free @@ -28,6 +29,9 @@ initial_conditions: Filename: ${SCREAM_DATA_DIR}/init/${EAMxx_tests_IC_FILE_72lev} precip_liq_surf_mass: 0.0 precip_ice_surf_mass: 0.0 + hetfrz_immersion_nucleation_tend: 0.1 + hetfrz_contact_nucleation_tend: 0.1 + hetfrz_deposition_nucleation_tend: 0.1 # The parameters for I/O control Scorpio: