Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -202,22 +202,31 @@ void MAMMicrophysics::set_grids(
add_field<Computed>("dqdt_h2so4_uptake", vector2d_nmodes, kg/m2/s, grid_name);

// Diagnostic fields for aerosol microphysics

//Flag to indicate if we want to compute extra diagnostics
extra_mam4_aero_microphys_diags_ = m_params.get<bool>("extra_mam4_aero_microphys_diags", false);
if (extra_mam4_aero_microphys_diags_) {
const FieldLayout vector3d_num_gas_aerosol_constituents =
grid_->get_3d_vector_layout(true, mam_coupling::gas_pcnst(), "num_gas_aerosol_constituents");

// Diagnostics: tendencies due to gas phase chemistry [kg/kg/s]
add_field<Computed>("mam4_microphysics_tendency_gas_phase_chemistry", vector3d_num_gas_aerosol_constituents, kg / kg / s, grid_name);
// Diagnostics: tendencies due to gas phase chemistry [mixed units: kg/kg/s or #/kg/s]
add_field<Computed>("mam4_microphysics_tendency_gas_phase_chemistry", vector3d_num_gas_aerosol_constituents, nondim, grid_name);

// Diagnostics: tendencies due to aqueous chemistry [mixed units: kg/kg/s or #/kg/s]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is basically perfect for a long name (you just need to add "mam4 microphys" or something to the start and it will be 🍑

add_field<Computed>("mam4_microphysics_tendency_aqueous_chemistry", vector3d_num_gas_aerosol_constituents, nondim, grid_name);

// Diagnostics: tendencies due to aqueous chemistry [kg/kg/s]
add_field<Computed>("mam4_microphysics_tendency_aqueous_chemistry", vector3d_num_gas_aerosol_constituents, kg / kg / s, grid_name);
// Diagnostics: SO4 in-cloud tendencies [mixed units: kg/kg/s or #/kg/s]
add_field<Computed>("mam4_microphysics_tendency_aqso4", vector3d_mid_nmodes, nondim, grid_name);

// Diagnostics: SO4 in-cloud tendencies[kg/kg/s]
add_field<Computed>("mam4_microphysics_tendency_aqso4", vector3d_mid_nmodes, kg / kg / s, grid_name);
// Diagnostics: H2SO4 in-cloud tendencies [mixed units: kg/kg/s or #/kg/s]
add_field<Computed>("mam4_microphysics_tendency_aqh2so4", vector3d_mid_nmodes, nondim, grid_name);

// Diagnostics: H2SO4 in-cloud tendencies[kg/kg/s]
add_field<Computed>("mam4_microphysics_tendency_aqh2so4", vector3d_mid_nmodes, kg / kg / s, grid_name);
// Diagnostics: tendencies due to aerosol microphysics (gas aerosol exchange) [mixed units: mol/mol/s or #/mol/s]
add_field<Computed>("mam4_microphysics_tendency_condensation", vector3d_num_gas_aerosol_constituents, nondim, grid_name);
add_field<Computed>("mam4_microphysics_tendency_renaming", vector3d_num_gas_aerosol_constituents, nondim, grid_name);
add_field<Computed>("mam4_microphysics_tendency_nucleation", vector3d_num_gas_aerosol_constituents, nondim, grid_name);
add_field<Computed>("mam4_microphysics_tendency_coagulation", vector3d_num_gas_aerosol_constituents, nondim, grid_name);
add_field<Computed>("mam4_microphysics_tendency_renaming_cloud_borne", vector3d_num_gas_aerosol_constituents, nondim, grid_name);
}

// Creating a Linoz reader and setting Linoz parameters involves reading data
Expand Down Expand Up @@ -516,6 +525,45 @@ void MAMMicrophysics::initialize_impl(const RunType run_type) {
// cloudborne aerosol, e.g., soa_c_1
populate_cloudborne_dry_aero(dry_aero_, buffer_);

if (extra_mam4_aero_microphys_diags_) {
//Some dignostics fields have mixed units (kg/kg/s, #/kg/s, etc.)
//For these fields, we add a docstring to the field to indicate that
//the units are mixed and the user should be careful when using these fields.
//Following map contains the map of fields with mixed units and their long names.
const std::map<std::string, std::string> mixed_units_fields = {
{"mam4_microphysics_tendency_gas_phase_chemistry",
"MAM4xx microphysics tendencies due to gas phase chemistry [mixed units: kg/kg/s or #/kg/s]"},

{"mam4_microphysics_tendency_aqueous_chemistry",
"MAM4xx microphysics tendencies due to aqueous chemistry [mixed units: kg/kg/s or #/kg/s]"},

{"mam4_microphysics_tendency_aqso4",
"MAM4xx microphysics tendencies due to aqueous SO4 [mixed units: kg/kg/s or #/kg/s]"},

{"mam4_microphysics_tendency_aqh2so4",
"MAM4xx microphysics tendencies due to aqueous H2SO4 [mixed units: kg/kg/s or #/kg/s]"},

{"mam4_microphysics_tendency_condensation",
"MAM4xx microphysics tendencies due to gas aerosol exchange (condensation) [mixed units: mol/mol/s or #/mol/s]"},

{"mam4_microphysics_tendency_renaming",
"MAM4xx microphysics tendencies due to gas aerosol exchange (renaming) [mixed units: mol/mol/s or #/mol/s]"},

{"mam4_microphysics_tendency_nucleation",
"MAM4xx microphysics tendencies due to gas aerosol exchange (nucleation) [mixed units: mol/mol/s or #/mol/s]"},

{"mam4_microphysics_tendency_coagulation",
"MAM4xx microphysics tendencies due to gas aerosol exchange (coagulation) [mixed units: mol/mol/s or #/mol/s]"},

{"mam4_microphysics_tendency_renaming_cloud_borne",
"MAM4xx microphysics tendencies due to gas aerosol exchange (renaming cloud borne) [mixed units: mol/mol/s or #/mol/s]"},

};
// Add docstring to the fields with mixed units
add_io_docstring_to_fields_with_mixed_units(mixed_units_fields);
}


// set field property checks for the fields in this process
/* e.g.
using Interval = FieldWithinIntervalCheck;
Expand Down Expand Up @@ -593,7 +641,7 @@ void MAMMicrophysics::run_impl(const double dt) {
const int team_size=nlev;
#else
const int team_size=1;
#endif
#endif
const auto policy =
ekat::ExeSpaceUtils<KT::ExeSpace>::get_team_policy_force_team_size(ncol, team_size);

Expand Down Expand Up @@ -663,13 +711,23 @@ void MAMMicrophysics::run_impl(const double dt) {
// - dvmr/dt: Tendencies for mixing ratios [kg/kg/s]
view_3d gas_phase_chemistry_dvmrdt, aqueous_chemistry_dvmrdt;
view_3d aqso4_incloud_mmr_tendency, aqh2so4_incloud_mmr_tendency;
view_3d gas_aero_exchange_condensation, gas_aero_exchange_renaming,
gas_aero_exchange_nucleation, gas_aero_exchange_coagulation,
gas_aero_exchange_renaming_cloud_borne;

if (extra_mam4_aero_microphys_diags_) {
gas_phase_chemistry_dvmrdt = get_field_out("mam4_microphysics_tendency_gas_phase_chemistry").get_view<Real ***>();
aqueous_chemistry_dvmrdt = get_field_out("mam4_microphysics_tendency_aqueous_chemistry").get_view<Real ***>();
aqso4_incloud_mmr_tendency = get_field_out("mam4_microphysics_tendency_aqso4").get_view<Real ***>();
aqh2so4_incloud_mmr_tendency = get_field_out("mam4_microphysics_tendency_aqh2so4").get_view<Real ***>();
gas_aero_exchange_condensation = get_field_out("mam4_microphysics_tendency_condensation").get_view<Real***>();
gas_aero_exchange_renaming = get_field_out("mam4_microphysics_tendency_renaming").get_view<Real***>();
gas_aero_exchange_nucleation = get_field_out("mam4_microphysics_tendency_nucleation").get_view<Real***>();
gas_aero_exchange_coagulation = get_field_out("mam4_microphysics_tendency_coagulation").get_view<Real***>();
gas_aero_exchange_renaming_cloud_borne = get_field_out("mam4_microphysics_tendency_renaming_cloud_borne").get_view<Real***>();
}


// climatology data for linear stratospheric chemistry
// ozone (climatology) [vmr]
auto linoz_o3_clim = buffer_.scratch[0];
Expand Down Expand Up @@ -910,13 +968,22 @@ void MAMMicrophysics::run_impl(const double dt) {
const auto work_set_het_icol = ekat::subview(work_set_het, icol);

mam4::MicrophysDiagnosticArrays diag_arrays;

if (extra_mam4_aero_microphys_diags) {
diag_arrays.gas_phase_chemistry_dvmrdt = ekat::subview(gas_phase_chemistry_dvmrdt, icol);

diag_arrays.aqueous_chemistry_dvmrdt = ekat::subview(aqueous_chemistry_dvmrdt, icol);
diag_arrays.aqso4_incloud_mmr_tendency = ekat::subview(aqso4_incloud_mmr_tendency, icol);
diag_arrays.aqh2so4_incloud_mmr_tendency = ekat::subview(aqh2so4_incloud_mmr_tendency, icol);

diag_arrays.gas_aero_exchange_condensation = ekat::subview(gas_aero_exchange_condensation, icol);
diag_arrays.gas_aero_exchange_renaming = ekat::subview(gas_aero_exchange_renaming, icol);
diag_arrays.gas_aero_exchange_nucleation = ekat::subview(gas_aero_exchange_nucleation, icol);
diag_arrays.gas_aero_exchange_coagulation = ekat::subview(gas_aero_exchange_coagulation, icol);
diag_arrays.gas_aero_exchange_renaming_cloud_borne = ekat::subview(gas_aero_exchange_renaming_cloud_borne, icol);
}


// Wind speed at the surface
const Real wind_speed =
haero::sqrt(u_wind(icol, surface_lev) * u_wind(icol, surface_lev) +
Expand Down Expand Up @@ -980,8 +1047,8 @@ void MAMMicrophysics::run_impl(const double dt) {
offset_aerosol, config.linoz.o3_sfc, config.linoz.o3_tau,
config.linoz.o3_lbl, dry_diameter_icol, wet_diameter_icol,
wetdens_icol, dry_atm.phis(icol), cmfdqr, prain_icol, nevapr_icol,
work_set_het_icol, drydep_data, aqso4_flx_col, aqh2so4_flx_col, diag_arrays,
dvel_col, dflx_col, progs);
work_set_het_icol, drydep_data, aqso4_flx_col, aqh2so4_flx_col,
diag_arrays, dvel_col, dflx_col, progs);

team.team_barrier();
// Update constituent fluxes with gas drydep fluxes (dflx)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,17 @@ class MAMMicrophysics final : public MAMGenericInterface {
void init_temporary_views();
int len_temporary_views_{0};

void add_io_docstring_to_fields_with_mixed_units(const std::map<std::string, std::string> &flds) {
using str_atts_t = std::map<std::string,std::string>;
for (const auto &pair : flds) {
// Get the field, and add a docstring to its string attributes
// This is used to document that the field contains heterogeneous
// quantities, i.e., species have different units.
auto &f = get_field_out(pair.first);
auto &io_str_atts = f.get_header().get_extra_data<str_atts_t>("io: string attributes");
io_str_atts["doc"] = pair.second;
}
}
Comment on lines +166 to +176
Copy link
Contributor

@mahf708 mahf708 Jul 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think this is not a good idea. This will be forgotten and having a non-standard "doc" entry in the netcdf files isn't going to be all that illuminating or helpful, frankly. I suggest two things:

  1. For now: Add these strings (you can keep them exactly as they are) to the io_metadata csv file in the link I shared under long_name column
  2. For later: Add a src/diagnostic impl to parse out these fields into the more regular fields (col, lev) instead of the non-obvious fields (col, something_no_user_will_be_ever_able_to_figure_out_readily, lev)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, these fields are there only to expose these quantities. Ideally, we should have fields with names that make sense (e.g., so4_mam4_gas_phase_tendency) and extract specific tracers/species from these fields.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But up to you if you wanna do this right away, or merge and do later. I am not picky about these doc strings (so I am happy to pretend they are not there ;))

}; // MAMMicrophysics

} // namespace scream
Expand Down
Loading