Skip to content

Commit 9acaab9

Browse files
EAMxx: Adds option for prescribed Ozone in MAM4xx
1 parent 60c0024 commit 9acaab9

6 files changed

+37
-42
lines changed

components/eamxx/cime_config/namelist_defaults_eamxx.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,8 +311,8 @@ be lost if SCREAM_HACK_XML is not enabled.
311311
<mam4_do_newnuc type="logical" doc="Switch to enable aerosol microphysics nucleation process">true</mam4_do_newnuc>
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>
314+
<use_mam4_precribed_ozone type="logical" doc="Switch to enable prescribed ozone in MAM4xx">false</use_mam4_precribed_ozone>
314315
<!-- LINOZ parameters -->
315-
<mam4_run_linoz type="logical" doc="turn on/off linoz computation">true</mam4_run_linoz>
316316
<mam4_o3_tau type="real" doc="Linoz tau parameter">172800.0</mam4_o3_tau>
317317
<mam4_o3_sfc type="real" doc="Linoz surface parameter">3.0E-008</mam4_o3_sfc>
318318
<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: 28 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,31 @@ 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+
176+
const auto &grid_name = grid_->name();
177+
178+
//Layout for 3D scalar fields at midpoints(col, level))
179+
const FieldLayout scalar3d_mid = grid_->get_3d_scalar_layout(true);
180+
181+
182+
//Special treatmenet for Ozone (O3):
183+
// O3 can be prescribed or prognostic depending upon the user input
184+
constexpr int o3_id = 0; //Index of Ozone in the gas list
185+
if (use_prescribed_ozone_) {
186+
// If using prescribed O3, we add it as a field
187+
add_field<Updated>(std::string(mam_coupling::gas_mmr_name[o3_id]), scalar3d_mid, q_unit, grid_name);
188+
} else {
189+
// If not using prescribed O3 (i.e., prognostic O3), we add it as a tracer
190+
add_tracer<Updated>(std::string(mam_coupling::gas_mmr_name[o3_id]), grid_, q_unit);
191+
}
192+
193+
// add other gases as tracers (note that the index of gases starts from 1)
194+
for(int g = 1; g < mam_coupling::num_aero_gases(); ++g) {
195+
add_tracer<Updated>(std::string(mam_coupling::gas_mmr_name[g]), grid_, q_unit);
175196
} // end for loop num gases
176197
}
177198
// ================================================================
@@ -252,8 +273,7 @@ void MAMGenericInterface::set_buffer_scratch_to_zero(
252273
void MAMGenericInterface::populate_gases_wet_aero(
253274
mam_coupling::AerosolState &wet_aero) {
254275
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 **>();
276+
wet_aero.gas_mmr[g] = get_field_out(std::string(mam_coupling::gas_mmr_name[g])).get_view<Real **>();
257277
}
258278
}
259279

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)