diff --git a/components/eamxx/src/physics/mam/CMakeLists.txt b/components/eamxx/src/physics/mam/CMakeLists.txt index 6339c85aef0..e4151707753 100644 --- a/components/eamxx/src/physics/mam/CMakeLists.txt +++ b/components/eamxx/src/physics/mam/CMakeLists.txt @@ -45,7 +45,6 @@ add_library(mam eamxx_mam_optics_process_interface.cpp eamxx_mam_dry_deposition_process_interface.cpp eamxx_mam_aci_process_interface.cpp) - target_compile_definitions(mam PUBLIC EAMXX_HAS_MAM) add_dependencies(mam mam4xx) target_include_directories(mam PUBLIC 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 c7f2471c447..ebbab7ab757 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 @@ -145,7 +145,7 @@ void MAMDryDep::set_grids( //----------- Variables from other mam4xx processes ------------ // Geometric mean wet diameter for number distribution [m] - add_field("dgncur_awet", scalar4d_mid, m, grid_name); + add_field("dgnumwet", scalar4d_mid, m, grid_name); // Wet density of interstitial aerosol [kg/m3] add_field("wetdens", scalar4d_mid, kg / m3, grid_name); @@ -355,7 +355,6 @@ void MAMDryDep::initialize_impl(const RunType run_type) { // ========================================================================================= void MAMDryDep::run_impl(const double dt) { - const auto scan_policy = ekat::ExeSpaceUtils< KT::ExeSpace>::get_thread_range_parallel_scan_team_policy(ncol_, nlev_); @@ -368,7 +367,7 @@ void MAMDryDep::run_impl(const double dt) { // ------------------------------------------------------------- // Geometric mean wet diameter for number distribution [m] - auto dgncur_awet_ = get_field_in("dgncur_awet").get_view(); + auto dgncur_awet_ = get_field_in("dgnumwet").get_view(); // Wet density of interstitial aerosol [kg/m3] auto wet_dens_ = get_field_in("wetdens").get_view(); // Obukhov length [m] @@ -401,10 +400,10 @@ 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 + // FIXME: remove it if it read from a file populated_fraction_landuse(fraction_landuse_, ncol_); - //Call drydeposition and get tendencies + // Call drydeposition and get tendencies compute_tendencies(ncol_, nlev_, dt, obukhov_length_, surface_friction_velocty_, land_fraction_, ice_fraction_, ocean_fraction_, friction_velocity_, diff --git a/components/eamxx/src/physics/mam/impl/compute_water_content.cpp b/components/eamxx/src/physics/mam/impl/compute_water_content.cpp index 673fe06292e..ea7190afff9 100644 --- a/components/eamxx/src/physics/mam/impl/compute_water_content.cpp +++ b/components/eamxx/src/physics/mam/impl/compute_water_content.cpp @@ -23,7 +23,7 @@ void compute_water_content(const mam4::Prognostics &progs, int k, // extract aerosol tracers for this level into state_q, which is needed // for computing dry aerosol properties below // FIXME: we should eliminate this index translation stuff - constexpr int nvars = mam4::aero_model::pcnst; + constexpr int nvars = aero_model::pcnst; Real state_q[nvars]; // aerosol tracers for level k for (int imode = 0; imode < num_modes; ++imode) { int la, lc; // interstitial and cloudborne indices within state_q diff --git a/components/eamxx/src/physics/mam/mam_coupling.hpp b/components/eamxx/src/physics/mam/mam_coupling.hpp index 8e77ae2484b..1e13cece98d 100644 --- a/components/eamxx/src/physics/mam/mam_coupling.hpp +++ b/components/eamxx/src/physics/mam/mam_coupling.hpp @@ -251,10 +251,7 @@ const char* cld_aero_mmr_field_name(const int mode, const int species) { // mixing ratio field in EAMxx KOKKOS_INLINE_FUNCTION const char* gas_mmr_field_name(const int gas) { - if (!gas_mmr_names(gas)[0]) { - concat_2_strings("", gas_species_name(gas), gas_mmr_names(gas)); - } - return gas_mmr_names(gas); + return const_cast(gas_species_name(gas)); } // This type stores multi-column views related specifically to the wet @@ -351,9 +348,8 @@ struct Buffer { // ======================= // number of local fields stored at column interfaces - static constexpr int num_2d_iface = 2; + static constexpr int num_2d_iface = 1; - uview_2d p_int; // pressure at interfaces uview_2d z_iface; // height at interfaces // storage @@ -469,7 +465,6 @@ inline size_t init_buffer(const ATMBufferManager &buffer_manager, // set view pointers for interface fields uview_2d* view_2d_iface_ptrs[Buffer::num_2d_iface] = { - &buffer.p_int, &buffer.z_iface }; for (int i = 0; i < Buffer::num_2d_iface; ++i) { @@ -524,8 +519,6 @@ haero::Atmosphere atmosphere_for_column(const DryAtmosphere& dry_atm, "cldfrac not defined for dry atmosphere state!"); EKAT_KERNEL_ASSERT_MSG(dry_atm.w_updraft.data() != nullptr, "w_updraft not defined for dry atmosphere state!"); - EKAT_KERNEL_ASSERT_MSG(dry_atm.p_int.data() != nullptr, - "p_int not defined for dry atmosphere state!"); return haero::Atmosphere(mam4::nlev, ekat::subview(dry_atm.T_mid, column_index), ekat::subview(dry_atm.p_mid, column_index), @@ -656,11 +649,11 @@ void compute_dry_mixing_ratios(const Team& team, int i = column_index; Kokkos::parallel_for(Kokkos::TeamVectorRange(team, nlev), [&] (const int k) { const auto qv_ik = wet_atm.qv(i,k); - dry_atm.qv(i,k) = wet_atm.qv(i,k);//PF::calculate_drymmr_from_wetmmr(wet_atm.qv(i,k), qv_ik); - dry_atm.qc(i,k) = wet_atm.qc(i,k);//PF::calculate_drymmr_from_wetmmr(wet_atm.qc(i,k), qv_ik); - dry_atm.nc(i,k) = wet_atm.nc(i,k);//PF::calculate_drymmr_from_wetmmr(wet_atm.nc(i,k), qv_ik); - dry_atm.qi(i,k) = wet_atm.qi(i,k);//PF::calculate_drymmr_from_wetmmr(wet_atm.qi(i,k), qv_ik); - dry_atm.ni(i,k) = wet_atm.ni(i,k);//PF::calculate_drymmr_from_wetmmr(wet_atm.ni(i,k), qv_ik); + dry_atm.qv(i,k) = PF::calculate_drymmr_from_wetmmr(wet_atm.qv(i,k), qv_ik); + dry_atm.qc(i,k) = PF::calculate_drymmr_from_wetmmr(wet_atm.qc(i,k), qv_ik); + dry_atm.nc(i,k) = PF::calculate_drymmr_from_wetmmr(wet_atm.nc(i,k), qv_ik); + dry_atm.qi(i,k) = PF::calculate_drymmr_from_wetmmr(wet_atm.qi(i,k), qv_ik); + dry_atm.ni(i,k) = PF::calculate_drymmr_from_wetmmr(wet_atm.ni(i,k), qv_ik); }); } @@ -681,21 +674,21 @@ void compute_dry_mixing_ratios(const Team& team, Kokkos::parallel_for(Kokkos::TeamVectorRange(team, nlev), [&] (const int k) { const auto qv_ik = wet_atm.qv(i,k); for (int m = 0; m < num_aero_modes(); ++m) { - dry_aero.int_aero_nmr[m](i,k) = wet_aero.int_aero_nmr[m](i,k);//PF::calculate_drymmr_from_wetmmr(wet_aero.int_aero_nmr[m](i,k), qv_ik); + dry_aero.int_aero_nmr[m](i,k) = PF::calculate_drymmr_from_wetmmr(wet_aero.int_aero_nmr[m](i,k), qv_ik); if (dry_aero.cld_aero_nmr[m].data()) { - dry_aero.cld_aero_nmr[m](i,k) = wet_aero.cld_aero_nmr[m](i,k);// PF::calculate_drymmr_from_wetmmr(wet_aero.cld_aero_nmr[m](i,k), qv_ik); + dry_aero.cld_aero_nmr[m](i,k) = PF::calculate_drymmr_from_wetmmr(wet_aero.cld_aero_nmr[m](i,k), qv_ik); } for (int a = 0; a < num_aero_species(); ++a) { if (dry_aero.int_aero_mmr[m][a].data()) { - dry_aero.int_aero_mmr[m][a](i,k) = wet_aero.int_aero_mmr[m][a](i,k);//PF::calculate_drymmr_from_wetmmr(wet_aero.int_aero_mmr[m][a](i,k), qv_ik); + dry_aero.int_aero_mmr[m][a](i,k) = PF::calculate_drymmr_from_wetmmr(wet_aero.int_aero_mmr[m][a](i,k), qv_ik); } if (dry_aero.cld_aero_mmr[m][a].data()) { - dry_aero.cld_aero_mmr[m][a](i,k) = wet_aero.cld_aero_mmr[m][a](i,k);//PF::calculate_drymmr_from_wetmmr(wet_aero.cld_aero_mmr[m][a](i,k), qv_ik); + dry_aero.cld_aero_mmr[m][a](i,k) = PF::calculate_drymmr_from_wetmmr(wet_aero.cld_aero_mmr[m][a](i,k), qv_ik); } } } for (int g = 0; g < num_aero_gases(); ++g) { - dry_aero.gas_mmr[g](i,k) = wet_aero.gas_mmr[g](i,k);//PF::calculate_drymmr_from_wetmmr(wet_aero.gas_mmr[g](i,k), qv_ik); + dry_aero.gas_mmr[g](i,k) = PF::calculate_drymmr_from_wetmmr(wet_aero.gas_mmr[g](i,k), qv_ik); } }); } @@ -766,7 +759,7 @@ void copy_view_lev_slice(haero::ThreadTeamPolicy team_policy, //inputs const auto PC = mam4::ModeIndex::PrimaryCarbon; \ const auto NoMode = mam4::ModeIndex::None; \ static const mam4::ModeIndex mode_for_cnst[gas_pcnst()] = { \ - NoMode, NoMode, NoMode, NoMode, NoMode, NoMode, /* gases (not aerosols) */ \ + NoMode, NoMode, NoMode, NoMode, NoMode, NoMode, /* gases (not aerosols) */ \ Accum, Accum, Accum, Accum, Accum, Accum, Accum, Accum, /* 7 aero species + NMR */ \ Aitken, Aitken, Aitken, Aitken, Aitken, /* 4 aero species + NMR */ \ Coarse, Coarse, Coarse, Coarse, Coarse, Coarse, Coarse, Coarse, /* 7 aero species + NMR */ \ diff --git a/components/eamxx/src/share/field/field_tag.hpp b/components/eamxx/src/share/field/field_tag.hpp index e500250b80f..673208d6ae8 100644 --- a/components/eamxx/src/share/field/field_tag.hpp +++ b/components/eamxx/src/share/field/field_tag.hpp @@ -34,15 +34,6 @@ enum class FieldTag { GaussPoint, Component, TimeLevel, - // Added for RRTMGP, TODO: Revisit this approach, is there a better way than adding more field tags? - Gases, - ShortWaveBand, - ShortWaveGpoint, - LongWaveBand, - LongWaveGpoint, - IsccpTau, - IsccpPrs, - num_modes }; // If using tags a lot, consider adding 'using namespace ShortFieldTagsNames' @@ -59,15 +50,6 @@ namespace ShortFieldTagsNames { constexpr auto LEV = FieldTag::LevelMidPoint; constexpr auto ILEV = FieldTag::LevelInterface; constexpr auto CMP = FieldTag::Component; - // Added for rrtmgp - see TODO item above - constexpr auto NGAS = FieldTag::Gases; - constexpr auto SWBND = FieldTag::ShortWaveBand; - constexpr auto LWBND = FieldTag::LongWaveBand; - constexpr auto SWGPT = FieldTag::ShortWaveGpoint; - constexpr auto LWGPT = FieldTag::LongWaveGpoint; - constexpr auto ISCCPTAU = FieldTag::IsccpTau; - constexpr auto ISCCPPRS = FieldTag::IsccpPrs; - constexpr auto NMODES = FieldTag::num_modes; } inline std::string e2str (const FieldTag ft) { @@ -98,31 +80,6 @@ inline std::string e2str (const FieldTag ft) { case FieldTag::Component: name = "dim"; break; - // Added for rrtmgp - see TODO item above - case FieldTag::Gases: - name = "ngas"; - break; - case FieldTag::ShortWaveBand: - name = "swband"; - break; - case FieldTag::ShortWaveGpoint: - name = "swgpt"; - break; - case FieldTag::LongWaveBand: - name = "lwband"; - break; - case FieldTag::LongWaveGpoint: - name = "lwgpt"; - break; - case FieldTag::IsccpTau: - name = "ISCCPTAU"; - break; - case FieldTag::IsccpPrs: - name = "ISCCPPRS"; - break; - case FieldTag::num_modes: - name = "num_modes"; - break; default: EKAT_ERROR_MSG("Error! Unrecognized field tag."); } diff --git a/components/eamxx/tests/CMakeLists.txt b/components/eamxx/tests/CMakeLists.txt index 635f5de80a8..5fd23a41d9d 100644 --- a/components/eamxx/tests/CMakeLists.txt +++ b/components/eamxx/tests/CMakeLists.txt @@ -63,7 +63,6 @@ if (NOT DEFINED ENV{SCREAM_FAKE_ONLY}) set(EAMxx_tests_IC_FILE_72lev "screami_unit_tests_ne2np4L72_20220822.nc") set(EAMxx_tests_IC_FILE_128lev "screami_unit_tests_ne2np4L128_20220822.nc") set(EAMxx_tests_TOPO_FILE "USGS-gtopo30_ne2np4pg2_x6t_20230331.nc") - set(EAMxx_tests_IC_FILE_MAM "scream_unit_tests_aerosol_optics_ne2np4L72_20220822.nc") set(EAMxx_tests_IC_FILE_MAM4xx_72lev "screami_unit_tests_mam4xx_ne2np4L72_20240329.nc") # Testing individual atm processes diff --git a/components/eamxx/tests/single-process/mam/drydep/CMakeLists.txt b/components/eamxx/tests/single-process/mam/drydep/CMakeLists.txt index 698b9cb7b54..d05e6823642 100644 --- a/components/eamxx/tests/single-process/mam/drydep/CMakeLists.txt +++ b/components/eamxx/tests/single-process/mam/drydep/CMakeLists.txt @@ -1,18 +1,19 @@ include (ScreamUtils) set (TEST_BASE_NAME mam4_drydep_standalone) +set (FIXTURES_BASE_NAME ${TEST_BASE_NAME}_generate_output_nc_files) # Create the test CreateADUnitTest(${TEST_BASE_NAME} LABELS mam4_drydep physics LIBS mam MPI_RANKS ${TEST_RANK_START} ${TEST_RANK_END} + FIXTURES_SETUP_INDIVIDUAL ${FIXTURES_BASE_NAME} ) # Set AD configurable options -set (ATM_TIME_STEP 3600) -SetVarDependingOnTestSize(NUM_STEPS 12 24 36) -SetVarDependingOnTestSize(NUM_STEPS 1 1 1) +set (ATM_TIME_STEP 1800) +SetVarDependingOnTestSize(NUM_STEPS 2 5 48) # 1h 2.5h 24h set (RUN_T0 2021-10-12-45000) ## Copy (and configure) yaml files needed by tests @@ -24,3 +25,22 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/output.yaml # Ensure test input files are present in the data dir GetInputFile(scream/init/${EAMxx_tests_IC_FILE_MAM4xx_72lev}) GetInputFile(cam/topo/${EAMxx_tests_TOPO_FILE}) + +# Compare output files produced by npX tests, to ensure they are bfb +include (CompareNCFiles) + +CompareNCFilesFamilyMpi ( + TEST_BASE_NAME ${TEST_BASE_NAME} + FILE_META_NAME ${TEST_BASE_NAME}_output.INSTANT.nsteps_x1.npMPIRANKS.${RUN_T0}.nc + MPI_RANKS ${TEST_RANK_START} ${TEST_RANK_END} + LABELS mam4_drydep physics + META_FIXTURES_REQUIRED ${FIXTURES_BASE_NAME}_npMPIRANKS_omp1 +) + +if (SCREAM_ENABLE_BASELINE_TESTS) + # Compare one of the output files with the baselines. + # Note: one is enough, since we already check that np1 is BFB with npX + set (OUT_FILE ${TEST_BASE_NAME}_output.INSTANT.nsteps_x1.np${TEST_RANK_END}.${RUN_T0}.nc) + CreateBaselineTest(${TEST_BASE_NAME} ${TEST_RANK_END} ${OUT_FILE} ${FIXTURES_BASE_NAME}) +endif() + diff --git a/components/eamxx/tests/single-process/mam/drydep/input.yaml b/components/eamxx/tests/single-process/mam/drydep/input.yaml index a95faf9047a..1de57ad7e68 100644 --- a/components/eamxx/tests/single-process/mam/drydep/input.yaml +++ b/components/eamxx/tests/single-process/mam/drydep/input.yaml @@ -23,11 +23,20 @@ grids_manager: initial_conditions: # The name of the file containing the initial conditions for this test. - Filename: /qfs/people/sing201/eagles/refactor_mam/mam4xx_scream/3src/screami_unit_tests_mam4xx_ne2np4L72_LAT_m38.0068938875434_LON_16p9323465700125_DRYDEP.nc + Filename: ${SCREAM_DATA_DIR}/init/${EAMxx_tests_IC_FILE_MAM4xx_72lev} topography_filename: ${TOPO_DATA_DIR}/${EAMxx_tests_TOPO_FILE} fraction_landuse: 0.2 w_updraft: 1e-5 pbl_height: 0.0 + Obukhov_length: -0.48167567011091336E+002 + friction_velocity: 0.47569674433601039E+000 + land_fraction: 0.14675684171817760E+000 + ice_fraction: 0.00000000000000000E+000 + ocean_fraction: 0.85324315828182240E+000 + surface_friction_velocty: 0.27482164092221828E+000 + aerodynamical_resistance: 0.45506166067091662E+002 + dgnumwet: 0.41417721820867320E-007 + wetdens: 0.15100083211582764E+004 # The parameters for I/O control Scorpio: diff --git a/components/eamxx/tests/single-process/mam/drydep/output.yaml b/components/eamxx/tests/single-process/mam/drydep/output.yaml index e900bb80434..6d8a79e8fe0 100644 --- a/components/eamxx/tests/single-process/mam/drydep/output.yaml +++ b/components/eamxx/tests/single-process/mam/drydep/output.yaml @@ -2,10 +2,63 @@ --- filename_prefix: mam4_drydep_standalone_output Averaging Type: Instant -Field Names: - - T_mid +Fields: + Physics: + Field Names: + - bc_a1 + - bc_a3 + - bc_a4 + - dst_a1 + - dst_a3 + - so4_a1 + - so4_a2 + - so4_a3 + - pom_a1 + - pom_a3 + - pom_a4 + - soa_a1 + - soa_a2 + - soa_a3 + - nacl_a1 + - nacl_a2 + - nacl_a3 + - mom_a1 + - mom_a2 + - mom_a3 + - mom_a4 + - num_a1 + - num_a2 + - num_a3 + - num_a4 + - bc_c1 + - bc_c3 + - bc_c4 + - dst_c1 + - dst_c3 + - so4_c1 + - so4_c2 + - so4_c3 + - pom_c1 + - pom_c3 + - pom_c4 + - soa_c1 + - soa_c2 + - soa_c3 + - nacl_c1 + - nacl_c2 + - nacl_c3 + - mom_c1 + - mom_c2 + - mom_c3 + - mom_c4 + - num_c1 + - num_c2 + - num_c3 + - num_c4 + - deposition_flux_of_cloud_borne_aerosols + - deposition_flux_of_interstitial_aerosols + output_control: Frequency: 1 frequency_units: nsteps - MPI Ranks in Filename: true ...