Skip to content

Commit 2de092c

Browse files
committed
EAMxx: turn on/off linoz.
1 parent ffe2fee commit 2de092c

File tree

4 files changed

+92
-69
lines changed

4 files changed

+92
-69
lines changed

components/eamxx/cime_config/namelist_defaults_eamxx.xml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ be lost if SCREAM_HACK_XML is not enabled.
229229
<constant_mu_rain type="real" doc="Constant shape parameter (mu) in the rain droplet distribution">1.0</constant_mu_rain>
230230
<spa_ccn_to_nc_factor type="real" doc="Scaling factor for turning SPA ccn into P3 nc">2000.0</spa_ccn_to_nc_factor>
231231
<spa_ccn_to_nc_factor hgrid="ne256np4.pg2">1000.0</spa_ccn_to_nc_factor>
232-
<spa_ccn_to_nc_exponent type="real" doc="Exponent for turning SPA ccn into P3 nc">0.55</spa_ccn_to_nc_exponent>
232+
<spa_ccn_to_nc_exponent type="real" doc="Exponent for turning SPA ccn into P3 nc">0.55</spa_ccn_to_nc_exponent>
233233
<cldliq_to_ice_collection_factor type="real" doc="Cloud liquid to ice collection scaling factor">0.5</cldliq_to_ice_collection_factor>
234234
<rain_to_ice_collection_factor type="real" doc="Rain to ice collection scaling factor">1.0</rain_to_ice_collection_factor>
235235
<min_rime_rho type="real" doc="Minimum rime density in kg/m3">50.0</min_rime_rho>
@@ -312,6 +312,7 @@ 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>
315316
<mam4_o3_tau type="real" doc="Linoz tau parameter">172800.0</mam4_o3_tau>
316317
<mam4_o3_sfc type="real" doc="Linoz surface parameter">3.0E-008</mam4_o3_sfc>
317318
<mam4_o3_lbl type="integer" doc="Linoz lbl parameter">4</mam4_o3_lbl>
@@ -562,6 +563,7 @@ be lost if SCREAM_HACK_XML is not enabled.
562563
</do_subcol_sampling>
563564
<pool_size_multiplier type="real">1.0</pool_size_multiplier>
564565
<force_run_after_restart type="logical" doc="Force rad to run on first step after restart, regardless of rad frequency">false</force_run_after_restart>
566+
565567
</rrtmgp>
566568

567569
<mac_aero_mic inherit="atm_proc_group">

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

Lines changed: 86 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,15 @@ MAMMicrophysics::MAMMicrophysics(const ekat::Comm &comm,
3535
config_.amicphys.newnuc_h2so4_conc_optaa = 2;
3636

3737
// LINOZ namelist parameters
38-
config_.linoz.o3_lbl = m_params.get<int>("mam4_o3_lbl");
39-
config_.linoz.o3_tau = m_params.get<double>("mam4_o3_tau");
40-
config_.linoz.o3_sfc = m_params.get<double>("mam4_o3_sfc");
41-
config_.linoz.psc_T = m_params.get<double>("mam4_psc_T");
38+
config_.linoz.compute = m_params.get<bool>("mam4_run_linoz", true);
39+
40+
if (config_.linoz.compute) {
41+
config_.linoz.o3_lbl = m_params.get<int>("mam4_o3_lbl");
42+
config_.linoz.o3_tau = m_params.get<double>("mam4_o3_tau");
43+
config_.linoz.o3_sfc = m_params.get<double>("mam4_o3_sfc");
44+
config_.linoz.psc_T = m_params.get<double>("mam4_psc_T");
45+
}
46+
4247
}
4348
// ================================================================
4449
// SET_GRIDS
@@ -231,7 +236,7 @@ void MAMMicrophysics::set_grids(
231236

232237
// Creating a Linoz reader and setting Linoz parameters involves reading data
233238
// from a file and configuring the necessary parameters for the Linoz model.
234-
{
239+
if (config_.linoz.compute) {
235240
linoz_file_name_ = m_params.get<std::string>("mam4_linoz_file_name");
236241
const std::string linoz_map_file =
237242
m_params.get<std::string>("aero_microphys_remap_file", "");
@@ -383,6 +388,7 @@ void MAMMicrophysics::set_grids(
383388
mam_coupling::find_season_index_reader(season_wes_file, clat,
384389
index_season_lai_);
385390
}
391+
386392
} // set_grids
387393

388394
// ================================================================
@@ -531,39 +537,39 @@ void MAMMicrophysics::initialize_impl(const RunType run_type) {
531537
//the units are mixed and the user should be careful when using these fields.
532538
//Following map contains the map of fields with mixed units and their long names.
533539
const std::map<std::string, std::string> mixed_units_fields = {
534-
{"mam4_microphysics_tendency_gas_phase_chemistry",
540+
{"mam4_microphysics_tendency_gas_phase_chemistry",
535541
"MAM4xx microphysics tendencies due to gas phase chemistry [mixed units: kg/kg/s or #/kg/s]"},
536542

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

540-
{"mam4_microphysics_tendency_aqso4",
546+
{"mam4_microphysics_tendency_aqso4",
541547
"MAM4xx microphysics tendencies due to aqueous SO4 [mixed units: kg/kg/s or #/kg/s]"},
542548

543-
{"mam4_microphysics_tendency_aqh2so4",
549+
{"mam4_microphysics_tendency_aqh2so4",
544550
"MAM4xx microphysics tendencies due to aqueous H2SO4 [mixed units: kg/kg/s or #/kg/s]"},
545551

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

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

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

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

558-
{"mam4_microphysics_tendency_renaming_cloud_borne",
564+
{"mam4_microphysics_tendency_renaming_cloud_borne",
559565
"MAM4xx microphysics tendencies due to gas aerosol exchange (renaming cloud borne) [mixed units: mol/mol/s or #/mol/s]"},
560-
566+
561567
};
562568
// Add docstring to the fields with mixed units
563569
add_io_docstring_to_fields_with_mixed_units(mixed_units_fields);
564570
}
565571

566-
572+
567573
// set field property checks for the fields in this process
568574
/* e.g.
569575
using Interval = FieldWithinIntervalCheck;
@@ -574,7 +580,7 @@ void MAMMicrophysics::initialize_impl(const RunType run_type) {
574580
add_postcondition_check<LowerBound>(get_field_out("tke"),m_grid,0);
575581
*/
576582

577-
{
583+
if (config_.linoz.compute) {
578584
// climatology data for linear stratospheric chemistry
579585
auto linoz_o3_clim = buffer_.scratch[0]; // ozone (climatology) [vmr]
580586
auto linoz_o3col_clim =
@@ -599,7 +605,7 @@ void MAMMicrophysics::initialize_impl(const RunType run_type) {
599605
scream::mam_coupling::create_linoz_chlorine_reader(
600606
linoz_chlorine_file, ts, chlorine_loading_ymd, chlorine_values_,
601607
chlorine_time_secs_);
602-
} // LINOZ
608+
}
603609

604610
init_temporary_views();
605611
// FIXME : why are we only using nlev_ instead of ncol_xnlev?
@@ -608,10 +614,10 @@ void MAMMicrophysics::initialize_impl(const RunType run_type) {
608614
// Note: At the first time step, the data will be moved into extfrc_lst_beg,
609615
// and extfrc_lst_end will be reloaded from file with the new month.
610616
const int curr_month = start_of_step_ts().get_month() - 1; // 0-based
611-
612-
scream::mam_coupling::update_tracer_data_from_file(
617+
if (config_.linoz.compute) {
618+
scream::mam_coupling::update_tracer_data_from_file(
613619
LinozDataReader_, curr_month, *LinozHorizInterp_, linoz_data_);
614-
620+
}
615621
scream::mam_coupling::update_tracer_data_from_file(
616622
TracerDataReader_, curr_month, *TracerHorizInterp_, tracer_data_);
617623

@@ -730,38 +736,44 @@ void MAMMicrophysics::run_impl(const double dt) {
730736

731737
// climatology data for linear stratospheric chemistry
732738
// ozone (climatology) [vmr]
733-
auto linoz_o3_clim = buffer_.scratch[0];
739+
view_2d linoz_o3_clim;
734740
// column o3 above box (climatology) [Dobson Units (DU)]
735-
auto linoz_o3col_clim = buffer_.scratch[1];
736-
auto linoz_t_clim = buffer_.scratch[2]; // temperature (climatology) [K]
737-
auto linoz_PmL_clim = buffer_.scratch[3]; // P minus L (climatology) [vmr/s]
741+
view_2d linoz_o3col_clim;
742+
// temperature (climatology) [K]
743+
view_2d linoz_t_clim;
744+
// P minus L (climatology) [vmr/s]
745+
view_2d linoz_PmL_clim;
738746
// sensitivity of P minus L to O3 [1/s]
739-
auto linoz_dPmL_dO3 = buffer_.scratch[4];
747+
view_2d linoz_dPmL_dO3;
740748
// sensitivity of P minus L to T3 [K]
741-
auto linoz_dPmL_dT = buffer_.scratch[5];
749+
view_2d linoz_dPmL_dT;
742750
// sensitivity of P minus L to overhead O3 column [vmr/DU]
743-
auto linoz_dPmL_dO3col = buffer_.scratch[6];
751+
view_2d linoz_dPmL_dO3col;
744752
// Cariolle parameter for PSC loss of ozone [1/s]
745-
auto linoz_cariolle_pscs = buffer_.scratch[7];
746-
747-
view_2d linoz_output[8];
748-
linoz_output[0] = linoz_o3_clim;
749-
linoz_output[1] = linoz_o3col_clim;
750-
linoz_output[2] = linoz_t_clim;
751-
linoz_output[3] = linoz_PmL_clim;
752-
linoz_output[4] = linoz_dPmL_dO3;
753-
linoz_output[5] = linoz_dPmL_dT;
754-
linoz_output[6] = linoz_dPmL_dO3col;
755-
linoz_output[7] = linoz_cariolle_pscs;
753+
view_2d linoz_cariolle_pscs;
754+
755+
if (config_.linoz.compute) {
756+
linoz_o3_clim = buffer_.scratch[0];
757+
linoz_o3col_clim = buffer_.scratch[1];
758+
linoz_t_clim = buffer_.scratch[2];
759+
linoz_PmL_clim = buffer_.scratch[3];
760+
linoz_dPmL_dO3 = buffer_.scratch[4];
761+
linoz_dPmL_dT = buffer_.scratch[5];
762+
linoz_dPmL_dO3col = buffer_.scratch[6];
763+
linoz_cariolle_pscs = buffer_.scratch[7];
764+
}
756765
// it's a bit wasteful to store this for all columns, but simpler from an
757766
// allocation perspective
758767
auto o3_col_dens = buffer_.scratch[8];
759768

760769
/* Gather time and state information for interpolation */
761770
const auto ts = end_of_step_ts();
762771

772+
if (config_.linoz.compute) {
763773
const Real chlorine_loading = scream::mam_coupling::chlorine_loading_advance(
764774
ts, chlorine_values_, chlorine_time_secs_);
775+
config_.linoz.chlorine_loading=chlorine_loading;
776+
}
765777

766778
// Update the TracerTimeState to reflect the current time
767779
trace_time_state_.t_now = ts.frac_of_year_in_days();
@@ -774,15 +786,26 @@ void MAMMicrophysics::run_impl(const double dt) {
774786
cnst_offline_); // out
775787
Kokkos::fence();
776788

777-
scream::mam_coupling::advance_tracer_data(
789+
if (config_.linoz.compute) {
790+
view_2d linoz_output[8];
791+
linoz_output[0] = linoz_o3_clim;
792+
linoz_output[1] = linoz_o3col_clim;
793+
linoz_output[2] = linoz_t_clim;
794+
linoz_output[3] = linoz_PmL_clim;
795+
linoz_output[4] = linoz_dPmL_dO3;
796+
linoz_output[5] = linoz_dPmL_dT;
797+
linoz_output[6] = linoz_dPmL_dO3col;
798+
linoz_output[7] = linoz_cariolle_pscs;
799+
800+
scream::mam_coupling::advance_tracer_data(
778801
LinozDataReader_, // in
779802
*LinozHorizInterp_, // out
780803
ts, // in
781804
linoz_time_state_, linoz_data_, // out
782805
dry_atm_.p_mid, dry_atm_.z_iface, // in
783806
linoz_output); // out
784-
Kokkos::fence();
785-
807+
Kokkos::fence();
808+
}
786809

787810
int i = 0;
788811
for(const auto &var_name : extfrc_lst_) {
@@ -804,6 +827,7 @@ void MAMMicrophysics::run_impl(const double dt) {
804827
mam_coupling::DryAtmosphere &dry_atm = dry_atm_;
805828
mam_coupling::AerosolState &dry_aero = dry_aero_;
806829

830+
807831
mam4::mo_photo::PhotoTableData &photo_table = photo_table_;
808832
const Config &config = config_;
809833
const auto &work_photo_table = work_photo_table_;
@@ -894,10 +918,10 @@ void MAMMicrophysics::run_impl(const double dt) {
894918
const auto &index_season_lai = index_season_lai_;
895919
const int pcnst = mam4::pcnst;
896920
const bool extra_mam4_aero_microphys_diags = extra_mam4_aero_microphys_diags_;
897-
898921
//NOTE: we need to initialize photo_rates_
899922
Kokkos::deep_copy(photo_rates_,0.0);
900-
// loop over atmosphere columns and compute aerosol microphyscs
923+
// loop over atmosphere columns and compute aerosol microphysics
924+
901925
Kokkos::parallel_for(
902926
"MAMMicrophysics::run_impl", policy,
903927
KOKKOS_LAMBDA(const ThreadTeam &team) {
@@ -943,7 +967,6 @@ void MAMMicrophysics::run_impl(const double dt) {
943967
for(int i = 0; i < mam4::mo_setinv::num_tracer_cnst; ++i) {
944968
cnst_offline_icol[i] = ekat::subview(cnst_offline[i], icol);
945969
}
946-
947970
// calculate o3 column densities (first component of col_dens in Fortran
948971
// code)
949972
auto o3_col_dens_i = ekat::subview(o3_col_dens, icol);
@@ -952,17 +975,20 @@ void MAMMicrophysics::run_impl(const double dt) {
952975

953976
const auto &photo_rates_icol = ekat::subview(photo_rates, icol);
954977

955-
const auto linoz_o3_clim_icol = ekat::subview(linoz_o3_clim, icol);
956-
const auto linoz_t_clim_icol = ekat::subview(linoz_t_clim, icol);
957-
const auto linoz_o3col_clim_icol =
978+
mam4::microphysics::LinozData linoz_data;
979+
if (config.linoz.compute) {
980+
linoz_data.linoz_o3_clim_icol = ekat::subview(linoz_o3_clim, icol);
981+
linoz_data.linoz_t_clim_icol = ekat::subview(linoz_t_clim, icol);
982+
linoz_data.linoz_o3col_clim_icol =
958983
ekat::subview(linoz_o3col_clim, icol);
959-
const auto linoz_PmL_clim_icol = ekat::subview(linoz_PmL_clim, icol);
960-
const auto linoz_dPmL_dO3_icol = ekat::subview(linoz_dPmL_dO3, icol);
961-
const auto linoz_dPmL_dT_icol = ekat::subview(linoz_dPmL_dT, icol);
962-
const auto linoz_dPmL_dO3col_icol =
984+
linoz_data.linoz_PmL_clim_icol = ekat::subview(linoz_PmL_clim, icol);
985+
linoz_data.linoz_dPmL_dO3_icol = ekat::subview(linoz_dPmL_dO3, icol);
986+
linoz_data.linoz_dPmL_dT_icol = ekat::subview(linoz_dPmL_dT, icol);
987+
linoz_data.linoz_dPmL_dO3col_icol =
963988
ekat::subview(linoz_dPmL_dO3col, icol);
964-
const auto linoz_cariolle_pscs_icol =
989+
linoz_data.linoz_cariolle_pscs_icol =
965990
ekat::subview(linoz_cariolle_pscs, icol);
991+
}
966992
const auto nevapr_icol = ekat::subview(nevapr, icol);
967993
const auto prain_icol = ekat::subview(prain, icol);
968994
const auto work_set_het_icol = ekat::subview(work_set_het, icol);
@@ -1036,16 +1062,15 @@ void MAMMicrophysics::run_impl(const double dt) {
10361062
mam4::microphysics::perform_atmospheric_chemistry_and_microphysics(
10371063
team, dt, rlats, sfc_temperature(icol), sfc_pressure(icol),
10381064
wind_speed, rain, solar_flux, cnst_offline_icol, forcings_in, atm,
1039-
photo_table, chlorine_loading, config.setsox, config.amicphys,
1040-
config.linoz.psc_T, zenith_angle(icol), d_sfc_alb_dir_vis(icol),
1065+
photo_table, config.setsox, config.amicphys,
1066+
zenith_angle(icol), d_sfc_alb_dir_vis(icol),
10411067
o3_col_dens_i, photo_rates_icol, extfrc_icol, invariants_icol,
1042-
work_photo_table_icol, linoz_o3_clim_icol, linoz_t_clim_icol,
1043-
linoz_o3col_clim_icol, linoz_PmL_clim_icol, linoz_dPmL_dO3_icol,
1044-
linoz_dPmL_dT_icol, linoz_dPmL_dO3col_icol,
1045-
linoz_cariolle_pscs_icol, eccf, adv_mass_kg_per_moles,
1068+
work_photo_table_icol,
1069+
config.linoz, linoz_data,
1070+
eccf, adv_mass_kg_per_moles,
10461071
fraction_landuse_icol, index_season, clsmap_4, permute_4,
1047-
offset_aerosol, config.linoz.o3_sfc, config.linoz.o3_tau,
1048-
config.linoz.o3_lbl, dry_diameter_icol, wet_diameter_icol,
1072+
offset_aerosol,
1073+
dry_diameter_icol, wet_diameter_icol,
10491074
wetdens_icol, dry_atm.phis(icol), cmfdqr, prain_icol, nevapr_icol,
10501075
work_set_het_icol, drydep_data, aqso4_flx_col, aqh2so4_flx_col,
10511076
diag_arrays, dvel_col, dflx_col, progs);
@@ -1090,6 +1115,7 @@ void MAMMicrophysics::run_impl(const double dt) {
10901115
// postprocess output
10911116
post_process(wet_aero_, dry_aero_, dry_atm_);
10921117
Kokkos::fence();
1118+
10931119
} // MAMMicrophysics::run_impl
10941120

10951121
} // namespace scream

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

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,7 @@ class MAMMicrophysics final : public MAMGenericInterface {
7979

8080
struct Config {
8181
// stratospheric chemistry parameters
82-
struct {
83-
int o3_lbl; // number of layers with ozone decay from the surface
84-
Real o3_sfc; // set from namelist input linoz_sfc
85-
Real o3_tau; // set from namelist input linoz_tau
86-
Real psc_T; // set from namelist input linoz_psc_T
87-
} linoz;
82+
mam4::microphysics::LinozConf linoz;
8883

8984
// aqueous chemistry parameters
9085
mam4::mo_setsox::Config setsox;
@@ -168,7 +163,7 @@ class MAMMicrophysics final : public MAMGenericInterface {
168163
for (const auto &pair : flds) {
169164
// Get the field, and add a docstring to its string attributes
170165
// This is used to document that the field contains heterogeneous
171-
// quantities, i.e., species have different units.
166+
// quantities, i.e., species have different units.
172167
auto &f = get_field_out(pair.first);
173168
auto &io_str_atts = f.get_header().get_extra_data<str_atts_t>("io: string attributes");
174169
io_str_atts["doc"] = pair.second;

0 commit comments

Comments
 (0)