diff --git a/components/eamxx/cime_config/namelist_defaults_scream.xml b/components/eamxx/cime_config/namelist_defaults_scream.xml
index 1b84aef2273..c392615e7db 100644
--- a/components/eamxx/cime_config/namelist_defaults_scream.xml
+++ b/components/eamxx/cime_config/namelist_defaults_scream.xml
@@ -37,6 +37,8 @@ be lost if SCREAM_HACK_XML is not enabled.
+
+
@@ -250,7 +252,17 @@ be lost if SCREAM_HACK_XML is not enabled.
-
+
+ ${DIN_LOC_ROOT}/atm/scream/mam4xx/drydep/ne30pg2/atmsrf_ne30pg2_c20241017.nc
+ ${DIN_LOC_ROOT}/atm/scream/mam4xx/drydep/ne4pg2/atmsrf_ne4pg2_c20241017.nc
+
+
+
+ ${DIN_LOC_ROOT}/atm/scream/maps/map_ne30pg2_to_ne120pg2_20231201.nc
+ ${DIN_LOC_ROOT}/atm/scream/maps/map_ne30pg2_to_ne256pg2_20231201.nc
+ ${DIN_LOC_ROOT}/atm/scream/maps/map_ne30pg2_to_ne512pg2_20231201.nc
+ ${DIN_LOC_ROOT}/atm/scream/maps/map_ne30pg2_to_ne1024pg2_20231201.nc
+
@@ -278,15 +290,6 @@ be lost if SCREAM_HACK_XML is not enabled.
- ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/DMSflux.2010.ne4pg2_conserv.POPmonthlyClimFromACES4BGC_c20240814.nc
- ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/cmip6_mam4_so2_surf_ne4pg2_2010_clim_c20240815.nc
- ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/cmip6_mam4_bc_a4_surf_ne4pg2_2010_clim_c20240815.nc
- ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/cmip6_mam4_num_a1_surf_ne4pg2_2010_clim_c20240815.nc
- ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/cmip6_mam4_num_a2_surf_ne4pg2_2010_clim_c20240815.nc
- ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/cmip6_mam4_num_a4_surf_ne4pg2_2010_clim_c20240815.nc
- ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/cmip6_mam4_pom_a4_surf_ne4pg2_2010_clim_c20240815.nc
- ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/cmip6_mam4_so4_a1_surf_ne4pg2_2010_clim_c20240815.nc
- ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/cmip6_mam4_so4_a2_surf_ne4pg2_2010_clim_c20240815.nc
${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/surface/DMSflux.2010.ne30pg2_conserv.POPmonthlyClimFromACES4BGC_c20240816.nc
${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/surface/cmip6_mam4_so2_surf_ne30pg2_2010_clim_c20240816.nc
@@ -297,6 +300,18 @@ be lost if SCREAM_HACK_XML is not enabled.
${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/surface/cmip6_mam4_pom_a4_surf_ne30pg2_2010_clim_c20240816.nc
${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/surface/cmip6_mam4_so4_a1_surf_ne30pg2_2010_clim_c20240816.nc
${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/surface/cmip6_mam4_so4_a2_surf_ne30pg2_2010_clim_c20240816.nc
+
+
+ ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/DMSflux.2010.ne4pg2_conserv.POPmonthlyClimFromACES4BGC_c20240814.nc
+ ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/cmip6_mam4_so2_surf_ne4pg2_2010_clim_c20240815.nc
+ ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/cmip6_mam4_bc_a4_surf_ne4pg2_2010_clim_c20240815.nc
+ ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/cmip6_mam4_num_a1_surf_ne4pg2_2010_clim_c20240815.nc
+ ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/cmip6_mam4_num_a2_surf_ne4pg2_2010_clim_c20240815.nc
+ ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/cmip6_mam4_num_a4_surf_ne4pg2_2010_clim_c20240815.nc
+ ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/cmip6_mam4_pom_a4_surf_ne4pg2_2010_clim_c20240815.nc
+ ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/cmip6_mam4_so4_a1_surf_ne4pg2_2010_clim_c20240815.nc
+ ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/cmip6_mam4_so4_a2_surf_ne4pg2_2010_clim_c20240815.nc
+
@@ -490,9 +505,11 @@ be lost if SCREAM_HACK_XML is not enabled.
UNSET
${DIN_LOC_ROOT}/atm/scream/init/screami_ne4np4L72_20220823.nc
+ ${DIN_LOC_ROOT}/atm/scream/init/screami_mam4xx_ne4np4L72_c20240208.nc
${DIN_LOC_ROOT}/atm/scream/init/screami_ne4np4L128_20241022.nc
${DIN_LOC_ROOT}/atm/scream/init/screami_ne30np4L72_20220823.nc
${DIN_LOC_ROOT}/atm/scream/init/screami_ne30np4L128_20221004.nc
+ ${DIN_LOC_ROOT}/atm/scream/init/screami_mam_ne30np4L72_c20240623.nc
${DIN_LOC_ROOT}/atm/scream/init/screami_ne120np4L72_20220823.nc
${DIN_LOC_ROOT}/atm/scream/init/screami_ne120np4L128_20230215.nc
${DIN_LOC_ROOT}/atm/scream/init/screami_ne256np4L128_ifs-20200120_20220914.nc
diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/aci/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/aci/shell_commands
index 658c94a3cf6..492bda019fc 100644
--- a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/aci/shell_commands
+++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/aci/shell_commands
@@ -5,9 +5,6 @@
#------------------------------------------------------
$CIMEROOT/../components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/update_eamxx_num_tracers.sh
-#modify initial condition file to get aerosol species ICs
-$CIMEROOT/../components/eamxx/scripts/atmchange initial_conditions::Filename='$DIN_LOC_ROOT/atm/scream/init/screami_mam4xx_ne4np4L72_c20240208.nc' -b
-
# Add spa as RRTMG needs spa
$CIMEROOT/../components/eamxx/scripts/atmchange physics::atm_procs_list="mac_aero_mic,spa,rrtmgp" -b
diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/drydep/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/drydep/shell_commands
index c5acf055a88..ea2d56ab53f 100644
--- a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/drydep/shell_commands
+++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/drydep/shell_commands
@@ -8,9 +8,8 @@
$CIMEROOT/../components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/update_eamxx_num_tracers.sh -b
#------------------------------------------------------
-#Update IC file and add drydep process
+# Add drydep process
#------------------------------------------------------
-$CIMEROOT/../components/eamxx/scripts/atmchange initial_conditions::Filename='$DIN_LOC_ROOT/atm/scream/init/screami_mam4xx_ne4np4L72_c20240208.nc' -b
$CIMEROOT/../components/eamxx/scripts/atmchange physics::atm_procs_list="mac_aero_mic,rrtmgp,mam4_drydep" -b
diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/optics/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/optics/shell_commands
index 224c1658610..9bbcfaea898 100644
--- a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/optics/shell_commands
+++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/optics/shell_commands
@@ -4,7 +4,6 @@
#------------------------------------------------------
$CIMEROOT/../components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/update_eamxx_num_tracers.sh
-$CIMEROOT/../components/eamxx/scripts/atmchange initial_conditions::Filename='$DIN_LOC_ROOT/atm/scream/init/screami_mam4xx_ne4np4L72_c20240208.nc' -b
$CIMEROOT/../components/eamxx/scripts/atmchange physics::atm_procs_list="mac_aero_mic,mam4_optics,rrtmgp" -b
diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/srf_online_emiss_constituent_fluxes/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/srf_online_emiss_constituent_fluxes/shell_commands
index f47a1729ed7..500d0bf660a 100644
--- a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/srf_online_emiss_constituent_fluxes/shell_commands
+++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/srf_online_emiss_constituent_fluxes/shell_commands
@@ -8,9 +8,8 @@
$CIMEROOT/../components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/update_eamxx_num_tracers.sh -b
#------------------------------------------------------
-#Update IC file and add the processes
+# Add the processes
#------------------------------------------------------
-$CIMEROOT/../components/eamxx/scripts/atmchange initial_conditions::Filename='$DIN_LOC_ROOT/atm/scream/init/screami_mam4xx_ne4np4L72_c20240208.nc' -b
$CIMEROOT/../components/eamxx/scripts/atmchange physics::atm_procs_list="mam4_constituent_fluxes,mac_aero_mic,rrtmgp,mam4_srf_online_emiss" -b
diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/wetscav/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/wetscav/shell_commands
index 7b5b9a87650..2cdf303a582 100644
--- a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/wetscav/shell_commands
+++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/wetscav/shell_commands
@@ -7,7 +7,6 @@
$CIMEROOT/../components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/update_eamxx_num_tracers.sh -b
#------------------------------------------------------
-#Update IC file and add wetscav process
+# Add wetscav process
#------------------------------------------------------
-$CIMEROOT/../components/eamxx/scripts/atmchange initial_conditions::Filename='$DIN_LOC_ROOT/atm/scream/init/screami_mam4xx_ne4np4L72_c20240208.nc' -b
$CIMEROOT/../components/eamxx/scripts/atmchange physics::atm_procs_list="mac_aero_mic,mam4_wetscav,rrtmgp" -b
diff --git a/components/eamxx/src/physics/mam/eamxx_mam_dry_deposition_functions.hpp b/components/eamxx/src/physics/mam/eamxx_mam_dry_deposition_functions.hpp
index f5423e8eb1c..93c085c8c1f 100644
--- a/components/eamxx/src/physics/mam/eamxx_mam_dry_deposition_functions.hpp
+++ b/components/eamxx/src/physics/mam/eamxx_mam_dry_deposition_functions.hpp
@@ -19,7 +19,7 @@ void compute_tendencies(
const MAMDryDep::const_view_1d ocnfrac,
const MAMDryDep::const_view_1d friction_velocity,
const MAMDryDep::const_view_1d aerodynamical_resistance,
- MAMDryDep::view_3d qtracers, MAMDryDep::view_2d fraction_landuse_,
+ const MAMDryDep::const_view_2d fraction_landuse_,
const MAMDryDep::const_view_3d dgncur_awet_,
const MAMDryDep::const_view_3d wet_dens_,
const mam_coupling::DryAtmosphere dry_atm,
@@ -35,7 +35,7 @@ void compute_tendencies(
// work arrays
MAMDryDep::view_2d rho_, MAMDryDep::view_4d vlc_dry_,
MAMDryDep::view_3d vlc_trb_, MAMDryDep::view_4d vlc_grv_,
- MAMDryDep::view_3d dqdt_tmp_) {
+ MAMDryDep::view_3d dqdt_tmp_, MAMDryDep::view_3d qtracers) {
static constexpr int num_aero_modes = mam_coupling::num_aero_modes();
const auto policy =
ekat::ExeSpaceUtils::get_default_team_policy(
@@ -86,7 +86,7 @@ void compute_tendencies(
static constexpr int n_land_type = MAMDryDep::n_land_type;
Real fraction_landuse[n_land_type];
for(int i = 0; i < n_land_type; ++i) {
- fraction_landuse[i] = fraction_landuse_(i, icol);
+ fraction_landuse[i] = fraction_landuse_(icol, i);
}
static constexpr int nmodes = mam4::AeroConfig::num_modes();
@@ -181,24 +181,6 @@ void update_cloudborne_mmrs(const MAMDryDep::view_3d qqcw, const double dt,
}
} // Update cloud borne aerosols ends
-// FIXME: remove the following function after implementing file read for landuse
-void populated_fraction_landuse(MAMDryDep::view_2d flu, const int ncol) {
- Kokkos::parallel_for(
- "populated_fraction_landuse", 1, KOKKOS_LAMBDA(int) {
- static constexpr int n_land_type = MAMDryDep::n_land_type;
- const Real temp[n_land_type] = {
- 0.28044346587077795E-003, 0.26634987180780171E-001,
- 0.16803558403621365E-001, 0.18076055155371872E-001,
- 0.00000000000000000E+000, 0.00000000000000000E+000,
- 0.91803784897907303E+000, 0.17186036997038400E-002,
- 0.00000000000000000E+000, 0.00000000000000000E+000,
- 0.18448503115578840E-001};
- for(int i = 0; i < n_land_type; ++i)
- for(int j = 0; j < ncol; ++j) flu(i, j) = temp[i];
- });
- Kokkos::fence();
-}
-
} // namespace
} // namespace scream
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 55bdf2d7158..1b4ad91d068 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,16 +3,13 @@
// Drydep functions are stored in the following hpp file
#include
-/*
------------------------------------------------------------------
-NOTES:
-1. Add a CIME test and multi-process tests
-2. Ensure that the submodule for MAM4xx is the main branch
-3. Read file for fractional landuse
------------------------------------------------------------------
-*/
+// For reading fractional land use file
+#include
+
namespace scream {
+using FracLandUseFunc = frac_landuse::fracLandUseFunctions;
+
MAMDryDep::MAMDryDep(const ekat::Comm &comm, const ekat::ParameterList ¶ms)
: AtmosphereProcess(comm, params) {
/* Anything that can be initialized without grid information can be
@@ -56,7 +53,8 @@ void MAMDryDep::set_grids(
// Layout for 4D (2d horiz X 1d vertical x number of modes) variables
// at mid points
const int num_aero_modes = mam_coupling::num_aero_modes();
- const FieldLayout vector3d_mid = grid_->get_3d_vector_layout(true, num_aero_modes, "num_modes");
+ const FieldLayout vector3d_mid =
+ grid_->get_3d_vector_layout(true, num_aero_modes, "num_modes");
using namespace ekat::units;
@@ -199,6 +197,27 @@ void MAMDryDep::set_grids(
// surface deposition flux of interstitial aerosols, [kg/m2/s] or [1/m2/s]
add_field("deposition_flux_of_interstitial_aerosols",
vector2d_pcnst, 1 / m2 / s, 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
// ================================================================
@@ -345,10 +364,14 @@ void MAMDryDep::initialize_impl(const RunType run_type) {
// Work array to hold tendency for 1 species [kg/kg/s] or [1/kg/s]
dqdt_tmp_ = view_3d("dqdt_tmp_", pcnst, ncol_, nlev_);
- static constexpr int n_land_type = mam4::DryDeposition::n_land_type;
- // FIXME: This should come from a file reading
- // The fraction of land use for the column. [non-dimentional]
- fraction_landuse_ = view_2d("fraction_landuse_", n_land_type, ncol_);
+ //-----------------------------------------------------------------
+ // Read fractional land use data
+ //-----------------------------------------------------------------
+ // 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
//-----------------------------------------------------------------
// Setup preprocessing and post processing
@@ -403,21 +426,20 @@ void MAMDryDep::run_impl(const double dt) {
auto aerdepdryis_ = get_field_out("deposition_flux_of_interstitial_aerosols")
.get_view();
- // FIXME: remove it if it read from a file
- populated_fraction_landuse(fraction_landuse_, ncol_);
-
+ //--------------------------------------------------------------------
// Call drydeposition and get tendencies
+ //--------------------------------------------------------------------
compute_tendencies(ncol_, nlev_, dt, obukhov_length_,
surface_friction_velocty_, land_fraction_, ice_fraction_,
ocean_fraction_, friction_velocity_,
- aerodynamical_resistance_, qtracers_, fraction_landuse_,
- dgncur_awet_, wet_dens_, dry_atm_, dry_aero_,
+ aerodynamical_resistance_, frac_landuse_, dgncur_awet_,
+ wet_dens_, dry_atm_, dry_aero_,
// Inouts-outputs
qqcw_,
// Outputs
ptend_q_, aerdepdrycw_, aerdepdryis_,
// work arrays
- rho_, vlc_dry_, vlc_trb_, vlc_grv_, dqdt_tmp_);
+ rho_, vlc_dry_, vlc_trb_, vlc_grv_, dqdt_tmp_, qtracers_);
Kokkos::fence();
// Update the interstitial aerosols using ptend.
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 e39090cecde..55ab5b15b95 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,6 +7,9 @@
// For MAM4 aerosol configuration
#include
+// For AtmosphereInput
+#include "share/io/scorpio_input.hpp"
+
// For component name
#include
@@ -26,6 +29,7 @@ class MAMDryDep final : public scream::AtmosphereProcess {
using view_3d = Field::view_dev_t;
using view_4d = Field::view_dev_t;
using const_view_1d = Field::view_dev_t;
+ using const_view_2d = Field::view_dev_t;
using const_view_3d = Field::view_dev_t;
private:
@@ -45,7 +49,6 @@ class MAMDryDep final : public scream::AtmosphereProcess {
// physics grid for column information
std::shared_ptr grid_;
-
/* Note on mam4::DryDeposition::aerosol_categories = 4
used in deposition velocity dimension defined below. These
correspond to the two attachment states and two moments:
@@ -64,14 +67,13 @@ class MAMDryDep final : public scream::AtmosphereProcess {
// Dimensions
// [num_modes, aerosol_categories_, num columns, num levels]
view_4d vlc_grv_;
-
+
// Output deposition velocity, [m/s]
- // fraction landuse weighted sum of vlc_grv and vlc_trb
+ // fraction landuse weighted sum of vlc_grv and vlc_trb
// Dimensions
// [num_modes, aerosol_categories_, num columns, num levels]
view_4d vlc_dry_;
-
// Output of the the mixing ratio tendencies [kg/kg/s or 1/kg/s]
// Dimensions
// [num columns, num levels, mam4::aero_model::pcnst]
@@ -81,25 +83,18 @@ class MAMDryDep final : public scream::AtmosphereProcess {
// Work array to hold the mixing ratios [kg/kg or 1/kg]
// Dimensions
// [num columns, num levels, mam4::aero_model::pcnst]
- // Packs AerosolState::int_aero_nmr
+ // Packs AerosolState::int_aero_nmr
// and AerosolState::int_aero_nmr
// into one array, hence is mixed kg/kg and 1/kg.
view_3d qtracers_;
- // Work array to hold the fraction [non-dimentional]
- // of land use for column.
- // Dimensions
- // [MAMDryDep::n_land_type, num columns]
- // Values should sum to 1.
- view_2d fraction_landuse_;
-
// Work array to hold the air density [kg/m3]
// Dimensions
// [num columns, num levels]
// Calculated from air pressure at layer midpoint,
// Constants::r_gas_dry_air and air temperture.
view_2d rho_;
-
+
// Work array to hold tendency for 1 species [kg/kg/s] or [1/kg/s]
// Dimensions
// [mam4::aero_model::pcnst, num column, num level]
@@ -111,6 +106,11 @@ class MAMDryDep final : public scream::AtmosphereProcess {
// 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_;
+
public:
using KT = ekat::KokkosTypes;
diff --git a/components/eamxx/src/physics/mam/readfiles/fractional_land_use.hpp b/components/eamxx/src/physics/mam/readfiles/fractional_land_use.hpp
new file mode 100644
index 00000000000..1dba53c38ed
--- /dev/null
+++ b/components/eamxx/src/physics/mam/readfiles/fractional_land_use.hpp
@@ -0,0 +1,59 @@
+#ifndef FRACTIONAL_LANDUSE_HPP
+#define FRACTIONAL_LANDUSE_HPP
+
+// For AtmosphereInput
+#include "share/io/scorpio_input.hpp"
+
+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"
\ No newline at end of file
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
new file mode 100644
index 00000000000..8bddd390e19
--- /dev/null
+++ b/components/eamxx/src/physics/mam/readfiles/fractional_land_use_impl.hpp
@@ -0,0 +1,148 @@
+#ifndef FRACTIONAL_LANDUSE_IMPL_HPP
+#define FRACTIONAL_LANDUSE_IMPL_HPP
+
+#include "share/grid/remap/identity_remapper.hpp"
+#include "share/grid/remap/refining_remapper_p2p.hpp"
+#include "share/io/scream_scorpio_interface.hpp"
+#include "share/util/scream_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);
+ }
+
+ remapper->registration_begins();
+
+ const auto tgt_grid = remapper->get_tgt_grid();
+
+ const auto layout_2d = tgt_grid->get_2d_vector_layout(nclass_data, "class");
+ const auto nondim = ekat::units::Units::nondimensional();
+
+ Field fractional_land_use(
+ FieldIdentifier(field_name, layout_2d, nondim, 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();
+ return std::make_shared(data_file, io_grid, io_fields, true);
+} // create_data_reader
+
+// -------------------------------------------------------------------------------------------
+// -------------------------------------------------------------------------------------------
+
+template
+void fracLandUseFunctions::update_frac_land_use_data_from_file(
+ std::shared_ptr &scorpio_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");
+ scorpio_reader->read_variables();
+ 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(/*forward = */ true);
+ 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 AtmosphereInput object)
+ FracLandUseDataReader = create_data_reader(FracLandUseHorizInterp, data_file);
+} // init_frac_landuse_file_read
+
+} // namespace frac_landuse
+} // namespace scream
+
+#endif // FRACTIONAL_LANDUSE_IMPL_HPP
diff --git a/components/eamxx/tests/multi-process/dynamics_physics/mam/homme_shoc_cld_mam_aci_p3_mam_optics_rrtmgp_mam_drydep/CMakeLists.txt b/components/eamxx/tests/multi-process/dynamics_physics/mam/homme_shoc_cld_mam_aci_p3_mam_optics_rrtmgp_mam_drydep/CMakeLists.txt
index e3c562cfcd1..43ec03b0cd6 100644
--- a/components/eamxx/tests/multi-process/dynamics_physics/mam/homme_shoc_cld_mam_aci_p3_mam_optics_rrtmgp_mam_drydep/CMakeLists.txt
+++ b/components/eamxx/tests/multi-process/dynamics_physics/mam/homme_shoc_cld_mam_aci_p3_mam_optics_rrtmgp_mam_drydep/CMakeLists.txt
@@ -79,6 +79,7 @@ set (TEST_INPUT_FILES
scream/mam4xx/physprops/ocpho_rrtmg_c20240206.nc
scream/mam4xx/physprops/bcpho_rrtmg_c20240206.nc
scream/mam4xx/physprops/poly_rrtmg_c20240206.nc
+ scream/mam4xx/drydep/ne2np4/atmsrf_ne2np4_c20241017.nc
)
foreach (file IN ITEMS ${TEST_INPUT_FILES})
diff --git a/components/eamxx/tests/multi-process/dynamics_physics/mam/homme_shoc_cld_mam_aci_p3_mam_optics_rrtmgp_mam_drydep/input.yaml b/components/eamxx/tests/multi-process/dynamics_physics/mam/homme_shoc_cld_mam_aci_p3_mam_optics_rrtmgp_mam_drydep/input.yaml
index 1857bc534dd..3dbd99682fd 100644
--- a/components/eamxx/tests/multi-process/dynamics_physics/mam/homme_shoc_cld_mam_aci_p3_mam_optics_rrtmgp_mam_drydep/input.yaml
+++ b/components/eamxx/tests/multi-process/dynamics_physics/mam/homme_shoc_cld_mam_aci_p3_mam_optics_rrtmgp_mam_drydep/input.yaml
@@ -96,6 +96,10 @@ atmosphere_processes:
rrtmgp_cloud_optics_file_sw: ${SCREAM_DATA_DIR}/init/rrtmgp-cloud-optics-coeffs-sw.nc
rrtmgp_cloud_optics_file_lw: ${SCREAM_DATA_DIR}/init/rrtmgp-cloud-optics-coeffs-lw.nc
enable_column_conservation_checks: true
+ mam4_drydep:
+ # Fractional land use file
+ drydep_remap_file: ""
+ fractional_land_use_file: ${SCREAM_DATA_DIR}/mam4xx/drydep/ne2np4/atmsrf_ne2np4_c20241017.nc
grids_manager:
Type: Homme
diff --git a/components/eamxx/tests/multi-process/physics_only/mam/shoc_mam4_drydep/CMakeLists.txt b/components/eamxx/tests/multi-process/physics_only/mam/shoc_mam4_drydep/CMakeLists.txt
index 9f6fb8733c2..d64cc7eebaf 100644
--- a/components/eamxx/tests/multi-process/physics_only/mam/shoc_mam4_drydep/CMakeLists.txt
+++ b/components/eamxx/tests/multi-process/physics_only/mam/shoc_mam4_drydep/CMakeLists.txt
@@ -21,6 +21,13 @@ set (SHOC_MAX_DT 300)
math (EXPR MAC_MIC_SUBCYCLES "(${ATM_TIME_STEP} + ${SHOC_MAX_DT} - 1) / ${SHOC_MAX_DT}")
# Ensure test input files are present in the data dir
+set (TEST_INPUT_FILES
+ scream/mam4xx/drydep/ne2np4/atmsrf_ne2np4_c20241017.nc
+)
+foreach (file IN ITEMS ${TEST_INPUT_FILES})
+ GetInputFile(${file})
+endforeach()
+
GetInputFile(scream/init/${EAMxx_tests_IC_FILE_MAM4xx_72lev})
GetInputFile(cam/topo/${EAMxx_tests_TOPO_FILE})
diff --git a/components/eamxx/tests/multi-process/physics_only/mam/shoc_mam4_drydep/input.yaml b/components/eamxx/tests/multi-process/physics_only/mam/shoc_mam4_drydep/input.yaml
index c451008adc7..24f610f041c 100644
--- a/components/eamxx/tests/multi-process/physics_only/mam/shoc_mam4_drydep/input.yaml
+++ b/components/eamxx/tests/multi-process/physics_only/mam/shoc_mam4_drydep/input.yaml
@@ -29,6 +29,10 @@ atmosphere_processes:
c_diag_3rd_mom: 7.0
Ckh: 0.1
Ckm: 0.1
+ mam4_drydep:
+ # Fractional land use file
+ drydep_remap_file: ""
+ fractional_land_use_file: ${SCREAM_DATA_DIR}/mam4xx/drydep/ne2np4/atmsrf_ne2np4_c20241017.nc
grids_manager:
Type: Mesh Free
diff --git a/components/eamxx/tests/single-process/mam/drydep/CMakeLists.txt b/components/eamxx/tests/single-process/mam/drydep/CMakeLists.txt
index d05e6823642..413e6be630c 100644
--- a/components/eamxx/tests/single-process/mam/drydep/CMakeLists.txt
+++ b/components/eamxx/tests/single-process/mam/drydep/CMakeLists.txt
@@ -23,6 +23,13 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/output.yaml
${CMAKE_CURRENT_BINARY_DIR}/output.yaml)
# Ensure test input files are present in the data dir
+set (TEST_INPUT_FILES
+ scream/mam4xx/drydep/ne2np4/atmsrf_ne2np4_c20241017.nc
+)
+foreach (file IN ITEMS ${TEST_INPUT_FILES})
+ GetInputFile(${file})
+endforeach()
+
GetInputFile(scream/init/${EAMxx_tests_IC_FILE_MAM4xx_72lev})
GetInputFile(cam/topo/${EAMxx_tests_TOPO_FILE})
diff --git a/components/eamxx/tests/single-process/mam/drydep/input.yaml b/components/eamxx/tests/single-process/mam/drydep/input.yaml
index 86c6dd8766a..4ae00b20297 100644
--- a/components/eamxx/tests/single-process/mam/drydep/input.yaml
+++ b/components/eamxx/tests/single-process/mam/drydep/input.yaml
@@ -10,6 +10,10 @@ time_stepping:
atmosphere_processes:
atm_procs_list: [mam4_drydep]
+ mam4_drydep:
+ # Fractional land use file
+ drydep_remap_file: ""
+ fractional_land_use_file: ${SCREAM_DATA_DIR}/mam4xx/drydep/ne2np4/atmsrf_ne2np4_c20241017.nc
grids_manager:
Type: Mesh Free
diff --git a/components/homme/src/theta-l/share/prim_state_mod.F90 b/components/homme/src/theta-l/share/prim_state_mod.F90
index 75c6089f62a..835dfd2ddf3 100644
--- a/components/homme/src/theta-l/share/prim_state_mod.F90
+++ b/components/homme/src/theta-l/share/prim_state_mod.F90
@@ -793,7 +793,7 @@ subroutine prim_printstate(elem, tl,hybrid,hvcoord,nets,nete)
write(iulog,100) "(E-E0)/E0 ",(TOTE(2)-TOTE0)/TOTE0
do q=1,qsize
if(Qmass0(q)>0.0D0) then
- write(iulog,'(a,E23.15,a,i1)') "(Q-Q0)/Q0 ",(Qmass(q,2)-Qmass0(q))/Qmass0(q)," Q",q
+ write(iulog,'(a,E23.15,a,i2)') "(Q-Q0)/Q0 ",(Qmass(q,2)-Qmass0(q))/Qmass0(q)," Q",q
end if
enddo
endif