Skip to content

Commit c70062e

Browse files
Merge branch 'singhbalwinder/eamxx/precribe-o3-mam4xx' (PR #7539)
EAMxx: Adds prescribed Ozone option for MAM4xx The user can now select whether to use prescribed or prognostic O3. Selecting prescribed O3 disables LINOZ calculations of stratospheric O3. Namelist switch: use_mam4_precribed_ozone Current default: false The switch above also replaces the mam4_run_linoz namelist. Removes redundant addition of gases as tracers in the optics interface. [BFB] * singhbalwinder/eamxx/precribe-o3-mam4xx: Moves option to base mam4 xml tag Fix a space in the comments Adds static compile time error checking EAMxx: Adds option for prescribed Ozone in MAM4xx
2 parents 09e0975 + 9774261 commit c70062e

6 files changed

+36
-43
lines changed

components/eamxx/cime_config/namelist_defaults_eamxx.xml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,9 +274,9 @@ be lost if SCREAM_HACK_XML is not enabled.
274274
<!-- Basic options for each mam4 atm process -->
275275
<mam4_atm_proc_base inherit="atm_proc_base">
276276
<create_fields_interval_checks type="logical" doc="Create field interval checks for all fields that are computed and requested in mam4xx." >false</create_fields_interval_checks>
277+
<use_mam4_precribed_ozone type="logical" doc="Switch to enable prescribed ozone in MAM4xx">false</use_mam4_precribed_ozone>
277278
</mam4_atm_proc_base>
278279

279-
280280
<!-- MAM4xx-ACI -->
281281
<mam4_aci inherit="mam4_atm_proc_base">
282282
<wsubmin type="real" doc="Minimum diagnostic sub-grid vertical velocity">0.001</wsubmin>
@@ -312,7 +312,6 @@ be lost if SCREAM_HACK_XML is not enabled.
312312
<mam4_do_coag type="logical" doc="Switch to enable aerosol microphysics coagulation process">true</mam4_do_coag>
313313
<mam4_do_rename type="logical" doc="Switch to enable aerosol microphysics rename process">true</mam4_do_rename>
314314
<!-- LINOZ parameters -->
315-
<mam4_run_linoz type="logical" doc="turn on/off linoz computation">true</mam4_run_linoz>
316315
<mam4_o3_tau type="real" doc="Linoz tau parameter">172800.0</mam4_o3_tau>
317316
<mam4_o3_sfc type="real" doc="Linoz surface parameter">3.0E-008</mam4_o3_sfc>
318317
<mam4_o3_lbl type="integer" doc="Linoz lbl parameter">4</mam4_o3_lbl>

components/eamxx/src/physics/mam/eamxx_mam_generic_process_interface.cpp

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ namespace scream {
1010
MAMGenericInterface::MAMGenericInterface(const ekat::Comm &comm,
1111
const ekat::ParameterList &params)
1212
: AtmosphereProcess(comm, params) {
13+
use_prescribed_ozone_ = m_params.get<bool>("use_mam4_precribed_ozone", false);
1314
/* Anything that can be initialized without grid information can be
1415
* initialized here. Like universal constants, mam wetscav options.
1516
*/
@@ -50,8 +51,7 @@ void MAMGenericInterface::set_aerosol_and_gas_ranges() {
5051
}
5152

5253
for(int g = 0; g < mam_coupling::num_aero_gases(); ++g) {
53-
const std::string gas_mmr_field_name = mam_coupling::gas_mmr_field_name(g);
54-
limits_aerosol_gas_tracers_[gas_mmr_field_name] =
54+
limits_aerosol_gas_tracers_[std::string(mam_coupling::gas_mmr_name[g])] =
5555
mam_coupling::physical_min_max(mmr_label);
5656
} // end for loop num gases
5757
}
@@ -99,6 +99,7 @@ void MAMGenericInterface::add_fields_cloudborne_aerosol() {
9999
auto n_unit = 1 / kg; // units of number mixing ratios of tracers
100100
const auto &grid_name = grid_->name();
101101

102+
//Layout for 3D scalar fields at midpoints(col, level))
102103
FieldLayout scalar3d_mid = grid_->get_3d_scalar_layout(true);
103104

104105
// ---------------------------------------------------------------------
@@ -167,11 +168,30 @@ void MAMGenericInterface::add_tracers_interstitial_aerosol() {
167168
// ================================================================
168169

169170
void MAMGenericInterface::add_tracers_gases() {
171+
//Note that the gas list in MAM4 is:
172+
//{"O3", "H2O2", "H2SO4", "SO2", "DMS", "SOAG"}
170173
using namespace ekat::units;
171-
auto q_unit = kg / kg; // units of mass mixing ratios of tracers
172-
for(int g = 0; g < mam_coupling::num_aero_gases(); ++g) {
173-
const std::string gas_mmr_field_name = mam_coupling::gas_mmr_field_name(g);
174-
add_tracer<Updated>(gas_mmr_field_name, grid_, q_unit);
174+
constexpr auto q_unit = kg / kg; // units of mass mixing ratios of tracers
175+
const auto &grid_name = grid_->name();
176+
177+
//Layout for 3D scalar fields at midpoints(col, level))
178+
const FieldLayout scalar3d_mid = grid_->get_3d_scalar_layout(true);
179+
180+
//O3 can be prescribed or prognostic depending upon the user input
181+
//Index of Ozone in the gas list (currently order of species is fixed)
182+
constexpr int o3_id = 0;
183+
static_assert(mam_coupling::gas_mmr_name[o3_id] == "O3", "The first gas must be O3");
184+
if (use_prescribed_ozone_) {
185+
// If using prescribed O3, we add it as a field
186+
add_field<Updated>(std::string(mam_coupling::gas_mmr_name[o3_id]), scalar3d_mid, q_unit, grid_name);
187+
} else {
188+
// If not using prescribed O3 (i.e., prognostic O3), we add it as a tracer
189+
add_tracer<Updated>(std::string(mam_coupling::gas_mmr_name[o3_id]), grid_, q_unit);
190+
}
191+
192+
// add other gases as tracers (note that the index of gases starts from 1)
193+
for(int g = 1; g < mam_coupling::num_aero_gases(); ++g) {
194+
add_tracer<Updated>(std::string(mam_coupling::gas_mmr_name[g]), grid_, q_unit);
175195
} // end for loop num gases
176196
}
177197
// ================================================================
@@ -252,8 +272,7 @@ void MAMGenericInterface::set_buffer_scratch_to_zero(
252272
void MAMGenericInterface::populate_gases_wet_aero(
253273
mam_coupling::AerosolState &wet_aero) {
254274
for(int g = 0; g < mam_coupling::num_aero_gases(); ++g) {
255-
const std::string gas_mmr_field_name = mam_coupling::gas_mmr_field_name(g);
256-
wet_aero.gas_mmr[g] = get_field_out(gas_mmr_field_name).get_view<Real **>();
275+
wet_aero.gas_mmr[g] = get_field_out(std::string(mam_coupling::gas_mmr_name[g])).get_view<Real **>();
257276
}
258277
}
259278

components/eamxx/src/physics/mam/eamxx_mam_generic_process_interface.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ class MAMGenericInterface : public scream::AtmosphereProcess {
7575
const std::map<std::string, std::pair<Real, Real>> &max_min_process);
7676
void set_buffer_scratch_to_zero(mam_coupling::Buffer &buffer);
7777

78+
//namelist variables (declared protected so that derived classes can access them)
79+
bool use_prescribed_ozone_{false}; // use prescribed ozone from MAM4
80+
7881
private:
7982
// The type of subcomponent
8083
// --------------------------------------------------------------------------

components/eamxx/src/physics/mam/eamxx_mam_microphysics_process_interface.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ MAMMicrophysics::MAMMicrophysics(const ekat::Comm &comm,
3535
config_.amicphys.newnuc_h2so4_conc_optaa = 2;
3636

3737
// LINOZ namelist parameters
38-
config_.linoz.compute = m_params.get<bool>("mam4_run_linoz", true);
38+
// Compute LINOZ only for prognostic Ozone (i.e. !use_prescribed_ozone_)
39+
config_.linoz.compute = !use_prescribed_ozone_;
3940

4041
if (config_.linoz.compute) {
4142
config_.linoz.o3_lbl = m_params.get<int>("mam4_o3_lbl");

components/eamxx/src/physics/mam/eamxx_mam_optics_process_interface.cpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,7 @@ void MAMOptics::set_grids(
8585
add_tracers_gases();
8686
// add fields e.g., num_c1, soa_c1
8787
add_fields_cloudborne_aerosol();
88-
89-
// aerosol-related gases: mass mixing ratios
90-
for(int g = 0; g < mam_coupling::num_aero_gases(); ++g) {
91-
const char *gas_mmr_field_name = mam_coupling::gas_mmr_field_name(g);
92-
add_tracer<Updated>(gas_mmr_field_name, grid_, kg / kg);
93-
}
94-
}
88+
} //set_grids
9589

9690
size_t MAMOptics::requested_buffer_size_in_bytes() const {
9791
return mam_coupling::buffer_size(ncol_, nlev_, num_2d_scratch_,

components/eamxx/src/physics/mam/mam_coupling.hpp

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,6 @@ constexpr int gas_pcnst() {
4848

4949
constexpr const char *num_modes_tag_name() { return "nmodes"; }
5050

51-
// number of aerosol/gas species tendencies
52-
KOKKOS_INLINE_FUNCTION
53-
constexpr int nqtendbb() { return 4; }
54-
5551
// returns the number of distinct aerosol modes
5652
KOKKOS_INLINE_FUNCTION
5753
constexpr int num_aero_modes() { return mam4::AeroConfig::num_modes(); }
@@ -96,14 +92,8 @@ const char *aero_species_name(const int species_id) {
9692
return species_names[species_id];
9793
}
9894

99-
// Given a MAM aerosol-related gas ID, returns a string denoting the symbolic
100-
// name of the gas species.
101-
KOKKOS_INLINE_FUNCTION
102-
const char *gas_species_name(const int gas_id) {
103-
static const char *species_names[num_aero_gases()] = {"O3", "H2O2", "H2SO4",
104-
"SO2", "DMS", "SOAG"};
105-
return species_names[gas_id];
106-
}
95+
// Given a MAM aerosol-related gas ID, returns a string_view denoting the symbolic
96+
constexpr std::array<std::string_view, num_aero_gases()> gas_mmr_name= {"O3", "H2O2", "H2SO4", "SO2", "DMS", "SOAG"};
10797

10898
// here we provide storage for names of fields generated by the functions below
10999
namespace {
@@ -165,12 +155,6 @@ char *cld_aero_mmr_names(int mode, int species) {
165155
return cld_aero_mmr_names_[mode][species];
166156
}
167157

168-
KOKKOS_INLINE_FUNCTION
169-
char *gas_mmr_names(int gas_id) {
170-
static char gas_mmr_names_[num_aero_gases()][max_field_name_len()] = {};
171-
return gas_mmr_names_[gas_id];
172-
}
173-
174158
} // end anonymous namespace
175159

176160
// Given a MAM aerosol mode index, returns the name of the related interstitial
@@ -227,13 +211,6 @@ const char *cld_aero_mmr_field_name(const int mode, const int species) {
227211
return const_cast<const char *>(cld_aero_mmr_names(mode, species));
228212
};
229213

230-
// Given a MAM aerosol-related gas identifier, returns the name of its mass
231-
// mixing ratio field in EAMxx
232-
KOKKOS_INLINE_FUNCTION
233-
const char *gas_mmr_field_name(const int gas) {
234-
return const_cast<const char *>(gas_species_name(gas));
235-
}
236-
237214
// This type stores multi-column views related specifically to the wet
238215
// atmospheric state used by EAMxx.
239216
struct WetAtmosphere {

0 commit comments

Comments
 (0)