Skip to content

Commit

Permalink
Allow for not advecting tracers in shoc
Browse files Browse the repository at this point in the history
  • Loading branch information
tcclevenger committed Oct 31, 2024
1 parent 91a2410 commit 14a4fd7
Show file tree
Hide file tree
Showing 20 changed files with 168 additions and 111 deletions.
60 changes: 60 additions & 0 deletions components/eamxx/src/control/atmosphere_driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,66 @@ void AtmosphereDriver::create_fields()
m_field_mgrs[grid->name()]->registration_begins();
}

// Before registering fields, check that Field Requests for tracers are compatible
{
// Create map from tracer name to a vector which contains the field requests for that tracer.
std::map<std::string, std::vector<FieldRequest>> tracer_requests;
auto gather_tracer_requests = [&] (FieldRequest req) {
if (std::find(req.groups.begin(),
req.groups.end(),
"tracers") == req.groups.end()) return;

std::string fname = req.fid.name();
if (tracer_requests.find(fname) == tracer_requests.end()) {
tracer_requests[fname] = std::vector<FieldRequest>(1, req);
} else {
tracer_requests[fname].push_back(req);
}
};
for (const auto& req : m_atm_process_group->get_required_field_requests()){
gather_tracer_requests(req);
}
for (const auto& req : m_atm_process_group->get_computed_field_requests()) {
gather_tracer_requests(req);
}

// Go through the map entry for each tracer and check that every one
// has the same request for turbulence advection.
for (auto fr : tracer_requests) {
bool mismatch_found = false;

const auto reqs = fr.second;
const bool is_first_turb_advect =
std::find(reqs.front().groups.begin(),
reqs.front().groups.end(),
"turbulence_advected_tracers") != reqs.front().groups.end();
for (size_t i=1; i<reqs.size(); ++i) {
const bool is_turb_advect =
std::find(reqs[i].groups.begin(),
reqs[i].groups.end(),
"turbulence_advected_tracers") != reqs[i].groups.end();
if (is_turb_advect != is_first_turb_advect) {
mismatch_found = true;
break;
}
}
if (mismatch_found) {
std::ostringstream ss;
ss << "Error! Incompatible tracer request. Turbulence advection requests not consistent among processes.\n"
" - Tracer name: " + fr.first + "\n"
" - Requests (process name, grid name, is tracers turbulence advected):\n";
for (auto req : reqs) {
const auto grid_name = req.fid.get_grid_name();
const bool turb_advect = std::find(req.groups.begin(),
req.groups.end(),
"turbulence_advected_tracers") != req.groups.end();
ss << " - (" + req.calling_process + ", " + grid_name + ", " + (turb_advect ? "true" : "false") + ")\n";
}
EKAT_ERROR_MSG(ss.str());
}
}
}

// Register required/computed fields
for (const auto& req : m_atm_process_group->get_required_field_requests()) {
m_field_mgrs.at(req.fid.get_grid_name())->register_field(req);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void SurfaceCouplingExporter::set_grids(const std::shared_ptr<const GridsManager
add_field<Required>("phis", scalar2d_layout, m2/s2, grid_name);
add_field<Required>("p_mid", scalar3d_layout_mid, Pa, grid_name, ps);
add_field<Required>("T_mid", scalar3d_layout_mid, K, grid_name, ps);
add_tracer<Required>("qv", m_grid, kg/kg, ps);
add_tracer<Required>("qv", m_grid, kg/kg, true, ps);
// TODO: Switch horiz_winds to using U and V, note right now there is an issue with when the subfields are created, so can't switch yet.
add_field<Required>("horiz_winds", vector3d_layout, m/s, grid_name);
add_field<Required>("sfc_flux_dir_nir", scalar2d_layout, W/m2, grid_name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ void HommeDynamics::set_grids (const std::shared_ptr<const GridsManager> grids_m
add_field<Computed>("p_dry_mid", pg_scalar3d_mid, Pa, pgn,N);
add_field<Computed>("omega", pg_scalar3d_mid, Pa/s, pgn,N);

add_tracer<Updated >("qv", m_phys_grid, kg/kg, N);
add_tracer<Updated >("qv", m_phys_grid, kg/kg, true, N);
add_group<Updated>("tracers",pgn,N, Bundling::Required);

if (fv_phys_active()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ void CldFraction::set_grids(const std::shared_ptr<const GridsManager> grids_mana

// Set of fields used strictly as input
constexpr int ps = Pack::n;
add_tracer<Required>("qi", m_grid, kg/kg, ps);
add_tracer<Required>("qi", m_grid, kg/kg, true, ps);
add_field<Required>("cldfrac_liq", scalar3d_layout_mid, nondim, grid_name,ps);

// Set of fields used strictly as output
Expand Down
6 changes: 3 additions & 3 deletions components/eamxx/src/physics/cosp/eamxx_cosp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ void Cosp::set_grids(const std::shared_ptr<const GridsManager> grids_manager)
add_field<Required>("phis", scalar2d , m2/s2, grid_name);
add_field<Required>("pseudo_density", scalar3d_mid, Pa, grid_name);
add_field<Required>("cldfrac_rad", scalar3d_mid, nondim, grid_name);
add_tracer<Required>("qv", m_grid, kg/kg);
add_tracer<Required>("qc", m_grid, kg/kg);
add_tracer<Required>("qi", m_grid, kg/kg);
add_tracer<Required>("qv", m_grid, kg/kg, true);
add_tracer<Required>("qc", m_grid, kg/kg, true);
add_tracer<Required>("qi", m_grid, kg/kg, true);
// Optical properties, should be computed in radiation interface
add_field<Required>("dtau067", scalar3d_mid, nondim, grid_name); // 0.67 micron optical depth
add_field<Required>("dtau105", scalar3d_mid, nondim, grid_name); // 10.5 micron optical depth
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,19 +86,19 @@ void MAMAci::set_grids(

// atmospheric quantities
// specific humidity [kg/kg]
add_tracer<Required>("qv", grid_, q_unit);
add_tracer<Required>("qv", grid_, q_unit, true);

// cloud liquid mass mixing ratio [kg/kg]
add_tracer<Required>("qc", grid_, q_unit);
add_tracer<Required>("qc", grid_, q_unit, true);

// cloud ice mass mixing ratio [kg/kg]
add_tracer<Required>("qi", grid_, q_unit);
add_tracer<Required>("qi", grid_, q_unit, true);

// cloud liquid number mixing ratio [1/kg]
add_tracer<Required>("nc", grid_, n_unit);
add_tracer<Required>("nc", grid_, n_unit, true);

// cloud ice number mixing ratio [1/kg]
add_tracer<Required>("ni", grid_, n_unit);
add_tracer<Required>("ni", grid_, n_unit, true);

// Temperature[K] at midpoints
add_field<Required>("T_mid", scalar3d_layout_mid, K, grid_name);
Expand Down Expand Up @@ -160,15 +160,16 @@ void MAMAci::set_grids(

// interstitial and cloudborne aerosol tracers of interest: mass (q) and
// number (n) mixing ratios
// NOTE:
// - For interstitial aerosols, we have dynamics advect, but not turbulence.
// - For cloudborne aerosols, DO NOT advect.
for(int mode = 0; mode < mam_coupling::num_aero_modes(); ++mode) {
// interstitial aerosol tracers of interest: number (n) mixing ratios
const char *int_nmr_field_name =
mam_coupling::int_aero_nmr_field_name(mode);
add_tracer<Updated>(int_nmr_field_name, grid_, n_unit);
add_tracer<Updated>(int_nmr_field_name, grid_, n_unit, false);

// cloudborne aerosol tracers of interest: number (n) mixing ratios
// NOTE: DO NOT add cld borne aerosols to the "tracer" group as these are
// NOT advected
const char *cld_nmr_field_name =
mam_coupling::cld_aero_nmr_field_name(mode);
add_field<Updated>(cld_nmr_field_name, scalar3d_layout_mid, n_unit,
Expand All @@ -179,11 +180,9 @@ void MAMAci::set_grids(
const char *int_mmr_field_name =
mam_coupling::int_aero_mmr_field_name(mode, a);
if(strlen(int_mmr_field_name) > 0) {
add_tracer<Updated>(int_mmr_field_name, grid_, q_unit);
add_tracer<Updated>(int_mmr_field_name, grid_, q_unit, false);
}
// (cloudborne) aerosol tracers of interest: mass (q) mixing ratios
// NOTE: DO NOT add cld borne aerosols to the "tracer" group as these are
// NOT advected
const char *cld_mmr_field_name =
mam_coupling::cld_aero_mmr_field_name(mode, a);
if(strlen(cld_mmr_field_name) > 0) {
Expand All @@ -195,7 +194,7 @@ void MAMAci::set_grids(

for(int g = 0; g < mam_coupling::num_aero_gases(); ++g) {
const char *gas_mmr_field_name = mam_coupling::gas_mmr_field_name(g);
add_tracer<Updated>(gas_mmr_field_name, grid_, q_unit);
add_tracer<Updated>(gas_mmr_field_name, grid_, q_unit, true);
} // end for loop num gases

// ------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,19 @@ void MAMConstituentFluxes::set_grids(
// --------------------------------------------------------------------------
// ----------- Atmospheric quantities -------------
// Specific humidity [kg/kg](Require only for building DS)
add_tracer<Required>("qv", grid_, q_unit);
add_tracer<Required>("qv", grid_, q_unit, true);

// Cloud liquid mass mixing ratio [kg/kg](Require only for building DS)
add_tracer<Required>("qc", grid_, q_unit);
add_tracer<Required>("qc", grid_, q_unit, true);

// Cloud ice mass mixing ratio [kg/kg](Require only for building DS)
add_tracer<Required>("qi", grid_, q_unit);
add_tracer<Required>("qi", grid_, q_unit, true);

// Cloud liquid number mixing ratio [1/kg](Require only for building DS)
add_tracer<Required>("nc", grid_, n_unit);
add_tracer<Required>("nc", grid_, n_unit, true);

// Cloud ice number mixing ratio [1/kg](Require only for building DS)
add_tracer<Required>("ni", grid_, n_unit);
add_tracer<Required>("ni", grid_, n_unit, true);

// Temperature[K] at midpoints
add_field<Required>("T_mid", scalar3d_mid, K, grid_name);
Expand Down Expand Up @@ -98,15 +98,16 @@ void MAMConstituentFluxes::set_grids(

// interstitial and cloudborne aerosol tracers of interest: mass (q) and
// number (n) mixing ratios
// NOTE:
// - For interstitial aerosols, we have dynamics advect, but not turbulence.
// - For cloudborne aerosols, DO NOT advect. (for now just a field)
for(int mode = 0; mode < mam_coupling::num_aero_modes(); ++mode) {
// interstitial aerosol tracers of interest: number (n) mixing ratios
const std::string int_nmr_field_name =
mam_coupling::int_aero_nmr_field_name(mode);
add_tracer<Updated>(int_nmr_field_name, grid_, n_unit);
add_tracer<Updated>(int_nmr_field_name, grid_, n_unit, false);

// cloudborne aerosol tracers of interest: number (n) mixing ratios
// NOTE: DO NOT add cld borne aerosols to the "tracer" group as these are
// NOT advected
const std::string cld_nmr_field_name =
mam_coupling::cld_aero_nmr_field_name(mode);
add_field<Updated>(cld_nmr_field_name, scalar3d_mid, n_unit, grid_name);
Expand All @@ -116,11 +117,9 @@ void MAMConstituentFluxes::set_grids(
const std::string int_mmr_field_name =
mam_coupling::int_aero_mmr_field_name(mode, a);
if(not int_mmr_field_name.empty()) {
add_tracer<Updated>(int_mmr_field_name, grid_, q_unit);
add_tracer<Updated>(int_mmr_field_name, grid_, q_unit, false);
}
// (cloudborne) aerosol tracers of interest: mass (q) mixing ratios
// NOTE: DO NOT add cld borne aerosols to the "tracer" group as these are
// NOT advected
const std::string cld_mmr_field_name =
mam_coupling::cld_aero_mmr_field_name(mode, a);
if(not cld_mmr_field_name.empty()) {
Expand All @@ -131,7 +130,7 @@ void MAMConstituentFluxes::set_grids(

for(int g = 0; g < mam_coupling::num_aero_gases(); ++g) {
const std::string gas_mmr_field_name = mam_coupling::gas_mmr_field_name(g);
add_tracer<Updated>(gas_mmr_field_name, grid_, q_unit);
add_tracer<Updated>(gas_mmr_field_name, grid_, q_unit, true);
} // end for loop num gases

} // set_grid
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,19 +71,19 @@ void MAMDryDep::set_grids(

// ----------- Atmospheric quantities -------------
// Specific humidity [kg/kg](Require only for building DS)
add_tracer<Required>("qv", grid_, q_unit);
add_tracer<Required>("qv", grid_, q_unit, true);

// Cloud liquid mass mixing ratio [kg/kg](Require only for building DS)
add_tracer<Required>("qc", grid_, q_unit);
add_tracer<Required>("qc", grid_, q_unit, true);

// Cloud ice mass mixing ratio [kg/kg](Require only for building DS)
add_tracer<Required>("qi", grid_, q_unit);
add_tracer<Required>("qi", grid_, q_unit, true);

// Cloud liquid number mixing ratio [1/kg](Require only for building DS)
add_tracer<Required>("nc", grid_, n_unit);
add_tracer<Required>("nc", grid_, n_unit, true);

// Cloud ice number mixing ratio [1/kg](Require only for building DS)
add_tracer<Required>("ni", grid_, n_unit);
add_tracer<Required>("ni", grid_, n_unit, true);

// Temperature[K] at midpoints
add_field<Required>("T_mid", scalar3d_mid, K, grid_name);
Expand Down Expand Up @@ -153,20 +153,22 @@ void MAMDryDep::set_grids(

// (interstitial) aerosol tracers of interest: mass (q) and number (n) mixing
// ratios
// NOTE: For interstitial aerosols, we have dynamics advect, but not turbulence.
for(int m = 0; m < num_aero_modes; ++m) {
const char *int_nmr_field_name = mam_coupling::int_aero_nmr_field_name(m);

add_tracer<Updated>(int_nmr_field_name, grid_, n_unit);
add_tracer<Updated>(int_nmr_field_name, grid_, n_unit, false);
for(int a = 0; a < mam_coupling::num_aero_species(); ++a) {
const char *int_mmr_field_name =
mam_coupling::int_aero_mmr_field_name(m, a);

if(strlen(int_mmr_field_name) > 0) {
add_tracer<Updated>(int_mmr_field_name, grid_, q_unit);
add_tracer<Updated>(int_mmr_field_name, grid_, q_unit, false);
}
}
}
// (cloud) aerosol tracers of interest: mass (q) and number (n) mixing ratios
// NOTE: For cloudborne aerosols, DO NOT advect.
for(int m = 0; m < num_aero_modes; ++m) {
const char *cld_nmr_field_name = mam_coupling::cld_aero_nmr_field_name(m);

Expand All @@ -184,7 +186,7 @@ void MAMDryDep::set_grids(
// aerosol-related gases: mass mixing ratios
for(int g = 0; g < mam_coupling::num_aero_gases(); ++g) {
const char *gas_mmr_field_name = mam_coupling::gas_mmr_field_name(g);
add_tracer<Updated>(gas_mmr_field_name, grid_, q_unit);
add_tracer<Updated>(gas_mmr_field_name, grid_, q_unit, true);
}

// -------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,53 +126,32 @@ void MAMMicrophysics::set_grids(const std::shared_ptr<const GridsManager> grids_
add_field<Required>("pseudo_density", scalar3d_layout_mid, Pa, grid_name); // p_del, hydrostatic pressure
add_field<Required>("phis", scalar2d_layout_col, m2/s2, grid_name);
add_field<Required>("cldfrac_tot", scalar3d_layout_mid, nondim, grid_name); // cloud fraction
add_tracer<Required>("qv", grid_, kg/kg); // specific humidity
add_tracer<Required>("qi", grid_, kg/kg); // ice wet mixing ratio
add_tracer<Required>("ni", grid_, n_unit); // ice number mixing ratio
add_tracer<Required>("qv", grid_, kg/kg, true); // specific humidity
add_tracer<Required>("qi", grid_, kg/kg, true); // ice wet mixing ratio
add_tracer<Required>("ni", grid_, n_unit, true); // ice number mixing ratio

// droplet activation can alter cloud liquid and number mixing ratios
add_tracer<Updated>("qc", grid_, kg/kg); // cloud liquid wet mixing ratio
add_tracer<Updated>("nc", grid_, n_unit); // cloud liquid wet number mixing ratio
add_tracer<Updated>("qc", grid_, kg/kg, true); // cloud liquid wet mixing ratio
add_tracer<Updated>("nc", grid_, n_unit, true); // cloud liquid wet number mixing ratio

// (interstitial) aerosol tracers of interest: mass (q) and number (n) mixing ratios
// NOTE: For interstitial aerosols, we have dynamics advect, but not turbulence.
for (int m = 0; m < mam_coupling::num_aero_modes(); ++m) {
const char* int_nmr_field_name = mam_coupling::int_aero_nmr_field_name(m);
add_tracer<Updated>(int_nmr_field_name, grid_, n_unit);
add_tracer<Updated>(int_nmr_field_name, grid_, n_unit, false);
for (int a = 0; a < mam_coupling::num_aero_species(); ++a) {
const char* int_mmr_field_name = mam_coupling::int_aero_mmr_field_name(m, a);
if (strlen(int_mmr_field_name) > 0) {
add_tracer<Updated>(int_mmr_field_name, grid_, kg/kg);
add_tracer<Updated>(int_mmr_field_name, grid_, kg/kg, false);
}
}
}

// aerosol-related gases: mass mixing ratios
for (int g = 0; g < mam_coupling::num_aero_gases(); ++g) {
const char* gas_mmr_field_name = mam_coupling::gas_mmr_field_name(g);
add_tracer<Updated>(gas_mmr_field_name, grid_, kg/kg);
add_tracer<Updated>(gas_mmr_field_name, grid_, kg/kg, true);
}

// Tracers group -- do we need this in addition to the tracers above? In any
// case, this call should be idempotent, so it can't hurt.
add_group<Updated>("tracers", grid_name, 1, Bundling::Required);
}

// this checks whether we have the tracers we expect
void MAMMicrophysics::
set_computed_group_impl(const FieldGroup& group) {
const auto& name = group.m_info->m_group_name;
EKAT_REQUIRE_MSG(name=="tracers",
"Error! MAM4 expects a 'tracers' field group (got '" << name << "')\n");

EKAT_REQUIRE_MSG(group.m_info->m_bundled,
"Error! MAM4 expects bundled fields for tracers.\n");

// how many aerosol/gas tracers do we expect?
int num_tracers = 2 * (mam_coupling::num_aero_modes() +
mam_coupling::num_aero_tracers()) +
mam_coupling::num_aero_gases();
EKAT_REQUIRE_MSG(group.m_info->size() >= num_tracers,
"Error! MAM4 requires at least " << num_tracers << " aerosol tracers.");
}

size_t MAMMicrophysics::requested_buffer_size_in_bytes() const
Expand All @@ -189,7 +168,6 @@ void MAMMicrophysics::init_buffers(const ATMBufferManager &buffer_manager) {
"Error! Used memory != requested memory for MAMMicrophysics.");
}


void MAMMicrophysics::initialize_impl(const RunType run_type) {

step_ = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,6 @@ class MAMMicrophysics final : public scream::AtmosphereProcess {
void run_impl(const double dt) override;
void finalize_impl() override;

// performs some checks on the tracers group
void set_computed_group_impl(const FieldGroup& group) override;

private_except_cuda:

// number of horizontal columns and vertical levels
Expand Down
Loading

0 comments on commit 14a4fd7

Please sign in to comment.