From 592ae22650592764ae1324f6edf167f72894b615 Mon Sep 17 00:00:00 2001 From: "Oscar H. Diaz-Ibarra" Date: Thu, 25 Jun 2026 22:17:33 -0600 Subject: [PATCH 1/7] Using DataInterpolation for fraction_land_ise in srf and online emissions. --- ...and_online_emissions_process_interface.cpp | 49 +++++++++---------- ...and_online_emissions_process_interface.hpp | 3 +- 2 files changed, 25 insertions(+), 27 deletions(-) diff --git a/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.cpp b/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.cpp index 90b8a4fc387c..1d87507632d9 100644 --- a/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.cpp +++ b/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.cpp @@ -3,17 +3,12 @@ // For surface and online emission functions #include -// For reading soil erodibility file -#include +#include "share/algorithm/eamxx_data_interpolation.hpp" #include namespace scream { -// For reading soil erodibility file -using soilErodibilityFunc = - soil_erodibility::soilErodibilityFunctions; - // ================================================================ // Constructor // ================================================================ @@ -215,23 +210,11 @@ void MAMSrfOnlineEmiss::create_requests() { //-------------------------------------------------------------------- // ------------------------------------------------------------- - // Setup to enable reading soil erodibility file + // Setup soil erodibility output field // ------------------------------------------------------------- - - const std::string soil_erodibility_data_file = - m_params.get("soil_erodibility_file"); - - // Field to be read from file - const std::string soil_erod_fld_name = "mbl_bsn_fct_geo"; - - // Dimensions of the field - const std::string soil_erod_dname = "ncol"; - - // initialize the file read - soilErodibilityFunc::init_soil_erodibility_file_read( - ncol_, soil_erod_fld_name, soil_erod_dname, grid_, - soil_erodibility_data_file, srf_map_file, serod_horizInterp_, - serod_dataReader_); // output + soil_erodibility_field_ = + Field(FieldIdentifier("soil_erodibility", scalar2d, none, grid_name)); + soil_erodibility_field_.allocate_view(); // ------------------------------------------------------------- // Setup to enable reading marine organics file @@ -355,9 +338,25 @@ void MAMSrfOnlineEmiss::initialize_impl(const RunType run_type) { if (dust_emis_scheme == 1) { // This data is time-independent, we read all data here for the // entire simulation - soilErodibilityFunc::update_soil_erodibility_data_from_file( - serod_dataReader_, *serod_horizInterp_, - soil_erodibility_); // output + const auto soil_erodibility_data_file = + m_params.get("soil_erodibility_file"); + const auto srf_map_file = m_params.get("srf_remap_file", ""); + const std::string soil_erod_fld_name = "mbl_bsn_fct_geo"; + + std::vector soil_erod_fields = { + soil_erodibility_field_.alias(soil_erod_fld_name)}; + auto soil_erod_data_interp = + std::make_shared(grid_, soil_erod_fields); + soil_erod_data_interp->set_logger(m_atm_logger); + soil_erod_data_interp->setup_static_database({soil_erodibility_data_file}); + soil_erod_data_interp->create_horiz_remappers( + srf_map_file == "none" ? "" : srf_map_file); + DataInterpolation::VertRemapData remap_data; + remap_data.vr_type = DataInterpolation::None; + soil_erod_data_interp->create_vert_remapper(remap_data); + soil_erod_data_interp->run(); + + soil_erodibility_ = soil_erodibility_field_.get_view(); } else if (dust_emis_scheme == 2) { // For dust emission scheme 2, override soil erodibility to 1 auto soil_erod_ones = view_1d("soil_erod_ones", ncol_); diff --git a/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.hpp b/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.hpp index 3bce8d01b59e..84b38c66ca7a 100644 --- a/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.hpp +++ b/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.hpp @@ -52,8 +52,7 @@ class MAMSrfOnlineEmiss final : public MAMGenericInterface { static constexpr Real amufac = 1.65979e-23; // 1.e4* kg / amu // For reading soil erodibility file - std::shared_ptr serod_horizInterp_; - std::shared_ptr serod_dataReader_; + Field soil_erodibility_field_; const_view_1d soil_erodibility_; public: From d853378d1e6472600fba6ddd04b2d390521a08d5 Mon Sep 17 00:00:00 2001 From: "Oscar H. Diaz-Ibarra" Date: Thu, 25 Jun 2026 22:17:52 -0600 Subject: [PATCH 2/7] Using DataInterpolation for fraction_land_ise in dry deposition. --- ...x_mam_dry_deposition_process_interface.cpp | 52 +++--- ...x_mam_dry_deposition_process_interface.hpp | 6 - .../mam/readfiles/fractional_land_use.hpp | 62 -------- .../readfiles/fractional_land_use_impl.hpp | 150 ------------------ 4 files changed, 20 insertions(+), 250 deletions(-) delete mode 100644 components/eamxx/src/physics/mam/readfiles/fractional_land_use.hpp delete mode 100644 components/eamxx/src/physics/mam/readfiles/fractional_land_use_impl.hpp diff --git a/components/eamxx/src/physics/mam/eamxx_mam_dry_deposition_process_interface.cpp b/components/eamxx/src/physics/mam/eamxx_mam_dry_deposition_process_interface.cpp index 0a563a11daa9..ea8b43c8f7b5 100644 --- a/components/eamxx/src/physics/mam/eamxx_mam_dry_deposition_process_interface.cpp +++ b/components/eamxx/src/physics/mam/eamxx_mam_dry_deposition_process_interface.cpp @@ -3,15 +3,12 @@ // Drydep functions are stored in the following hpp file #include -// For reading fractional land use file -#include +#include "share/algorithm/eamxx_data_interpolation.hpp" #include namespace scream { -using FracLandUseFunc = frac_landuse::fracLandUseFunctions; - MAMDryDep::MAMDryDep(const ekat::Comm &comm, const ekat::ParameterList ¶ms) : MAMGenericInterface(comm, params) { /* Anything that can be initialized without grid information can be @@ -147,25 +144,6 @@ void MAMDryDep::create_requests() { // Fractional land use [fraction] add_field("fraction_landuse", vector2d_class, none, grid_name); - // ------------------------------------------------------------- - // setup to enable reading fractional land use file - // ------------------------------------------------------------- - - const auto mapping_file = m_params.get("drydep_remap_file", ""); - const std::string frac_landuse_data_file = - m_params.get("fractional_land_use_file"); - - // Field to be read from file - const std::string field_name = "fraction_landuse"; - - // Dimensions of the filed - const std::string dim_name1 = "ncol"; - const std::string dim_name2 = "class"; - - // initialize the file read - FracLandUseFunc::init_frac_landuse_file_read( - ncol_, field_name, dim_name1, dim_name2, grid_, frac_landuse_data_file, - mapping_file, horizInterp_, dataReader_); // output } // set_grids @@ -321,15 +299,25 @@ void MAMDryDep::initialize_impl(const RunType run_type) { //----------------------------------------------------------------- // Read fractional land use data //----------------------------------------------------------------- - frac_landuse_fm_ = get_field_out("fraction_landuse").get_view(); - // This data is time-independent, we read all data here for the - // entire simulation - FracLandUseFunc::update_frac_land_use_data_from_file( - dataReader_, *horizInterp_, - frac_landuse_); // output - - // Copy fractional landuse values to a FM array to be used by other processes - Kokkos::deep_copy(frac_landuse_fm_, frac_landuse_); + { + const auto mapping_file = m_params.get("drydep_remap_file", ""); + const auto frac_landuse_data_file = + m_params.get("fractional_land_use_file"); + std::vector frac_landuse_fields = { + get_field_out("fraction_landuse")}; + auto frac_landuse_interp = + std::make_shared(grid_, frac_landuse_fields); + frac_landuse_interp->set_logger(m_atm_logger); + frac_landuse_interp->setup_static_database({frac_landuse_data_file}); + frac_landuse_interp->create_horiz_remappers( + mapping_file == "none" ? "" : mapping_file); + DataInterpolation::VertRemapData remap_data; + remap_data.vr_type = DataInterpolation::None; + frac_landuse_interp->create_vert_remapper(remap_data); + frac_landuse_interp->run(); + + frac_landuse_ = get_field_out("fraction_landuse").get_view(); + } } // initialize_impl // ========================================================================================= diff --git a/components/eamxx/src/physics/mam/eamxx_mam_dry_deposition_process_interface.hpp b/components/eamxx/src/physics/mam/eamxx_mam_dry_deposition_process_interface.hpp index 9719638eeaf2..438ae5c21278 100644 --- a/components/eamxx/src/physics/mam/eamxx_mam_dry_deposition_process_interface.hpp +++ b/components/eamxx/src/physics/mam/eamxx_mam_dry_deposition_process_interface.hpp @@ -7,8 +7,6 @@ // For MAM4 aerosol configuration #include -#include "share/field/field_reader.hpp" - // For component name #include @@ -89,11 +87,7 @@ class MAMDryDep final : public MAMGenericInterface { // Filled with Prognostics::n_mode_c and Prognostics::q_aero_c view_3d qqcw_; - // For reading fractional land use file - std::shared_ptr horizInterp_; - std::shared_ptr dataReader_; const_view_2d frac_landuse_; - view_2d frac_landuse_fm_; // aerosol state variables mam_coupling::AerosolState wet_aero_, dry_aero_; // wet mixing ratios (water species) diff --git a/components/eamxx/src/physics/mam/readfiles/fractional_land_use.hpp b/components/eamxx/src/physics/mam/readfiles/fractional_land_use.hpp deleted file mode 100644 index b3118dd8b5a2..000000000000 --- a/components/eamxx/src/physics/mam/readfiles/fractional_land_use.hpp +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef FRACTIONAL_LANDUSE_HPP -#define FRACTIONAL_LANDUSE_HPP - -#include "share/remap/abstract_remapper.hpp" -#include "share/field/field_reader.hpp" -#include "share/core/eamxx_types.hpp" - -#include - -namespace scream { -namespace frac_landuse { - -template -struct fracLandUseFunctions { - using Device = DeviceType; - - using KT = KokkosTypes; - using const_view_2d = typename KT::template view_2d; - - // ------------------------------------------------------------------------------------------- - // ------------------------------------------------------------------------------------------- - - // Fractional land use routines - static std::shared_ptr create_horiz_remapper( - const std::shared_ptr &model_grid, - const std::string &fracLandUse_data_file, const std::string &map_file, - const std::string &field_name, const std::string &dim_name1, - const std::string &dim_name2); - - // ------------------------------------------------------------------------------------------- - // ------------------------------------------------------------------------------------------- - - static std::shared_ptr create_data_reader( - const std::shared_ptr &horiz_remapper, - const std::string &data_file); - - // ------------------------------------------------------------------------------------------- - // ------------------------------------------------------------------------------------------- - - static void update_frac_land_use_data_from_file( - std::shared_ptr &scorpio_reader, - AbstractRemapper &horiz_interp, const_view_2d &input); - - // ------------------------------------------------------------------------------------------- - // ------------------------------------------------------------------------------------------- - - static void init_frac_landuse_file_read( - const int ncol, const std::string field_name, const std::string dim_name1, - const std::string dim_name2, - const std::shared_ptr &grid, - const std::string &data_file, const std::string &mapping_file, - // output - std::shared_ptr &FracLandUseHorizInterp, - std::shared_ptr &FracLandUseDataReader); - -}; // struct fracLandUseFunctions - -} // namespace frac_landuse -} // namespace scream -#endif // FRACTIONAL_LANDUSE_HPP - -#include "fractional_land_use_impl.hpp" diff --git a/components/eamxx/src/physics/mam/readfiles/fractional_land_use_impl.hpp b/components/eamxx/src/physics/mam/readfiles/fractional_land_use_impl.hpp deleted file mode 100644 index 4338388f262f..000000000000 --- a/components/eamxx/src/physics/mam/readfiles/fractional_land_use_impl.hpp +++ /dev/null @@ -1,150 +0,0 @@ -#ifndef FRACTIONAL_LANDUSE_IMPL_HPP -#define FRACTIONAL_LANDUSE_IMPL_HPP - -#include "share/remap/identity_remapper.hpp" -#include "share/remap/horizontal_remapper.hpp" -#include "share/scorpio_interface/eamxx_scorpio_interface.hpp" -#include "share/util/eamxx_timing.hpp" - -namespace scream { -namespace frac_landuse { - -template -std::shared_ptr -fracLandUseFunctions::create_horiz_remapper( - const std::shared_ptr &model_grid, - const std::string &data_file, const std::string &map_file, - const std::string &field_name, const std::string &dim_name1, - const std::string &dim_name2) { - using namespace ShortFieldTagsNames; - - scorpio::register_file(data_file, scorpio::Read); - const int ncols_data = scorpio::get_dimlen(data_file, dim_name1); - const int nclass_data = scorpio::get_dimlen(data_file, dim_name2); - scorpio::release_file(data_file); - - // We could use model_grid directly if using same num levels, - // but since shallow clones are cheap, we may as well do it (less lines of - // code) - auto horiz_interp_tgt_grid = - model_grid->clone("frac_land_use_horiz_interp_tgt_grid", true); - - const int ncols_model = model_grid->get_num_global_dofs(); - std::shared_ptr remapper; - if(ncols_data == ncols_model) { - remapper = std::make_shared( - horiz_interp_tgt_grid, IdentityRemapper::SrcAliasTgt); - } else { - EKAT_REQUIRE_MSG(ncols_data <= ncols_model, - "Error! We do not allow to coarsen fractional land use " - "data to fit the model. We only allow\n" - " fractional land use data to be at the same or " - "coarser resolution as the model.\n"); - // We must have a valid map file - EKAT_REQUIRE_MSG(map_file != "", - "ERROR: fractional land use data is on a different grid " - "than the model one,\n" - " but remap file is missing from fractional " - "land use parameter list."); - - remapper = - std::make_shared(horiz_interp_tgt_grid, map_file); - } - - const auto tgt_grid = remapper->get_tgt_grid(); - - const auto layout_2d = tgt_grid->get_2d_vector_layout(nclass_data, "class"); - - Field fractional_land_use( - FieldIdentifier(field_name, layout_2d, ekat::units::none, tgt_grid->name())); - fractional_land_use.allocate_view(); - - remapper->register_field_from_tgt(fractional_land_use); - - remapper->registration_ends(); - - return remapper; -} // create_horiz_remapper - -// ------------------------------------------------------------------------------------------- -// ------------------------------------------------------------------------------------------- - -template -std::shared_ptr fracLandUseFunctions::create_data_reader( - const std::shared_ptr &horiz_remapper, - const std::string &data_file) { - std::vector io_fields; - for(int i = 0; i < horiz_remapper->get_num_fields(); ++i) { - io_fields.push_back(horiz_remapper->get_src_field(i)); - } - const auto io_grid = horiz_remapper->get_src_grid(); - auto gids = io_grid->get_partitioned_dim_gids(); - auto comm = io_grid->get_comm(); - auto reader = std::make_shared(); - reader->set_file_specs(data_file); - reader->set_dim_decomp(gids, comm); - reader->set_fields(io_fields); - return reader; -} // create_data_reader - -// ------------------------------------------------------------------------------------------- -// ------------------------------------------------------------------------------------------- - -template -void fracLandUseFunctions::update_frac_land_use_data_from_file( - std::shared_ptr &reader, - AbstractRemapper &horiz_interp, const_view_2d &input) { - start_timer("EAMxx::FracLandUse::update_frac_land_use_data_from_file"); - - // 1. Read from file - start_timer( - "EAMxx::FracLandUse::update_frac_land_use_data_from_file::read_data"); - reader->read(); - stop_timer( - "EAMxx::FracLandUse::update_frac_land_use_data_from_file::read_data"); - - // 2. Run the horiz remapper (it is a do-nothing op if FracLandUse data is on - // same grid as model) - start_timer( - "EAMxx::FracLandUse::update_frac_land_use_data_from_file::horiz_remap"); - horiz_interp.remap_fwd(); - stop_timer( - "EAMxx::FracLandUse::update_frac_land_use_data_from_file::horiz_remap"); - - // 3. Get the tgt field of the remapper - start_timer( - "EAMxx::FracLandUse::update_frac_land_use_data_from_file::get_field"); - // Recall, the fields are registered in the order: - // Read the field from the file - input = horiz_interp.get_tgt_field(0).get_view(); - stop_timer( - "EAMxx::FracLandUse::update_frac_land_use_data_from_file::get_field"); - - stop_timer("EAMxx::FracLandUse::update_frac_land_use_data_from_file"); - -} // END update_frac_landuse_data_from_file - -// ------------------------------------------------------------------------------------------- -// ------------------------------------------------------------------------------------------- - -template -void fracLandUseFunctions::init_frac_landuse_file_read( - const int ncol, const std::string field_name, const std::string dim_name1, - const std::string dim_name2, - const std::shared_ptr &grid, - const std::string &data_file, const std::string &mapping_file, - // output - std::shared_ptr &FracLandUseHorizInterp, - std::shared_ptr &FracLandUseDataReader) { - // Init horizontal remap - FracLandUseHorizInterp = create_horiz_remapper( - grid, data_file, mapping_file, field_name, dim_name1, dim_name2); - - // Create reader (an FieldReader object) - FracLandUseDataReader = create_data_reader(FracLandUseHorizInterp, data_file); -} // init_frac_landuse_file_read - -} // namespace frac_landuse -} // namespace scream - -#endif // FRACTIONAL_LANDUSE_IMPL_HPP From 0af6dd0592234130b4a3a8f1a1a2618ebcb7ca5e Mon Sep 17 00:00:00 2001 From: "Oscar H. Diaz-Ibarra" Date: Thu, 25 Jun 2026 22:35:35 -0600 Subject: [PATCH 3/7] Using DataInterpolation for marine organics and soild erodibility. --- ...and_online_emissions_process_interface.cpp | 68 ++-- ...and_online_emissions_process_interface.hpp | 14 +- .../physics/mam/readfiles/marine_organics.hpp | 136 -------- .../mam/readfiles/marine_organics_impl.hpp | 295 ------------------ .../mam/readfiles/soil_erodibility.hpp | 47 --- .../mam/readfiles/soil_erodibility_impl.hpp | 147 --------- 6 files changed, 33 insertions(+), 674 deletions(-) delete mode 100644 components/eamxx/src/physics/mam/readfiles/marine_organics.hpp delete mode 100644 components/eamxx/src/physics/mam/readfiles/marine_organics_impl.hpp delete mode 100644 components/eamxx/src/physics/mam/readfiles/soil_erodibility.hpp delete mode 100644 components/eamxx/src/physics/mam/readfiles/soil_erodibility_impl.hpp diff --git a/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.cpp b/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.cpp index 1d87507632d9..59c34dc106f7 100644 --- a/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.cpp +++ b/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.cpp @@ -101,7 +101,10 @@ void MAMSrfOnlineEmiss::create_requests() { // Constituent fluxes of species in [kg/m2/s] // FIXME: confirm if it is Updated or Computed add_field("constituent_fluxes", vector2d_pcnst, kg / m2 / s, - grid_name); + grid_name); + + // Soil erodibility [fraction] + add_field("soil_erodibility", scalar2d, none, grid_name); // Surface emissions remapping file auto srf_map_file = m_params.get("srf_remap_file", ""); @@ -209,34 +212,35 @@ void MAMSrfOnlineEmiss::create_requests() { // DataInterpolation is set up in initialize_impl. //-------------------------------------------------------------------- - // ------------------------------------------------------------- - // Setup soil erodibility output field - // ------------------------------------------------------------- - soil_erodibility_field_ = - Field(FieldIdentifier("soil_erodibility", scalar2d, none, grid_name)); - soil_erodibility_field_.allocate_view(); - // ------------------------------------------------------------- // Setup to enable reading marine organics file // ------------------------------------------------------------- const std::string marine_organics_data_file = m_params.get("marine_organics_file"); + const auto marine_map_file = m_params.get("srf_remap_file", ""); // Fields to be read from file (order matters as they are read in the same // order) const std::vector marine_org_fld_name = { "TRUEPOLYC", "TRUEPROTC", "TRUELIPC"}; + for (const auto &field_name : marine_org_fld_name) { + add_field("morg_" + field_name, scalar2d, none, grid_name); + } + morg_fields_.clear(); + morg_fields_.reserve(marine_org_fld_name.size()); + for (const auto &field_name : marine_org_fld_name) { + morg_fields_.push_back( + get_field_out("morg_" + field_name).alias(field_name)); + } - // Dimensions of the field - const std::string marine_org_dname = "ncol"; - - // initialize the file read - marineOrganicsFunc::init_marine_organics_file_read( - ncol_, marine_org_fld_name, marine_org_dname, grid_, - marine_organics_data_file, srf_map_file, - // output - morg_horizInterp_, morg_data_start_, morg_data_end_, morg_data_out_, - morg_dataReader_); + morg_data_interp_ = std::make_shared(grid_, morg_fields_); + morg_data_interp_->set_logger(m_atm_logger); + morg_data_interp_->setup_periodic_time_database({marine_organics_data_file}); + morg_data_interp_->create_horiz_remappers( + marine_map_file == "none" ? "" : marine_map_file); + DataInterpolation::VertRemapData remap_data; + remap_data.vr_type = DataInterpolation::None; + morg_data_interp_->create_vert_remapper(remap_data); } // set_grid ends @@ -344,7 +348,7 @@ void MAMSrfOnlineEmiss::initialize_impl(const RunType run_type) { const std::string soil_erod_fld_name = "mbl_bsn_fct_geo"; std::vector soil_erod_fields = { - soil_erodibility_field_.alias(soil_erod_fld_name)}; + get_field_out("soil_erodibility").alias(soil_erod_fld_name)}; auto soil_erod_data_interp = std::make_shared(grid_, soil_erod_fields); soil_erod_data_interp->set_logger(m_atm_logger); @@ -367,10 +371,8 @@ void MAMSrfOnlineEmiss::initialize_impl(const RunType run_type) { //-------------------------------------------------------------------- // Update marine orgaincs from file //-------------------------------------------------------------------- - // Time dependent data - marineOrganicsFunc::update_marine_organics_data_from_file( - morg_dataReader_, start_of_step_ts(), curr_month, *morg_horizInterp_, - morg_data_end_); // output + morg_data_interp_->init_time_interpolation(start_of_step_ts(), + DataInterpolation::Linear); //----------------------------------------------------------------- // Setup preprocessing and post processing @@ -405,24 +407,12 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { //-------------------------------------------------------------------- // --- Interpolate marine organics data -- - - // Update TimeState, note the addition of dt - morg_timeState_.t_now = ts.frac_of_year_in_days(); - - // Update time state and if the month has changed, update the data. - marineOrganicsFunc::update_marine_organics_timestate( - morg_dataReader_, ts, *morg_horizInterp_, - // output - morg_timeState_, morg_data_start_, morg_data_end_); - - // Call the main marine organics routine to get interpolated forcings. - marineOrganicsFunc::marineOrganics_main(morg_timeState_, morg_data_start_, - morg_data_end_, morg_data_out_); + morg_data_interp_->run(ts); // Marine organics emission data read from the file (order is important here) - const const_view_1d mpoly = ekat::subview(morg_data_out_.emiss_sectors, 0); - const const_view_1d mprot = ekat::subview(morg_data_out_.emiss_sectors, 1); - const const_view_1d mlip = ekat::subview(morg_data_out_.emiss_sectors, 2); + const const_view_1d mpoly = morg_fields_[0].get_view(); + const const_view_1d mprot = morg_fields_[1].get_view(); + const const_view_1d mlip = morg_fields_[2].get_view(); // Ocean fraction [unitless] const const_view_1d ocnfrac = diff --git a/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.hpp b/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.hpp index 84b38c66ca7a..b111b0c3db36 100644 --- a/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.hpp +++ b/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.hpp @@ -51,14 +51,11 @@ class MAMSrfOnlineEmiss final : public MAMGenericInterface { // Unified atomic mass unit used for unit conversion (BAD constant) static constexpr Real amufac = 1.65979e-23; // 1.e4* kg / amu - // For reading soil erodibility file - Field soil_erodibility_field_; const_view_1d soil_erodibility_; public: - // For reading surface emissions and marine organics file - using marineOrganicsFunc = - marine_organics::marineOrganicsFunctions; + // For reading surface emissions file + using srfEmissFunc = mam_coupling::srfEmissFunctions; // Constructor MAMSrfOnlineEmiss(const ekat::Comm &comm, const ekat::ParameterList ¶ms); @@ -157,11 +154,8 @@ class MAMSrfOnlineEmiss final : public MAMGenericInterface { std::vector srf_emiss_species_; // For reading marine organics file - std::shared_ptr morg_horizInterp_; - std::shared_ptr morg_dataReader_; - marineOrganicsFunc::marineOrganicsTimeState morg_timeState_; - marineOrganicsFunc::marineOrganicsInput morg_data_start_, morg_data_end_; - marineOrganicsFunc::marineOrganicsOutput morg_data_out_; + std::shared_ptr morg_data_interp_; + std::vector morg_fields_; // offset for converting pcnst index to gas_pcnst index static constexpr int offset_ = diff --git a/components/eamxx/src/physics/mam/readfiles/marine_organics.hpp b/components/eamxx/src/physics/mam/readfiles/marine_organics.hpp deleted file mode 100644 index 788e979aac0e..000000000000 --- a/components/eamxx/src/physics/mam/readfiles/marine_organics.hpp +++ /dev/null @@ -1,136 +0,0 @@ -#ifndef MARINE_ORGANICS_HPP -#define MARINE_ORGANICS_HPP - -#include "share/remap/abstract_remapper.hpp" -#include "share/field/field_reader.hpp" -#include "share/core/eamxx_types.hpp" - -#include - -namespace scream { -namespace marine_organics { - -template -struct marineOrganicsFunctions { - using Device = DeviceType; - - using KT = KokkosTypes; - using MemberType = typename KT::MemberType; - using view_2d = typename KT::template view_2d; - - // ------------------------------------------------------------------------------------------- - struct marineOrganicsTimeState { - marineOrganicsTimeState() = default; - // Whether the timestate has been initialized. - // The current month - int current_month = -1; - // Julian Date for the beginning of the month, as defined in - // /src/share/util/eamxx_time_stamp.hpp - // See this file for definition of Julian Date. - Real t_beg_month; - // Current simulation Julian Date - Real t_now; - // Number of days in the current month, cast as a Real - Real days_this_month; - }; // marineOrganicsTimeState - - struct marineOrganicsData { - marineOrganicsData() = default; - marineOrganicsData(const int &ncol_, const int &nfields_) - : ncols(ncol_), nsectors(nfields_) { - init(ncols, nsectors, true); - } - - void init(const int &ncol, const int &nsector, const bool allocate) { - ncols = ncol; - nsectors = nsector; - if(allocate) emiss_sectors = view_2d("morgAllSectors", nsectors, ncols); - } // marineOrganicsData init - - // Basic spatial dimensions of the data - int ncols, nsectors; - view_2d emiss_sectors; - }; // marineOrganicsData - - // ------------------------------------------------------------------------------------------- - struct marineOrganicsInput { - marineOrganicsInput() = default; - marineOrganicsInput(const int &ncols_, const int &nfields_) { - init(ncols_, nfields_); - } - - void init(const int &ncols_, const int &nfields_) { - data.init(ncols_, nfields_, true); - } - marineOrganicsData data; // All marineOrganics fields - }; // marineOrganicsInput - - // The output is really just marineOrganicsData, but for clarity it might - // help to see a marineOrganicsOutput along a marineOrganicsInput in functions - // signatures - using marineOrganicsOutput = marineOrganicsData; - - // ------------------------------------------------------------------------------------------- - static std::shared_ptr create_horiz_remapper( - const std::shared_ptr &model_grid, - const std::string &marineOrganics_data_file, const std::string &map_file, - const std::vector &field_name, const std::string &dim_name1); - - // ------------------------------------------------------------------------------------------- - static std::shared_ptr create_data_reader( - const std::shared_ptr &horiz_remapper, - const std::string &data_file); - - // ------------------------------------------------------------------------------------------- - static void update_marine_organics_data_from_file( - std::shared_ptr &reader, - const util::TimeStamp &ts, - const int &time_index, // zero-based - AbstractRemapper &horiz_interp, - marineOrganicsInput &marineOrganics_input); - - // ------------------------------------------------------------------------------------------- - static void update_marine_organics_timestate( - std::shared_ptr &reader, - const util::TimeStamp &ts, AbstractRemapper &horiz_interp, - marineOrganicsTimeState &time_state, marineOrganicsInput &beg, - marineOrganicsInput &end); - - // ------------------------------------------------------------------------------------------- - static void marineOrganics_main(const marineOrganicsTimeState &time_state, - const marineOrganicsInput &data_beg, - const marineOrganicsInput &data_end, - const marineOrganicsOutput &data_out); - - // ------------------------------------------------------------------------------------------- - static void perform_time_interpolation( - const marineOrganicsTimeState &time_state, - const marineOrganicsInput &data_beg, const marineOrganicsInput &data_end, - const marineOrganicsOutput &data_out); - - // ------------------------------------------------------------------------------------------- - // Performs convex interpolation of x0 and x1 at point t - template - KOKKOS_INLINE_FUNCTION static ScalarX linear_interp(const ScalarX &x0, - const ScalarX &x1, - const ScalarT &t); - - // ------------------------------------------------------------------------------------------- - static void init_marine_organics_file_read( - const int &ncol, const std::vector &field_name, - const std::string &dim_name1, - const std::shared_ptr &grid, - const std::string &data_file, const std::string &mapping_file, - // output - std::shared_ptr &marineOrganicsHorizInterp, - marineOrganicsInput &morg_data_start_, - marineOrganicsInput &morg_data_end_, marineOrganicsData &morg_data_out_, - std::shared_ptr &marineOrganicsDataReader); - -}; // struct marineOrganicsFunctions - -} // namespace marine_organics -} // namespace scream -#endif // MARINE_ORGANICS_HPP - -#include "marine_organics_impl.hpp" diff --git a/components/eamxx/src/physics/mam/readfiles/marine_organics_impl.hpp b/components/eamxx/src/physics/mam/readfiles/marine_organics_impl.hpp deleted file mode 100644 index 56a32892bfb3..000000000000 --- a/components/eamxx/src/physics/mam/readfiles/marine_organics_impl.hpp +++ /dev/null @@ -1,295 +0,0 @@ -#ifndef MARINE_ORGANICS_IMPL_HPP -#define MARINE_ORGANICS_IMPL_HPP - -#include "share/remap/identity_remapper.hpp" -#include "share/remap/horizontal_remapper.hpp" -#include "share/scorpio_interface/eamxx_scorpio_interface.hpp" -#include "share/util/eamxx_timing.hpp" - -#include - -namespace scream { -namespace marine_organics { - -template -std::shared_ptr -marineOrganicsFunctions::create_horiz_remapper( - const std::shared_ptr &model_grid, - const std::string &data_file, const std::string &map_file, - const std::vector &field_name, const std::string &dim_name1) { - using namespace ShortFieldTagsNames; - - const int ncols_data = scorpio::get_dimlen(data_file, dim_name1); - - // Since shallow clones are cheap, we may as well do it (less lines of - // code) - auto horiz_interp_tgt_grid = - model_grid->clone("marine_organics_horiz_interp_tgt_grid", true); - - const int ncols_model = model_grid->get_num_global_dofs(); - std::shared_ptr remapper; - if(ncols_data == ncols_model) { - remapper = std::make_shared( - horiz_interp_tgt_grid, IdentityRemapper::SrcAliasTgt); - } else { - EKAT_REQUIRE_MSG(ncols_data <= ncols_model, - "Error! We do not allow to coarsen marine organics " - "data to fit the model. We only allow\n" - " marine organics data to be at the same or " - "coarser resolution as the model.\n"); - // We must have a valid map file - EKAT_REQUIRE_MSG(map_file != "", - "ERROR: marine organics data is on a different grid " - "than the model one,\n" - " but remap file is missing from marine organics " - "parameter list."); - - remapper = - std::make_shared(horiz_interp_tgt_grid, map_file); - } - - const auto tgt_grid = remapper->get_tgt_grid(); - - const auto layout_2d = tgt_grid->get_2d_scalar_layout(); - using namespace ekat::units; - using namespace ekat::prefixes; - Units umolC(micro * mol, "umol C"); - - std::vector fields_vector; - - const int field_size = field_name.size(); - for(int icomp = 0; icomp < field_size; ++icomp) { - auto comp_name = field_name[icomp]; - // set and allocate fields - Field f(FieldIdentifier(comp_name, layout_2d, umolC, tgt_grid->name())); - f.allocate_view(); - fields_vector.push_back(f); - remapper->register_field_from_tgt(f); - } - - remapper->registration_ends(); - - return remapper; - -} // create_horiz_remapper - -// ------------------------------------------------------------------------------------------- -template -std::shared_ptr -marineOrganicsFunctions::create_data_reader( - const std::shared_ptr &horiz_remapper, - const std::string &data_file) { - std::vector io_fields; - for(int ifld = 0; ifld < horiz_remapper->get_num_fields(); ++ifld) { - io_fields.push_back(horiz_remapper->get_src_field(ifld)); - } - const auto io_grid = horiz_remapper->get_src_grid(); - auto gids = io_grid->get_partitioned_dim_gids(); - auto comm = io_grid->get_comm(); - auto reader = std::make_shared(); - reader->set_file_specs(data_file); - reader->set_dim_decomp(gids, comm); - reader->set_fields(io_fields); - return reader; -} // create_data_reader - -// ------------------------------------------------------------------------------------------- -template -void marineOrganicsFunctions::update_marine_organics_data_from_file( - std::shared_ptr &reader, const util::TimeStamp &ts, - const int &time_index, // zero-based - AbstractRemapper &horiz_interp, marineOrganicsInput &marineOrganics_input) { - start_timer("EAMxx::marineOrganics::update_marine_organics_data_from_file"); - - // 1. Read from file - start_timer( - "EAMxx::marineOrganics::update_marine_organics_data_from_file::read_" - "data"); - reader->read(); - stop_timer( - "EAMxx::marineOrganics::update_marine_organics_data_from_file::read_" - "data"); - - // 2. Run the horiz remapper (it is a do-nothing op if marineOrganics data is - // on same grid as model) - start_timer( - "EAMxx::marineOrganics::update_marine_organics_data_from_file::horiz_" - "remap"); - horiz_interp.remap_fwd(); - stop_timer( - "EAMxx::marineOrganics::update_marine_organics_data_from_file::horiz_" - "remap"); - - // 3. Get the tgt field of the remapper - start_timer( - "EAMxx::marineOrganics::update_marine_organics_data_from_file::get_" - "field"); - // Recall, the fields are registered in the order: - // Read the field from the file - - for(int ifld = 0; ifld < horiz_interp.get_num_fields(); ++ifld) { - auto sector = horiz_interp.get_tgt_field(ifld).get_view(); - const auto emiss = Kokkos::subview(marineOrganics_input.data.emiss_sectors, - ifld, Kokkos::ALL()); - Kokkos::deep_copy(emiss, sector); - } - - Kokkos::fence(); - - stop_timer( - "EAMxx::marineOrganics::update_marine_organics_data_from_file::get_" - "field"); - - stop_timer("EAMxx::marineOrganics::update_marine_organics_data_from_file"); - -} // END update_marine_organics_data_from_file - -// ------------------------------------------------------------------------------------------- -template -void marineOrganicsFunctions::update_marine_organics_timestate( - std::shared_ptr &reader, const util::TimeStamp &ts, - AbstractRemapper &horiz_interp, marineOrganicsTimeState &time_state, - marineOrganicsInput &beg, marineOrganicsInput &end) { - // Now we check if we have to update the data that changes monthly - // NOTE: This means that marineOrganics assumes monthly data to update. Not - // any other frequency. - const auto month = ts.get_month() - 1; // Make it 0-based - if(month != time_state.current_month) { - // Update the marineOrganics time state information - time_state.current_month = month; - time_state.t_beg_month = ts.curr_month_beg().frac_of_year_in_days(); - time_state.days_this_month = ts.days_in_curr_month(); - - // Copy end'data into beg'data, and read in the new - // end - std::swap(beg, end); - - // Update the marineOrganics forcing data for this month and next month - // Start by copying next months data to this months data structure. - // NOTE: If the timestep is bigger than monthly this could cause the wrong - // values - // to be assigned. A timestep greater than a month is very unlikely - // so we will proceed. - int next_month = (time_state.current_month + 1) % 12; - update_marine_organics_data_from_file(reader, ts, next_month, - horiz_interp, end); - } - -} // END updata_marine_organics_timestate - -// ------------------------------------------------------------------------------------------- -template -template -KOKKOS_INLINE_FUNCTION ScalarX marineOrganicsFunctions::linear_interp( - const ScalarX &x0, const ScalarX &x1, const ScalarT &t) { - return (1 - t) * x0 + t * x1; -} // linear_interp - -// ------------------------------------------------------------------------------------------- -template -void marineOrganicsFunctions::perform_time_interpolation( - const marineOrganicsTimeState &time_state, - const marineOrganicsInput &data_beg, const marineOrganicsInput &data_end, - const marineOrganicsOutput &data_out) { - using ExeSpace = typename KT::ExeSpace; - using TPF = ekat::TeamPolicyFactory; - - // Gather time stamp info - auto &t_now = time_state.t_now; - auto &t_beg = time_state.t_beg_month; - auto &delta_t = time_state.days_this_month; - - // At this stage, begin/end must have the same dimensions - EKAT_REQUIRE(data_end.data.ncols == data_beg.data.ncols); - - auto delta_t_fraction = (t_now - t_beg) / delta_t; - - EKAT_REQUIRE_MSG(delta_t_fraction >= 0 && delta_t_fraction <= 1, - "Error! Convex interpolation with coefficient out of " - "[0,1].\n t_now : " + - std::to_string(t_now) + - "\n" - " t_beg : " + - std::to_string(t_beg) + - "\n delta_t: " + std::to_string(delta_t) + "\n"); - - const int nsectors = data_beg.data.nsectors; - const int ncols = data_beg.data.ncols; - const auto policy = TPF::get_default_team_policy(ncols, nsectors); - - Kokkos::parallel_for( - policy, KOKKOS_LAMBDA(const MemberType &team) { - const int icol = team.league_rank(); // column index - Kokkos::parallel_for( - Kokkos::TeamVectorRange(team, 0u, nsectors), [&](int isec) { - const auto beg = data_beg.data.emiss_sectors(isec, icol); - const auto end = data_end.data.emiss_sectors(isec, icol); - data_out.emiss_sectors(isec, icol) = - linear_interp(beg, end, delta_t_fraction); - }); - }); - Kokkos::fence(); - -} // perform_time_interpolation - -// ------------------------------------------------------------------------------------------- -template -void marineOrganicsFunctions::marineOrganics_main( - const marineOrganicsTimeState &time_state, - const marineOrganicsInput &data_beg, const marineOrganicsInput &data_end, - const marineOrganicsOutput &data_out) { - // Beg/End/Tmp month must have all sizes matching - - EKAT_REQUIRE_MSG( - data_end.data.ncols == data_beg.data.ncols, - "Error! marineOrganicsInput data structs must have the same number of " - "columns.\n"); - - // Horiz interpolation can be expensive, and does not depend on the particular - // time of the month, so it can be done ONCE per month, *outside* - // marineOrganics_main (when updating the beg/end states, reading them from - // file). - EKAT_REQUIRE_MSG(data_end.data.ncols == data_out.ncols, - "Error! Horizontal interpolation is performed *before* " - "calling marineOrganics_main,\n" - " marineOrganicsInput and marineOrganicsOutput data " - "structs must have the " - "same number columns " - << data_end.data.ncols << " " << data_out.ncols - << ".\n"); - - // Step 1. Perform time interpolation - perform_time_interpolation(time_state, data_beg, data_end, data_out); -} // marineOrganics_main - -// ------------------------------------------------------------------------------------------- -template -void marineOrganicsFunctions::init_marine_organics_file_read( - const int &ncol, const std::vector &field_name, - const std::string &dim_name1, - const std::shared_ptr &grid, - const std::string &data_file, const std::string &mapping_file, - // output - std::shared_ptr &marineOrganicsHorizInterp, - marineOrganicsInput &data_start_, marineOrganicsInput &data_end_, - marineOrganicsData &data_out_, - std::shared_ptr &marineOrganicsDataReader) { - // Init horizontal remap - - marineOrganicsHorizInterp = create_horiz_remapper( - grid, data_file, mapping_file, field_name, dim_name1); - - // Initialize the size of start/end/out data structures - data_start_ = marineOrganicsInput(ncol, field_name.size()); - data_end_ = marineOrganicsInput(ncol, field_name.size()); - data_out_.init(ncol, field_name.size(), true); - - // Create reader (an FieldReader object) - marineOrganicsDataReader = - create_data_reader(marineOrganicsHorizInterp, data_file); - -} // init_marine_organics_file_read -} // namespace marine_organics -} // namespace scream - -#endif // MARINE_ORGANICS_IMPL_HPP diff --git a/components/eamxx/src/physics/mam/readfiles/soil_erodibility.hpp b/components/eamxx/src/physics/mam/readfiles/soil_erodibility.hpp deleted file mode 100644 index 251522cf2278..000000000000 --- a/components/eamxx/src/physics/mam/readfiles/soil_erodibility.hpp +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef SOIL_ERODIBILITY_HPP -#define SOIL_ERODIBILITY_HPP - -#include "share/remap/abstract_remapper.hpp" -#include "share/field/field_reader.hpp" -#include "share/core/eamxx_types.hpp" - -#include - -namespace scream { -namespace soil_erodibility { - -template -struct soilErodibilityFunctions { - using Device = DeviceType; - - using KT = KokkosTypes; - using const_view_1d = typename KT::template view_1d; - - static std::shared_ptr create_horiz_remapper( - const std::shared_ptr &model_grid, - const std::string &soilErodibility_data_file, const std::string &map_file, - const std::string &field_name, const std::string &dim_name1); - - static std::shared_ptr create_data_reader( - const std::shared_ptr &horiz_remapper, - const std::string &data_file); - - static void update_soil_erodibility_data_from_file( - std::shared_ptr &reader, - AbstractRemapper &horiz_interp, const_view_1d &input); - - static void init_soil_erodibility_file_read( - const int ncol, const std::string field_name, const std::string dim_name1, - const std::shared_ptr &grid, - const std::string &data_file, const std::string &mapping_file, - // output - std::shared_ptr &SoilErodibilityHorizInterp, - std::shared_ptr &SoilErodibilityDataReader); - -}; // struct soilErodilityFunctions - -} // namespace soil_erodibility -} // namespace scream -#endif // SOIL_ERODIBILITY_HPP - -#include "soil_erodibility_impl.hpp" diff --git a/components/eamxx/src/physics/mam/readfiles/soil_erodibility_impl.hpp b/components/eamxx/src/physics/mam/readfiles/soil_erodibility_impl.hpp deleted file mode 100644 index 60355959f4e0..000000000000 --- a/components/eamxx/src/physics/mam/readfiles/soil_erodibility_impl.hpp +++ /dev/null @@ -1,147 +0,0 @@ -#ifndef SOIL_ERODIBILITY_IMPL_HPP -#define SOIL_ERODIBILITY_IMPL_HPP - -#include "share/remap/identity_remapper.hpp" -#include "share/remap/horizontal_remapper.hpp" -#include "share/scorpio_interface/eamxx_scorpio_interface.hpp" -#include "share/util/eamxx_timing.hpp" - -namespace scream { -namespace soil_erodibility { - -template -std::shared_ptr -soilErodibilityFunctions::create_horiz_remapper( - const std::shared_ptr &model_grid, - const std::string &data_file, const std::string &map_file, - const std::string &field_name, const std::string &dim_name1) { - using namespace ShortFieldTagsNames; - - const int ncols_data = scorpio::get_dimlen(data_file, dim_name1); - - // We could use model_grid directly if using same num levels, - // but since shallow clones are cheap, we may as well do it (less lines of - // code) - auto horiz_interp_tgt_grid = - model_grid->clone("soil_erodibility_horiz_interp_tgt_grid", true); - - const int ncols_model = model_grid->get_num_global_dofs(); - std::shared_ptr remapper; - if(ncols_data == ncols_model) { - remapper = std::make_shared( - horiz_interp_tgt_grid, IdentityRemapper::SrcAliasTgt); - } else { - EKAT_REQUIRE_MSG(ncols_data <= ncols_model, - "Error! We do not allow to coarsen soil erodibility " - "data to fit the model. We only allow\n" - " soil erodibility data to be at the same or " - "coarser resolution as the model.\n"); - // We must have a valid map file - EKAT_REQUIRE_MSG(map_file != "", - "ERROR: soil erodibility data is on a different grid " - "than the model one,\n" - " but remap file is missing from soil erodibility " - "parameter list."); - - remapper = - std::make_shared(horiz_interp_tgt_grid, map_file); - } - - const auto tgt_grid = remapper->get_tgt_grid(); - - const auto layout_2d = tgt_grid->get_2d_scalar_layout(); - - Field soil_erodibility( - FieldIdentifier(field_name, layout_2d, ekat::units::none, tgt_grid->name())); - soil_erodibility.allocate_view(); - - remapper->register_field_from_tgt(soil_erodibility); - - remapper->registration_ends(); - - return remapper; - -} // create_horiz_remapper - -// ------------------------------------------------------------------------------------------- -template -std::shared_ptr -soilErodibilityFunctions::create_data_reader( - const std::shared_ptr &horiz_remapper, - const std::string &data_file) { - std::vector io_fields; - for(int i = 0; i < horiz_remapper->get_num_fields(); ++i) { - io_fields.push_back(horiz_remapper->get_src_field(i)); - } - const auto io_grid = horiz_remapper->get_src_grid(); - auto gids = io_grid->get_partitioned_dim_gids(); - auto comm = io_grid->get_comm(); - auto reader = std::make_shared(); - reader->set_file_specs(data_file); - reader->set_dim_decomp(gids, comm); - reader->set_fields(io_fields); - return reader; -} // create_data_reader - -// ------------------------------------------------------------------------------------------- -template -void soilErodibilityFunctions::update_soil_erodibility_data_from_file( - std::shared_ptr &reader, - AbstractRemapper &horiz_interp, const_view_1d &input) { - start_timer("EAMxx::soilErodibility::update_soil_erodibility_data_from_file"); - - // 1. Read from file - start_timer( - "EAMxx::soilErodibility::update_soil_erodibility_data_from_file::read_" - "data"); - reader->read(); - stop_timer( - "EAMxx::soilErodibility::update_soil_erodibility_data_from_file::read_" - "data"); - - // 2. Run the horiz remapper (it is a do-nothing op if soilErodibility data is - // on same grid as model) - start_timer( - "EAMxx::soilErodibility::update_soil_erodibility_data_from_file::horiz_" - "remap"); - horiz_interp.remap_fwd(); - stop_timer( - "EAMxx::soilErodibility::update_soil_erodibility_data_from_file::horiz_" - "remap"); - - // 3. Get the tgt field of the remapper - start_timer( - "EAMxx::soilErodibility::update_soil_erodibility_data_from_file::get_" - "field"); - // Recall, the fields are registered in the order: - // Read the field from the file - input = horiz_interp.get_tgt_field(0).get_view(); - stop_timer( - "EAMxx::soilErodibility::update_soil_erodibility_data_from_file::get_" - "field"); - - stop_timer("EAMxx::soilErodibility::update_soil_erodibility_data_from_file"); - -} // END update_soil_erodibility_data_from_file - -// ------------------------------------------------------------------------------------------- -template -void soilErodibilityFunctions::init_soil_erodibility_file_read( - const int ncol, const std::string field_name, const std::string dim_name1, - const std::shared_ptr &grid, - const std::string &data_file, const std::string &mapping_file, - // output - std::shared_ptr &soilErodibilityHorizInterp, - std::shared_ptr &soilErodibilityDataReader) { - // Init horizontal remap - soilErodibilityHorizInterp = create_horiz_remapper( - grid, data_file, mapping_file, field_name, dim_name1); - - // Create reader (an FieldReader object) - soilErodibilityDataReader = - create_data_reader(soilErodibilityHorizInterp, data_file); -} // init_soil_erodibility_file_read -} // namespace soil_erodibility -} // namespace scream - -#endif // SOIL_ERODIBILITY_IMPL_HPP From dcac28cb784a19cd6dd71cc084ff5fe1b7e871d0 Mon Sep 17 00:00:00 2001 From: "Oscar H. Diaz-Ibarra" Date: Thu, 25 Jun 2026 23:05:18 -0600 Subject: [PATCH 4/7] Fixing rebasing issues and updating nc files. --- ...and_online_emissions_process_interface.cpp | 95 +++++++++++++++---- ...and_online_emissions_process_interface.hpp | 7 -- .../input.yaml | 3 +- .../mam/emissions/CMakeLists.txt | 2 +- .../single-process/mam/emissions/input.yaml | 3 +- 5 files changed, 79 insertions(+), 31 deletions(-) diff --git a/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.cpp b/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.cpp index 59c34dc106f7..4ad0ebee020b 100644 --- a/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.cpp +++ b/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.cpp @@ -6,6 +6,7 @@ #include "share/algorithm/eamxx_data_interpolation.hpp" #include +#include namespace scream { @@ -211,13 +212,10 @@ void MAMSrfOnlineEmiss::create_requests() { // Register sector fields in FM for surface emissions. // DataInterpolation is set up in initialize_impl. //-------------------------------------------------------------------- - // ------------------------------------------------------------- // Setup to enable reading marine organics file // ------------------------------------------------------------- - const std::string marine_organics_data_file = - m_params.get("marine_organics_file"); - const auto marine_map_file = m_params.get("srf_remap_file", ""); + // Fields to be read from file (order matters as they are read in the same // order) @@ -226,21 +224,7 @@ void MAMSrfOnlineEmiss::create_requests() { for (const auto &field_name : marine_org_fld_name) { add_field("morg_" + field_name, scalar2d, none, grid_name); } - morg_fields_.clear(); - morg_fields_.reserve(marine_org_fld_name.size()); - for (const auto &field_name : marine_org_fld_name) { - morg_fields_.push_back( - get_field_out("morg_" + field_name).alias(field_name)); - } - morg_data_interp_ = std::make_shared(grid_, morg_fields_); - morg_data_interp_->set_logger(m_atm_logger); - morg_data_interp_->setup_periodic_time_database({marine_organics_data_file}); - morg_data_interp_->create_horiz_remappers( - marine_map_file == "none" ? "" : marine_map_file); - DataInterpolation::VertRemapData remap_data; - remap_data.vr_type = DataInterpolation::None; - morg_data_interp_->create_vert_remapper(remap_data); } // set_grid ends @@ -299,6 +283,49 @@ void MAMSrfOnlineEmiss::initialize_impl(const RunType run_type) { // Constituent fluxes of species in [kg/m2/s] constituent_fluxes_ = get_field_out("constituent_fluxes"); + const std::string marine_organics_data_file = + m_params.get("marine_organics_file"); + const auto marine_map_file = m_params.get("srf_remap_file", ""); + + std::cout << "MAMSrfOnlineEmiss: get_field_out marine_organics_data_files " + << std::endl; + const std::vector marine_org_fld_name = { + "TRUEPOLYC", "TRUEPROTC", "TRUELIPC"}; + morg_fields_={}; + morg_fields_.reserve(marine_org_fld_name.size()); + for (const auto &field_name : marine_org_fld_name) { + morg_fields_.push_back( + get_field_out("morg_" + field_name).alias(field_name)); + } + + std::cout << "MAMSrfOnlineEmiss: before DataInterpolation ctor for marine organics" + << std::endl; + morg_data_interp_ = std::make_shared(grid_, morg_fields_); + std::cout << "MAMSrfOnlineEmiss: after DataInterpolation ctor for marine organics" + << std::endl; + std::cout << "MAMSrfOnlineEmiss: before set_logger (marine organics)" + << std::endl; + morg_data_interp_->set_logger(m_atm_logger); + std::cout << "MAMSrfOnlineEmiss: after set_logger (marine organics)" + << std::endl; + std::cout << "MAMSrfOnlineEmiss: before setup_periodic_time_database (marine organics)" + << std::endl; + morg_data_interp_->setup_periodic_time_database({marine_organics_data_file}); + std::cout << "MAMSrfOnlineEmiss: after setup_periodic_time_database (marine organics)" + << std::endl; + std::cout << "MAMSrfOnlineEmiss: before create_horiz_remappers (marine organics)" + << std::endl; + morg_data_interp_->create_horiz_remappers( + marine_map_file == "none" ? "" : marine_map_file); + std::cout << "MAMSrfOnlineEmiss: after create_horiz_remappers (marine organics)" + << std::endl; + DataInterpolation::VertRemapData remap_data; + remap_data.vr_type = DataInterpolation::None; + std::cout << "MAMSrfOnlineEmiss: before create_vert_remapper (marine organics)" + << std::endl; + morg_data_interp_->create_vert_remapper(remap_data); + std::cout << "MAMSrfOnlineEmiss: after create_vert_remapper (marine organics)" + << std::endl; //-------------------------------------------------------------------- // Setup data interpolation for surface emissions. //-------------------------------------------------------------------- @@ -349,18 +376,42 @@ void MAMSrfOnlineEmiss::initialize_impl(const RunType run_type) { std::vector soil_erod_fields = { get_field_out("soil_erodibility").alias(soil_erod_fld_name)}; + std::cout << "MAMSrfOnlineEmiss: before DataInterpolation ctor for soil erodibility" + << std::endl; auto soil_erod_data_interp = std::make_shared(grid_, soil_erod_fields); + std::cout << "MAMSrfOnlineEmiss: after DataInterpolation ctor for soil erodibility" + << std::endl; + std::cout << "MAMSrfOnlineEmiss: before set_logger (soil erodibility)" + << std::endl; soil_erod_data_interp->set_logger(m_atm_logger); + std::cout << "MAMSrfOnlineEmiss: after set_logger (soil erodibility)" + << std::endl; + std::cout << "MAMSrfOnlineEmiss: before setup_static_database (soil erodibility)" + << std::endl; soil_erod_data_interp->setup_static_database({soil_erodibility_data_file}); + std::cout << "MAMSrfOnlineEmiss: after setup_static_database (soil erodibility)" + << std::endl; + std::cout << "MAMSrfOnlineEmiss: before create_horiz_remappers (soil erodibility)" + << std::endl; soil_erod_data_interp->create_horiz_remappers( srf_map_file == "none" ? "" : srf_map_file); + std::cout << "MAMSrfOnlineEmiss: after create_horiz_remappers (soil erodibility)" + << std::endl; DataInterpolation::VertRemapData remap_data; remap_data.vr_type = DataInterpolation::None; + std::cout << "MAMSrfOnlineEmiss: before create_vert_remapper (soil erodibility)" + << std::endl; soil_erod_data_interp->create_vert_remapper(remap_data); + std::cout << "MAMSrfOnlineEmiss: after create_vert_remapper (soil erodibility)" + << std::endl; + std::cout << "MAMSrfOnlineEmiss: before run static interpolation (soil erodibility)" + << std::endl; soil_erod_data_interp->run(); + std::cout << "MAMSrfOnlineEmiss: after run static interpolation (soil erodibility)" + << std::endl; - soil_erodibility_ = soil_erodibility_field_.get_view(); + soil_erodibility_ = get_field_out("soil_erodibility").get_view(); } else if (dust_emis_scheme == 2) { // For dust emission scheme 2, override soil erodibility to 1 auto soil_erod_ones = view_1d("soil_erod_ones", ncol_); @@ -371,8 +422,12 @@ void MAMSrfOnlineEmiss::initialize_impl(const RunType run_type) { //-------------------------------------------------------------------- // Update marine orgaincs from file //-------------------------------------------------------------------- + std::cout << "MAMSrfOnlineEmiss: before init_time_interpolation (marine organics)" + << std::endl; morg_data_interp_->init_time_interpolation(start_of_step_ts(), DataInterpolation::Linear); + std::cout << "MAMSrfOnlineEmiss: after init_time_interpolation (marine organics)" + << std::endl; //----------------------------------------------------------------- // Setup preprocessing and post processing @@ -407,7 +462,9 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { //-------------------------------------------------------------------- // --- Interpolate marine organics data -- + std::cout << "MAMSrfOnlineEmiss: before run(ts) (marine organics)" << std::endl; morg_data_interp_->run(ts); + std::cout << "MAMSrfOnlineEmiss: after run(ts) (marine organics)" << std::endl; // Marine organics emission data read from the file (order is important here) const const_view_1d mpoly = morg_fields_[0].get_view(); diff --git a/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.hpp b/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.hpp index b111b0c3db36..397a1478cb3c 100644 --- a/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.hpp +++ b/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.hpp @@ -7,9 +7,6 @@ // For MAM4 aerosol configuration #include -// For reading marine organics file -#include - #include "share/field/field_reader.hpp" // For declaring surface and online emission class derived from atm process @@ -54,12 +51,8 @@ class MAMSrfOnlineEmiss final : public MAMGenericInterface { const_view_1d soil_erodibility_; public: - // For reading surface emissions file - using srfEmissFunc = mam_coupling::srfEmissFunctions; - // Constructor MAMSrfOnlineEmiss(const ekat::Comm &comm, const ekat::ParameterList ¶ms); - // -------------------------------------------------------------------------- // AtmosphereProcess overrides (see share/atm_process/atmosphere_process.hpp) // -------------------------------------------------------------------------- diff --git a/components/eamxx/tests/multi-process/physics_only/mam/mam4_srf_online_emiss_mam4_constituent_fluxes/input.yaml b/components/eamxx/tests/multi-process/physics_only/mam/mam4_srf_online_emiss_mam4_constituent_fluxes/input.yaml index ef66493941d8..3ee5ec53b6df 100644 --- a/components/eamxx/tests/multi-process/physics_only/mam/mam4_srf_online_emiss_mam4_constituent_fluxes/input.yaml +++ b/components/eamxx/tests/multi-process/physics_only/mam/mam4_srf_online_emiss_mam4_constituent_fluxes/input.yaml @@ -26,9 +26,8 @@ eamxx: srf_emis_scale_factor_for_dust: 1.5 soil_erodibility_file: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/dst_ne2np4_c20241028.nc - srf_emis_scale_factor_for_seasalt: 0.6 - marine_organics_file: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/monthly_macromolecules_0.1deg_bilinear_year01_merge_ne2np4_c20241030.nc + marine_organics_file: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/monthly_macromolecules_0.1deg_bilinear_year01_merge_ne2np4_c20260626.nc grids_manager: type: mesh_free geo_data_source: IC_FILE diff --git a/components/eamxx/tests/single-process/mam/emissions/CMakeLists.txt b/components/eamxx/tests/single-process/mam/emissions/CMakeLists.txt index 0c45342a4b69..da67b72b1a9b 100644 --- a/components/eamxx/tests/single-process/mam/emissions/CMakeLists.txt +++ b/components/eamxx/tests/single-process/mam/emissions/CMakeLists.txt @@ -37,7 +37,7 @@ set (TEST_INPUT_FILES scream/mam4xx/emissions/ne2np4/surface/cmip6_mam4_so4_a1_surf_ne2np4_2010_clim_c20260730.nc scream/mam4xx/emissions/ne2np4/surface/cmip6_mam4_so4_a2_surf_ne2np4_2010_clim_c20260730.nc scream/mam4xx/emissions/ne2np4/dst_ne2np4_c20241028.nc - scream/mam4xx/emissions/ne2np4/monthly_macromolecules_0.1deg_bilinear_year01_merge_ne2np4_c20241030.nc + scream/mam4xx/emissions/ne2np4/monthly_macromolecules_0.1deg_bilinear_year01_merge_ne2np4_c20260626.nc ) foreach (file IN ITEMS ${TEST_INPUT_FILES}) GetInputFile(${file}) diff --git a/components/eamxx/tests/single-process/mam/emissions/input.yaml b/components/eamxx/tests/single-process/mam/emissions/input.yaml index 5f76796b9e4f..51a9dfc5803b 100644 --- a/components/eamxx/tests/single-process/mam/emissions/input.yaml +++ b/components/eamxx/tests/single-process/mam/emissions/input.yaml @@ -26,9 +26,8 @@ eamxx: srf_emis_scale_factor_for_dust: 1.5 soil_erodibility_file: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/dst_ne2np4_c20241028.nc - srf_emis_scale_factor_for_seasalt: 0.6 - marine_organics_file: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/monthly_macromolecules_0.1deg_bilinear_year01_merge_ne2np4_c20241030.nc + marine_organics_file: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/monthly_macromolecules_0.1deg_bilinear_year01_merge_ne2np4_c20260626.nc grids_manager: type: mesh_free geo_data_source: IC_FILE From 8f9a3f8205663d0497a0119ec9105e05758d4339 Mon Sep 17 00:00:00 2001 From: "Oscar H. Diaz-Ibarra" Date: Fri, 7 Aug 2026 07:59:31 -0700 Subject: [PATCH 5/7] Update the NetCDF file to comply with all requirements of the DataInterpolation class. --- .../cime_config/namelist_defaults_eamxx.xml | 4 +- ...and_online_emissions_process_interface.cpp | 52 ------------------- .../CMakeLists.txt | 20 +++---- .../input.yaml | 2 +- .../mam/emissions/CMakeLists.txt | 2 +- .../single-process/mam/emissions/input.yaml | 2 +- 6 files changed, 16 insertions(+), 66 deletions(-) diff --git a/components/eamxx/cime_config/namelist_defaults_eamxx.xml b/components/eamxx/cime_config/namelist_defaults_eamxx.xml index 3e206a3b8b67..e0183b0b389a 100644 --- a/components/eamxx/cime_config/namelist_defaults_eamxx.xml +++ b/components/eamxx/cime_config/namelist_defaults_eamxx.xml @@ -476,8 +476,8 @@ be lost if SCREAM_HACK_XML is not enabled. ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/dst_ne30pg2_c20241028.nc ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/dst_ne4pg2_c20241028.nc - ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/monthly_macromolecules_0.1deg_bilinear_year01_merge_ne30pg2_c20241030.nc - ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/monthly_macromolecules_0.1deg_bilinear_year01_merge_ne4pg2_c20241030.nc + ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/monthly_macromolecules_0.1deg_bilinear_year01_merge_ne30pg2_c20260807.nc + ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/monthly_macromolecules_0.1deg_bilinear_year01_merge_ne4pg2_c20260807.nc none diff --git a/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.cpp b/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.cpp index 4ad0ebee020b..7ba8425e8f12 100644 --- a/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.cpp +++ b/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.cpp @@ -287,8 +287,6 @@ void MAMSrfOnlineEmiss::initialize_impl(const RunType run_type) { m_params.get("marine_organics_file"); const auto marine_map_file = m_params.get("srf_remap_file", ""); - std::cout << "MAMSrfOnlineEmiss: get_field_out marine_organics_data_files " - << std::endl; const std::vector marine_org_fld_name = { "TRUEPOLYC", "TRUEPROTC", "TRUELIPC"}; morg_fields_={}; @@ -298,34 +296,14 @@ void MAMSrfOnlineEmiss::initialize_impl(const RunType run_type) { get_field_out("morg_" + field_name).alias(field_name)); } - std::cout << "MAMSrfOnlineEmiss: before DataInterpolation ctor for marine organics" - << std::endl; morg_data_interp_ = std::make_shared(grid_, morg_fields_); - std::cout << "MAMSrfOnlineEmiss: after DataInterpolation ctor for marine organics" - << std::endl; - std::cout << "MAMSrfOnlineEmiss: before set_logger (marine organics)" - << std::endl; morg_data_interp_->set_logger(m_atm_logger); - std::cout << "MAMSrfOnlineEmiss: after set_logger (marine organics)" - << std::endl; - std::cout << "MAMSrfOnlineEmiss: before setup_periodic_time_database (marine organics)" - << std::endl; morg_data_interp_->setup_periodic_time_database({marine_organics_data_file}); - std::cout << "MAMSrfOnlineEmiss: after setup_periodic_time_database (marine organics)" - << std::endl; - std::cout << "MAMSrfOnlineEmiss: before create_horiz_remappers (marine organics)" - << std::endl; morg_data_interp_->create_horiz_remappers( marine_map_file == "none" ? "" : marine_map_file); - std::cout << "MAMSrfOnlineEmiss: after create_horiz_remappers (marine organics)" - << std::endl; DataInterpolation::VertRemapData remap_data; remap_data.vr_type = DataInterpolation::None; - std::cout << "MAMSrfOnlineEmiss: before create_vert_remapper (marine organics)" - << std::endl; morg_data_interp_->create_vert_remapper(remap_data); - std::cout << "MAMSrfOnlineEmiss: after create_vert_remapper (marine organics)" - << std::endl; //-------------------------------------------------------------------- // Setup data interpolation for surface emissions. //-------------------------------------------------------------------- @@ -376,40 +354,16 @@ void MAMSrfOnlineEmiss::initialize_impl(const RunType run_type) { std::vector soil_erod_fields = { get_field_out("soil_erodibility").alias(soil_erod_fld_name)}; - std::cout << "MAMSrfOnlineEmiss: before DataInterpolation ctor for soil erodibility" - << std::endl; auto soil_erod_data_interp = std::make_shared(grid_, soil_erod_fields); - std::cout << "MAMSrfOnlineEmiss: after DataInterpolation ctor for soil erodibility" - << std::endl; - std::cout << "MAMSrfOnlineEmiss: before set_logger (soil erodibility)" - << std::endl; soil_erod_data_interp->set_logger(m_atm_logger); - std::cout << "MAMSrfOnlineEmiss: after set_logger (soil erodibility)" - << std::endl; - std::cout << "MAMSrfOnlineEmiss: before setup_static_database (soil erodibility)" - << std::endl; soil_erod_data_interp->setup_static_database({soil_erodibility_data_file}); - std::cout << "MAMSrfOnlineEmiss: after setup_static_database (soil erodibility)" - << std::endl; - std::cout << "MAMSrfOnlineEmiss: before create_horiz_remappers (soil erodibility)" - << std::endl; soil_erod_data_interp->create_horiz_remappers( srf_map_file == "none" ? "" : srf_map_file); - std::cout << "MAMSrfOnlineEmiss: after create_horiz_remappers (soil erodibility)" - << std::endl; DataInterpolation::VertRemapData remap_data; remap_data.vr_type = DataInterpolation::None; - std::cout << "MAMSrfOnlineEmiss: before create_vert_remapper (soil erodibility)" - << std::endl; soil_erod_data_interp->create_vert_remapper(remap_data); - std::cout << "MAMSrfOnlineEmiss: after create_vert_remapper (soil erodibility)" - << std::endl; - std::cout << "MAMSrfOnlineEmiss: before run static interpolation (soil erodibility)" - << std::endl; soil_erod_data_interp->run(); - std::cout << "MAMSrfOnlineEmiss: after run static interpolation (soil erodibility)" - << std::endl; soil_erodibility_ = get_field_out("soil_erodibility").get_view(); } else if (dust_emis_scheme == 2) { @@ -422,12 +376,8 @@ void MAMSrfOnlineEmiss::initialize_impl(const RunType run_type) { //-------------------------------------------------------------------- // Update marine orgaincs from file //-------------------------------------------------------------------- - std::cout << "MAMSrfOnlineEmiss: before init_time_interpolation (marine organics)" - << std::endl; morg_data_interp_->init_time_interpolation(start_of_step_ts(), DataInterpolation::Linear); - std::cout << "MAMSrfOnlineEmiss: after init_time_interpolation (marine organics)" - << std::endl; //----------------------------------------------------------------- // Setup preprocessing and post processing @@ -462,9 +412,7 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { //-------------------------------------------------------------------- // --- Interpolate marine organics data -- - std::cout << "MAMSrfOnlineEmiss: before run(ts) (marine organics)" << std::endl; morg_data_interp_->run(ts); - std::cout << "MAMSrfOnlineEmiss: after run(ts) (marine organics)" << std::endl; // Marine organics emission data read from the file (order is important here) const const_view_1d mpoly = morg_fields_[0].get_view(); diff --git a/components/eamxx/tests/multi-process/physics_only/mam/mam4_srf_online_emiss_mam4_constituent_fluxes/CMakeLists.txt b/components/eamxx/tests/multi-process/physics_only/mam/mam4_srf_online_emiss_mam4_constituent_fluxes/CMakeLists.txt index 886936ca0846..3e5aec23f55c 100644 --- a/components/eamxx/tests/multi-process/physics_only/mam/mam4_srf_online_emiss_mam4_constituent_fluxes/CMakeLists.txt +++ b/components/eamxx/tests/multi-process/physics_only/mam/mam4_srf_online_emiss_mam4_constituent_fluxes/CMakeLists.txt @@ -22,15 +22,17 @@ GetInputFile(cam/topo/${EAMxx_tests_TOPO_FILE}) # Ensure test input files are present in the data dir set (TEST_INPUT_FILES - scream/mam4xx/emissions/ne2np4/surface/DMSflux.2010.ne2np4_conserv.POPmonthlyClimFromACES4BGC_c20240726.nc - scream/mam4xx/emissions/ne2np4/surface/cmip6_mam4_so2_surf_ne2np4_2010_clim_c20240723.nc - scream/mam4xx/emissions/ne2np4/surface/cmip6_mam4_bc_a4_surf_ne2np4_2010_clim_c20240726.nc - scream/mam4xx/emissions/ne2np4/surface/cmip6_mam4_num_a1_surf_ne2np4_2010_clim_c20240726.nc - scream/mam4xx/emissions/ne2np4/surface/cmip6_mam4_num_a2_surf_ne2np4_2010_clim_c20240726.nc - scream/mam4xx/emissions/ne2np4/surface/cmip6_mam4_num_a4_surf_ne2np4_2010_clim_c20240726.nc - scream/mam4xx/emissions/ne2np4/surface/cmip6_mam4_pom_a4_surf_ne2np4_2010_clim_c20240726.nc - scream/mam4xx/emissions/ne2np4/surface/cmip6_mam4_so4_a1_surf_ne2np4_2010_clim_c20240726.nc - scream/mam4xx/emissions/ne2np4/surface/cmip6_mam4_so4_a2_surf_ne2np4_2010_clim_c20240726.nc + scream/mam4xx/emissions/ne2np4/surface/DMSflux.2010.ne2np4_conserv.POPmonthlyClimFromACES4BGC_c20260730.nc + scream/mam4xx/emissions/ne2np4/surface/cmip6_mam4_so2_surf_ne2np4_2010_clim_c20260730.nc + scream/mam4xx/emissions/ne2np4/surface/cmip6_mam4_bc_a4_surf_ne2np4_2010_clim_c20260730.nc + scream/mam4xx/emissions/ne2np4/surface/cmip6_mam4_num_a1_surf_ne2np4_2010_clim_c20260730.nc + scream/mam4xx/emissions/ne2np4/surface/cmip6_mam4_num_a2_surf_ne2np4_2010_clim_c20260730.nc + scream/mam4xx/emissions/ne2np4/surface/cmip6_mam4_num_a4_surf_ne2np4_2010_clim_c20260730.nc + scream/mam4xx/emissions/ne2np4/surface/cmip6_mam4_pom_a4_surf_ne2np4_2010_clim_c20260730.nc + scream/mam4xx/emissions/ne2np4/surface/cmip6_mam4_so4_a1_surf_ne2np4_2010_clim_c20260730.nc + scream/mam4xx/emissions/ne2np4/surface/cmip6_mam4_so4_a2_surf_ne2np4_2010_clim_c20260730.nc + scream/mam4xx/emissions/ne2np4/monthly_macromolecules_0.1deg_bilinear_year01_merge_ne2np4_c20260807.nc + scream/mam4xx/emissions/ne2np4/dst_ne2np4_c20241028.nc ) foreach (file IN ITEMS ${TEST_INPUT_FILES}) GetInputFile(${file}) diff --git a/components/eamxx/tests/multi-process/physics_only/mam/mam4_srf_online_emiss_mam4_constituent_fluxes/input.yaml b/components/eamxx/tests/multi-process/physics_only/mam/mam4_srf_online_emiss_mam4_constituent_fluxes/input.yaml index 3ee5ec53b6df..c6990012a106 100644 --- a/components/eamxx/tests/multi-process/physics_only/mam/mam4_srf_online_emiss_mam4_constituent_fluxes/input.yaml +++ b/components/eamxx/tests/multi-process/physics_only/mam/mam4_srf_online_emiss_mam4_constituent_fluxes/input.yaml @@ -27,7 +27,7 @@ eamxx: srf_emis_scale_factor_for_dust: 1.5 soil_erodibility_file: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/dst_ne2np4_c20241028.nc srf_emis_scale_factor_for_seasalt: 0.6 - marine_organics_file: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/monthly_macromolecules_0.1deg_bilinear_year01_merge_ne2np4_c20260626.nc + marine_organics_file: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/monthly_macromolecules_0.1deg_bilinear_year01_merge_ne2np4_c20260807.nc grids_manager: type: mesh_free geo_data_source: IC_FILE diff --git a/components/eamxx/tests/single-process/mam/emissions/CMakeLists.txt b/components/eamxx/tests/single-process/mam/emissions/CMakeLists.txt index da67b72b1a9b..3da5921bc0ec 100644 --- a/components/eamxx/tests/single-process/mam/emissions/CMakeLists.txt +++ b/components/eamxx/tests/single-process/mam/emissions/CMakeLists.txt @@ -37,7 +37,7 @@ set (TEST_INPUT_FILES scream/mam4xx/emissions/ne2np4/surface/cmip6_mam4_so4_a1_surf_ne2np4_2010_clim_c20260730.nc scream/mam4xx/emissions/ne2np4/surface/cmip6_mam4_so4_a2_surf_ne2np4_2010_clim_c20260730.nc scream/mam4xx/emissions/ne2np4/dst_ne2np4_c20241028.nc - scream/mam4xx/emissions/ne2np4/monthly_macromolecules_0.1deg_bilinear_year01_merge_ne2np4_c20260626.nc + scream/mam4xx/emissions/ne2np4/monthly_macromolecules_0.1deg_bilinear_year01_merge_ne2np4_c20260807.nc ) foreach (file IN ITEMS ${TEST_INPUT_FILES}) GetInputFile(${file}) diff --git a/components/eamxx/tests/single-process/mam/emissions/input.yaml b/components/eamxx/tests/single-process/mam/emissions/input.yaml index 51a9dfc5803b..ca5c9aa3b5d0 100644 --- a/components/eamxx/tests/single-process/mam/emissions/input.yaml +++ b/components/eamxx/tests/single-process/mam/emissions/input.yaml @@ -27,7 +27,7 @@ eamxx: srf_emis_scale_factor_for_dust: 1.5 soil_erodibility_file: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/dst_ne2np4_c20241028.nc srf_emis_scale_factor_for_seasalt: 0.6 - marine_organics_file: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/monthly_macromolecules_0.1deg_bilinear_year01_merge_ne2np4_c20260626.nc + marine_organics_file: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/monthly_macromolecules_0.1deg_bilinear_year01_merge_ne2np4_c20260807.nc grids_manager: type: mesh_free geo_data_source: IC_FILE From 0564c5e9acec850dfd4790d15b5b5632363d3be7 Mon Sep 17 00:00:00 2001 From: "Oscar H. Diaz-Ibarra" Date: Tue, 25 Aug 2026 14:19:42 -0600 Subject: [PATCH 6/7] Move code blocks into separate methods. --- ...x_mam_dry_deposition_process_interface.cpp | 41 ++++++++++-------- ...x_mam_dry_deposition_process_interface.hpp | 3 ++ ...and_online_emissions_process_interface.cpp | 43 +++++++++++-------- ...and_online_emissions_process_interface.hpp | 3 ++ 4 files changed, 52 insertions(+), 38 deletions(-) diff --git a/components/eamxx/src/physics/mam/eamxx_mam_dry_deposition_process_interface.cpp b/components/eamxx/src/physics/mam/eamxx_mam_dry_deposition_process_interface.cpp index ea8b43c8f7b5..e96b28d118a8 100644 --- a/components/eamxx/src/physics/mam/eamxx_mam_dry_deposition_process_interface.cpp +++ b/components/eamxx/src/physics/mam/eamxx_mam_dry_deposition_process_interface.cpp @@ -299,27 +299,30 @@ void MAMDryDep::initialize_impl(const RunType run_type) { //----------------------------------------------------------------- // Read fractional land use data //----------------------------------------------------------------- - { - const auto mapping_file = m_params.get("drydep_remap_file", ""); - const auto frac_landuse_data_file = - m_params.get("fractional_land_use_file"); - std::vector frac_landuse_fields = { - get_field_out("fraction_landuse")}; - auto frac_landuse_interp = - std::make_shared(grid_, frac_landuse_fields); - frac_landuse_interp->set_logger(m_atm_logger); - frac_landuse_interp->setup_static_database({frac_landuse_data_file}); - frac_landuse_interp->create_horiz_remappers( - mapping_file == "none" ? "" : mapping_file); - DataInterpolation::VertRemapData remap_data; - remap_data.vr_type = DataInterpolation::None; - frac_landuse_interp->create_vert_remapper(remap_data); - frac_landuse_interp->run(); - - frac_landuse_ = get_field_out("fraction_landuse").get_view(); - } + read_fractional_land_use_data(); } // initialize_impl +// ========================================================================================= +void MAMDryDep::read_fractional_land_use_data() { + const auto mapping_file = m_params.get("drydep_remap_file", ""); + const auto frac_landuse_data_file = + m_params.get("fractional_land_use_file"); + std::vector frac_landuse_fields = { + get_field_out("fraction_landuse")}; + auto frac_landuse_interp = + std::make_shared(grid_, frac_landuse_fields); + frac_landuse_interp->set_logger(m_atm_logger); + frac_landuse_interp->setup_static_database({frac_landuse_data_file}); + frac_landuse_interp->create_horiz_remappers( + mapping_file == "none" ? "" : mapping_file); + DataInterpolation::VertRemapData remap_data; + remap_data.vr_type = DataInterpolation::None; + frac_landuse_interp->create_vert_remapper(remap_data); + frac_landuse_interp->run(); + + frac_landuse_ = get_field_out("fraction_landuse").get_view(); +} + // ========================================================================================= void MAMDryDep::run_impl(const double dt) { using TPF = ekat::TeamPolicyFactory; diff --git a/components/eamxx/src/physics/mam/eamxx_mam_dry_deposition_process_interface.hpp b/components/eamxx/src/physics/mam/eamxx_mam_dry_deposition_process_interface.hpp index 438ae5c21278..8c0becbec6cc 100644 --- a/components/eamxx/src/physics/mam/eamxx_mam_dry_deposition_process_interface.hpp +++ b/components/eamxx/src/physics/mam/eamxx_mam_dry_deposition_process_interface.hpp @@ -100,6 +100,9 @@ class MAMDryDep final : public MAMGenericInterface { int get_len_temporary_views(); void init_temporary_views(); int len_temporary_views_{0}; + + // Read fractional land use data from file + void read_fractional_land_use_data(); public: using KT = ekat::KokkosTypes; diff --git a/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.cpp b/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.cpp index 7ba8425e8f12..1a1d5a9dbd52 100644 --- a/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.cpp +++ b/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.cpp @@ -347,25 +347,7 @@ void MAMSrfOnlineEmiss::initialize_impl(const RunType run_type) { if (dust_emis_scheme == 1) { // This data is time-independent, we read all data here for the // entire simulation - const auto soil_erodibility_data_file = - m_params.get("soil_erodibility_file"); - const auto srf_map_file = m_params.get("srf_remap_file", ""); - const std::string soil_erod_fld_name = "mbl_bsn_fct_geo"; - - std::vector soil_erod_fields = { - get_field_out("soil_erodibility").alias(soil_erod_fld_name)}; - auto soil_erod_data_interp = - std::make_shared(grid_, soil_erod_fields); - soil_erod_data_interp->set_logger(m_atm_logger); - soil_erod_data_interp->setup_static_database({soil_erodibility_data_file}); - soil_erod_data_interp->create_horiz_remappers( - srf_map_file == "none" ? "" : srf_map_file); - DataInterpolation::VertRemapData remap_data; - remap_data.vr_type = DataInterpolation::None; - soil_erod_data_interp->create_vert_remapper(remap_data); - soil_erod_data_interp->run(); - - soil_erodibility_ = get_field_out("soil_erodibility").get_view(); + read_soil_erodibility_data(); } else if (dust_emis_scheme == 2) { // For dust emission scheme 2, override soil erodibility to 1 auto soil_erod_ones = view_1d("soil_erod_ones", ncol_); @@ -386,6 +368,29 @@ void MAMSrfOnlineEmiss::initialize_impl(const RunType run_type) { } // end initialize_impl() +// ========================================================================================= +void MAMSrfOnlineEmiss::read_soil_erodibility_data() { + const auto soil_erodibility_data_file = + m_params.get("soil_erodibility_file"); + const auto srf_map_file = m_params.get("srf_remap_file", ""); + const std::string soil_erod_fld_name = "mbl_bsn_fct_geo"; + + std::vector soil_erod_fields = { + get_field_out("soil_erodibility").alias(soil_erod_fld_name)}; + auto soil_erod_data_interp = + std::make_shared(grid_, soil_erod_fields); + soil_erod_data_interp->set_logger(m_atm_logger); + soil_erod_data_interp->setup_static_database({soil_erodibility_data_file}); + soil_erod_data_interp->create_horiz_remappers( + srf_map_file == "none" ? "" : srf_map_file); + DataInterpolation::VertRemapData remap_data; + remap_data.vr_type = DataInterpolation::None; + soil_erod_data_interp->create_vert_remapper(remap_data); + soil_erod_data_interp->run(); + + soil_erodibility_ = get_field_out("soil_erodibility").get_view(); +} + // ================================================================ // RUN_IMPL // ================================================================ diff --git a/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.hpp b/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.hpp index 397a1478cb3c..2d27dead5c9e 100644 --- a/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.hpp +++ b/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.hpp @@ -156,6 +156,9 @@ class MAMSrfOnlineEmiss final : public MAMGenericInterface { mam4::aero_model::pcnst - mam4::gas_chemistry::gas_pcnst; // workspace manager for internal local variables mam_coupling::Buffer buffer_; + + // Read soil erodibility data from file + void read_soil_erodibility_data(); }; // MAMSrfOnlineEmiss From df34494d251f1373e03404e1c545463c5a8cd153 Mon Sep 17 00:00:00 2001 From: "Oscar H. Diaz-Ibarra" Date: Tue, 25 Aug 2026 15:02:38 -0600 Subject: [PATCH 7/7] Add m_iop_data_manager to all DataInterpolation instances in MAM4. --- .../mam/eamxx_mam_dry_deposition_process_interface.cpp | 2 +- .../mam/eamxx_mam_microphysics_process_interface.cpp | 8 ++++---- ...mxx_mam_srf_and_online_emissions_process_interface.cpp | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/components/eamxx/src/physics/mam/eamxx_mam_dry_deposition_process_interface.cpp b/components/eamxx/src/physics/mam/eamxx_mam_dry_deposition_process_interface.cpp index e96b28d118a8..bee19d5a4e16 100644 --- a/components/eamxx/src/physics/mam/eamxx_mam_dry_deposition_process_interface.cpp +++ b/components/eamxx/src/physics/mam/eamxx_mam_dry_deposition_process_interface.cpp @@ -314,7 +314,7 @@ void MAMDryDep::read_fractional_land_use_data() { frac_landuse_interp->set_logger(m_atm_logger); frac_landuse_interp->setup_static_database({frac_landuse_data_file}); frac_landuse_interp->create_horiz_remappers( - mapping_file == "none" ? "" : mapping_file); + mapping_file == "none" ? "" : mapping_file, m_iop_data_manager); DataInterpolation::VertRemapData remap_data; remap_data.vr_type = DataInterpolation::None; frac_landuse_interp->create_vert_remapper(remap_data); diff --git a/components/eamxx/src/physics/mam/eamxx_mam_microphysics_process_interface.cpp b/components/eamxx/src/physics/mam/eamxx_mam_microphysics_process_interface.cpp index b269596c83b1..5a83dcc95931 100644 --- a/components/eamxx/src/physics/mam/eamxx_mam_microphysics_process_interface.cpp +++ b/components/eamxx/src/physics/mam/eamxx_mam_microphysics_process_interface.cpp @@ -471,7 +471,7 @@ void MAMMicrophysics::set_oxid_reader() data_interp_oxid_ = std::make_shared(grid_,oxid_fields); data_interp_oxid_->setup_periodic_time_database ({oxid_file_name}); - data_interp_oxid_->create_horiz_remappers (oxid_map_file=="none" ? "" : oxid_map_file); + data_interp_oxid_->create_horiz_remappers (oxid_map_file=="none" ? "" : oxid_map_file, m_iop_data_manager); data_interp_oxid_->set_logger(m_atm_logger); DataInterpolation::VertRemapData remap_data_oxid; remap_data_oxid.vr_type = DataInterpolation::Dynamic3DRef; @@ -505,7 +505,7 @@ void MAMMicrophysics::set_linoz_reader(){ data_interp_linoz_ = std::make_shared(grid_,linoz_fields); data_interp_linoz_->setup_periodic_time_database ({m_linoz_file_name}); - data_interp_linoz_->create_horiz_remappers (linoz_map_file=="none" ? "" : linoz_map_file); + data_interp_linoz_->create_horiz_remappers (linoz_map_file=="none" ? "" : linoz_map_file, m_iop_data_manager); data_interp_linoz_->set_logger(m_atm_logger); DataInterpolation::VertRemapData remap_data_linoz; @@ -553,7 +553,7 @@ void MAMMicrophysics::set_exo_coldens_reader() data_interp_exo_coldens_ = std::make_shared(grid_exo_coldens,exo_coldens_fields_); data_interp_exo_coldens_->setup_periodic_time_database ({exo_coldens_file_name}); - data_interp_exo_coldens_->create_horiz_remappers (exo_coldens_map_file=="none" ? "" : exo_coldens_map_file); + data_interp_exo_coldens_->create_horiz_remappers (exo_coldens_map_file=="none" ? "" : exo_coldens_map_file, m_iop_data_manager); data_interp_exo_coldens_->set_logger(m_atm_logger); DataInterpolation::VertRemapData remap_exo_coldens; remap_exo_coldens.vr_type = DataInterpolation::Custom; @@ -588,7 +588,7 @@ void MAMMicrophysics::set_elevated_emissions_reader() di_vertical->set_input_files_dimname(e2str(LEV),"altitude"); di_vertical->set_input_files_dimname(e2str(ILEV),"altitude_int"); di_vertical->setup_periodic_time_database ({file_name}); - di_vertical->create_horiz_remappers (extfrc_map_file=="none" ? "" : extfrc_map_file); + di_vertical->create_horiz_remappers (extfrc_map_file=="none" ? "" : extfrc_map_file, m_iop_data_manager); di_vertical->set_logger(m_atm_logger); DataInterpolation::VertRemapData remap_data_vertical; remap_data_vertical.vr_type = DataInterpolation::Custom; diff --git a/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.cpp b/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.cpp index 1a1d5a9dbd52..a13f429c4ff0 100644 --- a/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.cpp +++ b/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_process_interface.cpp @@ -300,7 +300,7 @@ void MAMSrfOnlineEmiss::initialize_impl(const RunType run_type) { morg_data_interp_->set_logger(m_atm_logger); morg_data_interp_->setup_periodic_time_database({marine_organics_data_file}); morg_data_interp_->create_horiz_remappers( - marine_map_file == "none" ? "" : marine_map_file); + marine_map_file == "none" ? "" : marine_map_file, m_iop_data_manager); DataInterpolation::VertRemapData remap_data; remap_data.vr_type = DataInterpolation::None; morg_data_interp_->create_vert_remapper(remap_data); @@ -328,7 +328,7 @@ void MAMSrfOnlineEmiss::initialize_impl(const RunType run_type) { ispec_srf.data_interp_->setup_periodic_time_database( {ispec_srf.data_file}); ispec_srf.data_interp_->create_horiz_remappers( - srf_map_file == "none" ? "" : srf_map_file); + srf_map_file == "none" ? "" : srf_map_file, m_iop_data_manager); DataInterpolation::VertRemapData remap_data; remap_data.vr_type = DataInterpolation::None; @@ -382,7 +382,7 @@ void MAMSrfOnlineEmiss::read_soil_erodibility_data() { soil_erod_data_interp->set_logger(m_atm_logger); soil_erod_data_interp->setup_static_database({soil_erodibility_data_file}); soil_erod_data_interp->create_horiz_remappers( - srf_map_file == "none" ? "" : srf_map_file); + srf_map_file == "none" ? "" : srf_map_file, m_iop_data_manager); DataInterpolation::VertRemapData remap_data; remap_data.vr_type = DataInterpolation::None; soil_erod_data_interp->create_vert_remapper(remap_data);