Skip to content

Commit

Permalink
Merge pull request #3083 from E3SM-Project/mjs/eamxx/aero_emis_interface
Browse files Browse the repository at this point in the history
  • Loading branch information
bartgol authored Nov 19, 2024
2 parents e98c12b + 71e4bc5 commit 0af3b66
Show file tree
Hide file tree
Showing 16 changed files with 1,102 additions and 85 deletions.
15 changes: 5 additions & 10 deletions components/eamxx/cime_config/namelist_defaults_scream.xml
Original file line number Diff line number Diff line change
Expand Up @@ -372,17 +372,11 @@ be lost if SCREAM_HACK_XML is not enabled.
<srf_emis_specifier_for_so4_a1 hgrid="ne4np4.pg2" type="file" doc="File containing surface emissions data for so4_a1">${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/cmip6_mam4_so4_a1_surf_ne4pg2_2010_clim_c20240815.nc</srf_emis_specifier_for_so4_a1>
<srf_emis_specifier_for_so4_a2 hgrid="ne4np4.pg2" type="file" doc="File containing surface emissions data for so4_a2">${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/cmip6_mam4_so4_a2_surf_ne4pg2_2010_clim_c20240815.nc</srf_emis_specifier_for_so4_a2>

<soil_erodibility_file type="file" doc="File containing soil erodibility">${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/dst_ne30pg2_c20241028.nc</soil_erodibility_file>
<soil_erodibility_file hgrid="ne4np4.pg2" type="file" doc="File containing soil erodibility">${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/dst_ne4pg2_c20241028.nc</soil_erodibility_file>

<!-- For ne4pg2 grid -->
<srf_emis_specifier_for_DMS hgrid="ne4np4.pg2" type="file" doc="File containing surface emissions data for DMS">${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/DMSflux.2010.ne4pg2_conserv.POPmonthlyClimFromACES4BGC_c20240814.nc</srf_emis_specifier_for_DMS>
<srf_emis_specifier_for_SO2 hgrid="ne4np4.pg2" type="file" doc="File containing surface emissions data for SO2">${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/cmip6_mam4_so2_surf_ne4pg2_2010_clim_c20240815.nc</srf_emis_specifier_for_SO2>
<srf_emis_specifier_for_bc_a4 hgrid="ne4np4.pg2" type="file" doc="File containing surface emissions data for bc_a4">${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/cmip6_mam4_bc_a4_surf_ne4pg2_2010_clim_c20240815.nc</srf_emis_specifier_for_bc_a4>
<srf_emis_specifier_for_num_a1 hgrid="ne4np4.pg2" type="file" doc="File containing surface emissions data for num_a1">${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/cmip6_mam4_num_a1_surf_ne4pg2_2010_clim_c20240815.nc</srf_emis_specifier_for_num_a1>
<srf_emis_specifier_for_num_a2 hgrid="ne4np4.pg2" type="file" doc="File containing surface emissions data for num_a2">${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/cmip6_mam4_num_a2_surf_ne4pg2_2010_clim_c20240815.nc</srf_emis_specifier_for_num_a2>
<srf_emis_specifier_for_num_a4 hgrid="ne4np4.pg2" type="file" doc="File containing surface emissions data for num_a4">${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/cmip6_mam4_num_a4_surf_ne4pg2_2010_clim_c20240815.nc</srf_emis_specifier_for_num_a4>
<srf_emis_specifier_for_pom_a4 hgrid="ne4np4.pg2" type="file" doc="File containing surface emissions data for pom_a4">${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/cmip6_mam4_pom_a4_surf_ne4pg2_2010_clim_c20240815.nc</srf_emis_specifier_for_pom_a4>
<srf_emis_specifier_for_so4_a1 hgrid="ne4np4.pg2" type="file" doc="File containing surface emissions data for so4_a1">${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/cmip6_mam4_so4_a1_surf_ne4pg2_2010_clim_c20240815.nc</srf_emis_specifier_for_so4_a1>
<srf_emis_specifier_for_so4_a2 hgrid="ne4np4.pg2" type="file" doc="File containing surface emissions data for so4_a2">${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/cmip6_mam4_so4_a2_surf_ne4pg2_2010_clim_c20240815.nc</srf_emis_specifier_for_so4_a2>
<marine_organics_file type="file" doc="File containing marine organics emissions">${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/monthly_macromolecules_0.1deg_bilinear_year01_merge_ne30pg2_c20241030.nc</marine_organics_file>
<marine_organics_file hgrid="ne4np4.pg2" type="file" doc="File containing marine organics emissions">${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/monthly_macromolecules_0.1deg_bilinear_year01_merge_ne4pg2_c20241030.nc</marine_organics_file>

<!-- Mapping Files for finer resolutions -->
<srf_remap_file type="file" doc="File containing mapping data from the grid of emission files to the model grid. Unused if the grid is the same."/>
Expand Down Expand Up @@ -639,6 +633,7 @@ be lost if SCREAM_HACK_XML is not enabled.
<dgnum type="array(real)" doc="Dry aerosol particles diameters (one per mode) [m]">1.37146e-07 ,3.45899e-08 ,1.00000e-06 ,9.99601e-08</dgnum>
<dgnumwet type="array(real)" doc="Wet aerosol particles diameter [m]">1.37452e-07 ,3.46684e-08 ,1.00900e-06 ,9.99601e-08</dgnumwet>
<wetdens type="array(real)" doc="Wet density of interstitial aerosol [kg/m3]">5.08262e-12 ,1.54035e-13 ,3.09018e-13 ,9.14710e-22</wetdens>
<constituent_fluxes type="real">0.0</constituent_fluxes>
<bc_c1 type="real">0.0</bc_c1>
<bc_c3 type="real">0.0</bc_c3>
<bc_c4 type="real">0.0</bc_c4>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,35 +28,41 @@ void SurfaceCouplingImporter::set_grids(const std::shared_ptr<const GridsManager

// The units of mixing ratio Q are technically non-dimensional.
// Nevertheless, for output reasons, we like to see 'kg/kg'.
auto nondim = Units::nondimensional();
Units m2 (m*m,"m2");
constexpr auto nondim = Units::nondimensional();
constexpr auto m2 = pow(m, 2);

// Define the different field layouts that will be used for this process
using namespace ShortFieldTagsNames;

FieldLayout scalar2d_layout { {COL }, {m_num_cols } };
FieldLayout vector2d_layout { {COL, CMP}, {m_num_cols, 2} };

add_field<Computed>("sfc_alb_dir_vis", scalar2d_layout, nondim, grid_name);
add_field<Computed>("sfc_alb_dir_nir", scalar2d_layout, nondim, grid_name);
add_field<Computed>("sfc_alb_dif_vis", scalar2d_layout, nondim, grid_name);
add_field<Computed>("sfc_alb_dif_nir", scalar2d_layout, nondim, grid_name);
add_field<Computed>("surf_lw_flux_up", scalar2d_layout, W/m2, grid_name);
add_field<Computed>("surf_sens_flux", scalar2d_layout, W/m2, grid_name);
add_field<Computed>("surf_evap", scalar2d_layout, kg/m2/s, grid_name);
add_field<Computed>("surf_mom_flux", vector2d_layout, N/m2, grid_name);
add_field<Computed>("surf_radiative_T", scalar2d_layout, K, grid_name);
add_field<Computed>("T_2m", scalar2d_layout, K, grid_name);
add_field<Computed>("qv_2m", scalar2d_layout, kg/kg, grid_name);
add_field<Computed>("wind_speed_10m", scalar2d_layout, m/s, grid_name);
add_field<Computed>("snow_depth_land", scalar2d_layout, m, grid_name);
add_field<Computed>("ocnfrac", scalar2d_layout, nondim, grid_name);
add_field<Computed>("landfrac", scalar2d_layout, nondim, grid_name);
add_field<Computed>("icefrac", scalar2d_layout, nondim, grid_name);
const FieldLayout scalar2d = m_grid->get_2d_scalar_layout();
const FieldLayout vector2d = m_grid->get_2d_vector_layout(2);
const FieldLayout vector4d = m_grid->get_2d_vector_layout(4);

add_field<Computed>("sfc_alb_dir_vis", scalar2d, nondim, grid_name);
add_field<Computed>("sfc_alb_dir_nir", scalar2d, nondim, grid_name);
add_field<Computed>("sfc_alb_dif_vis", scalar2d, nondim, grid_name);
add_field<Computed>("sfc_alb_dif_nir", scalar2d, nondim, grid_name);
add_field<Computed>("surf_lw_flux_up", scalar2d, W/m2, grid_name);
add_field<Computed>("surf_sens_flux", scalar2d, W/m2, grid_name);
add_field<Computed>("surf_evap", scalar2d, kg/m2/s, grid_name);
add_field<Computed>("surf_mom_flux", vector2d, N/m2, grid_name);
add_field<Computed>("surf_radiative_T", scalar2d, K, grid_name);
add_field<Computed>("T_2m", scalar2d, K, grid_name);
add_field<Computed>("qv_2m", scalar2d, kg/kg, grid_name);
add_field<Computed>("wind_speed_10m", scalar2d, m/s, grid_name);
add_field<Computed>("snow_depth_land", scalar2d, m, grid_name);
add_field<Computed>("ocnfrac", scalar2d, nondim, grid_name);
add_field<Computed>("landfrac", scalar2d, nondim, grid_name);
add_field<Computed>("icefrac", scalar2d, nondim, grid_name);
// Friction velocity [m/s]
add_field<Computed>("fv", scalar2d_layout, m/s, grid_name);
add_field<Computed>("fv", scalar2d, m/s, grid_name);
// Aerodynamical resistance
add_field<Computed>("ram1", scalar2d_layout, s/m, grid_name);
add_field<Computed>("ram1", scalar2d, s/m, grid_name);
// Sea surface temperature [K]
add_field<Computed>("sst", scalar2d, K, grid_name);
//dust fluxes [kg/m^2/s]: Four flux values for eacch column
add_field<Computed>("dstflx", vector4d, kg/m2/s, grid_name);

}
// =========================================================================================
void SurfaceCouplingImporter::setup_surface_coupling_data(const SCDataManager &sc_data_manager)
Expand Down
20 changes: 19 additions & 1 deletion components/eamxx/src/mct_coupling/scream_cpl_indices.F90
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module scream_cpl_indices
private

! Focus only on the ones that scream imports/exports (subsets of x2a and a2x)
integer, parameter, public :: num_scream_imports = 19
integer, parameter, public :: num_scream_imports = 24
integer, parameter, public :: num_scream_exports = 17
integer, public :: num_cpl_imports, num_cpl_exports, import_field_size, export_field_size

Expand Down Expand Up @@ -92,6 +92,11 @@ subroutine scream_set_cpl_indices (x2a, a2x)
import_field_names(17) = 'icefrac'
import_field_names(18) = 'fv'
import_field_names(19) = 'ram1'
import_field_names(20) = 'sst'
import_field_names(21) = 'dstflx'
import_field_names(22) = 'dstflx'
import_field_names(23) = 'dstflx'
import_field_names(24) = 'dstflx'

! CPL indices
import_cpl_indices(1) = mct_avect_indexra(x2a,'Sx_avsdr')
Expand All @@ -113,10 +118,23 @@ subroutine scream_set_cpl_indices (x2a, a2x)
import_cpl_indices(17) = mct_avect_indexra(x2a,'Sf_ifrac')
import_cpl_indices(18) = mct_avect_indexra(x2a,'Sl_fv')
import_cpl_indices(19) = mct_avect_indexra(x2a,'Sl_ram1')
!sst
import_cpl_indices(20) = mct_avect_indexra(x2a,'So_t')
!dust fluxes
import_cpl_indices(21) = mct_avect_indexra(x2a,'Fall_flxdst1')
import_cpl_indices(22) = mct_avect_indexra(x2a,'Fall_flxdst2')
import_cpl_indices(23) = mct_avect_indexra(x2a,'Fall_flxdst3')
import_cpl_indices(24) = mct_avect_indexra(x2a,'Fall_flxdst4')

! Vector components
!(Faxx_taux and Faxx_tauy)
import_vector_components(11) = 0
import_vector_components(12) = 1
!(dust fluxes)
import_vector_components(21) = 0
import_vector_components(22) = 1
import_vector_components(23) = 2
import_vector_components(24) = 3

! Constant multiples
import_constant_multiple(10) = -1
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#ifndef EAMXX_MAM_SRF_AND_ONLINE_EMISSIONS_FUNCTIONS_HPP
#define EAMXX_MAM_SRF_AND_ONLINE_EMISSIONS_FUNCTIONS_HPP

namespace scream {

namespace {

using KT = ekat::KokkosTypes<DefaultDevice>;
using view_1d = typename KT::template view_1d<Real>;
using view_2d = typename KT::template view_2d<Real>;
using const_view_1d = typename KT::template view_1d<const Real>;
using const_view_2d = typename KT::template view_2d<const Real>;

//-------- Inititlize gas and aerosol fluxes ------
void init_fluxes(const int &ncol,
view_2d &constituent_fluxes) { // input-output

constexpr int pcnst = mam4::aero_model::pcnst;
const int gas_start_ind = mam4::utils::gasses_start_ind();

const auto policy =
ekat::ExeSpaceUtils<KT::ExeSpace>::get_default_team_policy(
ncol, pcnst - gas_start_ind);

// Parallel loop over all the columns
Kokkos::parallel_for(
policy, KOKKOS_LAMBDA(const KT::MemberType &team) {
const int icol = team.league_rank();
view_1d flux_col = ekat::subview(constituent_fluxes, icol);

// Zero out constituent fluxes only for gasses and aerosols
Kokkos::parallel_for(
Kokkos::TeamVectorRange(team, gas_start_ind, pcnst),
[&](int icnst) { flux_col(icnst) = 0; });
});
} // init_fluxes ends

//-------- compute online emissions for dust, sea salt and marine organics -----
void compute_online_dust_nacl_emiss(
const int &ncol, const int &nlev, const const_view_1d &ocnfrac,
const const_view_1d &sst, const const_view_2d &u_wind,
const const_view_2d &v_wind, const const_view_2d &dstflx,
const const_view_1d &mpoly, const const_view_1d &mprot,
const const_view_1d &mlip, const const_view_1d &soil_erodibility,
const const_view_2d &z_mid,
// output
view_2d &constituent_fluxes) {
const int surf_lev = nlev - 1; // surface level

Kokkos::parallel_for(
"online_emis_fluxes", ncol, KOKKOS_LAMBDA(int icol) {
// Input
const const_view_1d dstflx_icol = ekat::subview(dstflx, icol);

// Output
view_1d fluxes_col = ekat::subview(constituent_fluxes, icol);

// Compute online emissions
// NOTE: mam4::aero_model_emissions calculates mass and number emission
// fluxes in units of [kg/m2/s or #/m2/s] (MKS), so no need to convert
mam4::aero_model_emissions::aero_model_emissions(
sst(icol), ocnfrac(icol), u_wind(icol, surf_lev),
v_wind(icol, surf_lev), z_mid(icol, surf_lev), dstflx_icol,
soil_erodibility(icol), mpoly(icol), mprot(icol), mlip(icol),
// out
fluxes_col);
});
} // compute_online_dust_nacl_emiss ends

} // namespace
} // namespace scream

#endif // EAMXX_MAM_SRF_AND_ONLINE_EMISSIONS_FUNCTIONS_HPP
Loading

0 comments on commit 0af3b66

Please sign in to comment.