From 664c784092453530bfa63b988815fbba0d2153c6 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Mon, 7 Oct 2024 14:59:51 -0600 Subject: [PATCH 001/147] Initial step. Get it building with latest rrtmgp subm --- components/eam/src/physics/rrtmgp/external | 2 +- components/eamxx/CMakeLists.txt | 4 ++-- .../eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp | 7 ++----- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/components/eam/src/physics/rrtmgp/external b/components/eam/src/physics/rrtmgp/external index 8ff525eeed1d..b851a86aa931 160000 --- a/components/eam/src/physics/rrtmgp/external +++ b/components/eam/src/physics/rrtmgp/external @@ -1 +1 @@ -Subproject commit 8ff525eeed1d87a2ca6f251c4d16b46222c5554d +Subproject commit b851a86aa9312193f8f292f612e40afb056f90cf diff --git a/components/eamxx/CMakeLists.txt b/components/eamxx/CMakeLists.txt index 07c3cda76728..5a7149234a5f 100644 --- a/components/eamxx/CMakeLists.txt +++ b/components/eamxx/CMakeLists.txt @@ -212,8 +212,8 @@ endif() # #cmakedefine RRTMGP_EXPENSIVE_CHECKS option (SCREAM_RRTMGP_DEBUG "Turn on extra debug checks in RRTMGP" ${SCREAM_DEBUG}) -option(SCREAM_RRTMGP_ENABLE_YAKL "Use YAKL under rrtmgp" TRUE) -option(SCREAM_RRTMGP_ENABLE_KOKKOS "Use Kokkos under rrtmgp" FALSE) +option(SCREAM_RRTMGP_ENABLE_YAKL "Use YAKL under rrtmgp" FALSE) +option(SCREAM_RRTMGP_ENABLE_KOKKOS "Use Kokkos under rrtmgp" TRUE) if (SCREAM_RRTMGP_ENABLE_YAKL) add_definitions("-DRRTMGP_ENABLE_YAKL") endif() diff --git a/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp b/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp index 216722b3766b..55e6d87e1feb 100644 --- a/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp +++ b/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp @@ -167,9 +167,6 @@ using MDRP = typename conv::MDRP; template using view_t = Kokkos::View; -template -using oview_t = Kokkos::Experimental::OffsetView; - template using hview_t = Kokkos::View; @@ -723,7 +720,7 @@ static void rrtmgp_sw( val |= p_lay(0, 0) < p_lay(0, nlay-1); }, Kokkos::LOr(top_at_1)); - oview_t col_gas("col_gas", std::make_pair(0, ncol-1), std::make_pair(0, nlay-1), std::make_pair(-1, k_dist.get_ngas()-1)); + view_t col_gas("col_gas", ncol, nlay, k_dist.get_ngas()+1); k_dist.gas_optics(nday, nlay, top_at_1, p_lay_day, p_lev_day, t_lay_limited, gas_concs_day, col_gas, optics, toa_flux); if (extra_clnsky_diag) { @@ -907,7 +904,7 @@ static void rrtmgp_lw( limit_to_bounds_k(t_lev, k_dist_lw_k.get_temp_min(), k_dist_lw_k.get_temp_max(), t_lev_limited); // Do gas optics - oview_t col_gas("col_gas", std::make_pair(0, ncol-1), std::make_pair(0, nlay-1), std::make_pair(-1, k_dist.get_ngas()-1)); + view_t col_gas("col_gas", ncol, nlay, k_dist.get_ngas()+1); k_dist.gas_optics(ncol, nlay, top_at_1, p_lay, p_lev, t_lay_limited, t_sfc, gas_concs, col_gas, optics, lw_sources, view_t(), t_lev_limited); if (extra_clnsky_diag) { k_dist.gas_optics(ncol, nlay, top_at_1, p_lay, p_lev, t_lay_limited, t_sfc, gas_concs, col_gas, optics_no_aerosols, lw_sources, view_t(), t_lev_limited); From 4e2dd44a2516cf1091cfe6fd760ece26fce9a34a Mon Sep 17 00:00:00 2001 From: James Foucar Date: Wed, 23 Oct 2024 08:50:19 -0700 Subject: [PATCH 002/147] Fixes for sw --- .../rrtmgp/scream_rrtmgp_interface.hpp | 70 +++++++++++++------ 1 file changed, 47 insertions(+), 23 deletions(-) diff --git a/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp b/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp index 55e6d87e1feb..8c89a8667afd 100644 --- a/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp +++ b/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp @@ -558,9 +558,9 @@ static void rrtmgp_sw( const bool extra_clnclrsky_diag, const bool extra_clnsky_diag) { // Get problem sizes - int nbnd = k_dist.get_nband(); - int ngpt = k_dist.get_ngpt(); - int ngas = gas_concs.get_num_gases(); + const int nbnd = k_dist.get_nband(); + const int ngpt = k_dist.get_ngpt(); + const int ngas = gas_concs.get_num_gases(); // Associate local pointers for fluxes auto &flux_up = fluxes.flux_up; @@ -601,7 +601,7 @@ static void rrtmgp_sw( }); // Get daytime indices - auto dayIndices = view_t("dayIndices", ncol); + auto dayIndices = pool_t::template alloc(ncol); Kokkos::deep_copy(dayIndices, -1); int nday = 0; @@ -616,24 +616,59 @@ static void rrtmgp_sw( if (nday == 0) { // No daytime columns in this chunk, skip the rest of this routine + pool_t::dealloc(dayIndices); return; } + // Allocate temporaries from pool + const int size1 = nday; + const int size2 = nday*nlay; // 4 + const int size3 = nday*(nlay+1); // 5 + const int size4 = ncol*nlay; + const int size5 = nbnd*nday; //2 + const int size6 = nday*ngpt; + const int size7 = nday*(nlay+1)*nbnd; // 3 + const int size8 = ncol*nlay*(k_dist.get_ngas()+1); + + const int total_size = size1 + size2*4 + size3*5 + size4 + size5*2 + size6 + size7*3 + size8; + auto data = pool_t::template alloc(total_size); RealT* dcurr = data.data(); + + auto mu0_day = view_t (dcurr, nday); dcurr += size1; + + auto p_lay_day = view_t (dcurr, nday, nlay); dcurr += size2; + auto t_lay_day = view_t (dcurr, nday, nlay); dcurr += size2; + auto vmr_day = view_t (dcurr, nday, nlay); dcurr += size2; + auto t_lay_limited = view_t (dcurr, nday, nlay); dcurr += size2; + + auto p_lev_day = view_t (dcurr, nday, nlay+1); dcurr += size3; + auto t_lev_day = view_t (dcurr, nday, nlay+1); dcurr += size3; + auto flux_up_day = view_t (dcurr, nday, nlay+1); dcurr += size3; + auto flux_dn_day = view_t (dcurr, nday, nlay+1); dcurr += size3; + auto flux_dn_dir_day = view_t (dcurr, nday, nlay+1); dcurr += size3; + + auto vmr = view_t (dcurr, ncol, nlay); dcurr += size4; + + auto sfc_alb_dir_T = view_t (dcurr, nbnd, nday); dcurr += size5; + auto sfc_alb_dif_T = view_t (dcurr, nbnd, nday); dcurr += size5; + + auto toa_flux = view_t (dcurr, nday, ngpt); dcurr += size6; + + auto bnd_flux_up_day = view_t(dcurr, nday, nlay+1, nbnd); dcurr += size7; + auto bnd_flux_dn_day = view_t(dcurr, nday, nlay+1, nbnd); dcurr += size7; + auto bnd_flux_dn_dir_day = view_t(dcurr, nday, nlay+1, nbnd); dcurr += size7; + + auto col_gas = view_t(dcurr, ncol, nlay, k_dist.get_ngas()+1); dcurr += size8; + // Subset mu0 - auto mu0_day = view_t("mu0_day", nday); Kokkos::parallel_for(nday, KOKKOS_LAMBDA(int iday) { mu0_day(iday) = mu0(dayIndices(iday)); }); // subset state variables - auto p_lay_day = view_t("p_lay_day", nday, nlay); - auto t_lay_day = view_t("t_lay_day", nday, nlay); Kokkos::parallel_for(MDRP::template get<2>({nlay,nday}), KOKKOS_LAMBDA(int ilay, int iday) { p_lay_day(iday,ilay) = p_lay(dayIndices(iday),ilay); t_lay_day(iday,ilay) = t_lay(dayIndices(iday),ilay); }); - auto p_lev_day = view_t("p_lev_day", nday, nlay+1); - auto t_lev_day = view_t("t_lev_day", nday, nlay+1); Kokkos::parallel_for(MDRP::template get<2>({nlay+1,nday}), KOKKOS_LAMBDA(int ilev, int iday) { p_lev_day(iday,ilev) = p_lev(dayIndices(iday),ilev); t_lev_day(iday,ilev) = t_lev(dayIndices(iday),ilev); @@ -644,8 +679,6 @@ static void rrtmgp_sw( gas_concs_t gas_concs_day; gas_concs_day.init(gas_names, nday, nlay); for (int igas = 0; igas < ngas; igas++) { - auto vmr_day = view_t("vmr_day", nday, nlay); - auto vmr = view_t("vmr" , ncol, nlay); gas_concs.get_vmr(gas_names[igas], vmr); Kokkos::parallel_for(MDRP::template get<2>({nlay,nday}), KOKKOS_LAMBDA(int ilay, int iday) { vmr_day(iday,ilay) = vmr(dayIndices(iday),ilay); @@ -677,20 +710,12 @@ static void rrtmgp_sw( // RRTMGP assumes surface albedos have a screwy dimension ordering // for some strange reason, so we need to transpose these; also do // daytime subsetting in the same kernel - view_t sfc_alb_dir_T("sfc_alb_dir", nbnd, nday); - view_t sfc_alb_dif_T("sfc_alb_dif", nbnd, nday); Kokkos::parallel_for(MDRP::template get<2>({nbnd,nday}), KOKKOS_LAMBDA(int ibnd, int icol) { sfc_alb_dir_T(ibnd,icol) = sfc_alb_dir(dayIndices(icol),ibnd); sfc_alb_dif_T(ibnd,icol) = sfc_alb_dif(dayIndices(icol),ibnd); }); // Temporaries we need for daytime-only fluxes - auto flux_up_day = view_t("flux_up_day", nday, nlay+1); - auto flux_dn_day = view_t("flux_dn_day", nday, nlay+1); - auto flux_dn_dir_day = view_t("flux_dn_dir_day", nday, nlay+1); - auto bnd_flux_up_day = view_t("bnd_flux_up_day", nday, nlay+1, nbnd); - auto bnd_flux_dn_day = view_t("bnd_flux_dn_day", nday, nlay+1, nbnd); - auto bnd_flux_dn_dir_day = view_t("bnd_flux_dn_dir_day", nday, nlay+1, nbnd); fluxes_t fluxes_day; fluxes_day.flux_up = flux_up_day; fluxes_day.flux_dn = flux_dn_day; @@ -710,18 +735,14 @@ static void rrtmgp_sw( } // Limit temperatures for gas optics look-up tables - auto t_lay_limited = view_t("t_lay_limited", nday, nlay); limit_to_bounds_k(t_lay_day, k_dist_sw_k.get_temp_min(), k_dist_sw_k.get_temp_max(), t_lay_limited); // Do gas optics - view_t toa_flux("toa_flux", nday, ngpt); bool top_at_1 = false; Kokkos::parallel_reduce(1, KOKKOS_LAMBDA(int, bool& val) { val |= p_lay(0, 0) < p_lay(0, nlay-1); }, Kokkos::LOr(top_at_1)); - view_t col_gas("col_gas", ncol, nlay, k_dist.get_ngas()+1); - k_dist.gas_optics(nday, nlay, top_at_1, p_lay_day, p_lev_day, t_lay_limited, gas_concs_day, col_gas, optics, toa_flux); if (extra_clnsky_diag) { k_dist.gas_optics(nday, nlay, top_at_1, p_lay_day, p_lev_day, t_lay_limited, gas_concs_day, col_gas, optics_no_aerosols, toa_flux); @@ -800,6 +821,9 @@ static void rrtmgp_sw( clnsky_flux_dn_dir(icol,ilev) = flux_dn_dir_day(iday,ilev); }); } + + pool_t::dealloc(data); + pool_t::dealloc(dayIndices); } /* From a9c40fd0eae13cea23e88e09216cc72fb2a9dce9 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Mon, 7 Oct 2024 16:02:09 -0600 Subject: [PATCH 003/147] rrtmgp_lw no allocations --- .../rrtmgp/scream_rrtmgp_interface.hpp | 57 ++++++++++++------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp b/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp index 8c89a8667afd..3c3d41119b4e 100644 --- a/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp +++ b/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp @@ -840,6 +840,24 @@ static void rrtmgp_lw( { // Problem size int nbnd = k_dist.get_nband(); + int constexpr max_gauss_pts = 4; + + const int size1 = ncol; + const int size2 = nbnd*ncol; + const int size3 = max_gauss_pts*max_gauss_pts; + const int size4 = ncol*nlay; + const int size5 = ncol*(nlay+1); + const int size6 = ncol*nlay*(k_dist.get_ngas()+1); + + RealT* data = pool_t::template alloc_raw(size1 + size2 + size3*2 + size4 + size5 + size6), *dcurr = data; + + view_t t_sfc (dcurr, ncol); dcurr += size1; + view_t emis_sfc (dcurr, nbnd,ncol); dcurr += size2; + view_t gauss_Ds (dcurr, max_gauss_pts,max_gauss_pts); dcurr += size3; + view_t gauss_wts (dcurr, max_gauss_pts,max_gauss_pts); dcurr += size3; + view_t t_lay_limited(dcurr, ncol, nlay); dcurr += size4; + view_t t_lev_limited(dcurr, ncol, nlay+1); dcurr += size5; + view_t col_gas (dcurr, ncol, nlay, k_dist.get_ngas()+1); dcurr += size6; // Associate local pointers for fluxes auto &flux_up = fluxes.flux_up; @@ -884,8 +902,6 @@ static void rrtmgp_lw( // Boundary conditions source_func_t lw_sources; lw_sources.alloc(ncol, nlay, k_dist); - view_t t_sfc ("t_sfc" ,ncol); - view_t emis_sfc("emis_sfc",nbnd,ncol); bool top_at_1 = false; Kokkos::parallel_reduce(1, KOKKOS_LAMBDA(int, bool& val) { @@ -903,32 +919,31 @@ static void rrtmgp_lw( // Weights and angle secants for first order (k=1) Gaussian quadrature. // Values from Table 2, Clough et al, 1992, doi:10.1029/92JD01419 // after Abramowitz & Stegun 1972, page 921 - int constexpr max_gauss_pts = 4; - hview_t gauss_Ds_host ("gauss_Ds" ,max_gauss_pts,max_gauss_pts); - gauss_Ds_host(0,0) = 1.66 ; gauss_Ds_host(1,0) = 0.; gauss_Ds_host(2,0) = 0.; gauss_Ds_host(3,0) = 0.; - gauss_Ds_host(0,1) = 1.18350343; gauss_Ds_host(1,1) = 2.81649655; gauss_Ds_host(2,1) = 0.; gauss_Ds_host(3,1) = 0.; - gauss_Ds_host(0,2) = 1.09719858; gauss_Ds_host(1,2) = 1.69338507; gauss_Ds_host(2,2) = 4.70941630; gauss_Ds_host(3,2) = 0.; - gauss_Ds_host(0,3) = 1.06056257; gauss_Ds_host(1,3) = 1.38282560; gauss_Ds_host(2,3) = 2.40148179; gauss_Ds_host(3,3) = 7.15513024; - - hview_t gauss_wts_host("gauss_wts",max_gauss_pts,max_gauss_pts); - gauss_wts_host(0,0) = 0.5 ; gauss_wts_host(1,0) = 0. ; gauss_wts_host(2,0) = 0. ; gauss_wts_host(3,0) = 0. ; - gauss_wts_host(0,1) = 0.3180413817; gauss_wts_host(1,1) = 0.1819586183; gauss_wts_host(2,1) = 0. ; gauss_wts_host(3,1) = 0. ; - gauss_wts_host(0,2) = 0.2009319137; gauss_wts_host(1,2) = 0.2292411064; gauss_wts_host(2,2) = 0.0698269799; gauss_wts_host(3,2) = 0. ; - gauss_wts_host(0,3) = 0.1355069134; gauss_wts_host(1,3) = 0.2034645680; gauss_wts_host(2,3) = 0.1298475476; gauss_wts_host(3,3) = 0.0311809710; - - view_t gauss_Ds ("gauss_Ds" ,max_gauss_pts,max_gauss_pts); - view_t gauss_wts("gauss_wts",max_gauss_pts,max_gauss_pts); + RealT gauss_Ds_host_raw[max_gauss_pts][max_gauss_pts] = { + {1.66, 1.18350343, 1.09719858, 1.06056257}, + {0., 2.81649655, 1.69338507, 1.38282560}, + {0., 0., 4.70941630, 2.40148179}, + {0., 0., 0., 7.15513024} + }; + hview_t gauss_Ds_host (&gauss_Ds_host_raw[0][0], max_gauss_pts, max_gauss_pts); + + RealT gauss_wts_host_raw[max_gauss_pts][max_gauss_pts] = { + {0.5, 0.3180413817, 0.2009319137, 0.1355069134}, + {0., 0.1819586183, 0.2292411064, 0.2034645680}, + {0., 0., 0.0698269799, 0.1298475476}, + {0., 0., 0., 0.0311809710} + }; + + hview_t gauss_wts_host(&gauss_wts_host_raw[0][0],max_gauss_pts,max_gauss_pts); + Kokkos::deep_copy(gauss_Ds, gauss_Ds_host); Kokkos::deep_copy(gauss_wts, gauss_wts_host); // Limit temperatures for gas optics look-up tables - auto t_lay_limited = view_t("t_lay_limited", ncol, nlay); - auto t_lev_limited = view_t("t_lev_limited", ncol, nlay+1); limit_to_bounds_k(t_lay, k_dist_lw_k.get_temp_min(), k_dist_lw_k.get_temp_max(), t_lay_limited); limit_to_bounds_k(t_lev, k_dist_lw_k.get_temp_min(), k_dist_lw_k.get_temp_max(), t_lev_limited); // Do gas optics - view_t col_gas("col_gas", ncol, nlay, k_dist.get_ngas()+1); k_dist.gas_optics(ncol, nlay, top_at_1, p_lay, p_lev, t_lay_limited, t_sfc, gas_concs, col_gas, optics, lw_sources, view_t(), t_lev_limited); if (extra_clnsky_diag) { k_dist.gas_optics(ncol, nlay, top_at_1, p_lay, p_lev, t_lay_limited, t_sfc, gas_concs, col_gas, optics_no_aerosols, lw_sources, view_t(), t_lev_limited); @@ -962,6 +977,8 @@ static void rrtmgp_lw( // Compute clean-sky fluxes rte_lw(max_gauss_pts, gauss_Ds, gauss_wts, optics_no_aerosols, top_at_1, lw_sources, emis_sfc, clnsky_fluxes); } + + pool_t::dealloc(data, dcurr - data); } /* From 1a701dd3edf2a497081fe94196c79d67f757941c Mon Sep 17 00:00:00 2001 From: James Foucar Date: Wed, 23 Oct 2024 10:18:50 -0700 Subject: [PATCH 004/147] Final pool allocs --- .../rrtmgp/scream_rrtmgp_interface.hpp | 68 +++++++++++++------ 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp b/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp index 3c3d41119b4e..3eb015d04244 100644 --- a/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp +++ b/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp @@ -849,7 +849,8 @@ static void rrtmgp_lw( const int size5 = ncol*(nlay+1); const int size6 = ncol*nlay*(k_dist.get_ngas()+1); - RealT* data = pool_t::template alloc_raw(size1 + size2 + size3*2 + size4 + size5 + size6), *dcurr = data; + const int total_size = size1 + size2 + size3*2 + size4 + size5 + size6; + auto data = pool_t::template alloc(total_size); RealT *dcurr = data.data(); view_t t_sfc (dcurr, ncol); dcurr += size1; view_t emis_sfc (dcurr, nbnd,ncol); dcurr += size2; @@ -978,24 +979,22 @@ static void rrtmgp_lw( rte_lw(max_gauss_pts, gauss_Ds, gauss_wts, optics_no_aerosols, top_at_1, lw_sources, emis_sfc, clnsky_fluxes); } - pool_t::dealloc(data, dcurr - data); + pool_t::dealloc(data); } /* * Return a subcolumn mask consistent with a specified overlap assumption */ -static int3dk get_subcolumn_mask(const int ncol, const int nlay, const int ngpt, const real2dk &cldf, const int overlap_option, int1dk &seeds) +template +static void get_subcolumn_mask(const int ncol, const int nlay, const int ngpt, const CldfT &cldf, const int overlap_option, const SeedsT &seeds, const SubcT& subcolumn_mask) { - // Routine will return subcolumn mask with values of 0 indicating no cloud, 1 indicating cloud - int3dk subcolumn_mask = int3dk("subcolumn_mask", ncol, nlay, ngpt); - // Subcolumn generators are a means for producing a variable x(i,j,k), where // // c(i,j,k) = 1 for x(i,j,k) > 1 - cldf(i,j) // c(i,j,k) = 0 for x(i,j,k) <= 1 - cldf(i,j) // // I am going to call this "cldx" to be just slightly less ambiguous - auto cldx = view_t("cldx", ncol, nlay, ngpt); + auto cldx = pool_t::template alloc(ncol, nlay, ngpt); // Apply overlap assumption to set cldx if (overlap_option == 0) { // Dummy mask, always cloudy @@ -1055,7 +1054,8 @@ static int3dk get_subcolumn_mask(const int ncol, const int nlay, const int ngpt, subcolumn_mask(icol,ilay,igpt) = 0; } }); - return subcolumn_mask; + + pool_t::dealloc(cldx); } /* @@ -1067,7 +1067,7 @@ static void compute_cloud_area( { // Subcolumn binary cld mask; if any layers with pressure between pmin and pmax are cloudy // then 2d subcol mask is 1, otherwise it is 0 - auto subcol_mask = view_t("subcol_mask", ncol, ngpt); + auto subcol_mask = pool_t::template alloc(ncol, ngpt); Kokkos::parallel_for(MDRP::template get<3>({ngpt, nlay, ncol}), KOKKOS_LAMBDA(int igpt, int ilay, int icol) { // NOTE: using plev would need to assume level ordering (top to bottom or bottom to top), but // using play/pmid does not @@ -1084,6 +1084,8 @@ static void compute_cloud_area( cld_area(icol) += subcol_mask(icol,igpt) * ngpt_inv; } }); + + pool_t::dealloc(subcol_mask); } /* @@ -1116,7 +1118,7 @@ static void compute_aerocom_cloudtop( Kokkos::deep_copy(eff_radius_qi_at_cldtop, 0.0); // Initialize the 1D "clear fraction" as 1 (totally clear) - auto aerocom_clr = view_t("aerocom_clr", ncol); + auto aerocom_clr = pool_t::template alloc(ncol); Kokkos::deep_copy(aerocom_clr, 1.0); // Get gravity acceleration constant from constants @@ -1189,6 +1191,8 @@ static void compute_aerocom_cloudtop( // (their products) cldfrac_tot_at_cldtop(icol) = 1.0 - aerocom_clr(icol); }); + + pool_t::dealloc(aerocom_clr); } /* @@ -1291,14 +1295,17 @@ static optical_props2_t get_cloud_optics_sw( cloud_optics.set_ice_roughness(2); // Limit effective radii to be within bounds of lookup table - auto rel_limited = view_t("rel_limited", ncol, nlay); - auto rei_limited = view_t("rei_limited", ncol, nlay); + auto rel_limited = pool_t::template alloc(ncol, nlay); + auto rei_limited = pool_t::template alloc(ncol, nlay); limit_to_bounds_k(rel, cloud_optics.radliq_lwr, cloud_optics.radliq_upr, rel_limited); limit_to_bounds_k(rei, cloud_optics.radice_lwr, cloud_optics.radice_upr, rei_limited); // Calculate cloud optics cloud_optics.cloud_optics(ncol, nlay, lwp, iwp, rel_limited, rei_limited, clouds); + pool_t::dealloc(rel_limited); + pool_t::dealloc(rei_limited); + // Return optics return clouds; } @@ -1317,14 +1324,17 @@ static optical_props1_t get_cloud_optics_lw( cloud_optics.set_ice_roughness(2); // Limit effective radii to be within bounds of lookup table - auto rel_limited = view_t("rel_limited", ncol, nlay); - auto rei_limited = view_t("rei_limited", ncol, nlay); + auto rel_limited = pool_t::template alloc(ncol, nlay); + auto rei_limited = pool_t::template alloc(ncol, nlay); limit_to_bounds_k(rel, cloud_optics.radliq_lwr, cloud_optics.radliq_upr, rel_limited); limit_to_bounds_k(rei, cloud_optics.radice_lwr, cloud_optics.radice_upr, rei_limited); // Calculate cloud optics cloud_optics.cloud_optics(ncol, nlay, lwp, iwp, rel_limited, rei_limited, clouds); + pool_t::dealloc(rel_limited); + pool_t::dealloc(rei_limited); + // Return optics return clouds; } @@ -1336,6 +1346,10 @@ static optical_props2_t get_subsampled_clouds( optical_props2_t subsampled_optics; subsampled_optics.init(kdist.get_band_lims_wavenumber(), kdist.get_band_lims_gpoint(), "subsampled_optics"); subsampled_optics.alloc_2str(ncol, nlay); + + // Subcolumn mask with values of 0 indicating no cloud, 1 indicating cloud + auto cldmask = pool_t::template alloc(ncol, nlay, ngpt); + // Check that we do not have clouds with no optical properties; this would get corrected // when we assign optical props, but we want to use a "radiative cloud fraction" // for the subcolumn sampling too because otherwise we can get vertically-contiguous cloud @@ -1343,7 +1357,7 @@ static optical_props2_t get_subsampled_clouds( // the vertical correlation of cloudy layers. I.e., cloudy layers might look maximally overlapped // even when separated by layers with no cloud properties, when in fact those layers should be // randomly overlapped. - auto cldfrac_rad = view_t("cldfrac_rad", ncol, nlay); + auto cldfrac_rad = pool_t::template alloc(ncol, nlay); Kokkos::parallel_for(MDRP::template get<3>({nbnd,nlay,ncol}), KOKKOS_LAMBDA (int ibnd, int ilay, int icol) { if (cloud_optics.tau(icol,ilay,ibnd) > 0) { cldfrac_rad(icol,ilay) = cld(icol,ilay); @@ -1357,11 +1371,11 @@ static optical_props2_t get_subsampled_clouds( int overlap = 1; // Get unique seeds for each column that are reproducible across different MPI rank layouts; // use decimal part of pressure for this, consistent with the implementation in EAM - auto seeds = view_t("seeds", ncol); + auto seeds = pool_t::template alloc(ncol); Kokkos::parallel_for(ncol, KOKKOS_LAMBDA(int icol) { seeds(icol) = 1e9 * (p_lay(icol,nlay-1) - int(p_lay(icol,nlay-1))); }); - auto cldmask = get_subcolumn_mask(ncol, nlay, ngpt, cldfrac_rad, overlap, seeds); + get_subcolumn_mask(ncol, nlay, ngpt, cldfrac_rad, overlap, seeds, cldmask); // Assign optical properties to subcolumns (note this implements MCICA) auto gpoint_bands = kdist.get_gpoint_bands(); Kokkos::parallel_for(MDRP::template get<3>({ngpt,nlay,ncol}), KOKKOS_LAMBDA(int igpt, int ilay, int icol) { @@ -1376,6 +1390,11 @@ static optical_props2_t get_subsampled_clouds( subsampled_optics.g (icol,ilay,igpt) = 0; } }); + + pool_t::dealloc(cldmask); + pool_t::dealloc(cldfrac_rad); + pool_t::dealloc(seeds); + return subsampled_optics; } @@ -1387,6 +1406,10 @@ static optical_props1_t get_subsampled_clouds( optical_props1_t subsampled_optics; subsampled_optics.init(kdist.get_band_lims_wavenumber(), kdist.get_band_lims_gpoint(), "subsampled_optics"); subsampled_optics.alloc_1scl(ncol, nlay); + + // Subcolumn mask with values of 0 indicating no cloud, 1 indicating cloud + auto cldmask = pool_t::template alloc(ncol, nlay, ngpt); + // Check that we do not have clouds with no optical properties; this would get corrected // when we assign optical props, but we want to use a "radiative cloud fraction" // for the subcolumn sampling too because otherwise we can get vertically-contiguous cloud @@ -1394,7 +1417,7 @@ static optical_props1_t get_subsampled_clouds( // the vertical correlation of cloudy layers. I.e., cloudy layers might look maximally overlapped // even when separated by layers with no cloud properties, when in fact those layers should be // randomly overlapped. - auto cldfrac_rad = view_t("cldfrac_rad", ncol, nlay); + auto cldfrac_rad = pool_t::template alloc(ncol, nlay); Kokkos::parallel_for(MDRP::template get<3>({nbnd,nlay,ncol}), KOKKOS_LAMBDA (int ibnd, int ilay, int icol) { if (cloud_optics.tau(icol,ilay,ibnd) > 0) { cldfrac_rad(icol,ilay) = cld(icol,ilay); @@ -1405,11 +1428,11 @@ static optical_props1_t get_subsampled_clouds( // Get unique seeds for each column that are reproducible across different MPI rank layouts; // use decimal part of pressure for this, consistent with the implementation in EAM; use different // seed values for longwave and shortwave - auto seeds = view_t("seeds", ncol); + auto seeds = pool_t::template alloc(ncol); Kokkos::parallel_for(ncol, KOKKOS_LAMBDA(int icol) { seeds(icol) = 1e9 * (p_lay(icol,nlay-2) - int(p_lay(icol,nlay-2))); }); - auto cldmask = get_subcolumn_mask(ncol, nlay, ngpt, cldfrac_rad, overlap, seeds); + get_subcolumn_mask(ncol, nlay, ngpt, cldfrac_rad, overlap, seeds, cldmask); // Assign optical properties to subcolumns (note this implements MCICA) auto gpoint_bands = kdist.get_gpoint_bands(); Kokkos::parallel_for(MDRP::template get<3>({ngpt,nlay,ncol}), KOKKOS_LAMBDA(int igpt, int ilay, int icol) { @@ -1420,6 +1443,11 @@ static optical_props1_t get_subsampled_clouds( subsampled_optics.tau(icol,ilay,igpt) = 0; } }); + + pool_t::dealloc(cldmask); + pool_t::dealloc(cldfrac_rad); + pool_t::dealloc(seeds); + return subsampled_optics; } From 784223887493e92c4f9913a7f4d76f1b85e195da Mon Sep 17 00:00:00 2001 From: James Foucar Date: Wed, 23 Oct 2024 10:41:03 -0700 Subject: [PATCH 005/147] Fix unit test --- .../eamxx/src/physics/rrtmgp/tests/rrtmgp_unit_tests.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/eamxx/src/physics/rrtmgp/tests/rrtmgp_unit_tests.cpp b/components/eamxx/src/physics/rrtmgp/tests/rrtmgp_unit_tests.cpp index 99a582445616..00a33c0380d5 100644 --- a/components/eamxx/src/physics/rrtmgp/tests/rrtmgp_unit_tests.cpp +++ b/components/eamxx/src/physics/rrtmgp/tests/rrtmgp_unit_tests.cpp @@ -1291,7 +1291,7 @@ TEST_CASE("rrtmgp_test_subcol_gen_k") { for (unsigned seed = 0; seed < 10; seed++) { auto seeds = int1dk("seeds", ncol); Kokkos::deep_copy(seeds, seed); - cldmask = interface_t::get_subcolumn_mask(ncol, nlay, ngpt, cldfrac, 1, seeds); + interface_t::get_subcolumn_mask(ncol, nlay, ngpt, cldfrac, 1, seeds, cldmask); // Check answers by computing new cldfrac from mask Kokkos::deep_copy(cldfrac_from_mask, 0.0); Kokkos::parallel_for(MDRP::template get<2>({nlay,ncol}), KOKKOS_LAMBDA(int ilay, int icol) { @@ -1325,7 +1325,7 @@ TEST_CASE("rrtmgp_test_subcol_gen_k") { for (unsigned seed = 0; seed < 10; seed++) { auto seeds = int1dk("seeds", ncol); Kokkos::deep_copy(seeds, seed); - cldmask = interface_t::get_subcolumn_mask(ncol, nlay, ngpt, cldfrac, 1, seeds); + interface_t::get_subcolumn_mask(ncol, nlay, ngpt, cldfrac, 1, seeds, cldmask); auto cldmask_h = chc(cldmask); for (int igpt = 0; igpt < ngpt; igpt++) { if (cldmask_h(0,0,igpt) == 1) { From afbefb4625b72ef102505cf812c8bf4c110547ad Mon Sep 17 00:00:00 2001 From: James Foucar Date: Wed, 23 Oct 2024 12:14:14 -0700 Subject: [PATCH 006/147] Something went wrong with merge --- .../rrtmgp/scream_rrtmgp_interface.hpp | 38 ------------------- 1 file changed, 38 deletions(-) diff --git a/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp b/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp index ecdaf7cb507c..3eb015d04244 100644 --- a/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp +++ b/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp @@ -562,44 +562,6 @@ static void rrtmgp_sw( const int ngpt = k_dist.get_ngpt(); const int ngas = gas_concs.get_num_gases(); - // Allocate temporaries from pool - const int size1 = nday; - const int size2 = nday*nlay; // 4 - const int size3 = nday*(nlay+1); // 5 - const int size4 = ncol*nlay; - const int size5 = nbnd*nday; //2 - const int size6 = nday*ngpt; - const int size7 = nday*(nlay+1)*nbnd; // 3 - const int size8 = ncol*nlay*(k_dist.get_ngas()+1); - - RealT* data = pool_t::template alloc_raw(size1 + size2*4 + size3*5 + size4 + size5*2 + size6 + size7*3 + size8), *dcurr = data; - - auto mu0_day = view_t (dcurr, nday); dcurr += size1; - - auto p_lay_day = view_t (dcurr, nday, nlay); dcurr += size2; - auto t_lay_day = view_t (dcurr, nday, nlay); dcurr += size2; - auto vmr_day = view_t (dcurr, nday, nlay); dcurr += size2; - auto t_lay_limited = view_t (dcurr, nday, nlay); dcurr += size2; - - auto p_lev_day = view_t (dcurr, nday, nlay+1); dcurr += size3; - auto t_lev_day = view_t (dcurr, nday, nlay+1); dcurr += size3; - auto flux_up_day = view_t (dcurr, nday, nlay+1); dcurr += size3; - auto flux_dn_day = view_t (dcurr, nday, nlay+1); dcurr += size3; - auto flux_dn_dir_day = view_t (dcurr, nday, nlay+1); dcurr += size3; - - auto vmr = view_t (dcurr, ncol, nlay); dcurr += size4; - - auto sfc_alb_dir_T = view_t (dcurr, nbnd, nday); dcurr += size5; - auto sfc_alb_dif_T = view_t (dcurr, nbnd, nday); dcurr += size5; - - auto toa_flux = view_t (dcurr, nday, ngpt); dcurr += size6; - - auto bnd_flux_up_day = view_t(dcurr, nday, nlay+1, nbnd); dcurr += size7; - auto bnd_flux_dn_day = view_t(dcurr, nday, nlay+1, nbnd); dcurr += size7; - auto bnd_flux_dn_dir_day = view_t(dcurr, nday, nlay+1, nbnd); dcurr += size7; - - auto col_gas = view_t(dcurr, ncol, nlay, k_dist.get_ngas()+1); dcurr += size8; - // Associate local pointers for fluxes auto &flux_up = fluxes.flux_up; auto &flux_dn = fluxes.flux_dn; From 461066e623d36a4cee51890ec89eba9b4d92fa5a Mon Sep 17 00:00:00 2001 From: James Foucar Date: Thu, 24 Oct 2024 11:51:20 -0600 Subject: [PATCH 007/147] Fix some pool issues --- components/eam/src/physics/rrtmgp/external | 2 +- .../physics/rrtmgp/scream_rrtmgp_interface.hpp | 2 +- .../physics/rrtmgp/tests/rrtmgp_unit_tests.cpp | 18 ++++++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/components/eam/src/physics/rrtmgp/external b/components/eam/src/physics/rrtmgp/external index b851a86aa931..b24ca1f616e4 160000 --- a/components/eam/src/physics/rrtmgp/external +++ b/components/eam/src/physics/rrtmgp/external @@ -1 +1 @@ -Subproject commit b851a86aa9312193f8f292f612e40afb056f90cf +Subproject commit b24ca1f616e45659b334dbd7297017cb7927367e diff --git a/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp b/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp index 3eb015d04244..0d890317b99b 100644 --- a/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp +++ b/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp @@ -1067,7 +1067,7 @@ static void compute_cloud_area( { // Subcolumn binary cld mask; if any layers with pressure between pmin and pmax are cloudy // then 2d subcol mask is 1, otherwise it is 0 - auto subcol_mask = pool_t::template alloc(ncol, ngpt); + auto subcol_mask = pool_t::template alloc_and_init(ncol, ngpt); Kokkos::parallel_for(MDRP::template get<3>({ngpt, nlay, ncol}), KOKKOS_LAMBDA(int igpt, int ilay, int icol) { // NOTE: using plev would need to assume level ordering (top to bottom or bottom to top), but // using play/pmid does not diff --git a/components/eamxx/src/physics/rrtmgp/tests/rrtmgp_unit_tests.cpp b/components/eamxx/src/physics/rrtmgp/tests/rrtmgp_unit_tests.cpp index 00a33c0380d5..06ca64af5f24 100644 --- a/components/eamxx/src/physics/rrtmgp/tests/rrtmgp_unit_tests.cpp +++ b/components/eamxx/src/physics/rrtmgp/tests/rrtmgp_unit_tests.cpp @@ -850,6 +850,7 @@ TEST_CASE("rrtmgp_aerocom_cloudtop") { #ifdef RRTMGP_ENABLE_KOKKOS using interface_t = scream::rrtmgp::rrtmgp_interface<>; +using pool_t = interface_t::pool_t; using real1dk = interface_t::view_t; using real2dk = interface_t::view_t; using real3dk = interface_t::view_t; @@ -861,6 +862,7 @@ using MDRP = interface_t::MDRP; TEST_CASE("rrtmgp_test_heating_k") { // Initialize Kokkos scream::init_kls(); + pool_t::init(10000); // Test heating rate function by passing simple inputs auto dp = real2dk("dp", 1, 1); @@ -908,12 +910,14 @@ TEST_CASE("rrtmgp_test_heating_k") { REQUIRE(chc(heating)(0,0) == heating_ref); // Clean up + pool_t::finalize(); scream::finalize_kls(); } TEST_CASE("rrtmgp_test_mixing_ratio_to_cloud_mass_k") { // Initialize YAKL scream::init_kls(); + pool_t::init(10000); using physconst = scream::physics::Constants; @@ -966,12 +970,14 @@ TEST_CASE("rrtmgp_test_mixing_ratio_to_cloud_mass_k") { REQUIRE(chc(cloud_mass)(0,0) == cloud_mass_ref); // Clean up + pool_t::finalize(); scream::finalize_kls(); } TEST_CASE("rrtmgp_test_limit_to_bounds_k") { // Initialize YAKL scream::init_kls(); + pool_t::init(10000); // Test limiter function auto arr = real2dk("arr", 2, 2); @@ -998,6 +1004,8 @@ TEST_CASE("rrtmgp_test_limit_to_bounds_k") { REQUIRE(chc(arr_limited)(0,1) == 2.0); REQUIRE(chc(arr_limited)(1,0) == 3.0); REQUIRE(chc(arr_limited)(1,1) == 3.5); + + pool_t::finalize(); scream::finalize_kls(); } @@ -1070,6 +1078,7 @@ TEST_CASE("rrtmgp_test_compute_broadband_surface_flux_k") { // Initialize YAKL scream::init_kls(); + pool_t::init(10000); // Create arrays const int ncol = 1; @@ -1227,6 +1236,7 @@ TEST_CASE("rrtmgp_test_compute_broadband_surface_flux_k") { logger->info("Free memory...\n"); interface_t::rrtmgp_finalize(); gas_concs.reset(); + pool_t::finalize(); scream::finalize_kls(); } @@ -1255,6 +1265,7 @@ TEST_CASE("rrtmgp_test_radiation_do_k") { TEST_CASE("rrtmgp_test_check_range_k") { // Initialize YAKL scream::init_kls(); + pool_t::init(10000); // Create some dummy data and test with both values inside valid range and outside auto dummy = real2dk("dummy", 2, 1); // All values within range @@ -1266,12 +1277,14 @@ TEST_CASE("rrtmgp_test_check_range_k") { // At least one value above upper bound Kokkos::parallel_for(1, KOKKOS_LAMBDA (int i) {dummy(i, 0) = 1.1;}); REQUIRE(scream::rrtmgp::check_range_k(dummy, 0.0, 1.0, "dummy") == false); + pool_t::finalize(); scream::finalize_kls(); } TEST_CASE("rrtmgp_test_subcol_gen_k") { // Initialize YAKL scream::init_kls(); + pool_t::init(10000); // Create dummy data const int ncol = 1; const int nlay = 4; @@ -1334,12 +1347,14 @@ TEST_CASE("rrtmgp_test_subcol_gen_k") { } } // Clean up after test + pool_t::finalize(); scream::finalize_kls(); } TEST_CASE("rrtmgp_cloud_area_k") { // Initialize YAKL scream::init_kls(); + pool_t::init(10000); // Create dummy data const int ncol = 1; const int nlay = 2; @@ -1429,12 +1444,14 @@ TEST_CASE("rrtmgp_cloud_area_k") { REQUIRE(chc(cldtot)(0) == 0.0); interface_t::compute_cloud_area(ncol, nlay, ngpt, 100, 300, pmid, cldtau, cldtot); REQUIRE(chc(cldtot)(0) == 2.0 / 3.0); + pool_t::finalize(); scream::finalize_kls(); } TEST_CASE("rrtmgp_aerocom_cloudtop_k") { // Initialize YAKL scream::init_kls(); + pool_t::init(10000); // Create dummy data const int ncol = 1; @@ -1623,6 +1640,7 @@ TEST_CASE("rrtmgp_aerocom_cloudtop_k") { REQUIRE(chc(cldfrac_ice_at_cldtop)(0) == 0.7); // max // cleanup + pool_t::finalize(); scream::finalize_kls(); } #endif From 8ee29b50e65013d4cb892020ed130b160ff497da Mon Sep 17 00:00:00 2001 From: James Foucar Date: Thu, 24 Oct 2024 11:58:12 -0600 Subject: [PATCH 008/147] alloc and init everything --- .../rrtmgp/scream_rrtmgp_interface.hpp | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp b/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp index 0d890317b99b..03cb0693d980 100644 --- a/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp +++ b/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp @@ -601,7 +601,7 @@ static void rrtmgp_sw( }); // Get daytime indices - auto dayIndices = pool_t::template alloc(ncol); + auto dayIndices = pool_t::template alloc_and_init(ncol); Kokkos::deep_copy(dayIndices, -1); int nday = 0; @@ -631,7 +631,7 @@ static void rrtmgp_sw( const int size8 = ncol*nlay*(k_dist.get_ngas()+1); const int total_size = size1 + size2*4 + size3*5 + size4 + size5*2 + size6 + size7*3 + size8; - auto data = pool_t::template alloc(total_size); RealT* dcurr = data.data(); + auto data = pool_t::template alloc_and_init(total_size); RealT* dcurr = data.data(); auto mu0_day = view_t (dcurr, nday); dcurr += size1; @@ -850,7 +850,7 @@ static void rrtmgp_lw( const int size6 = ncol*nlay*(k_dist.get_ngas()+1); const int total_size = size1 + size2 + size3*2 + size4 + size5 + size6; - auto data = pool_t::template alloc(total_size); RealT *dcurr = data.data(); + auto data = pool_t::template alloc_and_init(total_size); RealT *dcurr = data.data(); view_t t_sfc (dcurr, ncol); dcurr += size1; view_t emis_sfc (dcurr, nbnd,ncol); dcurr += size2; @@ -994,7 +994,7 @@ static void get_subcolumn_mask(const int ncol, const int nlay, const int ngpt, c // c(i,j,k) = 0 for x(i,j,k) <= 1 - cldf(i,j) // // I am going to call this "cldx" to be just slightly less ambiguous - auto cldx = pool_t::template alloc(ncol, nlay, ngpt); + auto cldx = pool_t::template alloc_and_init(ncol, nlay, ngpt); // Apply overlap assumption to set cldx if (overlap_option == 0) { // Dummy mask, always cloudy @@ -1118,7 +1118,7 @@ static void compute_aerocom_cloudtop( Kokkos::deep_copy(eff_radius_qi_at_cldtop, 0.0); // Initialize the 1D "clear fraction" as 1 (totally clear) - auto aerocom_clr = pool_t::template alloc(ncol); + auto aerocom_clr = pool_t::template alloc_and_init(ncol); Kokkos::deep_copy(aerocom_clr, 1.0); // Get gravity acceleration constant from constants @@ -1295,8 +1295,8 @@ static optical_props2_t get_cloud_optics_sw( cloud_optics.set_ice_roughness(2); // Limit effective radii to be within bounds of lookup table - auto rel_limited = pool_t::template alloc(ncol, nlay); - auto rei_limited = pool_t::template alloc(ncol, nlay); + auto rel_limited = pool_t::template alloc_and_init(ncol, nlay); + auto rei_limited = pool_t::template alloc_and_init(ncol, nlay); limit_to_bounds_k(rel, cloud_optics.radliq_lwr, cloud_optics.radliq_upr, rel_limited); limit_to_bounds_k(rei, cloud_optics.radice_lwr, cloud_optics.radice_upr, rei_limited); @@ -1324,8 +1324,8 @@ static optical_props1_t get_cloud_optics_lw( cloud_optics.set_ice_roughness(2); // Limit effective radii to be within bounds of lookup table - auto rel_limited = pool_t::template alloc(ncol, nlay); - auto rei_limited = pool_t::template alloc(ncol, nlay); + auto rel_limited = pool_t::template alloc_and_init(ncol, nlay); + auto rei_limited = pool_t::template alloc_and_init(ncol, nlay); limit_to_bounds_k(rel, cloud_optics.radliq_lwr, cloud_optics.radliq_upr, rel_limited); limit_to_bounds_k(rei, cloud_optics.radice_lwr, cloud_optics.radice_upr, rei_limited); @@ -1348,7 +1348,7 @@ static optical_props2_t get_subsampled_clouds( subsampled_optics.alloc_2str(ncol, nlay); // Subcolumn mask with values of 0 indicating no cloud, 1 indicating cloud - auto cldmask = pool_t::template alloc(ncol, nlay, ngpt); + auto cldmask = pool_t::template alloc_and_init(ncol, nlay, ngpt); // Check that we do not have clouds with no optical properties; this would get corrected // when we assign optical props, but we want to use a "radiative cloud fraction" @@ -1357,7 +1357,7 @@ static optical_props2_t get_subsampled_clouds( // the vertical correlation of cloudy layers. I.e., cloudy layers might look maximally overlapped // even when separated by layers with no cloud properties, when in fact those layers should be // randomly overlapped. - auto cldfrac_rad = pool_t::template alloc(ncol, nlay); + auto cldfrac_rad = pool_t::template alloc_and_init(ncol, nlay); Kokkos::parallel_for(MDRP::template get<3>({nbnd,nlay,ncol}), KOKKOS_LAMBDA (int ibnd, int ilay, int icol) { if (cloud_optics.tau(icol,ilay,ibnd) > 0) { cldfrac_rad(icol,ilay) = cld(icol,ilay); @@ -1371,7 +1371,7 @@ static optical_props2_t get_subsampled_clouds( int overlap = 1; // Get unique seeds for each column that are reproducible across different MPI rank layouts; // use decimal part of pressure for this, consistent with the implementation in EAM - auto seeds = pool_t::template alloc(ncol); + auto seeds = pool_t::template alloc_and_init(ncol); Kokkos::parallel_for(ncol, KOKKOS_LAMBDA(int icol) { seeds(icol) = 1e9 * (p_lay(icol,nlay-1) - int(p_lay(icol,nlay-1))); }); @@ -1408,7 +1408,7 @@ static optical_props1_t get_subsampled_clouds( subsampled_optics.alloc_1scl(ncol, nlay); // Subcolumn mask with values of 0 indicating no cloud, 1 indicating cloud - auto cldmask = pool_t::template alloc(ncol, nlay, ngpt); + auto cldmask = pool_t::template alloc_and_init(ncol, nlay, ngpt); // Check that we do not have clouds with no optical properties; this would get corrected // when we assign optical props, but we want to use a "radiative cloud fraction" @@ -1417,7 +1417,7 @@ static optical_props1_t get_subsampled_clouds( // the vertical correlation of cloudy layers. I.e., cloudy layers might look maximally overlapped // even when separated by layers with no cloud properties, when in fact those layers should be // randomly overlapped. - auto cldfrac_rad = pool_t::template alloc(ncol, nlay); + auto cldfrac_rad = pool_t::template alloc_and_init(ncol, nlay); Kokkos::parallel_for(MDRP::template get<3>({nbnd,nlay,ncol}), KOKKOS_LAMBDA (int ibnd, int ilay, int icol) { if (cloud_optics.tau(icol,ilay,ibnd) > 0) { cldfrac_rad(icol,ilay) = cld(icol,ilay); @@ -1428,7 +1428,7 @@ static optical_props1_t get_subsampled_clouds( // Get unique seeds for each column that are reproducible across different MPI rank layouts; // use decimal part of pressure for this, consistent with the implementation in EAM; use different // seed values for longwave and shortwave - auto seeds = pool_t::template alloc(ncol); + auto seeds = pool_t::template alloc_and_init(ncol); Kokkos::parallel_for(ncol, KOKKOS_LAMBDA(int icol) { seeds(icol) = 1e9 * (p_lay(icol,nlay-2) - int(p_lay(icol,nlay-2))); }); From 360692f3004c740a542c00867f7c726e1ef56629 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Fri, 25 Oct 2024 13:51:46 -0600 Subject: [PATCH 009/147] Way more pool mem was being allocated than was needed --- components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp b/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp index 03cb0693d980..b96477c5a3fa 100644 --- a/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp +++ b/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp @@ -240,7 +240,7 @@ static void rrtmgp_initialize( load_cld_lutcoeff(cloud_optics_lw_k, cloud_optics_file_lw); // initialize kokkos rrtmgp pool allocator - const size_t base_ref = 18000; + const size_t base_ref = 4000; const size_t ncol = gas_concs.ncol; const size_t nlay = gas_concs.nlay; const size_t nlev = SCREAM_NUM_VERTICAL_LEV; From 1634f028d1781dc9e4a9bf45f741473fdaa06409 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Fri, 25 Oct 2024 14:22:22 -0600 Subject: [PATCH 010/147] Moved base_ref in the wrong direction --- components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp b/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp index b96477c5a3fa..e807643b05a9 100644 --- a/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp +++ b/components/eamxx/src/physics/rrtmgp/scream_rrtmgp_interface.hpp @@ -240,7 +240,7 @@ static void rrtmgp_initialize( load_cld_lutcoeff(cloud_optics_lw_k, cloud_optics_file_lw); // initialize kokkos rrtmgp pool allocator - const size_t base_ref = 4000; + const size_t base_ref = 80000; const size_t ncol = gas_concs.ncol; const size_t nlay = gas_concs.nlay; const size_t nlev = SCREAM_NUM_VERTICAL_LEV; From 0e5ef8403e47a44a2200b8ef625d03d315c20604 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Thu, 31 Oct 2024 11:11:55 -0600 Subject: [PATCH 011/147] Refactor cmake --- .../eamxx/src/physics/p3/tests/CMakeLists.txt | 118 +++++++++--------- 1 file changed, 57 insertions(+), 61 deletions(-) diff --git a/components/eamxx/src/physics/p3/tests/CMakeLists.txt b/components/eamxx/src/physics/p3/tests/CMakeLists.txt index 217c2945e489..d6793e6337b8 100644 --- a/components/eamxx/src/physics/p3/tests/CMakeLists.txt +++ b/components/eamxx/src/physics/p3/tests/CMakeLists.txt @@ -44,75 +44,71 @@ else () set (FORCE_RUN_DIFF_FAILS "") endif() -# NOTE: tests inside this if statement won't be built in a baselines-only build -if (NOT SCREAM_ONLY_GENERATE_BASELINES) - CreateUnitTest(p3_tests "${P3_TESTS_SRCS}" - LIBS p3 - THREADS 1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC} - LABELS "p3;physics") - - # Make sure that a diff in the two implementation triggers a failed test (in debug only) - CreateUnitTest (p3_tests_fail p3_rain_sed_unit_tests.cpp - LIBS p3 - COMPILER_CXX_DEFS SCREAM_FORCE_RUN_DIFF - THREADS 1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC} - LABELS "p3;physics;fail" - ${FORCE_RUN_DIFF_FAILS}) - - if (NOT SCREAM_P3_SMALL_KERNELS) - CreateUnitTest(p3_sk_tests "${P3_TESTS_SRCS}" - LIBS p3_sk - THREADS 1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC} - LABELS "p3_sk;physics") - - # Make sure that a diff in the two implementation triggers a failed test (in debug only) - CreateUnitTest (p3_sk_tests_fail p3_rain_sed_unit_tests.cpp - LIBS p3_sk - COMPILER_CXX_DEFS SCREAM_FORCE_RUN_DIFF - THREADS 1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC} - LABELS "p3_sk;physics;fail" - ${FORCE_RUN_DIFF_FAILS}) - endif() -endif() - if (SCREAM_ENABLE_BASELINE_TESTS) if (SCREAM_ONLY_GENERATE_BASELINES) set(BASELINE_FILE_ARG "-g -b ${SCREAM_BASELINES_DIR}/data/p3_run_and_cmp.baseline") else() - set(BASELINE_FILE_ARG "-b ${SCREAM_BASELINES_DIR}/data/p3_run_and_cmp.baseline") + set(BASELINE_FILE_ARG "-c -b ${SCREAM_BASELINES_DIR}/data/p3_run_and_cmp.baseline") endif() +else() + set(BASELINE_FILE_ARG "--no-baselines") +endif() - CreateUnitTestExec(p3_run_and_cmp "p3_run_and_cmp.cpp" - LIBS p3 - EXCLUDE_MAIN_CPP) +CreateUnitTest(p3_tests "${P3_TESTS_SRCS}" + LIBS p3 + EXE_ARGS "${BASELINE_FILE_ARG}" + THREADS 1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC} + LABELS "p3;physics") - CreateUnitTestFromExec(p3_run_and_cmp_cxx p3_run_and_cmp - THREADS ${SCREAM_TEST_MAX_THREADS} - EXE_ARGS "${BASELINE_FILE_ARG}" - LABELS "p3;physics") +# Make sure that a diff in the two implementation triggers a failed test (in debug only) +CreateUnitTest (p3_tests_fail p3_rain_sed_unit_tests.cpp + LIBS p3 + EXE_ARGS "${BASELINE_FILE_ARG}" + COMPILER_CXX_DEFS SCREAM_FORCE_RUN_DIFF + THREADS 1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC} + LABELS "p3;physics;fail" + ${FORCE_RUN_DIFF_FAILS}) - CreateUnitTestFromExec(p3_run_and_cmp_f90 p3_run_and_cmp - THREADS ${SCREAM_TEST_MAX_THREADS} - EXE_ARGS "-f ${BASELINE_FILE_ARG}" - LABELS "p3;physics") +if (NOT SCREAM_P3_SMALL_KERNELS) + CreateUnitTest(p3_sk_tests "${P3_TESTS_SRCS}" + LIBS p3_sk + EXE_ARGS "${BASELINE_FILE_ARG}" + THREADS 1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC} + LABELS "p3_sk;physics") - # Make sure that a diff from baselines triggers a failed test (in debug only) - CreateUnitTest(p3_run_and_cmp_cxx_fail "p3_run_and_cmp.cpp" - LIBS p3 - COMPILER_CXX_DEFS SCREAM_FORCE_RUN_DIFF - THREADS ${SCREAM_TEST_MAX_THREADS} - EXE_ARGS "${BASELINE_FILE_ARG}" - LABELS "p3;physics;fail" - EXCLUDE_MAIN_CPP - ${FORCE_RUN_DIFF_FAILS}) + # Make sure that a diff in the two implementation triggers a failed test (in debug only) + CreateUnitTest (p3_sk_tests_fail p3_rain_sed_unit_tests.cpp + LIBS p3_sk + EXE_ARGS "${BASELINE_FILE_ARG}" + COMPILER_CXX_DEFS SCREAM_FORCE_RUN_DIFF + THREADS 1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC} + LABELS "p3_sk;physics;fail" + ${FORCE_RUN_DIFF_FAILS}) +endif() - # By default, baselines should be created using all fortran (ctest -L baseline_gen). If the user wants - # to use CXX to generate their baselines, they should use "ctest -L baseline_gen_cxx". - # Note: the baseline_gen label label is really only used if SCREAM_ONLY_GENERATE_BASELINES=ON, but no harm adding it - if (SCREAM_TEST_MAX_THREADS GREATER 1) - # ECUT only adds _ompX if we have more than one value of X, or if X>1 - set (TEST_SUFFIX _omp${SCREAM_TEST_MAX_THREADS}) - endif() - set_tests_properties (p3_run_and_cmp_f90${TEST_SUFFIX} PROPERTIES LABELS "baseline_gen;baseline_cmp") - set_tests_properties (p3_run_and_cmp_cxx${TEST_SUFFIX} PROPERTIES LABELS "baseline_gen;cxx baseline_cmp") +CreateUnitTestExec(p3_run_and_cmp "p3_run_and_cmp.cpp" + LIBS p3 + EXCLUDE_MAIN_CPP) + +CreateUnitTestFromExec(p3_run_and_cmp_cxx p3_run_and_cmp + THREADS ${SCREAM_TEST_MAX_THREADS} + EXE_ARGS "${BASELINE_FILE_ARG}" + LABELS "p3;physics") + +# Make sure that a diff from baselines triggers a failed test (in debug only) +CreateUnitTest(p3_run_and_cmp_cxx_fail "p3_run_and_cmp.cpp" + LIBS p3 + COMPILER_CXX_DEFS SCREAM_FORCE_RUN_DIFF + THREADS ${SCREAM_TEST_MAX_THREADS} + EXE_ARGS "${BASELINE_FILE_ARG}" + LABELS "p3;physics;fail" + EXCLUDE_MAIN_CPP + ${FORCE_RUN_DIFF_FAILS}) + +# Note: the baseline_gen label label is really only used if SCREAM_ONLY_GENERATE_BASELINES=ON, but no harm adding it +if (SCREAM_TEST_MAX_THREADS GREATER 1) + # ECUT only adds _ompX if we have more than one value of X, or if X>1 + set (TEST_SUFFIX _omp${SCREAM_TEST_MAX_THREADS}) endif() + +set_tests_properties (p3_run_and_cmp_cxx${TEST_SUFFIX} PROPERTIES LABELS "baseline_gen;cxx baseline_cmp") From 48ea3a94cce21acc0e9f570a7060533582f6255f Mon Sep 17 00:00:00 2001 From: James Foucar Date: Thu, 31 Oct 2024 12:46:15 -0600 Subject: [PATCH 012/147] progress --- components/eamxx/src/physics/p3/p3_f90.cpp | 2 +- .../eamxx/src/physics/p3/tests/CMakeLists.txt | 15 +++--- .../p3/tests/p3_rain_sed_unit_tests.cpp | 4 +- .../physics/p3/tests/p3_unit_tests_common.hpp | 49 ++++++++++++++++++- 4 files changed, 59 insertions(+), 11 deletions(-) diff --git a/components/eamxx/src/physics/p3/p3_f90.cpp b/components/eamxx/src/physics/p3/p3_f90.cpp index 38bb84c416ec..650ad3c645db 100644 --- a/components/eamxx/src/physics/p3/p3_f90.cpp +++ b/components/eamxx/src/physics/p3/p3_f90.cpp @@ -79,7 +79,7 @@ void FortranDataIterator::init (const FortranData::Ptr& dp) { fdipb(nc); fdipb(qr); fdipb(nr); fdipb(qi); fdipb(ni); fdipb(qm); fdipb(bm); fdipb(precip_liq_surf); fdipb(precip_ice_surf); fdipb(diag_eff_radius_qc); fdipb(diag_eff_radius_qi); fdipb(diag_eff_radius_qr); fdipb(rho_qi); - fdipb(dpres); fdipb(inv_exner); fdipb(qv2qi_depos_tend); + fdipb(dpres); fdipb(inv_exner); fdipb(qv2qi_depos_tend); fdipb(precip_liq_flux); fdipb(precip_ice_flux); fdipb(cld_frac_r); fdipb(cld_frac_l); fdipb(cld_frac_i); fdipb(liq_ice_exchange); fdipb(vap_liq_exchange); diff --git a/components/eamxx/src/physics/p3/tests/CMakeLists.txt b/components/eamxx/src/physics/p3/tests/CMakeLists.txt index d6793e6337b8..d5980d91cbf6 100644 --- a/components/eamxx/src/physics/p3/tests/CMakeLists.txt +++ b/components/eamxx/src/physics/p3/tests/CMakeLists.txt @@ -44,26 +44,27 @@ else () set (FORCE_RUN_DIFF_FAILS "") endif() +# All tests should understand the same baseline args if (SCREAM_ENABLE_BASELINE_TESTS) if (SCREAM_ONLY_GENERATE_BASELINES) - set(BASELINE_FILE_ARG "-g -b ${SCREAM_BASELINES_DIR}/data/p3_run_and_cmp.baseline") + set(BASELINE_FILE_ARG "-g -b ${SCREAM_BASELINES_DIR}/data") else() - set(BASELINE_FILE_ARG "-c -b ${SCREAM_BASELINES_DIR}/data/p3_run_and_cmp.baseline") + set(BASELINE_FILE_ARG "-c -b ${SCREAM_BASELINES_DIR}/data") endif() else() - set(BASELINE_FILE_ARG "--no-baselines") + set(BASELINE_FILE_ARG "-n") # no baselines endif() CreateUnitTest(p3_tests "${P3_TESTS_SRCS}" LIBS p3 - EXE_ARGS "${BASELINE_FILE_ARG}" + EXE_ARGS "--flags='${BASELINE_FILE_ARG}'" THREADS 1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC} LABELS "p3;physics") # Make sure that a diff in the two implementation triggers a failed test (in debug only) CreateUnitTest (p3_tests_fail p3_rain_sed_unit_tests.cpp LIBS p3 - EXE_ARGS "${BASELINE_FILE_ARG}" + EXE_ARGS "--flags='${BASELINE_FILE_ARG}'" COMPILER_CXX_DEFS SCREAM_FORCE_RUN_DIFF THREADS 1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC} LABELS "p3;physics;fail" @@ -72,14 +73,14 @@ CreateUnitTest (p3_tests_fail p3_rain_sed_unit_tests.cpp if (NOT SCREAM_P3_SMALL_KERNELS) CreateUnitTest(p3_sk_tests "${P3_TESTS_SRCS}" LIBS p3_sk - EXE_ARGS "${BASELINE_FILE_ARG}" + EXE_ARGS "--flags='${BASELINE_FILE_ARG}'" THREADS 1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC} LABELS "p3_sk;physics") # Make sure that a diff in the two implementation triggers a failed test (in debug only) CreateUnitTest (p3_sk_tests_fail p3_rain_sed_unit_tests.cpp LIBS p3_sk - EXE_ARGS "${BASELINE_FILE_ARG}" + EXE_ARGS "--flags='${BASELINE_FILE_ARG}'" COMPILER_CXX_DEFS SCREAM_FORCE_RUN_DIFF THREADS 1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC} LABELS "p3_sk;physics;fail" diff --git a/components/eamxx/src/physics/p3/tests/p3_rain_sed_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_rain_sed_unit_tests.cpp index 443b3801404b..2d6cd8d0a00e 100644 --- a/components/eamxx/src/physics/p3/tests/p3_rain_sed_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_rain_sed_unit_tests.cpp @@ -20,7 +20,7 @@ namespace p3 { namespace unit_test { template -struct UnitWrap::UnitTest::TestRainSed { +struct UnitWrap::UnitTest::TestRainSed : public UnitWrap::UnitTest::Base { static void run_phys_rain_vel() { @@ -219,7 +219,7 @@ TEST_CASE("p3_rain_sed", "[p3_functions]") { using TRS = scream::p3::unit_test::UnitWrap::UnitTest::TestRainSed; - scream::p3::p3_init(); // need fortran table data + TRS::init(); TRS::run_phys(); TRS::run_bfb(); diff --git a/components/eamxx/src/physics/p3/tests/p3_unit_tests_common.hpp b/components/eamxx/src/physics/p3/tests/p3_unit_tests_common.hpp index 68f4491f789d..611173af2c13 100644 --- a/components/eamxx/src/physics/p3/tests/p3_unit_tests_common.hpp +++ b/components/eamxx/src/physics/p3/tests/p3_unit_tests_common.hpp @@ -3,6 +3,11 @@ #include "share/scream_types.hpp" #include "p3_functions.hpp" +#include "p3_f90.hpp" +#include "ekat/util/ekat_test_utils.hpp" + +#include +#include namespace scream { namespace p3 { @@ -20,6 +25,12 @@ namespace unit_test { struct UnitWrap { + enum BASELINE_ACTION { + NONE, + COMPARE, + GENERATE + }; + template struct UnitTest : public KokkosTypes { @@ -58,6 +69,43 @@ struct UnitWrap { static constexpr Int max_pack_size = 16; static constexpr Int num_test_itrs = max_pack_size / Spack::n; + struct Base { + static inline std::string BASELINE_PATH; + static inline BASELINE_ACTION ACTION; + + static void init() + { + scream::p3::p3_init(); // many tests will need fortran table data + auto& ts = ekat::TestSession::get(); + auto raw_flags = ts.flags.begin()->first; + std::stringstream ss(raw_flags); + std::string flag; + ACTION = NONE; + BASELINE_PATH = ""; + bool next_token_is_path = false; + while (ss >> flag) { + if (flag == "-c") { + ACTION = COMPARE; + } + else if (flag == "-g") { + ACTION = GENERATE; + } + else if (flag == "-n") { + ACTION = NONE; + } + else if (flag == "-b") { + next_token_is_path = true; + } + else if (next_token_is_path) { + BASELINE_PATH = flag; + next_token_is_path = false; + } + } + EKAT_REQUIRE_MSG( !(ACTION != NONE && BASELINE_PATH == ""), + "P3 unit test flags problem: baseline actions were requested but no baseline path was provided"); + } + }; + // Put struct decls here struct TestTableIce; struct TestTable3; @@ -102,7 +150,6 @@ struct UnitWrap { struct TestIceDepositionSublimation; struct TestPreventLiqSupersaturation; }; - }; } // namespace unit_test From 7f9aaacd31cf3f7bf20c1d3d8518c5725659669a Mon Sep 17 00:00:00 2001 From: James Foucar Date: Thu, 31 Oct 2024 14:17:24 -0600 Subject: [PATCH 013/147] Transition to object complete --- .../p3/tests/p3_autoconversion_unit_tests.cpp | 20 +++--- .../p3_back_to_cell_average_unit_tests.cpp | 15 ++-- ...lc_liq_relaxation_timescale_unit_tests.cpp | 13 ++-- .../tests/p3_calc_rime_density_unit_tests.cpp | 15 ++-- .../p3/tests/p3_check_values_unit_tests.cpp | 17 ++--- .../p3_cldliq_imm_freezing_unit_tests.cpp | 15 ++-- .../p3/tests/p3_cloud_rain_acc_unit_tests.cpp | 15 ++-- .../p3/tests/p3_cloud_sed_unit_tests.cpp | 15 ++-- .../tests/p3_droplet_self_coll_unit_tests.cpp | 15 ++-- .../physics/p3/tests/p3_dsd2_unit_tests.cpp | 24 ++++--- .../p3/tests/p3_evaporate_rain_unit_tests.cpp | 29 ++++---- .../physics/p3/tests/p3_find_unit_tests.cpp | 9 ++- .../tests/p3_get_latent_heat_unit_tests.cpp | 13 ++-- .../p3_ice_cldliq_wet_growth_unit_tests.cpp | 13 ++-- .../p3/tests/p3_ice_collection_unit_tests.cpp | 38 +++++----- .../p3_ice_deposition_sublimation_tests.cpp | 26 +++---- .../p3/tests/p3_ice_melting_unit_tests.cpp | 16 +++-- .../p3/tests/p3_ice_nucleation_unit_tests.cpp | 13 ++-- ...p3_ice_relaxation_timescale_unit_tests.cpp | 13 ++-- .../p3/tests/p3_ice_sed_unit_tests.cpp | 27 ++++---- .../p3_ice_supersat_conservation_tests.cpp | 9 +-- .../p3/tests/p3_ice_tables_unit_tests.cpp | 19 ++--- .../p3_incloud_mixingratios_unit_tests.cpp | 13 ++-- .../physics/p3/tests/p3_main_unit_tests.cpp | 31 ++++----- .../p3/tests/p3_nc_conservation_tests.cpp | 9 +-- .../p3/tests/p3_ni_conservation_tests.cpp | 9 +-- .../p3/tests/p3_nr_conservation_tests.cpp | 9 +-- .../p3_prevent_liq_supersaturation_tests.cpp | 18 +++-- .../tests/p3_rain_imm_freezing_unit_tests.cpp | 15 ++-- .../p3/tests/p3_rain_sed_unit_tests.cpp | 23 +++---- .../tests/p3_rain_self_collection_tests.cpp | 11 +-- ...p3_subgrid_variance_scaling_unit_tests.cpp | 22 +++--- .../physics/p3/tests/p3_table3_unit_tests.cpp | 9 +-- .../src/physics/p3/tests/p3_unit_tests.cpp | 69 +++++++++++-------- .../physics/p3/tests/p3_unit_tests_common.hpp | 26 ++++--- .../physics/p3/tests/p3_upwind_unit_tests.cpp | 26 +++---- 36 files changed, 360 insertions(+), 319 deletions(-) diff --git a/components/eamxx/src/physics/p3/tests/p3_autoconversion_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_autoconversion_unit_tests.cpp index 78f673121dd6..e4ff1fd43669 100644 --- a/components/eamxx/src/physics/p3/tests/p3_autoconversion_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_autoconversion_unit_tests.cpp @@ -19,10 +19,10 @@ namespace p3 { namespace unit_test { template -struct UnitWrap::UnitTest::TestP3CloudWaterAutoconversion +struct UnitWrap::UnitTest::TestP3CloudWaterAutoconversion : public UnitWrap::UnitTest::Base { -static void cloud_water_autoconversion_unit_bfb_tests(){ +void cloud_water_autoconversion_unit_bfb_tests() { CloudWaterAutoconversionData cwadc[max_pack_size] = { // rho, qc_incld, nc_incld, inv_qc_relvar @@ -114,11 +114,11 @@ static void cloud_water_autoconversion_unit_bfb_tests(){ } } - static void run_bfb(){ + void run_bfb() { cloud_water_autoconversion_unit_bfb_tests(); } - KOKKOS_FUNCTION static void autoconversion_is_positive(const Int &i, Int &errors){ + KOKKOS_FUNCTION static void autoconversion_is_positive(const Int &i, Int &errors){ const Spack rho(1.0), inv_qc_relvar(1.0); Spack qc_incld, nc_incld(1e7), qc2qr_autoconv_tend(0.0), nc2nr_autoconv_tend(0.0), ncautr(0.0); @@ -134,7 +134,7 @@ static void cloud_water_autoconversion_unit_bfb_tests(){ } } - static void run_physics(){ + void run_physics(){ int nerr = 0; @@ -153,12 +153,14 @@ static void cloud_water_autoconversion_unit_bfb_tests(){ } // namespace p3 } // namespace scream -namespace{ +namespace { TEST_CASE("p3_cloud_water_autoconversion_test", "[p3_cloud_water_autoconversion_test]"){ - scream::p3::unit_test::UnitWrap::UnitTest::TestP3CloudWaterAutoconversion::run_physics(); - scream::p3::unit_test::UnitWrap::UnitTest::TestP3CloudWaterAutoconversion::run_bfb(); + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestP3CloudWaterAutoconversion; + + T t; + t.run_physics(); + t.run_bfb(); } } // namespace - diff --git a/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp index 0377b990d786..f73bd3d993a2 100644 --- a/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp @@ -19,14 +19,14 @@ namespace p3 { namespace unit_test { template -struct UnitWrap::UnitTest::TestBackToCellAverage { +struct UnitWrap::UnitTest::TestBackToCellAverage : public UnitWrap::UnitTest::Base { -static void run_phys() +void run_phys() { // TODO } -static void run_bfb() +void run_bfb() { auto engine = setup_random_test(); @@ -181,12 +181,11 @@ namespace { TEST_CASE("p3_back_to_cell_average", "[p3_functions]") { - using TRIF = scream::p3::unit_test::UnitWrap::UnitTest::TestBackToCellAverage; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestBackToCellAverage; - TRIF::run_phys(); - TRIF::run_bfb(); - - scream::p3::P3GlobalForFortran::deinit(); + T t; + t.run_phys(); + t.run_bfb(); } } // namespace diff --git a/components/eamxx/src/physics/p3/tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp index 97193fd06d31..69715267176d 100644 --- a/components/eamxx/src/physics/p3/tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp @@ -20,14 +20,14 @@ namespace p3 { namespace unit_test { template -struct UnitWrap::UnitTest::TestCalcLiqRelaxationTimescale { +struct UnitWrap::UnitTest::TestCalcLiqRelaxationTimescale : public UnitWrap::UnitTest::Base { - static void run_phys() + void run_phys() { // TODO } - static void run_bfb() + void run_bfb() { auto engine = setup_random_test(); @@ -115,10 +115,11 @@ namespace { TEST_CASE("p3_calc_liq_relaxation_timescale", "[p3_functions]") { - using TD = scream::p3::unit_test::UnitWrap::UnitTest::TestCalcLiqRelaxationTimescale; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestCalcLiqRelaxationTimescale; - TD::run_phys(); - TD::run_bfb(); + T t; + t.run_phys(); + t.run_bfb(); } } diff --git a/components/eamxx/src/physics/p3/tests/p3_calc_rime_density_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_calc_rime_density_unit_tests.cpp index 5d70c7302ae1..f858797fa002 100644 --- a/components/eamxx/src/physics/p3/tests/p3_calc_rime_density_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_calc_rime_density_unit_tests.cpp @@ -18,14 +18,14 @@ namespace p3 { namespace unit_test { template -struct UnitWrap::UnitTest::TestCalcRimeDensity { +struct UnitWrap::UnitTest::TestCalcRimeDensity : public UnitWrap::UnitTest::Base { -static void run_phys() +void run_phys() { // TODO } -static void run_bfb() +void run_bfb() { // This is the threshold for whether the qc cloud mixing ratio is large // enough to affect the rime density. @@ -144,12 +144,11 @@ namespace { TEST_CASE("p3_calc_rime_density", "[p3_functions]") { - using TRIF = scream::p3::unit_test::UnitWrap::UnitTest::TestCalcRimeDensity; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestCalcRimeDensity; - TRIF::run_phys(); - TRIF::run_bfb(); - - scream::p3::P3GlobalForFortran::deinit(); + T t; + t.run_phys(); + t.run_bfb(); } } // namespace diff --git a/components/eamxx/src/physics/p3/tests/p3_check_values_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_check_values_unit_tests.cpp index f2f4a7f44047..8b9ecf3904fd 100644 --- a/components/eamxx/src/physics/p3/tests/p3_check_values_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_check_values_unit_tests.cpp @@ -20,9 +20,9 @@ namespace p3 { namespace unit_test { template -struct UnitWrap::UnitTest::TestCheckValues { +struct UnitWrap::UnitTest::TestCheckValues : public UnitWrap::UnitTest::Base { -static void run_check_values_bfb() +void run_check_values_bfb() { auto engine = setup_random_test(); @@ -60,7 +60,7 @@ static void run_check_values_bfb() } } -static void run_check_values_phys() +void run_check_values_phys() { // TODO } @@ -75,14 +75,11 @@ namespace { TEST_CASE("p3_check_values", "[p3_functions]") { - using TRS = scream::p3::unit_test::UnitWrap::UnitTest::TestCheckValues; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestCheckValues; - scream::p3::p3_init(); // need fortran table data - - TRS::run_check_values_phys(); - TRS::run_check_values_bfb(); - - scream::p3::P3GlobalForFortran::deinit(); + T t; + t.run_check_values_phys(); + t.run_check_values_bfb(); } } // namespace diff --git a/components/eamxx/src/physics/p3/tests/p3_cldliq_imm_freezing_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_cldliq_imm_freezing_unit_tests.cpp index eeccb70fd58a..901650d8695b 100644 --- a/components/eamxx/src/physics/p3/tests/p3_cldliq_imm_freezing_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_cldliq_imm_freezing_unit_tests.cpp @@ -18,14 +18,14 @@ namespace p3 { namespace unit_test { template -struct UnitWrap::UnitTest::TestCldliqImmersionFreezing { +struct UnitWrap::UnitTest::TestCldliqImmersionFreezing : public UnitWrap::UnitTest::Base { -static void run_phys() +void run_phys() { // TODO } -static void run_bfb() +void run_bfb() { // This is the threshold for whether the qc and qr cloud mixing ratios are // large enough to affect the warm-phase process rates qc2qr_accret_tend and nc_accret_tend. @@ -127,12 +127,11 @@ namespace { TEST_CASE("p3_cldliq_immersion_freezing", "[p3_functions]") { - using TRIF = scream::p3::unit_test::UnitWrap::UnitTest::TestCldliqImmersionFreezing; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestCldliqImmersionFreezing; - TRIF::run_phys(); - TRIF::run_bfb(); - - scream::p3::P3GlobalForFortran::deinit(); + T t; + t.run_phys(); + t.run_bfb(); } } // namespace diff --git a/components/eamxx/src/physics/p3/tests/p3_cloud_rain_acc_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_cloud_rain_acc_unit_tests.cpp index 472f9de1987a..2cfe22e5a260 100644 --- a/components/eamxx/src/physics/p3/tests/p3_cloud_rain_acc_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_cloud_rain_acc_unit_tests.cpp @@ -18,14 +18,14 @@ namespace p3 { namespace unit_test { template -struct UnitWrap::UnitTest::TestCloudRainAccretion { +struct UnitWrap::UnitTest::TestCloudRainAccretion : public UnitWrap::UnitTest::Base { -static void run_phys() +void run_phys() { // TODO } -static void run_bfb() +void run_bfb() { // This is the threshold for whether the qc and qr cloud mixing ratios are // large enough to affect the warm-phase process rates qc2qr_accret_tend and nc_accret_tend. @@ -130,12 +130,11 @@ namespace { TEST_CASE("p3_cloud_rain_accretion", "[p3_functions]") { - using TCRA = scream::p3::unit_test::UnitWrap::UnitTest::TestCloudRainAccretion; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestCloudRainAccretion; - TCRA::run_phys(); - TCRA::run_bfb(); - - scream::p3::P3GlobalForFortran::deinit(); + T t; + t.run_phys(); + t.run_bfb(); } } // namespace diff --git a/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp index 19fe5b3279e7..b11400c98f42 100644 --- a/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp @@ -19,14 +19,14 @@ namespace p3 { namespace unit_test { template -struct UnitWrap::UnitTest::TestCloudSed { +struct UnitWrap::UnitTest::TestCloudSed : public UnitWrap::UnitTest::Base { -static void run_phys() +void run_phys() { // TODO } -static void run_bfb() +void run_bfb() { auto engine = setup_random_test(); @@ -98,12 +98,11 @@ namespace { TEST_CASE("p3_cloud_sed", "[p3_functions]") { - using TCS = scream::p3::unit_test::UnitWrap::UnitTest::TestCloudSed; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestCloudSed; - TCS::run_phys(); - TCS::run_bfb(); - - scream::p3::P3GlobalForFortran::deinit(); + T t; + t.run_phys(); + t.run_bfb(); } } // namespace diff --git a/components/eamxx/src/physics/p3/tests/p3_droplet_self_coll_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_droplet_self_coll_unit_tests.cpp index b81505816eac..fccf41db6272 100644 --- a/components/eamxx/src/physics/p3/tests/p3_droplet_self_coll_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_droplet_self_coll_unit_tests.cpp @@ -18,14 +18,14 @@ namespace p3 { namespace unit_test { template -struct UnitWrap::UnitTest::TestDropletSelfCollection { +struct UnitWrap::UnitTest::TestDropletSelfCollection : public UnitWrap::UnitTest::Base { -static void run_phys() +void run_phys() { // TODO } -static void run_bfb() +void run_bfb() { // This is the threshold for whether the qc and qr cloud mixing ratios are // large enough to affect the warm-phase process rates qc2qr_accret_tend and nc_accret_tend. @@ -124,12 +124,11 @@ namespace { TEST_CASE("p3_droplet_self_collection", "[p3_functions]") { - using TCRA = scream::p3::unit_test::UnitWrap::UnitTest::TestDropletSelfCollection; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestDropletSelfCollection; - TCRA::run_phys(); - TCRA::run_bfb(); - - scream::p3::P3GlobalForFortran::deinit(); + T t; + t.run_phys(); + t.run_bfb(); } } // namespace diff --git a/components/eamxx/src/physics/p3/tests/p3_dsd2_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_dsd2_unit_tests.cpp index 50894b03855f..43c5a7de8dde 100644 --- a/components/eamxx/src/physics/p3/tests/p3_dsd2_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_dsd2_unit_tests.cpp @@ -22,9 +22,9 @@ namespace unit_test { */ template -struct UnitWrap::UnitTest::TestDsd2 { +struct UnitWrap::UnitTest::TestDsd2 : public UnitWrap::UnitTest::Base { - static void run_cloud_bfb() + void run_cloud_bfb() { // Read in tables view_2d_table vn_table_vals; view_2d_table vm_table_vals; view_2d_table revap_table_vals; @@ -107,12 +107,12 @@ struct UnitWrap::UnitTest::TestDsd2 { } } - static void run_cloud_phys() + void run_cloud_phys() { // TODO } - static void run_rain_bfb() + void run_rain_bfb() { using KTH = KokkosTypes; @@ -190,7 +190,7 @@ struct UnitWrap::UnitTest::TestDsd2 { } } - static void run_rain_phys() + void run_rain_phys() { // TODO } @@ -204,18 +204,20 @@ namespace { TEST_CASE("p3_cloud_dsd2", "[p3_functions]") { - using TD = scream::p3::unit_test::UnitWrap::UnitTest::TestDsd2; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestDsd2; - TD::run_cloud_phys(); - TD::run_cloud_bfb(); + T t; + t.run_cloud_phys(); + t.run_cloud_bfb(); } TEST_CASE("p3_rain_dsd2", "[p3_functions]") { - using TD = scream::p3::unit_test::UnitWrap::UnitTest::TestDsd2; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestDsd2; - TD::run_rain_phys(); - TD::run_rain_bfb(); + T t; + t.run_rain_phys(); + t.run_rain_bfb(); } } diff --git a/components/eamxx/src/physics/p3/tests/p3_evaporate_rain_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_evaporate_rain_unit_tests.cpp index f8398135a19e..9df3ecdb0c82 100644 --- a/components/eamxx/src/physics/p3/tests/p3_evaporate_rain_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_evaporate_rain_unit_tests.cpp @@ -8,21 +8,14 @@ #include "p3_unit_tests_common.hpp" -//#include -//#include -//#include -//#include -//#include // std::setprecision - namespace scream { namespace p3 { namespace unit_test { template -struct UnitWrap::UnitTest::TestEvapSublPrecip -{ +struct UnitWrap::UnitTest::TestEvapSublPrecip : public UnitWrap::UnitTest::Base { - static void run_property(){ + void run_property() { //TEST WEIGHTING TIMESCALE //======================== @@ -133,9 +126,9 @@ struct UnitWrap::UnitTest::TestEvapSublPrecip REQUIRE( qrtend[0] <= qr_incld[0]/dt); REQUIRE( nrtend[0] <= nr_incld[0]/dt); //keep end-of-step nr positive. Should always be true. - }; //end run_property + } //end run_property - static void run_bfb(){ + void run_bfb() { constexpr Scalar latvap = C::LatVap; constexpr Scalar latice = C::LatIce; @@ -267,14 +260,18 @@ namespace { TEST_CASE("p3_evaporate_rain_property", "p3_unit_tests") { - using TestStruct = scream::p3::unit_test::UnitWrap::UnitTest::TestEvapSublPrecip; - TestStruct::run_property(); + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestEvapSublPrecip; + + T t; + t.run_property(); } TEST_CASE("p3_evaporate_rain_test", "p3_unit_tests") { - using TestStruct = scream::p3::unit_test::UnitWrap::UnitTest::TestEvapSublPrecip; - TestStruct::run_bfb(); -} + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestEvapSublPrecip; + + T t; + t.run_bfb(); + } }// end anonymous namespace diff --git a/components/eamxx/src/physics/p3/tests/p3_find_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_find_unit_tests.cpp index 4ba2dc6760e7..9c812f8f8426 100644 --- a/components/eamxx/src/physics/p3/tests/p3_find_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_find_unit_tests.cpp @@ -22,9 +22,9 @@ namespace unit_test { // template -struct UnitWrap::UnitTest::TestFind { +struct UnitWrap::UnitTest::TestFind : public UnitWrap::UnitTest::Base { -static void run() +void run() { const int max_threads = #ifdef KOKKOS_ENABLE_OPENMP @@ -112,7 +112,10 @@ namespace { TEST_CASE("p3_find", "[p3_functions]") { - scream::p3::unit_test::UnitWrap::UnitTest::TestFind::run(); + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestFind; + + T t; + t.run(); } } // namespace diff --git a/components/eamxx/src/physics/p3/tests/p3_get_latent_heat_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_get_latent_heat_unit_tests.cpp index 5d7b4de4ea7e..dfe6f3ca6a49 100644 --- a/components/eamxx/src/physics/p3/tests/p3_get_latent_heat_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_get_latent_heat_unit_tests.cpp @@ -20,9 +20,9 @@ namespace p3 { namespace unit_test { template -struct UnitWrap::UnitTest::TestLatentHeat { +struct UnitWrap::UnitTest::TestLatentHeat : public UnitWrap::UnitTest::Base { - static void run_latent_heat_bfb() + void run_latent_heat_bfb() { constexpr Scalar latvap = C::LatVap; constexpr Scalar latice = C::LatIce; @@ -55,7 +55,7 @@ struct UnitWrap::UnitTest::TestLatentHeat { } } - static void run_latent_heat_phys() + void run_latent_heat_phys() { // TODO } @@ -69,10 +69,11 @@ namespace { TEST_CASE("p3_latent_heat", "[p3_functions]") { - using TD = scream::p3::unit_test::UnitWrap::UnitTest::TestLatentHeat; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestLatentHeat; - TD::run_latent_heat_phys(); - TD::run_latent_heat_bfb(); + T t; + t.run_latent_heat_phys(); + t.run_latent_heat_bfb(); } } diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_cldliq_wet_growth_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_cldliq_wet_growth_unit_tests.cpp index caf6638d5cd5..e2a61b374818 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_cldliq_wet_growth_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_cldliq_wet_growth_unit_tests.cpp @@ -19,9 +19,9 @@ namespace p3 { namespace unit_test { template -struct UnitWrap::UnitTest::TestIceCldliqWetGrowth { +struct UnitWrap::UnitTest::TestIceCldliqWetGrowth : public UnitWrap::UnitTest::Base { - static void run_ice_cldliq_wet_growth_bfb() + void run_ice_cldliq_wet_growth_bfb() { using KTH = KokkosTypes; @@ -127,7 +127,7 @@ struct UnitWrap::UnitTest::TestIceCldliqWetGrowth { } } - static void run_ice_cldliq_wet_growth_phys() + void run_ice_cldliq_wet_growth_phys() { // TODO } @@ -141,10 +141,11 @@ namespace { TEST_CASE("p3_ice_cldliq_wet_growth", "[p3_functions]") { - using TD = scream::p3::unit_test::UnitWrap::UnitTest::TestIceCldliqWetGrowth; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestIceCldliqWetGrowth; - TD::run_ice_cldliq_wet_growth_phys(); - TD::run_ice_cldliq_wet_growth_bfb(); + T t; + t.run_ice_cldliq_wet_growth_phys(); + t.run_ice_cldliq_wet_growth_bfb(); } } diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_collection_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_collection_unit_tests.cpp index 8fa1649b1213..9c628c0641ce 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_collection_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_collection_unit_tests.cpp @@ -22,9 +22,9 @@ namespace unit_test { * Unit-tests for p3 ice collection functions. */ template -struct UnitWrap::UnitTest::TestIceCollection { +struct UnitWrap::UnitTest::TestIceCollection : public UnitWrap::UnitTest::Base { - static void run_ice_cldliq_bfb() + void run_ice_cldliq_bfb() { // Read in tables view_2d_table vn_table_vals; @@ -119,12 +119,12 @@ struct UnitWrap::UnitTest::TestIceCollection { } } - static void run_ice_cldliq_phys() + void run_ice_cldliq_phys() { // TODO } - static void run_ice_rain_bfb() + void run_ice_rain_bfb() { using KTH = KokkosTypes; @@ -206,12 +206,12 @@ struct UnitWrap::UnitTest::TestIceCollection { } } - static void run_ice_rain_phys() + void run_ice_rain_phys() { // TODO } - static void run_ice_self_bfb() + void run_ice_self_bfb() { using KTH = KokkosTypes; @@ -283,8 +283,7 @@ struct UnitWrap::UnitTest::TestIceCollection { } } - - static void run_ice_self_phys() + void run_ice_self_phys() { // TODO } @@ -298,24 +297,29 @@ namespace { TEST_CASE("p3_ice_cldliq", "[p3_functions]") { - using TD = scream::p3::unit_test::UnitWrap::UnitTest::TestIceCollection; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestIceCollection; - TD::run_ice_cldliq_phys(); - TD::run_ice_cldliq_bfb(); + T t; + t.run_ice_cldliq_phys(); + t.run_ice_cldliq_bfb(); } TEST_CASE("p3_ice_rain", "[p3_functions]") { - using TD = scream::p3::unit_test::UnitWrap::UnitTest::TestIceCollection; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestIceCollection; - TD::run_ice_rain_phys(); - TD::run_ice_rain_bfb(); + T t; + t.run_ice_rain_phys(); + t.run_ice_rain_bfb(); } TEST_CASE("p3_ice_self", "[p3_functions]") { - using TD = scream::p3::unit_test::UnitWrap::UnitTest::TestIceCollection; - TD::run_ice_self_phys(); - TD::run_ice_self_bfb(); + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestIceCollection; + + T t; + t.run_ice_self_phys(); + t.run_ice_self_bfb(); } + } diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_deposition_sublimation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_deposition_sublimation_tests.cpp index bc1921441bb3..f6afd915dc63 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_deposition_sublimation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_deposition_sublimation_tests.cpp @@ -13,9 +13,9 @@ namespace p3 { namespace unit_test { template -struct UnitWrap::UnitTest::TestIceDepositionSublimation { +struct UnitWrap::UnitTest::TestIceDepositionSublimation : public UnitWrap::UnitTest::Base { - static void run_property(){ + void run_property() { //Note that a lot of property tests are included in run_bfb for simplicity //Choose default values (just grabbed a row from the array in run_bfb) @@ -30,13 +30,13 @@ struct UnitWrap::UnitTest::TestIceDepositionSublimation { //init output vars Spack qv2qi_vapdep_tend, qi2qv_sublim_tend, ni_sublim_tend, qc2qi_berg_tend; - + //CHECK THAT UNREASONABLY LARGE VAPOR DEPOSITION DOESN'T LEAVE QV SUBSATURATED WRT QI Spack epsi_tmp=1e6; //make 1/(sat removal timescale) huge so vapdep rate removes all supersat in 1 dt. Functions::ice_deposition_sublimation(qi_incld, ni_incld, T_atm, qv_sat_l, qv_sat_i, epsi_tmp, abi, qv, inv_dt, qv2qi_vapdep_tend, qi2qv_sublim_tend, ni_sublim_tend, qc2qi_berg_tend); REQUIRE( (qv2qi_vapdep_tend[0]==0 || std::abs( qv2qi_vapdep_tend[0] - (qv[0] - qv_sat_i[0])*inv_dt) <1e-8) ); - + //CHECK THAT HUGE SUBLIMATION DOESN'T LEAVE QV SUPERSATURATED WRT QI Spack qv_sat_i_tmp=1e-2; Functions::ice_deposition_sublimation(qi_incld, ni_incld, T_atm, qv_sat_l, qv_sat_i_tmp, @@ -46,8 +46,8 @@ struct UnitWrap::UnitTest::TestIceDepositionSublimation { //CHECK BEHAVIOR AS DT->0? } - - static void run_bfb() + + void run_bfb() { IceDepositionSublimationData f90_data[max_pack_size] = { {1.0000E-04,4.5010E+05,2.8750E+02,1.1279E-02,1.1279E-02,0.0000E+00,3.3648E+00,5.0000E-03,1.666667e-02}, @@ -67,7 +67,7 @@ struct UnitWrap::UnitTest::TestIceDepositionSublimation { {5.1000E-03,5.1317E+05,2.5834E+02,1.6757E-03,1.4491E-03,6.0620E-02,1.3763E+00,5.0000E-03,1.666667e-02}, {5.0000E-08,5.4479E+05,2.4793E+02,7.5430E-04,5.8895E-04,4.6769E-04,1.1661E+00,1.5278E-04,1.666667e-02}, }; - + static constexpr Int num_runs = sizeof(f90_data) / sizeof(IceDepositionSublimationData); // Generate random input data @@ -162,16 +162,18 @@ namespace { TEST_CASE("ice_deposition_sublimation_property", "[p3]") { - using TestStruct = scream::p3::unit_test::UnitWrap::UnitTest::TestIceDepositionSublimation; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestIceDepositionSublimation; - TestStruct::run_property(); + T t; + t.run_property(); } - + TEST_CASE("ice_deposition_sublimation_bfb", "[p3]") { - using TestStruct = scream::p3::unit_test::UnitWrap::UnitTest::TestIceDepositionSublimation; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestIceDepositionSublimation; - TestStruct::run_bfb(); + T t; + t.run_bfb(); } } // empty namespace diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_melting_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_melting_unit_tests.cpp index 28c6582f8a14..5e29579a9107 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_melting_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_melting_unit_tests.cpp @@ -19,10 +19,10 @@ namespace p3 { namespace unit_test { template -struct UnitWrap::UnitTest::TestP3IceMelting +struct UnitWrap::UnitTest::TestP3IceMelting : public UnitWrap::UnitTest::Base { -static void ice_melting_bfb(){ +void ice_melting_bfb() { constexpr Scalar latvap = C::LatVap; constexpr Scalar latice = C::LatIce; @@ -105,7 +105,7 @@ static void ice_melting_bfb(){ REQUIRE(IceMelt[s].ni2nr_melt_tend == IceMelt_host(s).ni2nr_melt_tend); } } -}; // TestP3IceMelting +} }; // UnitWrap @@ -113,11 +113,13 @@ static void ice_melting_bfb(){ } // namespace p3 } // namespace scream -namespace{ +namespace { + +TEST_CASE("p3_ice_melting_test", "[p3_ice_melting_test]") { + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestP3IceMelting; -TEST_CASE("p3_ice_melting_test", "[p3_ice_melting_test]"){ - scream::p3::unit_test::UnitWrap::UnitTest::TestP3IceMelting::ice_melting_bfb(); + T t; + t.ice_melting_bfb(); } } // namespace - diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_nucleation_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_nucleation_unit_tests.cpp index 4e54b8837e04..51ab5031c45f 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_nucleation_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_nucleation_unit_tests.cpp @@ -19,9 +19,9 @@ namespace p3 { namespace unit_test { template -struct UnitWrap::UnitTest::TestIceNucleation { +struct UnitWrap::UnitTest::TestIceNucleation : public UnitWrap::UnitTest::Base { - static void run_ice_nucleation_bfb() + void run_ice_nucleation_bfb() { using KTH = KokkosTypes; @@ -104,7 +104,7 @@ struct UnitWrap::UnitTest::TestIceNucleation { } //end for do_prescribed_CCN } - static void run_ice_nucleation_phys() + void run_ice_nucleation_phys() { // TODO } @@ -118,10 +118,11 @@ namespace { TEST_CASE("p3_ice_nucleation", "[p3_functions]") { - using TD = scream::p3::unit_test::UnitWrap::UnitTest::TestIceNucleation; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestIceNucleation; - TD::run_ice_nucleation_phys(); - TD::run_ice_nucleation_bfb(); + T t; + t.run_ice_nucleation_phys(); + t.run_ice_nucleation_bfb(); } } diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_relaxation_timescale_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_relaxation_timescale_unit_tests.cpp index a75b55fdbece..dfb668bc81d8 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_relaxation_timescale_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_relaxation_timescale_unit_tests.cpp @@ -19,9 +19,9 @@ namespace p3 { namespace unit_test { template -struct UnitWrap::UnitTest::TestIceRelaxationTimescale { +struct UnitWrap::UnitTest::TestIceRelaxationTimescale : public UnitWrap::UnitTest::Base { - static void run_ice_relaxation_timescale_bfb() + void run_ice_relaxation_timescale_bfb() { using KTH = KokkosTypes; @@ -101,7 +101,7 @@ struct UnitWrap::UnitTest::TestIceRelaxationTimescale { } } - static void run_ice_relaxation_timescale_phys() + void run_ice_relaxation_timescale_phys() { // TODO } @@ -115,10 +115,11 @@ namespace { TEST_CASE("p3_ice_relaxation_timescale", "[p3_functions]") { - using TD = scream::p3::unit_test::UnitWrap::UnitTest::TestIceRelaxationTimescale; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestIceRelaxationTimescale; - TD::run_ice_relaxation_timescale_phys(); - TD::run_ice_relaxation_timescale_bfb(); + T t; + t.run_ice_relaxation_timescale_phys(); + t.run_ice_relaxation_timescale_bfb(); } } diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp index c04aa55be00a..86ff76e91690 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp @@ -19,31 +19,31 @@ namespace p3 { namespace unit_test { template -struct UnitWrap::UnitTest::TestIceSed { +struct UnitWrap::UnitTest::TestIceSed : public UnitWrap::UnitTest::Base { -static void run_phys_calc_bulk_rhime() +void run_phys_calc_bulk_rhime() { // TODO } -static void run_phys_ice_sed() +void run_phys_ice_sed() { // TODO } -static void run_phys_homogeneous_freezing() +void run_phys_homogeneous_freezing() { // TODO } -static void run_phys() +void run_phys() { run_phys_calc_bulk_rhime(); run_phys_ice_sed(); run_phys_homogeneous_freezing(); } -static void run_bfb_calc_bulk_rhime() +void run_bfb_calc_bulk_rhime() { constexpr Scalar qsmall = C::QSMALL; @@ -123,7 +123,7 @@ static void run_bfb_calc_bulk_rhime() } } -static void run_bfb_ice_sed() +void run_bfb_ice_sed() { auto engine = setup_random_test(); @@ -187,7 +187,7 @@ static void run_bfb_ice_sed() } } -static void run_bfb_homogeneous_freezing() +void run_bfb_homogeneous_freezing() { constexpr Scalar latice = C::LatIce; @@ -256,7 +256,7 @@ static void run_bfb_homogeneous_freezing() } } -static void run_bfb() +void run_bfb() { run_bfb_calc_bulk_rhime(); run_bfb_ice_sed(); @@ -273,12 +273,11 @@ namespace { TEST_CASE("p3_ice_sed", "[p3_functions]") { - using TCS = scream::p3::unit_test::UnitWrap::UnitTest::TestIceSed; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestIceSed; - TCS::run_phys(); - TCS::run_bfb(); - - scream::p3::P3GlobalForFortran::deinit(); + T t; + t.run_phys(); + t.run_bfb(); } } // namespace diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp index 5873b8335c38..3c8121cdf3c5 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp @@ -14,9 +14,9 @@ namespace p3 { namespace unit_test { template -struct UnitWrap::UnitTest::TestIceSupersatConservation { +struct UnitWrap::UnitTest::TestIceSupersatConservation : public UnitWrap::UnitTest::Base { - static void run_bfb() + void run_bfb() { constexpr Scalar latvap = C::LatVap; constexpr Scalar latice = C::LatIce; @@ -98,9 +98,10 @@ namespace { TEST_CASE("ice_supersat_conservation_bfb", "[p3]") { - using TestStruct = scream::p3::unit_test::UnitWrap::UnitTest::TestIceSupersatConservation; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestIceSupersatConservation; - TestStruct::run_bfb(); + T t; + t.run_bfb(); } } // empty namespace diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_tables_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_tables_unit_tests.cpp index 091d05895fcc..0b171b0a7ff7 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_tables_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_tables_unit_tests.cpp @@ -22,9 +22,9 @@ namespace unit_test { */ template -struct UnitWrap::UnitTest::TestTableIce { +struct UnitWrap::UnitTest::TestTableIce : public UnitWrap::UnitTest::Base { - static void test_read_lookup_tables_bfb() + void test_read_lookup_tables_bfb() { // Read in ice tables view_ice_table ice_table_vals; @@ -62,7 +62,7 @@ struct UnitWrap::UnitTest::TestTableIce { } template - static void init_table_linear_dimension(View& table, int linear_dimension) + void init_table_linear_dimension(View& table, int linear_dimension) { // set up views using NonConstView = typename View::non_const_type; @@ -96,7 +96,7 @@ struct UnitWrap::UnitTest::TestTableIce { table = view_device; } - static void run_bfb() + void run_bfb() { using KTH = KokkosTypes; @@ -294,7 +294,7 @@ struct UnitWrap::UnitTest::TestTableIce { } } - static void run_phys() + void run_phys() { #if 0 view_ice_table ice_table_vals; @@ -343,11 +343,12 @@ namespace { TEST_CASE("p3_ice_tables", "[p3_functions]") { - using TTI = scream::p3::unit_test::UnitWrap::UnitTest::TestTableIce; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestTableIce; - TTI::test_read_lookup_tables_bfb(); - TTI::run_phys(); - TTI::run_bfb(); + T t; + t.test_read_lookup_tables_bfb(); + t.run_phys(); + t.run_bfb(); } } diff --git a/components/eamxx/src/physics/p3/tests/p3_incloud_mixingratios_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_incloud_mixingratios_unit_tests.cpp index 4a405fcc7c43..a75bdbd17285 100644 --- a/components/eamxx/src/physics/p3/tests/p3_incloud_mixingratios_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_incloud_mixingratios_unit_tests.cpp @@ -19,9 +19,9 @@ namespace p3 { namespace unit_test { template -struct UnitWrap::UnitTest::TestIncloudMixing { +struct UnitWrap::UnitTest::TestIncloudMixing : public UnitWrap::UnitTest::Base { - static void run_incloud_mixing_bfb() + void run_incloud_mixing_bfb() { using KTH = KokkosTypes; @@ -129,7 +129,7 @@ struct UnitWrap::UnitTest::TestIncloudMixing { } } - static void run_incloud_mixing_phys() + void run_incloud_mixing_phys() { // TODO } @@ -143,10 +143,11 @@ namespace { TEST_CASE("p3_incloud_mixingratios", "[p3_functions]") { - using TD = scream::p3::unit_test::UnitWrap::UnitTest::TestIncloudMixing; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestIncloudMixing; - TD::run_incloud_mixing_phys(); - TD::run_incloud_mixing_bfb(); + T t; + t.run_incloud_mixing_phys(); + t.run_incloud_mixing_bfb(); } } diff --git a/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp index a804bd8756d5..35089c0e7f9b 100644 --- a/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp @@ -19,29 +19,29 @@ namespace p3 { namespace unit_test { template -struct UnitWrap::UnitTest::TestP3Main { +struct UnitWrap::UnitTest::TestP3Main : public UnitWrap::UnitTest::Base { -static void run_phys_p3_main_part1() +void run_phys_p3_main_part1() { // TODO } -static void run_phys_p3_main_part2() +void run_phys_p3_main_part2() { // TODO } -static void run_phys_p3_main_part3() +void run_phys_p3_main_part3() { // TODO } -static void run_phys_p3_main() +void run_phys_p3_main() { // TODO } -static void run_phys() +void run_phys() { run_phys_p3_main_part1(); run_phys_p3_main_part2(); @@ -49,7 +49,7 @@ static void run_phys() run_phys_p3_main(); } -static void run_bfb_p3_main_part1() +void run_bfb_p3_main_part1() { auto engine = setup_random_test(); @@ -150,7 +150,7 @@ static void run_bfb_p3_main_part1() } } -static void run_bfb_p3_main_part2() +void run_bfb_p3_main_part2() { auto engine = setup_random_test(); @@ -274,7 +274,7 @@ static void run_bfb_p3_main_part2() } } -static void run_bfb_p3_main_part3() +void run_bfb_p3_main_part3() { constexpr Scalar latvap = C::LatVap; constexpr Scalar latice = C::LatIce; @@ -369,7 +369,7 @@ static void run_bfb_p3_main_part3() } } -static void run_bfb_p3_main() +void run_bfb_p3_main() { auto engine = setup_random_test(); @@ -476,7 +476,7 @@ static void run_bfb_p3_main() } } -static void run_bfb() +void run_bfb() { run_bfb_p3_main_part1(); run_bfb_p3_main_part2(); @@ -494,12 +494,11 @@ namespace { TEST_CASE("p3_main", "[p3_functions]") { - using TP3 = scream::p3::unit_test::UnitWrap::UnitTest::TestP3Main; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestP3Main; - TP3::run_phys(); - TP3::run_bfb(); - - scream::p3::P3GlobalForFortran::deinit(); + T t; + t.run_phys(); + t.run_bfb(); } } // namespace diff --git a/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp index ffe7ea504e13..ecf47b99eaa7 100644 --- a/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp @@ -14,9 +14,9 @@ namespace p3 { namespace unit_test { template -struct UnitWrap::UnitTest::TestNcConservation { +struct UnitWrap::UnitTest::TestNcConservation : public UnitWrap::UnitTest::Base { - static void run_bfb() + void run_bfb() { auto engine = setup_random_test(); @@ -93,9 +93,10 @@ namespace { TEST_CASE("nc_conservation_bfb", "[p3]") { - using TestStruct = scream::p3::unit_test::UnitWrap::UnitTest::TestNcConservation; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestNcConservation; - TestStruct::run_bfb(); + T t; + t.run_bfb(); } } // empty namespace diff --git a/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp index 3aa3428825cd..41c13afd9235 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp @@ -14,9 +14,9 @@ namespace p3 { namespace unit_test { template -struct UnitWrap::UnitTest::TestNiConservation { +struct UnitWrap::UnitTest::TestNiConservation : public UnitWrap::UnitTest::Base { - static void run_bfb() + void run_bfb() { auto engine = setup_random_test(); @@ -92,9 +92,10 @@ namespace { TEST_CASE("ni_conservation_bfb", "[p3]") { - using TestStruct = scream::p3::unit_test::UnitWrap::UnitTest::TestNiConservation; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestNiConservation; - TestStruct::run_bfb(); + T t; + t.run_bfb(); } } // empty namespace diff --git a/components/eamxx/src/physics/p3/tests/p3_nr_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_nr_conservation_tests.cpp index fb9e1e758b42..2df8a01dbb33 100644 --- a/components/eamxx/src/physics/p3/tests/p3_nr_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_nr_conservation_tests.cpp @@ -14,9 +14,9 @@ namespace p3 { namespace unit_test { template -struct UnitWrap::UnitTest::TestNrConservation { +struct UnitWrap::UnitTest::TestNrConservation : public UnitWrap::UnitTest::Base { - static void run_bfb() + void run_bfb() { auto engine = setup_random_test(); @@ -97,9 +97,10 @@ namespace { TEST_CASE("nr_conservation_bfb", "[p3]") { - using TestStruct = scream::p3::unit_test::UnitWrap::UnitTest::TestNrConservation; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestNrConservation; - TestStruct::run_bfb(); + T t; + t.run_bfb(); } } // empty namespace diff --git a/components/eamxx/src/physics/p3/tests/p3_prevent_liq_supersaturation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_prevent_liq_supersaturation_tests.cpp index a1b270562819..2b845e9c97b7 100644 --- a/components/eamxx/src/physics/p3/tests/p3_prevent_liq_supersaturation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_prevent_liq_supersaturation_tests.cpp @@ -15,9 +15,9 @@ namespace p3 { namespace unit_test { template -struct UnitWrap::UnitTest::TestPreventLiqSupersaturation { +struct UnitWrap::UnitTest::TestPreventLiqSupersaturation : public UnitWrap::UnitTest::Base { - static void run_property() + void run_property() //Conceptual tests for prevent_liq_supersaturation. Note many conceptual tests make sense to run on //random data, so are included in run_bfb rather than here. { @@ -88,7 +88,7 @@ struct UnitWrap::UnitTest::TestPreventLiqSupersaturation { } //end run_property - static void run_bfb() + void run_bfb() { constexpr Scalar latvap = C::LatVap; constexpr Scalar latice = C::LatIce; @@ -187,14 +187,18 @@ namespace { TEST_CASE("prevent_liq_supersaturation_property", "[p3]") { - using TestStruct = scream::p3::unit_test::UnitWrap::UnitTest::TestPreventLiqSupersaturation; - TestStruct::run_property(); + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestPreventLiqSupersaturation; + + T t; + t.run_property(); } TEST_CASE("prevent_liq_supersaturation_bfb", "[p3]") { - using TestStruct = scream::p3::unit_test::UnitWrap::UnitTest::TestPreventLiqSupersaturation; - TestStruct::run_bfb(); + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestPreventLiqSupersaturation; + + T t; + t.run_bfb(); } } // empty namespace diff --git a/components/eamxx/src/physics/p3/tests/p3_rain_imm_freezing_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_rain_imm_freezing_unit_tests.cpp index ae142ae77ace..e19b83d6c2a7 100644 --- a/components/eamxx/src/physics/p3/tests/p3_rain_imm_freezing_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_rain_imm_freezing_unit_tests.cpp @@ -18,14 +18,14 @@ namespace p3 { namespace unit_test { template -struct UnitWrap::UnitTest::TestRainImmersionFreezing { +struct UnitWrap::UnitTest::TestRainImmersionFreezing : public UnitWrap::UnitTest::Base { -static void run_phys() +void run_phys() { // TODO } -static void run_bfb() +void run_bfb() { // This is the threshold for whether the qc and qr cloud mixing ratios are // large enough to affect the warm-phase process rates qc2qr_accret_tend and nc_accret_tend. @@ -124,12 +124,11 @@ namespace { TEST_CASE("p3_rain_immersion_freezing", "[p3_functions]") { - using TRIF = scream::p3::unit_test::UnitWrap::UnitTest::TestRainImmersionFreezing; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestRainImmersionFreezing; - TRIF::run_phys(); - TRIF::run_bfb(); - - scream::p3::P3GlobalForFortran::deinit(); + T t; + t.run_phys(); + t.run_bfb(); } } // namespace diff --git a/components/eamxx/src/physics/p3/tests/p3_rain_sed_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_rain_sed_unit_tests.cpp index 2d6cd8d0a00e..8184d5df0f34 100644 --- a/components/eamxx/src/physics/p3/tests/p3_rain_sed_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_rain_sed_unit_tests.cpp @@ -22,23 +22,23 @@ namespace unit_test { template struct UnitWrap::UnitTest::TestRainSed : public UnitWrap::UnitTest::Base { -static void run_phys_rain_vel() +void run_phys_rain_vel() { // TODO } -static void run_phys_rain_sed() +void run_phys_rain_sed() { // TODO } -static void run_phys() +void run_phys() { run_phys_rain_vel(); run_phys_rain_sed(); } -static void run_bfb_rain_vel() +void run_bfb_rain_vel() { // Read in tables view_2d_table vn_table_vals; view_2d_table vm_table_vals; view_2d_table revap_table_vals; @@ -124,7 +124,7 @@ static void run_bfb_rain_vel() } } -static void run_bfb_rain_sed() +void run_bfb_rain_sed() { auto engine = setup_random_test(); @@ -201,7 +201,7 @@ static void run_bfb_rain_sed() } } -static void run_bfb() +void run_bfb() { run_bfb_rain_vel(); run_bfb_rain_sed(); @@ -217,14 +217,11 @@ namespace { TEST_CASE("p3_rain_sed", "[p3_functions]") { - using TRS = scream::p3::unit_test::UnitWrap::UnitTest::TestRainSed; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestRainSed; - TRS::init(); - - TRS::run_phys(); - TRS::run_bfb(); - - scream::p3::P3GlobalForFortran::deinit(); + T t; + t.run_phys(); + t.run_bfb(); } } // namespace diff --git a/components/eamxx/src/physics/p3/tests/p3_rain_self_collection_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_rain_self_collection_tests.cpp index a8c0dbc07dd1..7bcdf59dac8a 100644 --- a/components/eamxx/src/physics/p3/tests/p3_rain_self_collection_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_rain_self_collection_tests.cpp @@ -22,9 +22,9 @@ namespace unit_test { * Unit-tests for p3 ice collection functions. */ template -struct UnitWrap::UnitTest::TestRainSelfCollection { +struct UnitWrap::UnitTest::TestRainSelfCollection : public UnitWrap::UnitTest::Base { - static void run_rain_self_collection_bfb_tests(){ + void run_rain_self_collection_bfb_tests() { RainSelfCollectionData dc[max_pack_size] = { // rho, qr_incld, nr_incld, nr_selfcollect_tend @@ -101,7 +101,7 @@ struct UnitWrap::UnitTest::TestRainSelfCollection { } } - static void run_bfb(){ + void run_bfb() { run_rain_self_collection_bfb_tests(); } @@ -114,7 +114,10 @@ struct UnitWrap::UnitTest::TestRainSelfCollection { namespace { TEST_CASE("p3_rain_self_collection_test", "[p3_rain_self_collection_test"){ - scream::p3::unit_test::UnitWrap::UnitTest::TestRainSelfCollection::run_bfb(); + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestRainSelfCollection; + + T t; + t.run_bfb(); } } // namespace diff --git a/components/eamxx/src/physics/p3/tests/p3_subgrid_variance_scaling_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_subgrid_variance_scaling_unit_tests.cpp index 9a728b6c57e6..9e75889df0c5 100644 --- a/components/eamxx/src/physics/p3/tests/p3_subgrid_variance_scaling_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_subgrid_variance_scaling_unit_tests.cpp @@ -19,11 +19,11 @@ namespace p3 { namespace unit_test { template -struct UnitWrap::UnitTest::TestP3SubgridVarianceScaling +struct UnitWrap::UnitTest::TestP3SubgridVarianceScaling : public UnitWrap::UnitTest::Base { //----------------------------------------------------------------- - static void run_bfb_tests(){ + void run_bfb_tests() { //test that C++ and F90 implementations are BFB //Set of relvar values to loop over @@ -81,7 +81,7 @@ struct UnitWrap::UnitTest::TestP3SubgridVarianceScaling //----------------------------------------------------------------- KOKKOS_FUNCTION static void subgrid_variance_scaling_linearity_test(const Scalar& relvar, - int& errors){ + int& errors) { //If expon=1, subgrid_variance_scaling should be 1 Scalar tol = C::macheps * 1e3; //1e3 is scale factor to make pass, essentially an estimate of numerical error @@ -97,7 +97,7 @@ struct UnitWrap::UnitTest::TestP3SubgridVarianceScaling } //----------------------------------------------------------------- - KOKKOS_FUNCTION static void subgrid_variance_scaling_relvar1_test(int& errors){ + KOKKOS_FUNCTION static void subgrid_variance_scaling_relvar1_test(int& errors) { //If relvar=1, subgrid_variance_scaling should be factorial(expon) Scalar tol = C::macheps * 1e3; //1e3 is scale factor to make pass, essentially an estimate of numerical error @@ -116,7 +116,7 @@ struct UnitWrap::UnitTest::TestP3SubgridVarianceScaling } //----------------------------------------------------------------- - KOKKOS_FUNCTION static void subgrid_variance_scaling_relvar3_test(int& errors){ + KOKKOS_FUNCTION static void subgrid_variance_scaling_relvar3_test(int& errors) { //If expon=3, subgrid variance scaling should be relvar^3+3*relvar^2+2*relvar/relvar^3 Scalar tol = C::macheps * 100; //100 is a fudge factor to make sure tests pass. 10 was too small for gnu on CPU. @@ -151,7 +151,7 @@ struct UnitWrap::UnitTest::TestP3SubgridVarianceScaling } //end relvar3_test //----------------------------------------------------------------- - static void run_property_tests(){ + void run_property_tests() { /*This function executes all the SGS variance scaling tests by looping *over a bunch of test and summing their return statuses. *If that sum is zero, no errors have occurred. Otherwise you have errors. @@ -189,12 +189,14 @@ struct UnitWrap::UnitTest::TestP3SubgridVarianceScaling } // namespace p3 } // namespace scream -namespace{ +namespace { TEST_CASE("p3_subgrid_variance_scaling_test", "[p3_subgrid_variance_scaling_test]"){ - scream::p3::unit_test::UnitWrap::UnitTest::TestP3SubgridVarianceScaling::run_bfb_tests(); - scream::p3::unit_test::UnitWrap::UnitTest::TestP3SubgridVarianceScaling::run_property_tests(); + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestP3SubgridVarianceScaling; + + T t; + t.run_bfb_tests(); + t.run_property_tests(); } } // namespace - diff --git a/components/eamxx/src/physics/p3/tests/p3_table3_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_table3_unit_tests.cpp index c99d156004e7..cc14bfc46d2e 100644 --- a/components/eamxx/src/physics/p3/tests/p3_table3_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_table3_unit_tests.cpp @@ -44,7 +44,7 @@ namespace unit_test { // refinement, where the mesh is a 1D mesh transecting the table domain. template -struct UnitWrap::UnitTest::TestTable3 { +struct UnitWrap::UnitTest::TestTable3 : public UnitWrap::UnitTest::Base { KOKKOS_FUNCTION static Scalar calc_lamr (const Scalar& mu_r, const Scalar& alpha) { // Parameters for lower and upper bounds, derived above, multiplied by @@ -68,7 +68,7 @@ struct UnitWrap::UnitTest::TestTable3 { return Functions::apply_table(table, t3); } - static void run () { + void run () { // This test doesn't use mu_r_table_vals, as that is not a table3 type. It // doesn't matter whether we use vm_table_vals or vn_table_vals, as the table values // don't matter in what we are testing; we are testing interpolation @@ -170,9 +170,10 @@ namespace { TEST_CASE("p3_tables", "[p3_functions]") { - scream::p3::p3_init(); // need fortran table data + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestTable3; - scream::p3::unit_test::UnitWrap::UnitTest::TestTable3::run(); + T t; + t.run(); } } // namespace diff --git a/components/eamxx/src/physics/p3/tests/p3_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_unit_tests.cpp index 3b994cfdad5d..2a33cc70db19 100644 --- a/components/eamxx/src/physics/p3/tests/p3_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_unit_tests.cpp @@ -21,10 +21,10 @@ namespace unit_test { * Unit-tests for p3_functions. */ template -struct UnitWrap::UnitTest::TestP3Conservation +struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest::Base { - static void cloud_water_conservation_tests_device() { + void cloud_water_conservation_tests_device() { using KTH = KokkosTypes; @@ -78,7 +78,7 @@ struct UnitWrap::UnitTest::TestP3Conservation REQUIRE(cwdc_host[0].qc2qr_autoconv_tend * cwdc[0].dt <= cwdc_host[0].qc); } - static void rain_water_conservation_tests_device() { + void rain_water_conservation_tests_device() { using KTH = KokkosTypes; RainWaterConservationData rwdc[1] = {{sp(1e-5), 0.0, 0.0, 0.0, 0.0, sp(1.1), sp(1e-4), 0.0, 0.0 }}; @@ -131,7 +131,7 @@ struct UnitWrap::UnitTest::TestP3Conservation REQUIRE( rwdc_host(0).qr2qv_evap_tend * rwdc_host(0).dt <= rwdc_host(0).qr); } - static void ice_water_conservation_tests_device(){ + void ice_water_conservation_tests_device() { using KTH = KokkosTypes; IceWaterConservationData iwdc[1] = {{sp(1e-5), 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, sp(1.1), sp(1e-4), 0.0}}; @@ -173,7 +173,7 @@ struct UnitWrap::UnitTest::TestP3Conservation } - static void run() + void run() { cloud_water_conservation_tests_device(); @@ -182,7 +182,7 @@ struct UnitWrap::UnitTest::TestP3Conservation ice_water_conservation_tests_device(); } - static void cloud_water_conservation_unit_bfb_tests(){ + void cloud_water_conservation_unit_bfb_tests() { using KTH = KokkosTypes; @@ -277,7 +277,7 @@ struct UnitWrap::UnitTest::TestP3Conservation } } - static void ice_water_conservation_unit_bfb_tests() + void ice_water_conservation_unit_bfb_tests() { using KTH = KokkosTypes; @@ -372,7 +372,7 @@ struct UnitWrap::UnitTest::TestP3Conservation } } - static void rain_water_conservation_unit_bfb_tests(){ + void rain_water_conservation_unit_bfb_tests() { using KTH = KokkosTypes; @@ -462,7 +462,7 @@ struct UnitWrap::UnitTest::TestP3Conservation } } - static void run_bfb() { + void run_bfb() { cloud_water_conservation_unit_bfb_tests(); rain_water_conservation_unit_bfb_tests(); @@ -473,9 +473,9 @@ struct UnitWrap::UnitTest::TestP3Conservation }; template -struct UnitWrap::UnitTest::TestP3UpdatePrognosticIce +struct UnitWrap::UnitTest::TestP3UpdatePrognosticIce : public UnitWrap::UnitTest::Base { - static void update_prognostic_ice_unit_bfb_tests() { + void update_prognostic_ice_unit_bfb_tests() { constexpr Scalar nmltratio = C::nmltratio; constexpr Scalar dt = 1.8000E+03; @@ -695,16 +695,16 @@ struct UnitWrap::UnitTest::TestP3UpdatePrognosticIce } } - static void run_bfb(){ + void run_bfb() { update_prognostic_ice_unit_bfb_tests(); } }; //TestP3UpdatePrognosticIce template -struct UnitWrap::UnitTest::TestGetTimeSpacePhysVariables +struct UnitWrap::UnitTest::TestGetTimeSpacePhysVariables : public UnitWrap::UnitTest::Base { - static void get_time_space_phys_variables_unit_bfb_tests(){ + void get_time_space_phys_variables_unit_bfb_tests() { constexpr Scalar latvap = C::LatVap; constexpr Scalar latice = C::LatIce; @@ -809,15 +809,15 @@ struct UnitWrap::UnitTest::TestGetTimeSpacePhysVariables } } - static void run_bfb(){ + void run_bfb() { get_time_space_phys_variables_unit_bfb_tests(); } }; //TestGetTimeSpacePhysVariables template -struct UnitWrap::UnitTest::TestP3UpdatePrognosticLiq +struct UnitWrap::UnitTest::TestP3UpdatePrognosticLiq : public UnitWrap::UnitTest::Base { - static void update_prognostic_liquid_unit_bfb_tests(){ + void update_prognostic_liquid_unit_bfb_tests() { constexpr Scalar latvap = C::LatVap; //fortran generated data is input to the following @@ -983,16 +983,16 @@ struct UnitWrap::UnitTest::TestP3UpdatePrognosticLiq } } - static void run_bfb(){ + void run_bfb() { update_prognostic_liquid_unit_bfb_tests(); } }; //TestP3UpdatePrognosticLiq template -struct UnitWrap::UnitTest::TestP3FunctionsImposeMaxTotalNi +struct UnitWrap::UnitTest::TestP3FunctionsImposeMaxTotalNi : public UnitWrap::UnitTest::Base { - static void impose_max_total_ni_bfb_test(){ + void impose_max_total_ni_bfb_test() { constexpr Scalar max_total_ni = 740.0e3; ImposeMaxTotalNiData dc[max_pack_size]= { @@ -1062,7 +1062,7 @@ struct UnitWrap::UnitTest::TestP3FunctionsImposeMaxTotalNi } } - static void run_bfb(){ + void run_bfb() { impose_max_total_ni_bfb_test(); } @@ -1075,24 +1075,39 @@ struct UnitWrap::UnitTest::TestP3FunctionsImposeMaxTotalNi namespace { TEST_CASE("p3_conservation_test", "[p3_unit_tests]"){ - scream::p3::unit_test::UnitWrap::UnitTest::TestP3Conservation::run(); - scream::p3::unit_test::UnitWrap::UnitTest::TestP3Conservation::run_bfb(); + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestP3Conservation; + + T t; + t.run(); + t.run_bfb(); } TEST_CASE("p3_get_time_space_phys_variables_test", "[p3_unit_tests]"){ - scream::p3::unit_test::UnitWrap::UnitTest::TestGetTimeSpacePhysVariables::run_bfb(); + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestGetTimeSpacePhysVariables; + + T t; + t.run_bfb(); } TEST_CASE("p3_update_prognostic_ice_test", "[p3_unit_tests]"){ - scream::p3::unit_test::UnitWrap::UnitTest::TestP3UpdatePrognosticIce::run_bfb(); + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestP3UpdatePrognosticIce; + + T t; + t.run_bfb(); } TEST_CASE("p3_update_prognostic_liquid_test", "[p3_unit_tests]"){ - scream::p3::unit_test::UnitWrap::UnitTest::TestP3UpdatePrognosticLiq::run_bfb(); + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestP3UpdatePrognosticLiq; + + T t; + t.run_bfb(); } TEST_CASE("p3_impose_max_total_ni_test", "[p3_unit_tests]"){ - scream::p3::unit_test::UnitWrap::UnitTest::TestP3FunctionsImposeMaxTotalNi::run_bfb(); + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestP3FunctionsImposeMaxTotalNi; + + T t; + t.run_bfb(); } } // namespace diff --git a/components/eamxx/src/physics/p3/tests/p3_unit_tests_common.hpp b/components/eamxx/src/physics/p3/tests/p3_unit_tests_common.hpp index 611173af2c13..685284a0463a 100644 --- a/components/eamxx/src/physics/p3/tests/p3_unit_tests_common.hpp +++ b/components/eamxx/src/physics/p3/tests/p3_unit_tests_common.hpp @@ -5,6 +5,7 @@ #include "p3_functions.hpp" #include "p3_f90.hpp" #include "ekat/util/ekat_test_utils.hpp" +#include "p3_functions_f90.hpp" #include #include @@ -70,40 +71,45 @@ struct UnitWrap { static constexpr Int num_test_itrs = max_pack_size / Spack::n; struct Base { - static inline std::string BASELINE_PATH; - static inline BASELINE_ACTION ACTION; + std::string m_baseline_path; + BASELINE_ACTION m_baseline_action; - static void init() + Base() : + m_baseline_path(""), + m_baseline_action(NONE) { scream::p3::p3_init(); // many tests will need fortran table data auto& ts = ekat::TestSession::get(); auto raw_flags = ts.flags.begin()->first; std::stringstream ss(raw_flags); std::string flag; - ACTION = NONE; - BASELINE_PATH = ""; bool next_token_is_path = false; while (ss >> flag) { if (flag == "-c") { - ACTION = COMPARE; + m_baseline_action = COMPARE; } else if (flag == "-g") { - ACTION = GENERATE; + m_baseline_action = GENERATE; } else if (flag == "-n") { - ACTION = NONE; + m_baseline_action = NONE; } else if (flag == "-b") { next_token_is_path = true; } else if (next_token_is_path) { - BASELINE_PATH = flag; + m_baseline_path = flag; next_token_is_path = false; } } - EKAT_REQUIRE_MSG( !(ACTION != NONE && BASELINE_PATH == ""), + EKAT_REQUIRE_MSG( !(m_baseline_action != NONE && m_baseline_path == ""), "P3 unit test flags problem: baseline actions were requested but no baseline path was provided"); } + + ~Base() + { + scream::p3::P3GlobalForFortran::deinit(); + } }; // Put struct decls here diff --git a/components/eamxx/src/physics/p3/tests/p3_upwind_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_upwind_unit_tests.cpp index fde2ca644cbf..b24a0ebb4a29 100644 --- a/components/eamxx/src/physics/p3/tests/p3_upwind_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_upwind_unit_tests.cpp @@ -36,9 +36,9 @@ namespace unit_test { // cells in the domain are 0. This lets us check the restricted-domain usage of // the upwind routine in the first time step. template -struct UnitWrap::UnitTest::TestUpwind { +struct UnitWrap::UnitTest::TestUpwind : public UnitWrap::UnitTest::Base { -static void run_phys() +void run_phys() { using ekat::repack; constexpr auto SPS = SCREAM_SMALL_PACK_SIZE; @@ -201,7 +201,7 @@ static void run_phys() } } -static void run_bfb() +void run_bfb() { auto engine = setup_random_test(); @@ -274,14 +274,14 @@ static void run_bfb() }; template -struct UnitWrap::UnitTest::TestGenSed { +struct UnitWrap::UnitTest::TestGenSed : public UnitWrap::UnitTest::Base { -static void run_phys() +void run_phys() { // TODO } -static void run_bfb() +void run_bfb() { auto engine = setup_random_test(); @@ -358,18 +358,20 @@ namespace { TEST_CASE("p3_upwind", "[p3_functions]") { - using TU = scream::p3::unit_test::UnitWrap::UnitTest::TestUpwind; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestUpwind; - TU::run_phys(); - TU::run_bfb(); + T t; + t.run_phys(); + t.run_bfb(); } TEST_CASE("p3_gen_sed", "[p3_functions]") { - using TG = scream::p3::unit_test::UnitWrap::UnitTest::TestGenSed; + using T = scream::p3::unit_test::UnitWrap::UnitTest::TestGenSed; - TG::run_phys(); - TG::run_bfb(); + T t; + t.run_phys(); + t.run_bfb(); } } // namespace From 4d404f9b0eeb07850a75068dbafef3b347e38bde Mon Sep 17 00:00:00 2001 From: James Foucar Date: Thu, 31 Oct 2024 16:15:23 -0600 Subject: [PATCH 014/147] rain_sed working --- .../eamxx/src/physics/p3/p3_functions_f90.hpp | 14 +++++ .../p3/tests/p3_rain_sed_unit_tests.cpp | 59 +++++++++++++------ .../src/physics/share/physics_test_data.cpp | 15 +++++ .../src/physics/share/physics_test_data.hpp | 39 +++++++++++- 4 files changed, 107 insertions(+), 20 deletions(-) diff --git a/components/eamxx/src/physics/p3/p3_functions_f90.hpp b/components/eamxx/src/physics/p3/p3_functions_f90.hpp index 89e6ac569085..364a068a4239 100644 --- a/components/eamxx/src/physics/p3/p3_functions_f90.hpp +++ b/components/eamxx/src/physics/p3/p3_functions_f90.hpp @@ -4,6 +4,7 @@ #include "physics/p3/p3_functions.hpp" #include "physics/share/physics_test_data.hpp" #include "share/scream_types.hpp" +#include "ekat/util/ekat_file_utils.hpp" #include #include @@ -471,6 +472,19 @@ struct ComputeRainFallVelocityData // Outputs Real mu_r, lamr, V_qr, V_nr; + + PTD_RW_SCALARS(5, nr_incld, mu_r, lamr, V_qr, V_nr); + + void read(const ekat::FILEPtr& fid) + { + read_scalars(fid); + } + + void write(const ekat::FILEPtr& fid) const + { + write_scalars(fid); + } + }; /////////////////////////////////////////////////////////////////////////////// diff --git a/components/eamxx/src/physics/p3/tests/p3_rain_sed_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_rain_sed_unit_tests.cpp index 8184d5df0f34..22f0c50b41df 100644 --- a/components/eamxx/src/physics/p3/tests/p3_rain_sed_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_rain_sed_unit_tests.cpp @@ -46,7 +46,7 @@ void run_bfb_rain_vel() Functions::init_kokkos_tables(vn_table_vals, vm_table_vals, revap_table_vals, mu_r_table_vals, dnu); // Load some lookup inputs, need at least one per pack value - ComputeRainFallVelocityData crfv_fortran[max_pack_size] = { + ComputeRainFallVelocityData crfv_baseline[max_pack_size] = { // qr_incld, rhofacr, nr_incld {1.1030E-04, 1.3221E+00, 6.2964E+05}, {2.1437E-13, 1.0918E+00, 6.5337E+07}, @@ -70,16 +70,20 @@ void run_bfb_rain_vel() }; - // Sync to device, needs to happen before fortran calls so that + // Sync to device, needs to happen before reads so that // inout data is in original state view_1d crfv_device("crfv", max_pack_size); const auto crfv_host = Kokkos::create_mirror_view(crfv_device); - std::copy(&crfv_fortran[0], &crfv_fortran[0] + max_pack_size, crfv_host.data()); + std::copy(&crfv_baseline[0], &crfv_baseline[0] + max_pack_size, crfv_host.data()); Kokkos::deep_copy(crfv_device, crfv_host); - // Get data from fortran - for (Int i = 0; i < max_pack_size; ++i) { - compute_rain_fall_velocity(crfv_fortran[i]); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/rain_fall_velocity.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + crfv_baseline[i].read(fid); + } } // Calc bulk rime from a kernel and copy results back to host @@ -112,21 +116,28 @@ void run_bfb_rain_vel() // Sync back to host Kokkos::deep_copy(crfv_host, crfv_device); - // Validate results - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { + // Validate results for (Int s = 0; s < max_pack_size; ++s) { - REQUIRE(crfv_fortran[s].nr_incld == crfv_host(s).nr_incld); - REQUIRE(crfv_fortran[s].mu_r == crfv_host(s).mu_r); - REQUIRE(crfv_fortran[s].lamr == crfv_host(s).lamr); - REQUIRE(crfv_fortran[s].V_qr == crfv_host(s).V_qr); - REQUIRE(crfv_fortran[s].V_nr == crfv_host(s).V_nr); + REQUIRE(crfv_baseline[s].nr_incld == crfv_host(s).nr_incld); + REQUIRE(crfv_baseline[s].mu_r == crfv_host(s).mu_r); + REQUIRE(crfv_baseline[s].lamr == crfv_host(s).lamr); + REQUIRE(crfv_baseline[s].V_qr == crfv_host(s).V_qr); + REQUIRE(crfv_baseline[s].V_nr == crfv_host(s).V_nr); + } + } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + crfv_host(s).write(fid); } } } void run_bfb_rain_sed() { - auto engine = setup_random_test(); + // With stored baselines, we must use a fixed seed! + auto engine = setup_random_test(1267351); // F90 is quite slow on weaver, so we decrease dt to reduce // the number of steps in rain_sed. @@ -151,7 +162,7 @@ void run_bfb_rain_sed() d.randomize(engine, { {d.qr_incld, {C::QSMALL/2, C::QSMALL*2}} }); } - // Create copies of data for use by cxx. Needs to happen before fortran calls so that + // Create copies of data for use by cxx. Needs to happen before reads so that // inout data is in original state RainSedData rsds_cxx[num_runs] = { RainSedData(rsds_fortran[0]), @@ -160,9 +171,13 @@ void run_bfb_rain_sed() RainSedData(rsds_fortran[3]), }; - // Get data from fortran - for (auto& d : rsds_fortran) { - rain_sedimentation(d); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/rain_sed.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (auto& d : rsds_fortran) { + d.read(fid); + } } // Get data from cxx @@ -180,7 +195,7 @@ void run_bfb_rain_sed() d.qr_tend, d.nr_tend); } - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int i = 0; i < num_runs; ++i) { // Due to pack issues, we must restrict checks to the active k space Int start = std::min(rsds_fortran[i].kbot, rsds_fortran[i].ktop) - 1; // 0-based indx @@ -199,6 +214,12 @@ void run_bfb_rain_sed() REQUIRE(rsds_fortran[i].precip_liq_surf == rsds_cxx[i].precip_liq_surf); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int i = 0; i < num_runs; ++i) { + rsds_cxx[i].write(fid); + } + } } void run_bfb() diff --git a/components/eamxx/src/physics/share/physics_test_data.cpp b/components/eamxx/src/physics/share/physics_test_data.cpp index 4a13528e98b6..986a7c0800f7 100644 --- a/components/eamxx/src/physics/share/physics_test_data.cpp +++ b/components/eamxx/src/physics/share/physics_test_data.cpp @@ -26,4 +26,19 @@ PhysicsTestData& PhysicsTestData::assignment_impl(const PhysicsTestData& rhs) return *this; } +void PhysicsTestData::read(const ekat::FILEPtr& fid) +{ + m_reals.read(fid); + m_ints.read(fid); + m_bools.read(fid); +} + +void PhysicsTestData::write(const ekat::FILEPtr& fid) const +{ + m_reals.write(fid); + m_ints.write(fid); + m_bools.write(fid); +} + + } // namespace scream diff --git a/components/eamxx/src/physics/share/physics_test_data.hpp b/components/eamxx/src/physics/share/physics_test_data.hpp index 099480b44393..fca5ca04cc0f 100644 --- a/components/eamxx/src/physics/share/physics_test_data.hpp +++ b/components/eamxx/src/physics/share/physics_test_data.hpp @@ -5,6 +5,7 @@ #include "ekat/util/ekat_math_utils.hpp" #include "ekat/ekat_assert.hpp" +#include "ekat/util/ekat_file_utils.hpp" #include #include @@ -90,12 +91,34 @@ struct SHOCGridData : public PhysicsTestData { #define PTD_ASS19(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s ) PTD_ASS18(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r) ; s = rhs.s #define PTD_ASS20(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t ) PTD_ASS19(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s) ; t = rhs.t +#define PTD_RW0(action ) ((void) (0)) +#define PTD_RW1(action, a ) ekat::action(&a, 1, fid) +#define PTD_RW2(action, a, b ) PTD_RW1(action, a) ; ekat::action(&b, 1, fid) +#define PTD_RW3(action, a, b, c ) PTD_RW2(action, a, b) ; ekat::action(&c, 1, fid) +#define PTD_RW4(action, a, b, c, d ) PTD_RW3(action, a, b, c) ; ekat::action(&d, 1, fid) +#define PTD_RW5(action, a, b, c, d, e ) PTD_RW4(action, a, b, c, d) ; ekat::action(&e, 1, fid) +#define PTD_RW6(action, a, b, c, d, e, f ) PTD_RW5(action, a, b, c, d, e) ; ekat::action(&f, 1, fid) +#define PTD_RW7(action, a, b, c, d, e, f, g ) PTD_RW6(action, a, b, c, d, e, f) ; ekat::action(&g, 1, fid) +#define PTD_RW8(action, a, b, c, d, e, f, g, h ) PTD_RW7(action, a, b, c, d, e, f, g) ; ekat::action(&h, 1, fid) +#define PTD_RW9(action, a, b, c, d, e, f, g, h, i ) PTD_RW8(action, a, b, c, d, e, f, g, h) ; ekat::action(&i, 1, fid) +#define PTD_RW10(action, a, b, c, d, e, f, g, h, i, j ) PTD_RW9(action, a, b, c, d, e, f, g, h, i) ; ekat::action(&j, 1, fid) + #define PTD_ASSIGN_OP(name, num_scalars, ...) \ name& operator=(const name& rhs) { PTD_ASS##num_scalars(__VA_ARGS__); assignment_impl(rhs); return *this; } +#define PTD_RW_SCALARS(num_scalars, ...) \ + void read_scalars(const ekat::FILEPtr& fid) { PTD_RW##num_scalars(read, __VA_ARGS__); } \ + void write_scalars(const ekat::FILEPtr& fid) const { PTD_RW##num_scalars(write, __VA_ARGS__); } + +#define PTD_RW() \ + void read(const ekat::FILEPtr& fid) { read_scalars(fid); PhysicsTestData::read(fid); } \ + void write(const ekat::FILEPtr& fid) const { write_scalars(fid); PhysicsTestData::write(fid); } + #define PTD_STD_DEF(name, num_scalars, ...) \ PTD_DATA_COPY_CTOR(name, num_scalars); \ - PTD_ASSIGN_OP(name, num_scalars, __VA_ARGS__) + PTD_ASSIGN_OP(name, num_scalars, __VA_ARGS__) \ + PTD_RW() \ + PTD_RW_SCALARS(num_scalars, __VA_ARGS__) namespace scream { @@ -241,6 +264,16 @@ class PhysicsTestData m_data = new_data; } + void read(const ekat::FILEPtr& fid) + { + ekat::read(m_data.data(), m_data.size(), fid); + } + + void write(const ekat::FILEPtr& fid) const + { + ekat::write(m_data.data(), m_data.size(), fid); + } + std::vector > m_dims_list; // list of dims, one per unique set of dims std::vector > m_members_list; // list of member pointers, same outer index space as m_dims_list std::vector m_data; // the member data in a flat vector @@ -336,6 +369,10 @@ class PhysicsTestData } } + void read(const ekat::FILEPtr& fid); + + void write(const ekat::FILEPtr& fid) const; + protected: PhysicsTestData& assignment_impl(const PhysicsTestData& rhs); From f669e8beb2e9a88942bdb2cc7a1e59ea2f705a75 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Fri, 1 Nov 2024 11:35:20 -0600 Subject: [PATCH 015/147] Upwind working --- .../eamxx/src/physics/p3/p3_functions_f90.hpp | 2 + .../physics/p3/tests/p3_upwind_unit_tests.cpp | 102 +++++++++++------- .../src/physics/share/physics_test_data.cpp | 2 + .../src/physics/share/physics_test_data.hpp | 57 ++++++---- 4 files changed, 100 insertions(+), 63 deletions(-) diff --git a/components/eamxx/src/physics/p3/p3_functions_f90.hpp b/components/eamxx/src/physics/p3/p3_functions_f90.hpp index 364a068a4239..20207460c0a0 100644 --- a/components/eamxx/src/physics/p3/p3_functions_f90.hpp +++ b/components/eamxx/src/physics/p3/p3_functions_f90.hpp @@ -353,6 +353,8 @@ struct GenSedData : public CalcUpwindData PTD_DATA_COPY_CTOR(GenSedData, 10); PTD_ASSIGN_OP(GenSedData, 11, kts, kte, kdir, kbot, k_qxtop, num_arrays, dt_sub, Co_max, k_qxbot, dt_left, prt_accum); + PTD_RW(); + PTD_RW_SCALARS(11, kts, kte, kdir, kbot, k_qxtop, num_arrays, dt_sub, Co_max, k_qxbot, dt_left, prt_accum); }; /////////////////////////////////////////////////////////////////////////////// diff --git a/components/eamxx/src/physics/p3/tests/p3_upwind_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_upwind_unit_tests.cpp index b24a0ebb4a29..b6b5307966af 100644 --- a/components/eamxx/src/physics/p3/tests/p3_upwind_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_upwind_unit_tests.cpp @@ -203,9 +203,10 @@ void run_phys() void run_bfb() { - auto engine = setup_random_test(); + // With stored baselines, we must use a fixed seed! + auto engine = setup_random_test(12345745); - CalcUpwindData cuds_fortran[] = { + CalcUpwindData cuds_baseline[] = { // kts, kte, kdir, kbot, k_qxtop, na, dt_sub, CalcUpwindData( 1, 72, -1, 72, 36, 2, 1.833E+03), CalcUpwindData( 1, 72, 1, 36, 72, 2, 1.833E+03), @@ -216,28 +217,32 @@ void run_bfb() CalcUpwindData( 1, 32, -1, 21, 7, 1, 1.833E+03), }; - static constexpr Int num_runs = sizeof(cuds_fortran) / sizeof(CalcUpwindData); + static constexpr Int num_runs = sizeof(cuds_baseline) / sizeof(CalcUpwindData); // Set up random input data - for (auto& d : cuds_fortran) { + for (auto& d : cuds_baseline) { d.randomize(engine); } - // Create copies of data for use by cxx. Needs to happen before fortran calls so that + // Create copies of data for use by cxx. Needs to happen before reads so that // inout data is in original state CalcUpwindData cuds_cxx[num_runs] = { - CalcUpwindData(cuds_fortran[0]), - CalcUpwindData(cuds_fortran[1]), - CalcUpwindData(cuds_fortran[2]), - CalcUpwindData(cuds_fortran[3]), - CalcUpwindData(cuds_fortran[4]), - CalcUpwindData(cuds_fortran[5]), - CalcUpwindData(cuds_fortran[6]), + CalcUpwindData(cuds_baseline[0]), + CalcUpwindData(cuds_baseline[1]), + CalcUpwindData(cuds_baseline[2]), + CalcUpwindData(cuds_baseline[3]), + CalcUpwindData(cuds_baseline[4]), + CalcUpwindData(cuds_baseline[5]), + CalcUpwindData(cuds_baseline[6]), }; - // Get data from fortran - for (auto& d : cuds_fortran) { - calc_first_order_upwind_step(d); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/upwind.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (auto& d : cuds_baseline) { + d.read(fid); + } } // Get data from cxx @@ -251,17 +256,17 @@ void run_bfb() d.num_arrays, fluxes, vs, qnx); } - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int i = 0; i < num_runs; ++i) { // Due to pack issues, we must restrict checks to the active k space - Int start = std::min(cuds_fortran[i].kbot, cuds_fortran[i].k_qxtop) - 1; // 0-based indx - Int end = std::max(cuds_fortran[i].kbot, cuds_fortran[i].k_qxtop); // 0-based indx + Int start = std::min(cuds_baseline[i].kbot, cuds_baseline[i].k_qxtop) - 1; // 0-based indx + Int end = std::max(cuds_baseline[i].kbot, cuds_baseline[i].k_qxtop); // 0-based indx Real** fluxesf90, **vsf90, **qnxf90, **fluxescxx, **vscxx, **qnxcxx; - cuds_fortran[i].convert_to_ptr_arr(tmp1, fluxesf90, vsf90, qnxf90); + cuds_baseline[i].convert_to_ptr_arr(tmp1, fluxesf90, vsf90, qnxf90); cuds_cxx[i].convert_to_ptr_arr(tmp1, fluxescxx, vscxx, qnxcxx); - for (int n = 0; n < cuds_fortran[i].num_arrays; ++n) { + for (int n = 0; n < cuds_baseline[i].num_arrays; ++n) { for (Int k = start; k < end; ++k) { REQUIRE(fluxesf90[n][k] == fluxescxx[n][k]); REQUIRE(qnxf90[n][k] == qnxcxx[n][k]); @@ -269,6 +274,12 @@ void run_bfb() } } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int i = 0; i < num_runs; ++i) { + cuds_cxx[i].write(fid); + } + } } }; @@ -283,9 +294,10 @@ void run_phys() void run_bfb() { - auto engine = setup_random_test(); + // With stored baselines, we must use a fixed seed! + auto engine = setup_random_test(2346563); - GenSedData gsds_fortran[] = { + GenSedData gsds_baseline[] = { // kts, kte, kdir, k_qxtop, k_qxbot, kbot, Co_max, dt_left, prt_accum, num_arrays GenSedData(1, 72, -1, 36, 72, 72, 9.196E-02, 1.818E+01, 4.959E-05, 2), GenSedData(1, 72, -1, 36, 57, 72, 4.196E-01, 1.418E+02, 4.959E-06, 1), @@ -293,25 +305,29 @@ void run_bfb() GenSedData(1, 72, -1, 72, 72, 72, 4.196E-01, 1.418E+02, 4.959E-06, 1), }; - static constexpr Int num_runs = sizeof(gsds_fortran) / sizeof(GenSedData); + static constexpr Int num_runs = sizeof(gsds_baseline) / sizeof(GenSedData); // Set up random input data - for (auto& d : gsds_fortran) { + for (auto& d : gsds_baseline) { d.randomize(engine); } - // Create copies of data for use by cxx. Needs to happen before fortran calls so that + // Create copies of data for use by cxx. Needs to happen before reads so that // inout data is in original state GenSedData gsds_cxx[num_runs] = { - GenSedData(gsds_fortran[0]), - GenSedData(gsds_fortran[1]), - GenSedData(gsds_fortran[2]), - GenSedData(gsds_fortran[3]), + GenSedData(gsds_baseline[0]), + GenSedData(gsds_baseline[1]), + GenSedData(gsds_baseline[2]), + GenSedData(gsds_baseline[3]), }; - // Get data from fortran - for (auto& d : gsds_fortran) { - generalized_sedimentation(d); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/gen_sed.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (auto& d : gsds_baseline) { + d.read(fid); + } } // Get data from cxx @@ -325,25 +341,31 @@ void run_bfb() d.num_arrays, fluxes, vs, qnx); } - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int i = 0; i < num_runs; ++i) { // Due to pack issues, we must restrict checks to the active k space - Int start = std::min(gsds_fortran[i].k_qxbot, gsds_fortran[i].k_qxtop) - 1; // 0-based indx - Int end = std::max(gsds_fortran[i].k_qxbot, gsds_fortran[i].k_qxtop); // 0-based indx + Int start = std::min(gsds_baseline[i].k_qxbot, gsds_baseline[i].k_qxtop) - 1; // 0-based indx + Int end = std::max(gsds_baseline[i].k_qxbot, gsds_baseline[i].k_qxtop); // 0-based indx Real** fluxesf90, **vsf90, **qnxf90, **fluxescxx, **vscxx, **qnxcxx; - gsds_fortran[i].convert_to_ptr_arr(tmp1, fluxesf90, vsf90, qnxf90); + gsds_baseline[i].convert_to_ptr_arr(tmp1, fluxesf90, vsf90, qnxf90); gsds_cxx[i].convert_to_ptr_arr(tmp1, fluxescxx, vscxx, qnxcxx); - for (int n = 0; n < gsds_fortran[i].num_arrays; ++n) { + for (int n = 0; n < gsds_baseline[i].num_arrays; ++n) { for (Int k = start; k < end; ++k) { REQUIRE(fluxesf90[n][k] == fluxescxx[n][k]); REQUIRE(qnxf90[n][k] == qnxcxx[n][k]); } } - REQUIRE(gsds_fortran[i].k_qxbot == gsds_cxx[i].k_qxbot); - REQUIRE(gsds_fortran[i].dt_left == gsds_cxx[i].dt_left); - REQUIRE(gsds_fortran[i].prt_accum == gsds_cxx[i].prt_accum); + REQUIRE(gsds_baseline[i].k_qxbot == gsds_cxx[i].k_qxbot); + REQUIRE(gsds_baseline[i].dt_left == gsds_cxx[i].dt_left); + REQUIRE(gsds_baseline[i].prt_accum == gsds_cxx[i].prt_accum); + } + } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int i = 0; i < num_runs; ++i) { + gsds_cxx[i].write(fid); } } } diff --git a/components/eamxx/src/physics/share/physics_test_data.cpp b/components/eamxx/src/physics/share/physics_test_data.cpp index 986a7c0800f7..f6c6d733fd0e 100644 --- a/components/eamxx/src/physics/share/physics_test_data.cpp +++ b/components/eamxx/src/physics/share/physics_test_data.cpp @@ -28,6 +28,8 @@ PhysicsTestData& PhysicsTestData::assignment_impl(const PhysicsTestData& rhs) void PhysicsTestData::read(const ekat::FILEPtr& fid) { + EKAT_REQUIRE_MSG(fid, + "Tried to read from missing file. You may have forgotten to generate baselines for some BFB unit tests"); m_reals.read(fid); m_ints.read(fid); m_bools.read(fid); diff --git a/components/eamxx/src/physics/share/physics_test_data.hpp b/components/eamxx/src/physics/share/physics_test_data.hpp index fca5ca04cc0f..153ec7b9b286 100644 --- a/components/eamxx/src/physics/share/physics_test_data.hpp +++ b/components/eamxx/src/physics/share/physics_test_data.hpp @@ -69,17 +69,17 @@ struct SHOCGridData : public PhysicsTestData { #define PTD_DATA_COPY_CTOR(name, num_args) \ name(const name& rhs) : name(PTD_ONES(num_args)) { *this = rhs; } -#define PTD_ASS0( ) ((void) (0)) -#define PTD_ASS1(a ) a = rhs.a -#define PTD_ASS2(a, b ) PTD_ASS1(a) ; b = rhs.b -#define PTD_ASS3(a, b, c ) PTD_ASS2(a, b) ; c = rhs.c -#define PTD_ASS4(a, b, c, d ) PTD_ASS3(a, b, c) ; d = rhs.d -#define PTD_ASS5(a, b, c, d, e ) PTD_ASS4(a, b, c, d) ; e = rhs.e -#define PTD_ASS6(a, b, c, d, e, f ) PTD_ASS5(a, b, c, d, e) ; f = rhs.f -#define PTD_ASS7(a, b, c, d, e, f, g ) PTD_ASS6(a, b, c, d, e, f) ; g = rhs.g -#define PTD_ASS8(a, b, c, d, e, f, g, h ) PTD_ASS7(a, b, c, d, e, f, g) ; h = rhs.h -#define PTD_ASS9(a, b, c, d, e, f, g, h, i ) PTD_ASS8(a, b, c, d, e, f, g, h) ; i = rhs.i -#define PTD_ASS10(a, b, c, d, e, f, g, h, i, j ) PTD_ASS9(a, b, c, d, e, f, g, h, i) ; j = rhs.j +#define PTD_ASS0( ) ((void) (0)) +#define PTD_ASS1(a ) PTD_ASS0() ; a = rhs.a +#define PTD_ASS2(a, b ) PTD_ASS1(a) ; b = rhs.b +#define PTD_ASS3(a, b, c ) PTD_ASS2(a, b) ; c = rhs.c +#define PTD_ASS4(a, b, c, d ) PTD_ASS3(a, b, c) ; d = rhs.d +#define PTD_ASS5(a, b, c, d, e ) PTD_ASS4(a, b, c, d) ; e = rhs.e +#define PTD_ASS6(a, b, c, d, e, f ) PTD_ASS5(a, b, c, d, e) ; f = rhs.f +#define PTD_ASS7(a, b, c, d, e, f, g ) PTD_ASS6(a, b, c, d, e, f) ; g = rhs.g +#define PTD_ASS8(a, b, c, d, e, f, g, h ) PTD_ASS7(a, b, c, d, e, f, g) ; h = rhs.h +#define PTD_ASS9(a, b, c, d, e, f, g, h, i ) PTD_ASS8(a, b, c, d, e, f, g, h) ; i = rhs.i +#define PTD_ASS10(a, b, c, d, e, f, g, h, i, j ) PTD_ASS9(a, b, c, d, e, f, g, h, i) ; j = rhs.j #define PTD_ASS11(a, b, c, d, e, f, g, h, i, j, k ) PTD_ASS10(a, b, c, d, e, f, g, h, i, j) ; k = rhs.k #define PTD_ASS12(a, b, c, d, e, f, g, h, i, j, k, l ) PTD_ASS11(a, b, c, d, e, f, g, h, i, j, k) ; l = rhs.l #define PTD_ASS13(a, b, c, d, e, f, g, h, i, j, k, l, m ) PTD_ASS12(a, b, c, d, e, f, g, h, i, j, k, l) ; m = rhs.m @@ -91,23 +91,34 @@ struct SHOCGridData : public PhysicsTestData { #define PTD_ASS19(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s ) PTD_ASS18(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r) ; s = rhs.s #define PTD_ASS20(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t ) PTD_ASS19(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s) ; t = rhs.t -#define PTD_RW0(action ) ((void) (0)) -#define PTD_RW1(action, a ) ekat::action(&a, 1, fid) -#define PTD_RW2(action, a, b ) PTD_RW1(action, a) ; ekat::action(&b, 1, fid) -#define PTD_RW3(action, a, b, c ) PTD_RW2(action, a, b) ; ekat::action(&c, 1, fid) -#define PTD_RW4(action, a, b, c, d ) PTD_RW3(action, a, b, c) ; ekat::action(&d, 1, fid) -#define PTD_RW5(action, a, b, c, d, e ) PTD_RW4(action, a, b, c, d) ; ekat::action(&e, 1, fid) -#define PTD_RW6(action, a, b, c, d, e, f ) PTD_RW5(action, a, b, c, d, e) ; ekat::action(&f, 1, fid) -#define PTD_RW7(action, a, b, c, d, e, f, g ) PTD_RW6(action, a, b, c, d, e, f) ; ekat::action(&g, 1, fid) -#define PTD_RW8(action, a, b, c, d, e, f, g, h ) PTD_RW7(action, a, b, c, d, e, f, g) ; ekat::action(&h, 1, fid) -#define PTD_RW9(action, a, b, c, d, e, f, g, h, i ) PTD_RW8(action, a, b, c, d, e, f, g, h) ; ekat::action(&i, 1, fid) -#define PTD_RW10(action, a, b, c, d, e, f, g, h, i, j ) PTD_RW9(action, a, b, c, d, e, f, g, h, i) ; ekat::action(&j, 1, fid) + +#define PTD_RW0(action ) ((void) (0)) +#define PTD_RW1(action, a ) PTD_RW0(action) ; ekat::action(&a, 1, fid) +#define PTD_RW2(action, a, b ) PTD_RW1(action, a) ; ekat::action(&b, 1, fid) +#define PTD_RW3(action, a, b, c ) PTD_RW2(action, a, b) ; ekat::action(&c, 1, fid) +#define PTD_RW4(action, a, b, c, d ) PTD_RW3(action, a, b, c) ; ekat::action(&d, 1, fid) +#define PTD_RW5(action, a, b, c, d, e ) PTD_RW4(action, a, b, c, d) ; ekat::action(&e, 1, fid) +#define PTD_RW6(action, a, b, c, d, e, f ) PTD_RW5(action, a, b, c, d, e) ; ekat::action(&f, 1, fid) +#define PTD_RW7(action, a, b, c, d, e, f, g ) PTD_RW6(action, a, b, c, d, e, f) ; ekat::action(&g, 1, fid) +#define PTD_RW8(action, a, b, c, d, e, f, g, h ) PTD_RW7(action, a, b, c, d, e, f, g) ; ekat::action(&h, 1, fid) +#define PTD_RW9(action, a, b, c, d, e, f, g, h, i ) PTD_RW8(action, a, b, c, d, e, f, g, h) ; ekat::action(&i, 1, fid) +#define PTD_RW10(action, a, b, c, d, e, f, g, h, i, j ) PTD_RW9(action, a, b, c, d, e, f, g, h, i) ; ekat::action(&j, 1, fid) +#define PTD_RW11(action, a, b, c, d, e, f, g, h, i, j, k ) PTD_RW10(action, a, b, c, d, e, f, g, h, i, j) ; ekat::action(&k, 1, fid) +#define PTD_RW12(action, a, b, c, d, e, f, g, h, i, j, k, l ) PTD_RW11(action, a, b, c, d, e, f, g, h, i, j, k) ; ekat::action(&l, 1, fid) +#define PTD_RW13(action, a, b, c, d, e, f, g, h, i, j, k, l, m ) PTD_RW12(action, a, b, c, d, e, f, g, h, i, j, k, l) ; ekat::action(&m, 1, fid) +#define PTD_RW14(action, a, b, c, d, e, f, g, h, i, j, k, l, m, n ) PTD_RW13(action, a, b, c, d, e, f, g, h, i, j, k, l, m) ; ekat::action(&n, 1, fid) +#define PTD_RW15(action, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o ) PTD_RW14(action, a, b, c, d, e, f, g, h, i, j, k, l, m, n) ; ekat::action(&o, 1, fid) +#define PTD_RW16(action, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p ) PTD_RW15(action, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) ; ekat::action(&p, 1, fid) +#define PTD_RW17(action, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q ) PTD_RW16(action, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) ; ekat::action(&q, 1, fid) +#define PTD_RW18(action, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r ) PTD_RW17(action, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) ; ekat::action(&r, 1, fid) +#define PTD_RW19(action, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s ) PTD_RW18(action, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r) ; ekat::action(&s, 1, fid) +#define PTD_RW20(action, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t ) PTD_RW19(action, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s) ; ekat::action(&t, 1, fid) #define PTD_ASSIGN_OP(name, num_scalars, ...) \ name& operator=(const name& rhs) { PTD_ASS##num_scalars(__VA_ARGS__); assignment_impl(rhs); return *this; } #define PTD_RW_SCALARS(num_scalars, ...) \ - void read_scalars(const ekat::FILEPtr& fid) { PTD_RW##num_scalars(read, __VA_ARGS__); } \ + void read_scalars(const ekat::FILEPtr& fid) { EKAT_REQUIRE_MSG(fid, "Tried to read from missing file. You may have forgotten to generate baselines for some BFB unit tests"); PTD_RW##num_scalars(read, __VA_ARGS__); } \ void write_scalars(const ekat::FILEPtr& fid) const { PTD_RW##num_scalars(write, __VA_ARGS__); } #define PTD_RW() \ From cda50baf714be1751516257015dc5fe7f8d60c5d Mon Sep 17 00:00:00 2001 From: James Foucar Date: Fri, 1 Nov 2024 12:49:57 -0600 Subject: [PATCH 016/147] p3_unit_tests and macro cleanup --- .../eamxx/src/physics/p3/p3_functions_f90.hpp | 97 +++++++++++--- .../src/physics/p3/tests/p3_unit_tests.cpp | 126 ++++++++++++++---- .../src/physics/share/physics_test_data.hpp | 102 ++++++++------ 3 files changed, 234 insertions(+), 91 deletions(-) diff --git a/components/eamxx/src/physics/p3/p3_functions_f90.hpp b/components/eamxx/src/physics/p3/p3_functions_f90.hpp index 20207460c0a0..461736bfc643 100644 --- a/components/eamxx/src/physics/p3/p3_functions_f90.hpp +++ b/components/eamxx/src/physics/p3/p3_functions_f90.hpp @@ -93,6 +93,8 @@ struct LookupIceData // Outputs Int dumi, dumjj, dumii, dumzz; Real dum1, dum4, dum5, dum6; + + PTD_RW_SCALARS_ONLY(8, dumi, dumjj, dumii, dumzz, dum1, dum4, dum5, dum6); }; /////////////////////////////////////////////////////////////////////////////// @@ -105,6 +107,8 @@ struct LookupIceDataB // Outputs Int dumj; Real dum3; + + PTD_RW_SCALARS_ONLY(2, dumj, dum3); }; /////////////////////////////////////////////////////////////////////////////// @@ -117,6 +121,8 @@ struct AccessLookupTableData // Outputs Real proc; + + PTD_RW_SCALARS_ONLY(1, proc); }; /////////////////////////////////////////////////////////////////////////////// @@ -130,6 +136,8 @@ struct AccessLookupTableCollData // Outputs Real proc; + + PTD_RW_SCALARS_ONLY(1, proc); }; /////////////////////////////////////////////////////////////////////////////// @@ -147,6 +155,11 @@ struct BackToCellAverageData // This populates all fields with test data within [0,1]. void randomize(std::mt19937_64& engine); + + PTD_RW_SCALARS_ONLY(31, qc2qr_accret_tend, qr2qv_evap_tend, qc2qr_autoconv_tend, nc_accret_tend, nc_selfcollect_tend, nc2nr_autoconv_tend, nr_selfcollect_tend, nr_evap_tend, ncautr, qcnuc, + nc_nuceat_tend, qi2qv_sublim_tend, nr_ice_shed_tend, qc2qi_hetero_freeze_tend, qr2qi_collect_tend, qc2qr_ice_shed_tend, qi2qr_melt_tend, qc2qi_collect_tend, qr2qi_immers_freeze_tend, ni2nr_melt_tend, + nc_collect_tend, ncshdc, nc2ni_immers_freeze_tend, nr_collect_tend, ni_selfcollect_tend, qv2qi_vapdep_tend, nr2ni_immers_freeze_tend, ni_sublim_tend, qv2qi_nucleat_tend, ni_nucleat_tend, + qc2qi_berg_tend); }; /////////////////////////////////////////////////////////////////////////////// @@ -158,6 +171,8 @@ struct CloudWaterConservationData //output Real qc2qr_autoconv_tend, qc2qr_accret_tend, qc2qi_collect_tend, qc2qi_hetero_freeze_tend, qc2qr_ice_shed_tend, qc2qi_berg_tend, qi2qv_sublim_tend, qv2qi_vapdep_tend; + + PTD_RW_SCALARS_ONLY(8, qc2qr_autoconv_tend, qc2qr_accret_tend, qc2qi_collect_tend, qc2qi_hetero_freeze_tend, qc2qr_ice_shed_tend, qc2qi_berg_tend, qi2qv_sublim_tend, qv2qi_vapdep_tend); }; struct RainWaterConservationData @@ -167,6 +182,8 @@ struct RainWaterConservationData //output Real qr2qv_evap_tend, qr2qi_collect_tend, qr2qi_immers_freeze_tend; + + PTD_RW_SCALARS_ONLY(3, qr2qv_evap_tend, qr2qi_collect_tend, qr2qi_immers_freeze_tend); }; struct IceWaterConservationData @@ -176,6 +193,8 @@ struct IceWaterConservationData //output Real qi2qv_sublim_tend, qi2qr_melt_tend; + + PTD_RW_SCALARS_ONLY(2, qi2qv_sublim_tend, qi2qr_melt_tend); }; /////////////////////////////////////////////////////////////////////////////// @@ -187,6 +206,8 @@ struct CalcRimeDensityData // output Real vtrmi1, rho_qm_cloud; + + PTD_RW_SCALARS_ONLY(2, vtrmi1, rho_qm_cloud); }; /////////////////////////////////////////////////////////////////////////////// @@ -198,6 +219,8 @@ struct CldliqImmersionFreezingData // output Real qc2qi_hetero_freeze_tend, nc2ni_immers_freeze_tend; + + PTD_RW_SCALARS_ONLY(2, qc2qi_hetero_freeze_tend, nc2ni_immers_freeze_tend); }; /////////////////////////////////////////////////////////////////////////////// @@ -209,6 +232,8 @@ struct RainImmersionFreezingData // output Real qr2qi_immers_freeze_tend, nr2ni_immers_freeze_tend; + + PTD_RW_SCALARS_ONLY(2, qr2qi_immers_freeze_tend, nr2ni_immers_freeze_tend); }; /////////////////////////////////////////////////////////////////////////////// @@ -220,6 +245,8 @@ struct DropletSelfCollectionData // output Real nc_selfcollect_tend; + + PTD_RW_SCALARS_ONLY(1, nc_selfcollect_tend); }; /////////////////////////////////////////////////////////////////////////////// @@ -231,6 +258,8 @@ struct CloudRainAccretionData // output Real qc2qr_accret_tend, nc_accret_tend; + + PTD_RW_SCALARS_ONLY(2, qc2qr_accret_tend, nc_accret_tend); }; /////////////////////////////////////////////////////////////////////////////// @@ -238,15 +267,12 @@ struct CloudRainAccretionData struct CloudWaterAutoconversionData { // inputs - Real rho; - Real qc_incld; - Real nc_incld; - Real inv_qc_relvar; + Real rho, qc_incld, nc_incld, inv_qc_relvar; // output - Real qc2qr_autoconv_tend; - Real nc2nr_autoconv_tend; - Real ncautr; + Real qc2qr_autoconv_tend, nc2nr_autoconv_tend, ncautr; + + PTD_RW_SCALARS_ONLY(3, qc2qr_autoconv_tend, nc2nr_autoconv_tend, ncautr); }; /////////////////////////////////////////////////////////////////////////////// @@ -258,6 +284,8 @@ struct RainSelfCollectionData //output Real nr_selfcollect_tend; + + PTD_RW_SCALARS_ONLY(1, nr_selfcollect_tend); }; /////////////////////////////////////////////////////////////////////////////// @@ -268,6 +296,8 @@ struct ImposeMaxTotalNiData{ //input Real max_total_ni, inv_rho_local; + + PTD_RW_SCALARS_ONLY(2, ni_local, inv_rho_local); }; /////////////////////////////////////////////////////////////////////////////// @@ -279,6 +309,8 @@ struct IceMeltingData // output Real qi2qr_melt_tend,ni2nr_melt_tend; + + PTD_RW_SCALARS_ONLY(2, qi2qr_melt_tend, ni2nr_melt_tend); }; /////////////////////////////////////////////////////////////////////////////// @@ -299,6 +331,8 @@ struct GetCloudDsd2Data // Outputs Real nc_out, mu_c, nu, lamc, cdist, cdist1; + + PTD_RW_SCALARS_ONLY(6, nc_out, mu_c, nu, lamc, cdist, cdist1) }; ////////////////////////////////////////////////////////////////////////// @@ -310,6 +344,8 @@ struct GetRainDsd2Data // Outputs Real nr_out, lamr, mu_r, cdistr, logn0r; + + PTD_RW_SCALARS_ONLY(5, nr_out, lamr, mu_r, cdistr, logn0r); }; /////////////////////////////////////////////////////////////////////////////// @@ -440,6 +476,8 @@ struct CalcBulkRhoRimeData // Outputs Real rho_rime; + + PTD_RW_SCALARS_ONLY(3, qi_rim, bi_rim, rho_rime); }; /////////////////////////////////////////////////////////////////////////////// @@ -475,18 +513,7 @@ struct ComputeRainFallVelocityData // Outputs Real mu_r, lamr, V_qr, V_nr; - PTD_RW_SCALARS(5, nr_incld, mu_r, lamr, V_qr, V_nr); - - void read(const ekat::FILEPtr& fid) - { - read_scalars(fid); - } - - void write(const ekat::FILEPtr& fid) const - { - write_scalars(fid); - } - + PTD_RW_SCALARS_ONLY(5, nr_incld, mu_r, lamr, V_qr, V_nr); }; /////////////////////////////////////////////////////////////////////////////// @@ -498,6 +525,8 @@ struct GetTimeSpacePhysVarsData //Outs Real mu, dv, sc, dqsdt, dqsidt, ab, abi, kap, eii; + + PTD_RW_SCALARS_ONLY(9, mu, dv, sc, dqsdt, dqsidt, ab, abi, kap, eii); }; /////////////////////////////////////////////////////////////////////////////// @@ -512,6 +541,8 @@ struct P3UpdatePrognosticIceData // In/outs Real th_atm, qv, qi, ni, qm, bm, qc, nc, qr, nr; + + PTD_RW_SCALARS_ONLY(10, th_atm, qv, qi, ni, qm, bm, qc, nc, qr, nr); }; /////////////////////////////////////////////////////////////////////////////// @@ -524,6 +555,8 @@ struct EvapRainData //Outs Real qr2qv_evap_tend, nr_evap_tend; + + PTD_RW_SCALARS_ONLY(2, qr2qv_evap_tend, nr_evap_tend); }; /////////////////////////////////////////////////////////////////////////////// @@ -539,6 +572,8 @@ struct P3UpdatePrognosticLiqData // In/outs Real th_atm, qv, qc, nc, qr, nr; + + PTD_RW_SCALARS_ONLY(6, th_atm, qv, qc, nc, qr, nr); }; /////////////////////////////////////////////////////////////////////////////// @@ -554,6 +589,7 @@ struct IceDepositionSublimationData // This populates all input fields with test data within [0,1]. void randomize(std::mt19937_64& engine); + PTD_RW_SCALARS_ONLY(4, qv2qi_vapdep_tend, qi2qv_sublim_tend, ni_sublim_tend, qc2qi_berg_tend); }; struct IceCldliqCollectionData @@ -565,6 +601,7 @@ struct IceCldliqCollectionData // Outputs Real qc2qi_collect_tend, nc_collect_tend, qc2qr_ice_shed_tend, ncshdc; + PTD_RW_SCALARS_ONLY(4, qc2qi_collect_tend, nc_collect_tend, qc2qr_ice_shed_tend, ncshdc); }; struct IceRainCollectionData @@ -576,6 +613,7 @@ struct IceRainCollectionData // Outputs Real qr2qi_collect_tend, nr_collect_tend; + PTD_RW_SCALARS_ONLY(2, qr2qi_collect_tend, nr_collect_tend); }; struct IceSelfCollectionData @@ -587,6 +625,7 @@ struct IceSelfCollectionData // Outputs Real ni_selfcollect_tend; + PTD_RW_SCALARS_ONLY(1, ni_selfcollect_tend); }; struct IceRelaxationData @@ -596,6 +635,8 @@ struct IceRelaxationData // Outputs Real epsi, epsi_tot; + + PTD_RW_SCALARS_ONLY(2, epsi, epsi_tot); }; struct CalcLiqRelaxationData @@ -608,6 +649,8 @@ struct CalcLiqRelaxationData // This populates all input fields with test data within [0,1]. void randomize(std::mt19937_64& engine); + + PTD_RW_SCALARS_ONLY(2, epsr, epsc); }; struct IceNucleationData @@ -619,6 +662,8 @@ struct IceNucleationData // Outputs Real qv2qi_nucleat_tend, ni_nucleat_tend; + + PTD_RW_SCALARS_ONLY(2, qv2qi_nucleat_tend, ni_nucleat_tend); }; struct IceWetGrowthData @@ -631,6 +676,8 @@ struct IceWetGrowthData bool log_wetgrowth; Real qr2qi_collect_tend, qc2qi_collect_tend, qc_growth_rate, nr_ice_shed_tend, qc2qr_ice_shed_tend; + + PTD_RW_SCALARS_ONLY(6, log_wetgrowth, qr2qi_collect_tend, qc2qi_collect_tend, qc_growth_rate, nr_ice_shed_tend, qc2qr_ice_shed_tend); }; struct LatentHeatData : public PhysicsTestData @@ -675,6 +722,8 @@ struct IncloudMixingData // Outputs Real qc_incld, qr_incld, qi_incld, qm_incld, nc_incld, nr_incld, ni_incld, bm_incld; + + PTD_RW_SCALARS_ONLY(8, qc_incld, qr_incld, qi_incld, qm_incld, nc_incld, nr_incld, ni_incld, bm_incld); }; /////////////////////////////////////////////////////////////////////////////// @@ -796,6 +845,8 @@ struct IceSupersatConservationData { Real qidep, qinuc; void randomize(std::mt19937_64& engine); + + PTD_RW_SCALARS_ONLY(2, qidep, qinuc); }; struct NcConservationData { @@ -806,6 +857,8 @@ struct NcConservationData { Real nc_collect_tend, nc2ni_immers_freeze_tend, nc_accret_tend, nc2nr_autoconv_tend; void randomize(std::mt19937_64& engine); + + PTD_RW_SCALARS_ONLY(4, nc_collect_tend, nc2ni_immers_freeze_tend, nc_accret_tend, nc2nr_autoconv_tend); }; struct NrConservationData { @@ -816,6 +869,8 @@ struct NrConservationData { Real nr_collect_tend, nr2ni_immers_freeze_tend, nr_selfcollect_tend, nr_evap_tend; void randomize(std::mt19937_64& engine); + + PTD_RW_SCALARS_ONLY(4, nr_collect_tend, nr2ni_immers_freeze_tend, nr_selfcollect_tend, nr_evap_tend); }; struct NiConservationData { @@ -826,6 +881,8 @@ struct NiConservationData { Real ni2nr_melt_tend, ni_sublim_tend, ni_selfcollect_tend; void randomize(std::mt19937_64& engine); + + PTD_RW_SCALARS_ONLY(3, ni2nr_melt_tend, ni_sublim_tend, ni_selfcollect_tend); }; struct PreventLiqSupersaturationData { @@ -837,6 +894,8 @@ struct PreventLiqSupersaturationData { // This populates all fields with test data within [0,1]. void randomize(std::mt19937_64& engine); + + PTD_RW_SCALARS_ONLY(2, qi2qv_sublim_tend, qr2qv_evap_tend); }; // Glue functions to call fortran from from C++ with the Data struct diff --git a/components/eamxx/src/physics/p3/tests/p3_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_unit_tests.cpp index 2a33cc70db19..9bf227602798 100644 --- a/components/eamxx/src/physics/p3/tests/p3_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_unit_tests.cpp @@ -222,9 +222,13 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: std::copy(&cwdc[0], &cwdc[0] + max_pack_size, cwdc_host.data()); Kokkos::deep_copy(cwdc_device, cwdc_host); - // Get data from fortran - for (Int i = 0; i < max_pack_size; ++i) { - cloud_water_conservation(cwdc[i]); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/cloud_water_conservation.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + cwdc[i].read(fid); + } } // Run the lookup from a kernel and copy results back to host @@ -263,7 +267,7 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: Kokkos::deep_copy(cwdc_host, cwdc_device); // Validate results - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int s = 0; s < max_pack_size; ++s) { REQUIRE(cwdc[s].qc == cwdc_host(s).qc); REQUIRE(cwdc[s].qc2qr_autoconv_tend == cwdc_host(s).qc2qr_autoconv_tend); @@ -275,6 +279,12 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: REQUIRE(cwdc[s].qv2qi_vapdep_tend == cwdc_host(s).qv2qi_vapdep_tend); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + cwdc_host(s).write(fid); + } + } } void ice_water_conservation_unit_bfb_tests() @@ -312,9 +322,13 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: std::copy(&iwdc[0], &iwdc[0] + max_pack_size, iwdc_host.data()); Kokkos::deep_copy(iwdc_device, iwdc_host); - // Get data from fortran - for (Int i = 0; i < max_pack_size; ++i) { - ice_water_conservation(iwdc[i]); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/ice_water_conservation.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + iwdc[i].read(fid); + } } // Run the lookup from a kernel and copy results back to host @@ -356,7 +370,7 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: Kokkos::deep_copy(iwdc_host, iwdc_device); // Validate results - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int s = 0; s < max_pack_size; ++s) { REQUIRE(iwdc[s].qi == iwdc_host(s).qi); REQUIRE(iwdc[s].qv2qi_vapdep_tend == iwdc_host(s).qv2qi_vapdep_tend ); @@ -370,6 +384,12 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: REQUIRE(iwdc[s].qi2qr_melt_tend == iwdc_host(s).qi2qr_melt_tend); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + iwdc_host(s).write(fid); + } + } } void rain_water_conservation_unit_bfb_tests() { @@ -407,9 +427,13 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: std::copy(&rwdc[0], &rwdc[0] + max_pack_size, rwdc_host.data()); Kokkos::deep_copy(rwdc_device, rwdc_host); - // Get data from fortran - for (Int i = 0; i < max_pack_size; ++i) { - rain_water_conservation(rwdc[i]); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/rain_water_conservation.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + rwdc[i].read(fid); + } } // Run the lookup from a kernel and copy results back to host @@ -448,7 +472,7 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: Kokkos::deep_copy(rwdc_host, rwdc_device); // Validate results - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int s = 0; s < max_pack_size; ++s) { REQUIRE(rwdc[s].qr == rwdc_host(s).qr); REQUIRE(rwdc[s].qc2qr_autoconv_tend == rwdc_host(s).qc2qr_autoconv_tend); @@ -460,6 +484,12 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: REQUIRE(rwdc[s].qr2qi_immers_freeze_tend == rwdc_host(s).qr2qi_immers_freeze_tend); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + rwdc_host(s).write(fid); + } + } } void run_bfb() { @@ -591,9 +621,13 @@ struct UnitWrap::UnitTest::TestP3UpdatePrognosticIce : public UnitWrap::UnitT std::copy(&pupidc[0], &pupidc[0] + max_pack_size, pupidc_host.data()); Kokkos::deep_copy(pupidc_device, pupidc_host); - // Get data from fortran - for (Int i = 0; i < max_pack_size; ++i) { - update_prognostic_ice(pupidc[i]); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/update_prognostic_ice.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + pupidc[i].read(fid); + } } // Run the lookup from a kernel and copy results back to host @@ -679,7 +713,7 @@ struct UnitWrap::UnitTest::TestP3UpdatePrognosticIce : public UnitWrap::UnitT Kokkos::deep_copy(pupidc_host, pupidc_device); // Validate results - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int s = 0; s < max_pack_size; ++s) { REQUIRE(pupidc[s].th_atm == pupidc_host(s).th_atm); REQUIRE(pupidc[s].qc == pupidc_host(s).qc); @@ -693,6 +727,12 @@ struct UnitWrap::UnitTest::TestP3UpdatePrognosticIce : public UnitWrap::UnitT REQUIRE(pupidc[s].bm == pupidc_host(s).bm ); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + pupidc_host(s).write(fid); + } + } } void run_bfb() { @@ -737,9 +777,13 @@ struct UnitWrap::UnitTest::TestGetTimeSpacePhysVariables : public UnitWrap::U std::copy(>spvd[0], >spvd[0] + max_pack_size, gtspvd_host.data()); Kokkos::deep_copy(gtspvd_device, gtspvd_host); - // Get data from fortran - for (Int i = 0; i < max_pack_size; ++i) { - get_time_space_phys_variables(gtspvd[i]); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/get_time_space_phys_variables.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + gtspvd[i].read(fid); + } } // Run the lookup from a kernel and copy results back to host @@ -794,7 +838,7 @@ struct UnitWrap::UnitTest::TestGetTimeSpacePhysVariables : public UnitWrap::U Kokkos::deep_copy(gtspvd_host, gtspvd_device); // Validate results - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int s = 0; s < max_pack_size; ++s) { REQUIRE(gtspvd[s].mu == gtspvd_host(s).mu); REQUIRE(gtspvd[s].dv == gtspvd_host(s).dv); @@ -807,6 +851,12 @@ struct UnitWrap::UnitTest::TestGetTimeSpacePhysVariables : public UnitWrap::U REQUIRE(gtspvd[s].eii == gtspvd_host(s).eii); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + gtspvd_host(s).write(fid); + } + } } void run_bfb() { @@ -896,9 +946,13 @@ struct UnitWrap::UnitTest::TestP3UpdatePrognosticLiq : public UnitWrap::UnitT std::copy(&pupldc[0], &pupldc[0] + max_pack_size, pupldc_host.data()); Kokkos::deep_copy(pupldc_device, pupldc_host); - // Get data from fortran - for (Int i = 0; i < max_pack_size; ++i) { - update_prognostic_liquid(pupldc[i]); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/update_prognostic_liquid.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + pupldc[i].read(fid); + } } // Run the lookup from a kernel and copy results back to host @@ -971,7 +1025,7 @@ struct UnitWrap::UnitTest::TestP3UpdatePrognosticLiq : public UnitWrap::UnitT Kokkos::deep_copy(pupldc_host, pupldc_device); // Validate results - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int s = 0; s < max_pack_size; ++s) { REQUIRE(pupldc[s].th_atm == pupldc_host(s).th_atm); REQUIRE(pupldc[s].qv == pupldc_host(s).qv); @@ -981,6 +1035,12 @@ struct UnitWrap::UnitTest::TestP3UpdatePrognosticLiq : public UnitWrap::UnitT REQUIRE(pupldc[s].nr == pupldc_host(s).nr); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + pupldc_host(s).write(fid); + } + } } void run_bfb() { @@ -1026,9 +1086,13 @@ struct UnitWrap::UnitTest::TestP3FunctionsImposeMaxTotalNi : public UnitWrap: std::copy(&dc[0], &dc[0] + max_pack_size, dc_host.data()); Kokkos::deep_copy(dc_device, dc_host); - //Get data from fortran - for (Int i = 0; i < max_pack_size; ++i) { - impose_max_total_ni(dc[i]); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/impose_max_total_ni.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + dc[i].read(fid); + } } //Run function from a kernal and copy results back to the host @@ -1054,12 +1118,18 @@ struct UnitWrap::UnitTest::TestP3FunctionsImposeMaxTotalNi : public UnitWrap: Kokkos::deep_copy(dc_host, dc_device); // Validate results - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int s = 0; s < max_pack_size; ++s) { REQUIRE(dc[s].ni_local == dc_host(s).ni_local); REQUIRE(dc[s].inv_rho_local == dc_host(s).inv_rho_local); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + dc_host(s).write(fid); + } + } } void run_bfb() { diff --git a/components/eamxx/src/physics/share/physics_test_data.hpp b/components/eamxx/src/physics/share/physics_test_data.hpp index 153ec7b9b286..ddd7d77fa860 100644 --- a/components/eamxx/src/physics/share/physics_test_data.hpp +++ b/components/eamxx/src/physics/share/physics_test_data.hpp @@ -69,50 +69,60 @@ struct SHOCGridData : public PhysicsTestData { #define PTD_DATA_COPY_CTOR(name, num_args) \ name(const name& rhs) : name(PTD_ONES(num_args)) { *this = rhs; } -#define PTD_ASS0( ) ((void) (0)) -#define PTD_ASS1(a ) PTD_ASS0() ; a = rhs.a -#define PTD_ASS2(a, b ) PTD_ASS1(a) ; b = rhs.b -#define PTD_ASS3(a, b, c ) PTD_ASS2(a, b) ; c = rhs.c -#define PTD_ASS4(a, b, c, d ) PTD_ASS3(a, b, c) ; d = rhs.d -#define PTD_ASS5(a, b, c, d, e ) PTD_ASS4(a, b, c, d) ; e = rhs.e -#define PTD_ASS6(a, b, c, d, e, f ) PTD_ASS5(a, b, c, d, e) ; f = rhs.f -#define PTD_ASS7(a, b, c, d, e, f, g ) PTD_ASS6(a, b, c, d, e, f) ; g = rhs.g -#define PTD_ASS8(a, b, c, d, e, f, g, h ) PTD_ASS7(a, b, c, d, e, f, g) ; h = rhs.h -#define PTD_ASS9(a, b, c, d, e, f, g, h, i ) PTD_ASS8(a, b, c, d, e, f, g, h) ; i = rhs.i -#define PTD_ASS10(a, b, c, d, e, f, g, h, i, j ) PTD_ASS9(a, b, c, d, e, f, g, h, i) ; j = rhs.j -#define PTD_ASS11(a, b, c, d, e, f, g, h, i, j, k ) PTD_ASS10(a, b, c, d, e, f, g, h, i, j) ; k = rhs.k -#define PTD_ASS12(a, b, c, d, e, f, g, h, i, j, k, l ) PTD_ASS11(a, b, c, d, e, f, g, h, i, j, k) ; l = rhs.l -#define PTD_ASS13(a, b, c, d, e, f, g, h, i, j, k, l, m ) PTD_ASS12(a, b, c, d, e, f, g, h, i, j, k, l) ; m = rhs.m -#define PTD_ASS14(a, b, c, d, e, f, g, h, i, j, k, l, m, n ) PTD_ASS13(a, b, c, d, e, f, g, h, i, j, k, l, m) ; n = rhs.n -#define PTD_ASS15(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o ) PTD_ASS14(a, b, c, d, e, f, g, h, i, j, k, l, m, n) ; o = rhs.o -#define PTD_ASS16(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p ) PTD_ASS15(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) ; p = rhs.p -#define PTD_ASS17(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q ) PTD_ASS16(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) ; q = rhs.q -#define PTD_ASS18(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r ) PTD_ASS17(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) ; r = rhs.r -#define PTD_ASS19(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s ) PTD_ASS18(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r) ; s = rhs.s -#define PTD_ASS20(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t ) PTD_ASS19(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s) ; t = rhs.t - - -#define PTD_RW0(action ) ((void) (0)) -#define PTD_RW1(action, a ) PTD_RW0(action) ; ekat::action(&a, 1, fid) -#define PTD_RW2(action, a, b ) PTD_RW1(action, a) ; ekat::action(&b, 1, fid) -#define PTD_RW3(action, a, b, c ) PTD_RW2(action, a, b) ; ekat::action(&c, 1, fid) -#define PTD_RW4(action, a, b, c, d ) PTD_RW3(action, a, b, c) ; ekat::action(&d, 1, fid) -#define PTD_RW5(action, a, b, c, d, e ) PTD_RW4(action, a, b, c, d) ; ekat::action(&e, 1, fid) -#define PTD_RW6(action, a, b, c, d, e, f ) PTD_RW5(action, a, b, c, d, e) ; ekat::action(&f, 1, fid) -#define PTD_RW7(action, a, b, c, d, e, f, g ) PTD_RW6(action, a, b, c, d, e, f) ; ekat::action(&g, 1, fid) -#define PTD_RW8(action, a, b, c, d, e, f, g, h ) PTD_RW7(action, a, b, c, d, e, f, g) ; ekat::action(&h, 1, fid) -#define PTD_RW9(action, a, b, c, d, e, f, g, h, i ) PTD_RW8(action, a, b, c, d, e, f, g, h) ; ekat::action(&i, 1, fid) -#define PTD_RW10(action, a, b, c, d, e, f, g, h, i, j ) PTD_RW9(action, a, b, c, d, e, f, g, h, i) ; ekat::action(&j, 1, fid) -#define PTD_RW11(action, a, b, c, d, e, f, g, h, i, j, k ) PTD_RW10(action, a, b, c, d, e, f, g, h, i, j) ; ekat::action(&k, 1, fid) -#define PTD_RW12(action, a, b, c, d, e, f, g, h, i, j, k, l ) PTD_RW11(action, a, b, c, d, e, f, g, h, i, j, k) ; ekat::action(&l, 1, fid) -#define PTD_RW13(action, a, b, c, d, e, f, g, h, i, j, k, l, m ) PTD_RW12(action, a, b, c, d, e, f, g, h, i, j, k, l) ; ekat::action(&m, 1, fid) -#define PTD_RW14(action, a, b, c, d, e, f, g, h, i, j, k, l, m, n ) PTD_RW13(action, a, b, c, d, e, f, g, h, i, j, k, l, m) ; ekat::action(&n, 1, fid) -#define PTD_RW15(action, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o ) PTD_RW14(action, a, b, c, d, e, f, g, h, i, j, k, l, m, n) ; ekat::action(&o, 1, fid) -#define PTD_RW16(action, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p ) PTD_RW15(action, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) ; ekat::action(&p, 1, fid) -#define PTD_RW17(action, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q ) PTD_RW16(action, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) ; ekat::action(&q, 1, fid) -#define PTD_RW18(action, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r ) PTD_RW17(action, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) ; ekat::action(&r, 1, fid) -#define PTD_RW19(action, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s ) PTD_RW18(action, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r) ; ekat::action(&s, 1, fid) -#define PTD_RW20(action, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t ) PTD_RW19(action, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s) ; ekat::action(&t, 1, fid) +#define PTD_ASS0() ((void) (0)) +#define PTD_ASS1(first) first = rhs.first; PTD_ASS0() +#define PTD_ASS2(first, ...) first = rhs.first; PTD_ASS1(__VA_ARGS__) +#define PTD_ASS3(first, ...) first = rhs.first; PTD_ASS2(__VA_ARGS__) +#define PTD_ASS4(first, ...) first = rhs.first; PTD_ASS3(__VA_ARGS__) +#define PTD_ASS5(first, ...) first = rhs.first; PTD_ASS4(__VA_ARGS__) +#define PTD_ASS6(first, ...) first = rhs.first; PTD_ASS5(__VA_ARGS__) +#define PTD_ASS7(first, ...) first = rhs.first; PTD_ASS6(__VA_ARGS__) +#define PTD_ASS8(first, ...) first = rhs.first; PTD_ASS7(__VA_ARGS__) +#define PTD_ASS9(first, ...) first = rhs.first; PTD_ASS8(__VA_ARGS__) +#define PTD_ASS10(first, ...) first = rhs.first; PTD_ASS9(__VA_ARGS__) +#define PTD_ASS11(first, ...) first = rhs.first; PTD_ASS10(__VA_ARGS__) +#define PTD_ASS12(first, ...) first = rhs.first; PTD_ASS11(__VA_ARGS__) +#define PTD_ASS13(first, ...) first = rhs.first; PTD_ASS12(__VA_ARGS__) +#define PTD_ASS14(first, ...) first = rhs.first; PTD_ASS13(__VA_ARGS__) +#define PTD_ASS15(first, ...) first = rhs.first; PTD_ASS14(__VA_ARGS__) +#define PTD_ASS16(first, ...) first = rhs.first; PTD_ASS15(__VA_ARGS__) +#define PTD_ASS17(first, ...) first = rhs.first; PTD_ASS16(__VA_ARGS__) +#define PTD_ASS18(first, ...) first = rhs.first; PTD_ASS17(__VA_ARGS__) +#define PTD_ASS19(first, ...) first = rhs.first; PTD_ASS18(__VA_ARGS__) +#define PTD_ASS20(first, ...) first = rhs.first; PTD_ASS19(__VA_ARGS__) + +#define PTD_RW0(action) ((void) (0)) +#define PTD_RW1(action, first) ekat::action(&first, 1, fid); PTD_RW0(action) +#define PTD_RW2(action, first, ...) ekat::action(&first, 1, fid); PTD_RW1(action, __VA_ARGS__) +#define PTD_RW3(action, first, ...) ekat::action(&first, 1, fid); PTD_RW2(action, __VA_ARGS__) +#define PTD_RW4(action, first, ...) ekat::action(&first, 1, fid); PTD_RW3(action, __VA_ARGS__) +#define PTD_RW5(action, first, ...) ekat::action(&first, 1, fid); PTD_RW4(action, __VA_ARGS__) +#define PTD_RW6(action, first, ...) ekat::action(&first, 1, fid); PTD_RW5(action, __VA_ARGS__) +#define PTD_RW7(action, first, ...) ekat::action(&first, 1, fid); PTD_RW6(action, __VA_ARGS__) +#define PTD_RW8(action, first, ...) ekat::action(&first, 1, fid); PTD_RW7(action, __VA_ARGS__) +#define PTD_RW9(action, first, ...) ekat::action(&first, 1, fid); PTD_RW8(action, __VA_ARGS__) +#define PTD_RW10(action, first, ...) ekat::action(&first, 1, fid); PTD_RW9(action, __VA_ARGS__) +#define PTD_RW11(action, first, ...) ekat::action(&first, 1, fid); PTD_RW10(action, __VA_ARGS__) +#define PTD_RW12(action, first, ...) ekat::action(&first, 1, fid); PTD_RW11(action, __VA_ARGS__) +#define PTD_RW13(action, first, ...) ekat::action(&first, 1, fid); PTD_RW12(action, __VA_ARGS__) +#define PTD_RW14(action, first, ...) ekat::action(&first, 1, fid); PTD_RW13(action, __VA_ARGS__) +#define PTD_RW15(action, first, ...) ekat::action(&first, 1, fid); PTD_RW14(action, __VA_ARGS__) +#define PTD_RW16(action, first, ...) ekat::action(&first, 1, fid); PTD_RW15(action, __VA_ARGS__) +#define PTD_RW17(action, first, ...) ekat::action(&first, 1, fid); PTD_RW16(action, __VA_ARGS__) +#define PTD_RW18(action, first, ...) ekat::action(&first, 1, fid); PTD_RW17(action, __VA_ARGS__) +#define PTD_RW19(action, first, ...) ekat::action(&first, 1, fid); PTD_RW18(action, __VA_ARGS__) +#define PTD_RW20(action, first, ...) ekat::action(&first, 1, fid); PTD_RW19(action, __VA_ARGS__) +#define PTD_RW21(action, first, ...) ekat::action(&first, 1, fid); PTD_RW20(action, __VA_ARGS__) +#define PTD_RW22(action, first, ...) ekat::action(&first, 1, fid); PTD_RW21(action, __VA_ARGS__) +#define PTD_RW23(action, first, ...) ekat::action(&first, 1, fid); PTD_RW22(action, __VA_ARGS__) +#define PTD_RW24(action, first, ...) ekat::action(&first, 1, fid); PTD_RW23(action, __VA_ARGS__) +#define PTD_RW25(action, first, ...) ekat::action(&first, 1, fid); PTD_RW24(action, __VA_ARGS__) +#define PTD_RW26(action, first, ...) ekat::action(&first, 1, fid); PTD_RW25(action, __VA_ARGS__) +#define PTD_RW27(action, first, ...) ekat::action(&first, 1, fid); PTD_RW26(action, __VA_ARGS__) +#define PTD_RW28(action, first, ...) ekat::action(&first, 1, fid); PTD_RW27(action, __VA_ARGS__) +#define PTD_RW29(action, first, ...) ekat::action(&first, 1, fid); PTD_RW28(action, __VA_ARGS__) +#define PTD_RW30(action, first, ...) ekat::action(&first, 1, fid); PTD_RW29(action, __VA_ARGS__) +#define PTD_RW31(action, first, ...) ekat::action(&first, 1, fid); PTD_RW30(action, __VA_ARGS__) #define PTD_ASSIGN_OP(name, num_scalars, ...) \ name& operator=(const name& rhs) { PTD_ASS##num_scalars(__VA_ARGS__); assignment_impl(rhs); return *this; } @@ -121,6 +131,10 @@ struct SHOCGridData : public PhysicsTestData { void read_scalars(const ekat::FILEPtr& fid) { EKAT_REQUIRE_MSG(fid, "Tried to read from missing file. You may have forgotten to generate baselines for some BFB unit tests"); PTD_RW##num_scalars(read, __VA_ARGS__); } \ void write_scalars(const ekat::FILEPtr& fid) const { PTD_RW##num_scalars(write, __VA_ARGS__); } +#define PTD_RW_SCALARS_ONLY(num_scalars, ...) \ + void read(const ekat::FILEPtr& fid) { EKAT_REQUIRE_MSG(fid, "Tried to read from missing file. You may have forgotten to generate baselines for some BFB unit tests"); PTD_RW##num_scalars(read, __VA_ARGS__); } \ + void write(const ekat::FILEPtr& fid) const { PTD_RW##num_scalars(write, __VA_ARGS__); } + #define PTD_RW() \ void read(const ekat::FILEPtr& fid) { read_scalars(fid); PhysicsTestData::read(fid); } \ void write(const ekat::FILEPtr& fid) const { write_scalars(fid); PhysicsTestData::write(fid); } From c3560ef4e9c167c759533b2070bd0d948215ca56 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Fri, 1 Nov 2024 13:33:14 -0600 Subject: [PATCH 017/147] p3_cloud_water_autoconversion_test --- .../p3/tests/p3_autoconversion_unit_tests.cpp | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/components/eamxx/src/physics/p3/tests/p3_autoconversion_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_autoconversion_unit_tests.cpp index e4ff1fd43669..39a8d1435443 100644 --- a/components/eamxx/src/physics/p3/tests/p3_autoconversion_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_autoconversion_unit_tests.cpp @@ -59,12 +59,16 @@ void cloud_water_autoconversion_unit_bfb_tests() { std::copy(&cwadc[0], &cwadc[0] + max_pack_size, cwadc_host.data()); Kokkos::deep_copy(cwadc_device, cwadc_host); - // Get data from fortran - for (Int i = 0; i < max_pack_size; ++i) { - cloud_water_autoconversion(cwadc[i]); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/cloud_water_autoconversion.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + cwadc[i].read(fid); + } } - // Run the lookup from a kernel and copy results back to host + // Run the lookup from a kernel and copy results back to host Kokkos::parallel_for(num_test_itrs, KOKKOS_LAMBDA(const Int& i) { const Int offset = i * Spack::n; @@ -101,7 +105,7 @@ void cloud_water_autoconversion_unit_bfb_tests() { Kokkos::deep_copy(cwadc_host, cwadc_device); // Validate results - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int s = 0; s < max_pack_size; ++s) { REQUIRE(cwadc[s].rho == cwadc_host(s).rho); REQUIRE(cwadc[s].qc_incld == cwadc_host(s).qc_incld); @@ -112,6 +116,12 @@ void cloud_water_autoconversion_unit_bfb_tests() { REQUIRE(cwadc[s].ncautr == cwadc_host(s).ncautr); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + cwadc_host(s).write(fid); + } + } } void run_bfb() { From cd284196a1f5ce30548d2f6be080ab33de0beda2 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Fri, 1 Nov 2024 13:40:25 -0600 Subject: [PATCH 018/147] p3_back_to_cell_average was not following the standard pattern --- .../p3_back_to_cell_average_unit_tests.cpp | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp index f73bd3d993a2..796eb6912c00 100644 --- a/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp @@ -32,32 +32,34 @@ void run_bfb() // Generate n test structs, each populated with random data (values within // [0,1]) by the default constructor. - BackToCellAverageData back_to_cell_average_data[Spack::n]; - for (Int i = 0; i < Spack::n; ++i) { - back_to_cell_average_data[i].randomize(engine); + BackToCellAverageData back_to_cell_average_data[max_pack_size]; + for (auto& item : back_to_cell_average_data) { + item.randomize(engine); } // Sync to device. - view_1d device_data("back_to_cell_average", Spack::n); + view_1d device_data("back_to_cell_average", max_pack_size); const auto host_data = Kokkos::create_mirror_view(device_data); - std::copy(&back_to_cell_average_data[0], &back_to_cell_average_data[0] + Spack::n, + std::copy(&back_to_cell_average_data[0], &back_to_cell_average_data[0] + max_pack_size, host_data.data()); Kokkos::deep_copy(device_data, host_data); // Run the Fortran subroutine. - for (Int i = 0; i < Spack::n; ++i) { + for (Int i = 0; i < max_pack_size; ++i) { back_to_cell_average(back_to_cell_average_data[i]); } // Run the lookup from a kernel and copy results back to host - Kokkos::parallel_for(1, KOKKOS_LAMBDA(const Int&) { + Kokkos::parallel_for(num_test_itrs, KOKKOS_LAMBDA(const Int& i) { + const Int offset = i * Spack::n; + // Init pack inputs Spack cld_frac_l, cld_frac_r, cld_frac_i, qc2qr_accret_tend, qr2qv_evap_tend, qc2qr_autoconv_tend, nc_accret_tend, nc_selfcollect_tend, nc2nr_autoconv_tend, nr_selfcollect_tend, nr_evap_tend, ncautr, qi2qv_sublim_tend, nr_ice_shed_tend, qc2qi_hetero_freeze_tend, qr2qi_collect_tend, qc2qr_ice_shed_tend, qi2qr_melt_tend, qc2qi_collect_tend, qr2qi_immers_freeze_tend, ni2nr_melt_tend, nc_collect_tend, ncshdc, nc2ni_immers_freeze_tend, nr_collect_tend, ni_selfcollect_tend, qv2qi_vapdep_tend, nr2ni_immers_freeze_tend, ni_sublim_tend, qv2qi_nucleat_tend, ni_nucleat_tend, qc2qi_berg_tend; - for (Int s = 0; s < Spack::n; ++s) { + for (Int s = 0, vs = offset; s < Spack::n; ++s, ++vs) { cld_frac_l[s] = device_data[s].cld_frac_l; cld_frac_r[s] = device_data[s].cld_frac_r; cld_frac_i[s] = device_data[s].cld_frac_i; @@ -99,7 +101,7 @@ void run_bfb() nr_collect_tend, ni_selfcollect_tend, qv2qi_vapdep_tend, nr2ni_immers_freeze_tend, ni_sublim_tend, qv2qi_nucleat_tend, ni_nucleat_tend, qc2qi_berg_tend); // Copy results back into views - for (Int s = 0; s < Spack::n; ++s) { + for (Int s = 0, vs = offset; s < Spack::n; ++s, ++vs) { device_data(s).qc2qr_accret_tend = qc2qr_accret_tend[s]; device_data(s).qr2qv_evap_tend = qr2qv_evap_tend[s]; device_data(s).qc2qr_autoconv_tend = qc2qr_autoconv_tend[s]; @@ -137,7 +139,7 @@ void run_bfb() // Validate results. if (SCREAM_BFB_TESTING) { - for (Int s = 0; s < Spack::n; ++s) { + for (Int s = 0; s < max_pack_size; ++s) { REQUIRE(back_to_cell_average_data[s].qc2qr_accret_tend == host_data[s].qc2qr_accret_tend); REQUIRE(back_to_cell_average_data[s].qr2qv_evap_tend == host_data[s].qr2qv_evap_tend); REQUIRE(back_to_cell_average_data[s].qc2qr_autoconv_tend == host_data[s].qc2qr_autoconv_tend); From a28704098c25b0a5bd629efa01de0f947b5055a7 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Fri, 1 Nov 2024 13:44:40 -0600 Subject: [PATCH 019/147] p3_back_to_cell_average --- .../p3_back_to_cell_average_unit_tests.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp index 796eb6912c00..58066bb6eac7 100644 --- a/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp @@ -28,7 +28,7 @@ void run_phys() void run_bfb() { - auto engine = setup_random_test(); + auto engine = setup_random_test(314552); // Generate n test structs, each populated with random data (values within // [0,1]) by the default constructor. @@ -48,6 +48,14 @@ void run_bfb() for (Int i = 0; i < max_pack_size; ++i) { back_to_cell_average(back_to_cell_average_data[i]); } + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/back_to_cell_average.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + back_to_cell_average_data[i].read(fid); + } + } // Run the lookup from a kernel and copy results back to host Kokkos::parallel_for(num_test_itrs, KOKKOS_LAMBDA(const Int& i) { @@ -138,7 +146,7 @@ void run_bfb() Kokkos::deep_copy(host_data, device_data); // Validate results. - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int s = 0; s < max_pack_size; ++s) { REQUIRE(back_to_cell_average_data[s].qc2qr_accret_tend == host_data[s].qc2qr_accret_tend); REQUIRE(back_to_cell_average_data[s].qr2qv_evap_tend == host_data[s].qr2qv_evap_tend); @@ -171,6 +179,12 @@ void run_bfb() REQUIRE(back_to_cell_average_data[s].qc2qi_berg_tend == host_data[s].qc2qi_berg_tend); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + host_data(s).write(fid); + } + } } }; From eae74a877d48627db88989810e1eb54fe7dfb2f5 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Fri, 1 Nov 2024 13:53:47 -0600 Subject: [PATCH 020/147] Two more easy ones --- ...lc_liq_relaxation_timescale_unit_tests.cpp | 20 ++++++++++++++----- .../tests/p3_calc_rime_density_unit_tests.cpp | 18 +++++++++++++---- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/components/eamxx/src/physics/p3/tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp index 69715267176d..c0da609087c1 100644 --- a/components/eamxx/src/physics/p3/tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp @@ -29,7 +29,7 @@ struct UnitWrap::UnitTest::TestCalcLiqRelaxationTimescale : public UnitWrap:: void run_bfb() { - auto engine = setup_random_test(); + auto engine = setup_random_test(12354); // Read in tables view_2d_table vn_table_vals, vm_table_vals, revap_table_vals; @@ -54,9 +54,13 @@ struct UnitWrap::UnitTest::TestCalcLiqRelaxationTimescale : public UnitWrap:: self[i].f2r = C::f2r; } - // Get data from fortran - for (Int i = 0; i < max_pack_size; ++i) { - calc_liq_relaxation_timescale(self[i]); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/calc_liq_relaxation_timescale.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + self[i].read(fid); + } } // Sync to device @@ -97,12 +101,18 @@ struct UnitWrap::UnitTest::TestCalcLiqRelaxationTimescale : public UnitWrap:: Kokkos::deep_copy(self_host, self_device); - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int s = 0; s < max_pack_size; ++s) { REQUIRE(self[s].epsr == self_host(s).epsr); REQUIRE(self[s].epsc == self_host(s).epsc); } } + else { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + self_host(s).write(fid); + } + } } }; diff --git a/components/eamxx/src/physics/p3/tests/p3_calc_rime_density_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_calc_rime_density_unit_tests.cpp index f858797fa002..1fee033460b5 100644 --- a/components/eamxx/src/physics/p3/tests/p3_calc_rime_density_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_calc_rime_density_unit_tests.cpp @@ -87,9 +87,13 @@ void run_bfb() host_data.data()); Kokkos::deep_copy(device_data, host_data); - // Run the Fortran subroutine. - for (Int i = 0; i < max_pack_size; ++i) { - calc_rime_density(calc_rime_density_data[i]); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/calc_rime_density.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + calc_rime_density_data[i].read(fid); + } } // Run the lookup from a kernel and copy results back to host @@ -126,12 +130,18 @@ void run_bfb() Kokkos::deep_copy(host_data, device_data); // Validate results. - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int s = 0; s < max_pack_size; ++s) { REQUIRE(calc_rime_density_data[s].vtrmi1 == host_data[s].vtrmi1); REQUIRE(calc_rime_density_data[s].rho_qm_cloud == host_data[s].rho_qm_cloud); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + host_data(s).write(fid); + } + } } }; From ac5851d3150fa5fdfd535b44eb49c968912c1c97 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Fri, 1 Nov 2024 14:06:31 -0600 Subject: [PATCH 021/147] Four more --- .../p3/tests/p3_check_values_unit_tests.cpp | 21 +------ .../p3_cldliq_imm_freezing_unit_tests.cpp | 18 ++++-- .../p3/tests/p3_cloud_rain_acc_unit_tests.cpp | 18 ++++-- .../p3/tests/p3_cloud_sed_unit_tests.cpp | 56 +++++++++++-------- 4 files changed, 64 insertions(+), 49 deletions(-) diff --git a/components/eamxx/src/physics/p3/tests/p3_check_values_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_check_values_unit_tests.cpp index 8b9ecf3904fd..15d76d346f4b 100644 --- a/components/eamxx/src/physics/p3/tests/p3_check_values_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_check_values_unit_tests.cpp @@ -24,9 +24,10 @@ struct UnitWrap::UnitTest::TestCheckValues : public UnitWrap::UnitTest::Ba void run_check_values_bfb() { + // This is not really a bfb test since no results are being checked. auto engine = setup_random_test(); - CheckValuesData cvd_fortran[] = { + CheckValuesData cvd_cxx[] = { // kts_, kte_, timestepcount_, source_ind_, force_abort_ CheckValuesData(1, 72, 2, 100, false), CheckValuesData(1, 72, 3, 100, false), @@ -34,26 +35,10 @@ void run_check_values_bfb() CheckValuesData(1, 72, 5, 100, false), }; - static constexpr Int num_runs = sizeof(cvd_fortran) / sizeof(CheckValuesData); - - for (auto& d : cvd_fortran) { + for (auto& d : cvd_cxx) { d.randomize(engine, { {d.qv, {-4.056E-01, 1.153E+00}}, {d.temp, {1.000E+02, 5.000E+02}} }); } - // Create copies of data for use by cxx. Needs to happen before fortran calls so that - // inout data is in original state - CheckValuesData cvd_cxx[num_runs] = { - CheckValuesData(cvd_fortran[0]), - CheckValuesData(cvd_fortran[1]), - CheckValuesData(cvd_fortran[2]), - CheckValuesData(cvd_fortran[3]), - }; - - // Get data from fortran - for (auto& d : cvd_fortran) { - check_values(d); - } - // Get data from cxx for (auto& d : cvd_cxx) { check_values_f(d.qv, d.temp, d.kts, d.kte, d.timestepcount, d.force_abort, d.source_ind, d.col_loc); diff --git a/components/eamxx/src/physics/p3/tests/p3_cldliq_imm_freezing_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_cldliq_imm_freezing_unit_tests.cpp index 901650d8695b..9c1524434054 100644 --- a/components/eamxx/src/physics/p3/tests/p3_cldliq_imm_freezing_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_cldliq_imm_freezing_unit_tests.cpp @@ -70,9 +70,13 @@ void run_bfb() host_data.data()); Kokkos::deep_copy(device_data, host_data); - // Run the Fortran subroutine. - for (Int i = 0; i < max_pack_size; ++i) { - cldliq_immersion_freezing(cldliq_imm_freezing_data[i]); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/cldliq_imm_freezing.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + cldliq_imm_freezing_data[i].read(fid); + } } // Run the lookup from a kernel and copy results back to host @@ -109,12 +113,18 @@ void run_bfb() Kokkos::deep_copy(host_data, device_data); // Validate results. - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int s = 0; s < max_pack_size; ++s) { REQUIRE(cldliq_imm_freezing_data[s].qc2qi_hetero_freeze_tend == host_data[s].qc2qi_hetero_freeze_tend); REQUIRE(cldliq_imm_freezing_data[s].nc2ni_immers_freeze_tend == host_data[s].nc2ni_immers_freeze_tend); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + host_data(s).write(fid); + } + } } }; diff --git a/components/eamxx/src/physics/p3/tests/p3_cloud_rain_acc_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_cloud_rain_acc_unit_tests.cpp index 2cfe22e5a260..276187f8ec07 100644 --- a/components/eamxx/src/physics/p3/tests/p3_cloud_rain_acc_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_cloud_rain_acc_unit_tests.cpp @@ -73,9 +73,13 @@ void run_bfb() host_data.data()); Kokkos::deep_copy(device_data, host_data); - // Run the Fortran subroutine. - for (Int i = 0; i < max_pack_size; ++i) { - cloud_rain_accretion(cloud_rain_acc_data[i]); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/cloud_rain_accretion.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + cloud_rain_acc_data[i].read(fid); + } } // Run the lookup from a kernel and copy results back to host @@ -112,12 +116,18 @@ void run_bfb() Kokkos::deep_copy(host_data, device_data); // Validate results. - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int s = 0; s < max_pack_size; ++s) { REQUIRE(cloud_rain_acc_data[s].qc2qr_accret_tend == host_data[s].qc2qr_accret_tend); REQUIRE(cloud_rain_acc_data[s].nc_accret_tend == host_data[s].nc_accret_tend); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + host_data(s).write(fid); + } + } } }; diff --git a/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp index b11400c98f42..ace2523fc2d9 100644 --- a/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp @@ -28,9 +28,9 @@ void run_phys() void run_bfb() { - auto engine = setup_random_test(); + auto engine = setup_random_test(23512); - CloudSedData csds_fortran[] = { + CloudSedData csds_baseline[] = { // kts, kte, ktop, kbot, kdir, dt, inv_dt, do_predict_nc, precip_liq_surf, CloudSedData(1, 72, 27, 72, -1, 1.800E+03, 5.556E-04, false, 0.0), CloudSedData(1, 72, 72, 27, 1, 1.800E+03, 5.556E-04, false, 0.0), @@ -39,26 +39,30 @@ void run_bfb() CloudSedData(1, 72, 27, 27, -1, 1.800E+03, 5.556E-04, true, 0.0), }; - static constexpr Int num_runs = sizeof(csds_fortran) / sizeof(CloudSedData); + static constexpr Int num_runs = sizeof(csds_baseline) / sizeof(CloudSedData); // Set up random input data - for (auto& d : csds_fortran) { + for (auto& d : csds_baseline) { d.randomize(engine, { {d.qc_incld, {C::QSMALL/2, C::QSMALL*2}} }); } // Create copies of data for use by cxx. Needs to happen before fortran calls so that // inout data is in original state CloudSedData csds_cxx[num_runs] = { - CloudSedData(csds_fortran[0]), - CloudSedData(csds_fortran[1]), - CloudSedData(csds_fortran[2]), - CloudSedData(csds_fortran[3]), - CloudSedData(csds_fortran[4]), + CloudSedData(csds_baseline[0]), + CloudSedData(csds_baseline[1]), + CloudSedData(csds_baseline[2]), + CloudSedData(csds_baseline[3]), + CloudSedData(csds_baseline[4]), }; - // Get data from fortran - for (auto& d : csds_fortran) { - cloud_sedimentation(d); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/cloud_sedimentation.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (auto& d : csds_baseline) { + d.read(fid); + } } // Get data from cxx @@ -69,21 +73,27 @@ void run_bfb() d.qc, d.nc, d.nc_incld, d.mu_c, d.lamc, &d.precip_liq_surf, d.qc_tend, d.nc_tend); } - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int i = 0; i < num_runs; ++i) { // Due to pack issues, we must restrict checks to the active k space - Int start = std::min(csds_fortran[i].kbot, csds_fortran[i].ktop) - 1; // 0-based indx - Int end = std::max(csds_fortran[i].kbot, csds_fortran[i].ktop); // 0-based indx + Int start = std::min(csds_baseline[i].kbot, csds_baseline[i].ktop) - 1; // 0-based indx + Int end = std::max(csds_baseline[i].kbot, csds_baseline[i].ktop); // 0-based indx for (Int k = start; k < end; ++k) { - REQUIRE(csds_fortran[i].qc[k] == csds_cxx[i].qc[k]); - REQUIRE(csds_fortran[i].nc[k] == csds_cxx[i].nc[k]); - REQUIRE(csds_fortran[i].nc_incld[k] == csds_cxx[i].nc_incld[k]); - REQUIRE(csds_fortran[i].mu_c[k] == csds_cxx[i].mu_c[k]); - REQUIRE(csds_fortran[i].lamc[k] == csds_cxx[i].lamc[k]); - REQUIRE(csds_fortran[i].qc_tend[k] == csds_cxx[i].qc_tend[k]); - REQUIRE(csds_fortran[i].nc_tend[k] == csds_cxx[i].nc_tend[k]); + REQUIRE(csds_baseline[i].qc[k] == csds_cxx[i].qc[k]); + REQUIRE(csds_baseline[i].nc[k] == csds_cxx[i].nc[k]); + REQUIRE(csds_baseline[i].nc_incld[k] == csds_cxx[i].nc_incld[k]); + REQUIRE(csds_baseline[i].mu_c[k] == csds_cxx[i].mu_c[k]); + REQUIRE(csds_baseline[i].lamc[k] == csds_cxx[i].lamc[k]); + REQUIRE(csds_baseline[i].qc_tend[k] == csds_cxx[i].qc_tend[k]); + REQUIRE(csds_baseline[i].nc_tend[k] == csds_cxx[i].nc_tend[k]); } - REQUIRE(csds_fortran[i].precip_liq_surf == csds_cxx[i].precip_liq_surf); + REQUIRE(csds_baseline[i].precip_liq_surf == csds_cxx[i].precip_liq_surf); + } + } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int i = 0; i < num_runs; ++i) { + csds_cxx[i].write(fid); } } } From 3a64d91391f40b64729b549f438872e15f7225d7 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Fri, 1 Nov 2024 14:25:14 -0600 Subject: [PATCH 022/147] get_latent_heat is not being used on the cxx side --- .../eamxx/src/physics/p3/p3_functions_f90.cpp | 16 ---- .../eamxx/src/physics/p3/p3_functions_f90.hpp | 16 ---- .../tests/p3_droplet_self_coll_unit_tests.cpp | 19 ++++- .../physics/p3/tests/p3_dsd2_unit_tests.cpp | 36 +++++++-- .../p3/tests/p3_evaporate_rain_unit_tests.cpp | 18 ++++- .../tests/p3_get_latent_heat_unit_tests.cpp | 79 ------------------- 6 files changed, 57 insertions(+), 127 deletions(-) delete mode 100644 components/eamxx/src/physics/p3/tests/p3_get_latent_heat_unit_tests.cpp diff --git a/components/eamxx/src/physics/p3/p3_functions_f90.cpp b/components/eamxx/src/physics/p3/p3_functions_f90.cpp index 7ce3f8aaa321..6b027935801c 100644 --- a/components/eamxx/src/physics/p3/p3_functions_f90.cpp +++ b/components/eamxx/src/physics/p3/p3_functions_f90.cpp @@ -176,8 +176,6 @@ void ice_cldliq_wet_growth_c(Real rho, Real temp, Real pres, Real rhofaci, Real Real qi_incld, Real ni_incld, Real qr_incld, bool* log_wetgrowth, Real* qr2qi_collect_tend, Real* qc2qi_collect_tend, Real* qc_growth_rate, Real* nr_ice_shed_tend, Real* qc2qr_ice_shed_tend); -void get_latent_heat_c(Int its, Int ite, Int kts, Int kte, Real* s, Real* v, Real* f); - Real subgrid_variance_scaling_c(Real relvar, Real expon); void check_values_c(Real* qv, Real* temp, Int kts, Int kte, Int timestepcount, @@ -347,20 +345,6 @@ void cldliq_immersion_freezing(CldliqImmersionFreezingData& d) &d.qc2qi_hetero_freeze_tend, &d.nc2ni_immers_freeze_tend); } -LatentHeatData::LatentHeatData(Int kts_, Int kte_, Int its_, Int ite_) : - PhysicsTestData( { {(ite_ - its_) + 1, (kte_ - kts_) + 1} }, - { {&v, &s, &f} }), - its(its_), ite(ite_), kts(kts_), kte(kte_) -{} - -void get_latent_heat(LatentHeatData& d) -{ - p3_init(); - d.transpose(); - get_latent_heat_c(d.its, d.ite, d.kts, d.kte, d.v, d.s, d.f); - d.transpose(); -} - void droplet_self_collection(DropletSelfCollectionData& d) { p3_init(); diff --git a/components/eamxx/src/physics/p3/p3_functions_f90.hpp b/components/eamxx/src/physics/p3/p3_functions_f90.hpp index 461736bfc643..40b92fe47b61 100644 --- a/components/eamxx/src/physics/p3/p3_functions_f90.hpp +++ b/components/eamxx/src/physics/p3/p3_functions_f90.hpp @@ -680,21 +680,6 @@ struct IceWetGrowthData PTD_RW_SCALARS_ONLY(6, log_wetgrowth, qr2qi_collect_tend, qc2qi_collect_tend, qc_growth_rate, nr_ice_shed_tend, qc2qr_ice_shed_tend); }; -struct LatentHeatData : public PhysicsTestData -{ - static constexpr size_t NUM_ARRAYS = 3; - - // Inputs - Int its, ite, kts, kte; - - // Outputs - Real* v, *s, *f; - - LatentHeatData(Int its_, Int ite_, Int kts_, Int kte_); - - PTD_STD_DEF(LatentHeatData, 4, its, ite, kts, kte); -}; - struct CheckValuesData : public PhysicsTestData { static constexpr size_t NUM_ARRAYS = 2; @@ -940,7 +925,6 @@ void ice_relaxation_timescale(IceRelaxationData& d); void calc_liq_relaxation_timescale(CalcLiqRelaxationData& d); void ice_nucleation(IceNucleationData& d); void ice_cldliq_wet_growth(IceWetGrowthData& d); -void get_latent_heat(LatentHeatData& d); void check_values(CheckValuesData& d); void calculate_incloud_mixingratios(IncloudMixingData& d); void p3_main_part1(P3MainPart1Data& d); diff --git a/components/eamxx/src/physics/p3/tests/p3_droplet_self_coll_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_droplet_self_coll_unit_tests.cpp index fccf41db6272..2a96b1b3bff2 100644 --- a/components/eamxx/src/physics/p3/tests/p3_droplet_self_coll_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_droplet_self_coll_unit_tests.cpp @@ -72,9 +72,13 @@ void run_bfb() host_data.data()); Kokkos::deep_copy(device_data, host_data); - // Run the Fortran subroutine. - for (Int i = 0; i < max_pack_size; ++i) { - droplet_self_collection(droplet_self_coll_data[i]); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/droplet_self_collection.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + droplet_self_coll_data[i].read(fid); + } } // Run the lookup from a kernel and copy results back to host @@ -107,11 +111,18 @@ void run_bfb() Kokkos::deep_copy(host_data, device_data); // Validate results. - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int s = 0; s < max_pack_size; ++s) { REQUIRE(droplet_self_coll_data[s].nc_selfcollect_tend == host_data[s].nc_selfcollect_tend); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + host_data(s).write(fid); + } + } + } }; diff --git a/components/eamxx/src/physics/p3/tests/p3_dsd2_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_dsd2_unit_tests.cpp index 43c5a7de8dde..6563335acb0b 100644 --- a/components/eamxx/src/physics/p3/tests/p3_dsd2_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_dsd2_unit_tests.cpp @@ -60,9 +60,13 @@ struct UnitWrap::UnitTest::TestDsd2 : public UnitWrap::UnitTest::Base { std::copy(&gcdd[0], &gcdd[0] + max_pack_size, gcdd_host.data()); Kokkos::deep_copy(gcdd_device, gcdd_host); - // Get data from fortran - for (Int i = 0; i < max_pack_size; ++i) { - get_cloud_dsd2(gcdd[i]); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/get_cloud_dsd2.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + gcdd[i].read(fid); + } } // Run the lookup from a kernel and copy results back to host @@ -95,7 +99,7 @@ struct UnitWrap::UnitTest::TestDsd2 : public UnitWrap::UnitTest::Base { Kokkos::deep_copy(gcdd_host, gcdd_device); // Validate results - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int s = 0; s < max_pack_size; ++s) { REQUIRE(gcdd[s].nc_out == gcdd_host(s).nc_out); REQUIRE(gcdd[s].mu_c == gcdd_host(s).mu_c); @@ -105,6 +109,12 @@ struct UnitWrap::UnitTest::TestDsd2 : public UnitWrap::UnitTest::Base { REQUIRE(gcdd[s].cdist1 == gcdd_host(s).cdist1); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + gcdd_host(s).write(fid); + } + } } void run_cloud_phys() @@ -144,9 +154,13 @@ struct UnitWrap::UnitTest::TestDsd2 : public UnitWrap::UnitTest::Base { std::copy(&grdd[0], &grdd[0] + max_pack_size, grdd_host.data()); Kokkos::deep_copy(grdd_device, grdd_host); - // Get data from fortran - for (Int i = 0; i < max_pack_size; ++i) { - get_rain_dsd2(grdd[i]); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/get_rain_dsd2.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + grdd[i].read(fid); + } } // Run the lookup from a kernel and copy results back to host @@ -179,7 +193,7 @@ struct UnitWrap::UnitTest::TestDsd2 : public UnitWrap::UnitTest::Base { Kokkos::deep_copy(grdd_host, grdd_device); // Validate results - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int s = 0; s < max_pack_size; ++s) { REQUIRE(grdd[s].nr_out == grdd_host(s).nr_out); REQUIRE(grdd[s].mu_r == grdd_host(s).mu_r); @@ -188,6 +202,12 @@ struct UnitWrap::UnitTest::TestDsd2 : public UnitWrap::UnitTest::Base { REQUIRE(grdd[s].logn0r == grdd_host(s).logn0r); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + grdd_host(s).write(fid); + } + } } void run_rain_phys() diff --git a/components/eamxx/src/physics/p3/tests/p3_evaporate_rain_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_evaporate_rain_unit_tests.cpp index 9df3ecdb0c82..c5626e0387cc 100644 --- a/components/eamxx/src/physics/p3/tests/p3_evaporate_rain_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_evaporate_rain_unit_tests.cpp @@ -173,9 +173,13 @@ struct UnitWrap::UnitTest::TestEvapSublPrecip : public UnitWrap::UnitTest: std::copy(&espd[0], &espd[0] + max_pack_size, espd_host.data()); Kokkos::deep_copy(espd_device, espd_host); - // Get data from fortran - for (Int i = 0; i < max_pack_size; ++i) { - evaporate_rain(espd[i]); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/evaporate_rain.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + espd[i].read(fid); + } } // Run the lookup from a kernel and copy results back to host @@ -241,12 +245,18 @@ struct UnitWrap::UnitTest::TestEvapSublPrecip : public UnitWrap::UnitTest: Kokkos::deep_copy(espd_host, espd_device); // Validate results - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int s = 0; s < max_pack_size; ++s) { REQUIRE(espd[s].qr2qv_evap_tend == espd_host(s).qr2qv_evap_tend); REQUIRE(espd[s].nr_evap_tend == espd_host(s).nr_evap_tend); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + espd_host(s).write(fid); + } + } } // end run_bfb diff --git a/components/eamxx/src/physics/p3/tests/p3_get_latent_heat_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_get_latent_heat_unit_tests.cpp deleted file mode 100644 index dfe6f3ca6a49..000000000000 --- a/components/eamxx/src/physics/p3/tests/p3_get_latent_heat_unit_tests.cpp +++ /dev/null @@ -1,79 +0,0 @@ -#include "catch2/catch.hpp" - -#include "share/scream_types.hpp" -#include "ekat/ekat_pack.hpp" -#include "ekat/kokkos/ekat_kokkos_utils.hpp" -#include "p3_functions.hpp" -#include "p3_functions_f90.hpp" -#include "p3_f90.hpp" - -#include "p3_unit_tests_common.hpp" - -#include -#include -#include -#include -#include // std::setprecision - -namespace scream { -namespace p3 { -namespace unit_test { - -template -struct UnitWrap::UnitTest::TestLatentHeat : public UnitWrap::UnitTest::Base { - - void run_latent_heat_bfb() - { - constexpr Scalar latvap = C::LatVap; - constexpr Scalar latice = C::LatIce; - - LatentHeatData latent_fortran[] = { - // its, ite, kts, kte - LatentHeatData(1, 7, 1, 10), - }; - - static constexpr Int num_runs = sizeof(latent_fortran) / sizeof(LatentHeatData); - - LatentHeatData latent_cxx[num_runs] = { - LatentHeatData(latent_fortran[0]), - LatentHeatData(latent_fortran[1]), - LatentHeatData(latent_fortran[2]), - LatentHeatData(latent_fortran[3]), - }; - - for (Int i = 0; i < num_runs; ++i) { - LatentHeatData& h = latent_fortran[i]; - get_latent_heat(h); - - if (SCREAM_BFB_TESTING) { - for (Int j = 0; j < h.total(h.v); ++j) { - REQUIRE(h.v[j] == latvap); - REQUIRE(h.s[j] == (latvap+latice)); - REQUIRE(h.f[j] == latice); - } - } - } - } - - void run_latent_heat_phys() - { - // TODO - } -}; - -} -} -} - -namespace { - -TEST_CASE("p3_latent_heat", "[p3_functions]") -{ - using T = scream::p3::unit_test::UnitWrap::UnitTest::TestLatentHeat; - - T t; - t.run_latent_heat_phys(); - t.run_latent_heat_bfb(); -} - -} From dd7f4539890adea185fb6ef44eb1f51f00e5137c Mon Sep 17 00:00:00 2001 From: James Foucar Date: Fri, 1 Nov 2024 14:55:31 -0600 Subject: [PATCH 023/147] More --- .../p3_ice_cldliq_wet_growth_unit_tests.cpp | 18 ++- .../p3/tests/p3_ice_collection_unit_tests.cpp | 54 +++++-- .../p3_ice_deposition_sublimation_tests.cpp | 77 +++++----- .../p3/tests/p3_ice_melting_unit_tests.cpp | 19 ++- .../p3/tests/p3_ice_nucleation_unit_tests.cpp | 21 ++- ...p3_ice_relaxation_timescale_unit_tests.cpp | 20 ++- .../p3/tests/p3_ice_sed_unit_tests.cpp | 145 +++++++++++------- 7 files changed, 231 insertions(+), 123 deletions(-) diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_cldliq_wet_growth_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_cldliq_wet_growth_unit_tests.cpp index e2a61b374818..5060d9d2fdcb 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_cldliq_wet_growth_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_cldliq_wet_growth_unit_tests.cpp @@ -57,9 +57,13 @@ struct UnitWrap::UnitTest::TestIceCldliqWetGrowth : public UnitWrap::UnitTest std::copy(&self[0], &self[0] + max_pack_size, self_host.data()); Kokkos::deep_copy(self_device, self_host); - // Get data from fortran - for (Int i = 0; i < max_pack_size; ++i) { - ice_cldliq_wet_growth(self[i]); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/ice_cldliq_wet_growth.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + self[i].read(fid); + } } // Run the lookup from a kernel and copy results back to host @@ -114,7 +118,7 @@ struct UnitWrap::UnitTest::TestIceCldliqWetGrowth : public UnitWrap::UnitTest Kokkos::deep_copy(self_host, self_device); - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int s = 0; s < max_pack_size; ++s) { REQUIRE(static_cast(self[s].log_wetgrowth) == static_cast(self_host(s).log_wetgrowth)); @@ -125,6 +129,12 @@ struct UnitWrap::UnitTest::TestIceCldliqWetGrowth : public UnitWrap::UnitTest REQUIRE(self[s].qc2qr_ice_shed_tend == self_host(s).qc2qr_ice_shed_tend); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + self_host(s).write(fid); + } + } } void run_ice_cldliq_wet_growth_phys() diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_collection_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_collection_unit_tests.cpp index 9c628c0641ce..6f34526e9b07 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_collection_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_collection_unit_tests.cpp @@ -63,9 +63,13 @@ struct UnitWrap::UnitTest::TestIceCollection : public UnitWrap::UnitTest:: std::copy(&cldliq[0], &cldliq[0] + max_pack_size, cldliq_host.data()); Kokkos::deep_copy(cldliq_device, cldliq_host); - // Get data from fortran - for (Int i = 0; i < max_pack_size; ++i) { - ice_cldliq_collection(cldliq[i]); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/ice_cldliq_collection.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + cldliq[i].read(fid); + } } // Run the lookup from a kernel and copy results back to host @@ -109,7 +113,7 @@ struct UnitWrap::UnitTest::TestIceCollection : public UnitWrap::UnitTest:: Kokkos::deep_copy(cldliq_host, cldliq_device); // Validate results - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int s = 0; s < max_pack_size; ++s) { REQUIRE(cldliq[s].qc2qi_collect_tend == cldliq_host(s).qc2qi_collect_tend); REQUIRE(cldliq[s].nc_collect_tend == cldliq_host(s).nc_collect_tend); @@ -117,6 +121,12 @@ struct UnitWrap::UnitTest::TestIceCollection : public UnitWrap::UnitTest:: REQUIRE(cldliq[s].ncshdc == cldliq_host(s).ncshdc); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + cldliq_host(s).write(fid); + } + } } void run_ice_cldliq_phys() @@ -157,9 +167,13 @@ struct UnitWrap::UnitTest::TestIceCollection : public UnitWrap::UnitTest:: std::copy(&rain[0], &rain[0] + max_pack_size, rain_host.data()); Kokkos::deep_copy(rain_device, rain_host); - // Get data from fortran - for (Int i = 0; i < max_pack_size; ++i) { - ice_rain_collection(rain[i]); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/ice_rain_collection.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + rain[i].read(fid); + } } // Run the lookup from a kernel and copy results back to host @@ -198,12 +212,18 @@ struct UnitWrap::UnitTest::TestIceCollection : public UnitWrap::UnitTest:: Kokkos::deep_copy(rain_host, rain_device); // Validate results - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int s = 0; s < max_pack_size; ++s) { REQUIRE(rain[s].qr2qi_collect_tend == rain_host(s).qr2qi_collect_tend); REQUIRE(rain[s].nr_collect_tend == rain_host(s).nr_collect_tend); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + rain_host(s).write(fid); + } + } } void run_ice_rain_phys() @@ -244,9 +264,13 @@ struct UnitWrap::UnitTest::TestIceCollection : public UnitWrap::UnitTest:: std::copy(&self[0], &self[0] + max_pack_size, self_host.data()); Kokkos::deep_copy(self_device, self_host); - // Get data from fortran - for (Int i = 0; i < max_pack_size; ++i) { - ice_self_collection(self[i]); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/ice_self_collection.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + self[i].read(fid); + } } // Run the lookup from a kernel and copy results back to host @@ -276,11 +300,17 @@ struct UnitWrap::UnitTest::TestIceCollection : public UnitWrap::UnitTest:: Kokkos::deep_copy(self_host, self_device); - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int s = 0; s < max_pack_size; ++s) { REQUIRE(self[s].ni_selfcollect_tend == self_host(s).ni_selfcollect_tend); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + self_host(s).write(fid); + } + } } void run_ice_self_phys() diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_deposition_sublimation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_deposition_sublimation_tests.cpp index f6afd915dc63..b359ad661e95 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_deposition_sublimation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_deposition_sublimation_tests.cpp @@ -49,7 +49,7 @@ struct UnitWrap::UnitTest::TestIceDepositionSublimation : public UnitWrap::Un void run_bfb() { - IceDepositionSublimationData f90_data[max_pack_size] = { + IceDepositionSublimationData baseline_data[max_pack_size] = { {1.0000E-04,4.5010E+05,2.8750E+02,1.1279E-02,1.1279E-02,0.0000E+00,3.3648E+00,5.0000E-03,1.666667e-02}, {5.1000E-03,4.5370E+05,2.8542E+02,9.9759E-03,9.9759E-03,0.0000E+00,3.1223E+00,5.0000E-03,1.666667e-02}, {5.1000E-03,4.5742E+05,2.8334E+02,8.8076E-03,8.8076E-03,0.0000E+00,2.9014E+00,5.0000E-03,1.666667e-02}, @@ -68,11 +68,9 @@ struct UnitWrap::UnitTest::TestIceDepositionSublimation : public UnitWrap::Un {5.0000E-08,5.4479E+05,2.4793E+02,7.5430E-04,5.8895E-04,4.6769E-04,1.1661E+00,1.5278E-04,1.666667e-02}, }; - static constexpr Int num_runs = sizeof(f90_data) / sizeof(IceDepositionSublimationData); - // Generate random input data - // Alternatively, you can use the f90_data construtors/initializer lists to hardcode data - //for (auto& d : f90_data) { + // Alternatively, you can use the baseline_data construtors/initializer lists to hardcode data + //for (auto& d : baseline_data) { // d.randomize(); //} @@ -80,12 +78,16 @@ struct UnitWrap::UnitTest::TestIceDepositionSublimation : public UnitWrap::Un // inout data is in original state view_1d cxx_device("cxx_device", max_pack_size); const auto cxx_host = Kokkos::create_mirror_view(cxx_device); - std::copy(&f90_data[0], &f90_data[0] + max_pack_size, cxx_host.data()); + std::copy(&baseline_data[0], &baseline_data[0] + max_pack_size, cxx_host.data()); Kokkos::deep_copy(cxx_device, cxx_host); - // Get data from fortran - for (auto& d : f90_data) { - ice_deposition_sublimation(d); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/ice_deposition_sublimation.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + baseline_data[i].read(fid); + } } // Get data from cxx. Run ice_deposition_sublimation from a kernel and copy results back to host @@ -110,7 +112,6 @@ struct UnitWrap::UnitTest::TestIceDepositionSublimation : public UnitWrap::Un // Init outputs Spack ni_sublim_tend(0), qi2qv_sublim_tend(0), qc2qi_berg_tend(0), qv2qi_vapdep_tend(0); - Functions::ice_deposition_sublimation(qi_incld, ni_incld, T_atm, qv_sat_l, qv_sat_i, epsi, abi, qv, inv_dt, qv2qi_vapdep_tend, qi2qv_sublim_tend, ni_sublim_tend, qc2qi_berg_tend); // Copy spacks back into cxx_device view @@ -120,35 +121,41 @@ struct UnitWrap::UnitTest::TestIceDepositionSublimation : public UnitWrap::Un cxx_device(vs).qc2qi_berg_tend = qc2qi_berg_tend[s]; cxx_device(vs).qv2qi_vapdep_tend = qv2qi_vapdep_tend[s]; } - }); Kokkos::deep_copy(cxx_host, cxx_device); - for (Int i = 0; i < num_runs; ++i) { - // Verify BFB results - IceDepositionSublimationData& d_f90 = f90_data[i]; - IceDepositionSublimationData& d_cxx = cxx_host[i]; - REQUIRE(d_f90.qv2qi_vapdep_tend == d_cxx.qv2qi_vapdep_tend); - REQUIRE(d_f90.qi2qv_sublim_tend == d_cxx.qi2qv_sublim_tend); - REQUIRE(d_f90.ni_sublim_tend == d_cxx.ni_sublim_tend); - REQUIRE(d_f90.qc2qi_berg_tend == d_cxx.qc2qi_berg_tend); - - //MAKE SURE OUTPUT IS WITHIN EXPECTED BOUNDS: - REQUIRE(d_cxx.qv2qi_vapdep_tend >=0); - REQUIRE(d_cxx.qi2qv_sublim_tend >=0); - REQUIRE(d_cxx.ni_sublim_tend >=0); - REQUIRE(d_cxx.qc2qi_berg_tend >=0); - - //vapdep should only occur when qv>qv_sat_i - REQUIRE( (d_cxx.qv2qi_vapdep_tend==0 || d_cxx.qv + d_cxx.qv2qi_vapdep_tend*d_cxx.inv_dt >= d_cxx.qv_sat_i) ); - //sublim should only occur when qvfrz, berg and vapdep should be 0: - REQUIRE( (d_cxx.T_atmm_baseline_action == COMPARE) { + for (Int i = 0; i < max_pack_size; ++i) { + // Verify BFB results + IceDepositionSublimationData& d_f90 = baseline_data[i]; + IceDepositionSublimationData& d_cxx = cxx_host[i]; + REQUIRE(d_f90.qv2qi_vapdep_tend == d_cxx.qv2qi_vapdep_tend); + REQUIRE(d_f90.qi2qv_sublim_tend == d_cxx.qi2qv_sublim_tend); + REQUIRE(d_f90.ni_sublim_tend == d_cxx.ni_sublim_tend); + REQUIRE(d_f90.qc2qi_berg_tend == d_cxx.qc2qi_berg_tend); + + //MAKE SURE OUTPUT IS WITHIN EXPECTED BOUNDS: + REQUIRE(d_cxx.qv2qi_vapdep_tend >=0); + REQUIRE(d_cxx.qi2qv_sublim_tend >=0); + REQUIRE(d_cxx.ni_sublim_tend >=0); + REQUIRE(d_cxx.qc2qi_berg_tend >=0); + + //vapdep should only occur when qv>qv_sat_i + REQUIRE( (d_cxx.qv2qi_vapdep_tend==0 || d_cxx.qv + d_cxx.qv2qi_vapdep_tend*d_cxx.inv_dt >= d_cxx.qv_sat_i) ); + //sublim should only occur when qvfrz, berg and vapdep should be 0: + REQUIRE( (d_cxx.T_atmm_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + cxx_host(s).write(fid); + } } } // run_bfb diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_melting_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_melting_unit_tests.cpp index 5e29579a9107..86c42707c1eb 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_melting_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_melting_unit_tests.cpp @@ -57,9 +57,13 @@ void ice_melting_bfb() { std::copy(&IceMelt[0], &IceMelt[0] + max_pack_size, IceMelt_host.data()); Kokkos::deep_copy(IceMelt_device, IceMelt_host); - // Get data from fortran - for (Int i = 0; i < max_pack_size; ++i) { - ice_melting(IceMelt[i]); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/ice_melting.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + IceMelt[i].read(fid); + } } // Run the lookup from a kernel and copy results back to host @@ -99,12 +103,19 @@ void ice_melting_bfb() { Kokkos::deep_copy(IceMelt_host, IceMelt_device); // Validate results - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int s = 0; s < max_pack_size; ++s) { REQUIRE(IceMelt[s].qi2qr_melt_tend == IceMelt_host(s).qi2qr_melt_tend); REQUIRE(IceMelt[s].ni2nr_melt_tend == IceMelt_host(s).ni2nr_melt_tend); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + IceMelt_host(s).write(fid); + } + } + } }; // UnitWrap diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_nucleation_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_nucleation_unit_tests.cpp index 51ab5031c45f..154adbabb15e 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_nucleation_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_nucleation_unit_tests.cpp @@ -54,10 +54,15 @@ struct UnitWrap::UnitTest::TestIceNucleation : public UnitWrap::UnitTest:: {2.702E+02, 1.069E+00, 0.323E+03, 2.221E+01, 9.952E-01, inv_dt, do_predict_nc, do_prescribed_CCN } }; - // Run the fortran code - for (Int i = 0; i < max_pack_size; ++i) { - ice_nucleation(self[i]); - } + std::string root_name = "ice_nucleation"; + std::string file_name = root_name + (do_predict_nc ? "1" : "0") + (do_prescribed_CCN ? "1" : "0"); + std::string baseline_name = this->m_baseline_path + "/" + file_name + ".dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + self[i].read(fid); + } + } // Sync to device KTH::view_1d self_host("self_host", max_pack_size); @@ -94,12 +99,18 @@ struct UnitWrap::UnitTest::TestIceNucleation : public UnitWrap::UnitTest:: Kokkos::deep_copy(self_host, self_device); - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int s = 0; s < max_pack_size; ++s) { REQUIRE(self[s].qv2qi_nucleat_tend == self_host(s).qv2qi_nucleat_tend); REQUIRE(self[s].ni_nucleat_tend == self_host(s).ni_nucleat_tend); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + self_host(s).write(fid); + } + } } //end for do_predict_nc } //end for do_prescribed_CCN } diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_relaxation_timescale_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_relaxation_timescale_unit_tests.cpp index dfb668bc81d8..7015b7a94f8a 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_relaxation_timescale_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_relaxation_timescale_unit_tests.cpp @@ -49,10 +49,14 @@ struct UnitWrap::UnitTest::TestIceRelaxationTimescale : public UnitWrap::Unit {1.352E+01, 3.210E+03, 1.069E+00, 0.123E+00, 3.456E+00, 1.221E-02, 9.952E-07, 6.596E-05, 4.532E-01, 1.734E+04} }; - // Get data from fortran - for (Int i = 0; i < max_pack_size; ++i) { - ice_relaxation_timescale(self[i]); - } + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/ice_relaxation_timescale.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + self[i].read(fid); + } + } // Sync to device KTH::view_1d self_host("self_host", max_pack_size); @@ -93,12 +97,18 @@ struct UnitWrap::UnitTest::TestIceRelaxationTimescale : public UnitWrap::Unit Kokkos::deep_copy(self_host, self_device); - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int s = 0; s < max_pack_size; ++s) { REQUIRE(self[s].epsi == self_host(s).epsi); REQUIRE(self[s].epsi_tot == self_host(s).epsi_tot); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + self_host(s).write(fid); + } + } } void run_ice_relaxation_timescale_phys() diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp index 86ff76e91690..3afcc6af92b5 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp @@ -48,7 +48,7 @@ void run_bfb_calc_bulk_rhime() constexpr Scalar qsmall = C::QSMALL; // Load some lookup inputs, need at least one per pack value - CalcBulkRhoRimeData cbrr_fortran[max_pack_size] = { + CalcBulkRhoRimeData cbrr_baseline[max_pack_size] = { // qi_tot, qi_rim, bi_rim {9.999978E-08, 9.999978E-03, 1.111108E-10}, {0.000000E+00, 8.571428E-05, 1.000000E-02}, @@ -75,13 +75,15 @@ void run_bfb_calc_bulk_rhime() // inout data is in original state view_1d cbrr_device("cbrr", max_pack_size); const auto cbrr_host = Kokkos::create_mirror_view(cbrr_device); - std::copy(&cbrr_fortran[0], &cbrr_fortran[0] + max_pack_size, cbrr_host.data()); + std::copy(&cbrr_baseline[0], &cbrr_baseline[0] + max_pack_size, cbrr_host.data()); Kokkos::deep_copy(cbrr_device, cbrr_host); - // Get data from fortran - for (Int i = 0; i < max_pack_size; ++i) { - if (cbrr_fortran[i].qi_tot > qsmall) { - calc_bulk_rho_rime(cbrr_fortran[i]); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/calc_bulk_rho_rime.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + cbrr_baseline[i].read(fid); } } @@ -114,20 +116,26 @@ void run_bfb_calc_bulk_rhime() Kokkos::deep_copy(cbrr_host, cbrr_device); // Validate results - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int s = 0; s < max_pack_size; ++s) { - REQUIRE(cbrr_fortran[s].qi_rim == cbrr_host(s).qi_rim); - REQUIRE(cbrr_fortran[s].bi_rim == cbrr_host(s).bi_rim); - REQUIRE(cbrr_fortran[s].rho_rime == cbrr_host(s).rho_rime); + REQUIRE(cbrr_baseline[s].qi_rim == cbrr_host(s).qi_rim); + REQUIRE(cbrr_baseline[s].bi_rim == cbrr_host(s).bi_rim); + REQUIRE(cbrr_baseline[s].rho_rime == cbrr_host(s).rho_rime); + } + } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + cbrr_host(s).write(fid); } } } void run_bfb_ice_sed() { - auto engine = setup_random_test(); + auto engine = setup_random_test(124135); - IceSedData isds_fortran[] = { + IceSedData isds_baseline[] = { // kts, kte, ktop, kbot, kdir, dt, inv_dt, precip_ice_surf IceSedData(1, 72, 27, 72, -1, 1.800E+03, 5.556E-04, 0.0), IceSedData(1, 72, 72, 27, 1, 1.800E+03, 5.556E-04, 1.0), @@ -135,25 +143,29 @@ void run_bfb_ice_sed() IceSedData(1, 72, 27, 27, 1, 1.800E+03, 5.556E-04, 2.0), }; - static constexpr Int num_runs = sizeof(isds_fortran) / sizeof(IceSedData); + static constexpr Int num_runs = sizeof(isds_baseline) / sizeof(IceSedData); // Set up random input data - for (auto& d : isds_fortran) { + for (auto& d : isds_baseline) { d.randomize(engine, { {d.qi_incld, {C::QSMALL/2, C::QSMALL*2}} }); } // Create copies of data for use by cxx. Needs to happen before fortran calls so that // inout data is in original state IceSedData isds_cxx[num_runs] = { - IceSedData(isds_fortran[0]), - IceSedData(isds_fortran[1]), - IceSedData(isds_fortran[2]), - IceSedData(isds_fortran[3]), + IceSedData(isds_baseline[0]), + IceSedData(isds_baseline[1]), + IceSedData(isds_baseline[2]), + IceSedData(isds_baseline[3]), }; - // Get data from fortran - for (auto& d : isds_fortran) { - ice_sedimentation(d); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/ice_sedimentation.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < num_runs; ++i) { + isds_baseline[i].read(fid); + } } // Get data from cxx @@ -165,24 +177,30 @@ void run_bfb_ice_sed() d.ni_incld, &d.precip_ice_surf, d.qi_tend, d.ni_tend); } - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int i = 0; i < num_runs; ++i) { // Due to pack issues, we must restrict checks to the active k space - Int start = std::min(isds_fortran[i].kbot, isds_fortran[i].ktop) - 1; // 0-based indx - Int end = std::max(isds_fortran[i].kbot, isds_fortran[i].ktop); // 0-based indx + Int start = std::min(isds_baseline[i].kbot, isds_baseline[i].ktop) - 1; // 0-based indx + Int end = std::max(isds_baseline[i].kbot, isds_baseline[i].ktop); // 0-based indx for (Int k = start; k < end; ++k) { - REQUIRE(isds_fortran[i].qi[k] == isds_cxx[i].qi[k]); - REQUIRE(isds_fortran[i].qi_incld[k] == isds_cxx[i].qi_incld[k]); - REQUIRE(isds_fortran[i].ni[k] == isds_cxx[i].ni[k]); - REQUIRE(isds_fortran[i].ni_incld[k] == isds_cxx[i].ni_incld[k]); - REQUIRE(isds_fortran[i].qm[k] == isds_cxx[i].qm[k]); - REQUIRE(isds_fortran[i].qm_incld[k] == isds_cxx[i].qm_incld[k]); - REQUIRE(isds_fortran[i].bm[k] == isds_cxx[i].bm[k]); - REQUIRE(isds_fortran[i].bm_incld[k] == isds_cxx[i].bm_incld[k]); - REQUIRE(isds_fortran[i].qi_tend[k] == isds_cxx[i].qi_tend[k]); - REQUIRE(isds_fortran[i].ni_tend[k] == isds_cxx[i].ni_tend[k]); + REQUIRE(isds_baseline[i].qi[k] == isds_cxx[i].qi[k]); + REQUIRE(isds_baseline[i].qi_incld[k] == isds_cxx[i].qi_incld[k]); + REQUIRE(isds_baseline[i].ni[k] == isds_cxx[i].ni[k]); + REQUIRE(isds_baseline[i].ni_incld[k] == isds_cxx[i].ni_incld[k]); + REQUIRE(isds_baseline[i].qm[k] == isds_cxx[i].qm[k]); + REQUIRE(isds_baseline[i].qm_incld[k] == isds_cxx[i].qm_incld[k]); + REQUIRE(isds_baseline[i].bm[k] == isds_cxx[i].bm[k]); + REQUIRE(isds_baseline[i].bm_incld[k] == isds_cxx[i].bm_incld[k]); + REQUIRE(isds_baseline[i].qi_tend[k] == isds_cxx[i].qi_tend[k]); + REQUIRE(isds_baseline[i].ni_tend[k] == isds_cxx[i].ni_tend[k]); } - REQUIRE(isds_fortran[i].precip_ice_surf == isds_cxx[i].precip_ice_surf); + REQUIRE(isds_baseline[i].precip_ice_surf == isds_cxx[i].precip_ice_surf); + } + } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int i = 0; i < num_runs; ++i) { + isds_cxx[i].write(fid); } } } @@ -191,9 +209,9 @@ void run_bfb_homogeneous_freezing() { constexpr Scalar latice = C::LatIce; - auto engine = setup_random_test(); + auto engine = setup_random_test(13543563); - HomogeneousFreezingData hfds_fortran[] = { + HomogeneousFreezingData hfds_baseline[] = { // kts, kte, ktop, kbot, kdir HomogeneousFreezingData(1, 72, 27, 72, -1), HomogeneousFreezingData(1, 72, 72, 27, 1), @@ -201,10 +219,10 @@ void run_bfb_homogeneous_freezing() HomogeneousFreezingData(1, 72, 27, 27, 1), }; - static constexpr Int num_runs = sizeof(hfds_fortran) / sizeof(HomogeneousFreezingData); + static constexpr Int num_runs = sizeof(hfds_baseline) / sizeof(HomogeneousFreezingData); // Set up random input data - for (auto& d : hfds_fortran) { + for (auto& d : hfds_baseline) { const auto qsmall_r = std::make_pair(C::QSMALL/2, C::QSMALL*2); d.randomize(engine, { {d.T_atm, {C::T_homogfrz - 10, C::T_homogfrz + 10}}, {d.qc, qsmall_r}, {d.qr, qsmall_r} }); @@ -218,15 +236,19 @@ void run_bfb_homogeneous_freezing() // Create copies of data for use by cxx. Needs to happen before fortran calls so that // inout data is in original state HomogeneousFreezingData hfds_cxx[num_runs] = { - HomogeneousFreezingData(hfds_fortran[0]), - HomogeneousFreezingData(hfds_fortran[1]), - HomogeneousFreezingData(hfds_fortran[2]), - HomogeneousFreezingData(hfds_fortran[3]), + HomogeneousFreezingData(hfds_baseline[0]), + HomogeneousFreezingData(hfds_baseline[1]), + HomogeneousFreezingData(hfds_baseline[2]), + HomogeneousFreezingData(hfds_baseline[3]), }; - // Get data from fortran - for (auto& d : hfds_fortran) { - homogeneous_freezing(d); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/homogeneous_freezing.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (auto& d : hfds_baseline) { + d.read(fid); + } } // Get data from cxx @@ -236,24 +258,31 @@ void run_bfb_homogeneous_freezing() d.qc, d.nc, d.qr, d.nr, d.qi, d.ni, d.qm, d.bm, d.th_atm); } - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int i = 0; i < num_runs; ++i) { // Due to pack issues, we must restrict checks to the active k space - Int start = std::min(hfds_fortran[i].kbot, hfds_fortran[i].ktop) - 1; // 0-based indx - Int end = std::max(hfds_fortran[i].kbot, hfds_fortran[i].ktop); // 0-based indx + Int start = std::min(hfds_baseline[i].kbot, hfds_baseline[i].ktop) - 1; // 0-based indx + Int end = std::max(hfds_baseline[i].kbot, hfds_baseline[i].ktop); // 0-based indx for (Int k = start; k < end; ++k) { - REQUIRE(hfds_fortran[i].qc[k] == hfds_cxx[i].qc[k]); - REQUIRE(hfds_fortran[i].nc[k] == hfds_cxx[i].nc[k]); - REQUIRE(hfds_fortran[i].qr[k] == hfds_cxx[i].qr[k]); - REQUIRE(hfds_fortran[i].nr[k] == hfds_cxx[i].nr[k]); - REQUIRE(hfds_fortran[i].qi[k] == hfds_cxx[i].qi[k]); - REQUIRE(hfds_fortran[i].ni[k] == hfds_cxx[i].ni[k]); - REQUIRE(hfds_fortran[i].qm[k] == hfds_cxx[i].qm[k]); - REQUIRE(hfds_fortran[i].bm[k] == hfds_cxx[i].bm[k]); - REQUIRE(hfds_fortran[i].th_atm[k] == hfds_cxx[i].th_atm[k]); + REQUIRE(hfds_baseline[i].qc[k] == hfds_cxx[i].qc[k]); + REQUIRE(hfds_baseline[i].nc[k] == hfds_cxx[i].nc[k]); + REQUIRE(hfds_baseline[i].qr[k] == hfds_cxx[i].qr[k]); + REQUIRE(hfds_baseline[i].nr[k] == hfds_cxx[i].nr[k]); + REQUIRE(hfds_baseline[i].qi[k] == hfds_cxx[i].qi[k]); + REQUIRE(hfds_baseline[i].ni[k] == hfds_cxx[i].ni[k]); + REQUIRE(hfds_baseline[i].qm[k] == hfds_cxx[i].qm[k]); + REQUIRE(hfds_baseline[i].bm[k] == hfds_cxx[i].bm[k]); + REQUIRE(hfds_baseline[i].th_atm[k] == hfds_cxx[i].th_atm[k]); } } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int i = 0; i < num_runs; ++i) { + hfds_cxx[i].write(fid); + } + } + } void run_bfb() From 343c6d6d789888a7581ec57a87710a67682302c4 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Fri, 1 Nov 2024 16:07:46 -0600 Subject: [PATCH 024/147] More --- .../eamxx/src/physics/p3/p3_functions_f90.cpp | 6 +- .../eamxx/src/physics/p3/p3_functions_f90.hpp | 13 +- .../p3_ice_supersat_conservation_tests.cpp | 33 +- .../p3/tests/p3_ice_tables_unit_tests.cpp | 60 ++- .../p3_incloud_mixingratios_unit_tests.cpp | 18 +- .../physics/p3/tests/p3_main_unit_tests.cpp | 374 ++++++++++-------- 6 files changed, 296 insertions(+), 208 deletions(-) diff --git a/components/eamxx/src/physics/p3/p3_functions_f90.cpp b/components/eamxx/src/physics/p3/p3_functions_f90.cpp index 6b027935801c..b5e051a4d112 100644 --- a/components/eamxx/src/physics/p3/p3_functions_f90.cpp +++ b/components/eamxx/src/physics/p3/p3_functions_f90.cpp @@ -701,7 +701,7 @@ void compute_rain_fall_velocity(ComputeRainFallVelocityData& d) P3MainPart1Data::P3MainPart1Data( Int kts_, Int kte_, Int kbot_, Int ktop_, Int kdir_, - bool do_predict_nc_, bool do_prescribed_CCN_, Real dt_) : + bool do_predict_nc_, bool do_prescribed_CCN_, Real dt_, bool, bool) : PhysicsTestData( { {(kte_ - kts_) + 1} }, { { &pres, &dpres, &dz, &nc_nuceat_tend, &inv_exner, &exner, &inv_cld_frac_l, &inv_cld_frac_i, &inv_cld_frac_r, &latent_heat_vapor, &latent_heat_sublim, &latent_heat_fusion, &nccn_prescribed, &T_atm, &rho, &inv_rho, &qv_sat_l, &qv_sat_i, &qv_supersat_i, &rhofacr, &rhofaci, @@ -730,7 +730,7 @@ void p3_main_part1(P3MainPart1Data& d) P3MainPart2Data::P3MainPart2Data( Int kts_, Int kte_, Int kbot_, Int ktop_, Int kdir_, - bool do_predict_nc_, bool do_prescribed_CCN_, Real dt_) : + bool do_predict_nc_, bool do_prescribed_CCN_, Real dt_, Real, bool) : PhysicsTestData( { {(kte_ - kts_) + 1} }, { { &pres, &dpres, &dz, &nc_nuceat_tend, &inv_exner, &exner, &inv_cld_frac_l, &inv_cld_frac_i, &inv_cld_frac_r, &ni_activated, &inv_qc_relvar, &cld_frac_i, &cld_frac_l, &cld_frac_r, &qv_prev, &t_prev, &T_atm, &rho, &inv_rho, &qv_sat_l, &qv_sat_i, &qv_supersat_i, &rhofacr, &rhofaci, &acn, @@ -785,7 +785,7 @@ void p3_main_part3(P3MainPart3Data& d) /////////////////////////////////////////////////////////////////////////////// P3MainData::P3MainData( - Int its_, Int ite_, Int kts_, Int kte_, Int it_, Real dt_, bool do_predict_nc_, bool do_prescribed_CCN_) : + Int its_, Int ite_, Int kts_, Int kte_, Int it_, Real dt_, bool do_predict_nc_, bool do_prescribed_CCN_, Real) : PhysicsTestData( { {(ite_ - its_) + 1, (kte_ - kts_) + 1}, {(ite_ - its_) + 1, (kte_ - kts_) + 2} }, { { &pres, &dz, &nc_nuceat_tend, &nccn_prescribed, &ni_activated, &dpres, &inv_exner, &cld_frac_i, &cld_frac_l, &cld_frac_r, &inv_qc_relvar, &qc, &nc, &qr, &nr, &qi, &qm, &ni, &bm, &qv, &th_atm, &qv_prev, &t_prev, diff --git a/components/eamxx/src/physics/p3/p3_functions_f90.hpp b/components/eamxx/src/physics/p3/p3_functions_f90.hpp index 40b92fe47b61..881356f3d9b5 100644 --- a/components/eamxx/src/physics/p3/p3_functions_f90.hpp +++ b/components/eamxx/src/physics/p3/p3_functions_f90.hpp @@ -733,9 +733,9 @@ struct P3MainPart1Data : public PhysicsTestData bool is_nucleat_possible, is_hydromet_present; P3MainPart1Data(Int kts_, Int kte_, Int kbot_, Int ktop_, Int kdir_, - bool do_predict_nc_, bool do_prescribed_CCN_, Real dt_); + bool do_predict_nc_, bool do_prescribed_CCN_, Real dt_, bool=false, bool=false); - PTD_STD_DEF(P3MainPart1Data, 8, kts, kte, kbot, ktop, kdir, do_predict_nc, do_prescribed_CCN, dt); + PTD_STD_DEF(P3MainPart1Data, 10, kts, kte, kbot, ktop, kdir, do_predict_nc, do_prescribed_CCN, dt, is_nucleat_possible, is_hydromet_present); Int nk() const { return (kte - kts) + 1; } }; @@ -762,10 +762,9 @@ struct P3MainPart2Data : public PhysicsTestData bool is_hydromet_present; P3MainPart2Data(Int kts_, Int kte_, Int kbot_, Int ktop_, Int kdir_, - bool do_predict_nc_, bool do_prescribed_CCN, Real dt_); + bool do_predict_nc_, bool do_prescribed_CCN, Real dt_, Real=0., bool=false); - PTD_DATA_COPY_CTOR(P3MainPart2Data, 8); - PTD_ASSIGN_OP(P3MainPart2Data, 10, kts, kte, kbot, ktop, kdir, do_predict_nc, do_prescribed_CCN, dt, inv_dt, is_hydromet_present); + PTD_STD_DEF(P3MainPart2Data, 10, kts, kte, kbot, ktop, kdir, do_predict_nc, do_prescribed_CCN, dt, inv_dt, is_hydromet_present); Int nk() const { return (kte - kts) + 1; } }; @@ -817,9 +816,9 @@ struct P3MainData : public PhysicsTestData *precip_liq_flux, *precip_ice_flux, *precip_liq_surf, *precip_ice_surf; Real elapsed_s; - P3MainData(Int its_, Int ite_, Int kts_, Int kte_, Int it_, Real dt_, bool do_predict_nc_, bool do_prescribed_CCN_); + P3MainData(Int its_, Int ite_, Int kts_, Int kte_, Int it_, Real dt_, bool do_predict_nc_, bool do_prescribed_CCN_, Real=0.); - PTD_STD_DEF(P3MainData, 8, its, ite, kts, kte, it, dt, do_predict_nc, do_prescribed_CCN); + PTD_STD_DEF(P3MainData, 9, its, ite, kts, kte, it, dt, do_predict_nc, do_prescribed_CCN, elapsed_s); }; struct IceSupersatConservationData { diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp index 3c8121cdf3c5..e71463f1e257 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp @@ -21,15 +21,15 @@ struct UnitWrap::UnitTest::TestIceSupersatConservation : public UnitWrap::Uni constexpr Scalar latvap = C::LatVap; constexpr Scalar latice = C::LatIce; - auto engine = setup_random_test(); + auto engine = setup_random_test(124151); - IceSupersatConservationData f90_data[max_pack_size]; + IceSupersatConservationData baseline_data[max_pack_size]; // Generate random input data - // Alternatively, you can use the f90_data construtors/initializer lists to hardcode data - for (auto& d : f90_data) { + // Alternatively, you can use the baseline_data construtors/initializer lists to hardcode data + for (auto& d : baseline_data) { d.randomize(engine); - d.dt = f90_data[0].dt; // hold this fixed, it is not packed data + d.dt = baseline_data[0].dt; // hold this fixed, it is not packed data // C++ impl uses constants for latent_heat values. Manually set here // so F90 can match @@ -40,12 +40,16 @@ struct UnitWrap::UnitTest::TestIceSupersatConservation : public UnitWrap::Uni // inout data is in original state view_1d cxx_device("cxx_device", max_pack_size); const auto cxx_host = Kokkos::create_mirror_view(cxx_device); - std::copy(&f90_data[0], &f90_data[0] + max_pack_size, cxx_host.data()); + std::copy(&baseline_data[0], &baseline_data[0] + max_pack_size, cxx_host.data()); Kokkos::deep_copy(cxx_device, cxx_host); - // Get data from fortran - for (auto& d : f90_data) { - ice_supersat_conservation(d); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/ice_supersat_conservation.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + baseline_data[i].read(fid); + } } // Get data from cxx. Run ice_supersat_conservation from a kernel and copy results back to host @@ -72,20 +76,25 @@ struct UnitWrap::UnitTest::TestIceSupersatConservation : public UnitWrap::Uni cxx_device(vs).qidep = qidep[s]; cxx_device(vs).qinuc = qinuc[s]; } - }); Kokkos::deep_copy(cxx_host, cxx_device); // Verify BFB results - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - IceSupersatConservationData& d_f90 = f90_data[i]; + IceSupersatConservationData& d_f90 = baseline_data[i]; IceSupersatConservationData& d_cxx = cxx_host[i]; REQUIRE(d_f90.qidep == d_cxx.qidep); REQUIRE(d_f90.qinuc == d_cxx.qinuc); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + cxx_host(s).write(fid); + } + } } // run_bfb }; diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_tables_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_tables_unit_tests.cpp index 0b171b0a7ff7..98f617668608 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_tables_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_tables_unit_tests.cpp @@ -199,14 +199,6 @@ struct UnitWrap::UnitTest::TestTableIce : public UnitWrap::UnitTest::Base {lid[15], lidb[15], access_table_index} }; - // Get data from fortran - for (Int i = 0; i < max_pack_size; ++i) { - find_lookuptable_indices_1a(lid[i]); - find_lookuptable_indices_1b(lidb[i]); - access_lookup_table(altd[i]); - access_lookup_table_coll(altcd[i]); - } - // Sync to device KTH::view_1d lid_host("lid_host", max_pack_size); KTH::view_1d lidb_host("lidb_host", max_pack_size); @@ -217,6 +209,18 @@ struct UnitWrap::UnitTest::TestTableIce : public UnitWrap::UnitTest::Base Kokkos::deep_copy(lid_device, lid_host); Kokkos::deep_copy(lidb_device, lidb_host); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/p3_ice_tables_all.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + lid[i].read(fid); + lidb[i].read(fid); + altd[i].read(fid); + altcd[i].read(fid); + } + } + // Run the lookup from a kernel and copy results back to host view_2d int_results("int results", 5, max_pack_size); view_2d real_results("real results", 7, max_pack_size); @@ -270,15 +274,14 @@ struct UnitWrap::UnitTest::TestTableIce : public UnitWrap::UnitTest::Base Kokkos::deep_copy(real_results_mirror, real_results); // Validate results - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for(int s = 0; s < max_pack_size; ++s) { - // +1 for O vs 1-based indexing - REQUIRE(int_results_mirror(0, s)+1 == lid[s].dumi); - REQUIRE(int_results_mirror(1, s)+1 == lid[s].dumjj); - REQUIRE(int_results_mirror(2, s)+1 == lid[s].dumii); - REQUIRE(int_results_mirror(3, s)+1 == lid[s].dumzz); + REQUIRE(int_results_mirror(0, s) == lid[s].dumi); + REQUIRE(int_results_mirror(1, s) == lid[s].dumjj); + REQUIRE(int_results_mirror(2, s) == lid[s].dumii); + REQUIRE(int_results_mirror(3, s) == lid[s].dumzz); - REQUIRE(int_results_mirror(4, s)+1 == lidb[s].dumj); + REQUIRE(int_results_mirror(4, s) == lidb[s].dumj); REQUIRE(real_results_mirror(0, s) == lid[s].dum1); REQUIRE(real_results_mirror(1, s) == lid[s].dum4); @@ -292,6 +295,33 @@ struct UnitWrap::UnitTest::TestTableIce : public UnitWrap::UnitTest::Base REQUIRE(real_results_mirror(6, s) == altcd[s].proc); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + lid[s].dumi = int_results_mirror(0, s); + lid[s].dumjj = int_results_mirror(1, s); + lid[s].dumii = int_results_mirror(2, s); + lid[s].dumzz = int_results_mirror(3, s); + + lidb[s].dumj = int_results_mirror(4, s); + + lid[s].dum1 = real_results_mirror(0, s); + lid[s].dum4 = real_results_mirror(1, s); + lid[s].dum5 = real_results_mirror(2, s); + lid[s].dum6 = real_results_mirror(3, s); + + lidb[s].dum3 = real_results_mirror(4, s); + + altd[s].proc = real_results_mirror(5, s); + + altcd[s].proc = real_results_mirror(6, s); + + lid[s].write(fid); + lidb[s].write(fid); + altd[s].write(fid); + altcd[s].write(fid); + } + } } void run_phys() diff --git a/components/eamxx/src/physics/p3/tests/p3_incloud_mixingratios_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_incloud_mixingratios_unit_tests.cpp index a75bdbd17285..fd768e708392 100644 --- a/components/eamxx/src/physics/p3/tests/p3_incloud_mixingratios_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_incloud_mixingratios_unit_tests.cpp @@ -69,9 +69,13 @@ struct UnitWrap::UnitTest::TestIncloudMixing : public UnitWrap::UnitTest:: std::copy(&self[0], &self[0] + max_pack_size, self_host.data()); Kokkos::deep_copy(self_device, self_host); - // Get data from fortran - for (Int i = 0; i < max_pack_size; ++i) { - calculate_incloud_mixingratios(self[i]); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/calculate_incloud_mixingratios.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + self[i].read(fid); + } } // Run the lookup from a kernel and copy results back to host @@ -115,7 +119,7 @@ struct UnitWrap::UnitTest::TestIncloudMixing : public UnitWrap::UnitTest:: Kokkos::deep_copy(self_host, self_device); - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int s = 0; s < max_pack_size; ++s) { REQUIRE(self[s].qc_incld == self_host(s).qc_incld); REQUIRE(self[s].qr_incld == self_host(s).qr_incld); @@ -127,6 +131,12 @@ struct UnitWrap::UnitTest::TestIncloudMixing : public UnitWrap::UnitTest:: REQUIRE(self[s].bm_incld == self_host(s).bm_incld); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + self_host(s).write(fid); + } + } } void run_incloud_mixing_phys() diff --git a/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp index 35089c0e7f9b..62a7e19dddb5 100644 --- a/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp @@ -51,7 +51,7 @@ void run_phys() void run_bfb_p3_main_part1() { - auto engine = setup_random_test(); + auto engine = setup_random_test(125125); constexpr Scalar qsmall = C::QSMALL; //PMC wouldn't it make more sense to define qsmall at a higher level since used in part1, part2, and part3? constexpr Scalar T_zerodegc = C::T_zerodegc; @@ -60,7 +60,7 @@ void run_bfb_p3_main_part1() constexpr Scalar latvap = C::LatVap; constexpr Scalar latice = C::LatIce; - P3MainPart1Data isds_fortran[] = { + P3MainPart1Data isds_baseline[] = { // kts, kte, ktop, kbot, kdir, do_predict_nc, do_prescribed_CCN, dt P3MainPart1Data(1, 72, 1, 72, 1, false, true, 1.800E+03), P3MainPart1Data(1, 72, 1, 72, 1, true, true, 1.800E+03), @@ -68,9 +68,9 @@ void run_bfb_p3_main_part1() P3MainPart1Data(1, 72, 72, 1, -1, true, false, 1.800E+03), }; - static constexpr Int num_runs = sizeof(isds_fortran) / sizeof(P3MainPart1Data); + static constexpr Int num_runs = sizeof(isds_baseline) / sizeof(P3MainPart1Data); - for (auto& d : isds_fortran) { + for (auto& d : isds_baseline) { const auto qsmall_r = std::make_pair(0, qsmall*2); //PMC this range seems inappropriately small d.randomize(engine, { {d.T_atm, {T_zerodegc - 10, T_zerodegc + 10}}, @@ -86,18 +86,22 @@ void run_bfb_p3_main_part1() } } - // Create copies of data for use by cxx. Needs to happen before fortran calls so that + // Create copies of data for use by cxx. Needs to happen before reads so that // inout data is in original state P3MainPart1Data isds_cxx[num_runs] = { - P3MainPart1Data(isds_fortran[0]), - P3MainPart1Data(isds_fortran[1]), - P3MainPart1Data(isds_fortran[2]), - P3MainPart1Data(isds_fortran[3]), + P3MainPart1Data(isds_baseline[0]), + P3MainPart1Data(isds_baseline[1]), + P3MainPart1Data(isds_baseline[2]), + P3MainPart1Data(isds_baseline[3]), }; - // Get data from fortran - for (auto& d : isds_fortran) { - p3_main_part1(d); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/p3_main_part1.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (auto& d : isds_baseline) { + d.read(fid); + } } // Get data from cxx @@ -111,48 +115,54 @@ void run_bfb_p3_main_part1() &d.is_nucleat_possible, &d.is_hydromet_present); } - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int i = 0; i < num_runs; ++i) { - Int start = std::min(isds_fortran[i].kbot, isds_fortran[i].ktop) - 1; // 0-based indx - Int end = std::max(isds_fortran[i].kbot, isds_fortran[i].ktop); // 0-based indx + Int start = std::min(isds_baseline[i].kbot, isds_baseline[i].ktop) - 1; // 0-based indx + Int end = std::max(isds_baseline[i].kbot, isds_baseline[i].ktop); // 0-based indx for (Int k = start; k < end; ++k) { - REQUIRE(isds_fortran[i].T_atm[k] == isds_cxx[i].T_atm[k]); - REQUIRE(isds_fortran[i].rho[k] == isds_cxx[i].rho[k]); - REQUIRE(isds_fortran[i].inv_rho[k] == isds_cxx[i].inv_rho[k]); - REQUIRE(isds_fortran[i].qv_sat_l[k] == isds_cxx[i].qv_sat_l[k]); - REQUIRE(isds_fortran[i].qv_sat_i[k] == isds_cxx[i].qv_sat_i[k]); - REQUIRE(isds_fortran[i].qv_supersat_i[k] == isds_cxx[i].qv_supersat_i[k]); - REQUIRE(isds_fortran[i].rhofacr[k] == isds_cxx[i].rhofacr[k]); - REQUIRE(isds_fortran[i].rhofaci[k] == isds_cxx[i].rhofaci[k]); - REQUIRE(isds_fortran[i].acn[k] == isds_cxx[i].acn[k]); - REQUIRE(isds_fortran[i].qv[k] == isds_cxx[i].qv[k]); - REQUIRE(isds_fortran[i].th_atm[k] == isds_cxx[i].th_atm[k]); - REQUIRE(isds_fortran[i].qc[k] == isds_cxx[i].qc[k]); - REQUIRE(isds_fortran[i].nc[k] == isds_cxx[i].nc[k]); - REQUIRE(isds_fortran[i].qr[k] == isds_cxx[i].qr[k]); - REQUIRE(isds_fortran[i].nr[k] == isds_cxx[i].nr[k]); - REQUIRE(isds_fortran[i].qi[k] == isds_cxx[i].qi[k]); - REQUIRE(isds_fortran[i].ni[k] == isds_cxx[i].ni[k]); - REQUIRE(isds_fortran[i].qm[k] == isds_cxx[i].qm[k]); - REQUIRE(isds_fortran[i].bm[k] == isds_cxx[i].bm[k]); - REQUIRE(isds_fortran[i].qc_incld[k] == isds_cxx[i].qc_incld[k]); - REQUIRE(isds_fortran[i].qr_incld[k] == isds_cxx[i].qr_incld[k]); - REQUIRE(isds_fortran[i].qi_incld[k] == isds_cxx[i].qi_incld[k]); - REQUIRE(isds_fortran[i].qm_incld[k] == isds_cxx[i].qm_incld[k]); - REQUIRE(isds_fortran[i].nc_incld[k] == isds_cxx[i].nc_incld[k]); - REQUIRE(isds_fortran[i].nr_incld[k] == isds_cxx[i].nr_incld[k]); - REQUIRE(isds_fortran[i].ni_incld[k] == isds_cxx[i].ni_incld[k]); - REQUIRE(isds_fortran[i].bm_incld[k] == isds_cxx[i].bm_incld[k]); + REQUIRE(isds_baseline[i].T_atm[k] == isds_cxx[i].T_atm[k]); + REQUIRE(isds_baseline[i].rho[k] == isds_cxx[i].rho[k]); + REQUIRE(isds_baseline[i].inv_rho[k] == isds_cxx[i].inv_rho[k]); + REQUIRE(isds_baseline[i].qv_sat_l[k] == isds_cxx[i].qv_sat_l[k]); + REQUIRE(isds_baseline[i].qv_sat_i[k] == isds_cxx[i].qv_sat_i[k]); + REQUIRE(isds_baseline[i].qv_supersat_i[k] == isds_cxx[i].qv_supersat_i[k]); + REQUIRE(isds_baseline[i].rhofacr[k] == isds_cxx[i].rhofacr[k]); + REQUIRE(isds_baseline[i].rhofaci[k] == isds_cxx[i].rhofaci[k]); + REQUIRE(isds_baseline[i].acn[k] == isds_cxx[i].acn[k]); + REQUIRE(isds_baseline[i].qv[k] == isds_cxx[i].qv[k]); + REQUIRE(isds_baseline[i].th_atm[k] == isds_cxx[i].th_atm[k]); + REQUIRE(isds_baseline[i].qc[k] == isds_cxx[i].qc[k]); + REQUIRE(isds_baseline[i].nc[k] == isds_cxx[i].nc[k]); + REQUIRE(isds_baseline[i].qr[k] == isds_cxx[i].qr[k]); + REQUIRE(isds_baseline[i].nr[k] == isds_cxx[i].nr[k]); + REQUIRE(isds_baseline[i].qi[k] == isds_cxx[i].qi[k]); + REQUIRE(isds_baseline[i].ni[k] == isds_cxx[i].ni[k]); + REQUIRE(isds_baseline[i].qm[k] == isds_cxx[i].qm[k]); + REQUIRE(isds_baseline[i].bm[k] == isds_cxx[i].bm[k]); + REQUIRE(isds_baseline[i].qc_incld[k] == isds_cxx[i].qc_incld[k]); + REQUIRE(isds_baseline[i].qr_incld[k] == isds_cxx[i].qr_incld[k]); + REQUIRE(isds_baseline[i].qi_incld[k] == isds_cxx[i].qi_incld[k]); + REQUIRE(isds_baseline[i].qm_incld[k] == isds_cxx[i].qm_incld[k]); + REQUIRE(isds_baseline[i].nc_incld[k] == isds_cxx[i].nc_incld[k]); + REQUIRE(isds_baseline[i].nr_incld[k] == isds_cxx[i].nr_incld[k]); + REQUIRE(isds_baseline[i].ni_incld[k] == isds_cxx[i].ni_incld[k]); + REQUIRE(isds_baseline[i].bm_incld[k] == isds_cxx[i].bm_incld[k]); } - REQUIRE( isds_fortran[i].is_hydromet_present == isds_cxx[i].is_hydromet_present ); - REQUIRE( isds_fortran[i].is_nucleat_possible == isds_cxx[i].is_nucleat_possible ); + REQUIRE( isds_baseline[i].is_hydromet_present == isds_cxx[i].is_hydromet_present ); + REQUIRE( isds_baseline[i].is_nucleat_possible == isds_cxx[i].is_nucleat_possible ); + } + } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int i = 0; i < num_runs; ++i) { + isds_cxx[i].write(fid); } } } void run_bfb_p3_main_part2() { - auto engine = setup_random_test(); + auto engine = setup_random_test(263267); constexpr Scalar qsmall = C::QSMALL; constexpr Scalar T_zerodegc = C::T_zerodegc; @@ -161,7 +171,7 @@ void run_bfb_p3_main_part2() constexpr Scalar latvap = C::LatVap; constexpr Scalar latice = C::LatIce; - P3MainPart2Data isds_fortran[] = { + P3MainPart2Data isds_baseline[] = { // kts, kte, ktop, kbot, kdir, do_predict_nc, do_prescribed_CCN, dt P3MainPart2Data(1, 72, 1, 72, 1, false, true, 1.800E+03), P3MainPart2Data(1, 72, 1, 72, 1, true, true, 1.800E+03), @@ -169,9 +179,9 @@ void run_bfb_p3_main_part2() P3MainPart2Data(1, 72, 72, 1, -1, true, false, 1.800E+03), }; - static constexpr Int num_runs = sizeof(isds_fortran) / sizeof(P3MainPart2Data); + static constexpr Int num_runs = sizeof(isds_baseline) / sizeof(P3MainPart2Data); - for (auto& d : isds_fortran) { + for (auto& d : isds_baseline) { const auto qsmall_r = std::make_pair(0, qsmall*2); d.randomize(engine, { {d.T_atm, {T_zerodegc - 10, T_zerodegc + 10}}, @@ -188,18 +198,22 @@ void run_bfb_p3_main_part2() } } - // Create copies of data for use by cxx. Needs to happen before fortran calls so that + // Create copies of data for use by cxx. Needs to happen before reads so that // inout data is in original state P3MainPart2Data isds_cxx[num_runs] = { - P3MainPart2Data(isds_fortran[0]), - P3MainPart2Data(isds_fortran[1]), - P3MainPart2Data(isds_fortran[2]), - P3MainPart2Data(isds_fortran[3]), + P3MainPart2Data(isds_baseline[0]), + P3MainPart2Data(isds_baseline[1]), + P3MainPart2Data(isds_baseline[2]), + P3MainPart2Data(isds_baseline[3]), }; - // Get data from fortran - for (auto& d : isds_fortran) { - p3_main_part2(d); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/p3_main_part2.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (auto& d : isds_baseline) { + d.read(fid); + } } // Get data from cxx @@ -215,61 +229,67 @@ void run_bfb_p3_main_part2() d.prctot, &d.is_hydromet_present); } - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int i = 0; i < num_runs; ++i) { - Int start = std::min(isds_fortran[i].kbot, isds_fortran[i].ktop) - 1; // 0-based indx - Int end = std::max(isds_fortran[i].kbot, isds_fortran[i].ktop); // 0-based indx + Int start = std::min(isds_baseline[i].kbot, isds_baseline[i].ktop) - 1; // 0-based indx + Int end = std::max(isds_baseline[i].kbot, isds_baseline[i].ktop); // 0-based indx for (Int k = start; k < end; ++k) { - REQUIRE(isds_fortran[i].T_atm[k] == isds_cxx[i].T_atm[k]); - REQUIRE(isds_fortran[i].rho[k] == isds_cxx[i].rho[k]); - REQUIRE(isds_fortran[i].inv_rho[k] == isds_cxx[i].inv_rho[k]); - REQUIRE(isds_fortran[i].qv_sat_l[k] == isds_cxx[i].qv_sat_l[k]); - REQUIRE(isds_fortran[i].qv_sat_i[k] == isds_cxx[i].qv_sat_i[k]); - REQUIRE(isds_fortran[i].qv_supersat_i[k] == isds_cxx[i].qv_supersat_i[k]); - REQUIRE(isds_fortran[i].rhofacr[k] == isds_cxx[i].rhofacr[k]); - REQUIRE(isds_fortran[i].rhofaci[k] == isds_cxx[i].rhofaci[k]); - REQUIRE(isds_fortran[i].acn[k] == isds_cxx[i].acn[k]); - REQUIRE(isds_fortran[i].qv[k] == isds_cxx[i].qv[k]); - REQUIRE(isds_fortran[i].th_atm[k] == isds_cxx[i].th_atm[k]); - REQUIRE(isds_fortran[i].qc[k] == isds_cxx[i].qc[k]); - REQUIRE(isds_fortran[i].nc[k] == isds_cxx[i].nc[k]); - REQUIRE(isds_fortran[i].qr[k] == isds_cxx[i].qr[k]); - REQUIRE(isds_fortran[i].nr[k] == isds_cxx[i].nr[k]); - REQUIRE(isds_fortran[i].qi[k] == isds_cxx[i].qi[k]); - REQUIRE(isds_fortran[i].ni[k] == isds_cxx[i].ni[k]); - REQUIRE(isds_fortran[i].qm[k] == isds_cxx[i].qm[k]); - REQUIRE(isds_fortran[i].bm[k] == isds_cxx[i].bm[k]); - REQUIRE(isds_fortran[i].latent_heat_vapor[k] == latvap); - REQUIRE(isds_fortran[i].latent_heat_sublim[k] == (latvap+latice)); - REQUIRE(isds_fortran[i].latent_heat_fusion[k] == latice); - REQUIRE(isds_fortran[i].qc_incld[k] == isds_cxx[i].qc_incld[k]); - REQUIRE(isds_fortran[i].qr_incld[k] == isds_cxx[i].qr_incld[k]); - REQUIRE(isds_fortran[i].qi_incld[k] == isds_cxx[i].qi_incld[k]); - REQUIRE(isds_fortran[i].qm_incld[k] == isds_cxx[i].qm_incld[k]); - REQUIRE(isds_fortran[i].nc_incld[k] == isds_cxx[i].nc_incld[k]); - REQUIRE(isds_fortran[i].nr_incld[k] == isds_cxx[i].nr_incld[k]); - REQUIRE(isds_fortran[i].ni_incld[k] == isds_cxx[i].ni_incld[k]); - REQUIRE(isds_fortran[i].bm_incld[k] == isds_cxx[i].bm_incld[k]); - REQUIRE(isds_fortran[i].mu_c[k] == isds_cxx[i].mu_c[k]); - REQUIRE(isds_fortran[i].nu[k] == isds_cxx[i].nu[k]); - REQUIRE(isds_fortran[i].lamc[k] == isds_cxx[i].lamc[k]); - REQUIRE(isds_fortran[i].cdist[k] == isds_cxx[i].cdist[k]); - REQUIRE(isds_fortran[i].cdist1[k] == isds_cxx[i].cdist1[k]); - REQUIRE(isds_fortran[i].cdistr[k] == isds_cxx[i].cdistr[k]); - REQUIRE(isds_fortran[i].mu_r[k] == isds_cxx[i].mu_r[k]); - REQUIRE(isds_fortran[i].lamr[k] == isds_cxx[i].lamr[k]); - REQUIRE(isds_fortran[i].logn0r[k] == isds_cxx[i].logn0r[k]); - REQUIRE(isds_fortran[i].qv2qi_depos_tend[k] == isds_cxx[i].qv2qi_depos_tend[k]); - REQUIRE(isds_fortran[i].precip_total_tend[k] == isds_cxx[i].precip_total_tend[k]); - REQUIRE(isds_fortran[i].nevapr[k] == isds_cxx[i].nevapr[k]); - REQUIRE(isds_fortran[i].qr_evap_tend[k] == isds_cxx[i].qr_evap_tend[k]); - REQUIRE(isds_fortran[i].vap_liq_exchange[k] == isds_cxx[i].vap_liq_exchange[k]); - REQUIRE(isds_fortran[i].vap_ice_exchange[k] == isds_cxx[i].vap_ice_exchange[k]); - REQUIRE(isds_fortran[i].liq_ice_exchange[k] == isds_cxx[i].liq_ice_exchange[k]); - REQUIRE(isds_fortran[i].pratot[k] == isds_cxx[i].pratot[k]); - REQUIRE(isds_fortran[i].prctot[k] == isds_cxx[i].prctot[k]); + REQUIRE(isds_baseline[i].T_atm[k] == isds_cxx[i].T_atm[k]); + REQUIRE(isds_baseline[i].rho[k] == isds_cxx[i].rho[k]); + REQUIRE(isds_baseline[i].inv_rho[k] == isds_cxx[i].inv_rho[k]); + REQUIRE(isds_baseline[i].qv_sat_l[k] == isds_cxx[i].qv_sat_l[k]); + REQUIRE(isds_baseline[i].qv_sat_i[k] == isds_cxx[i].qv_sat_i[k]); + REQUIRE(isds_baseline[i].qv_supersat_i[k] == isds_cxx[i].qv_supersat_i[k]); + REQUIRE(isds_baseline[i].rhofacr[k] == isds_cxx[i].rhofacr[k]); + REQUIRE(isds_baseline[i].rhofaci[k] == isds_cxx[i].rhofaci[k]); + REQUIRE(isds_baseline[i].acn[k] == isds_cxx[i].acn[k]); + REQUIRE(isds_baseline[i].qv[k] == isds_cxx[i].qv[k]); + REQUIRE(isds_baseline[i].th_atm[k] == isds_cxx[i].th_atm[k]); + REQUIRE(isds_baseline[i].qc[k] == isds_cxx[i].qc[k]); + REQUIRE(isds_baseline[i].nc[k] == isds_cxx[i].nc[k]); + REQUIRE(isds_baseline[i].qr[k] == isds_cxx[i].qr[k]); + REQUIRE(isds_baseline[i].nr[k] == isds_cxx[i].nr[k]); + REQUIRE(isds_baseline[i].qi[k] == isds_cxx[i].qi[k]); + REQUIRE(isds_baseline[i].ni[k] == isds_cxx[i].ni[k]); + REQUIRE(isds_baseline[i].qm[k] == isds_cxx[i].qm[k]); + REQUIRE(isds_baseline[i].bm[k] == isds_cxx[i].bm[k]); + REQUIRE(isds_baseline[i].latent_heat_vapor[k] == latvap); + REQUIRE(isds_baseline[i].latent_heat_sublim[k] == (latvap+latice)); + REQUIRE(isds_baseline[i].latent_heat_fusion[k] == latice); + REQUIRE(isds_baseline[i].qc_incld[k] == isds_cxx[i].qc_incld[k]); + REQUIRE(isds_baseline[i].qr_incld[k] == isds_cxx[i].qr_incld[k]); + REQUIRE(isds_baseline[i].qi_incld[k] == isds_cxx[i].qi_incld[k]); + REQUIRE(isds_baseline[i].qm_incld[k] == isds_cxx[i].qm_incld[k]); + REQUIRE(isds_baseline[i].nc_incld[k] == isds_cxx[i].nc_incld[k]); + REQUIRE(isds_baseline[i].nr_incld[k] == isds_cxx[i].nr_incld[k]); + REQUIRE(isds_baseline[i].ni_incld[k] == isds_cxx[i].ni_incld[k]); + REQUIRE(isds_baseline[i].bm_incld[k] == isds_cxx[i].bm_incld[k]); + REQUIRE(isds_baseline[i].mu_c[k] == isds_cxx[i].mu_c[k]); + REQUIRE(isds_baseline[i].nu[k] == isds_cxx[i].nu[k]); + REQUIRE(isds_baseline[i].lamc[k] == isds_cxx[i].lamc[k]); + REQUIRE(isds_baseline[i].cdist[k] == isds_cxx[i].cdist[k]); + REQUIRE(isds_baseline[i].cdist1[k] == isds_cxx[i].cdist1[k]); + REQUIRE(isds_baseline[i].cdistr[k] == isds_cxx[i].cdistr[k]); + REQUIRE(isds_baseline[i].mu_r[k] == isds_cxx[i].mu_r[k]); + REQUIRE(isds_baseline[i].lamr[k] == isds_cxx[i].lamr[k]); + REQUIRE(isds_baseline[i].logn0r[k] == isds_cxx[i].logn0r[k]); + REQUIRE(isds_baseline[i].qv2qi_depos_tend[k] == isds_cxx[i].qv2qi_depos_tend[k]); + REQUIRE(isds_baseline[i].precip_total_tend[k] == isds_cxx[i].precip_total_tend[k]); + REQUIRE(isds_baseline[i].nevapr[k] == isds_cxx[i].nevapr[k]); + REQUIRE(isds_baseline[i].qr_evap_tend[k] == isds_cxx[i].qr_evap_tend[k]); + REQUIRE(isds_baseline[i].vap_liq_exchange[k] == isds_cxx[i].vap_liq_exchange[k]); + REQUIRE(isds_baseline[i].vap_ice_exchange[k] == isds_cxx[i].vap_ice_exchange[k]); + REQUIRE(isds_baseline[i].liq_ice_exchange[k] == isds_cxx[i].liq_ice_exchange[k]); + REQUIRE(isds_baseline[i].pratot[k] == isds_cxx[i].pratot[k]); + REQUIRE(isds_baseline[i].prctot[k] == isds_cxx[i].prctot[k]); } - REQUIRE( isds_fortran[i].is_hydromet_present == isds_cxx[i].is_hydromet_present ); + REQUIRE( isds_baseline[i].is_hydromet_present == isds_cxx[i].is_hydromet_present ); + } + } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int i = 0; i < num_runs; ++i) { + isds_cxx[i].write(fid); } } } @@ -279,11 +299,11 @@ void run_bfb_p3_main_part3() constexpr Scalar latvap = C::LatVap; constexpr Scalar latice = C::LatIce; - auto engine = setup_random_test(); + auto engine = setup_random_test(3734734); constexpr Scalar qsmall = C::QSMALL; - P3MainPart3Data isds_fortran[] = { + P3MainPart3Data isds_baseline[] = { // kts, kte, ktop, kbot, kdir P3MainPart3Data(1, 72, 1, 72, 1), P3MainPart3Data(1, 72, 1, 72, 1), @@ -291,9 +311,9 @@ void run_bfb_p3_main_part3() P3MainPart3Data(1, 72, 72, 1, -1), }; - static constexpr Int num_runs = sizeof(isds_fortran) / sizeof(P3MainPart3Data); + static constexpr Int num_runs = sizeof(isds_baseline) / sizeof(P3MainPart3Data); - for (auto& d : isds_fortran) { + for (auto& d : isds_baseline) { const auto qsmall_r = std::make_pair(0, qsmall*2); d.randomize(engine, { {d.qc, qsmall_r}, {d.qr, qsmall_r}, {d.qi, qsmall_r} }); @@ -305,18 +325,22 @@ void run_bfb_p3_main_part3() } } - // Create copies of data for use by cxx. Needs to happen before fortran calls so that + // Create copies of data for use by cxx. Needs to happen before reads so that // inout data is in original state P3MainPart3Data isds_cxx[num_runs] = { - P3MainPart3Data(isds_fortran[0]), - P3MainPart3Data(isds_fortran[1]), - P3MainPart3Data(isds_fortran[2]), - P3MainPart3Data(isds_fortran[3]), + P3MainPart3Data(isds_baseline[0]), + P3MainPart3Data(isds_baseline[1]), + P3MainPart3Data(isds_baseline[2]), + P3MainPart3Data(isds_baseline[3]), }; - // Get data from fortran - for (auto& d : isds_fortran) { - p3_main_part3(d); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/p3_main_part3.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (auto& d : isds_baseline) { + d.read(fid); + } } // Get data from cxx @@ -329,59 +353,65 @@ void run_bfb_p3_main_part3() d. ze_rain, d.ze_ice, d.diag_vm_qi, d.diag_eff_radius_qi, d.diag_diam_qi, d.rho_qi, d.diag_equiv_reflectivity, d.diag_eff_radius_qc, d.diag_eff_radius_qr); } - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int i = 0; i < num_runs; ++i) { - Int start = std::min(isds_fortran[i].kbot, isds_fortran[i].ktop) - 1; // 0-based indx - Int end = std::max(isds_fortran[i].kbot, isds_fortran[i].ktop); // 0-based indx + Int start = std::min(isds_baseline[i].kbot, isds_baseline[i].ktop) - 1; // 0-based indx + Int end = std::max(isds_baseline[i].kbot, isds_baseline[i].ktop); // 0-based indx for (Int k = start; k < end; ++k) { - REQUIRE(isds_fortran[i].rho[k] == isds_cxx[i].rho[k]); - REQUIRE(isds_fortran[i].inv_rho[k] == isds_cxx[i].inv_rho[k]); - REQUIRE(isds_fortran[i].rhofaci[k] == isds_cxx[i].rhofaci[k]); - REQUIRE(isds_fortran[i].qv[k] == isds_cxx[i].qv[k]); - REQUIRE(isds_fortran[i].th_atm[k] == isds_cxx[i].th_atm[k]); - REQUIRE(isds_fortran[i].qc[k] == isds_cxx[i].qc[k]); - REQUIRE(isds_fortran[i].nc[k] == isds_cxx[i].nc[k]); - REQUIRE(isds_fortran[i].qr[k] == isds_cxx[i].qr[k]); - REQUIRE(isds_fortran[i].nr[k] == isds_cxx[i].nr[k]); - REQUIRE(isds_fortran[i].qi[k] == isds_cxx[i].qi[k]); - REQUIRE(isds_fortran[i].ni[k] == isds_cxx[i].ni[k]); - REQUIRE(isds_fortran[i].qm[k] == isds_cxx[i].qm[k]); - REQUIRE(isds_fortran[i].bm[k] == isds_cxx[i].bm[k]); - REQUIRE(isds_fortran[i].latent_heat_vapor[k] == latvap); - REQUIRE(isds_fortran[i].latent_heat_sublim[k] == latvap+latice); - REQUIRE(isds_fortran[i].mu_c[k] == isds_cxx[i].mu_c[k]); - REQUIRE(isds_fortran[i].nu[k] == isds_cxx[i].nu[k]); - REQUIRE(isds_fortran[i].lamc[k] == isds_cxx[i].lamc[k]); - REQUIRE(isds_fortran[i].mu_r[k] == isds_cxx[i].mu_r[k]); - REQUIRE(isds_fortran[i].lamr[k] == isds_cxx[i].lamr[k]); - REQUIRE(isds_fortran[i].vap_liq_exchange[k] == isds_cxx[i].vap_liq_exchange[k]); - REQUIRE(isds_fortran[i].ze_rain[k] == isds_cxx[i].ze_rain[k]); - REQUIRE(isds_fortran[i].ze_ice[k] == isds_cxx[i].ze_ice[k]); - REQUIRE(isds_fortran[i].diag_vm_qi[k] == isds_cxx[i].diag_vm_qi[k]); - REQUIRE(isds_fortran[i].diag_eff_radius_qi[k] == isds_cxx[i].diag_eff_radius_qi[k]); - REQUIRE(isds_fortran[i].diag_diam_qi[k] == isds_cxx[i].diag_diam_qi[k]); - REQUIRE(isds_fortran[i].rho_qi[k] == isds_cxx[i].rho_qi[k]); - REQUIRE(isds_fortran[i].diag_equiv_reflectivity[k] == isds_cxx[i].diag_equiv_reflectivity[k]); - REQUIRE(isds_fortran[i].diag_eff_radius_qc[k] == isds_cxx[i].diag_eff_radius_qc[k]); - REQUIRE(isds_fortran[i].diag_eff_radius_qr[k] == isds_cxx[i].diag_eff_radius_qr[k]); + REQUIRE(isds_baseline[i].rho[k] == isds_cxx[i].rho[k]); + REQUIRE(isds_baseline[i].inv_rho[k] == isds_cxx[i].inv_rho[k]); + REQUIRE(isds_baseline[i].rhofaci[k] == isds_cxx[i].rhofaci[k]); + REQUIRE(isds_baseline[i].qv[k] == isds_cxx[i].qv[k]); + REQUIRE(isds_baseline[i].th_atm[k] == isds_cxx[i].th_atm[k]); + REQUIRE(isds_baseline[i].qc[k] == isds_cxx[i].qc[k]); + REQUIRE(isds_baseline[i].nc[k] == isds_cxx[i].nc[k]); + REQUIRE(isds_baseline[i].qr[k] == isds_cxx[i].qr[k]); + REQUIRE(isds_baseline[i].nr[k] == isds_cxx[i].nr[k]); + REQUIRE(isds_baseline[i].qi[k] == isds_cxx[i].qi[k]); + REQUIRE(isds_baseline[i].ni[k] == isds_cxx[i].ni[k]); + REQUIRE(isds_baseline[i].qm[k] == isds_cxx[i].qm[k]); + REQUIRE(isds_baseline[i].bm[k] == isds_cxx[i].bm[k]); + REQUIRE(isds_baseline[i].latent_heat_vapor[k] == latvap); + REQUIRE(isds_baseline[i].latent_heat_sublim[k] == latvap+latice); + REQUIRE(isds_baseline[i].mu_c[k] == isds_cxx[i].mu_c[k]); + REQUIRE(isds_baseline[i].nu[k] == isds_cxx[i].nu[k]); + REQUIRE(isds_baseline[i].lamc[k] == isds_cxx[i].lamc[k]); + REQUIRE(isds_baseline[i].mu_r[k] == isds_cxx[i].mu_r[k]); + REQUIRE(isds_baseline[i].lamr[k] == isds_cxx[i].lamr[k]); + REQUIRE(isds_baseline[i].vap_liq_exchange[k] == isds_cxx[i].vap_liq_exchange[k]); + REQUIRE(isds_baseline[i].ze_rain[k] == isds_cxx[i].ze_rain[k]); + REQUIRE(isds_baseline[i].ze_ice[k] == isds_cxx[i].ze_ice[k]); + REQUIRE(isds_baseline[i].diag_vm_qi[k] == isds_cxx[i].diag_vm_qi[k]); + REQUIRE(isds_baseline[i].diag_eff_radius_qi[k] == isds_cxx[i].diag_eff_radius_qi[k]); + REQUIRE(isds_baseline[i].diag_diam_qi[k] == isds_cxx[i].diag_diam_qi[k]); + REQUIRE(isds_baseline[i].rho_qi[k] == isds_cxx[i].rho_qi[k]); + REQUIRE(isds_baseline[i].diag_equiv_reflectivity[k] == isds_cxx[i].diag_equiv_reflectivity[k]); + REQUIRE(isds_baseline[i].diag_eff_radius_qc[k] == isds_cxx[i].diag_eff_radius_qc[k]); + REQUIRE(isds_baseline[i].diag_eff_radius_qr[k] == isds_cxx[i].diag_eff_radius_qr[k]); } } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int i = 0; i < num_runs; ++i) { + isds_cxx[i].write(fid); + } + } } void run_bfb_p3_main() { - auto engine = setup_random_test(); + auto engine = setup_random_test(3427727); - P3MainData isds_fortran[] = { + P3MainData isds_baseline[] = { // its, ite, kts, kte, it, dt, do_predict_nc, do_prescribed_CCN P3MainData(1, 10, 1, 72, 1, 1.800E+03, false, true), P3MainData(1, 10, 1, 72, 1, 1.800E+03, true, false), }; - static constexpr Int num_runs = sizeof(isds_fortran) / sizeof(P3MainData); + static constexpr Int num_runs = sizeof(isds_baseline) / sizeof(P3MainData); - for (auto& d : isds_fortran) { + for (auto& d : isds_baseline) { d.randomize(engine, { {d.pres , {1.00000000E+02 , 9.87111111E+04}}, {d.dz , {1.22776609E+02 , 3.49039167E+04}}, @@ -409,16 +439,20 @@ void run_bfb_p3_main() }); } - // Create copies of data for use by cxx. Needs to happen before fortran calls so that + // Create copies of data for use by cxx. Needs to happen before reads so that // inout data is in original state P3MainData isds_cxx[num_runs] = { - P3MainData(isds_fortran[0]), - P3MainData(isds_fortran[1]), + P3MainData(isds_baseline[0]), + P3MainData(isds_baseline[1]), }; - // Get data from fortran - for (auto& d : isds_fortran) { - p3_main(d); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/p3_main.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (auto& d : isds_baseline) { + d.read(fid); + } } // Get data from cxx @@ -434,11 +468,11 @@ void run_bfb_p3_main() d.template transpose(); } - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int i = 0; i < num_runs; ++i) { - const auto& df90 = isds_fortran[i]; - const auto& dcxx = isds_fortran[i]; - const auto tot = isds_fortran[i].total(df90.qc); + const auto& df90 = isds_baseline[i]; + const auto& dcxx = isds_baseline[i]; + const auto tot = isds_baseline[i].total(df90.qc); for (Int t = 0; t < tot; ++t) { REQUIRE(df90.qc[t] == dcxx.qc[t]); REQUIRE(df90.nc[t] == dcxx.nc[t]); @@ -474,6 +508,12 @@ void run_bfb_p3_main() REQUIRE(df90.precip_ice_surf[tot] == dcxx.precip_ice_surf[tot]); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int i = 0; i < num_runs; ++i) { + isds_cxx[i].write(fid); + } + } } void run_bfb() From 85906748d0a90e489402f10f498ed1cfbd96c738 Mon Sep 17 00:00:00 2001 From: Oscar Diaz-Ibarra Date: Mon, 4 Nov 2024 08:46:13 -0700 Subject: [PATCH 025/147] Rename the LEV scream tag from 'Lev' to 'altitude' in the source grid when using a remap file. --- ...mxx_mam_microphysics_process_interface.cpp | 4 ++- .../mam/readfiles/tracer_reader_utils.hpp | 34 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) 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 b0ab232c255c..feb87c186835 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 @@ -289,8 +289,10 @@ void MAMMicrophysics::set_grids( verti_emiss_cyclical_ymd); auto hor_rem = scream::mam_coupling::create_horiz_remapper( grid_, file_name, extfrc_map_file, var_names, data_tracer); + auto file_reader = - scream::mam_coupling::create_tracer_data_reader(hor_rem, file_name); + scream::mam_coupling::create_tracer_data_reader(hor_rem, file_name, + data_tracer, extfrc_map_file); VertEmissionsHorizInterp_.push_back(hor_rem); VertEmissionsDataReader_.push_back(file_reader); vert_emis_data_.push_back(data_tracer); diff --git a/components/eamxx/src/physics/mam/readfiles/tracer_reader_utils.hpp b/components/eamxx/src/physics/mam/readfiles/tracer_reader_utils.hpp index 2e34db2b4962..1f757e930276 100644 --- a/components/eamxx/src/physics/mam/readfiles/tracer_reader_utils.hpp +++ b/components/eamxx/src/physics/mam/readfiles/tracer_reader_utils.hpp @@ -448,6 +448,40 @@ inline std::shared_ptr create_tracer_data_reader( true); } // create_tracer_data_reader +inline std::shared_ptr create_tracer_data_reader( + const std::shared_ptr &horiz_remapper, + const std::string &tracer_data_file, + const TracerData &tracer_data, + const std::string &extfrc_map_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(); + + // NOTE: If we are using a vertical emission NC file with altitude instead of levels, + // we must rename this tag. This is only necessary when a map file is used. + bool rename_LEV_grid=false; + if(tracer_data.file_type == VERT_EMISSION && extfrc_map_file != ""){ + rename_LEV_grid=true; + } + + if (rename_LEV_grid) { + auto horiz_interp_src_grid = + io_grid->clone("tracer_horiz_interp_src_grid", true); + horiz_interp_src_grid->reset_field_tag_name(LEV, "altitude"); + horiz_interp_src_grid->reset_field_tag_name(ILEV, "altitude_int"); + return std::make_shared(tracer_data_file, horiz_interp_src_grid, io_fields, + true); + } else { + return std::make_shared(tracer_data_file, io_grid, io_fields, + true); + } + + +} // create_tracer_data_reader + inline void update_tracer_data_from_file( const std::shared_ptr &scorpio_reader, const int time_index, // zero-based From f1c9a3903b9aded1ccff7226b3b15f134c5066b6 Mon Sep 17 00:00:00 2001 From: Oscar Diaz-Ibarra Date: Mon, 4 Nov 2024 09:51:54 -0700 Subject: [PATCH 026/147] Removing unnecessary if statement. --- .../eamxx/src/physics/mam/readfiles/tracer_reader_utils.hpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/components/eamxx/src/physics/mam/readfiles/tracer_reader_utils.hpp b/components/eamxx/src/physics/mam/readfiles/tracer_reader_utils.hpp index 1f757e930276..e31300a679a6 100644 --- a/components/eamxx/src/physics/mam/readfiles/tracer_reader_utils.hpp +++ b/components/eamxx/src/physics/mam/readfiles/tracer_reader_utils.hpp @@ -462,12 +462,7 @@ inline std::shared_ptr create_tracer_data_reader( // NOTE: If we are using a vertical emission NC file with altitude instead of levels, // we must rename this tag. This is only necessary when a map file is used. - bool rename_LEV_grid=false; if(tracer_data.file_type == VERT_EMISSION && extfrc_map_file != ""){ - rename_LEV_grid=true; - } - - if (rename_LEV_grid) { auto horiz_interp_src_grid = io_grid->clone("tracer_horiz_interp_src_grid", true); horiz_interp_src_grid->reset_field_tag_name(LEV, "altitude"); @@ -479,7 +474,6 @@ inline std::shared_ptr create_tracer_data_reader( true); } - } // create_tracer_data_reader inline void update_tracer_data_from_file( From e166eaaeaffc472258ddd60c526af93a87dc6172 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Mon, 4 Nov 2024 11:44:57 -0700 Subject: [PATCH 027/147] All bfb unit tests complete --- .../p3/tests/p3_nc_conservation_tests.cpp | 40 +++++++++++------- .../p3/tests/p3_ni_conservation_tests.cpp | 39 ++++++++++------- .../p3/tests/p3_nr_conservation_tests.cpp | 42 ++++++++++++------- .../p3_prevent_liq_supersaturation_tests.cpp | 39 ++++++++++------- .../tests/p3_rain_imm_freezing_unit_tests.cpp | 18 ++++++-- .../tests/p3_rain_self_collection_tests.cpp | 18 ++++++-- ...p3_subgrid_variance_scaling_unit_tests.cpp | 29 +++++++++---- 7 files changed, 147 insertions(+), 78 deletions(-) diff --git a/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp index ecf47b99eaa7..0161566d5396 100644 --- a/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp @@ -18,27 +18,31 @@ struct UnitWrap::UnitTest::TestNcConservation : public UnitWrap::UnitTest: void run_bfb() { - auto engine = setup_random_test(); + auto engine = setup_random_test(1241556); - NcConservationData f90_data[max_pack_size]; + NcConservationData baseline_data[max_pack_size]; // Generate random input data - // Alternatively, you can use the f90_data construtors/initializer lists to hardcode data - for (auto& d : f90_data) { + // Alternatively, you can use the baseline_data construtors/initializer lists to hardcode data + for (auto& d : baseline_data) { d.randomize(engine); - d.dt = f90_data[0].dt; // Hold this fixed, this is not packed data + d.dt = baseline_data[0].dt; // Hold this fixed, this is not packed data } // Create copies of data for use by cxx and sync it to device. Needs to happen before fortran calls so that // inout data is in original state view_1d cxx_device("cxx_device", max_pack_size); const auto cxx_host = Kokkos::create_mirror_view(cxx_device); - std::copy(&f90_data[0], &f90_data[0] + max_pack_size, cxx_host.data()); + std::copy(&baseline_data[0], &baseline_data[0] + max_pack_size, cxx_host.data()); Kokkos::deep_copy(cxx_device, cxx_host); - // Get data from fortran - for (auto& d : f90_data) { - nc_conservation(d); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/nc_conservation.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + baseline_data[i].read(fid); + } } // Get data from cxx. Run nc_conservation from a kernel and copy results back to host @@ -71,14 +75,20 @@ struct UnitWrap::UnitTest::TestNcConservation : public UnitWrap::UnitTest: Kokkos::deep_copy(cxx_host, cxx_device); // Verify BFB results - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - NcConservationData& d_f90 = f90_data[i]; + NcConservationData& d_baseline = baseline_data[i]; NcConservationData& d_cxx = cxx_host[i]; - REQUIRE(d_f90.nc_collect_tend == d_cxx.nc_collect_tend); - REQUIRE(d_f90.nc2ni_immers_freeze_tend == d_cxx.nc2ni_immers_freeze_tend); - REQUIRE(d_f90.nc_accret_tend == d_cxx.nc_accret_tend); - REQUIRE(d_f90.nc2nr_autoconv_tend == d_cxx.nc2nr_autoconv_tend); + REQUIRE(d_baseline.nc_collect_tend == d_cxx.nc_collect_tend); + REQUIRE(d_baseline.nc2ni_immers_freeze_tend == d_cxx.nc2ni_immers_freeze_tend); + REQUIRE(d_baseline.nc_accret_tend == d_cxx.nc_accret_tend); + REQUIRE(d_baseline.nc2nr_autoconv_tend == d_cxx.nc2nr_autoconv_tend); + } + } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + cxx_host(s).write(fid); } } } // run_bfb diff --git a/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp index 41c13afd9235..c5feff71ea88 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp @@ -18,27 +18,31 @@ struct UnitWrap::UnitTest::TestNiConservation : public UnitWrap::UnitTest: void run_bfb() { - auto engine = setup_random_test(); + auto engine = setup_random_test(1925985); - NiConservationData f90_data[max_pack_size]; + NiConservationData baseline_data[max_pack_size]; // Generate random input data - // Alternatively, you can use the f90_data construtors/initializer lists to hardcode data - for (auto& d : f90_data) { + // Alternatively, you can use the baseline_data construtors/initializer lists to hardcode data + for (auto& d : baseline_data) { d.randomize(engine); - d.dt = f90_data[0].dt; // hold dt fixed, it is not packed data + d.dt = baseline_data[0].dt; // hold dt fixed, it is not packed data } // Create copies of data for use by cxx and sync it to device. Needs to happen before fortran calls so that // inout data is in original state view_1d cxx_device("cxx_device", max_pack_size); const auto cxx_host = Kokkos::create_mirror_view(cxx_device); - std::copy(&f90_data[0], &f90_data[0] + max_pack_size, cxx_host.data()); + std::copy(&baseline_data[0], &baseline_data[0] + max_pack_size, cxx_host.data()); Kokkos::deep_copy(cxx_device, cxx_host); - // Get data from fortran - for (auto& d : f90_data) { - ni_conservation(d); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/ni_conservation.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + baseline_data[i].read(fid); + } } // Get data from cxx. Run ni_conservation from a kernel and copy results back to host @@ -71,17 +75,22 @@ struct UnitWrap::UnitTest::TestNiConservation : public UnitWrap::UnitTest: Kokkos::deep_copy(cxx_host, cxx_device); // Verify BFB results - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - NiConservationData& d_f90 = f90_data[i]; + NiConservationData& d_baseline = baseline_data[i]; NiConservationData& d_cxx = cxx_host[i]; - REQUIRE(d_f90.ni2nr_melt_tend == d_cxx.ni2nr_melt_tend); - REQUIRE(d_f90.ni_sublim_tend == d_cxx.ni_sublim_tend); - REQUIRE(d_f90.ni_selfcollect_tend == d_cxx.ni_selfcollect_tend); + REQUIRE(d_baseline.ni2nr_melt_tend == d_cxx.ni2nr_melt_tend); + REQUIRE(d_baseline.ni_sublim_tend == d_cxx.ni_sublim_tend); + REQUIRE(d_baseline.ni_selfcollect_tend == d_cxx.ni_selfcollect_tend); + } + } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + cxx_host(s).write(fid); } } } // run_bfb - }; } // namespace unit_test diff --git a/components/eamxx/src/physics/p3/tests/p3_nr_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_nr_conservation_tests.cpp index 2df8a01dbb33..c268a763d79a 100644 --- a/components/eamxx/src/physics/p3/tests/p3_nr_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_nr_conservation_tests.cpp @@ -18,28 +18,32 @@ struct UnitWrap::UnitTest::TestNrConservation : public UnitWrap::UnitTest: void run_bfb() { - auto engine = setup_random_test(); + auto engine = setup_random_test(912874); - NrConservationData f90_data[max_pack_size]; + NrConservationData baseline_data[max_pack_size]; // Generate random input data - // Alternatively, you can use the f90_data construtors/initializer lists to hardcode data - for (auto& d : f90_data) { + // Alternatively, you can use the baseline_data construtors/initializer lists to hardcode data + for (auto& d : baseline_data) { d.randomize(engine); - d.dt = f90_data[0].dt; // hold dt fixed, it is not packed data - d.nmltratio = f90_data[0].nmltratio; // hold nmltratio fixed, it is not packed data + d.dt = baseline_data[0].dt; // hold dt fixed, it is not packed data + d.nmltratio = baseline_data[0].nmltratio; // hold nmltratio fixed, it is not packed data } // Create copies of data for use by cxx and sync it to device. Needs to happen before fortran calls so that // inout data is in original state view_1d cxx_device("cxx_device", max_pack_size); const auto cxx_host = Kokkos::create_mirror_view(cxx_device); - std::copy(&f90_data[0], &f90_data[0] + max_pack_size, cxx_host.data()); + std::copy(&baseline_data[0], &baseline_data[0] + max_pack_size, cxx_host.data()); Kokkos::deep_copy(cxx_device, cxx_host); - // Get data from fortran - for (auto& d : f90_data) { - nr_conservation(d); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/nr_conservation.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + baseline_data[i].read(fid); + } } // Get data from cxx. Run nr_conservation from a kernel and copy results back to host @@ -75,14 +79,20 @@ struct UnitWrap::UnitTest::TestNrConservation : public UnitWrap::UnitTest: Kokkos::deep_copy(cxx_host, cxx_device); // Verify BFB results - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - NrConservationData& d_f90 = f90_data[i]; + NrConservationData& d_baseline = baseline_data[i]; NrConservationData& d_cxx = cxx_host[i]; - REQUIRE(d_f90.nr_collect_tend == d_cxx.nr_collect_tend); - REQUIRE(d_f90.nr2ni_immers_freeze_tend == d_cxx.nr2ni_immers_freeze_tend); - REQUIRE(d_f90.nr_selfcollect_tend == d_cxx.nr_selfcollect_tend); - REQUIRE(d_f90.nr_evap_tend == d_cxx.nr_evap_tend); + REQUIRE(d_baseline.nr_collect_tend == d_cxx.nr_collect_tend); + REQUIRE(d_baseline.nr2ni_immers_freeze_tend == d_cxx.nr2ni_immers_freeze_tend); + REQUIRE(d_baseline.nr_selfcollect_tend == d_cxx.nr_selfcollect_tend); + REQUIRE(d_baseline.nr_evap_tend == d_cxx.nr_evap_tend); + } + } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + cxx_host(s).write(fid); } } } // run_bfb diff --git a/components/eamxx/src/physics/p3/tests/p3_prevent_liq_supersaturation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_prevent_liq_supersaturation_tests.cpp index 2b845e9c97b7..acd7e7d74541 100644 --- a/components/eamxx/src/physics/p3/tests/p3_prevent_liq_supersaturation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_prevent_liq_supersaturation_tests.cpp @@ -93,18 +93,18 @@ struct UnitWrap::UnitTest::TestPreventLiqSupersaturation : public UnitWrap::U constexpr Scalar latvap = C::LatVap; constexpr Scalar latice = C::LatIce; - auto engine = setup_random_test(); + auto engine = setup_random_test(1298758); - PreventLiqSupersaturationData f90_data[max_pack_size]; + PreventLiqSupersaturationData baseline_data[max_pack_size]; // Generate random input data - // Alternatively, you can use the f90_data construtors/initializer lists to hardcode data - for (auto& d : f90_data) { + // Alternatively, you can use the baseline_data construtors/initializer lists to hardcode data + for (auto& d : baseline_data) { d.randomize(engine); - d.dt = f90_data[0].dt; // Hold this fixed, this is not packed data + d.dt = baseline_data[0].dt; // Hold this fixed, this is not packed data // C++ impl uses constants for latent_heat values. Manually set here - // so F90 can match + // so BASELINE can match d.latent_heat_vapor = latvap; d.latent_heat_sublim = latvap+latice; } @@ -113,7 +113,7 @@ struct UnitWrap::UnitTest::TestPreventLiqSupersaturation : public UnitWrap::U // fortran calls so that inout data is in original state view_1d cxx_device("cxx_device", max_pack_size); const auto cxx_host = Kokkos::create_mirror_view(cxx_device); - std::copy(&f90_data[0], &f90_data[0] + max_pack_size, cxx_host.data()); + std::copy(&baseline_data[0], &baseline_data[0] + max_pack_size, cxx_host.data()); Kokkos::deep_copy(cxx_device, cxx_host); // Save copy of inout vars to check that prevent_liq_supersaturation always makes them smaller @@ -123,9 +123,13 @@ struct UnitWrap::UnitTest::TestPreventLiqSupersaturation : public UnitWrap::U qr2qv_evap_tend_init[i] = cxx_host(i).qr2qv_evap_tend; } - // Get data from fortran - for (auto& d : f90_data) { - prevent_liq_supersaturation(d); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/prevent_liq_supersaturation.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + baseline_data[i].read(fid); + } } // Get data from cxx. Run prevent_liq_supersaturation from a kernel and copy results back to host @@ -158,13 +162,13 @@ struct UnitWrap::UnitTest::TestPreventLiqSupersaturation : public UnitWrap::U Kokkos::deep_copy(cxx_host, cxx_device); - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { // Verify BFB results - PreventLiqSupersaturationData& d_f90 = f90_data[i]; + PreventLiqSupersaturationData& d_baseline = baseline_data[i]; PreventLiqSupersaturationData& d_cxx = cxx_host[i]; - REQUIRE(d_f90.qi2qv_sublim_tend == d_cxx.qi2qv_sublim_tend); - REQUIRE(d_f90.qr2qv_evap_tend == d_cxx.qr2qv_evap_tend); + REQUIRE(d_baseline.qi2qv_sublim_tend == d_cxx.qi2qv_sublim_tend); + REQUIRE(d_baseline.qr2qv_evap_tend == d_cxx.qr2qv_evap_tend); //Verify tendencies are always >=0: REQUIRE(d_cxx.qi2qv_sublim_tend>=0); @@ -175,8 +179,13 @@ struct UnitWrap::UnitTest::TestPreventLiqSupersaturation : public UnitWrap::U REQUIRE(d_cxx.qr2qv_evap_tend<=qr2qv_evap_tend_init[i]); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + cxx_host(s).write(fid); + } + } } // run_bfb - }; } // namespace unit_test diff --git a/components/eamxx/src/physics/p3/tests/p3_rain_imm_freezing_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_rain_imm_freezing_unit_tests.cpp index e19b83d6c2a7..92123d63e82e 100644 --- a/components/eamxx/src/physics/p3/tests/p3_rain_imm_freezing_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_rain_imm_freezing_unit_tests.cpp @@ -69,9 +69,13 @@ void run_bfb() host_data.data()); Kokkos::deep_copy(device_data, host_data); - // Run the Fortran subroutine. - for (Int i = 0; i < max_pack_size; ++i) { - rain_immersion_freezing(rain_imm_freezing_data[i]); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/rain_immersion_freezing.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + rain_imm_freezing_data[i].read(fid); + } } // Run the lookup from a kernel and copy results back to host @@ -106,12 +110,18 @@ void run_bfb() Kokkos::deep_copy(host_data, device_data); // Validate results. - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int s = 0; s < max_pack_size; ++s) { REQUIRE(rain_imm_freezing_data[s].qr2qi_immers_freeze_tend == host_data[s].qr2qi_immers_freeze_tend); REQUIRE(rain_imm_freezing_data[s].nr2ni_immers_freeze_tend == host_data[s].nr2ni_immers_freeze_tend); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + host_data(s).write(fid); + } + } } }; diff --git a/components/eamxx/src/physics/p3/tests/p3_rain_self_collection_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_rain_self_collection_tests.cpp index 7bcdf59dac8a..d9d8ef004122 100644 --- a/components/eamxx/src/physics/p3/tests/p3_rain_self_collection_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_rain_self_collection_tests.cpp @@ -56,9 +56,13 @@ struct UnitWrap::UnitTest::TestRainSelfCollection : public UnitWrap::UnitTest std::copy(&dc[0], &dc[0] + max_pack_size, dc_host.data()); Kokkos::deep_copy(dc_device, dc_host); - //Get data from fortran - for (Int i = 0; i < max_pack_size; ++i) { - rain_self_collection(dc[i]); + // Read baseline data + std::string baseline_name = this->m_baseline_path + "/rain_self_collection.dat"; + if (this->m_baseline_action == COMPARE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + for (Int i = 0; i < max_pack_size; ++i) { + dc[i].read(fid); + } } //Run function from a kernal and copy results back to the host @@ -91,7 +95,7 @@ struct UnitWrap::UnitTest::TestRainSelfCollection : public UnitWrap::UnitTest Kokkos::deep_copy(dc_host, dc_device); // Validate results - if (SCREAM_BFB_TESTING) { + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int s = 0; s < max_pack_size; ++s) { REQUIRE(dc[s].rho == dc_host(s).rho); REQUIRE(dc[s].qr_incld == dc_host(s).qr_incld); @@ -99,6 +103,12 @@ struct UnitWrap::UnitTest::TestRainSelfCollection : public UnitWrap::UnitTest REQUIRE(dc[s].nr_selfcollect_tend == dc_host(s).nr_selfcollect_tend); } } + else if (this->m_baseline_action == GENERATE) { + auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + for (Int s = 0; s < max_pack_size; ++s) { + dc_host(s).write(fid); + } + } } void run_bfb() { diff --git a/components/eamxx/src/physics/p3/tests/p3_subgrid_variance_scaling_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_subgrid_variance_scaling_unit_tests.cpp index 9e75889df0c5..a71b3abd4225 100644 --- a/components/eamxx/src/physics/p3/tests/p3_subgrid_variance_scaling_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_subgrid_variance_scaling_unit_tests.cpp @@ -36,22 +36,30 @@ struct UnitWrap::UnitTest::TestP3SubgridVarianceScaling : public UnitWrap::Un //Set of exponents to loop over Scalar expons[3] = {1.0,2.47,0.1}; - //initialize struct required for F90 call - SubgridVarianceScalingData f_data; - Scalar f_scaling; + Scalar baseline_scaling; //Make C++ output available on host and device view_1d scaling_device("c scaling",1); auto scaling_host = Kokkos::create_mirror_view(scaling_device); + std::string baseline_name = this->m_baseline_path + "/subgrid_variance_scaling.dat"; + ekat::FILEPtr rfid = nullptr; + ekat::FILEPtr wfid = nullptr; + if (this->m_baseline_action == COMPARE) { + rfid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + } + else if (this->m_baseline_action == GENERATE) { + wfid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + } + for (Int i = 0; i < 3; ++i) { // loop over exponents for (Int j = 0; j < 16; ++j) { // loop over relvars - // Get F90 solution + // Get baseline solution // ---------------------------------- - f_data.relvar=relvars[j]; - f_data.expon =expons[i]; - f_scaling = subgrid_variance_scaling(f_data); + if (this->m_baseline_action == COMPARE) { + ekat::read(&baseline_scaling, 1, rfid); + } // Get C++ solution // ---------------------------------- @@ -72,8 +80,11 @@ struct UnitWrap::UnitTest::TestP3SubgridVarianceScaling : public UnitWrap::Un Kokkos::deep_copy(scaling_host, scaling_device); // Validate results - if (SCREAM_BFB_TESTING) { - REQUIRE(f_scaling == scaling_host(0) ); + if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { + REQUIRE(baseline_scaling == scaling_host(0) ); + } + else if (this->m_baseline_action == GENERATE) { + ekat::write(&scaling_host(0), 1, wfid); } } //end loop over relvar[j] } //end loop over expons[i] From 23fd73091a0c1cd214289c7e7c89276be179b769 Mon Sep 17 00:00:00 2001 From: Oscar Diaz-Ibarra Date: Mon, 4 Nov 2024 12:40:18 -0700 Subject: [PATCH 028/147] Fix bug by using target grid instead of source grid. --- .../mam/eamxx_mam_microphysics_process_interface.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 feb87c186835..0b1440b3826f 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 @@ -205,7 +205,7 @@ void MAMMicrophysics::set_grids( LinozHorizInterp_, linoz_file_name_); // linoz reader - const auto io_grid_linoz = LinozHorizInterp_->get_src_grid(); + const auto io_grid_linoz = LinozHorizInterp_->get_tgt_grid(); const int num_cols_io_linoz = io_grid_linoz->get_num_local_dofs(); // Number of columns on this rank const int num_levs_io_linoz = @@ -233,7 +233,7 @@ void MAMMicrophysics::set_grids( TracerHorizInterp_, oxid_file_name_); const int nvars = int(var_names.size()); - const auto io_grid = TracerHorizInterp_->get_src_grid(); + const auto io_grid = TracerHorizInterp_->get_tgt_grid(); const int num_cols_io = io_grid->get_num_local_dofs(); // Number of columns on this rank const int num_levs_io = @@ -308,7 +308,7 @@ void MAMMicrophysics::set_grids( // I am assuming the order of species in extfrc_lst_. // Indexing in mam4xx is fortran. forcings_[i].frc_ndx = i + 1; - const auto io_grid_emis = VertEmissionsHorizInterp_[i]->get_src_grid(); + const auto io_grid_emis = VertEmissionsHorizInterp_[i]->get_tgt_grid(); const int num_cols_io_emis = io_grid_emis->get_num_local_dofs(); // Number of columns on this rank const int num_levs_io_emis = From f72cc87ef0e493dae0f26ce31ba2898a1c77eaf0 Mon Sep 17 00:00:00 2001 From: Aaron Donahue Date: Mon, 4 Nov 2024 12:04:50 -0800 Subject: [PATCH 029/147] Add ilev as a default output in all EAMxx output streams This commit follows the example for the geometry data for 'lev' and adds 'ilev'. The variable 'ilev' will now be a default variable in all EAMxx output similar to what is currently done with lat/lon, hyam/hybm, hyai/hybi and lev. Addresses #3022 --- .../dynamics/homme/homme_grids_manager.cpp | 18 +++++-- .../share/grid/mesh_free_grids_manager.cpp | 48 ++++++++++++++----- .../eamxx/src/share/io/scream_io_utils.hpp | 5 +- .../src/share/io/scream_output_manager.cpp | 2 +- 4 files changed, 54 insertions(+), 19 deletions(-) diff --git a/components/eamxx/src/dynamics/homme/homme_grids_manager.cpp b/components/eamxx/src/dynamics/homme/homme_grids_manager.cpp index 87009c7d074e..df5de6827f69 100644 --- a/components/eamxx/src/dynamics/homme/homme_grids_manager.cpp +++ b/components/eamxx/src/dynamics/homme/homme_grids_manager.cpp @@ -271,6 +271,7 @@ build_physics_grid (const ci_string& type, const ci_string& rebalance) { auto hyam = phys_grid->create_geometry_data("hyam",layout_mid,nondim); auto hybm = phys_grid->create_geometry_data("hybm",layout_mid,nondim); auto lev = phys_grid->create_geometry_data("lev", layout_mid,mbar); + auto ilev = phys_grid->create_geometry_data("ilev",layout_int,mbar); for (auto f : {hyai, hybi, hyam, hybm}) { auto f_d = get_grid("Dynamics")->get_geometry_data(f.name()); @@ -281,13 +282,20 @@ build_physics_grid (const ci_string& type, const ci_string& rebalance) { // Build lev from hyam and hybm const Real ps0 = 100000.0; - auto hya_v = hyam.get_view(); - auto hyb_v = hybm.get_view(); - auto lev_v = lev.get_view(); - for (int ii=0;iiget_num_vertical_levels();ii++) { - lev_v(ii) = 0.01*ps0*(hya_v(ii)+hyb_v(ii)); + auto hyam_v = hyam.get_view(); + auto hybm_v = hybm.get_view(); + auto hyai_v = hyai.get_view(); + auto hybi_v = hybi.get_view(); + auto lev_v = lev.get_view(); + auto ilev_v = ilev.get_view(); + auto num_v_levs = phys_grid->get_num_vertical_levels(); + for (int ii=0;iiget_num_vertical_levels()}); + FieldLayout layout_int ({ILEV},{grid->get_num_vertical_levels()}); const auto units = ekat::units::Units::nondimensional(); auto lat = grid->create_geometry_data("lat" , grid->get_2d_scalar_layout(), units); auto lon = grid->create_geometry_data("lon" , grid->get_2d_scalar_layout(), units); auto hyam = grid->create_geometry_data("hyam" , layout_mid, units); auto hybm = grid->create_geometry_data("hybm" , layout_mid, units); + auto hyai = grid->create_geometry_data("hyai" , layout_int, units); + auto hybi = grid->create_geometry_data("hybi" , layout_int, units); auto lev = grid->create_geometry_data("lev" , layout_mid, units); + auto ilev = grid->create_geometry_data("ilev" , layout_int, units); lat.deep_copy(ekat::ScalarTraits::invalid()); lon.deep_copy(ekat::ScalarTraits::invalid()); hyam.deep_copy(ekat::ScalarTraits::invalid()); hybm.deep_copy(ekat::ScalarTraits::invalid()); lev.deep_copy(ekat::ScalarTraits::invalid()); + ilev.deep_copy(ekat::ScalarTraits::invalid()); lat.sync_to_dev(); lon.sync_to_dev(); hyam.sync_to_dev(); hybm.sync_to_dev(); lev.sync_to_dev(); + ilev.sync_to_dev(); } else if (geo_data_source=="IC_FILE"){ const auto& filename = m_params.get("ic_filename"); if (scorpio::has_var(filename,"lat") && @@ -173,7 +179,9 @@ add_geo_data (const nonconstgrid_ptr_type& grid) const } if (scorpio::has_var(filename,"hyam") && - scorpio::has_var(filename,"hybm")) { + scorpio::has_var(filename,"hybm") && + scorpio::has_var(filename,"hyai") && + scorpio::has_var(filename,"hybi") ) { load_vertical_coordinates(grid,filename); } } @@ -234,53 +242,71 @@ load_vertical_coordinates (const nonconstgrid_ptr_type& grid, const std::string& using namespace ekat::units; FieldLayout layout_mid ({LEV},{grid->get_num_vertical_levels()}); + FieldLayout layout_int ({ILEV},{grid->get_num_vertical_levels()}); Units nondim = Units::nondimensional(); Units mbar (100*Pa,"mb"); auto hyam = grid->create_geometry_data("hyam", layout_mid, nondim); auto hybm = grid->create_geometry_data("hybm", layout_mid, nondim); + auto hyai = grid->create_geometry_data("hyai", layout_int, nondim); + auto hybi = grid->create_geometry_data("hybi", layout_int, nondim); auto lev = grid->create_geometry_data("lev", layout_mid, mbar); + auto ilev = grid->create_geometry_data("ilev", layout_int, mbar); // Create host mirrors for reading in data std::map host_views = { { "hyam", hyam.get_view() }, - { "hybm", hybm.get_view() } + { "hybm", hybm.get_view() }, + { "hyai", hyai.get_view() }, + { "hybi", hybi.get_view() } }; // Store view layouts using namespace ShortFieldTagsNames; std::map layouts = { { "hyam", hyam.get_header().get_identifier().get_layout() }, - { "hybm", hybm.get_header().get_identifier().get_layout() } + { "hybm", hybm.get_header().get_identifier().get_layout() }, + { "hyai", hyai.get_header().get_identifier().get_layout() }, + { "hybi", hybi.get_header().get_identifier().get_layout() } }; // Read hyam/hybm into host views ekat::ParameterList vcoord_reader_pl; vcoord_reader_pl.set("Filename",filename); - vcoord_reader_pl.set>("Field Names",{"hyam","hybm"}); + vcoord_reader_pl.set>("Field Names",{"hyam","hybm","hyai","hybi"}); AtmosphereInput vcoord_reader(vcoord_reader_pl,grid, host_views, layouts); vcoord_reader.read_variables(); vcoord_reader.finalize(); - // Build lev from hyam and hybm + // Build lev and ilev from hyam and hybm, and ilev from hyai and hybi using PC = scream::physics::Constants; const Real ps0 = PC::P0; - auto hya_v = hyam.get_view(); - auto hyb_v = hybm.get_view(); - auto lev_v = lev.get_view(); - for (int ii=0;iiget_num_vertical_levels();ii++) { - lev_v(ii) = 0.01*ps0*(hya_v(ii)+hyb_v(ii)); + auto hyam_v = hyam.get_view(); + auto hybm_v = hybm.get_view(); + auto lev_v = lev.get_view(); + auto hyai_v = hyai.get_view(); + auto hybi_v = hybi.get_view(); + auto ilev_v = ilev.get_view(); + auto num_lev = grid->get_num_vertical_levels(); + for (int ii=0;iinum_lev;ii++) { + lev_v(ii) = 0.01*ps0*(hyam_v(ii)+hybm_v(ii)); + ilev_v(ii) = 0.01*ps0*(hyai_v(ii)+hybi_v(ii)); } + // Note, ilev is just 1 more level than the number of midpoint levs + ilev_v(num_lev) = 0.01*ps0*(hyai_v(num_lev)+hybi_v(num_lev)); // Sync to dev hyam.sync_to_dev(); hybm.sync_to_dev(); + hyai.sync_to_dev(); + hybi.sync_to_dev(); lev.sync_to_dev(); + ilev.sync_to_dev(); #ifndef NDEBUG - for (auto f : {hyam, hybm}) { + for (auto f : {hyam, hybm, hyai, hybi}) { auto nan_check = std::make_shared(f,grid)->check(); EKAT_REQUIRE_MSG (nan_check.result==CheckResult::Pass, "ERROR! NaN values detected in " + f.name() + " field.\n" + nan_check.msg); diff --git a/components/eamxx/src/share/io/scream_io_utils.hpp b/components/eamxx/src/share/io/scream_io_utils.hpp index 01bc46e1e601..d6c36ab37583 100644 --- a/components/eamxx/src/share/io/scream_io_utils.hpp +++ b/components/eamxx/src/share/io/scream_io_utils.hpp @@ -85,8 +85,9 @@ struct LongNames { // Create map of longnames, can be added to as developers see fit. std::map name_2_longname = { - {"lev","hybrid level at midpoints (1000*(A+B))"}, - {"hyai","hybrid A coefficient at layer interfaces"}, + {"lev","hybrid level at midpoints (1000*(A+B))"}, + {"ilev","hybrid level at interfaces (1000*(A+B))"}, + {"hyai","hybrid A coefficient at layer interfaces"}, {"hybi","hybrid B coefficient at layer interfaces"}, {"hyam","hybrid A coefficient at layer midpoints"}, {"hybm","hybrid B coefficient at layer midpoints"} diff --git a/components/eamxx/src/share/io/scream_output_manager.cpp b/components/eamxx/src/share/io/scream_output_manager.cpp index 0628a889be9d..4ac141c42e1d 100644 --- a/components/eamxx/src/share/io/scream_output_manager.cpp +++ b/components/eamxx/src/share/io/scream_output_manager.cpp @@ -402,7 +402,7 @@ void OutputManager::run(const util::TimeStamp& timestamp) // Check if we need to open a new file if (not filespecs.is_open) { filespecs.filename = compute_filename (filespecs,timestamp); - // Register all dims/vars, write geometry data (e.g. lat/lon/hyam/hybm) + // Register all dims/vars, write geometry data (e.g. lat/lon/hyam/hybm/hyai/hybi) setup_file(filespecs,control); } From a2b0af0ae7df8a91ce9aaf364961f1bb004c261f Mon Sep 17 00:00:00 2001 From: James Foucar Date: Mon, 4 Nov 2024 13:08:03 -0700 Subject: [PATCH 030/147] p3_run_and_cmp fixed up --- .../eamxx/src/physics/p3/tests/CMakeLists.txt | 42 +++++----- .../src/physics/p3/tests/p3_run_and_cmp.cpp | 78 +++++++++++-------- 2 files changed, 66 insertions(+), 54 deletions(-) diff --git a/components/eamxx/src/physics/p3/tests/CMakeLists.txt b/components/eamxx/src/physics/p3/tests/CMakeLists.txt index d5980d91cbf6..663462790189 100644 --- a/components/eamxx/src/physics/p3/tests/CMakeLists.txt +++ b/components/eamxx/src/physics/p3/tests/CMakeLists.txt @@ -62,13 +62,15 @@ CreateUnitTest(p3_tests "${P3_TESTS_SRCS}" LABELS "p3;physics") # Make sure that a diff in the two implementation triggers a failed test (in debug only) -CreateUnitTest (p3_tests_fail p3_rain_sed_unit_tests.cpp - LIBS p3 - EXE_ARGS "--flags='${BASELINE_FILE_ARG}'" - COMPILER_CXX_DEFS SCREAM_FORCE_RUN_DIFF - THREADS 1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC} - LABELS "p3;physics;fail" - ${FORCE_RUN_DIFF_FAILS}) +if (SCREAM_ENABLE_BASELINE_TESTS) + CreateUnitTest (p3_tests_fail p3_rain_sed_unit_tests.cpp + LIBS p3 + EXE_ARGS "--flags='${BASELINE_FILE_ARG}'" + COMPILER_CXX_DEFS SCREAM_FORCE_RUN_DIFF + THREADS 1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC} + LABELS "p3;physics;fail" + ${FORCE_RUN_DIFF_FAILS}) +endif() if (NOT SCREAM_P3_SMALL_KERNELS) CreateUnitTest(p3_sk_tests "${P3_TESTS_SRCS}" @@ -87,24 +89,24 @@ if (NOT SCREAM_P3_SMALL_KERNELS) ${FORCE_RUN_DIFF_FAILS}) endif() -CreateUnitTestExec(p3_run_and_cmp "p3_run_and_cmp.cpp" +CreateUnitTest(p3_run_and_cmp "p3_run_and_cmp.cpp" LIBS p3 - EXCLUDE_MAIN_CPP) - -CreateUnitTestFromExec(p3_run_and_cmp_cxx p3_run_and_cmp + EXCLUDE_MAIN_CPP THREADS ${SCREAM_TEST_MAX_THREADS} EXE_ARGS "${BASELINE_FILE_ARG}" LABELS "p3;physics") # Make sure that a diff from baselines triggers a failed test (in debug only) -CreateUnitTest(p3_run_and_cmp_cxx_fail "p3_run_and_cmp.cpp" - LIBS p3 - COMPILER_CXX_DEFS SCREAM_FORCE_RUN_DIFF - THREADS ${SCREAM_TEST_MAX_THREADS} - EXE_ARGS "${BASELINE_FILE_ARG}" - LABELS "p3;physics;fail" - EXCLUDE_MAIN_CPP - ${FORCE_RUN_DIFF_FAILS}) +if (SCREAM_ENABLE_BASELINE_TESTS) + CreateUnitTest(p3_run_and_cmp_fail "p3_run_and_cmp.cpp" + LIBS p3 + COMPILER_CXX_DEFS SCREAM_FORCE_RUN_DIFF + THREADS ${SCREAM_TEST_MAX_THREADS} + EXE_ARGS "${BASELINE_FILE_ARG}" + LABELS "p3;physics;fail" + EXCLUDE_MAIN_CPP + ${FORCE_RUN_DIFF_FAILS}) +endif() # Note: the baseline_gen label label is really only used if SCREAM_ONLY_GENERATE_BASELINES=ON, but no harm adding it if (SCREAM_TEST_MAX_THREADS GREATER 1) @@ -112,4 +114,4 @@ if (SCREAM_TEST_MAX_THREADS GREATER 1) set (TEST_SUFFIX _omp${SCREAM_TEST_MAX_THREADS}) endif() -set_tests_properties (p3_run_and_cmp_cxx${TEST_SUFFIX} PROPERTIES LABELS "baseline_gen;cxx baseline_cmp") +set_tests_properties (p3_run_and_cmp${TEST_SUFFIX} PROPERTIES LABELS "baseline_gen;cxx baseline_cmp") diff --git a/components/eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp b/components/eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp index 5bc12b2464db..9e491cea6a42 100644 --- a/components/eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp @@ -75,7 +75,7 @@ struct Baseline { } } - Int generate_baseline (const std::string& filename, bool use_fortran) { + Int generate_baseline (const std::string& filename) { auto fid = ekat::FILEPtr(fopen(filename.c_str(), "w")); EKAT_REQUIRE_MSG( fid, "generate_baseline can't write " << filename); Int nerr = 0; @@ -93,16 +93,13 @@ struct Baseline { std::cout << "Running P3 with ni=" << d->ncol << ", nk=" << d->nlev << ", dt=" << d->dt << ", ts=" << d->it << ", predict_nc=" << d->do_predict_nc - << ", prescribed_CCN=" << d->do_prescribed_CCN; - - if (!use_fortran) { - std::cout << ", small_packn=" << SCREAM_SMALL_PACK_SIZE; - } - std::cout << std::endl; + << ", prescribed_CCN=" << d->do_prescribed_CCN + << ", small_packn=" << SCREAM_SMALL_PACK_SIZE + << std::endl; } for (int it=0; it 0) { // do not count the "cold" run total_duration_microsec += current_microsec; @@ -123,29 +120,40 @@ struct Baseline { return nerr; } - Int run_and_cmp (const std::string& filename, const double& tol, bool use_fortran) { + Int run_and_cmp (const std::string& filename, const double& tol, bool no_baseline) { auto fid = ekat::FILEPtr(fopen(filename.c_str(), "r")); EKAT_REQUIRE_MSG( fid, "generate_baseline can't read " << filename); Int nerr = 0, ne; int case_num = 0; for (auto ps : params_) { case_num++; - // Read the reference impl's data from the baseline file. - const auto d_ref = ic::Factory::create(ps.ic, ps.ncol, ps.nlev); - set_params(ps, *d_ref); - // Now run a sequence of other impls. This includes the reference - // implementation b/c it's likely we'll want to change it as we go. - { + if (no_baseline) { const auto d = ic::Factory::create(ps.ic, ps.ncol, ps.nlev); set_params(ps, *d); p3_init(); for (int it=0; it Path to directory containing baselines.\n" " -t Tolerance for relative error. Default 0.\n" " -s Number of timesteps. Default=6.\n" " -dt Length of timestep. Default=300.\n" " -i Number of columns. Default=3.\n" " -k Number of vertical levels. Default=72.\n" " -r Number of repetitions, implies timing run (generate + no I/O). Default=0.\n" - " -p yes|no|both. Default=both.\n" - " -c yes|no|both. Default=both.\n"; + " --predict-nc yes|no|both. Default=both.\n" + " --prescribed-ccn yes|no|both. Default=both.\n"; return 1; } - bool generate = false, use_fortran = false; + bool generate = false, no_baseline = true; scream::Real tol = SCREAM_BFB_TESTING ? 0 : std::numeric_limits::infinity(); Int timesteps = 6; Int dt = 300; @@ -247,8 +257,8 @@ int main (int argc, char** argv) { std::string prescribed_ccn = "both"; std::string baseline_fn; for (int i = 1; i < argc-1; ++i) { - if (ekat::argv_matches(argv[i], "-g", "--generate")) generate = true; - if (ekat::argv_matches(argv[i], "-f", "--fortran")) use_fortran = true; + if (ekat::argv_matches(argv[i], "-g", "--generate")) { generate = true; no_baseline = false; } + if (ekat::argv_matches(argv[i], "-c", "--compare")) { no_baseline = false; } if (ekat::argv_matches(argv[i], "-t", "--tol")) { expect_another_arg(i, argc); ++i; @@ -292,14 +302,14 @@ int main (int argc, char** argv) { generate = true; } } - if (ekat::argv_matches(argv[i], "-p", "--predict-nc")) { + if (ekat::argv_matches(argv[i], "-pn", "--predict-nc")) { expect_another_arg(i, argc); ++i; predict_nc = std::string(argv[i]); EKAT_REQUIRE_MSG(predict_nc == "yes" || predict_nc == "no" || predict_nc == "both", "Predict option value must be one of yes|no|both"); } - if (ekat::argv_matches(argv[i], "-c", "--prescribed-ccn")) { + if (ekat::argv_matches(argv[i], "-pc", "--prescribed-ccn")) { expect_another_arg(i, argc); ++i; prescribed_ccn = std::string(argv[i]); @@ -308,8 +318,8 @@ int main (int argc, char** argv) { } } - // Decorate baseline name with precision. - baseline_fn += std::to_string(sizeof(scream::Real)); + // Compute full baseline file name with precision. + baseline_fn += "/p3_run_and_cmp.baseline" + std::to_string(sizeof(scream::Real)); std::vector args; for (int i=0; i(dt), ncol, nlev, repeat, predict_nc, prescribed_ccn); if (generate) { std::cout << "Generating to " << baseline_fn << "\n"; - nerr += bln.generate_baseline(baseline_fn, use_fortran); + nerr += bln.generate_baseline(baseline_fn); } else { printf("Comparing with %s at tol %1.1e\n", baseline_fn.c_str(), tol); - nerr += bln.run_and_cmp(baseline_fn, tol, use_fortran); + nerr += bln.run_and_cmp(baseline_fn, tol, no_baseline); } P3GlobalForFortran::deinit(); } scream::finalize_scream_session(); From 5e46e3373a0c246ec081a1c2142a6548a05be3a3 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Mon, 4 Nov 2024 13:37:43 -0700 Subject: [PATCH 031/147] Progress. Can not remove fortran --- .../p3/tests/p3_cloud_sed_unit_tests.cpp | 2 +- .../p3/tests/p3_evaporate_rain_unit_tests.cpp | 2 +- .../p3_ice_deposition_sublimation_tests.cpp | 2 +- .../p3/tests/p3_ice_sed_unit_tests.cpp | 6 +-- .../p3_ice_supersat_conservation_tests.cpp | 2 +- .../p3/tests/p3_nc_conservation_tests.cpp | 2 +- .../p3/tests/p3_ni_conservation_tests.cpp | 2 +- .../p3/tests/p3_nr_conservation_tests.cpp | 2 +- .../p3_prevent_liq_supersaturation_tests.cpp | 2 +- .../p3/tests/p3_rain_sed_unit_tests.cpp | 40 +++++++++---------- .../src/physics/p3/tests/p3_unit_tests.cpp | 6 +-- 11 files changed, 34 insertions(+), 34 deletions(-) diff --git a/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp index ace2523fc2d9..29fbdad8aef0 100644 --- a/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp @@ -46,7 +46,7 @@ void run_bfb() d.randomize(engine, { {d.qc_incld, {C::QSMALL/2, C::QSMALL*2}} }); } - // Create copies of data for use by cxx. Needs to happen before fortran calls so that + // Create copies of data for use by cxx. Needs to happen before reads so that // inout data is in original state CloudSedData csds_cxx[num_runs] = { CloudSedData(csds_baseline[0]), diff --git a/components/eamxx/src/physics/p3/tests/p3_evaporate_rain_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_evaporate_rain_unit_tests.cpp index c5626e0387cc..a17165bafdd2 100644 --- a/components/eamxx/src/physics/p3/tests/p3_evaporate_rain_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_evaporate_rain_unit_tests.cpp @@ -132,7 +132,7 @@ struct UnitWrap::UnitTest::TestEvapSublPrecip : public UnitWrap::UnitTest: constexpr Scalar latvap = C::LatVap; constexpr Scalar latice = C::LatIce; - //fortran generated data is input to the following + //baseline generated data is input to the following //This subroutine has 20 args, only 18 are supplied here for invoking it as last 2 are intent-outs //note that dt is the same val for each row - this is needed since dt is a scalar and all rows are executed simultaneously on CPU in C++. //row1: above freezing, should trigger diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_deposition_sublimation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_deposition_sublimation_tests.cpp index b359ad661e95..7a52c1b42f0b 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_deposition_sublimation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_deposition_sublimation_tests.cpp @@ -74,7 +74,7 @@ struct UnitWrap::UnitTest::TestIceDepositionSublimation : public UnitWrap::Un // d.randomize(); //} - // Create copies of data for use by cxx and sync it to device. Needs to happen before fortran calls so that + // Create copies of data for use by cxx and sync it to device. Needs to happen before reads so that // inout data is in original state view_1d cxx_device("cxx_device", max_pack_size); const auto cxx_host = Kokkos::create_mirror_view(cxx_device); diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp index 3afcc6af92b5..f63e0badfb06 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp @@ -71,7 +71,7 @@ void run_bfb_calc_bulk_rhime() {5.164017E-10, 0.000000E+00, 0.000000E+00}, }; - // Sync to device, needs to happen before fortran calls so that + // Sync to device, needs to happen before reads so that // inout data is in original state view_1d cbrr_device("cbrr", max_pack_size); const auto cbrr_host = Kokkos::create_mirror_view(cbrr_device); @@ -150,7 +150,7 @@ void run_bfb_ice_sed() d.randomize(engine, { {d.qi_incld, {C::QSMALL/2, C::QSMALL*2}} }); } - // Create copies of data for use by cxx. Needs to happen before fortran calls so that + // Create copies of data for use by cxx. Needs to happen before reads so that // inout data is in original state IceSedData isds_cxx[num_runs] = { IceSedData(isds_baseline[0]), @@ -233,7 +233,7 @@ void run_bfb_homogeneous_freezing() } } - // Create copies of data for use by cxx. Needs to happen before fortran calls so that + // Create copies of data for use by cxx. Needs to happen before reads so that // inout data is in original state HomogeneousFreezingData hfds_cxx[num_runs] = { HomogeneousFreezingData(hfds_baseline[0]), diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp index e71463f1e257..c15c1383ab73 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp @@ -36,7 +36,7 @@ struct UnitWrap::UnitTest::TestIceSupersatConservation : public UnitWrap::Uni d.latent_heat_sublim = latvap+latice; } - // Create copies of data for use by cxx and sync it to device. Needs to happen before fortran calls so that + // Create copies of data for use by cxx and sync it to device. Needs to happen before reads so that // inout data is in original state view_1d cxx_device("cxx_device", max_pack_size); const auto cxx_host = Kokkos::create_mirror_view(cxx_device); diff --git a/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp index 0161566d5396..e13d49affc07 100644 --- a/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp @@ -29,7 +29,7 @@ struct UnitWrap::UnitTest::TestNcConservation : public UnitWrap::UnitTest: d.dt = baseline_data[0].dt; // Hold this fixed, this is not packed data } - // Create copies of data for use by cxx and sync it to device. Needs to happen before fortran calls so that + // Create copies of data for use by cxx and sync it to device. Needs to happen before reads so that // inout data is in original state view_1d cxx_device("cxx_device", max_pack_size); const auto cxx_host = Kokkos::create_mirror_view(cxx_device); diff --git a/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp index c5feff71ea88..2f2db25d1d7a 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp @@ -29,7 +29,7 @@ struct UnitWrap::UnitTest::TestNiConservation : public UnitWrap::UnitTest: d.dt = baseline_data[0].dt; // hold dt fixed, it is not packed data } - // Create copies of data for use by cxx and sync it to device. Needs to happen before fortran calls so that + // Create copies of data for use by cxx and sync it to device. Needs to happen before reads so that // inout data is in original state view_1d cxx_device("cxx_device", max_pack_size); const auto cxx_host = Kokkos::create_mirror_view(cxx_device); diff --git a/components/eamxx/src/physics/p3/tests/p3_nr_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_nr_conservation_tests.cpp index c268a763d79a..5b8b0d839511 100644 --- a/components/eamxx/src/physics/p3/tests/p3_nr_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_nr_conservation_tests.cpp @@ -30,7 +30,7 @@ struct UnitWrap::UnitTest::TestNrConservation : public UnitWrap::UnitTest: d.nmltratio = baseline_data[0].nmltratio; // hold nmltratio fixed, it is not packed data } - // Create copies of data for use by cxx and sync it to device. Needs to happen before fortran calls so that + // Create copies of data for use by cxx and sync it to device. Needs to happen before reads so that // inout data is in original state view_1d cxx_device("cxx_device", max_pack_size); const auto cxx_host = Kokkos::create_mirror_view(cxx_device); diff --git a/components/eamxx/src/physics/p3/tests/p3_prevent_liq_supersaturation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_prevent_liq_supersaturation_tests.cpp index acd7e7d74541..c4f95b28c836 100644 --- a/components/eamxx/src/physics/p3/tests/p3_prevent_liq_supersaturation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_prevent_liq_supersaturation_tests.cpp @@ -110,7 +110,7 @@ struct UnitWrap::UnitTest::TestPreventLiqSupersaturation : public UnitWrap::U } // Create copies of data for use by cxx and sync it to device. Needs to happen before - // fortran calls so that inout data is in original state + // reads so that inout data is in original state view_1d cxx_device("cxx_device", max_pack_size); const auto cxx_host = Kokkos::create_mirror_view(cxx_device); std::copy(&baseline_data[0], &baseline_data[0] + max_pack_size, cxx_host.data()); diff --git a/components/eamxx/src/physics/p3/tests/p3_rain_sed_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_rain_sed_unit_tests.cpp index 22f0c50b41df..abad922cfb40 100644 --- a/components/eamxx/src/physics/p3/tests/p3_rain_sed_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_rain_sed_unit_tests.cpp @@ -147,7 +147,7 @@ void run_bfb_rain_sed() constexpr Scalar dt = 1.800E+03; #endif - RainSedData rsds_fortran[] = { + RainSedData rsds_baseline[] = { // kts, kte, ktop, kbot, kdir, dt, inv_dt, precip_liq_surf RainSedData(1, 72, 27, 72, -1, dt, 1/dt, 0.0), RainSedData(1, 72, 72, 27, 1, dt, 1/dt, 1.0), @@ -155,27 +155,27 @@ void run_bfb_rain_sed() RainSedData(1, 72, 27, 27, 1, dt, 1/dt, 2.0), }; - static constexpr Int num_runs = sizeof(rsds_fortran) / sizeof(RainSedData); + static constexpr Int num_runs = sizeof(rsds_baseline) / sizeof(RainSedData); // Set up random input data - for (auto& d : rsds_fortran) { + for (auto& d : rsds_baseline) { d.randomize(engine, { {d.qr_incld, {C::QSMALL/2, C::QSMALL*2}} }); } // Create copies of data for use by cxx. Needs to happen before reads so that // inout data is in original state RainSedData rsds_cxx[num_runs] = { - RainSedData(rsds_fortran[0]), - RainSedData(rsds_fortran[1]), - RainSedData(rsds_fortran[2]), - RainSedData(rsds_fortran[3]), + RainSedData(rsds_baseline[0]), + RainSedData(rsds_baseline[1]), + RainSedData(rsds_baseline[2]), + RainSedData(rsds_baseline[3]), }; // Read baseline data std::string baseline_name = this->m_baseline_path + "/rain_sed.dat"; if (this->m_baseline_action == COMPARE) { auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); - for (auto& d : rsds_fortran) { + for (auto& d : rsds_baseline) { d.read(fid); } } @@ -198,20 +198,20 @@ void run_bfb_rain_sed() if (SCREAM_BFB_TESTING && this->m_baseline_action == COMPARE) { for (Int i = 0; i < num_runs; ++i) { // Due to pack issues, we must restrict checks to the active k space - Int start = std::min(rsds_fortran[i].kbot, rsds_fortran[i].ktop) - 1; // 0-based indx - Int end = std::max(rsds_fortran[i].kbot, rsds_fortran[i].ktop); // 0-based indx + Int start = std::min(rsds_baseline[i].kbot, rsds_baseline[i].ktop) - 1; // 0-based indx + Int end = std::max(rsds_baseline[i].kbot, rsds_baseline[i].ktop); // 0-based indx for (Int k = start; k < end; ++k) { - REQUIRE(rsds_fortran[i].qr[k] == rsds_cxx[i].qr[k]); - REQUIRE(rsds_fortran[i].nr[k] == rsds_cxx[i].nr[k]); - REQUIRE(rsds_fortran[i].nr_incld[k] == rsds_cxx[i].nr_incld[k]); - REQUIRE(rsds_fortran[i].mu_r[k] == rsds_cxx[i].mu_r[k]); - REQUIRE(rsds_fortran[i].lamr[k] == rsds_cxx[i].lamr[k]); - REQUIRE(rsds_fortran[i].precip_liq_flux[k] == rsds_cxx[i].precip_liq_flux[k]); - REQUIRE(rsds_fortran[i].qr_tend[k] == rsds_cxx[i].qr_tend[k]); - REQUIRE(rsds_fortran[i].nr_tend[k] == rsds_cxx[i].nr_tend[k]); + REQUIRE(rsds_baseline[i].qr[k] == rsds_cxx[i].qr[k]); + REQUIRE(rsds_baseline[i].nr[k] == rsds_cxx[i].nr[k]); + REQUIRE(rsds_baseline[i].nr_incld[k] == rsds_cxx[i].nr_incld[k]); + REQUIRE(rsds_baseline[i].mu_r[k] == rsds_cxx[i].mu_r[k]); + REQUIRE(rsds_baseline[i].lamr[k] == rsds_cxx[i].lamr[k]); + REQUIRE(rsds_baseline[i].precip_liq_flux[k] == rsds_cxx[i].precip_liq_flux[k]); + REQUIRE(rsds_baseline[i].qr_tend[k] == rsds_cxx[i].qr_tend[k]); + REQUIRE(rsds_baseline[i].nr_tend[k] == rsds_cxx[i].nr_tend[k]); } - REQUIRE(rsds_fortran[i].precip_liq_flux[end] == rsds_cxx[i].precip_liq_flux[end]); - REQUIRE(rsds_fortran[i].precip_liq_surf == rsds_cxx[i].precip_liq_surf); + REQUIRE(rsds_baseline[i].precip_liq_flux[end] == rsds_cxx[i].precip_liq_flux[end]); + REQUIRE(rsds_baseline[i].precip_liq_surf == rsds_cxx[i].precip_liq_surf); } } else if (this->m_baseline_action == GENERATE) { diff --git a/components/eamxx/src/physics/p3/tests/p3_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_unit_tests.cpp index 9bf227602798..2c1971f0ba9d 100644 --- a/components/eamxx/src/physics/p3/tests/p3_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_unit_tests.cpp @@ -513,7 +513,7 @@ struct UnitWrap::UnitTest::TestP3UpdatePrognosticIce : public UnitWrap::UnitT constexpr Scalar latvap = C::LatVap; constexpr Scalar latice = C::LatIce; - //fortran generated data is input to the following + //baseline generated data is input to the following P3UpdatePrognosticIceData pupidc[max_pack_size] = { {4.9078E-19, 1.5312E-09, 4.4387E-09, 3.7961E+06, 1.7737E-04, 0.0000E+00, 3.8085E-08, 5.1281E+04, 1.9251E-15, @@ -748,7 +748,7 @@ struct UnitWrap::UnitTest::TestGetTimeSpacePhysVariables : public UnitWrap::U constexpr Scalar latvap = C::LatVap; constexpr Scalar latice = C::LatIce; - //fortran generated data is input to the following + //baseline generated data is input to the following GetTimeSpacePhysVarsData gtspvd[max_pack_size] = { // T_atm, pres, rho, latent_heat_vapor, latent_heat_sublim, qv_sat_l, qv_sat_i {2.9792E+02, 9.8711E+04, 1.1532E+00, latvap, latvap+latice, 2.0321E-02, 2.0321E-02}, @@ -870,7 +870,7 @@ struct UnitWrap::UnitTest::TestP3UpdatePrognosticLiq : public UnitWrap::UnitT void update_prognostic_liquid_unit_bfb_tests() { constexpr Scalar latvap = C::LatVap; - //fortran generated data is input to the following + //baseline generated data is input to the following P3UpdatePrognosticLiqData pupldc[max_pack_size] = { {1.0631E-12, 1.0631E+00, 1.5833E-12, 1.5833E+00, 2.4190E-02, 0.0000E+00, 0.0000E+00, 0.0000E+00, 4.2517E+00, From 58b70ac410615b646d8cd83161b1792512e56b51 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Mon, 4 Nov 2024 15:29:00 -0700 Subject: [PATCH 032/147] Remove most of the f90 bridges --- .../eamxx/src/physics/p3/p3_functions_f90.cpp | 671 +------------- .../eamxx/src/physics/p3/p3_functions_f90.hpp | 144 +-- components/eamxx/src/physics/p3/p3_iso_c.f90 | 821 ------------------ .../eamxx/src/physics/p3/p3_main_wrap.cpp | 58 +- .../eamxx/src/physics/p3/p3_main_wrap.hpp | 5 +- .../eamxx/src/physics/p3/tests/CMakeLists.txt | 12 +- .../p3_back_to_cell_average_unit_tests.cpp | 4 - .../p3/tests/p3_check_values_unit_tests.cpp | 2 +- .../p3/tests/p3_cloud_sed_unit_tests.cpp | 2 +- .../p3/tests/p3_ice_sed_unit_tests.cpp | 4 +- .../physics/p3/tests/p3_main_unit_tests.cpp | 8 +- .../p3/tests/p3_rain_sed_unit_tests.cpp | 2 +- .../eamxx/src/physics/p3/tests/p3_tests.cpp | 7 +- .../physics/p3/tests/p3_upwind_unit_tests.cpp | 4 +- 14 files changed, 101 insertions(+), 1643 deletions(-) diff --git a/components/eamxx/src/physics/p3/p3_functions_f90.cpp b/components/eamxx/src/physics/p3/p3_functions_f90.cpp index b5e051a4d112..40d5342a31fc 100644 --- a/components/eamxx/src/physics/p3/p3_functions_f90.cpp +++ b/components/eamxx/src/physics/p3/p3_functions_f90.cpp @@ -11,275 +11,22 @@ using scream::Real; using scream::Int; -// -// A C++ interface to micro_p3 fortran calls and vice versa -// extern "C" { void p3_init_a_c(Real* ice_table_vals, Real* collect_table_vals); -void find_lookuptable_indices_1a_c(Int* dumi, Int* dumjj, Int* dumii, Int* dumzz, - Real* dum1, Real* dum4, Real* dum5, Real* dum6, - Real qi, Real ni, Real qm, Real rhop); - -void find_lookuptable_indices_1b_c(Int* dumj, Real* dum3, Real qr, Real nr); - -void access_lookup_table_c(Int dumjj, Int dumii, Int dumi, Int index, - Real dum1, Real dum4, Real dum5, Real* proc); - -void access_lookup_table_coll_c(Int dumjj, Int dumii, Int dumj, Int dumi, Int index, - Real dum1, Real dum3, Real dum4, Real dum5, Real* proc); - -void back_to_cell_average_c(Real cld_frac_l_, Real cld_frac_r_, Real cld_frac_i_, - Real* qc2qr_accret_tend_, Real* qr2qv_evap_tend_, Real* qc2qr_autoconv_tend_, - Real* nc_accret_tend_, Real* nc_selfcollect_tend_, Real* nc2nr_autoconv_tend_, - Real* nr_selfcollect_tend_, Real* nr_evap_tend_, Real* ncautr_, - Real* qi2qv_sublim_tend_, - Real* nr_ice_shed_tend_, Real* qc2qi_hetero_freeze_tend_, Real* qr2qi_collect_tend_, - Real* qc2qr_ice_shed_tend_, Real* qi2qr_melt_tend_, Real* qc2qi_collect_tend_, - Real* qr2qi_immers_freeze_tend_, Real* ni2nr_melt_tend_, Real* nc_collect_tend_, - Real* ncshdc_, Real* nc2ni_immers_freeze_tend_, Real* nr_collect_tend_, - Real* ni_selfcollect_tend_, Real* qv2qi_vapdep_tend_, Real* nr2ni_immers_freeze_tend_, - Real* ni_sublim_tend_, Real* qv2qi_nucleat_tend_, Real* ni_nucleat_tend_, - Real* qc2qi_berg_tend_); - -void cloud_water_conservation_c(Real qc, Real dt, Real* qc2qr_autoconv_tend, Real* qc2qr_accret_tend, Real* qc2qi_collect_tend, - Real* qc2qi_hetero_freeze_tend, Real* qc2qr_ice_shed_tend, Real* qc2qi_berg_tend, Real* qi2qv_sublim_tend, Real* qv2qi_vapdep_tend); - -void rain_water_conservation_c(Real qr, Real qc2qr_autoconv_tend, Real qc2qr_accret_tend, Real qi2qr_melt_tend, Real qc2qr_ice_shed_tend, - Real dt, Real* qr2qv_evap_tend, Real* qr2qi_collect_tend, Real* qr2qi_immers_freeze_tend); - -void ice_water_conservation_c(Real qi, Real qv2qi_vapdep_tend, Real qv2qi_nucleat_tend, Real qc2qi_berg_tend, Real qr2qi_collect_tend, Real qc2qi_collect_tend, - Real qr2qi_immers_freeze_tend, Real qc2qi_hetero_freeze_tend, Real dt, Real* qi2qv_sublim_tend, Real* qi2qr_melt_tend); - -void get_cloud_dsd2_c(Real qc, Real* nc, Real* mu_c, Real rho, Real* nu, Real* lamc, - Real* cdist, Real* cdist1); - -void get_rain_dsd2_c(Real qr, Real* nr, Real* mu_r, Real* lamr, Real* cdistr, Real* logn0r); - -void calc_rime_density_c(Real T_atm, Real rhofaci, Real table_val_qi_fallspd, Real acn, - Real lamc, Real mu_c, Real qc_incld, Real qc2qi_collect_tend, - Real* vtrmi1, Real* rho_qm_cloud); - -void cldliq_immersion_freezing_c(Real T_atm, Real lamc, Real mu_c, Real cdist1, - Real qc_incld, Real inv_qc_relvar, Real* qc2qi_hetero_freeze_tend, Real* nc2ni_immers_freeze_tend); - -void rain_immersion_freezing_c(Real T_atm, Real lamr, Real mu_r, Real cdistr, - Real qr_incld, Real* qr2qi_immers_freeze_tend, Real* nr2ni_immers_freeze_tend); - -void droplet_self_collection_c(Real rho, Real inv_rho, Real qc_incld, Real mu_c, - Real nu, Real nc2nr_autoconv_tend, Real* nc_accret_tend); - -void cloud_rain_accretion_c(Real rho, Real inv_rho, Real qc_incld, Real nc_incld, - Real qr_incld, Real inv_qc_relvar, Real* qc2qr_accret_tend, Real* nc_accret_tend); - -void cloud_water_autoconversion_c(Real rho, Real qc_incld, Real nc_incld, Real inv_qc_relvar, Real* qc2qr_autoconv_tend, Real* nc2nr_autoconv_tend, Real* ncautr); - -void rain_self_collection_c(Real rho, Real qr_incld, Real nr_incld, Real* nr_selfcollect_tend); - -void impose_max_total_ni_c(Real* ni_local, Real max_total_ni, Real inv_rho_local); - -void ice_melting_c(Real rho,Real T_atm,Real pres,Real rhofaci,Real table_val_qi2qr_melting,Real table_val_qi2qr_vent_melt, - Real latent_heat_vapor,Real latent_heat_fusion,Real dv,Real sc,Real mu,Real kap,Real qv,Real qi_incld, - Real ni_incld,Real* qi2qr_melt_tend,Real* ni2nr_melt_tend); - -void calc_first_order_upwind_step_c(Int kts, Int kte, Int kdir, Int kbot, Int k_qxtop, Real dt_sub, Real* rho, - Real* inv_rho, Real* inv_dz, Int num_arrays, Real** fluxes, Real** vs, Real** qnx); - -void generalized_sedimentation_c(Int kts, Int kte, Int kdir, Int k_qxtop, Int* k_qxbot, Int kbot, Real Co_max, - Real* dt_left, Real* prt_accum, Real* inv_dz, Real* inv_rho, Real* rho, - Int num_arrays, Real** vs, Real** fluxes, Real** qnx); -void cloud_sedimentation_c( - Int kts, Int kte, Int ktop, Int kbot, Int kdir, - Real* qc_incld, Real* rho, Real* inv_rho, Real* cld_frac_l, Real* acn, Real* inv_dz, - Real dt, Real inv_dt, bool do_predict_nc, - Real* qc, Real* nc, Real* nc_incld, Real* mu_c, Real* lamc, Real* precip_liq_surf, Real* qc_tend, Real* nc_tend); - -void ice_sedimentation_c( - Int kts, Int kte, Int ktop, Int kbot, Int kdir, - Real* rho, Real* inv_rho, Real* rhofaci, Real* cld_frac_i, Real* inv_dz, - Real dt, Real inv_dt, - Real* qi, Real* qi_incld, Real* ni, Real* qm, Real* qm_incld, Real* bm, Real* bm_incld, - Real* ni_incld, Real* precip_ice_surf, Real* qi_tend, Real* ni_tend); - -void rain_sedimentation_c( - Int kts, Int kte, Int ktop, Int kbot, Int kdir, - Real* qr_incld, Real* rho, Real* inv_rho, Real* rhofacr, Real* cld_frac_r, Real* inv_dz, - Real dt, Real inv_dt, - Real* qr, Real* nr, Real* nr_incld, Real* mu_r, Real* lamr, Real* precip_liq_surf, Real* precip_liq_flux, Real* qr_tend, Real* nr_tend); - -void calc_bulk_rho_rime_c(Real qi_tot, Real* qi_rim, Real* bi_rim, Real* rho_rime); - -void homogeneous_freezing_c( - Int kts, Int kte, Int ktop, Int kbot, Int kdir, - Real* T_atm, Real* inv_exner, Real* latent_heat_fusion, - Real* qc, Real* nc, Real* qr, Real* nr, Real* qi, Real* ni, Real* qm, Real* bm, Real* th_atm); - -void get_time_space_phys_variables_c(Real T_atm, Real pres, Real rho, Real latent_heat_vapor, Real latent_heat_sublim, Real qv_sat_l, Real qv_sat_i, - Real* mu, Real* dv, Real* sc, Real* dqsdt, Real* dqsidt, Real* ab, Real* abi, Real* kap, Real* eii); - -void update_prognostic_ice_c( - Real qc2qi_hetero_freeze_tend, Real qc2qi_collect_tend, Real qc2qr_ice_shed_tend, Real nc_collect_tend, Real nc2ni_immers_freeze_tend, Real ncshdc, - Real qr2qi_collect_tend, Real nr_collect_tend, Real qr2qi_immers_freeze_tend, Real nr2ni_immers_freeze_tend, Real nr_ice_shed_tend, - Real qi2qr_melt_tend, Real ni2nr_melt_tend, Real qi2qv_sublim_tend, Real qv2qi_vapdep_tend, Real qv2qi_nucleat_tend, Real ni_nucleat_tend, - Real ni_selfcollect_tend, Real ni_sublim_tend, Real qc2qi_berg_tend, Real inv_exner, Real latent_heat_sublim, Real latent_heat_fusion, - bool do_predict_nc, bool log_wetgrowth, Real dt, Real nmltratio, - Real rho_qm_cloud, Real* th_atm, Real* qv, Real* qi, Real* ni, Real* qm, - Real* bm, Real* qc, Real* nc, Real* qr, Real* nr); - -void evaporate_rain_c( Real qr_incld, Real qc_incld, Real nr_incld, Real qi_incld, - Real cld_frac_l, Real cld_frac_r, Real qv, Real qv_prev, - Real qv_sat_l, Real qv_sat_i, Real ab, Real abi, - Real epsr, Real epsi_tot, Real t, Real t_prev, - Real latent_heat_sublim, Real dqsdt, Real dt, - Real* qr2qv_evap_tend, Real* nr_evap_tend); - -void update_prognostic_liquid_c( - Real qc2qr_accret_tend, Real nc_accret_tend, Real qc2qr_autoconv_tend, Real nc2nr_autoconv_tend, Real ncautr, - Real nc_selfcollect_tend, Real qr2qv_evap_tend, Real nr_evap_tend, Real nr_selfcollect_tend , bool do_predict_nc, bool do_prescribed_CCN, - Real inv_rho, Real inv_exner, Real latent_heat_vapor, Real dt, Real* th_atm, Real* qv, - Real* qc, Real* nc, Real* qr, Real* nr); - -void ice_deposition_sublimation_c(Real qi_incld, Real ni_incld, Real t_atm, Real qv_sat_l, Real qv_sat_i, Real epsi, Real abi, Real qv, Real inv_dt, Real* qidep, Real* qi2qv_sublim_tend, Real* ni_sublim_tend, Real* qiberg); - -void compute_rain_fall_velocity_c(Real qr_incld, Real rhofacr, - Real* nr_incld, Real* mu_r, Real* lamr, Real* V_qr, Real* V_nr); - -void ice_cldliq_collection_c(Real rho, Real temp, Real rhofaci, Real table_val_qc2qi_collect, - Real qi_incld,Real qc_incld, Real ni_incld, Real nc_incld, - Real* qc2qi_collect_tend, Real* nc_collect_tend, Real* qc2qr_ice_shed_tend, Real* ncshdc); - -void ice_rain_collection_c(Real rho, Real temp, Real rhofaci, Real logn0r, Real table_val_nr_collect, Real table_val_qr2qi_collect, - Real qi_incld, Real ni_incld, Real qr_incld, Real* qr2qi_collect_tend, Real* nr_collect_tend); - - -void ice_self_collection_c(Real rho, Real rhofaci, Real table_val_ni_self_collect, Real eii, - Real qm_incld, Real qi_incld, Real ni_incld, Real* ni_selfcollect_tend); - -void ice_relaxation_timescale_c(Real rho, Real temp, Real rhofaci, Real table_val_qi2qr_melting, Real table_val_qi2qr_vent_melt, - Real dv, Real mu, Real sc, Real qi_incld, Real ni_incld, - Real* epsi, Real* epsi_tot); - -void calc_liq_relaxation_timescale_c(Real rho, Real f1r, Real f2r, Real dv, - Real mu, Real sc, Real mu_r, Real lamr, - Real cdistr, Real cdist, Real qr_incld, - Real qc_incld, Real* epsr, Real* epsc); - -void ice_nucleation_c(Real temp, Real inv_rho, Real ni, Real ni_activated, - Real qv_supersat_i, Real inv_dt, bool do_predict_nc, bool do_prescribed_CCN, - Real* qv2qi_nucleat_tend, Real* ni_nucleat_tend); - -void ice_cldliq_wet_growth_c(Real rho, Real temp, Real pres, Real rhofaci, Real table_val_qi2qr_melting, - Real table_val_qi2qr_vent_melt, Real latent_heat_vapor, Real latent_heat_fusion, Real dv, - Real kap, Real mu, Real sc, Real qv, Real qc_incld, - Real qi_incld, Real ni_incld, Real qr_incld, bool* log_wetgrowth, - Real* qr2qi_collect_tend, Real* qc2qi_collect_tend, Real* qc_growth_rate, Real* nr_ice_shed_tend, Real* qc2qr_ice_shed_tend); - -Real subgrid_variance_scaling_c(Real relvar, Real expon); - -void check_values_c(Real* qv, Real* temp, Int kts, Int kte, Int timestepcount, - Int force_abort, Int source_ind, Real* col_loc); - -void calculate_incloud_mixingratios_c(Real qc, Real qr, Real qi, Real qm, Real nc, Real nr, Real ni, Real bm, - Real inv_cld_frac_l, Real inv_cld_frac_i, Real inv_cld_frac_r, - Real* qc_incld, Real* qr_incld, Real* qi_incld, Real* qm_incld, - Real* nc_incld, Real* nr_incld, Real* ni_incld, Real* bm_incld); - -void p3_main_part1_c( - Int kts, Int kte, Int kbot, Int ktop, Int kdir, - bool do_predict_nc, bool do_prescribed_CCN, - Real dt, - Real* pres, Real* dpres, Real* dz, Real* nc_nuceat_tend, Real* nccn_prescribed, Real* inv_exner, Real* exner, Real* inv_cld_frac_l, Real* inv_cld_frac_i, - Real* inv_cld_frac_r, Real* latent_heat_vapor, Real* latent_heat_sublim, Real* latent_heat_fusion, - Real* T_atm, Real* rho, Real* inv_rho, Real* qv_sat_l, Real* qv_sat_i, Real* qv_supersat_i, Real* rhofacr, Real* rhofaci, - Real* acn, Real* qv, Real* th_atm, Real* qc, Real* nc, Real* qr, Real* nr, Real* qi, Real* ni, Real* qm, Real* bm, Real* qc_incld, Real* qr_incld, Real* qi_incld, - Real* qm_incld, Real* nc_incld, Real* nr_incld, Real* ni_incld, Real* bm_incld, - bool* is_nucleat_possible, bool* is_hydromet_present); - -void p3_main_part2_c( - Int kts, Int kte, Int kbot, Int ktop, Int kdir, bool do_predict_nc, bool do_prescribed_CCN, Real dt, Real inv_dt, - Real* pres, Real* inv_exner, Real* inv_cld_frac_l, Real* inv_cld_frac_i, - Real* inv_cld_frac_r, Real* ni_activated, Real* inv_qc_relvar, Real* cld_frac_i, Real* cld_frac_l, Real* cld_frac_r, Real* qv_prev, Real* t_prev, - Real* T_atm, Real* rho, Real* inv_rho, Real* qv_sat_l, Real* qv_sat_i, Real* qv_supersat_i, Real* rhofaci, Real* acn, - Real* qv, Real* th_atm, Real* qc, Real* nc, Real* qr, Real* nr, Real* qi, Real* ni, - Real* qm, Real* bm, Real* latent_heat_vapor, Real* latent_heat_sublim, Real* latent_heat_fusion, Real* qc_incld, - Real* qr_incld, Real* qi_incld, Real* qm_incld, Real* nc_incld, Real* nr_incld, - Real* ni_incld, Real* bm_incld, Real* mu_c, Real* nu, Real* lamc, Real* cdist, Real* cdist1, - Real* cdistr, Real* mu_r, Real* lamr, Real* logn0r, Real* qv2qi_depos_tend, Real* precip_total_tend, - Real* nevapr, Real* qr_evap_tend, Real* vap_liq_exchange, Real* vap_ice_exchange, Real* liq_ice_exchange, Real* pratot, - Real* prctot, bool* is_hydromet_present); - -void p3_main_part3_c( - Int kts, Int kte, Int kbot, Int ktop, Int kdir, - Real* inv_exner, Real* cld_frac_l, Real* cld_frac_r, Real* cld_frac_i, - Real* rho, Real* inv_rho, Real* rhofaci, Real* qv, Real* th_atm, Real* qc, Real* nc, Real* qr, Real* nr, - Real* qi, Real* ni, Real* qm, Real* bm, Real* latent_heat_vapor, Real* latent_heat_sublim, - Real* mu_c, Real* nu, Real* lamc, Real* mu_r, Real* lamr, Real* vap_liq_exchange, - Real* ze_rain, Real* ze_ice, Real* diag_vm_qi, Real* diag_eff_radius_qi, Real* diag_diam_qi, Real* rho_qi, Real* diag_equiv_reflectivity, Real* diag_eff_radius_qc, Real* diag_eff_radius_qr); - -void p3_main_c( - Real* qc, Real* nc, Real* qr, Real* nr, Real* th_atm, Real* qv, Real dt, - Real* qi, Real* qm, Real* ni, Real* bm, Real* pres, Real* dz, - Real* nc_nuceat_tend, Real* nccn_prescribed, Real* ni_activated, Real* inv_qc_relvar, Int it, Real* precip_liq_surf, - Real* precip_ice_surf, Int its, Int ite, Int kts, Int kte, Real* diag_eff_radius_qc, - Real* diag_eff_radius_qi, Real* diag_eff_radius_qr, Real* rho_qi, bool do_predict_nc, bool do_prescribed, Real* dpres, Real* inv_exner, - Real* qv2qi_depos_tend, Real* precip_liq_flux, Real* precip_ice_flux, Real* cld_frac_r, Real* cld_frac_l, Real* cld_frac_i, - Real* liq_ice_exchange, Real* vap_liq_exchange, Real* vap_ice_exchange, Real* qv_prev, Real* t_prev, Real* elapsed_s); - -void ice_supersat_conservation_c(Real* qidep, Real* qinuc, Real cld_frac_i, Real qv, Real qv_sat_i, Real latent_heat_sublim, Real t_atm, Real dt, Real qi2qv_sublim_tend, Real qr2qv_evap_tend); -void nc_conservation_c(Real nc, Real nc_selfcollect_tend, Real dt, Real* nc_collect_tend, Real* nc2ni_immers_freeze_tend, Real* nc_accret_tend, Real* nc2nr_autoconv_tend); -void nr_conservation_c(Real nr, Real ni2nr_melt_tend, Real nr_ice_shed_tend, Real ncshdc, Real nc2nr_autoconv_tend, Real dt, Real nmltratio, Real* nr_collect_tend, Real* nr2ni_immers_freeze_tend, Real* nr_selfcollect_tend, Real* nr_evap_tend); -void ni_conservation_c(Real ni, Real ni_nucleat_tend, Real nr2ni_immers_freeze_tend, Real nc2ni_immers_freeze_tend, Real dt, Real* ni2nr_melt_tend, Real* ni_sublim_tend, Real* ni_selfcollect_tend); -void prevent_liq_supersaturation_c(Real pres, Real t_atm, Real qv, Real latent_heat_vapor, Real latent_heat_sublim, Real dt, Real qidep, Real qinuc, Real* qi2qv_sublim_tend, Real* qr2qv_evap_tend); } // extern "C" : end _c decls namespace scream { namespace p3 { -// -// In all C++ -> Fortran bridge functions you should see p3_init(). P3 needs -// to be initialized since most of its function depend on global tables to be -// populated. The 'true' argument is to set p3 to use its fortran implementations -// instead of calling back to C++. We want this behavior since it doesn't make much -// sense for C++ to bridge over to fortran only to have fortran bridge back to C++. -// If the client wanted the C++ implementation, they should just call it directly. -// - void p3_init_a(P3InitAFortranData& d) { p3_init(); // need to initialize p3 first so that tables are loaded p3_init_a_c(d.ice_table_vals.data(), d.collect_table_vals.data()); } -void find_lookuptable_indices_1a(LookupIceData& d) -{ - p3_init(); // need to initialize p3 first so that tables are loaded - find_lookuptable_indices_1a_c(&d.dumi, &d.dumjj, &d.dumii, &d.dumzz, - &d.dum1, &d.dum4, &d.dum5, &d.dum6, - d.qi, d.ni, d.qm, d.rhop); -} - -void find_lookuptable_indices_1b(LookupIceDataB& d) -{ - p3_init(); - find_lookuptable_indices_1b_c(&d.dumj, &d.dum3, d.qr, d.nr); -} - -void access_lookup_table(AccessLookupTableData& d) -{ - p3_init(); // need to initialize p3 first so that tables are loaded - access_lookup_table_c(d.lid.dumjj, d.lid.dumii, d.lid.dumi, d.index, - d.lid.dum1, d.lid.dum4, d.lid.dum5, &d.proc); -} - -void access_lookup_table_coll(AccessLookupTableCollData& d) -{ - p3_init(); // need to initialize p3 first so that tables are loaded - access_lookup_table_coll_c(d.lid.dumjj, d.lid.dumii, d.lidb.dumj, d.lid.dumi, d.index, - d.lid.dum1, d.lidb.dum3, d.lid.dum4, d.lid.dum5, &d.proc); -} - void BackToCellAverageData::randomize(std::mt19937_64& engine) { // Populate the struct with numbers between 0 and 1. @@ -320,141 +67,6 @@ void BackToCellAverageData::randomize(std::mt19937_64& engine) qc2qi_berg_tend = data_dist(engine); } -void back_to_cell_average(BackToCellAverageData& d) -{ - p3_init(); - back_to_cell_average_c(d.cld_frac_l, d.cld_frac_r, d.cld_frac_i, &d.qc2qr_accret_tend, &d.qr2qv_evap_tend, - &d.qc2qr_autoconv_tend, &d.nc_accret_tend, &d.nc_selfcollect_tend, &d.nc2nr_autoconv_tend, &d.nr_selfcollect_tend, &d.nr_evap_tend, &d.ncautr, - &d.qi2qv_sublim_tend, &d.nr_ice_shed_tend, &d.qc2qi_hetero_freeze_tend, &d.qr2qi_collect_tend, &d.qc2qr_ice_shed_tend, - &d.qi2qr_melt_tend, &d.qc2qi_collect_tend, &d.qr2qi_immers_freeze_tend, &d.ni2nr_melt_tend, &d.nc_collect_tend, &d.ncshdc, &d.nc2ni_immers_freeze_tend, - &d.nr_collect_tend, &d.ni_selfcollect_tend, &d.qv2qi_vapdep_tend, &d.nr2ni_immers_freeze_tend, &d.ni_sublim_tend, &d.qv2qi_nucleat_tend, &d.ni_nucleat_tend, - &d.qc2qi_berg_tend); -} - -void calc_rime_density(CalcRimeDensityData& d) -{ - p3_init(); - calc_rime_density_c(d.T_atm, d.rhofaci, d.table_val_qi_fallspd, d.acn, d.lamc, d.mu_c, - d.qc_incld, d.qc2qi_collect_tend, &d.vtrmi1, &d.rho_qm_cloud); -} - -void cldliq_immersion_freezing(CldliqImmersionFreezingData& d) -{ - p3_init(); - cldliq_immersion_freezing_c(d.T_atm, d.lamc, d.mu_c, d.cdist1, d.qc_incld, d.inv_qc_relvar, - &d.qc2qi_hetero_freeze_tend, &d.nc2ni_immers_freeze_tend); -} - -void droplet_self_collection(DropletSelfCollectionData& d) -{ - p3_init(); - droplet_self_collection_c(d.rho, d.inv_rho, d.qc_incld, d.mu_c, d.nu, d.nc2nr_autoconv_tend, - &d.nc_selfcollect_tend); -} - -void rain_immersion_freezing(RainImmersionFreezingData& d) -{ - p3_init(); - rain_immersion_freezing_c(d.T_atm, d.lamr, d.mu_r, d.cdistr, d.qr_incld, - &d.qr2qi_immers_freeze_tend, &d.nr2ni_immers_freeze_tend); -} - -void cloud_rain_accretion(CloudRainAccretionData& d) -{ - p3_init(); - cloud_rain_accretion_c(d.rho, d.inv_rho, d.qc_incld, d.nc_incld, d.qr_incld, d.inv_qc_relvar, - &d.qc2qr_accret_tend, &d.nc_accret_tend); -} - -void cloud_water_conservation(CloudWaterConservationData& d){ - p3_init(); - cloud_water_conservation_c(d.qc, d.dt, &d.qc2qr_autoconv_tend, &d.qc2qr_accret_tend, &d.qc2qi_collect_tend, &d.qc2qi_hetero_freeze_tend, - &d.qc2qr_ice_shed_tend, &d.qc2qi_berg_tend, &d.qi2qv_sublim_tend, &d.qv2qi_vapdep_tend); -} - -void rain_water_conservation(RainWaterConservationData& d){ - p3_init(); - rain_water_conservation_c(d.qr, d.qc2qr_autoconv_tend, d.qc2qr_accret_tend, d.qi2qr_melt_tend, d.qc2qr_ice_shed_tend, - d.dt, &d.qr2qv_evap_tend, &d.qr2qi_collect_tend, &d.qr2qi_immers_freeze_tend); -} - -void ice_water_conservation(IceWaterConservationData& d){ - p3_init(); - ice_water_conservation_c(d.qi, d.qv2qi_vapdep_tend, d.qv2qi_nucleat_tend, d.qc2qi_berg_tend, d.qr2qi_collect_tend, d.qc2qi_collect_tend, d.qr2qi_immers_freeze_tend, - d.qc2qi_hetero_freeze_tend, d.dt, &d.qi2qv_sublim_tend, &d.qi2qr_melt_tend); -} - -void cloud_water_autoconversion(CloudWaterAutoconversionData& d){ - p3_init(); - cloud_water_autoconversion_c(d.rho, d.qc_incld, d.nc_incld, d.inv_qc_relvar, - &d.qc2qr_autoconv_tend, &d.nc2nr_autoconv_tend, &d.ncautr); -} - -void rain_self_collection(RainSelfCollectionData& d){ - p3_init(); - rain_self_collection_c(d.rho, d.qr_incld, d.nr_incld, &d.nr_selfcollect_tend); -} - -void impose_max_total_ni(ImposeMaxTotalNiData& d){ - p3_init(); - impose_max_total_ni_c(&d.ni_local, d.max_total_ni, d.inv_rho_local); -} - -void get_cloud_dsd2(GetCloudDsd2Data& d) -{ - p3_init(); - Real nc_in = d.nc_in; - get_cloud_dsd2_c(d.qc, &nc_in, &d.mu_c, d.rho, &d.nu, &d.lamc, &d.cdist, &d.cdist1); - d.nc_out = nc_in; -} - -void get_rain_dsd2(GetRainDsd2Data& d) -{ - p3_init(); - Real nr_in = d.nr_in; - get_rain_dsd2_c(d.qr, &nr_in, &d.mu_r, &d.lamr, &d.cdistr, &d.logn0r); - d.nr_out = nr_in; -} - -void ice_cldliq_collection(IceCldliqCollectionData& d) -{ - p3_init(); - ice_cldliq_collection_c(d.rho, d.temp, d.rhofaci, d.table_val_qc2qi_collect, - d.qi_incld, d.qc_incld, d.ni_incld, d.nc_incld, - &d.qc2qi_collect_tend, &d.nc_collect_tend, &d.qc2qr_ice_shed_tend, &d.ncshdc); -} - -void ice_rain_collection(IceRainCollectionData& d) -{ - p3_init(); - ice_rain_collection_c(d.rho, d.temp, d.rhofaci, d.logn0r, d.table_val_nr_collect, d.table_val_qr2qi_collect, - d.qi_incld, d.ni_incld, d.qr_incld, - &d.qr2qi_collect_tend, &d.nr_collect_tend); -} - -void ice_self_collection(IceSelfCollectionData& d) -{ - p3_init(); - ice_self_collection_c(d.rho, d.rhofaci, d.table_val_ni_self_collect, d.eii, d.qm_incld, - d.qi_incld, d.ni_incld, - &d.ni_selfcollect_tend); -} - -void get_time_space_phys_variables(GetTimeSpacePhysVarsData& d) -{ - p3_init(); - get_time_space_phys_variables_c(d.T_atm, d.pres, d.rho, d.latent_heat_vapor, d.latent_heat_sublim, d.qv_sat_l, d.qv_sat_i, &d.mu, &d.dv, - &d.sc, &d.dqsdt, &d.dqsidt, &d.ab, &d.abi, &d.kap, &d.eii); -} - -void ice_relaxation_timescale(IceRelaxationData& d) -{ - p3_init(); - ice_relaxation_timescale_c(d.rho, d.temp, d.rhofaci, d.table_val_qi2qr_melting, d.table_val_qi2qr_vent_melt, - d.dv, d.mu, d.sc, d.qi_incld, d.ni_incld, - &d.epsi, &d.epsi_tot); -} - void CalcLiqRelaxationData::randomize(std::mt19937_64& engine) { // Populate the struct's input fields with numbers between 0 and 1. @@ -473,31 +85,6 @@ void CalcLiqRelaxationData::randomize(std::mt19937_64& engine) qc_incld = data_dist(engine); } -void calc_liq_relaxation_timescale(CalcLiqRelaxationData& d) -{ - p3_init(); - calc_liq_relaxation_timescale_c(d.rho, d.f1r, d.f2r, d.dv, d.mu, d.sc, d.mu_r, - d.lamr, d.cdistr, d.cdist, d.qr_incld, d.qc_incld, &d.epsr, &d.epsc); -} - -void ice_nucleation(IceNucleationData& d) -{ - p3_init(); - ice_nucleation_c(d.temp, d.inv_rho, d.ni, d.ni_activated, - d.qv_supersat_i, d.inv_dt, d.do_predict_nc, d.do_prescribed_CCN, &d.qv2qi_nucleat_tend, &d.ni_nucleat_tend); -} - -void ice_cldliq_wet_growth(IceWetGrowthData& d) -{ - p3_init(); - - ice_cldliq_wet_growth_c(d.rho, d.temp, d.pres, d.rhofaci, d.table_val_qi2qr_melting, - d.table_val_qi2qr_vent_melt, d.latent_heat_vapor, d.latent_heat_fusion, d.dv, - d.kap, d.mu, d.sc, d.qv, d.qc_incld, - d.qi_incld, d.ni_incld, d.qr_incld, &d.log_wetgrowth, - &d.qr2qi_collect_tend, &d.qc2qi_collect_tend, &d.qc_growth_rate, &d.nr_ice_shed_tend, &d.qc2qr_ice_shed_tend); -} - CheckValuesData::CheckValuesData( Int kts_, Int kte_, Int timestepcount_, Int source_ind_, bool force_abort_) : PhysicsTestData( { {(kte_-kts_)+1} }, @@ -507,57 +94,6 @@ CheckValuesData::CheckValuesData( EKAT_REQUIRE_MSG(nk() >= 3 || (kte == 1 && kts == 1), "nk too small to use for col_loc"); } -void check_values(CheckValuesData& d) -{ - p3_init(); - check_values_c(d.qv, d.temp, d.kts, d.kte, d.timestepcount, - d.force_abort, d.source_ind, d.col_loc); -} - -void calculate_incloud_mixingratios(IncloudMixingData& d) -{ - p3_init(); - - calculate_incloud_mixingratios_c(d.qc, d.qr, d.qi, d.qm, d.nc, d.nr, d.ni, d.bm, d.inv_cld_frac_l, d.inv_cld_frac_i, d.inv_cld_frac_r, - &d.qc_incld, &d.qr_incld, &d.qi_incld, &d.qm_incld, - &d.nc_incld, &d.nr_incld, &d.ni_incld, &d.bm_incld); - -} - -void update_prognostic_ice(P3UpdatePrognosticIceData& d){ - p3_init(); - update_prognostic_ice_c(d.qc2qi_hetero_freeze_tend, d.qc2qi_collect_tend, d.qc2qr_ice_shed_tend, d.nc_collect_tend, d.nc2ni_immers_freeze_tend, d.ncshdc, - d.qr2qi_collect_tend, d.nr_collect_tend, d.qr2qi_immers_freeze_tend, d.nr2ni_immers_freeze_tend, d.nr_ice_shed_tend, - d.qi2qr_melt_tend, d.ni2nr_melt_tend, d.qi2qv_sublim_tend, d.qv2qi_vapdep_tend, d.qv2qi_nucleat_tend, d.ni_nucleat_tend, - d.ni_selfcollect_tend, d.ni_sublim_tend, d.qc2qi_berg_tend, d.inv_exner, d.latent_heat_sublim, d.latent_heat_fusion, - d.do_predict_nc, d.log_wetgrowth, d.dt, d.nmltratio, - d.rho_qm_cloud, &d.th_atm, &d.qv, &d.qi, &d.ni, &d.qm, - &d.bm, &d.qc, &d.nc, &d.qr, &d.nr); -} - -void evaporate_rain(EvapRainData& d) -{ - p3_init(); - evaporate_rain_c(d.qr_incld,d.qc_incld,d.nr_incld,d.qi_incld, - d.cld_frac_l,d.cld_frac_r,d.qv,d.qv_prev,d.qv_sat_l,d.qv_sat_i, - d.ab,d.abi,d.epsr,d.epsi_tot,d.t,d.t_prev,d.latent_heat_sublim,d.dqsdt,d.dt, - &d.qr2qv_evap_tend,&d.nr_evap_tend); -} - -void update_prognostic_liquid(P3UpdatePrognosticLiqData& d){ - p3_init(); - update_prognostic_liquid_c(d.qc2qr_accret_tend, d.nc_accret_tend, d.qc2qr_autoconv_tend, d.nc2nr_autoconv_tend, d.ncautr, - d.nc_selfcollect_tend, d. qr2qv_evap_tend, d.nr_evap_tend, d.nr_selfcollect_tend , d.do_predict_nc, d.do_prescribed_CCN, - d.inv_rho, d.inv_exner, d.latent_heat_vapor, d.dt, &d.th_atm, &d.qv, - &d.qc, &d.nc, &d.qr, &d.nr); -} - -void ice_deposition_sublimation(IceDepositionSublimationData& d) -{ - p3_init(); - ice_deposition_sublimation_c(d.qi_incld, d.ni_incld, d.T_atm, d.qv_sat_l, d.qv_sat_i, d.epsi, d.abi, d.qv, d.inv_dt, &d.qv2qi_vapdep_tend, &d.qi2qv_sublim_tend, &d.ni_sublim_tend, &d.qc2qi_berg_tend); -} - CalcUpwindData::CalcUpwindData( Int kts_, Int kte_, Int kdir_, Int kbot_, Int k_qxtop_, Int num_arrays_, Real dt_sub_) : PhysicsTestData({ {(kte_ - kts_)+1, num_arrays_}, {(kte_ - kts_)+1} }, @@ -578,15 +114,6 @@ void CalcUpwindData::convert_to_ptr_arr(std::vector& mem_space, Real**& f qnx_ = mem_space.data() + num_arrays*2; } -void calc_first_order_upwind_step(CalcUpwindData& d) -{ - p3_init(); - std::vector tmp; - Real** fluxes, **vs, **qnx; - d.convert_to_ptr_arr(tmp, fluxes, vs, qnx); - calc_first_order_upwind_step_c(d.kts, d.kte, d.kdir, d.kbot, d.k_qxtop, d.dt_sub, d.rho, d.inv_rho, d.inv_dz, d.num_arrays, fluxes, vs, qnx); -} - GenSedData::GenSedData( Int kts_, Int kte_, Int kdir_, Int k_qxtop_, Int k_qxbot_, Int kbot_, Real Co_max_, Real dt_left_, Real prt_accum_, Int num_arrays_) : @@ -594,17 +121,6 @@ GenSedData::GenSedData( Co_max(Co_max_), k_qxbot(k_qxbot_), dt_left(dt_left_), prt_accum(prt_accum_) { } -void generalized_sedimentation(GenSedData& d) -{ - p3_init(); - std::vector tmp; - Real** fluxes, **vs, **qnx; - d.convert_to_ptr_arr(tmp, fluxes, vs, qnx); - generalized_sedimentation_c(d.kts, d.kte, d.kdir, d.k_qxtop, &d.k_qxbot, d.kbot, d.Co_max, - &d.dt_left, &d.prt_accum, d.inv_dz, d.inv_rho, d.rho, - d.num_arrays, fluxes, vs, qnx); -} - CloudSedData::CloudSedData( Int kts_, Int kte_, Int ktop_, Int kbot_, Int kdir_, Real dt_, Real inv_dt_, bool do_predict_nc_, Real precip_liq_surf_) : @@ -614,15 +130,6 @@ CloudSedData::CloudSedData( dt(dt_), inv_dt(inv_dt_), do_predict_nc(do_predict_nc_), precip_liq_surf(precip_liq_surf_) {} -void cloud_sedimentation(CloudSedData& d) -{ - p3_init(); - cloud_sedimentation_c(d.kts, d.kte, d.ktop, d.kbot, d.kdir, - d.qc_incld, d.rho, d.inv_rho, d.cld_frac_l, d.acn, d.inv_dz, - d.dt, d.inv_dt, d.do_predict_nc, - d.qc, d.nc, d.nc_incld, d.mu_c, d.lamc, &d.precip_liq_surf, d.qc_tend, d.nc_tend); -} - IceSedData::IceSedData( Int kts_, Int kte_, Int ktop_, Int kbot_, Int kdir_, Real dt_, Real inv_dt_, Real precip_ice_surf_) : @@ -632,15 +139,6 @@ IceSedData::IceSedData( dt(dt_), inv_dt(inv_dt_), precip_ice_surf(precip_ice_surf_) {} -void ice_sedimentation(IceSedData& d) -{ - p3_init(); - ice_sedimentation_c(d.kts, d.kte, d.ktop, d.kbot, d.kdir, - d.rho, d.inv_rho, d.rhofaci, d.cld_frac_i, d.inv_dz, d.dt, d.inv_dt, - d.qi, d.qi_incld, d.ni, d.qm, d.qm_incld, d.bm, d.bm_incld, d.ni_incld, - &d.precip_ice_surf, d.qi_tend, d.ni_tend); -} - RainSedData::RainSedData( Int kts_, Int kte_, Int ktop_, Int kbot_, Int kdir_, Real dt_, Real inv_dt_, Real precip_liq_surf_) : @@ -650,21 +148,6 @@ RainSedData::RainSedData( dt(dt_), inv_dt(inv_dt_), precip_liq_surf(precip_liq_surf_) {} -void rain_sedimentation(RainSedData& d) -{ - p3_init(); - rain_sedimentation_c(d.kts, d.kte, d.ktop, d.kbot, d.kdir, - d.qr_incld, d.rho, d.inv_rho, d.rhofacr, d.cld_frac_r, d.inv_dz, - d.dt, d.inv_dt, - d.qr, d.nr, d.nr_incld, d.mu_r, d.lamr, &d.precip_liq_surf, d.precip_liq_flux, d.qr_tend, d.nr_tend); -} - -void calc_bulk_rho_rime(CalcBulkRhoRimeData& d) -{ - p3_init(); - calc_bulk_rho_rime_c(d.qi_tot, &d.qi_rim, &d.bi_rim, &d.rho_rime); -} - HomogeneousFreezingData::HomogeneousFreezingData( Int kts_, Int kte_, Int ktop_, Int kbot_, Int kdir_) : PhysicsTestData( { {(kte_ - kts_) + 1} }, @@ -672,33 +155,6 @@ HomogeneousFreezingData::HomogeneousFreezingData( kts(kts_), kte(kte_), ktop(ktop_), kbot(kbot_), kdir(kdir_) {} -void homogeneous_freezing(HomogeneousFreezingData& d) -{ - p3_init(); - homogeneous_freezing_c(d.kts, d.kte, d.ktop, d.kbot, d.kdir, - d.T_atm, d.inv_exner, d.latent_heat_fusion, - d.qc, d.nc, d.qr, d.nr, d.qi, d.ni, d.qm, d.bm, d.th_atm); -} - -void ice_melting(IceMeltingData& d){ - p3_init(); - ice_melting_c(d.rho,d.T_atm,d.pres,d.rhofaci,d.table_val_qi2qr_melting,d.table_val_qi2qr_vent_melt, - d.latent_heat_vapor,d.latent_heat_fusion,d.dv,d.sc,d.mu,d.kap, - d.qv,d.qi_incld,d.ni_incld,&d.qi2qr_melt_tend,&d.ni2nr_melt_tend); -} - -Real subgrid_variance_scaling(SubgridVarianceScalingData& d){ - p3_init(); - return subgrid_variance_scaling_c(d.relvar,d.expon); -} - -void compute_rain_fall_velocity(ComputeRainFallVelocityData& d) -{ - p3_init(); - compute_rain_fall_velocity_c(d.qr_incld, d.rhofacr, - &d.nr_incld, &d.mu_r, &d.lamr, &d.V_qr, &d.V_nr); -} - P3MainPart1Data::P3MainPart1Data( Int kts_, Int kte_, Int kbot_, Int ktop_, Int kdir_, bool do_predict_nc_, bool do_prescribed_CCN_, Real dt_, bool, bool) : @@ -711,21 +167,6 @@ P3MainPart1Data::P3MainPart1Data( do_predict_nc(do_predict_nc_), do_prescribed_CCN(do_prescribed_CCN_), dt(dt_) {} -void p3_main_part1(P3MainPart1Data& d) -{ - p3_init(); - p3_main_part1_c( - d.kts, d.kte, d.kbot, d.ktop, d.kdir, - d.do_predict_nc, d.do_prescribed_CCN, - d.dt, - d.pres, d.dpres, d.dz, d.nc_nuceat_tend, d.nccn_prescribed, d.inv_exner, d.exner, d.inv_cld_frac_l, d.inv_cld_frac_i, d.inv_cld_frac_r, d.latent_heat_vapor, - d.latent_heat_sublim, d.latent_heat_fusion, - d.T_atm, d.rho, d.inv_rho, d.qv_sat_l, d.qv_sat_i, d.qv_supersat_i, d.rhofacr, d.rhofaci, - d.acn, d.qv, d.th_atm, d.qc, d.nc, d.qr, d.nr, d.qi, d.ni, d.qm, d.bm, d.qc_incld, d.qr_incld, d.qi_incld, - d.qm_incld, d.nc_incld, d.nr_incld, d.ni_incld, d.bm_incld, - &d.is_nucleat_possible, &d.is_hydromet_present); -} - /////////////////////////////////////////////////////////////////////////////// P3MainPart2Data::P3MainPart2Data( @@ -742,20 +183,6 @@ P3MainPart2Data::P3MainPart2Data( do_predict_nc(do_predict_nc_), do_prescribed_CCN(do_prescribed_CCN_), dt(dt_), inv_dt(1 / dt) {} -void p3_main_part2(P3MainPart2Data& d) -{ - p3_init(); - p3_main_part2_c( - d.kts, d.kte, d.kbot, d.ktop, d.kdir, d.do_predict_nc, d.do_prescribed_CCN, d.dt, d.inv_dt, - d.pres, d.inv_exner, d.inv_cld_frac_l, d.inv_cld_frac_i, d.inv_cld_frac_r, d.ni_activated, d.inv_qc_relvar, - d.cld_frac_i, d.cld_frac_l, d.cld_frac_r, d.qv_prev, d.t_prev, - d.T_atm, d.rho, d.inv_rho, d.qv_sat_l, d.qv_sat_i, d.qv_supersat_i, d.rhofaci, d.acn, d.qv, d.th_atm, d.qc, d.nc, d.qr, d.nr, d.qi, d.ni, - d.qm, d.bm, d.latent_heat_vapor, d.latent_heat_sublim, d.latent_heat_fusion, d.qc_incld, d.qr_incld, d.qi_incld, d.qm_incld, d.nc_incld, d.nr_incld, - d.ni_incld, d.bm_incld, d.mu_c, d.nu, d.lamc, d.cdist, d.cdist1, d.cdistr, d.mu_r, d.lamr, d.logn0r, d.qv2qi_depos_tend, d.precip_total_tend, - d.nevapr, d.qr_evap_tend, d.vap_liq_exchange, d.vap_ice_exchange, d.liq_ice_exchange, d.pratot, - d.prctot, &d.is_hydromet_present); -} - /////////////////////////////////////////////////////////////////////////////// P3MainPart3Data::P3MainPart3Data( @@ -771,17 +198,6 @@ P3MainPart3Data::P3MainPart3Data( kts(kts_), kte(kte_), kbot(kbot_), ktop(ktop_), kdir(kdir_) {} -void p3_main_part3(P3MainPart3Data& d) -{ - p3_init(); - p3_main_part3_c( - d.kts, d.kte, d.kbot, d.ktop, d.kdir, - d.inv_exner, d.cld_frac_l, d.cld_frac_r, d.cld_frac_i, - d.rho, d.inv_rho, d.rhofaci, d.qv, d.th_atm, d.qc, d.nc, d.qr, d.nr, d.qi, d.ni, d.qm, d.bm, d.latent_heat_vapor, d.latent_heat_sublim, - d.mu_c, d.nu, d.lamc, d.mu_r, d.lamr, d.vap_liq_exchange, - d. ze_rain, d.ze_ice, d.diag_vm_qi, d.diag_eff_radius_qi, d.diag_diam_qi, d.rho_qi, d.diag_equiv_reflectivity, d.diag_eff_radius_qc, d.diag_eff_radius_qr); -} - /////////////////////////////////////////////////////////////////////////////// P3MainData::P3MainData( @@ -796,51 +212,6 @@ P3MainData::P3MainData( its(its_), ite(ite_), kts(kts_), kte(kte_), it(it_), dt(dt_), do_predict_nc(do_predict_nc_), do_prescribed_CCN(do_prescribed_CCN_) {} -//This is the variable ordering from micro_p3.F90 -void p3_main(P3MainData& d) -{ - p3_init(); - d.transpose(); - p3_main_c( - d.qc, d.nc, d.qr, d.nr, d.th_atm, d.qv, d.dt, d.qi, d.qm, d.ni, - d.bm, d.pres, d.dz, d.nc_nuceat_tend, d.nccn_prescribed, d.ni_activated, d.inv_qc_relvar, d.it, d.precip_liq_surf, - d.precip_ice_surf, d.its, d.ite, d.kts, d.kte, d.diag_eff_radius_qc, d.diag_eff_radius_qi, d.diag_eff_radius_qr, - d.rho_qi, d.do_predict_nc, d.do_prescribed_CCN, d.dpres, d.inv_exner, d.qv2qi_depos_tend, - d.precip_liq_flux, d.precip_ice_flux, d.cld_frac_r, d.cld_frac_l, d.cld_frac_i, - d.liq_ice_exchange, d.vap_liq_exchange, d.vap_ice_exchange, d.qv_prev, d.t_prev, &d.elapsed_s); - d.transpose(); -} - -void ice_supersat_conservation(IceSupersatConservationData& d) -{ - p3_init(); - ice_supersat_conservation_c(&d.qidep, &d.qinuc, d.cld_frac_i, d.qv, d.qv_sat_i, d.latent_heat_sublim, d.t_atm, d.dt, d.qi2qv_sublim_tend, d.qr2qv_evap_tend); -} - -void nc_conservation(NcConservationData& d) -{ - p3_init(); - nc_conservation_c(d.nc, d.nc_selfcollect_tend, d.dt, &d.nc_collect_tend, &d.nc2ni_immers_freeze_tend, &d.nc_accret_tend, &d.nc2nr_autoconv_tend); -} - -void nr_conservation(NrConservationData& d) -{ - p3_init(); - nr_conservation_c(d.nr, d.ni2nr_melt_tend, d.nr_ice_shed_tend, d.ncshdc, d.nc2nr_autoconv_tend, d.dt, d.nmltratio, &d.nr_collect_tend, &d.nr2ni_immers_freeze_tend, &d.nr_selfcollect_tend, &d.nr_evap_tend); -} - -void ni_conservation(NiConservationData& d) -{ - p3_init(); - ni_conservation_c(d.ni, d.ni_nucleat_tend, d.nr2ni_immers_freeze_tend, d.nc2ni_immers_freeze_tend, d.dt, &d.ni2nr_melt_tend, &d.ni_sublim_tend, &d.ni_selfcollect_tend); -} - -void prevent_liq_supersaturation(PreventLiqSupersaturationData& d) -{ - p3_init(); - prevent_liq_supersaturation_c(d.pres, d.t_atm, d.qv, d.latent_heat_vapor, d.latent_heat_sublim, d.dt, d.qidep, d.qinuc, &d.qi2qv_sublim_tend, &d.qr2qv_evap_tend); -} - void IceSupersatConservationData::randomize(std::mt19937_64& engine) { std::uniform_real_distribution data_dist(0.0, 1.0); @@ -954,8 +325,6 @@ void PreventLiqSupersaturationData::randomize(std::mt19937_64& engine) */ } -// end _c impls - /////////////////////////////////////////////////////////////////////////////// std::shared_ptr P3GlobalForFortran::s_views; @@ -977,7 +346,7 @@ void P3GlobalForFortran::deinit() } // -// _f function definitions +// _host function definitions // template @@ -990,7 +359,7 @@ std::vector ptr_to_arr(T** data, int n) } template -void calc_first_order_upwind_step_f_impl( +void calc_first_order_upwind_step_host_impl( Int kts, Int kte, Int kdir, Int kbot, Int k_qxtop, Real dt_sub, Real* rho, Real* inv_rho, Real* inv_dz, Real** fluxes, Real** vs, Real** qnx) @@ -1054,7 +423,7 @@ void calc_first_order_upwind_step_f_impl( } template -void generalized_sedimentation_f_impl( +void generalized_sedimentation_host_impl( Int kts, Int kte, Int kdir, Int k_qxtop, Int* k_qxbot, Int kbot, Real Co_max, Real* dt_left, Real* prt_accum, Real* inv_dz, Real* inv_rho, Real* rho, Real** vs, Real** fluxes, Real** qnx) @@ -1143,40 +512,40 @@ void generalized_sedimentation_f_impl( *k_qxbot = scalars[2] + 1; } -void calc_first_order_upwind_step_f( +void calc_first_order_upwind_step_host( Int kts, Int kte, Int kdir, Int kbot, Int k_qxtop, Real dt_sub, Real* rho, Real* inv_rho, Real* inv_dz, Int num_arrays, Real** fluxes, Real** vs, Real** qnx) { if (num_arrays == 1) { - calc_first_order_upwind_step_f_impl<1>(kts, kte, kdir, kbot, k_qxtop, dt_sub, rho, inv_rho, inv_dz, fluxes, vs, qnx); + calc_first_order_upwind_step_host_impl<1>(kts, kte, kdir, kbot, k_qxtop, dt_sub, rho, inv_rho, inv_dz, fluxes, vs, qnx); } else if (num_arrays == 2) { - calc_first_order_upwind_step_f_impl<2>(kts, kte, kdir, kbot, k_qxtop, dt_sub, rho, inv_rho, inv_dz, fluxes, vs, qnx); + calc_first_order_upwind_step_host_impl<2>(kts, kte, kdir, kbot, k_qxtop, dt_sub, rho, inv_rho, inv_dz, fluxes, vs, qnx); } else if (num_arrays == 4) { - calc_first_order_upwind_step_f_impl<4>(kts, kte, kdir, kbot, k_qxtop, dt_sub, rho, inv_rho, inv_dz, fluxes, vs, qnx); + calc_first_order_upwind_step_host_impl<4>(kts, kte, kdir, kbot, k_qxtop, dt_sub, rho, inv_rho, inv_dz, fluxes, vs, qnx); } else { EKAT_REQUIRE_MSG(false, "Unsupported num arrays in bridge calc_first_order_upwind_step_f: " << num_arrays); } } -void generalized_sedimentation_f( +void generalized_sedimentation_host( Int kts, Int kte, Int kdir, Int k_qxtop, Int* k_qxbot, Int kbot, Real Co_max, Real* dt_left, Real* prt_accum, Real* inv_dz, Real* inv_rho, Real* rho, Int num_arrays, Real** vs, Real** fluxes, Real** qnx) { if (num_arrays == 1) { - generalized_sedimentation_f_impl<1>(kts, kte, kdir, k_qxtop, k_qxbot, kbot, Co_max, dt_left, prt_accum, + generalized_sedimentation_host_impl<1>(kts, kte, kdir, k_qxtop, k_qxbot, kbot, Co_max, dt_left, prt_accum, inv_dz, inv_rho, rho, vs, fluxes, qnx); } else if (num_arrays == 2) { - generalized_sedimentation_f_impl<2>(kts, kte, kdir, k_qxtop, k_qxbot, kbot, Co_max, dt_left, prt_accum, + generalized_sedimentation_host_impl<2>(kts, kte, kdir, k_qxtop, k_qxbot, kbot, Co_max, dt_left, prt_accum, inv_dz, inv_rho, rho, vs, fluxes, qnx); } else if (num_arrays == 4) { - generalized_sedimentation_f_impl<4>(kts, kte, kdir, k_qxtop, k_qxbot, kbot, Co_max, dt_left, prt_accum, + generalized_sedimentation_host_impl<4>(kts, kte, kdir, k_qxtop, k_qxbot, kbot, Co_max, dt_left, prt_accum, inv_dz, inv_rho, rho, vs, fluxes, qnx); } else { @@ -1184,7 +553,7 @@ void generalized_sedimentation_f( } } -void cloud_sedimentation_f( +void cloud_sedimentation_host( Int kts, Int kte, Int ktop, Int kbot, Int kdir, Real* qc_incld, Real* rho, Real* inv_rho, Real* cld_frac_l, Real* acn, Real* inv_dz, Real dt, Real inv_dt, bool do_predict_nc, @@ -1251,7 +620,7 @@ void cloud_sedimentation_f( ekat::device_to_host({qc, nc, nc_incld, mu_c, lamc, qc_tend, nc_tend}, nk, inout_views); } -void ice_sedimentation_f( +void ice_sedimentation_host( Int kts, Int kte, Int ktop, Int kbot, Int kdir, Real* rho, Real* inv_rho, Real* rhofaci, Real* cld_frac_i, Real* inv_dz, Real dt, Real inv_dt, @@ -1324,7 +693,7 @@ void ice_sedimentation_f( ekat::device_to_host({qi, qi_incld, ni, ni_incld, qm, qm_incld, bm, bm_incld, qi_tend, ni_tend}, nk, inout_views); } -void rain_sedimentation_f( +void rain_sedimentation_host( Int kts, Int kte, Int ktop, Int kbot, Int kdir, Real* qr_incld, Real* rho, Real* inv_rho, Real* rhofacr, Real* cld_frac_r, Real* inv_dz, Real dt, Real inv_dt, @@ -1399,7 +768,7 @@ void rain_sedimentation_f( ekat::device_to_host({qr, nr, nr_incld, mu_r, lamr, qr_tend, nr_tend, precip_liq_flux}, sizes_out, inout_views); } -void homogeneous_freezing_f( +void homogeneous_freezing_host( Int kts, Int kte, Int ktop, Int kbot, Int kdir, Real* T_atm, Real* inv_exner, Real* qc, Real* nc, Real* qr, Real* nr, Real* qi, Real* ni, Real* qm, Real* bm, Real* th_atm) @@ -1460,7 +829,7 @@ void homogeneous_freezing_f( ekat::device_to_host({qc, nc, qr, nr, qi, ni, qm, bm, th_atm}, nk, inout_views); } -void check_values_f(Real* qv, Real* temp, Int kstart, Int kend, +void check_values_host(Real* qv, Real* temp, Int kstart, Int kend, Int timestepcount, bool force_abort, Int source_ind, Real* col_loc) { using P3F = Functions; @@ -1493,7 +862,7 @@ void check_values_f(Real* qv, Real* temp, Int kstart, Int kend, }); } -void p3_main_part1_f( +void p3_main_part1_host( Int kts, Int kte, Int kbot, Int ktop, Int kdir, bool do_predict_nc, bool do_prescribed_CCN, Real dt, @@ -1605,7 +974,7 @@ void p3_main_part1_f( *is_hydromet_present = bools_h(1); } -void p3_main_part2_f( +void p3_main_part2_host( Int kts, Int kte, Int kbot, Int ktop, Int kdir, bool do_predict_nc, bool do_prescribed_CCN, Real dt, Real inv_dt, Real* pres, Real* dpres, Real* dz, Real* nc_nuceat_tend, Real* inv_exner, Real* exner, Real* inv_cld_frac_l, Real* inv_cld_frac_i, Real* inv_cld_frac_r, Real* ni_activated, Real* inv_qc_relvar, Real* cld_frac_i, Real* cld_frac_l, Real* cld_frac_r, Real* qv_prev, Real* t_prev, @@ -1761,7 +1130,7 @@ void p3_main_part2_f( *is_hydromet_present = bools_h(0); } -void p3_main_part3_f( +void p3_main_part3_host( Int kts, Int kte, Int kbot, Int ktop, Int kdir, Real* inv_exner, Real* cld_frac_l, Real* cld_frac_r, Real* cld_frac_i, Real* rho, Real* inv_rho, Real* rhofaci, Real* qv, Real* th_atm, Real* qc, @@ -1869,7 +1238,7 @@ void p3_main_part3_f( nk, inout_views); } -Int p3_main_f( +Int p3_main_host( Real* qc, Real* nc, Real* qr, Real* nr, Real* th_atm, Real* qv, Real dt, Real* qi, Real* qm, Real* ni, Real* bm, Real* pres, Real* dz, Real* nc_nuceat_tend, Real* nccn_prescribed, Real* ni_activated, Real* inv_qc_relvar, Int it, Real* precip_liq_surf, diff --git a/components/eamxx/src/physics/p3/p3_functions_f90.hpp b/components/eamxx/src/physics/p3/p3_functions_f90.hpp index 881356f3d9b5..7042f0f9fb86 100644 --- a/components/eamxx/src/physics/p3/p3_functions_f90.hpp +++ b/components/eamxx/src/physics/p3/p3_functions_f90.hpp @@ -10,18 +10,34 @@ #include #include // for shared_ptr -// -// Bridge functions to call fortran version of p3 functions from C++ -// - namespace scream { namespace p3 { -// +/////////////////////////////////////////////////////////////////////////////// + +struct P3InitAFortranData +{ + // Must use Host as device, f90 code might not be able to use Device memory + using P3F = Functions; + using P3C = typename P3F::P3C; + + using view_ice_table = typename P3F::KT::template lview; + using view_collect_table = typename P3F::KT::template lview; + + // Need to be LayoutLeft to be fortran compatible + view_ice_table ice_table_vals; + view_collect_table collect_table_vals; + + P3InitAFortranData() : + ice_table_vals("P3InitAFortranData::ice_table_vals"), + collect_table_vals("P3InitAFortranData::collect_table_vals") + {} +}; + +/////////////////////////////////////////////////////////////////////////////// + // Singleton for holding the same global data that are maintained in -// micro_p3, but for use in C++. This data is necessary to complete -// the "bridge" when calling C++ from micro_p3. -// +// micro_p3, but for use in C++. struct P3GlobalForFortran { using P3F = Functions; @@ -64,26 +80,10 @@ struct P3GlobalForFortran /////////////////////////////////////////////////////////////////////////////// -struct P3InitAFortranData -{ - // Must use Host as device, f90 code might not be able to use Device memory - using P3F = Functions; - using P3C = typename P3F::P3C; - - using view_ice_table = typename P3F::KT::template lview; - using view_collect_table = typename P3F::KT::template lview; - - // Need to be LayoutLeft to be fortran compatible - view_ice_table ice_table_vals; - view_collect_table collect_table_vals; - - P3InitAFortranData() : - ice_table_vals("P3InitAFortranData::ice_table_vals"), - collect_table_vals("P3InitAFortranData::collect_table_vals") - {} -}; - -/////////////////////////////////////////////////////////////////////////////// +/** + * Structs for holding data related to specific P3 calls; these are used for + * the BFB unit tests. + */ struct LookupIceData { @@ -882,98 +882,50 @@ struct PreventLiqSupersaturationData { PTD_RW_SCALARS_ONLY(2, qi2qv_sublim_tend, qr2qv_evap_tend); }; -// Glue functions to call fortran from from C++ with the Data struct void p3_init_a(P3InitAFortranData& d); -void find_lookuptable_indices_1a(LookupIceData& d); -void find_lookuptable_indices_1b(LookupIceDataB& d); -void access_lookup_table(AccessLookupTableData& d); -void access_lookup_table_coll(AccessLookupTableCollData& d); -void back_to_cell_average(BackToCellAverageData& d); -void cloud_water_conservation(CloudWaterConservationData& d); -void rain_water_conservation(RainWaterConservationData& d); -void ice_water_conservation(IceWaterConservationData& d); -void calc_rime_density(CalcRimeDensityData& d); -void cldliq_immersion_freezing(CldliqImmersionFreezingData& d); -void rain_immersion_freezing(RainImmersionFreezingData& d); -void droplet_self_collection(DropletSelfCollectionData& d); -void cloud_rain_accretion(CloudRainAccretionData& d); -void cloud_water_autoconversion(CloudWaterAutoconversionData& d); -void rain_self_collection(RainSelfCollectionData& d); -void impose_max_total_ni(ImposeMaxTotalNiData& d); -void ice_melting(IceMeltingData& d); -Real subgrid_variance_scaling(SubgridVarianceScalingData& d); -void get_cloud_dsd2(GetCloudDsd2Data& d); -void get_rain_dsd2(GetRainDsd2Data& d); -void calc_first_order_upwind_step(CalcUpwindData& d); -void generalized_sedimentation(GenSedData& d); -void cloud_sedimentation(CloudSedData& d); -void ice_sedimentation(IceSedData& d); -void rain_sedimentation(RainSedData& d); -void calc_bulk_rho_rime(CalcBulkRhoRimeData& d); -void homogeneous_freezing(HomogeneousFreezingData& d); -void compute_rain_fall_velocity(ComputeRainFallVelocityData& d); -void get_time_space_phys_variables(GetTimeSpacePhysVarsData& d); -void update_prognostic_ice(P3UpdatePrognosticIceData& d); -void evaporate_rain(EvapRainData& d); -void update_prognostic_liquid(P3UpdatePrognosticLiqData& d); -void ice_deposition_sublimation(IceDepositionSublimationData& d); -void ice_cldliq_collection(IceCldliqCollectionData& d); -void ice_rain_collection(IceRainCollectionData& d); -void ice_self_collection(IceSelfCollectionData& d); -void ice_relaxation_timescale(IceRelaxationData& d); -void calc_liq_relaxation_timescale(CalcLiqRelaxationData& d); -void ice_nucleation(IceNucleationData& d); -void ice_cldliq_wet_growth(IceWetGrowthData& d); -void check_values(CheckValuesData& d); -void calculate_incloud_mixingratios(IncloudMixingData& d); -void p3_main_part1(P3MainPart1Data& d); -void p3_main_part2(P3MainPart2Data& d); -void p3_main_part3(P3MainPart3Data& d); -void p3_main(P3MainData& d); - -void ice_supersat_conservation(IceSupersatConservationData& d); -void nc_conservation(NcConservationData& d); -void nr_conservation(NrConservationData& d); -void ni_conservation(NiConservationData& d); -void prevent_liq_supersaturation(PreventLiqSupersaturationData& d); -extern "C" { // _f function decls - -void calc_first_order_upwind_step_f( + +/** + * Convenience functions for calling p3 routines from the host with scalar data. + * These function will pack your data, sync it to device, call the p3 function, + * then sync back to host and unpack. These are used by the BFB unit tests. + */ + +void calc_first_order_upwind_step_host( Int kts, Int kte, Int kdir, Int kbot, Int k_qxtop, Real dt_sub, Real* rho, Real* inv_rho, Real* inv_dz, Int num_arrays, Real** fluxes, Real** vs, Real** qnx); -void generalized_sedimentation_f(Int kts, Int kte, Int kdir, Int k_qxtop, Int *k_qxbot, Int kbot, Real Co_max, +void generalized_sedimentation_host(Int kts, Int kte, Int kdir, Int k_qxtop, Int *k_qxbot, Int kbot, Real Co_max, Real* dt_left, Real* prt_accum, Real* inv_dz, Real* inv_rho, Real* rho, Int num_arrays, Real** vs, Real** fluxes, Real** qnx); -void cloud_sedimentation_f( +void cloud_sedimentation_host( Int kts, Int kte, Int ktop, Int kbot, Int kdir, Real* qc_incld, Real* rho, Real* inv_rho, Real* cld_frac_l, Real* acn, Real* inv_dz, Real dt, Real inv_dt, bool do_predict_nc, Real* qc, Real* nc, Real* nc_incld, Real* mu_c, Real* lamc, Real* precip_liq_surf, Real* qc_tend, Real* nc_tend); -void ice_sedimentation_f( +void ice_sedimentation_host( Int kts, Int kte, Int ktop, Int kbot, Int kdir, Real* rho, Real* inv_rho, Real* rhofaci, Real* cld_frac_i, Real* inv_dz, Real dt, Real inv_dt, Real* qi, Real* qi_incld, Real* ni, Real* qm, Real* qm_incld, Real* bm, Real* bm_incld, Real* ni_incld, Real* precip_ice_surf, Real* qi_tend, Real* ni_tend); -void rain_sedimentation_f( +void rain_sedimentation_host( Int kts, Int kte, Int ktop, Int kbot, Int kdir, Real* qr_incld, Real* rho, Real* inv_rho, Real* rhofacr, Real* cld_frac_r, Real* inv_dz, Real dt, Real inv_dt, Real* qr, Real* nr, Real* nr_incld, Real* mu_r, Real* lamr, Real* precip_liq_surf, Real* precip_liq_flux, Real* qr_tend, Real* nr_tend); -void homogeneous_freezing_f( +void homogeneous_freezing_host( Int kts, Int kte, Int ktop, Int kbot, Int kdir, Real* T_atm, Real* inv_exner, Real* qc, Real* nc, Real* qr, Real* nr, Real* qi, Real* ni, Real* qm, Real* bm, Real* th_atm); -void check_values_f(Real* Qv, Real* temp, Int kstart, Int kend, - Int timestepcount, bool force_abort, Int source_ind, Real* col_loc); +void check_values_host(Real* Qv, Real* temp, Int kstart, Int kend, + Int timestepcount, bool force_abort, Int source_ind, Real* col_loc); -void p3_main_part1_f( +void p3_main_part1_host( Int kts, Int kte, Int kbot, Int ktop, Int kdir, bool do_predict_nc, bool do_prescribed_CCN, Real dt, @@ -984,7 +936,7 @@ void p3_main_part1_f( Real* qm_incld, Real* nc_incld, Real* nr_incld, Real* ni_incld, Real* bm_incld, bool* is_nucleat_possible, bool* is_hydromet_present); -void p3_main_part2_f( +void p3_main_part2_host( Int kts, Int kte, Int kbot, Int ktop, Int kdir, bool do_predict_nc, bool do_prescribed_CCN, Real dt, Real inv_dt, Real* pres, Real* dpres, Real* dz, Real* nc_nuceat_tend, Real* inv_exner, Real* exner, Real* inv_cld_frac_l, Real* inv_cld_frac_i, Real* inv_cld_frac_r, Real* ni_activated, Real* inv_qc_relvar, Real* cld_frac_i, Real* cld_frac_l, Real* cld_frac_r, Real* qv_prev, Real* t_prev, Real* T_atm, Real* rho, Real* inv_rho, Real* qv_sat_l, Real* qv_sat_i, Real* qv_supersat_i, Real* rhofacr, Real* rhofaci, Real* acn, Real* qv, Real* th_atm, Real* qc, Real* nc, Real* qr, Real* nr, Real* qi, Real* ni, @@ -993,14 +945,14 @@ void p3_main_part2_f( Real* nevapr, Real* qr_evap_tend, Real* vap_liq_exchange, Real* vap_ice_exchange, Real* liq_ice_exchange, Real* pratot, Real* prctot, bool* is_hydromet_present); -void p3_main_part3_f( +void p3_main_part3_host( Int kts, Int kte, Int kbot, Int ktop, Int kdir, Real* inv_exner, Real* cld_frac_l, Real* cld_frac_r, Real* cld_frac_i, Real* rho, Real* inv_rho, Real* rhofaci, Real* qv, Real* th_atm, Real* qc, Real* nc, Real* qr, Real* nr, Real* qi, Real* ni, Real* qm, Real* bm, Real* mu_c, Real* nu, Real* lamc, Real* mu_r, Real* lamr, Real* vap_liq_exchange, Real* ze_rain, Real* ze_ice, Real* diag_vm_qi, Real* diag_eff_radius_qi, Real* diag_diam_qi, Real* rho_qi, Real* diag_equiv_reflectivity, Real* diag_eff_radius_qc, Real* diag_eff_radius_qr); -Int p3_main_f( +Int p3_main_host( Real* qc, Real* nc, Real* qr, Real* nr, Real* th_atm, Real* qv, Real dt, Real* qi, Real* qm, Real* ni, Real* bm, Real* pres, Real* dz, Real* nc_nuceat_tend, Real* nccn_prescribed, Real* ni_activated, Real* inv_qc_relvar, Int it, Real* precip_liq_surf, @@ -1009,8 +961,6 @@ Int p3_main_f( Real* qv2qi_depos_tend, Real* precip_liq_flux, Real* precip_ice_flux, Real* cld_frac_r, Real* cld_frac_l, Real* cld_frac_i, Real* liq_ice_exchange, Real* vap_liq_exchange, Real* vap_ice_exchange, Real* qv_prev, Real* t_prev); -} // end _f function decls - } // namespace p3 } // namespace scream diff --git a/components/eamxx/src/physics/p3/p3_iso_c.f90 b/components/eamxx/src/physics/p3/p3_iso_c.f90 index ea0a18411c10..34ee99cde333 100644 --- a/components/eamxx/src/physics/p3/p3_iso_c.f90 +++ b/components/eamxx/src/physics/p3/p3_iso_c.f90 @@ -129,59 +129,6 @@ subroutine p3_init_c(lookup_file_dir_c, info, write_tables) bind(c) end subroutine p3_init_c - subroutine p3_main_c(qc,nc,qr,nr,th_atm,qv,dt,qi,qm,ni,bm, & - pres,dz,nc_nuceat_tend,nccn_prescribed,ni_activated,inv_qc_relvar,it,precip_liq_surf,precip_ice_surf,its,ite,kts,kte,diag_eff_radius_qc, & - diag_eff_radius_qi,diag_eff_radius_qr,rho_qi,do_predict_nc,do_prescribed_CCN,dpres,inv_exner,qv2qi_depos_tend, & - precip_liq_flux,precip_ice_flux,cld_frac_r,cld_frac_l,cld_frac_i,liq_ice_exchange, & - vap_liq_exchange, vap_ice_exchange, qv_prev, t_prev, elapsed_s) bind(C) - use micro_p3, only : p3_main - - real(kind=c_real), intent(inout), dimension(its:ite,kts:kte) :: qc, nc, qr, nr, qv, th_atm - real(kind=c_real), intent(inout), dimension(its:ite,kts:kte) :: qi, qm, ni, bm - real(kind=c_real), intent(in), dimension(its:ite,kts:kte) :: pres, dz - real(kind=c_real), intent(in), dimension(its:ite,kts:kte) :: nc_nuceat_tend,nccn_prescribed,ni_activated - real(kind=c_real), intent(in), dimension(its:ite,kts:kte) :: inv_qc_relvar - real(kind=c_real), value, intent(in) :: dt - real(kind=c_real), intent(out), dimension(its:ite) :: precip_liq_surf, precip_ice_surf - real(kind=c_real), intent(out), dimension(its:ite,kts:kte) :: diag_eff_radius_qc - real(kind=c_real), intent(out), dimension(its:ite,kts:kte) :: diag_eff_radius_qi - real(kind=c_real), intent(out), dimension(its:ite,kts:kte) :: diag_eff_radius_qr - real(kind=c_real), intent(out), dimension(its:ite,kts:kte) :: rho_qi - integer(kind=c_int), value, intent(in) :: its,ite, kts,kte, it - logical(kind=c_bool), value, intent(in) :: do_predict_nc,do_prescribed_CCN - - real(kind=c_real), intent(in), dimension(its:ite,kts:kte) :: dpres - real(kind=c_real), intent(in), dimension(its:ite,kts:kte) :: inv_exner - real(kind=c_real), intent(out), dimension(its:ite,kts:kte) :: qv2qi_depos_tend - real(kind=c_real), intent(out), dimension(its:ite,kts:kte+1) :: precip_liq_flux - real(kind=c_real), intent(out), dimension(its:ite,kts:kte+1) :: precip_ice_flux - real(kind=c_real), intent(in), dimension(its:ite,kts:kte) :: cld_frac_i, cld_frac_l, cld_frac_r - real(kind=c_real), intent(out), dimension(its:ite,kts:kte) :: liq_ice_exchange - real(kind=c_real), intent(out), dimension(its:ite,kts:kte) :: vap_liq_exchange - real(kind=c_real), intent(out), dimension(its:ite,kts:kte) :: vap_ice_exchange - real(kind=c_real), intent(in), dimension(its:ite,kts:kte) :: qv_prev - real(kind=c_real), intent(in), dimension(its:ite,kts:kte) :: t_prev - - real(kind=c_real), intent(out) :: elapsed_s - - real(kind=c_real), dimension(its:ite,kts:kte,49) :: p3_tend_out - real(kind=c_real), dimension(its:ite,3) :: col_location - real(kind=c_real), dimension(its:ite,kts:kte) :: mu_c, lamc - real(kind=c_real), dimension(its:ite,kts:kte) :: precip_total_tend - real(kind=c_real), dimension(its:ite,kts:kte) :: nevapr - real(kind=c_real), dimension(its:ite,kts:kte) :: qr_evap_tend - integer :: i - do i = its,ite - col_location(i,:) = real(i) - end do - - call p3_main(qc,nc,qr,nr,th_atm,qv,dt,qi,qm,ni,bm, & - pres,dz,nc_nuceat_tend,nccn_prescribed,ni_activated,inv_qc_relvar,it,precip_liq_surf,precip_ice_surf,its,ite,kts,kte,diag_eff_radius_qc, & - diag_eff_radius_qi,diag_eff_radius_qr, rho_qi,do_predict_nc,do_prescribed_CCN,dpres,inv_exner,qv2qi_depos_tend,precip_total_tend,nevapr, & - qr_evap_tend,precip_liq_flux,precip_ice_flux,cld_frac_r,cld_frac_l,cld_frac_i,p3_tend_out,mu_c,lamc,liq_ice_exchange,& - vap_liq_exchange,vap_ice_exchange,qv_prev,t_prev,col_location,elapsed_s) - end subroutine p3_main_c - subroutine micro_p3_utils_init_c(Cpair, Rair, RH2O, RHO_H2O, & MWH2O, MWdry, gravit, LatVap, LatIce, & CpLiq, Tmelt, Pi, masterproc) bind(C) @@ -217,772 +164,4 @@ subroutine p3_init_a_c(ice_table_vals_c, collect_table_vals_c) bind(C) collect_table_vals_c(:,:,:,:,:) = collect_table_vals(:,:,:,:,:) end subroutine p3_init_a_c - subroutine find_lookuptable_indices_1a_c(dumi,dumjj,dumii,dumzz,dum1,dum4,dum5,dum6, & - qi,ni,qm,rhop) bind(C) - use micro_p3, only: find_lookupTable_indices_1a - use micro_p3_utils, only: densize,rimsize,isize - - ! arguments: - integer(kind=c_int), intent(out) :: dumi,dumjj,dumii,dumzz - real(kind=c_real), intent(out) :: dum1,dum4,dum5,dum6 - real(kind=c_real), value, intent(in) :: qi,ni,qm,rhop - - call find_lookupTable_indices_1a(dumi, dumjj, dumii, dumzz, dum1, dum4, dum5, dum6, & - isize, rimsize, densize, qi, ni, qm, rhop) - end subroutine find_lookuptable_indices_1a_c - - subroutine find_lookuptable_indices_1b_c(dumj,dum3,qr,nr) bind(C) - use micro_p3, only: find_lookupTable_indices_1b - use micro_p3_utils, only: rcollsize - - integer(kind=c_int), intent(out) :: dumj - real(kind=c_real), intent(out) :: dum3 - real(kind=c_real), value, intent(in) :: qr, nr - - call find_lookupTable_indices_1b(dumj, dum3, rcollsize, qr, nr) - end subroutine find_lookupTable_indices_1b_c - - subroutine access_lookup_table_c(dumjj,dumii,dumi,index,dum1,dum4,dum5,proc) bind(C) - use micro_p3, only: access_lookup_table - - integer(kind=c_int), value, intent(in) :: dumjj, dumii, dumi, index - real(kind=c_real), value, intent(in) :: dum1, dum4, dum5 - real(kind=c_real), intent(out) :: proc - - call access_lookup_table(dumjj,dumii,dumi,index,dum1,dum4,dum5,proc) - end subroutine access_lookup_table_c - - subroutine access_lookup_table_coll_c(dumjj,dumii,dumj,dumi,index,dum1,dum3,dum4,dum5,proc) bind(C) - use micro_p3, only: access_lookup_table_coll - - integer(kind=c_int), value, intent(in) :: dumjj,dumii,dumj,dumi,index - real(kind=c_real), value, intent(in) :: dum1,dum3,dum4,dum5 - real(kind=c_real), intent(out) :: proc - - call access_lookup_table_coll(dumjj,dumii,dumj,dumi,index,dum1,dum3,dum4,dum5,proc) - end subroutine access_lookup_table_coll_c - - subroutine back_to_cell_average_c(cld_frac_l,cld_frac_r,cld_frac_i, qc2qr_accret_tend,qr2qv_evap_tend,qc2qr_autoconv_tend,& - nc_accret_tend,nc_selfcollect_tend,nc2nr_autoconv_tend,nr_selfcollect_tend,nr_evap_tend,ncautr,qi2qv_sublim_tend,nr_ice_shed_tend,qc2qi_hetero_freeze_tend,& - qr2qi_collect_tend,qc2qr_ice_shed_tend,qi2qr_melt_tend,qc2qi_collect_tend,qr2qi_immers_freeze_tend,ni2nr_melt_tend,nc_collect_tend,ncshdc,nc2ni_immers_freeze_tend,nr_collect_tend,ni_selfcollect_tend,& - qv2qi_vapdep_tend,nr2ni_immers_freeze_tend,ni_sublim_tend,qv2qi_nucleat_tend,ni_nucleat_tend,qc2qi_berg_tend) bind(C) - - use micro_p3, only: back_to_cell_average - real(kind=c_real), value, intent(in) :: cld_frac_l, cld_frac_r, cld_frac_i - - real(kind=c_real), intent(inout) :: qc2qr_accret_tend, qr2qv_evap_tend, qc2qr_autoconv_tend, nc_accret_tend, nc_selfcollect_tend, nc2nr_autoconv_tend, & - nr_selfcollect_tend, nr_evap_tend, ncautr, qi2qv_sublim_tend, & - nr_ice_shed_tend, qc2qi_hetero_freeze_tend, qr2qi_collect_tend, qc2qr_ice_shed_tend, qi2qr_melt_tend, qc2qi_collect_tend, & - qr2qi_immers_freeze_tend, ni2nr_melt_tend, nc_collect_tend, ncshdc, nc2ni_immers_freeze_tend, nr_collect_tend,& - ni_selfcollect_tend, qv2qi_vapdep_tend, nr2ni_immers_freeze_tend, ni_sublim_tend, qv2qi_nucleat_tend, ni_nucleat_tend, & - qc2qi_berg_tend - - call back_to_cell_average(cld_frac_l, cld_frac_r, cld_frac_i, qc2qr_accret_tend, qr2qv_evap_tend, qc2qr_autoconv_tend,& - nc_accret_tend, nc_selfcollect_tend, nc2nr_autoconv_tend, nr_selfcollect_tend, nr_evap_tend, ncautr, qi2qv_sublim_tend, nr_ice_shed_tend, qc2qi_hetero_freeze_tend,& - qr2qi_collect_tend, qc2qr_ice_shed_tend, qi2qr_melt_tend, qc2qi_collect_tend, qr2qi_immers_freeze_tend, ni2nr_melt_tend, nc_collect_tend, ncshdc, nc2ni_immers_freeze_tend, nr_collect_tend, ni_selfcollect_tend,& - qv2qi_vapdep_tend, nr2ni_immers_freeze_tend, ni_sublim_tend, qv2qi_nucleat_tend, ni_nucleat_tend, qc2qi_berg_tend) - end subroutine back_to_cell_average_c - - subroutine cloud_water_conservation_c(qc,dt,qc2qr_autoconv_tend,qc2qr_accret_tend,qc2qi_collect_tend,qc2qi_hetero_freeze_tend,qc2qr_ice_shed_tend, & - qc2qi_berg_tend,qi2qv_sublim_tend,qv2qi_vapdep_tend) bind(C) - use micro_p3, only: cloud_water_conservation - - real(kind=c_real), value, intent(in) :: qc, dt - real(kind=c_real), intent(inout) :: qc2qr_autoconv_tend, qc2qr_accret_tend, qc2qi_collect_tend, qc2qi_hetero_freeze_tend, qc2qr_ice_shed_tend, qc2qi_berg_tend, qi2qv_sublim_tend, qv2qi_vapdep_tend - - call cloud_water_conservation(qc,dt,qc2qr_autoconv_tend,qc2qr_accret_tend,qc2qi_collect_tend,qc2qi_hetero_freeze_tend,qc2qr_ice_shed_tend,qc2qi_berg_tend,qi2qv_sublim_tend,qv2qi_vapdep_tend) - end subroutine cloud_water_conservation_c - - subroutine rain_water_conservation_c(qr,qc2qr_autoconv_tend,qc2qr_accret_tend,qi2qr_melt_tend,qc2qr_ice_shed_tend,dt, & - qr2qv_evap_tend,qr2qi_collect_tend,qr2qi_immers_freeze_tend) bind(C) - use micro_p3, only: rain_water_conservation - - real(kind=c_real), value, intent(in) :: qr, qc2qr_autoconv_tend, qc2qr_accret_tend, qi2qr_melt_tend, qc2qr_ice_shed_tend, dt - real(kind=c_real), intent(inout) :: qr2qv_evap_tend, qr2qi_collect_tend, qr2qi_immers_freeze_tend - - call rain_water_conservation(qr,qc2qr_autoconv_tend,qc2qr_accret_tend,qi2qr_melt_tend,qc2qr_ice_shed_tend,dt,qr2qv_evap_tend,qr2qi_collect_tend,qr2qi_immers_freeze_tend) - end subroutine rain_water_conservation_c - - subroutine rain_self_collection_c(rho, qr_incld, nr_incld, nr_selfcollect_tend) bind(C) - use micro_p3, only: rain_self_collection - - real(kind=c_real), value, intent(in) :: rho, qr_incld, nr_incld - real(kind=c_real), intent(out) :: nr_selfcollect_tend - - call rain_self_collection(rho, qr_incld, nr_incld, nr_selfcollect_tend) - end subroutine rain_self_collection_c - - subroutine ice_water_conservation_c(qi,qv2qi_vapdep_tend,qv2qi_nucleat_tend,qc2qi_berg_tend,qr2qi_collect_tend,qc2qi_collect_tend,qr2qi_immers_freeze_tend,qc2qi_hetero_freeze_tend,dt, & - qi2qv_sublim_tend,qi2qr_melt_tend) bind(C) - use micro_p3, only: ice_water_conservation - - real(kind=c_real), value, intent(in) :: qi, qv2qi_vapdep_tend, qv2qi_nucleat_tend, qr2qi_collect_tend, qc2qi_collect_tend, qr2qi_immers_freeze_tend, qc2qi_hetero_freeze_tend, qc2qi_berg_tend, dt - real(kind=c_real), intent(inout) :: qi2qv_sublim_tend, qi2qr_melt_tend - - call ice_water_conservation(qi,qv2qi_vapdep_tend,qv2qi_nucleat_tend,qr2qi_collect_tend,qc2qi_collect_tend,qr2qi_immers_freeze_tend,qc2qi_hetero_freeze_tend,qc2qi_berg_tend,dt,qi2qv_sublim_tend,qi2qr_melt_tend) - end subroutine ice_water_conservation_c - - subroutine get_cloud_dsd2_c(qc,nc,mu_c,rho,nu,lamc,cdist,cdist1) bind(C) - use micro_p3, only: get_cloud_dsd2 - use micro_p3_utils, only: dnu - - !arguments: - real(kind=c_real), value, intent(in) :: qc,rho - real(kind=c_real), intent(inout) :: nc - real(kind=c_real), intent(out) :: mu_c,nu,lamc,cdist,cdist1 - - call get_cloud_dsd2(qc,nc,mu_c,rho,nu,dnu,lamc,cdist,cdist1) - end subroutine get_cloud_dsd2_c - - subroutine get_rain_dsd2_c(qr,nr,mu_r,lamr,cdistr,logn0r) bind(C) - use micro_p3, only: get_rain_dsd2 - - !arguments: - real(kind=c_real), value, intent(in) :: qr - real(kind=c_real), intent(inout) :: nr - real(kind=c_real), intent(out) :: lamr,mu_r,cdistr,logn0r - - call get_rain_dsd2(qr,nr,mu_r,lamr,cdistr,logn0r) - end subroutine get_rain_dsd2_c - - subroutine calc_rime_density_c(T_atm,rhofaci,table_val_qi_fallspd,acn,lamc,mu_c,qc_incld,qc2qi_collect_tend, & - vtrmi1,rho_qm_cloud) bind(C) - - use micro_p3, only: calc_rime_density - real(kind=c_real), value, intent(in) :: T_atm, rhofaci, table_val_qi_fallspd, acn, lamc, mu_c, qc_incld, qc2qi_collect_tend - real(kind=c_real), intent(out) :: vtrmi1, rho_qm_cloud - - call calc_rime_density(T_atm, rhofaci, table_val_qi_fallspd, acn, lamc, mu_c, qc_incld, qc2qi_collect_tend, vtrmi1, rho_qm_cloud) - end subroutine calc_rime_density_c - - subroutine cldliq_immersion_freezing_c(T_atm,lamc,mu_c,cdist1,qc_incld,inv_qc_relvar,qc2qi_hetero_freeze_tend,nc2ni_immers_freeze_tend) bind(C) - - use micro_p3, only: cldliq_immersion_freezing - real(kind=c_real), value, intent(in) :: T_atm, lamc, mu_c, cdist1, qc_incld,inv_qc_relvar - real(kind=c_real), intent(out) :: qc2qi_hetero_freeze_tend, nc2ni_immers_freeze_tend - - call cldliq_immersion_freezing(T_atm, lamc, mu_c, cdist1, qc_incld, inv_qc_relvar, qc2qi_hetero_freeze_tend, nc2ni_immers_freeze_tend) - end subroutine cldliq_immersion_freezing_c - - subroutine rain_immersion_freezing_c(T_atm,lamr,mu_r,cdistr,qr_incld,qr2qi_immers_freeze_tend,nr2ni_immers_freeze_tend) bind(C) - - use micro_p3, only: rain_immersion_freezing - real(kind=c_real), value, intent(in) :: T_atm, lamr, mu_r, cdistr, qr_incld - real(kind=c_real), intent(out) :: qr2qi_immers_freeze_tend, nr2ni_immers_freeze_tend - - call rain_immersion_freezing(T_atm, lamr, mu_r, cdistr, qr_incld, qr2qi_immers_freeze_tend, nr2ni_immers_freeze_tend) - end subroutine rain_immersion_freezing_c - - subroutine droplet_self_collection_c(rho,inv_rho,qc_incld,mu_c,nu,nc2nr_autoconv_tend,nc_selfcollect_tend) bind(C) - - use micro_p3, only: droplet_self_collection - real(kind=c_real), value, intent(in) :: rho, inv_rho, qc_incld, mu_c, nu, nc2nr_autoconv_tend - real(kind=c_real), intent(out) :: nc_selfcollect_tend - - call droplet_self_collection(rho, inv_rho, qc_incld, mu_c, nu, nc2nr_autoconv_tend, nc_selfcollect_tend) - end subroutine droplet_self_collection_c - - subroutine cloud_rain_accretion_c(rho,inv_rho,qc_incld,nc_incld,qr_incld,inv_qc_relvar,qc2qr_accret_tend,nc_accret_tend) bind(C) - - use micro_p3, only: cloud_rain_accretion - real(kind=c_real), value, intent(in) :: rho, inv_rho, qc_incld, nc_incld, qr_incld,inv_qc_relvar - real(kind=c_real), intent(out) :: qc2qr_accret_tend, nc_accret_tend - - call cloud_rain_accretion(rho, inv_rho, qc_incld, nc_incld, qr_incld, inv_qc_relvar, qc2qr_accret_tend, nc_accret_tend) - end subroutine cloud_rain_accretion_c - - subroutine cloud_water_autoconversion_c(rho,qc_incld,nc_incld,inv_qc_relvar,qc2qr_autoconv_tend,nc2nr_autoconv_tend,ncautr) bind(C) - - use micro_p3, only: cloud_water_autoconversion - real(kind=c_real), value, intent(in) :: rho, qc_incld, nc_incld,inv_qc_relvar - real(kind=c_real), intent(inout) :: qc2qr_autoconv_tend, nc2nr_autoconv_tend, ncautr - - call cloud_water_autoconversion(rho, qc_incld, nc_incld, inv_qc_relvar, qc2qr_autoconv_tend, nc2nr_autoconv_tend, ncautr) - end subroutine cloud_water_autoconversion_c - - subroutine impose_max_total_ni_c(ni_local, max_total_ni, inv_rho_local) bind(C) - use micro_p3, only: impose_max_total_ni - - real(kind=c_real), intent(inout) :: ni_local - real(kind=c_real), value, intent(in) :: max_total_ni, inv_rho_local - - call impose_max_total_ni(ni_local, max_total_ni, inv_rho_local) - end subroutine impose_max_total_ni_c - - subroutine calc_first_order_upwind_step_c(kts, kte, kdir, kbot, k_qxtop, dt_sub, rho, inv_rho, inv_dz, num_arrays, fluxes, vs, qnx) bind(C) - use micro_p3, only: calc_first_order_upwind_step, realptr - - !arguments: - integer(kind=c_int), value, intent(in) :: kts, kte, kdir, kbot, k_qxtop, num_arrays - real(kind=c_real), value, intent(in) :: dt_sub - real(kind=c_real), dimension(kts:kte), intent(in) :: rho, inv_rho, inv_dz - type(c_ptr), intent(in), dimension(num_arrays) :: fluxes, vs, qnx - - type(realptr), dimension(num_arrays) :: fluxes_f, vs_f, qnx_f - integer :: i - - do i = 1, num_arrays - call c_f_pointer(fluxes(i), fluxes_f(i)%p, [(kte-kts)+1]) - call c_f_pointer(vs(i), vs_f(i)%p, [(kte-kts)+1]) - call c_f_pointer(qnx(i), qnx_f(i)%p , [(kte-kts)+1]) - end do - - call calc_first_order_upwind_step(kts, kte, kdir, kbot, k_qxtop, dt_sub, rho, inv_rho, inv_dz, num_arrays, fluxes_f, vs_f, qnx_f) - - end subroutine calc_first_order_upwind_step_c - - subroutine generalized_sedimentation_c(kts, kte, kdir, k_qxtop, k_qxbot, kbot, Co_max, dt_left, prt_accum, inv_dz, inv_rho, rho, num_arrays, vs, fluxes, qnx) bind(C) - use micro_p3, only: generalized_sedimentation, realptr - - ! arguments - integer(kind=c_int), value, intent(in) :: kts, kte, kdir, k_qxtop, kbot, num_arrays - integer(kind=c_int), intent(inout) :: k_qxbot - real(kind=c_real), value, intent(in) :: Co_max - real(kind=c_real), intent(inout) :: dt_left, prt_accum - real(kind=c_real), dimension(kts:kte), intent(in) :: inv_dz, inv_rho, rho - type(c_ptr), intent(in), dimension(num_arrays) :: vs, fluxes, qnx - - type(realptr), dimension(num_arrays) :: fluxes_f, vs_f, qnx_f - integer :: i - - do i = 1, num_arrays - call c_f_pointer(fluxes(i), fluxes_f(i)%p, [(kte-kts)+1]) - call c_f_pointer(vs(i), vs_f(i)%p, [(kte-kts)+1]) - call c_f_pointer(qnx(i), qnx_f(i)%p , [(kte-kts)+1]) - end do - - call generalized_sedimentation(kts, kte, kdir, k_qxtop, k_qxbot, kbot, Co_max, dt_left, prt_accum, inv_dz, inv_rho, rho, num_arrays, vs_f, fluxes_f, qnx_f) - - end subroutine generalized_sedimentation_c - - subroutine cloud_sedimentation_c(kts,kte,ktop,kbot,kdir, & - qc_incld,rho,inv_rho,cld_frac_l,acn,inv_dz,& - dt,inv_dt,do_predict_nc, & - qc, nc, nc_incld,mu_c,lamc,precip_liq_surf,qc_tend,nc_tend) bind(C) - use micro_p3, only: cloud_sedimentation, dnu - - ! arguments - integer(kind=c_int), value, intent(in) :: kts, kte, ktop, kbot, kdir - - real(kind=c_real), intent(in), dimension(kts:kte) :: rho - real(kind=c_real), intent(in), dimension(kts:kte) :: inv_rho - real(kind=c_real), intent(in), dimension(kts:kte) :: cld_frac_l - real(kind=c_real), intent(in), dimension(kts:kte) :: acn - real(kind=c_real), intent(in), dimension(kts:kte) :: inv_dz - - real(kind=c_real), value, intent(in) :: dt - real(kind=c_real), value, intent(in) :: inv_dt - logical(kind=c_bool), value, intent(in) :: do_predict_nc - - real(kind=c_real), intent(inout), dimension(kts:kte) :: qc - real(kind=c_real), intent(inout), dimension(kts:kte) :: nc - real(kind=c_real), intent(inout), dimension(kts:kte) :: qc_incld - real(kind=c_real), intent(inout), dimension(kts:kte) :: nc_incld - real(kind=c_real), intent(inout), dimension(kts:kte) :: mu_c - real(kind=c_real), intent(inout), dimension(kts:kte) :: lamc - real(kind=c_real), intent(inout) :: precip_liq_surf - real(kind=c_real), intent(inout), dimension(kts:kte) :: qc_tend - real(kind=c_real), intent(inout), dimension(kts:kte) :: nc_tend - - call cloud_sedimentation(kts,kte,ktop,kbot,kdir, & - qc_incld,rho,inv_rho,cld_frac_l,acn,inv_dz,& - dt,inv_dt,dnu,do_predict_nc, & - qc, nc, nc_incld,mu_c,lamc,precip_liq_surf,qc_tend,nc_tend) - - end subroutine cloud_sedimentation_c - - subroutine ice_sedimentation_c(kts,kte,ktop,kbot,kdir, & - rho,inv_rho,rhofaci,cld_frac_i,inv_dz,dt,inv_dt, & - qi,qi_incld,ni,qm,qm_incld,bm,bm_incld,ni_incld,precip_ice_surf,qi_tend,ni_tend) bind(C) - use micro_p3, only: ice_sedimentation - - ! arguments - integer(kind=c_int), value, intent(in) :: kts, kte, ktop, kbot, kdir - - real(kind=c_real), intent(in), dimension(kts:kte) :: rho - real(kind=c_real), intent(in), dimension(kts:kte) :: inv_rho - real(kind=c_real), intent(in), dimension(kts:kte) :: rhofaci - real(kind=c_real), intent(in), dimension(kts:kte) :: cld_frac_i - real(kind=c_real), intent(in), dimension(kts:kte) :: inv_dz - real(kind=c_real), value, intent(in) :: dt, inv_dt - - real(kind=c_real), intent(inout), dimension(kts:kte), target :: qi - real(kind=c_real), intent(inout), dimension(kts:kte) :: qi_incld - real(kind=c_real), intent(inout), dimension(kts:kte), target :: ni - real(kind=c_real), intent(inout), dimension(kts:kte) :: ni_incld - real(kind=c_real), intent(inout), dimension(kts:kte), target :: qm - real(kind=c_real), intent(inout), dimension(kts:kte) :: qm_incld - real(kind=c_real), intent(inout), dimension(kts:kte), target :: bm - real(kind=c_real), intent(inout), dimension(kts:kte) :: bm_incld - - real(kind=c_real), intent(inout) :: precip_ice_surf - real(kind=c_real), intent(inout), dimension(kts:kte) :: qi_tend - real(kind=c_real), intent(inout), dimension(kts:kte) :: ni_tend - - call ice_sedimentation(kts,kte,ktop,kbot,kdir, & - rho,inv_rho,rhofaci,cld_frac_i,inv_dz,dt,inv_dt, & - qi,qi_incld,ni,qm,qm_incld,bm,bm_incld,ni_incld,precip_ice_surf,qi_tend,ni_tend) - - end subroutine ice_sedimentation_c - - subroutine rain_sedimentation_c(kts,kte,ktop,kbot,kdir, & - qr_incld,rho,inv_rho,rhofacr,cld_frac_r,inv_dz,dt,inv_dt, & - qr,nr,nr_incld,mu_r,lamr,precip_liq_surf,precip_liq_flux,qr_tend,nr_tend) bind(C) - use micro_p3, only: rain_sedimentation - - integer(kind=c_int), value, intent(in) :: kts, kte, ktop, kbot, kdir - - real(kind=c_real), intent(in), dimension(kts:kte) :: rho - real(kind=c_real), intent(in), dimension(kts:kte) :: inv_rho - real(kind=c_real), intent(in), dimension(kts:kte) :: rhofacr - real(kind=c_real), intent(in), dimension(kts:kte) :: cld_frac_r - real(kind=c_real), intent(in), dimension(kts:kte) :: inv_dz - real(kind=c_real), value, intent(in) :: dt, inv_dt - - real(kind=c_real), intent(inout), target, dimension(kts:kte) :: qr - real(kind=c_real), intent(inout), target, dimension(kts:kte) :: nr - real(kind=c_real), intent(inout), dimension(kts:kte) :: qr_incld - real(kind=c_real), intent(inout), dimension(kts:kte) :: nr_incld - real(kind=c_real), intent(inout), dimension(kts:kte) :: mu_r - real(kind=c_real), intent(inout), dimension(kts:kte) :: lamr - real(kind=c_real), intent(inout) :: precip_liq_surf - real(kind=c_real), intent(inout), dimension(kts:kte+1) :: precip_liq_flux - real(kind=c_real), intent(inout), dimension(kts:kte) :: qr_tend - real(kind=c_real), intent(inout), dimension(kts:kte) :: nr_tend - - call rain_sedimentation(kts,kte,ktop,kbot,kdir, & - qr_incld,rho,inv_rho,rhofacr,cld_frac_r,inv_dz,dt,inv_dt, & - qr,nr,nr_incld,mu_r,lamr,precip_liq_surf,precip_liq_flux,qr_tend,nr_tend) - - end subroutine rain_sedimentation_c - - subroutine calc_bulk_rho_rime_c(qi_tot, qi_rim, bi_rim, rho_rime) bind(C) - use micro_p3, only: calc_bulkRhoRime - - ! arguments: - real(kind=c_real), value, intent(in) :: qi_tot - real(kind=c_real), intent(inout) :: qi_rim, bi_rim - real(kind=c_real), intent(out) :: rho_rime - - call calc_bulkRhoRime(qi_tot, qi_rim, bi_rim, rho_rime) - end subroutine calc_bulk_rho_rime_c - - subroutine homogeneous_freezing_c(kts,kte,ktop,kbot,kdir,T_atm,inv_exner,latent_heat_fusion, & - qc,nc,qr,nr,qi,ni,qm,bm,th_atm) bind(C) - use micro_p3, only: homogeneous_freezing - - ! arguments: - integer(kind=c_int), value, intent(in) :: kts, kte, ktop, kbot, kdir - real(kind=c_real), intent(in), dimension(kts:kte) :: T_atm - real(kind=c_real), intent(in), dimension(kts:kte) :: inv_exner - real(kind=c_real), intent(in), dimension(kts:kte) :: latent_heat_fusion - - real(kind=c_real), intent(inout), dimension(kts:kte) :: qc - real(kind=c_real), intent(inout), dimension(kts:kte) :: nc - real(kind=c_real), intent(inout), dimension(kts:kte) :: qr - real(kind=c_real), intent(inout), dimension(kts:kte) :: nr - - real(kind=c_real), intent(inout), dimension(kts:kte) :: qi - real(kind=c_real), intent(inout), dimension(kts:kte) :: ni - real(kind=c_real), intent(inout), dimension(kts:kte) :: qm - real(kind=c_real), intent(inout), dimension(kts:kte) :: bm - real(kind=c_real), intent(inout), dimension(kts:kte) :: th_atm - - call homogeneous_freezing(kts,kte,ktop,kbot,kdir,T_atm,inv_exner,latent_heat_fusion, & - qc,nc,qr,nr,qi,ni,qm,bm,th_atm) - end subroutine homogeneous_freezing_c - - subroutine compute_rain_fall_velocity_c(qr_incld, rhofacr, nr_incld, mu_r, lamr, V_qr, V_nr) bind(C) - use micro_p3, only: compute_rain_fall_velocity - - ! arguments: - real(kind=c_real), value, intent(in) :: qr_incld, rhofacr - real(kind=c_real), intent(inout) :: nr_incld - real(kind=c_real), intent(out) :: mu_r, lamr, V_qr, V_nr - - call compute_rain_fall_velocity(qr_incld, rhofacr, nr_incld, mu_r, lamr, V_qr, V_nr) - end subroutine compute_rain_fall_velocity_c - -subroutine update_prognostic_ice_c(qc2qi_hetero_freeze_tend,qc2qi_collect_tend,qc2qr_ice_shed_tend,nc_collect_tend,nc2ni_immers_freeze_tend,ncshdc,qr2qi_collect_tend,nr_collect_tend,qr2qi_immers_freeze_tend,nr2ni_immers_freeze_tend,nr_ice_shed_tend, & - qi2qr_melt_tend,ni2nr_melt_tend,qi2qv_sublim_tend,qv2qi_vapdep_tend,qv2qi_nucleat_tend,ni_nucleat_tend,ni_selfcollect_tend,ni_sublim_tend,qc2qi_berg_tend,inv_exner,latent_heat_sublim,latent_heat_fusion,do_predict_nc,log_wetgrowth, & - dt,nmltratio,rho_qm_cloud,th_atm,qv,qi,ni,qm,bm,qc,nc,qr,nr) bind(C) - use micro_p3, only: update_prognostic_ice - - ! arguments - real(kind=c_real), value, intent(in) :: qc2qi_hetero_freeze_tend, qc2qi_collect_tend, qc2qr_ice_shed_tend, nc_collect_tend, nc2ni_immers_freeze_tend, ncshdc, qr2qi_collect_tend, nr_collect_tend, & - qr2qi_immers_freeze_tend, nr2ni_immers_freeze_tend, nr_ice_shed_tend, qi2qr_melt_tend, ni2nr_melt_tend, qi2qv_sublim_tend, qv2qi_vapdep_tend, qv2qi_nucleat_tend, ni_nucleat_tend, ni_selfcollect_tend, ni_sublim_tend, qc2qi_berg_tend, inv_exner, & - latent_heat_fusion, latent_heat_sublim, dt, nmltratio, rho_qm_cloud - - logical(kind=c_bool), value, intent(in) :: do_predict_nc, log_wetgrowth - - real(kind=c_real), intent(inout) :: th_atm, qv, qc, nc, qr, nr, qi, ni, qm, bm - - call update_prognostic_ice(qc2qi_hetero_freeze_tend,qc2qi_collect_tend,qc2qr_ice_shed_tend,nc_collect_tend,nc2ni_immers_freeze_tend,ncshdc,qr2qi_collect_tend,nr_collect_tend,qr2qi_immers_freeze_tend,nr2ni_immers_freeze_tend,nr_ice_shed_tend, & - qi2qr_melt_tend,ni2nr_melt_tend,qi2qv_sublim_tend,qv2qi_vapdep_tend,qv2qi_nucleat_tend,ni_nucleat_tend,ni_selfcollect_tend,ni_sublim_tend,qc2qi_berg_tend,inv_exner,latent_heat_sublim,latent_heat_fusion,do_predict_nc,log_wetgrowth, & - dt,nmltratio,rho_qm_cloud,th_atm,qv,qi,ni,qm,bm,qc,nc,qr,nr) - - end subroutine update_prognostic_ice_c - - subroutine get_time_space_phys_variables_c(T_atm, pres, rho, latent_heat_vapor, latent_heat_sublim, qv_sat_l, qv_sat_i, mu, dv, sc, dqsdt, dqsidt, & - ab, abi, kap, eii) bind(C) - use micro_p3, only: get_time_space_phys_variables - - !arguments - real(kind=c_real), value, intent(in) :: T_atm, pres, rho, latent_heat_vapor, latent_heat_sublim, qv_sat_l, qv_sat_i - real(kind=c_real), intent(out) :: mu, dv, sc, dqsdt, dqsidt, ab, abi, kap, eii - - call get_time_space_phys_variables(T_atm, pres, rho, latent_heat_vapor, latent_heat_sublim, qv_sat_l, qv_sat_i, mu, dv, sc, dqsdt, dqsidt, & - ab, abi, kap, eii) - end subroutine get_time_space_phys_variables_c - - subroutine ice_cldliq_collection_c(rho, temp, rhofaci, table_val_qc2qi_collect, qi_incld, qc_incld, ni_incld, & - nc_incld, qc2qi_collect_tend, nc_collect_tend, qc2qr_ice_shed_tend, ncshdc) bind(C) - use micro_p3, only: ice_cldliq_collection - - ! arguments: - real(kind=c_real), value, intent(in) :: rho, temp, rhofaci, table_val_qc2qi_collect - real(kind=c_real), value, intent(in) :: qi_incld, qc_incld, ni_incld, nc_incld - real(kind=c_real), intent(out) :: qc2qi_collect_tend, nc_collect_tend, qc2qr_ice_shed_tend, ncshdc - - call ice_cldliq_collection(rho, temp, rhofaci, table_val_qc2qi_collect, qi_incld, qc_incld, ni_incld, & - nc_incld, qc2qi_collect_tend, nc_collect_tend, qc2qr_ice_shed_tend, ncshdc) - end subroutine ice_cldliq_collection_c - - subroutine ice_rain_collection_c(rho, temp, rhofaci, logn0r, table_val_nr_collect, table_val_qr2qi_collect, & - qi_incld, ni_incld, qr_incld, qr2qi_collect_tend, nr_collect_tend) bind(C) - use micro_p3, only: ice_rain_collection - - ! arguments: - real(kind=c_real), value, intent(in) :: rho, temp, rhofaci, logn0r, table_val_nr_collect, table_val_qr2qi_collect - real(kind=c_real), value, intent(in) :: qi_incld, ni_incld, qr_incld - real(kind=c_real), intent(out) :: qr2qi_collect_tend, nr_collect_tend - - call ice_rain_collection(rho, temp, rhofaci, logn0r, table_val_nr_collect, table_val_qr2qi_collect, & - qi_incld, ni_incld, qr_incld, qr2qi_collect_tend, nr_collect_tend) - end subroutine ice_rain_collection_c - - subroutine ice_self_collection_c(rho, rhofaci, table_val_ni_self_collect, eii, qm_incld, & - qi_incld, ni_incld, ni_selfcollect_tend) bind(C) - use micro_p3, only: ice_self_collection - - ! arguments: - real(kind=c_real), value, intent(in) :: rho, rhofaci, table_val_ni_self_collect, eii, qm_incld - real(kind=c_real), value, intent(in) :: qi_incld, ni_incld - real(kind=c_real), intent(out) :: ni_selfcollect_tend - - call ice_self_collection(rho, rhofaci, table_val_ni_self_collect, eii, qm_incld, & - qi_incld, ni_incld, ni_selfcollect_tend) - end subroutine ice_self_collection_c - - subroutine evaporate_rain_c(qr_incld,qc_incld,nr_incld,qi_incld, & - cld_frac_l,cld_frac_r,qv,qv_prev,qv_sat_l,qv_sat_i, & - ab,abi,epsr,epsi_tot,t,t_prev,latent_heat_sublim,dqsdt,dt,& - qr2qv_evap_tend,nr_evap_tend) bind(C) - use micro_p3, only: evaporate_rain - - ! arguments - real(kind=c_real), value, intent(in) :: qr_incld,qc_incld,nr_incld,qi_incld, & - cld_frac_l,cld_frac_r,qv,qv_prev,qv_sat_l,qv_sat_i, & - ab,abi,epsr,epsi_tot,t,t_prev,latent_heat_sublim,dqsdt,dt - - real(kind=c_real), intent(out) :: qr2qv_evap_tend, nr_evap_tend - - call evaporate_rain(qr_incld,qc_incld,nr_incld,qi_incld, & - cld_frac_l,cld_frac_r,qv,qv_prev,qv_sat_l,qv_sat_i, & - ab,abi,epsr,epsi_tot,t,t_prev,latent_heat_sublim,dqsdt,dt,& - qr2qv_evap_tend,nr_evap_tend) - end subroutine evaporate_rain_c - - subroutine update_prognostic_liquid_c(qc2qr_accret_tend, nc_accret_tend, qc2qr_autoconv_tend,nc2nr_autoconv_tend, ncautr, nc_selfcollect_tend, & - qr2qv_evap_tend, nr_evap_tend, nr_selfcollect_tend, do_predict_nc, do_prescribed_CCN, inv_rho, inv_exner, latent_heat_vapor, dt, th_atm, qv, qc, nc, qr, nr) bind(C) - use micro_p3, only: update_prognostic_liquid - - ! arguments - real(kind=c_real), value, intent(in) :: qc2qr_accret_tend, nc_accret_tend, qc2qr_autoconv_tend, nc2nr_autoconv_tend, ncautr, nc_selfcollect_tend, & - qr2qv_evap_tend, nr_evap_tend, nr_selfcollect_tend - - logical(kind=c_bool), value, intent(in) :: do_predict_nc - logical(kind=c_bool), value, intent(in) :: do_prescribed_CCN - - real(kind=c_real), value, intent(in) :: inv_rho, inv_exner, latent_heat_vapor, dt - - real(kind=c_real), intent(inout) :: th_atm, qv, qc, nc, qr, nr - - call update_prognostic_liquid(qc2qr_accret_tend, nc_accret_tend, qc2qr_autoconv_tend,nc2nr_autoconv_tend, ncautr, nc_selfcollect_tend, & - qr2qv_evap_tend, nr_evap_tend, nr_selfcollect_tend, do_predict_nc, do_prescribed_CCN, inv_rho, inv_exner, latent_heat_vapor, dt, th_atm, qv, qc, nc, qr, nr) - - end subroutine update_prognostic_liquid_c - - subroutine ice_deposition_sublimation_c(qi_incld, ni_incld, t_atm, qv_sat_l, qv_sat_i, epsi, abi, qv, inv_dt, qidep, qi2qv_sublim_tend, ni_sublim_tend, qiberg) bind(C) - use micro_p3, only : ice_deposition_sublimation - - real(kind=c_real) , value, intent(in) :: qi_incld, ni_incld, t_atm, qv_sat_l, qv_sat_i, epsi, abi, qv, inv_dt - real(kind=c_real) , intent(out) :: qidep, qi2qv_sublim_tend, ni_sublim_tend, qiberg - - call ice_deposition_sublimation(qi_incld, ni_incld, t_atm, qv_sat_l, qv_sat_i, epsi, abi, qv, inv_dt, qidep, qi2qv_sublim_tend, ni_sublim_tend, qiberg) - end subroutine ice_deposition_sublimation_c - - subroutine ice_relaxation_timescale_c(rho, temp, rhofaci, table_val_qi2qr_melting, table_val_qi2qr_vent_melt, & - dv, mu, sc, qi_incld, ni_incld, & - epsi, epsi_tot) bind(C) - use micro_p3, only: calc_ice_relaxation_timescale - - ! arguments - real(kind=c_real), value, intent(in) :: rho, temp, rhofaci, table_val_qi2qr_melting, table_val_qi2qr_vent_melt, & - dv, mu, sc, qi_incld, ni_incld - real(kind=c_real), intent(out) :: epsi - real(kind=c_real), intent(inout) :: epsi_tot - - call calc_ice_relaxation_timescale(rho, temp, rhofaci, table_val_qi2qr_melting, table_val_qi2qr_vent_melt, & - dv, mu, sc, qi_incld, ni_incld, & - epsi, epsi_tot) - end subroutine ice_relaxation_timescale_c - - subroutine calc_liq_relaxation_timescale_c(rho, f1r, f2r, dv, mu, sc, mu_r, & - lamr, cdistr, cdist, qr_incld, & - qc_incld, epsr, epsc) bind(C) - use micro_p3, only: calc_liq_relaxation_timescale - - ! arguments - real(kind=c_real), value, intent(in) :: rho,f1r,f2r,dv,mu,sc,mu_r,lamr, & - cdistr,cdist,qr_incld,qc_incld - real(kind=c_real), intent(out) :: epsr - real(kind=c_real), intent(out) :: epsc - - call calc_liq_relaxation_timescale(rho,f1r,f2r,dv,mu,sc,mu_r,lamr, & - cdistr,cdist,qr_incld,qc_incld,epsr, & - epsc) - end subroutine calc_liq_relaxation_timescale_c - - subroutine ice_nucleation_c(temp, inv_rho, ni, ni_activated, qv_supersat_i, inv_dt, & - do_predict_nc, do_prescribed_CCN, qv2qi_nucleat_tend, ni_nucleat_tend) bind(C) - use micro_p3, only: ice_nucleation - - ! arguments - real(kind=c_real), value, intent(in) :: temp, inv_rho, ni, ni_activated, qv_supersat_i, inv_dt - logical(c_bool), value, intent(in) :: do_predict_nc - logical(c_bool), value, intent(in) :: do_prescribed_CCN - - real(kind=c_real), intent(inout) :: qv2qi_nucleat_tend, ni_nucleat_tend - - call ice_nucleation(temp, inv_rho, ni, ni_activated, qv_supersat_i, inv_dt, & - do_predict_nc, do_prescribed_CCN, qv2qi_nucleat_tend, ni_nucleat_tend) - end subroutine ice_nucleation_c - - subroutine ice_melting_c(rho,T_atm,pres,rhofaci,table_val_qi2qr_melting,table_val_qi2qr_vent_melt,latent_heat_vapor,latent_heat_fusion, & - dv,sc,mu,kap,qv,qi_incld,ni_incld,qi2qr_melt_tend,ni2nr_melt_tend) bind(C) - use micro_p3, only: ice_melting - - ! arguments: - real(kind=c_real), value, intent(in) :: rho,T_atm,pres,rhofaci,table_val_qi2qr_melting,table_val_qi2qr_vent_melt,latent_heat_vapor,latent_heat_fusion,dv,sc,mu,kap,qv,qi_incld,ni_incld - real(kind=c_real), intent(out) :: qi2qr_melt_tend,ni2nr_melt_tend - - call ice_melting(rho,T_atm,pres,rhofaci,table_val_qi2qr_melting,table_val_qi2qr_vent_melt,latent_heat_vapor,latent_heat_fusion,dv,sc,mu,kap,qv,qi_incld,ni_incld,qi2qr_melt_tend,ni2nr_melt_tend) - - end subroutine ice_melting_c - - subroutine ice_cldliq_wet_growth_c(rho, temp, pres, rhofaci, table_val_qi2qr_melting, & - table_val_qi2qr_vent_melt, latent_heat_vapor, latent_heat_fusion, dv, kap, mu, sc, qv, qc_incld, & - qi_incld, ni_incld, qr_incld, & - log_wetgrowth, qr2qi_collect_tend, qc2qi_collect_tend, qc_growth_rate, nr_ice_shed_tend, qc2qr_ice_shed_tend) bind(C) - use micro_p3, only: ice_cldliq_wet_growth - - ! argmens - real(kind=c_real), value, intent(in) :: rho, temp ,pres, rhofaci, table_val_qi2qr_melting, table_val_qi2qr_vent_melt, latent_heat_vapor, latent_heat_fusion, dv, & - kap, mu, sc, qv, qc_incld, qi_incld, ni_incld,qr_incld - logical(kind=c_bool), intent(inout) :: log_wetgrowth - real(kind=c_real), intent(inout) :: qr2qi_collect_tend, qc2qi_collect_tend, qc_growth_rate, nr_ice_shed_tend, qc2qr_ice_shed_tend - - call ice_cldliq_wet_growth(rho, temp, pres, rhofaci, table_val_qi2qr_melting, & - table_val_qi2qr_vent_melt, latent_heat_vapor, latent_heat_fusion, dv, kap, mu, sc, qv, qc_incld, & - qi_incld, ni_incld, qr_incld, & - log_wetgrowth, qr2qi_collect_tend, qc2qi_collect_tend, qc_growth_rate, nr_ice_shed_tend, qc2qr_ice_shed_tend) - end subroutine ice_cldliq_wet_growth_c - - subroutine get_latent_heat_c(its,ite,kts,kte,v,s,f) bind(C) - use micro_p3, only: get_latent_heat - - ! arguments - integer(kind=c_int), intent(in), value :: its, ite, kts, kte - real(kind=c_real), dimension(its:ite, kts:kte), intent(out) :: v, s, f - - call get_latent_heat(its,ite,kts,kte,v,s,f) - end subroutine get_latent_heat_c - - function subgrid_variance_scaling_c(relvar,expon) result(res) bind(C) - use micro_p3, only: subgrid_variance_scaling - - ! arguments - real(kind=c_real), value, intent(in) :: relvar,expon - real(kind=c_real) :: res - - res = subgrid_variance_scaling(relvar,expon) - return - end function subgrid_variance_scaling_c - - subroutine check_values_c(qv, temp, kts, kte, timestepcount, & - force_abort, source_ind, col_loc) bind(C) - use micro_p3, only: check_values - - ! argmens - real(kind=c_real), intent(in) :: qv(kts:kte), temp(kts:kte), col_loc(3) - integer(kind=c_int), value, intent(in) :: kts, kte, timestepcount, source_ind - logical(kind=c_bool), value, intent(in) :: force_abort - - call check_values(qv,Temp,kts,kte,timestepcount,force_abort,source_ind,col_loc) - end subroutine check_values_c - - subroutine calculate_incloud_mixingratios_c(qc, qr, qi, qm, nc, nr, ni, bm, & - inv_cld_frac_l, inv_cld_frac_i, inv_cld_frac_r, & - qc_incld, qr_incld, qi_incld, qm_incld, & - nc_incld, nr_incld, ni_incld, bm_incld) bind(C) - use micro_p3, only: calculate_incloud_mixingratios - - ! argumens - real(kind=c_real), value, intent(in) :: qc, qr, qi, qm, nc, nr, ni, bm, inv_cld_frac_l, inv_cld_frac_i, inv_cld_frac_r - real(kind=c_real), intent(inout) :: qc_incld, qr_incld, qi_incld, qm_incld, nc_incld, nr_incld, ni_incld, bm_incld - - call calculate_incloud_mixingratios(qc, qr, qi, qm, nc, nr, ni, bm, & - inv_cld_frac_l, inv_cld_frac_i, inv_cld_frac_r, & - qc_incld, qr_incld, qi_incld, qm_incld, & - nc_incld, nr_incld, ni_incld, bm_incld) - end subroutine calculate_incloud_mixingratios_c - - subroutine p3_main_part1_c(kts, kte, kbot, ktop, kdir, do_predict_nc, do_prescribed_CCN, dt, & - pres, dpres, dz, nc_nuceat_tend, inv_exner, exner, inv_cld_frac_l, inv_cld_frac_i, inv_cld_frac_r, latent_heat_vapor, latent_heat_sublim, latent_heat_fusion, nccn_prescribed, & - T_atm, rho, inv_rho, qv_sat_l, qv_sat_i, qv_supersat_i, rhofacr, rhofaci, acn, qv, th_atm, qc, nc, qr, nr, & - qi, ni, qm, bm, qc_incld, qr_incld, qi_incld, qm_incld, & - nc_incld, nr_incld, ni_incld, bm_incld, is_nucleat_possible, is_hydromet_present) bind(C) - - use micro_p3, only: p3_main_part1 - - ! arguments - integer(kind=c_int), value, intent(in) :: kts, kte, kbot, ktop, kdir - logical(kind=c_bool), value, intent(in) :: do_predict_nc, do_prescribed_CCN - real(kind=c_real), value, intent(in) :: dt - - real(kind=c_real), intent(in), dimension(kts:kte) :: pres, dpres, dz, nc_nuceat_tend, inv_exner, exner, inv_cld_frac_l, inv_cld_frac_i, & - inv_cld_frac_r, latent_heat_vapor, latent_heat_sublim, latent_heat_fusion, nccn_prescribed - - real(kind=c_real), intent(inout), dimension(kts:kte) :: T_atm, rho, inv_rho, qv_sat_l, qv_sat_i, qv_supersat_i, rhofacr, rhofaci, & - acn, qv, th_atm, qc, nc, qr, nr, qi, ni, qm, bm, qc_incld, qr_incld, qi_incld, & - qm_incld, nc_incld, nr_incld, ni_incld, bm_incld - - logical(kind=c_bool), intent(out) :: is_nucleat_possible, is_hydromet_present - - call p3_main_part1(kts, kte, kbot, ktop, kdir, do_predict_nc, do_prescribed_CCN, dt, & - pres, dpres, dz, nc_nuceat_tend, inv_exner, exner, inv_cld_frac_l, inv_cld_frac_i, inv_cld_frac_r, latent_heat_vapor, latent_heat_sublim, latent_heat_fusion, nccn_prescribed, & - T_atm, rho, inv_rho, qv_sat_l, qv_sat_i, qv_supersat_i, rhofacr, rhofaci, acn, qv, th_atm, qc, nc, qr, nr, & - qi, ni, qm, bm, qc_incld, qr_incld, qi_incld, qm_incld, & - nc_incld, nr_incld, ni_incld, bm_incld, is_nucleat_possible, is_hydromet_present) - - end subroutine p3_main_part1_c - - subroutine p3_main_part2_c(kts, kte, kbot, ktop, kdir, do_predict_nc, do_prescribed_CCN, dt, inv_dt, & - pres, inv_exner, inv_cld_frac_l, inv_cld_frac_i, inv_cld_frac_r, & - ni_activated, inv_qc_relvar, cld_frac_i, cld_frac_l, cld_frac_r, qv_prev, t_prev, & - T_atm, rho, inv_rho, qv_sat_l, qv_sat_i, qv_supersat_i, rhofaci, acn, qv, th_atm, qc, nc, qr, nr, qi, ni, & - qm, bm, latent_heat_vapor, latent_heat_sublim, latent_heat_fusion, qc_incld, qr_incld, qi_incld, qm_incld, nc_incld, nr_incld, & - ni_incld, bm_incld, mu_c, nu, lamc, cdist, cdist1, cdistr, mu_r, lamr, logn0r, qv2qi_depos_tend, precip_total_tend, & - nevapr, qr_evap_tend, vap_liq_exchange, vap_ice_exchange, liq_ice_exchange, pratot, & - prctot, is_hydromet_present) bind(C) - - use micro_p3, only: p3_main_part2 - - !arguments - integer(kind=c_int), value, intent(in) :: kts, kte, kbot, ktop, kdir - logical(kind=c_bool), value, intent(in) :: do_predict_nc, do_prescribed_CCN - real(kind=c_real), value, intent(in) :: dt, inv_dt - - real(kind=c_real), intent(in), dimension(kts:kte) :: pres, inv_exner, inv_cld_frac_l, inv_cld_frac_i, & - inv_cld_frac_r, ni_activated, inv_qc_relvar, cld_frac_i, cld_frac_l, cld_frac_r, qv_prev, t_prev - - real(kind=c_real), intent(inout), dimension(kts:kte) :: T_atm, rho, inv_rho, qv_sat_l, qv_sat_i, qv_supersat_i, rhofaci, acn, & - qv, th_atm, qc, nc, qr, nr, qi, ni, qm, bm, latent_heat_vapor, latent_heat_sublim, latent_heat_fusion, qc_incld, qr_incld, & - qi_incld, qm_incld, nc_incld, nr_incld, ni_incld, bm_incld, mu_c, nu, lamc, cdist, cdist1, & - cdistr, mu_r, lamr, logn0r, qv2qi_depos_tend, precip_total_tend, nevapr, qr_evap_tend, vap_liq_exchange, & - vap_ice_exchange, liq_ice_exchange, pratot, prctot - - logical(kind=c_bool), intent(out) :: is_hydromet_present - - ! throwaway - real(kind=c_real), dimension(kts:kte,49) :: p3_tend_out - - call p3_main_part2(kts, kte, kbot, ktop, kdir, do_predict_nc, do_prescribed_CCN, dt, inv_dt, & - pres, inv_exner, inv_cld_frac_l, inv_cld_frac_i, inv_cld_frac_r, ni_activated, inv_qc_relvar, cld_frac_i, cld_frac_l, cld_frac_r, qv_prev, t_prev, & - T_atm, rho, inv_rho, qv_sat_l, qv_sat_i, qv_supersat_i, rhofaci, acn, qv, th_atm, qc, nc, qr, nr, qi, ni, & - qm, bm, latent_heat_vapor, latent_heat_sublim, latent_heat_fusion, qc_incld, qr_incld, qi_incld, qm_incld, nc_incld, nr_incld, & - ni_incld, bm_incld, mu_c, nu, lamc, cdist, cdist1, cdistr, mu_r, lamr, logn0r, qv2qi_depos_tend, precip_total_tend, & - nevapr, qr_evap_tend, vap_liq_exchange, vap_ice_exchange, liq_ice_exchange, pratot, & - prctot, p3_tend_out, is_hydromet_present) - - end subroutine p3_main_part2_c - - subroutine p3_main_part3_c(kts, kte, kbot, ktop, kdir, & - inv_exner, cld_frac_l, cld_frac_r, cld_frac_i, & - rho, inv_rho, rhofaci, qv, th_atm, qc, nc, qr, nr, qi, ni, qm, bm, latent_heat_vapor, latent_heat_sublim, & - mu_c, nu, lamc, mu_r, lamr, vap_liq_exchange, & - ze_rain, ze_ice, diag_vm_qi, diag_eff_radius_qi, diag_diam_qi, rho_qi, diag_equiv_reflectivity, diag_eff_radius_qc, diag_eff_radius_qr) bind(C) - - use micro_p3, only: p3_main_part3 - - ! args - - integer(kind=c_int), value, intent(in) :: kts, kte, kbot, ktop, kdir - real(kind=c_real), intent(in), dimension(kts:kte) :: inv_exner, cld_frac_l, cld_frac_r, cld_frac_i - real(kind=c_real), intent(inout), dimension(kts:kte) :: rho, inv_rho, rhofaci, & - qv, th_atm, qc, nc, qr, nr, qi, ni, qm, bm, latent_heat_vapor, latent_heat_sublim, & - mu_c, nu, lamc, mu_r, & - lamr, vap_liq_exchange, & - ze_rain, ze_ice, diag_vm_qi, diag_eff_radius_qi, diag_diam_qi, rho_qi, & - diag_equiv_reflectivity, diag_eff_radius_qc, diag_eff_radius_qr - - call p3_main_part3(kts, kte, kbot, ktop, kdir, & - inv_exner, cld_frac_l, cld_frac_r, cld_frac_i, & - rho, inv_rho, rhofaci, qv, th_atm, qc, nc, qr, nr, qi, ni, qm, bm, latent_heat_vapor, latent_heat_sublim, & - mu_c, nu, lamc, mu_r, lamr, vap_liq_exchange, & - ze_rain, ze_ice, diag_vm_qi, diag_eff_radius_qi, diag_diam_qi, rho_qi, diag_equiv_reflectivity, diag_eff_radius_qc, diag_eff_radius_qr) - - end subroutine p3_main_part3_c - - subroutine ice_supersat_conservation_c(qidep, qinuc, cld_frac_i, qv, qv_sat_i, latent_heat_sublim, t_atm, dt, qi2qv_sublim_tend, qr2qv_evap_tend) bind(C) - use micro_p3, only : ice_supersat_conservation - - real(kind=c_real) , intent(inout) :: qidep, qinuc - real(kind=c_real) , value, intent(in) :: cld_frac_i, qv, qv_sat_i, latent_heat_sublim, t_atm, dt, qi2qv_sublim_tend, qr2qv_evap_tend - - call ice_supersat_conservation(qidep, qinuc, cld_frac_i, qv, qv_sat_i, latent_heat_sublim, t_atm, dt, qi2qv_sublim_tend, qr2qv_evap_tend) - end subroutine ice_supersat_conservation_c - subroutine nc_conservation_c(nc, nc_selfcollect_tend, dt, nc_collect_tend, nc2ni_immers_freeze_tend, nc_accret_tend, nc2nr_autoconv_tend) bind(C) - use micro_p3, only : nc_conservation - - real(kind=c_real) , value, intent(in) :: nc, nc_selfcollect_tend, dt - real(kind=c_real) , intent(inout) :: nc_collect_tend, nc2ni_immers_freeze_tend, nc_accret_tend, nc2nr_autoconv_tend - - call nc_conservation(nc, nc_selfcollect_tend, dt, nc_collect_tend, nc2ni_immers_freeze_tend, nc_accret_tend, nc2nr_autoconv_tend) - end subroutine nc_conservation_c - subroutine nr_conservation_c(nr, ni2nr_melt_tend, nr_ice_shed_tend, ncshdc, nc2nr_autoconv_tend, dt, nmltratio, nr_collect_tend, nr2ni_immers_freeze_tend, nr_selfcollect_tend, nr_evap_tend) bind(C) - use micro_p3, only : nr_conservation - - real(kind=c_real) , value, intent(in) :: nr, ni2nr_melt_tend, nr_ice_shed_tend, ncshdc, nc2nr_autoconv_tend, dt, nmltratio - real(kind=c_real) , intent(inout) :: nr_collect_tend, nr2ni_immers_freeze_tend, nr_selfcollect_tend, nr_evap_tend - - call nr_conservation(nr, ni2nr_melt_tend, nr_ice_shed_tend, ncshdc, nc2nr_autoconv_tend, dt, nmltratio, nr_collect_tend, nr2ni_immers_freeze_tend, nr_selfcollect_tend, nr_evap_tend) - end subroutine nr_conservation_c - subroutine ni_conservation_c(ni, ni_nucleat_tend, nr2ni_immers_freeze_tend, nc2ni_immers_freeze_tend, dt, ni2nr_melt_tend, ni_sublim_tend, ni_selfcollect_tend) bind(C) - use micro_p3, only : ni_conservation - - real(kind=c_real) , value, intent(in) :: ni, ni_nucleat_tend, nr2ni_immers_freeze_tend, nc2ni_immers_freeze_tend, dt - real(kind=c_real) , intent(inout) :: ni2nr_melt_tend, ni_sublim_tend, ni_selfcollect_tend - - call ni_conservation(ni, ni_nucleat_tend, nr2ni_immers_freeze_tend, nc2ni_immers_freeze_tend, dt, ni2nr_melt_tend, ni_sublim_tend, ni_selfcollect_tend) - end subroutine ni_conservation_c - subroutine prevent_liq_supersaturation_c(pres, t_atm, qv, latent_heat_vapor, latent_heat_sublim, dt, qidep, qinuc, qi2qv_sublim_tend, qr2qv_evap_tend) bind(C) - use micro_p3, only : prevent_liq_supersaturation - - real(kind=c_real) , value, intent(in) :: pres, t_atm, qv, latent_heat_vapor, latent_heat_sublim, dt, qidep, qinuc - real(kind=c_real) , intent(inout) :: qi2qv_sublim_tend, qr2qv_evap_tend - - call prevent_liq_supersaturation(pres, t_atm, qv, latent_heat_vapor, latent_heat_sublim, dt, qidep, qinuc, qi2qv_sublim_tend, qr2qv_evap_tend) - end subroutine prevent_liq_supersaturation_c end module p3_iso_c diff --git a/components/eamxx/src/physics/p3/p3_main_wrap.cpp b/components/eamxx/src/physics/p3/p3_main_wrap.cpp index ed46e281a675..eb10aca9e7fe 100644 --- a/components/eamxx/src/physics/p3/p3_main_wrap.cpp +++ b/components/eamxx/src/physics/p3/p3_main_wrap.cpp @@ -8,53 +8,23 @@ using scream::Real; using scream::Int; -extern "C" { - void p3_main_c(Real* qc, Real* nc, Real* qr, Real* nr, Real* th_atm, - Real* qv, Real dt, Real* qi, Real* qm, - Real* ni, Real* bm, Real* pres, - Real* dz, Real* nc_nuceat_tend, Real* nccn_prescribed, Real* ni_activated, Real* inv_qc_relvar, - Int it, Real* precip_liq_surf, Real* precip_ice_surf, Int its, - Int ite, Int kts, Int kte, Real* diag_eff_radius_qc, Real* diag_eff_radius_qi, Real* diag_eff_radius_qr, - Real* rho_qi, bool do_predict_nc, bool do_prescribed_CCN, Real* dpres, Real* inv_exner, - Real* qv2qi_depos_tend, - Real* precip_liq_flux, Real* precip_ice_flux, // 1 extra column size - Real* cld_frac_r, Real* cld_frac_l, Real* cld_frac_i, - Real* liq_ice_exchange, Real* vap_liq_exchange, - Real* vap_ice_exchange, Real* qv_prev, Real* t_prev, Real* elapsed_s); -} namespace scream { namespace p3 { -Int p3_main_wrap(const FortranData& d, bool use_fortran) { +Int p3_main_wrap(const FortranData& d) { EKAT_REQUIRE_MSG(d.dt > 0, "invalid dt"); - if (use_fortran) { - Real elapsed_s; - p3_main_c(d.qc.data(), d.nc.data(), d.qr.data(), d.nr.data(), - d.th_atm.data(), d.qv.data(), d.dt, d.qi.data(), - d.qm.data(), d.ni.data(), d.bm.data(), - d.pres.data(), d.dz.data(), d.nc_nuceat_tend.data(), d.nccn_prescribed.data(), d.ni_activated.data(), d.inv_qc_relvar.data(), - d.it, d.precip_liq_surf.data(), d.precip_ice_surf.data(), 1, d.ncol, 1, d.nlev, - d.diag_eff_radius_qc.data(), d.diag_eff_radius_qi.data(), d.diag_eff_radius_qr.data(), d.rho_qi.data(), - d.do_predict_nc, d.do_prescribed_CCN, d.dpres.data(), d.inv_exner.data(), d.qv2qi_depos_tend.data(), - d.precip_liq_flux.data(), d.precip_ice_flux.data(), d.cld_frac_r.data(), d.cld_frac_l.data(), d.cld_frac_i.data(), - d.liq_ice_exchange.data(), d.vap_liq_exchange.data(),d.vap_ice_exchange.data(),d.qv_prev.data(),d.t_prev.data(), &elapsed_s); - return static_cast(elapsed_s * 1000000); - } - else { - return p3_main_f(d.qc.data(), d.nc.data(), d.qr.data(), d.nr.data(), d.th_atm.data(), - d.qv.data(), d.dt, d.qi.data(), d.qm.data(), d.ni.data(), - d.bm.data(), d.pres.data(), d.dz.data(), d.nc_nuceat_tend.data(), d.nccn_prescribed.data(), - d.ni_activated.data(), d.inv_qc_relvar.data(), d.it, d.precip_liq_surf.data(), - d.precip_ice_surf.data(), 1, d.ncol, 1, d.nlev, d.diag_eff_radius_qc.data(), - d.diag_eff_radius_qi.data(), d.diag_eff_radius_qr.data(), d.rho_qi.data(), d.do_predict_nc, d.do_prescribed_CCN, - d.dpres.data(), d.inv_exner.data(), d.qv2qi_depos_tend.data(), - d.precip_liq_flux.data(), d.precip_ice_flux.data(), - d.cld_frac_r.data(), d.cld_frac_l.data(), d.cld_frac_i.data(), - d.liq_ice_exchange.data(), d.vap_liq_exchange.data(), - d.vap_ice_exchange.data(),d.qv_prev.data(),d.t_prev.data() ); - - } + return p3_main_host(d.qc.data(), d.nc.data(), d.qr.data(), d.nr.data(), d.th_atm.data(), + d.qv.data(), d.dt, d.qi.data(), d.qm.data(), d.ni.data(), + d.bm.data(), d.pres.data(), d.dz.data(), d.nc_nuceat_tend.data(), d.nccn_prescribed.data(), + d.ni_activated.data(), d.inv_qc_relvar.data(), d.it, d.precip_liq_surf.data(), + d.precip_ice_surf.data(), 1, d.ncol, 1, d.nlev, d.diag_eff_radius_qc.data(), + d.diag_eff_radius_qi.data(), d.diag_eff_radius_qr.data(), d.rho_qi.data(), d.do_predict_nc, d.do_prescribed_CCN, + d.dpres.data(), d.inv_exner.data(), d.qv2qi_depos_tend.data(), + d.precip_liq_flux.data(), d.precip_ice_flux.data(), + d.cld_frac_r.data(), d.cld_frac_l.data(), d.cld_frac_i.data(), + d.liq_ice_exchange.data(), d.vap_liq_exchange.data(), + d.vap_ice_exchange.data(),d.qv_prev.data(),d.t_prev.data() ); } int test_p3_init () { @@ -63,11 +33,11 @@ int test_p3_init () { return 0; } -int test_p3_ic (bool use_fortran) { +int test_p3_ic () { const auto d = ic::Factory::create(ic::Factory::mixed); d->dt = 300.0; p3_init(); - p3_main_wrap(*d, use_fortran); + p3_main_wrap(*d); P3GlobalForFortran::deinit(); return 0; } diff --git a/components/eamxx/src/physics/p3/p3_main_wrap.hpp b/components/eamxx/src/physics/p3/p3_main_wrap.hpp index 7c980fa8a5bb..186b32477367 100644 --- a/components/eamxx/src/physics/p3/p3_main_wrap.hpp +++ b/components/eamxx/src/physics/p3/p3_main_wrap.hpp @@ -11,12 +11,11 @@ namespace p3 { struct FortranData; // Returns number of microseconds of p3_main execution -Int p3_main_wrap(const FortranData& d, bool use_fortran=false); +Int p3_main_wrap(const FortranData& d); int test_p3_init(); -int test_p3_ic(bool use_fortran); - +int test_p3_ic(); } // namespace p3 } // namespace scream diff --git a/components/eamxx/src/physics/p3/tests/CMakeLists.txt b/components/eamxx/src/physics/p3/tests/CMakeLists.txt index 663462790189..5a949afa2498 100644 --- a/components/eamxx/src/physics/p3/tests/CMakeLists.txt +++ b/components/eamxx/src/physics/p3/tests/CMakeLists.txt @@ -57,17 +57,17 @@ endif() CreateUnitTest(p3_tests "${P3_TESTS_SRCS}" LIBS p3 - EXE_ARGS "--flags='${BASELINE_FILE_ARG}'" + EXE_ARGS "--flags=\\'${BASELINE_FILE_ARG}\\'" THREADS 1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC} LABELS "p3;physics") # Make sure that a diff in the two implementation triggers a failed test (in debug only) +# No need to run lots of different thread counts. if (SCREAM_ENABLE_BASELINE_TESTS) CreateUnitTest (p3_tests_fail p3_rain_sed_unit_tests.cpp LIBS p3 - EXE_ARGS "--flags='${BASELINE_FILE_ARG}'" + EXE_ARGS "--flags=\\'${BASELINE_FILE_ARG}\\'" COMPILER_CXX_DEFS SCREAM_FORCE_RUN_DIFF - THREADS 1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC} LABELS "p3;physics;fail" ${FORCE_RUN_DIFF_FAILS}) endif() @@ -75,16 +75,16 @@ endif() if (NOT SCREAM_P3_SMALL_KERNELS) CreateUnitTest(p3_sk_tests "${P3_TESTS_SRCS}" LIBS p3_sk - EXE_ARGS "--flags='${BASELINE_FILE_ARG}'" + EXE_ARGS "--flags=\\'${BASELINE_FILE_ARG}\\'" THREADS 1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC} LABELS "p3_sk;physics") # Make sure that a diff in the two implementation triggers a failed test (in debug only) + # No need to run lots of different thread counts. CreateUnitTest (p3_sk_tests_fail p3_rain_sed_unit_tests.cpp LIBS p3_sk - EXE_ARGS "--flags='${BASELINE_FILE_ARG}'" + EXE_ARGS "--flags=\\'${BASELINE_FILE_ARG}\\'" COMPILER_CXX_DEFS SCREAM_FORCE_RUN_DIFF - THREADS 1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC} LABELS "p3_sk;physics;fail" ${FORCE_RUN_DIFF_FAILS}) endif() diff --git a/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp index 58066bb6eac7..9df32bc32ffe 100644 --- a/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp @@ -44,10 +44,6 @@ void run_bfb() host_data.data()); Kokkos::deep_copy(device_data, host_data); - // Run the Fortran subroutine. - for (Int i = 0; i < max_pack_size; ++i) { - back_to_cell_average(back_to_cell_average_data[i]); - } // Read baseline data std::string baseline_name = this->m_baseline_path + "/back_to_cell_average.dat"; if (this->m_baseline_action == COMPARE) { diff --git a/components/eamxx/src/physics/p3/tests/p3_check_values_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_check_values_unit_tests.cpp index 15d76d346f4b..e7952c850321 100644 --- a/components/eamxx/src/physics/p3/tests/p3_check_values_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_check_values_unit_tests.cpp @@ -41,7 +41,7 @@ void run_check_values_bfb() // Get data from cxx for (auto& d : cvd_cxx) { - check_values_f(d.qv, d.temp, d.kts, d.kte, d.timestepcount, d.force_abort, d.source_ind, d.col_loc); + check_values_host(d.qv, d.temp, d.kts, d.kte, d.timestepcount, d.force_abort, d.source_ind, d.col_loc); } } diff --git a/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp index 29fbdad8aef0..e3b325a6d1f7 100644 --- a/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp @@ -67,7 +67,7 @@ void run_bfb() // Get data from cxx for (auto& d : csds_cxx) { - cloud_sedimentation_f(d.kts, d.kte, d.ktop, d.kbot, d.kdir, + cloud_sedimentation_host(d.kts, d.kte, d.ktop, d.kbot, d.kdir, d.qc_incld, d.rho, d.inv_rho, d.cld_frac_l, d.acn, d.inv_dz, d.dt, d.inv_dt, d.do_predict_nc, d.qc, d.nc, d.nc_incld, d.mu_c, d.lamc, &d.precip_liq_surf, d.qc_tend, d.nc_tend); diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp index f63e0badfb06..9ddd97aa497b 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp @@ -170,7 +170,7 @@ void run_bfb_ice_sed() // Get data from cxx for (auto& d : isds_cxx) { - ice_sedimentation_f(d.kts, d.kte, d.ktop, d.kbot, d.kdir, + ice_sedimentation_host(d.kts, d.kte, d.ktop, d.kbot, d.kdir, d.rho, d.inv_rho, d.rhofaci, d.cld_frac_i, d.inv_dz, d.dt, d.inv_dt, d.qi, d.qi_incld, d.ni, d.qm, d.qm_incld, d.bm, d.bm_incld, @@ -253,7 +253,7 @@ void run_bfb_homogeneous_freezing() // Get data from cxx for (auto& d : hfds_cxx) { - homogeneous_freezing_f(d.kts, d.kte, d.ktop, d.kbot, d.kdir, + homogeneous_freezing_host(d.kts, d.kte, d.ktop, d.kbot, d.kdir, d.T_atm, d.inv_exner, d.qc, d.nc, d.qr, d.nr, d.qi, d.ni, d.qm, d.bm, d.th_atm); } diff --git a/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp index 62a7e19dddb5..b37978c66574 100644 --- a/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp @@ -106,7 +106,7 @@ void run_bfb_p3_main_part1() // Get data from cxx for (auto& d : isds_cxx) { - p3_main_part1_f(d.kts, d.kte, d.ktop, d.kbot, d.kdir, d.do_predict_nc, d.do_prescribed_CCN, d.dt, + p3_main_part1_host(d.kts, d.kte, d.ktop, d.kbot, d.kdir, d.do_predict_nc, d.do_prescribed_CCN, d.dt, d.pres, d.dpres, d.dz, d.nc_nuceat_tend, d.nccn_prescribed, d.inv_exner, d.exner, d.inv_cld_frac_l, d.inv_cld_frac_i, d.inv_cld_frac_r, d.T_atm, d.rho, d.inv_rho, d.qv_sat_l, d.qv_sat_i, d.qv_supersat_i, d.rhofacr, d.rhofaci, @@ -218,7 +218,7 @@ void run_bfb_p3_main_part2() // Get data from cxx for (auto& d : isds_cxx) { - p3_main_part2_f( + p3_main_part2_host( d.kts, d.kte, d.kbot, d.ktop, d.kdir, d.do_predict_nc, d.do_prescribed_CCN, d.dt, d.inv_dt, d.pres, d.dpres, d.dz, d.nc_nuceat_tend, d.inv_exner, d.exner, d.inv_cld_frac_l, d.inv_cld_frac_i, d.inv_cld_frac_r, d.ni_activated, d.inv_qc_relvar, d.cld_frac_i, d.cld_frac_l, d.cld_frac_r, d.qv_prev, d.t_prev, @@ -345,7 +345,7 @@ void run_bfb_p3_main_part3() // Get data from cxx for (auto& d : isds_cxx) { - p3_main_part3_f( + p3_main_part3_host( d.kts, d.kte, d.kbot, d.ktop, d.kdir, d.inv_exner, d.cld_frac_l, d.cld_frac_r, d.cld_frac_i, d.rho, d.inv_rho, d.rhofaci, d.qv, d.th_atm, d.qc, d.nc, d.qr, d.nr, d.qi, d.ni, d.qm, d.bm, @@ -458,7 +458,7 @@ void run_bfb_p3_main() // Get data from cxx for (auto& d : isds_cxx) { d.template transpose(); - p3_main_f( + p3_main_host( d.qc, d.nc, d.qr, d.nr, d.th_atm, d.qv, d.dt, d.qi, d.qm, d.ni, d.bm, d.pres, d.dz, d.nc_nuceat_tend, d.nccn_prescribed, d.ni_activated, d.inv_qc_relvar, d.it, d.precip_liq_surf, d.precip_ice_surf, d.its, d.ite, d.kts, d.kte, d.diag_eff_radius_qc, d.diag_eff_radius_qi, d.diag_eff_radius_qr, diff --git a/components/eamxx/src/physics/p3/tests/p3_rain_sed_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_rain_sed_unit_tests.cpp index abad922cfb40..297d899a0902 100644 --- a/components/eamxx/src/physics/p3/tests/p3_rain_sed_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_rain_sed_unit_tests.cpp @@ -188,7 +188,7 @@ void run_bfb_rain_sed() #if defined(SCREAM_FORCE_RUN_DIFF) inv_dt *= 2; #endif - rain_sedimentation_f(d.kts, d.kte, d.ktop, d.kbot, d.kdir, + rain_sedimentation_host(d.kts, d.kte, d.ktop, d.kbot, d.kdir, d.qr_incld, d.rho, d.inv_rho, d.rhofacr, d.cld_frac_r, d.inv_dz, d.dt, inv_dt, d.qr, d.nr, d.nr_incld, d.mu_r, d.lamr, &d.precip_liq_surf, d.precip_liq_flux, diff --git a/components/eamxx/src/physics/p3/tests/p3_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_tests.cpp index d1a64f48520c..081252e9cffb 100644 --- a/components/eamxx/src/physics/p3/tests/p3_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_tests.cpp @@ -29,13 +29,8 @@ TEST_CASE("p3_init", "p3") { REQUIRE(nerr == 0); } -TEST_CASE("p3_ic_f", "p3") { - int nerr = scream::p3::test_p3_ic(true); - REQUIRE(nerr == 0); -} - TEST_CASE("p3_ic_c", "p3") { - int nerr = scream::p3::test_p3_ic(false); + int nerr = scream::p3::test_p3_ic(); REQUIRE(nerr == 0); } diff --git a/components/eamxx/src/physics/p3/tests/p3_upwind_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_upwind_unit_tests.cpp index b6b5307966af..4c91cfe8fa98 100644 --- a/components/eamxx/src/physics/p3/tests/p3_upwind_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_upwind_unit_tests.cpp @@ -250,7 +250,7 @@ void run_bfb() for (auto& d : cuds_cxx) { Real** fluxes, **vs, **qnx; d.convert_to_ptr_arr(tmp1, fluxes, vs, qnx); - calc_first_order_upwind_step_f( + calc_first_order_upwind_step_host( d.kts, d.kte, d.kdir, d.kbot, d.k_qxtop, d.dt_sub, d.rho, d.inv_rho, d.inv_dz, d.num_arrays, fluxes, vs, qnx); @@ -335,7 +335,7 @@ void run_bfb() for (auto& d : gsds_cxx) { Real** fluxes, **vs, **qnx; d.convert_to_ptr_arr(tmp1, fluxes, vs, qnx); - generalized_sedimentation_f(d.kts, d.kte, d.kdir, d.k_qxtop, + generalized_sedimentation_host(d.kts, d.kte, d.kdir, d.k_qxtop, &d.k_qxbot, d.kbot, d.Co_max, &d.dt_left, &d.prt_accum, d.inv_dz, d.inv_rho, d.rho, d.num_arrays, fluxes, vs, qnx); From 576d7b4f045bf0758db8480c3affda99cd468c2a Mon Sep 17 00:00:00 2001 From: James Foucar Date: Mon, 4 Nov 2024 15:37:16 -0700 Subject: [PATCH 033/147] Rename FortranData --- components/eamxx/src/physics/p3/p3_f90.cpp | 14 +++++------ components/eamxx/src/physics/p3/p3_f90.hpp | 24 +++++++++---------- .../eamxx/src/physics/p3/p3_functions_f90.cpp | 2 +- .../eamxx/src/physics/p3/p3_functions_f90.hpp | 10 ++++---- .../eamxx/src/physics/p3/p3_ic_cases.cpp | 8 +++---- .../eamxx/src/physics/p3/p3_ic_cases.hpp | 4 ++-- .../eamxx/src/physics/p3/p3_main_wrap.cpp | 2 +- .../eamxx/src/physics/p3/p3_main_wrap.hpp | 4 ++-- .../p3/tests/p3_ice_tables_unit_tests.cpp | 2 +- .../src/physics/p3/tests/p3_run_and_cmp.cpp | 14 +++++------ .../eamxx/src/physics/p3/tests/p3_tests.cpp | 8 +++---- 11 files changed, 46 insertions(+), 46 deletions(-) diff --git a/components/eamxx/src/physics/p3/p3_f90.cpp b/components/eamxx/src/physics/p3/p3_f90.cpp index 650ad3c645db..bf19af693e5b 100644 --- a/components/eamxx/src/physics/p3/p3_f90.cpp +++ b/components/eamxx/src/physics/p3/p3_f90.cpp @@ -16,7 +16,7 @@ extern "C" { namespace scream { namespace p3 { -FortranData::FortranData (Int ncol_, Int nlev_) +P3Data::P3Data (Int ncol_, Int nlev_) : ncol(ncol_), nlev(nlev_) { do_predict_nc = true; @@ -62,11 +62,11 @@ FortranData::FortranData (Int ncol_, Int nlev_) vap_ice_exchange = Array2("sum of vap-ice phase change tendenices", ncol, nlev); } -FortranDataIterator::FortranDataIterator (const FortranData::Ptr& d) { +P3DataIterator::P3DataIterator (const P3Data::Ptr& d) { init(d); } -void FortranDataIterator::init (const FortranData::Ptr& dp) { +void P3DataIterator::init (const P3Data::Ptr& dp) { d_ = dp; #define fdipb(name) \ fields_.push_back({#name, \ @@ -87,8 +87,8 @@ void FortranDataIterator::init (const FortranData::Ptr& dp) { #undef fdipb } -const FortranDataIterator::RawArray& -FortranDataIterator::getfield (Int i) const { +const P3DataIterator::RawArray& +P3DataIterator::getfield (Int i) const { EKAT_ASSERT(i >= 0 || i < nfield()); return fields_[i]; } @@ -112,8 +112,8 @@ void p3_init (const bool write_tables, const bool masterproc) { } } -int test_FortranData () { - FortranData d(11, 72); +int test_P3Data () { + P3Data d(11, 72); return 0; } diff --git a/components/eamxx/src/physics/p3/p3_f90.hpp b/components/eamxx/src/physics/p3/p3_f90.hpp index d07524d9c7a2..fceca0b56018 100644 --- a/components/eamxx/src/physics/p3/p3_f90.hpp +++ b/components/eamxx/src/physics/p3/p3_f90.hpp @@ -10,8 +10,8 @@ namespace scream { namespace p3 { // Data format we can use to communicate with Fortran version. -struct FortranData { - typedef std::shared_ptr Ptr; +struct P3Data { + typedef std::shared_ptr Ptr; using KT = KokkosTypes; using Scalar = Real; @@ -36,29 +36,29 @@ struct FortranData { Array3 p3_tend_out; Array2 liq_ice_exchange,vap_liq_exchange,vap_ice_exchange; - FortranData(Int ncol, Int nlev); + P3Data(Int ncol, Int nlev); }; -// Iterate over a FortranData's arrays. For examples, see Baseline::write, read. -struct FortranDataIterator { +// Iterate over a P3Data's arrays. For examples, see Baseline::write, read. +struct P3DataIterator { struct RawArray { std::string name; Int dim; Int extent[3]; - FortranData::Scalar* data; - FortranData::Array1::size_type size; + P3Data::Scalar* data; + P3Data::Array1::size_type size; }; - explicit FortranDataIterator(const FortranData::Ptr& d); + explicit P3DataIterator(const P3Data::Ptr& d); Int nfield () const { return fields_.size(); } const RawArray& getfield(Int i) const; private: - FortranData::Ptr d_; + P3Data::Ptr d_; std::vector fields_; - void init(const FortranData::Ptr& d); + void init(const P3Data::Ptr& d); }; void p3_init(const bool write_tables = false, @@ -68,9 +68,9 @@ void p3_init(const bool write_tables = false, // to the exact implementation or arithmetic in P3. For now, these checks are // here to establish that the initial regression-testing code gives results that // match the python f2py tester, without needing a data file. -Int check_against_python(const FortranData& d); +Int check_against_python(const P3Data& d); -int test_FortranData(); +int test_P3Data(); } // namespace p3 } // namespace scream diff --git a/components/eamxx/src/physics/p3/p3_functions_f90.cpp b/components/eamxx/src/physics/p3/p3_functions_f90.cpp index 40d5342a31fc..19d9b59e6b8f 100644 --- a/components/eamxx/src/physics/p3/p3_functions_f90.cpp +++ b/components/eamxx/src/physics/p3/p3_functions_f90.cpp @@ -21,7 +21,7 @@ void p3_init_a_c(Real* ice_table_vals, Real* collect_table_vals); namespace scream { namespace p3 { -void p3_init_a(P3InitAFortranData& d) +void p3_init_a(P3InitAP3Data& d) { p3_init(); // need to initialize p3 first so that tables are loaded p3_init_a_c(d.ice_table_vals.data(), d.collect_table_vals.data()); diff --git a/components/eamxx/src/physics/p3/p3_functions_f90.hpp b/components/eamxx/src/physics/p3/p3_functions_f90.hpp index 7042f0f9fb86..a1bbe864f4cc 100644 --- a/components/eamxx/src/physics/p3/p3_functions_f90.hpp +++ b/components/eamxx/src/physics/p3/p3_functions_f90.hpp @@ -15,7 +15,7 @@ namespace p3 { /////////////////////////////////////////////////////////////////////////////// -struct P3InitAFortranData +struct P3InitAP3Data { // Must use Host as device, f90 code might not be able to use Device memory using P3F = Functions; @@ -28,9 +28,9 @@ struct P3InitAFortranData view_ice_table ice_table_vals; view_collect_table collect_table_vals; - P3InitAFortranData() : - ice_table_vals("P3InitAFortranData::ice_table_vals"), - collect_table_vals("P3InitAFortranData::collect_table_vals") + P3InitAP3Data() : + ice_table_vals("P3InitAP3Data::ice_table_vals"), + collect_table_vals("P3InitAP3Data::collect_table_vals") {} }; @@ -882,7 +882,7 @@ struct PreventLiqSupersaturationData { PTD_RW_SCALARS_ONLY(2, qi2qv_sublim_tend, qr2qv_evap_tend); }; -void p3_init_a(P3InitAFortranData& d); +void p3_init_a(P3InitAP3Data& d); /** * Convenience functions for calling p3 routines from the host with scalar data. diff --git a/components/eamxx/src/physics/p3/p3_ic_cases.cpp b/components/eamxx/src/physics/p3/p3_ic_cases.cpp index 1560dc0afb28..52b70de6025b 100644 --- a/components/eamxx/src/physics/p3/p3_ic_cases.cpp +++ b/components/eamxx/src/physics/p3/p3_ic_cases.cpp @@ -8,12 +8,12 @@ namespace p3 { namespace ic { // From mixed_case_data.py in scream-docs at commit 4bbea4. -FortranData::Ptr make_mixed (const Int ncol, const Int nlev) { +P3Data::Ptr make_mixed (const Int ncol, const Int nlev) { using consts = scream::physics::Constants; const Int nk = nlev; Int k; - const auto dp = std::make_shared(ncol, nk); + const auto dp = std::make_shared(ncol, nk); auto& d = *dp; for (Int i = 0; i < ncol; ++i) { @@ -66,7 +66,7 @@ FortranData::Ptr make_mixed (const Int ncol, const Int nlev) { // To get potential temperature, start by making absolute temperature vary // between 150K at top of atmos and 300k at surface, then convert to potential // temp. - FortranData::Array1 T_atm("T", nk); + P3Data::Array1 T_atm("T", nk); for (k = 0; k < nk; ++k) { T_atm(k) = 150 + 150/double(nk)*k; if (i > 0) T_atm(k) += ((i % 3) - 0.5)/double(nk)*k; @@ -119,7 +119,7 @@ FortranData::Ptr make_mixed (const Int ncol, const Int nlev) { return dp; } -FortranData::Ptr Factory::create (IC ic, Int ncol, Int nlev) { +P3Data::Ptr Factory::create (IC ic, Int ncol, Int nlev) { switch (ic) { case mixed: return make_mixed(ncol, nlev); default: diff --git a/components/eamxx/src/physics/p3/p3_ic_cases.hpp b/components/eamxx/src/physics/p3/p3_ic_cases.hpp index a8c461b06daa..0ab502e8c00e 100644 --- a/components/eamxx/src/physics/p3/p3_ic_cases.hpp +++ b/components/eamxx/src/physics/p3/p3_ic_cases.hpp @@ -7,12 +7,12 @@ namespace scream { namespace p3 { namespace ic { -FortranData::Ptr make_mixed(Int ncol); +P3Data::Ptr make_mixed(Int ncol); struct Factory { enum IC { mixed }; - static FortranData::Ptr create(IC ic, Int ncol = 1, Int nlev = 72); + static P3Data::Ptr create(IC ic, Int ncol = 1, Int nlev = 72); }; } // namespace ic diff --git a/components/eamxx/src/physics/p3/p3_main_wrap.cpp b/components/eamxx/src/physics/p3/p3_main_wrap.cpp index eb10aca9e7fe..27b510bcbc6a 100644 --- a/components/eamxx/src/physics/p3/p3_main_wrap.cpp +++ b/components/eamxx/src/physics/p3/p3_main_wrap.cpp @@ -12,7 +12,7 @@ using scream::Int; namespace scream { namespace p3 { -Int p3_main_wrap(const FortranData& d) { +Int p3_main_wrap(const P3Data& d) { EKAT_REQUIRE_MSG(d.dt > 0, "invalid dt"); return p3_main_host(d.qc.data(), d.nc.data(), d.qr.data(), d.nr.data(), d.th_atm.data(), d.qv.data(), d.dt, d.qi.data(), d.qm.data(), d.ni.data(), diff --git a/components/eamxx/src/physics/p3/p3_main_wrap.hpp b/components/eamxx/src/physics/p3/p3_main_wrap.hpp index 186b32477367..c55007427cdb 100644 --- a/components/eamxx/src/physics/p3/p3_main_wrap.hpp +++ b/components/eamxx/src/physics/p3/p3_main_wrap.hpp @@ -8,10 +8,10 @@ namespace scream { namespace p3 { -struct FortranData; +struct P3Data; // Returns number of microseconds of p3_main execution -Int p3_main_wrap(const FortranData& d); +Int p3_main_wrap(const P3Data& d); int test_p3_init(); diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_tables_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_tables_unit_tests.cpp index 98f617668608..4acd18f29274 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_tables_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_tables_unit_tests.cpp @@ -32,7 +32,7 @@ struct UnitWrap::UnitTest::TestTableIce : public UnitWrap::UnitTest::Base Functions::init_kokkos_ice_lookup_tables(ice_table_vals, collect_table_vals); // Get data from fortran - P3InitAFortranData d; + P3InitAP3Data d; p3_init_a(d); // Copy device data to host diff --git a/components/eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp b/components/eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp index 9e491cea6a42..91b7f2550481 100644 --- a/components/eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp @@ -35,10 +35,10 @@ using namespace scream::p3; * large discrepancies. */ Int compare (const double& tol, - const FortranData::Ptr& ref, const FortranData::Ptr& d) { + const P3Data::Ptr& ref, const P3Data::Ptr& d) { Int nerr = 0; - FortranDataIterator refi(ref), di(d); + P3DataIterator refi(ref), di(d); EKAT_ASSERT(refi.nfield() == di.nfield()); for (Int i = 0, n = refi.nfield(); i < n; ++i) { const auto& fr = refi.getfield(i); @@ -170,7 +170,7 @@ struct Baseline { bool do_predict_nc, do_prescribed_CCN; }; - static void set_params (const ParamSet& ps, FortranData& d) { + static void set_params (const ParamSet& ps, P3Data& d) { // Items not set by factory d.dt = ps.dt; d.it = ps.nsteps; @@ -180,8 +180,8 @@ struct Baseline { std::vector params_; - static void write (const ekat::FILEPtr& fid, const FortranData::Ptr& d) { - FortranDataIterator fdi(d); + static void write (const ekat::FILEPtr& fid, const P3Data::Ptr& d) { + P3DataIterator fdi(d); for (Int i = 0, n = fdi.nfield(); i < n; ++i) { const auto& f = fdi.getfield(i); ekat::write(&f.dim, 1, fid); @@ -190,8 +190,8 @@ struct Baseline { } } - static void read (const ekat::FILEPtr& fid, const FortranData::Ptr& d) { - FortranDataIterator fdi(d); + static void read (const ekat::FILEPtr& fid, const P3Data::Ptr& d) { + P3DataIterator fdi(d); for (Int i = 0, n = fdi.nfield(); i < n; ++i) { const auto& f = fdi.getfield(i); int dim, ds[3]; diff --git a/components/eamxx/src/physics/p3/tests/p3_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_tests.cpp index 081252e9cffb..cbb00623cd0d 100644 --- a/components/eamxx/src/physics/p3/tests/p3_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_tests.cpp @@ -5,15 +5,15 @@ namespace { -TEST_CASE("FortranData", "p3") { - int val = scream::p3::test_FortranData(); +TEST_CASE("P3Data", "p3") { + int val = scream::p3::test_P3Data(); REQUIRE(val == 0); } -TEST_CASE("FortranDataIterator", "p3") { +TEST_CASE("P3DataIterator", "p3") { using scream::p3::ic::Factory; const auto d = Factory::create(Factory::mixed); - scream::p3::FortranDataIterator fdi(d); + scream::p3::P3DataIterator fdi(d); REQUIRE(fdi.nfield() == 35); const auto& f = fdi.getfield(0); REQUIRE(f.dim == 2); From 96f5a284f09cc0f5faf1ebf2c2bd59a66ec69dad Mon Sep 17 00:00:00 2001 From: Aaron Donahue Date: Mon, 4 Nov 2024 15:54:24 -0800 Subject: [PATCH 034/147] fix typo in new changes --- components/eamxx/src/share/grid/mesh_free_grids_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eamxx/src/share/grid/mesh_free_grids_manager.cpp b/components/eamxx/src/share/grid/mesh_free_grids_manager.cpp index b2878881fc4d..446fba5229ff 100644 --- a/components/eamxx/src/share/grid/mesh_free_grids_manager.cpp +++ b/components/eamxx/src/share/grid/mesh_free_grids_manager.cpp @@ -290,7 +290,7 @@ load_vertical_coordinates (const nonconstgrid_ptr_type& grid, const std::string& auto hybi_v = hybi.get_view(); auto ilev_v = ilev.get_view(); auto num_lev = grid->get_num_vertical_levels(); - for (int ii=0;iinum_lev;ii++) { + for (int ii=0;ii Date: Tue, 5 Nov 2024 09:39:16 -0700 Subject: [PATCH 035/147] reorg --- components/eamxx/src/physics/p3/CMakeLists.txt | 14 -------------- .../src/physics/p3/eamxx_p3_process_interface.cpp | 2 +- .../eamxx/src/physics/p3/p3_tables_setup.cpp | 2 +- .../eamxx/src/physics/p3/tests/CMakeLists.txt | 14 ++++++++------ .../p3/{p3_f90.cpp => tests/infra/p3_data.cpp} | 2 +- .../p3/{p3_f90.hpp => tests/infra/p3_data.hpp} | 6 +++--- .../physics/p3/{ => tests/infra}/p3_ic_cases.cpp | 0 .../physics/p3/{ => tests/infra}/p3_ic_cases.hpp | 2 +- .../physics/p3/{ => tests/infra}/p3_main_wrap.cpp | 4 ++-- .../physics/p3/{ => tests/infra}/p3_main_wrap.hpp | 0 .../infra/p3_test_data.cpp} | 4 ++-- .../infra/p3_test_data.hpp} | 0 .../p3/tests/p3_autoconversion_unit_tests.cpp | 2 +- .../tests/p3_back_to_cell_average_unit_tests.cpp | 2 +- ...p3_calc_liq_relaxation_timescale_unit_tests.cpp | 2 +- .../p3/tests/p3_calc_rime_density_unit_tests.cpp | 2 +- .../p3/tests/p3_check_values_unit_tests.cpp | 4 ++-- .../p3/tests/p3_cldliq_imm_freezing_unit_tests.cpp | 2 +- .../p3/tests/p3_cloud_rain_acc_unit_tests.cpp | 2 +- .../physics/p3/tests/p3_cloud_sed_unit_tests.cpp | 2 +- .../p3/tests/p3_droplet_self_coll_unit_tests.cpp | 2 +- .../src/physics/p3/tests/p3_dsd2_unit_tests.cpp | 2 +- .../p3/tests/p3_evaporate_rain_unit_tests.cpp | 2 +- .../src/physics/p3/tests/p3_find_unit_tests.cpp | 2 +- .../tests/p3_ice_cldliq_wet_growth_unit_tests.cpp | 2 +- .../p3/tests/p3_ice_collection_unit_tests.cpp | 2 +- .../tests/p3_ice_deposition_sublimation_tests.cpp | 2 +- .../physics/p3/tests/p3_ice_melting_unit_tests.cpp | 2 +- .../p3/tests/p3_ice_nucleation_unit_tests.cpp | 2 +- .../p3_ice_relaxation_timescale_unit_tests.cpp | 2 +- .../src/physics/p3/tests/p3_ice_sed_unit_tests.cpp | 2 +- .../tests/p3_ice_supersat_conservation_tests.cpp | 2 +- .../physics/p3/tests/p3_ice_tables_unit_tests.cpp | 2 +- .../tests/p3_incloud_mixingratios_unit_tests.cpp | 2 +- .../src/physics/p3/tests/p3_main_unit_tests.cpp | 2 +- .../physics/p3/tests/p3_nc_conservation_tests.cpp | 2 +- .../physics/p3/tests/p3_ni_conservation_tests.cpp | 2 +- .../physics/p3/tests/p3_nr_conservation_tests.cpp | 2 +- .../tests/p3_prevent_liq_supersaturation_tests.cpp | 2 +- .../p3/tests/p3_rain_imm_freezing_unit_tests.cpp | 2 +- .../physics/p3/tests/p3_rain_sed_unit_tests.cpp | 4 ++-- .../p3/tests/p3_rain_self_collection_tests.cpp | 2 +- .../eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp | 2 +- .../p3_subgrid_variance_scaling_unit_tests.cpp | 2 +- .../src/physics/p3/tests/p3_table3_unit_tests.cpp | 4 ++-- components/eamxx/src/physics/p3/tests/p3_tests.cpp | 2 +- .../eamxx/src/physics/p3/tests/p3_unit_tests.cpp | 2 +- .../src/physics/p3/tests/p3_unit_tests_common.hpp | 4 ++-- .../src/physics/p3/tests/p3_upwind_unit_tests.cpp | 2 +- 49 files changed, 60 insertions(+), 72 deletions(-) rename components/eamxx/src/physics/p3/{p3_f90.cpp => tests/infra/p3_data.cpp} (99%) rename components/eamxx/src/physics/p3/{p3_f90.hpp => tests/infra/p3_data.hpp} (93%) rename components/eamxx/src/physics/p3/{ => tests/infra}/p3_ic_cases.cpp (100%) rename components/eamxx/src/physics/p3/{ => tests/infra}/p3_ic_cases.hpp (93%) rename components/eamxx/src/physics/p3/{ => tests/infra}/p3_main_wrap.cpp (96%) rename components/eamxx/src/physics/p3/{ => tests/infra}/p3_main_wrap.hpp (100%) rename components/eamxx/src/physics/p3/{p3_functions_f90.cpp => tests/infra/p3_test_data.cpp} (99%) rename components/eamxx/src/physics/p3/{p3_functions_f90.hpp => tests/infra/p3_test_data.hpp} (100%) diff --git a/components/eamxx/src/physics/p3/CMakeLists.txt b/components/eamxx/src/physics/p3/CMakeLists.txt index a1dfc946267d..df1285412a5d 100644 --- a/components/eamxx/src/physics/p3/CMakeLists.txt +++ b/components/eamxx/src/physics/p3/CMakeLists.txt @@ -1,19 +1,10 @@ set(P3_SRCS - p3_f90.cpp - p3_ic_cases.cpp p3_iso_c.f90 ${SCREAM_BASE_DIR}/../eam/src/physics/p3/scream/micro_p3.F90 eamxx_p3_process_interface.cpp eamxx_p3_run.cpp ) -if (NOT SCREAM_LIB_ONLY) - list(APPEND P3_SRCS - p3_functions_f90.cpp - p3_main_wrap.cpp - ) # Add f90 bridges needed for testing -endif() - # Add ETI source files if not on CUDA/HIP if (NOT EAMXX_ENABLE_GPU OR Kokkos_ENABLE_CUDA_RELOCATABLE_DEVICE_CODE OR Kokkos_ENABLE_HIP_RELOCATABLE_DEVICE_CODE) list(APPEND P3_SRCS @@ -123,11 +114,6 @@ endforeach() add_executable(p3_tables_setup EXCLUDE_FROM_ALL p3_tables_setup.cpp) target_link_libraries(p3_tables_setup p3) -#crusher change -if (Kokkos_ENABLE_HIP) -set_source_files_properties(p3_functions_f90.cpp PROPERTIES COMPILE_FLAGS -O0) -endif() - if (NOT SCREAM_LIB_ONLY) add_subdirectory(tests) endif() diff --git a/components/eamxx/src/physics/p3/eamxx_p3_process_interface.cpp b/components/eamxx/src/physics/p3/eamxx_p3_process_interface.cpp index a2b8ccb2e298..9dfdb385a4d9 100644 --- a/components/eamxx/src/physics/p3/eamxx_p3_process_interface.cpp +++ b/components/eamxx/src/physics/p3/eamxx_p3_process_interface.cpp @@ -3,7 +3,7 @@ #include "share/property_checks/field_lower_bound_check.hpp" // Needed for p3_init, the only F90 code still used. #include "physics/p3/p3_functions.hpp" -#include "physics/p3/p3_f90.hpp" +#include "physics/p3/p3_data.hpp" #include "ekat/ekat_assert.hpp" #include "ekat/util/ekat_units.hpp" diff --git a/components/eamxx/src/physics/p3/p3_tables_setup.cpp b/components/eamxx/src/physics/p3/p3_tables_setup.cpp index 8582674d1fe5..ec3f5ccbb433 100644 --- a/components/eamxx/src/physics/p3/p3_tables_setup.cpp +++ b/components/eamxx/src/physics/p3/p3_tables_setup.cpp @@ -1,6 +1,6 @@ // This is a tiny program that calls p3_init() to generate tables used by p3 -#include "physics/p3/p3_f90.hpp" +#include "physics/p3/p3_data.hpp" int main(int /* argc */, char** /* argv */) { scream::p3::p3_init(/* write_tables = */ true); diff --git a/components/eamxx/src/physics/p3/tests/CMakeLists.txt b/components/eamxx/src/physics/p3/tests/CMakeLists.txt index 5a949afa2498..70ac3947fa8b 100644 --- a/components/eamxx/src/physics/p3/tests/CMakeLists.txt +++ b/components/eamxx/src/physics/p3/tests/CMakeLists.txt @@ -1,5 +1,7 @@ include(ScreamUtils) +add_subdirectory(infra) + set(P3_TESTS_SRCS p3_tests.cpp p3_unit_tests.cpp @@ -56,7 +58,7 @@ else() endif() CreateUnitTest(p3_tests "${P3_TESTS_SRCS}" - LIBS p3 + LIBS p3 p3_test_infra EXE_ARGS "--flags=\\'${BASELINE_FILE_ARG}\\'" THREADS 1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC} LABELS "p3;physics") @@ -65,7 +67,7 @@ CreateUnitTest(p3_tests "${P3_TESTS_SRCS}" # No need to run lots of different thread counts. if (SCREAM_ENABLE_BASELINE_TESTS) CreateUnitTest (p3_tests_fail p3_rain_sed_unit_tests.cpp - LIBS p3 + LIBS p3 p3_test_infra EXE_ARGS "--flags=\\'${BASELINE_FILE_ARG}\\'" COMPILER_CXX_DEFS SCREAM_FORCE_RUN_DIFF LABELS "p3;physics;fail" @@ -74,7 +76,7 @@ endif() if (NOT SCREAM_P3_SMALL_KERNELS) CreateUnitTest(p3_sk_tests "${P3_TESTS_SRCS}" - LIBS p3_sk + LIBS p3_sk p3_test_infra EXE_ARGS "--flags=\\'${BASELINE_FILE_ARG}\\'" THREADS 1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC} LABELS "p3_sk;physics") @@ -82,7 +84,7 @@ if (NOT SCREAM_P3_SMALL_KERNELS) # Make sure that a diff in the two implementation triggers a failed test (in debug only) # No need to run lots of different thread counts. CreateUnitTest (p3_sk_tests_fail p3_rain_sed_unit_tests.cpp - LIBS p3_sk + LIBS p3_sk p3_test_infra EXE_ARGS "--flags=\\'${BASELINE_FILE_ARG}\\'" COMPILER_CXX_DEFS SCREAM_FORCE_RUN_DIFF LABELS "p3_sk;physics;fail" @@ -90,7 +92,7 @@ if (NOT SCREAM_P3_SMALL_KERNELS) endif() CreateUnitTest(p3_run_and_cmp "p3_run_and_cmp.cpp" - LIBS p3 + LIBS p3 p3_test_infra EXCLUDE_MAIN_CPP THREADS ${SCREAM_TEST_MAX_THREADS} EXE_ARGS "${BASELINE_FILE_ARG}" @@ -99,7 +101,7 @@ CreateUnitTest(p3_run_and_cmp "p3_run_and_cmp.cpp" # Make sure that a diff from baselines triggers a failed test (in debug only) if (SCREAM_ENABLE_BASELINE_TESTS) CreateUnitTest(p3_run_and_cmp_fail "p3_run_and_cmp.cpp" - LIBS p3 + LIBS p3 p3_test_infra COMPILER_CXX_DEFS SCREAM_FORCE_RUN_DIFF THREADS ${SCREAM_TEST_MAX_THREADS} EXE_ARGS "${BASELINE_FILE_ARG}" diff --git a/components/eamxx/src/physics/p3/p3_f90.cpp b/components/eamxx/src/physics/p3/tests/infra/p3_data.cpp similarity index 99% rename from components/eamxx/src/physics/p3/p3_f90.cpp rename to components/eamxx/src/physics/p3/tests/infra/p3_data.cpp index bf19af693e5b..793c062f63f0 100644 --- a/components/eamxx/src/physics/p3/p3_f90.cpp +++ b/components/eamxx/src/physics/p3/tests/infra/p3_data.cpp @@ -1,4 +1,4 @@ -#include "p3_f90.hpp" +#include "p3_data.hpp" #include "physics_constants.hpp" #include "p3_ic_cases.hpp" diff --git a/components/eamxx/src/physics/p3/p3_f90.hpp b/components/eamxx/src/physics/p3/tests/infra/p3_data.hpp similarity index 93% rename from components/eamxx/src/physics/p3/p3_f90.hpp rename to components/eamxx/src/physics/p3/tests/infra/p3_data.hpp index fceca0b56018..d3319445e7cd 100644 --- a/components/eamxx/src/physics/p3/p3_f90.hpp +++ b/components/eamxx/src/physics/p3/tests/infra/p3_data.hpp @@ -1,5 +1,5 @@ -#ifndef SCREAM_P3_F90_HPP -#define SCREAM_P3_F90_HPP +#ifndef SCREAM_P3_DATA_HPP +#define SCREAM_P3_DATA_HPP #include "share/scream_types.hpp" @@ -9,7 +9,7 @@ namespace scream { namespace p3 { -// Data format we can use to communicate with Fortran version. +// Data format we can use to store (and read/write) data for a full P3 run. struct P3Data { typedef std::shared_ptr Ptr; diff --git a/components/eamxx/src/physics/p3/p3_ic_cases.cpp b/components/eamxx/src/physics/p3/tests/infra/p3_ic_cases.cpp similarity index 100% rename from components/eamxx/src/physics/p3/p3_ic_cases.cpp rename to components/eamxx/src/physics/p3/tests/infra/p3_ic_cases.cpp diff --git a/components/eamxx/src/physics/p3/p3_ic_cases.hpp b/components/eamxx/src/physics/p3/tests/infra/p3_ic_cases.hpp similarity index 93% rename from components/eamxx/src/physics/p3/p3_ic_cases.hpp rename to components/eamxx/src/physics/p3/tests/infra/p3_ic_cases.hpp index 0ab502e8c00e..bbf6f133e516 100644 --- a/components/eamxx/src/physics/p3/p3_ic_cases.hpp +++ b/components/eamxx/src/physics/p3/tests/infra/p3_ic_cases.hpp @@ -1,7 +1,7 @@ #ifndef INCLUDE_SCREAM_P3_IC_CASES_HPP #define INCLUDE_SCREAM_P3_IC_CASES_HPP -#include "p3_f90.hpp" +#include "p3_data.hpp" namespace scream { namespace p3 { diff --git a/components/eamxx/src/physics/p3/p3_main_wrap.cpp b/components/eamxx/src/physics/p3/tests/infra/p3_main_wrap.cpp similarity index 96% rename from components/eamxx/src/physics/p3/p3_main_wrap.cpp rename to components/eamxx/src/physics/p3/tests/infra/p3_main_wrap.cpp index 27b510bcbc6a..4126d80c0348 100644 --- a/components/eamxx/src/physics/p3/p3_main_wrap.cpp +++ b/components/eamxx/src/physics/p3/tests/infra/p3_main_wrap.cpp @@ -1,6 +1,6 @@ #include "p3_main_wrap.hpp" -#include "p3_f90.hpp" -#include "p3_functions_f90.hpp" +#include "p3_data.hpp" +#include "p3_test_data.hpp" #include "physics_constants.hpp" #include "p3_ic_cases.hpp" diff --git a/components/eamxx/src/physics/p3/p3_main_wrap.hpp b/components/eamxx/src/physics/p3/tests/infra/p3_main_wrap.hpp similarity index 100% rename from components/eamxx/src/physics/p3/p3_main_wrap.hpp rename to components/eamxx/src/physics/p3/tests/infra/p3_main_wrap.hpp diff --git a/components/eamxx/src/physics/p3/p3_functions_f90.cpp b/components/eamxx/src/physics/p3/tests/infra/p3_test_data.cpp similarity index 99% rename from components/eamxx/src/physics/p3/p3_functions_f90.cpp rename to components/eamxx/src/physics/p3/tests/infra/p3_test_data.cpp index 19d9b59e6b8f..d0b252869871 100644 --- a/components/eamxx/src/physics/p3/p3_functions_f90.cpp +++ b/components/eamxx/src/physics/p3/tests/infra/p3_test_data.cpp @@ -1,6 +1,6 @@ -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "ekat/kokkos/ekat_kokkos_types.hpp" -#include "p3_f90.hpp" +#include "p3_data.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "ekat/ekat_pack_kokkos.hpp" diff --git a/components/eamxx/src/physics/p3/p3_functions_f90.hpp b/components/eamxx/src/physics/p3/tests/infra/p3_test_data.hpp similarity index 100% rename from components/eamxx/src/physics/p3/p3_functions_f90.hpp rename to components/eamxx/src/physics/p3/tests/infra/p3_test_data.hpp diff --git a/components/eamxx/src/physics/p3/tests/p3_autoconversion_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_autoconversion_unit_tests.cpp index 39a8d1435443..cb799a672873 100644 --- a/components/eamxx/src/physics/p3/tests/p3_autoconversion_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_autoconversion_unit_tests.cpp @@ -4,7 +4,7 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp index 9df32bc32ffe..aa70e7fe42cf 100644 --- a/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp @@ -4,7 +4,7 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "share/util/scream_setup_random_test.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp index c0da609087c1..7f3d7ee126f4 100644 --- a/components/eamxx/src/physics/p3/tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp @@ -4,7 +4,7 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "share/util/scream_setup_random_test.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_calc_rime_density_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_calc_rime_density_unit_tests.cpp index 1fee033460b5..ef4cd6218436 100644 --- a/components/eamxx/src/physics/p3/tests/p3_calc_rime_density_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_calc_rime_density_unit_tests.cpp @@ -4,7 +4,7 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_check_values_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_check_values_unit_tests.cpp index e7952c850321..2a858f86dfca 100644 --- a/components/eamxx/src/physics/p3/tests/p3_check_values_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_check_values_unit_tests.cpp @@ -4,8 +4,8 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" -#include "p3_f90.hpp" +#include "p3_test_data.hpp" +#include "p3_data.hpp" #include "share/util/scream_setup_random_test.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_cldliq_imm_freezing_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_cldliq_imm_freezing_unit_tests.cpp index 9c1524434054..5dacc132a87e 100644 --- a/components/eamxx/src/physics/p3/tests/p3_cldliq_imm_freezing_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_cldliq_imm_freezing_unit_tests.cpp @@ -4,7 +4,7 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_cloud_rain_acc_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_cloud_rain_acc_unit_tests.cpp index 276187f8ec07..fff6784ab61d 100644 --- a/components/eamxx/src/physics/p3/tests/p3_cloud_rain_acc_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_cloud_rain_acc_unit_tests.cpp @@ -4,7 +4,7 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp index e3b325a6d1f7..4f729d8fde66 100644 --- a/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp @@ -4,7 +4,7 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "share/util/scream_setup_random_test.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_droplet_self_coll_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_droplet_self_coll_unit_tests.cpp index 2a96b1b3bff2..b17d8309c3c0 100644 --- a/components/eamxx/src/physics/p3/tests/p3_droplet_self_coll_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_droplet_self_coll_unit_tests.cpp @@ -4,7 +4,7 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_dsd2_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_dsd2_unit_tests.cpp index 6563335acb0b..5bf199fa85ab 100644 --- a/components/eamxx/src/physics/p3/tests/p3_dsd2_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_dsd2_unit_tests.cpp @@ -4,7 +4,7 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_evaporate_rain_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_evaporate_rain_unit_tests.cpp index a17165bafdd2..15efcd85fcae 100644 --- a/components/eamxx/src/physics/p3/tests/p3_evaporate_rain_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_evaporate_rain_unit_tests.cpp @@ -4,7 +4,7 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_find_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_find_unit_tests.cpp index 9c812f8f8426..6e8e09226b7f 100644 --- a/components/eamxx/src/physics/p3/tests/p3_find_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_find_unit_tests.cpp @@ -4,7 +4,7 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_cldliq_wet_growth_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_cldliq_wet_growth_unit_tests.cpp index 5060d9d2fdcb..3389b52efc60 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_cldliq_wet_growth_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_cldliq_wet_growth_unit_tests.cpp @@ -4,7 +4,7 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_collection_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_collection_unit_tests.cpp index 6f34526e9b07..a2f3e7a8b726 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_collection_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_collection_unit_tests.cpp @@ -4,7 +4,7 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_deposition_sublimation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_deposition_sublimation_tests.cpp index 7a52c1b42f0b..e5983fb8c748 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_deposition_sublimation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_deposition_sublimation_tests.cpp @@ -4,7 +4,7 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "physics/share/physics_constants.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_melting_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_melting_unit_tests.cpp index 86c42707c1eb..f3e57a415bd4 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_melting_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_melting_unit_tests.cpp @@ -4,7 +4,7 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_nucleation_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_nucleation_unit_tests.cpp index 154adbabb15e..47115afd4309 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_nucleation_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_nucleation_unit_tests.cpp @@ -4,7 +4,7 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_relaxation_timescale_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_relaxation_timescale_unit_tests.cpp index 7015b7a94f8a..08bded63ff4b 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_relaxation_timescale_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_relaxation_timescale_unit_tests.cpp @@ -4,7 +4,7 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp index 9ddd97aa497b..c250a15a6ff2 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp @@ -4,7 +4,7 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "share/util/scream_setup_random_test.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp index c15c1383ab73..0e56fb75bec1 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp @@ -4,7 +4,7 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "share/util/scream_setup_random_test.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_tables_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_tables_unit_tests.cpp index 4acd18f29274..92097e57191b 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_tables_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_tables_unit_tests.cpp @@ -4,7 +4,7 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_incloud_mixingratios_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_incloud_mixingratios_unit_tests.cpp index fd768e708392..2741992b90e9 100644 --- a/components/eamxx/src/physics/p3/tests/p3_incloud_mixingratios_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_incloud_mixingratios_unit_tests.cpp @@ -4,7 +4,7 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp index b37978c66574..136fdb2fbe2a 100644 --- a/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp @@ -4,7 +4,7 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "share/util/scream_setup_random_test.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp index e13d49affc07..26b9beecc7e3 100644 --- a/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp @@ -4,7 +4,7 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "share/util/scream_setup_random_test.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp index 2f2db25d1d7a..6c50154c0462 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp @@ -4,7 +4,7 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "share/util/scream_setup_random_test.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_nr_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_nr_conservation_tests.cpp index 5b8b0d839511..b33dd02b0f04 100644 --- a/components/eamxx/src/physics/p3/tests/p3_nr_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_nr_conservation_tests.cpp @@ -4,7 +4,7 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "share/util/scream_setup_random_test.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_prevent_liq_supersaturation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_prevent_liq_supersaturation_tests.cpp index c4f95b28c836..31d18572f3b7 100644 --- a/components/eamxx/src/physics/p3/tests/p3_prevent_liq_supersaturation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_prevent_liq_supersaturation_tests.cpp @@ -3,7 +3,7 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "share/util/scream_setup_random_test.hpp" #include "share/scream_types.hpp" #include "physics/share/physics_functions.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_rain_imm_freezing_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_rain_imm_freezing_unit_tests.cpp index 92123d63e82e..875b47e47221 100644 --- a/components/eamxx/src/physics/p3/tests/p3_rain_imm_freezing_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_rain_imm_freezing_unit_tests.cpp @@ -4,7 +4,7 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_rain_sed_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_rain_sed_unit_tests.cpp index 297d899a0902..eac5c4827b62 100644 --- a/components/eamxx/src/physics/p3/tests/p3_rain_sed_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_rain_sed_unit_tests.cpp @@ -4,8 +4,8 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" -#include "p3_f90.hpp" +#include "p3_test_data.hpp" +#include "p3_data.hpp" #include "share/util/scream_setup_random_test.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_rain_self_collection_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_rain_self_collection_tests.cpp index d9d8ef004122..c175f6915477 100644 --- a/components/eamxx/src/physics/p3/tests/p3_rain_self_collection_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_rain_self_collection_tests.cpp @@ -4,7 +4,7 @@ #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp b/components/eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp index 91b7f2550481..30195147cac5 100644 --- a/components/eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp @@ -3,7 +3,7 @@ #include "share/util/scream_utils.hpp" #include "p3_main_wrap.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "p3_ic_cases.hpp" #include "ekat/util/ekat_file_utils.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_subgrid_variance_scaling_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_subgrid_variance_scaling_unit_tests.cpp index a71b3abd4225..bf1c3543dd2d 100644 --- a/components/eamxx/src/physics/p3/tests/p3_subgrid_variance_scaling_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_subgrid_variance_scaling_unit_tests.cpp @@ -3,7 +3,7 @@ #include "share/scream_types.hpp" #include "ekat/ekat_pack.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_table3_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_table3_unit_tests.cpp index cc14bfc46d2e..57197fea6c8e 100644 --- a/components/eamxx/src/physics/p3/tests/p3_table3_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_table3_unit_tests.cpp @@ -3,8 +3,8 @@ #include "p3_unit_tests_common.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" -#include "p3_f90.hpp" +#include "p3_test_data.hpp" +#include "p3_data.hpp" #include "share/scream_types.hpp" #include "ekat/ekat_pack.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_tests.cpp index cbb00623cd0d..858a231094d4 100644 --- a/components/eamxx/src/physics/p3/tests/p3_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_tests.cpp @@ -1,5 +1,5 @@ #include "catch2/catch.hpp" -#include "p3_f90.hpp" +#include "p3_data.hpp" #include "p3_main_wrap.hpp" #include "p3_ic_cases.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_unit_tests.cpp index 2c1971f0ba9d..c3f8571d1173 100644 --- a/components/eamxx/src/physics/p3/tests/p3_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_unit_tests.cpp @@ -5,7 +5,7 @@ #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "ekat/util/ekat_arch.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_unit_tests_common.hpp b/components/eamxx/src/physics/p3/tests/p3_unit_tests_common.hpp index 685284a0463a..68ff4569eb17 100644 --- a/components/eamxx/src/physics/p3/tests/p3_unit_tests_common.hpp +++ b/components/eamxx/src/physics/p3/tests/p3_unit_tests_common.hpp @@ -3,9 +3,9 @@ #include "share/scream_types.hpp" #include "p3_functions.hpp" -#include "p3_f90.hpp" +#include "p3_data.hpp" #include "ekat/util/ekat_test_utils.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include #include diff --git a/components/eamxx/src/physics/p3/tests/p3_upwind_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_upwind_unit_tests.cpp index 4c91cfe8fa98..1f65984d727a 100644 --- a/components/eamxx/src/physics/p3/tests/p3_upwind_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_upwind_unit_tests.cpp @@ -3,7 +3,7 @@ #include "p3_unit_tests_common.hpp" #include "p3_functions.hpp" -#include "p3_functions_f90.hpp" +#include "p3_test_data.hpp" #include "share/scream_types.hpp" #include "share/util/scream_setup_random_test.hpp" From 3c2c875e80bd6c211d2a4f97afd3cc0a4dfe0158 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Tue, 5 Nov 2024 10:49:27 -0700 Subject: [PATCH 036/147] More reorg --- .../eamxx/src/physics/p3/CMakeLists.txt | 1 + .../physics/p3/eamxx_p3_process_interface.cpp | 10 ++--- .../eamxx/src/physics/p3/eti/p3_init.cpp | 14 +++++++ .../src/physics/p3/impl/p3_init_impl.hpp | 40 +++++++++++++++++++ .../eamxx/src/physics/p3/p3_functions.hpp | 4 ++ components/eamxx/src/physics/p3/p3_iso_c.f90 | 9 ----- .../src/physics/p3/tests/infra/CMakeLists.txt | 15 +++++++ .../src/physics/p3/tests/infra/p3_data.cpp | 25 ------------ .../src/physics/p3/tests/infra/p3_data.hpp | 3 -- .../physics/p3/tests/infra/p3_main_wrap.cpp | 9 ++++- .../physics/p3/tests/infra/p3_test_data.cpp | 4 +- .../src/physics/p3/tests/p3_run_and_cmp.cpp | 7 ++-- .../physics/p3/tests/p3_unit_tests_common.hpp | 2 +- 13 files changed, 93 insertions(+), 50 deletions(-) create mode 100644 components/eamxx/src/physics/p3/eti/p3_init.cpp create mode 100644 components/eamxx/src/physics/p3/impl/p3_init_impl.hpp create mode 100644 components/eamxx/src/physics/p3/tests/infra/CMakeLists.txt diff --git a/components/eamxx/src/physics/p3/CMakeLists.txt b/components/eamxx/src/physics/p3/CMakeLists.txt index df1285412a5d..2a630438049d 100644 --- a/components/eamxx/src/physics/p3/CMakeLists.txt +++ b/components/eamxx/src/physics/p3/CMakeLists.txt @@ -18,6 +18,7 @@ if (NOT EAMXX_ENABLE_GPU OR Kokkos_ENABLE_CUDA_RELOCATABLE_DEVICE_CODE OR Kokkos eti/p3_table_ice.cpp eti/p3_dsd2.cpp eti/p3_find.cpp + eti/p3_init.cpp eti/p3_update_prognostics.cpp eti/p3_get_time_space_phys_variables.cpp eti/p3_autoconversion.cpp diff --git a/components/eamxx/src/physics/p3/eamxx_p3_process_interface.cpp b/components/eamxx/src/physics/p3/eamxx_p3_process_interface.cpp index 9dfdb385a4d9..f6771d6bf171 100644 --- a/components/eamxx/src/physics/p3/eamxx_p3_process_interface.cpp +++ b/components/eamxx/src/physics/p3/eamxx_p3_process_interface.cpp @@ -1,9 +1,7 @@ -#include "physics/p3/eamxx_p3_process_interface.hpp" #include "share/property_checks/field_within_interval_check.hpp" #include "share/property_checks/field_lower_bound_check.hpp" -// Needed for p3_init, the only F90 code still used. -#include "physics/p3/p3_functions.hpp" -#include "physics/p3/p3_data.hpp" +#include "p3_functions.hpp" +#include "eamxx_p3_process_interface.hpp" #include "ekat/ekat_assert.hpp" #include "ekat/util/ekat_units.hpp" @@ -243,8 +241,8 @@ void P3Microphysics::initialize_impl (const RunType /* run_type */) add_postcondition_check(get_field_out("eff_radius_qr"),m_grid,0.0,5.0e3,false); // Initialize p3 - p3::p3_init(/* write_tables = */ false, - this->get_comm().am_i_root()); + P3F::p3_init(/* write_tables = */ false, + this->get_comm().am_i_root()); // Initialize all of the structures that are passed to p3_main in run_impl. // Note: Some variables in the structures are not stored in the field manager. For these diff --git a/components/eamxx/src/physics/p3/eti/p3_init.cpp b/components/eamxx/src/physics/p3/eti/p3_init.cpp new file mode 100644 index 000000000000..b1878af89840 --- /dev/null +++ b/components/eamxx/src/physics/p3/eti/p3_init.cpp @@ -0,0 +1,14 @@ +#include "p3_init_impl.hpp" + +namespace scream { +namespace p3 { + +/* + * Explicit instantiation for doing find functions on Reals using the + * default device. + */ + +template struct Functions; + +} // namespace p3 +} // namespace scream diff --git a/components/eamxx/src/physics/p3/impl/p3_init_impl.hpp b/components/eamxx/src/physics/p3/impl/p3_init_impl.hpp new file mode 100644 index 000000000000..9b4b999bce0f --- /dev/null +++ b/components/eamxx/src/physics/p3/impl/p3_init_impl.hpp @@ -0,0 +1,40 @@ +#ifndef P3_INIT_IMPL_HPP +#define P3_INIT_IMPL_HPP + +#include "p3_functions.hpp" // for ETI only but harmless for GPU + +extern "C" { + void micro_p3_utils_init_c(scream::Real Cpair, scream::Real Rair, scream::Real RH2O, scream::Real RHO_H2O, + scream::Real MWH2O, scream::Real MWdry, scream::Real gravit, scream::Real LatVap, scream::Real LatIce, + scream::Real CpLiq, scream::Real Tmelt, scream::Real Pi, bool masterproc); + void p3_init_c(const char** lookup_file_dir, int* info, const bool& write_tables); +} + +namespace scream { +namespace p3 { + +/* + * Implementation of p3 init. Clients should NOT #include + * this file, #include p3_functions.hpp instead. + */ +template +void Functions +::p3_init (const bool write_tables, const bool masterproc) { + static bool is_init = false; + if (!is_init) { + using c = scream::physics::Constants; + micro_p3_utils_init_c(c::Cpair, c::Rair, c::RH2O, c::RHO_H2O, + c::MWH2O, c::MWdry, c::gravit, c::LatVap, c::LatIce, + c::CpLiq, c::Tmelt, c::Pi, masterproc); + static const char* dir = SCREAM_DATA_DIR "/tables"; + Int info; + p3_init_c(&dir, &info, write_tables); + EKAT_REQUIRE_MSG(info == 0, "p3_init_c returned info " << info); + is_init = true; + } +} + +} // namespace p3 +} // namespace scream + +#endif diff --git a/components/eamxx/src/physics/p3/p3_functions.hpp b/components/eamxx/src/physics/p3/p3_functions.hpp index 4ac88b4afc48..2aaaf5afb3e5 100644 --- a/components/eamxx/src/physics/p3/p3_functions.hpp +++ b/components/eamxx/src/physics/p3/p3_functions.hpp @@ -357,6 +357,9 @@ struct Functions static void init_kokkos_ice_lookup_tables( view_ice_table& ice_table_vals, view_collect_table& collect_table_vals); + static void p3_init(const bool write_tables = false, + const bool masterproc = false); + // Map (mu_r, lamr) to Table3 data. KOKKOS_FUNCTION static void lookup(const Spack& mu_r, const Spack& lamr, @@ -1468,5 +1471,6 @@ void init_tables_from_f90_c(Real* vn_table_vals_data, Real* vm_table_vals_data, # include "p3_nr_conservation_impl.hpp" # include "p3_ni_conservation_impl.hpp" # include "p3_prevent_liq_supersaturation_impl.hpp" +# inlcude "p3_init_impl.hpp" #endif // GPU && !KOKKOS_ENABLE_*_RELOCATABLE_DEVICE_CODE #endif // P3_FUNCTIONS_HPP diff --git a/components/eamxx/src/physics/p3/p3_iso_c.f90 b/components/eamxx/src/physics/p3/p3_iso_c.f90 index 34ee99cde333..71c846b71674 100644 --- a/components/eamxx/src/physics/p3/p3_iso_c.f90 +++ b/components/eamxx/src/physics/p3/p3_iso_c.f90 @@ -14,15 +14,6 @@ module p3_iso_c ! contains - subroutine append_precision(string, prefix) - - character(kind=c_char, len=512), intent(out) :: string - character(*), intent(in) :: prefix - real(kind=c_real) :: s - - write (string, '(a,i1,a1)') prefix, sizeof(s), C_NULL_CHAR - end subroutine append_precision - subroutine init_tables_from_f90_c(vn_table_vals_c, vm_table_vals_c, revap_table_vals_c, mu_table_c) bind(C) use micro_p3, only: p3_get_tables diff --git a/components/eamxx/src/physics/p3/tests/infra/CMakeLists.txt b/components/eamxx/src/physics/p3/tests/infra/CMakeLists.txt new file mode 100644 index 000000000000..6f7093a33ec7 --- /dev/null +++ b/components/eamxx/src/physics/p3/tests/infra/CMakeLists.txt @@ -0,0 +1,15 @@ +set(INFRA_SRCS + p3_data.cpp + p3_ic_cases.cpp + p3_main_wrap.cpp + p3_test_data.cpp +) + +#crusher change +if (Kokkos_ENABLE_HIP) +set_source_files_properties(p3_test_data.cpp PROPERTIES COMPILE_FLAGS -O0) +endif() + +add_library(p3_test_infra ${INFRA_SRCS}) +target_link_libraries(p3_test_infra p3) +target_include_directories(p3_test_infra PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/components/eamxx/src/physics/p3/tests/infra/p3_data.cpp b/components/eamxx/src/physics/p3/tests/infra/p3_data.cpp index 793c062f63f0..24fd6529f22d 100644 --- a/components/eamxx/src/physics/p3/tests/infra/p3_data.cpp +++ b/components/eamxx/src/physics/p3/tests/infra/p3_data.cpp @@ -6,12 +6,6 @@ using scream::Real; using scream::Int; -extern "C" { - void micro_p3_utils_init_c(Real Cpair, Real Rair, Real RH2O, Real RHO_H2O, - Real MWH2O, Real MWdry, Real gravit, Real LatVap, Real LatIce, - Real CpLiq, Real Tmelt, Real Pi, bool masterproc); - void p3_init_c(const char** lookup_file_dir, int* info, const bool& write_tables); -} namespace scream { namespace p3 { @@ -93,25 +87,6 @@ P3DataIterator::getfield (Int i) const { return fields_[i]; } -void micro_p3_utils_init (const bool masterproc) { - using c = scream::physics::Constants; - micro_p3_utils_init_c(c::Cpair, c::Rair, c::RH2O, c::RHO_H2O, - c::MWH2O, c::MWdry, c::gravit, c::LatVap, c::LatIce, - c::CpLiq, c::Tmelt, c::Pi, masterproc); -} - -void p3_init (const bool write_tables, const bool masterproc) { - static bool is_init = false; - if (!is_init) { - micro_p3_utils_init(masterproc); - static const char* dir = SCREAM_DATA_DIR "/tables"; - Int info; - p3_init_c(&dir, &info, write_tables); - EKAT_REQUIRE_MSG(info == 0, "p3_init_c returned info " << info); - is_init = true; - } -} - int test_P3Data () { P3Data d(11, 72); return 0; diff --git a/components/eamxx/src/physics/p3/tests/infra/p3_data.hpp b/components/eamxx/src/physics/p3/tests/infra/p3_data.hpp index d3319445e7cd..df5b25e311ae 100644 --- a/components/eamxx/src/physics/p3/tests/infra/p3_data.hpp +++ b/components/eamxx/src/physics/p3/tests/infra/p3_data.hpp @@ -61,9 +61,6 @@ struct P3DataIterator { void init(const P3Data::Ptr& d); }; -void p3_init(const bool write_tables = false, - const bool masterproc = false); - // We will likely want to remove these checks in the future, as we're not tied // to the exact implementation or arithmetic in P3. For now, these checks are // here to establish that the initial regression-testing code gives results that diff --git a/components/eamxx/src/physics/p3/tests/infra/p3_main_wrap.cpp b/components/eamxx/src/physics/p3/tests/infra/p3_main_wrap.cpp index 4126d80c0348..2b758a513ec5 100644 --- a/components/eamxx/src/physics/p3/tests/infra/p3_main_wrap.cpp +++ b/components/eamxx/src/physics/p3/tests/infra/p3_main_wrap.cpp @@ -28,15 +28,20 @@ Int p3_main_wrap(const P3Data& d) { } int test_p3_init () { - p3_init(); + using P3F = Functions; + + P3F::p3_init(); P3GlobalForFortran::deinit(); return 0; } int test_p3_ic () { + using P3F = Functions; + const auto d = ic::Factory::create(ic::Factory::mixed); + d->dt = 300.0; - p3_init(); + P3F::p3_init(); p3_main_wrap(*d); P3GlobalForFortran::deinit(); return 0; diff --git a/components/eamxx/src/physics/p3/tests/infra/p3_test_data.cpp b/components/eamxx/src/physics/p3/tests/infra/p3_test_data.cpp index d0b252869871..23a9998f43c6 100644 --- a/components/eamxx/src/physics/p3/tests/infra/p3_test_data.cpp +++ b/components/eamxx/src/physics/p3/tests/infra/p3_test_data.cpp @@ -23,7 +23,9 @@ namespace p3 { void p3_init_a(P3InitAP3Data& d) { - p3_init(); // need to initialize p3 first so that tables are loaded + using P3F = Functions; + + P3F::p3_init(); // need to initialize p3 first so that tables are loaded p3_init_a_c(d.ice_table_vals.data(), d.collect_table_vals.data()); } diff --git a/components/eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp b/components/eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp index 30195147cac5..4c0d5a214e04 100644 --- a/components/eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp @@ -16,6 +16,7 @@ namespace { using namespace scream; using namespace scream::p3; +using P3F = Functions; /* * p3_run_and_cmp can be run in 2 modes. First, generate_baseline @@ -87,7 +88,7 @@ struct Baseline { for (Int r = -1; r < ps.repeat; ++r) { const auto d = ic::Factory::create(ps.ic, ps.ncol, ps.nlev); set_params(ps, *d); - p3_init(); + P3F::p3_init(); if (ps.repeat > 0 && r == -1) { std::cout << "Running P3 with ni=" << d->ncol << ", nk=" << d->nlev @@ -130,7 +131,7 @@ struct Baseline { if (no_baseline) { const auto d = ic::Factory::create(ps.ic, ps.ncol, ps.nlev); set_params(ps, *d); - p3_init(); + P3F::p3_init(); for (int it=0; itfirst; std::stringstream ss(raw_flags); From 6caafa33b10f4009426239581650ddcfe65b905c Mon Sep 17 00:00:00 2001 From: James Foucar Date: Tue, 5 Nov 2024 11:05:39 -0700 Subject: [PATCH 037/147] Fix typo --- components/eamxx/src/physics/p3/p3_functions.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eamxx/src/physics/p3/p3_functions.hpp b/components/eamxx/src/physics/p3/p3_functions.hpp index 2aaaf5afb3e5..eef5a8ec73ee 100644 --- a/components/eamxx/src/physics/p3/p3_functions.hpp +++ b/components/eamxx/src/physics/p3/p3_functions.hpp @@ -1471,6 +1471,6 @@ void init_tables_from_f90_c(Real* vn_table_vals_data, Real* vm_table_vals_data, # include "p3_nr_conservation_impl.hpp" # include "p3_ni_conservation_impl.hpp" # include "p3_prevent_liq_supersaturation_impl.hpp" -# inlcude "p3_init_impl.hpp" +# include "p3_init_impl.hpp" #endif // GPU && !KOKKOS_ENABLE_*_RELOCATABLE_DEVICE_CODE #endif // P3_FUNCTIONS_HPP From 8f96dfe6c65b1d94ba919e79d17ca9621ef9a0e8 Mon Sep 17 00:00:00 2001 From: Luca Bertagna Date: Tue, 5 Nov 2024 11:58:26 -0700 Subject: [PATCH 038/147] ci(Mergify): configuration update Signed-off-by: Luca Bertagna --- .mergify.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .mergify.yml diff --git a/.mergify.yml b/.mergify.yml new file mode 100644 index 000000000000..81b832dee59e --- /dev/null +++ b/.mergify.yml @@ -0,0 +1,31 @@ +merge_protections: + - name: Enforce checks passing + description: Make sure that checks are not failing on the PR, and reviewers approved + if: + - base = master + success_conditions: + - "#approved >= 1" # At least 1 approval + - "#changes-requested == 0" # No reviewer asked for changes + - or: + - and: + - check-success=eamxx-sa/gcc-openmp/sp + - check-success=eamxx-sa/gcc-openmp/dbg + - check-success=eamxx-sa/gcc-openmp/fpe + - check-success=eamxx-sa/gcc-openmp/opt + - check-skipped="eamxx-sa/gcc-openmp/${{matrix.build_type}}" + - or: + - and: + - check-success=eamxx-sa/gcc-cuda/sp + - check-success=eamxx-sa/gcc-cuda/dbg + - check-success=eamxx-sa/gcc-cuda/opt + - check-skipped="eamxx-sa/gcc-cuda/${{matrix.build_type}}" + - or: + - and: + - check-success=eamxx-v1/cpu-gcc/ERS_Ln9.ne4_ne4.F2000-SCREAMv1-AQP1.scream-output-preset-2 + - check-success=eamxx-v1/cpu-gcc/ERS_P16_Ln22.ne30pg2_ne30pg2.FIOP-SCREAMv1-DP.scream-dpxx-arm97 + - check-success=eamxx-v1/cpu-gcc/ERS_Ln22.ne4pg2_ne4pg2.F2010-SCREAMv1.scream-small_kernels--scream-output-preset-5 + - check-success=eamxx-v1/cpu-gcc/SMS_D_Ln5.ne4pg2_oQU480.F2010-SCREAMv1-MPASSI.scream-mam4xx-all_mam4xx_procs + - check-skipped="eamxx-v1/cpu-gcc-/${{matrix.test.short_name}}" + - or: + - check-success=eamxx-scripts/cpu-gcc + - check-skipped=eamxx-scripts/cpu-gcc From 6f30ec5088c07dcff7b546cd58457efa206cd4c5 Mon Sep 17 00:00:00 2001 From: Luca Bertagna Date: Wed, 6 Nov 2024 20:50:58 -0700 Subject: [PATCH 039/147] Mergify: fix syntax --- .mergify.yml | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/.mergify.yml b/.mergify.yml index 81b832dee59e..85c1375e90fa 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -4,28 +4,17 @@ merge_protections: if: - base = master success_conditions: - - "#approved >= 1" # At least 1 approval - - "#changes-requested == 0" # No reviewer asked for changes + - "#approved-reviews-by >= 1" # At least 1 approval + - "#changes-requested-reviews-by == 0" # No reviewer asked for changes - or: - - and: - - check-success=eamxx-sa/gcc-openmp/sp - - check-success=eamxx-sa/gcc-openmp/dbg - - check-success=eamxx-sa/gcc-openmp/fpe - - check-success=eamxx-sa/gcc-openmp/opt - - check-skipped="eamxx-sa/gcc-openmp/${{matrix.build_type}}" + - check-success=eamxx-sa/gcc-openmp/* + - check-skipped=eamxx-sa/gcc-openmp/* - or: - - and: - - check-success=eamxx-sa/gcc-cuda/sp - - check-success=eamxx-sa/gcc-cuda/dbg - - check-success=eamxx-sa/gcc-cuda/opt - - check-skipped="eamxx-sa/gcc-cuda/${{matrix.build_type}}" + - check-success=eamxx-sa/gcc-cuda/* + - check-skipped=eamxx-sa/gcc-cuda/* - or: - - and: - - check-success=eamxx-v1/cpu-gcc/ERS_Ln9.ne4_ne4.F2000-SCREAMv1-AQP1.scream-output-preset-2 - - check-success=eamxx-v1/cpu-gcc/ERS_P16_Ln22.ne30pg2_ne30pg2.FIOP-SCREAMv1-DP.scream-dpxx-arm97 - - check-success=eamxx-v1/cpu-gcc/ERS_Ln22.ne4pg2_ne4pg2.F2010-SCREAMv1.scream-small_kernels--scream-output-preset-5 - - check-success=eamxx-v1/cpu-gcc/SMS_D_Ln5.ne4pg2_oQU480.F2010-SCREAMv1-MPASSI.scream-mam4xx-all_mam4xx_procs - - check-skipped="eamxx-v1/cpu-gcc-/${{matrix.test.short_name}}" + - check-success=eamxx-v1/cpu-gcc/* + - check-skipped=eamxx-v1/cpu-gcc/* - or: - check-success=eamxx-scripts/cpu-gcc - check-skipped=eamxx-scripts/cpu-gcc From e0a1f20b50e6f9579eba6893c77c8adb90a3f327 Mon Sep 17 00:00:00 2001 From: Oscar Diaz-Ibarra Date: Thu, 7 Nov 2024 09:11:57 -0700 Subject: [PATCH 040/147] Remove overload of create_tracer_data_reader. Pass tracer file type to change tag Lev of vertical emissions. --- ...mxx_mam_microphysics_process_interface.cpp | 2 +- .../mam/readfiles/tracer_reader_utils.hpp | 42 +++++++------------ 2 files changed, 15 insertions(+), 29 deletions(-) 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 0b1440b3826f..6f26646ad6fa 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 @@ -292,7 +292,7 @@ void MAMMicrophysics::set_grids( auto file_reader = scream::mam_coupling::create_tracer_data_reader(hor_rem, file_name, - data_tracer, extfrc_map_file); + data_tracer.file_type); VertEmissionsHorizInterp_.push_back(hor_rem); VertEmissionsDataReader_.push_back(file_reader); vert_emis_data_.push_back(data_tracer); diff --git a/components/eamxx/src/physics/mam/readfiles/tracer_reader_utils.hpp b/components/eamxx/src/physics/mam/readfiles/tracer_reader_utils.hpp index e31300a679a6..bec628b1f965 100644 --- a/components/eamxx/src/physics/mam/readfiles/tracer_reader_utils.hpp +++ b/components/eamxx/src/physics/mam/readfiles/tracer_reader_utils.hpp @@ -72,6 +72,8 @@ enum TracerFileType { ZONAL, // vertical emission files VERT_EMISSION, + // + NONE }; enum TracerDataIndex { BEG = 0, END = 1, OUT = 2 }; @@ -381,11 +383,6 @@ inline std::shared_ptr create_horiz_remapper( model_grid->clone("tracer_horiz_interp_tgt_grid", true); horiz_interp_tgt_grid->reset_num_vertical_lev(tracer_data.nlevs_data); - if(tracer_data.file_type == VERT_EMISSION) { - horiz_interp_tgt_grid->reset_field_tag_name(LEV, "altitude"); - horiz_interp_tgt_grid->reset_field_tag_name(ILEV, "altitude_int"); - } - const int ncols_model = model_grid->get_num_global_dofs(); std::shared_ptr remapper; if(tracer_data.ncols_data == ncols_model) { @@ -436,44 +433,33 @@ inline std::shared_ptr create_horiz_remapper( } // create_horiz_remapper -inline std::shared_ptr create_tracer_data_reader( - const std::shared_ptr &horiz_remapper, - const std::string &tracer_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(tracer_data_file, io_grid, io_fields, - true); -} // create_tracer_data_reader - inline std::shared_ptr create_tracer_data_reader( const std::shared_ptr &horiz_remapper, const std::string &tracer_data_file, - const TracerData &tracer_data, - const std::string &extfrc_map_file - ) { + const TracerFileType file_type = NONE) +{ 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(); - - // NOTE: If we are using a vertical emission NC file with altitude instead of levels, - // we must rename this tag. This is only necessary when a map file is used. - if(tracer_data.file_type == VERT_EMISSION && extfrc_map_file != ""){ + if(file_type == VERT_EMISSION ){ + // NOTE: If we are using a vertical emission nc file with altitude instead of lev, + // we must rename this tag. + // We need to perform a shallow clone of io_grid because tags are const in this object. auto horiz_interp_src_grid = io_grid->clone("tracer_horiz_interp_src_grid", true); - horiz_interp_src_grid->reset_field_tag_name(LEV, "altitude"); - horiz_interp_src_grid->reset_field_tag_name(ILEV, "altitude_int"); - return std::make_shared(tracer_data_file, horiz_interp_src_grid, io_fields, + horiz_interp_src_grid->reset_field_tag_name(LEV, "altitude"); + horiz_interp_src_grid->reset_field_tag_name(ILEV, "altitude_int"); + return std::make_shared(tracer_data_file, horiz_interp_src_grid, io_fields, true); - } else { + } else{ + // We do not need to rename tags in or clone io_grid for other types of files. return std::make_shared(tracer_data_file, io_grid, io_fields, true); } + } // create_tracer_data_reader inline void update_tracer_data_from_file( From deb0ceba431b798545f446466dbf46fe5dbe9610 Mon Sep 17 00:00:00 2001 From: Luca Bertagna Date: Thu, 7 Nov 2024 11:41:27 -0700 Subject: [PATCH 041/147] Workflows: nano-fixes to eamxx workflows * Add name entry for pre_process_pr steps * Ensure actual jobs run if pre_process_pr is skipped --- .github/workflows/eamxx-sa-testing.yml | 10 ++++++---- .github/workflows/eamxx-scripts-tests.yml | 6 ++++-- .github/workflows/eamxx-v1-testing.yml | 6 ++++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/.github/workflows/eamxx-sa-testing.yml b/.github/workflows/eamxx-sa-testing.yml index 0c0bca084132..bbfa12b80acc 100644 --- a/.github/workflows/eamxx-sa-testing.yml +++ b/.github/workflows/eamxx-sa-testing.yml @@ -44,7 +44,8 @@ jobs: relevant_paths: ${{ steps.check_paths.outputs.value }} labels: ${{ steps.get_labels.outputs.labels }} steps: - - id: check_paths + - name: Check files modified by PR + id: check_paths run: | paths=( components/eamxx @@ -74,14 +75,15 @@ jobs: echo "No relevant files touched by this PR." echo "value=false" >> $GITHUB_OUTPUT fi - - id: get_labels + - name: Retrieve PR labels + id: get_labels run: | labels="${{ join(github.event.pull_request.labels.*.name, ',') }}" echo "labels=${labels}" >> $GITHUB_OUTPUT gcc-openmp: needs: [pre_process_pr] if: | - github.event_name == 'schedule' || + success() && github.event_name == 'schedule' || ( github.event_name == 'pull_request' && needs.pre_process_pr.outputs.relevant_paths=='true' && @@ -128,7 +130,7 @@ jobs: gcc-cuda: needs: [pre_process_pr] if: | - github.event_name == 'schedule' || + success() && github.event_name == 'schedule' || ( github.event_name == 'pull_request' && needs.pre_process_pr.outputs.relevant_paths=='true' && diff --git a/.github/workflows/eamxx-scripts-tests.yml b/.github/workflows/eamxx-scripts-tests.yml index d41f3eaf62ae..6d39200e2739 100644 --- a/.github/workflows/eamxx-scripts-tests.yml +++ b/.github/workflows/eamxx-scripts-tests.yml @@ -28,7 +28,8 @@ jobs: relevant_paths: ${{ steps.check_paths.outputs.value}} labels: ${{ steps.get_labels.outputs.labels }} steps: - - id: check_paths + - name: Check files modified by PR + id: check_paths run: | paths=( components/eamxx/scripts @@ -53,7 +54,8 @@ jobs: echo "No relevant files touched by this PR." echo "value=false" >> $GITHUB_OUTPUT fi - - id: get_labels + - name: Retrieve PR labels + id: get_labels run: | labels="${{ join(github.event.pull_request.labels.*.name, ',') }}" echo "labels=${labels}" >> $GITHUB_OUTPUT diff --git a/.github/workflows/eamxx-v1-testing.yml b/.github/workflows/eamxx-v1-testing.yml index ca83177fde58..3a4b28cfed32 100644 --- a/.github/workflows/eamxx-v1-testing.yml +++ b/.github/workflows/eamxx-v1-testing.yml @@ -36,7 +36,8 @@ jobs: relevant_paths: ${{ steps.check_paths.outputs.value }} labels: ${{ steps.get_labels.outputs.labels }} steps: - - id: check_paths + - name: Check files modified by PR + id: check_paths run: | paths=( components/eamxx @@ -66,7 +67,8 @@ jobs: echo "No relevant files touched by this PR." echo "value=false" >> $GITHUB_OUTPUT fi - - id: get_labels + - name: Retrieve PR labels + id: get_labels run: | labels="${{ join(github.event.pull_request.labels.*.name, ',') }}" echo "labels=${labels}" >> $GITHUB_OUTPUT From 776a79a9083f592b93a0f469899aca4c63f6abf1 Mon Sep 17 00:00:00 2001 From: Luca Bertagna Date: Thu, 7 Nov 2024 12:20:07 -0700 Subject: [PATCH 042/147] Update .mergify.yml Disable comments from merge_protections on PRs --- .mergify.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.mergify.yml b/.mergify.yml index 85c1375e90fa..e931d54eb095 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -1,6 +1,7 @@ merge_protections: - name: Enforce checks passing description: Make sure that checks are not failing on the PR, and reviewers approved + comment: false if: - base = master success_conditions: From 2b6fd04d4b484fa28d41ef750444e2068407c9a4 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Thu, 7 Nov 2024 15:45:25 -0700 Subject: [PATCH 043/147] pre sed --- .../{ => infra}/p3_unit_tests_common.hpp | 35 ++++++++++++++++++- .../p3/tests/p3_autoconversion_unit_tests.cpp | 3 -- .../p3_back_to_cell_average_unit_tests.cpp | 4 --- ...lc_liq_relaxation_timescale_unit_tests.cpp | 4 --- .../tests/p3_calc_rime_density_unit_tests.cpp | 3 -- .../p3/tests/p3_check_values_unit_tests.cpp | 1 - .../p3_cldliq_imm_freezing_unit_tests.cpp | 3 -- .../p3/tests/p3_cloud_rain_acc_unit_tests.cpp | 3 -- .../p3/tests/p3_cloud_sed_unit_tests.cpp | 4 --- .../tests/p3_droplet_self_coll_unit_tests.cpp | 3 -- .../physics/p3/tests/p3_dsd2_unit_tests.cpp | 6 ---- .../p3/tests/p3_evaporate_rain_unit_tests.cpp | 3 -- .../p3_ice_cldliq_wet_growth_unit_tests.cpp | 3 -- .../p3/tests/p3_ice_collection_unit_tests.cpp | 9 ----- .../p3_ice_deposition_sublimation_tests.cpp | 3 -- .../p3/tests/p3_ice_melting_unit_tests.cpp | 3 -- .../p3/tests/p3_ice_nucleation_unit_tests.cpp | 3 -- ...p3_ice_relaxation_timescale_unit_tests.cpp | 3 -- .../p3/tests/p3_ice_sed_unit_tests.cpp | 10 ------ .../p3_ice_supersat_conservation_tests.cpp | 4 --- .../p3/tests/p3_ice_tables_unit_tests.cpp | 3 -- .../p3_incloud_mixingratios_unit_tests.cpp | 3 -- .../physics/p3/tests/p3_main_unit_tests.cpp | 13 ------- .../p3/tests/p3_nc_conservation_tests.cpp | 4 --- .../p3/tests/p3_ni_conservation_tests.cpp | 4 --- .../p3/tests/p3_nr_conservation_tests.cpp | 4 --- .../p3_prevent_liq_supersaturation_tests.cpp | 4 --- .../tests/p3_rain_imm_freezing_unit_tests.cpp | 3 -- .../p3/tests/p3_rain_sed_unit_tests.cpp | 17 +++------ .../tests/p3_rain_self_collection_tests.cpp | 3 -- ...p3_subgrid_variance_scaling_unit_tests.cpp | 14 ++------ .../src/physics/p3/tests/p3_unit_tests.cpp | 21 ----------- .../physics/p3/tests/p3_upwind_unit_tests.cpp | 20 ++++------- .../share/util/scream_setup_random_test.hpp | 8 +++-- 34 files changed, 53 insertions(+), 178 deletions(-) rename components/eamxx/src/physics/p3/tests/{ => infra}/p3_unit_tests_common.hpp (82%) diff --git a/components/eamxx/src/physics/p3/tests/p3_unit_tests_common.hpp b/components/eamxx/src/physics/p3/tests/infra/p3_unit_tests_common.hpp similarity index 82% rename from components/eamxx/src/physics/p3/tests/p3_unit_tests_common.hpp rename to components/eamxx/src/physics/p3/tests/infra/p3_unit_tests_common.hpp index 36614cf9a884..523315ae5ecc 100644 --- a/components/eamxx/src/physics/p3/tests/p3_unit_tests_common.hpp +++ b/components/eamxx/src/physics/p3/tests/infra/p3_unit_tests_common.hpp @@ -2,6 +2,7 @@ #define P3_UNIT_TESTS_COMMON_HPP #include "share/scream_types.hpp" +#include "share/util/scream_setup_random_test.hpp" #include "p3_functions.hpp" #include "p3_data.hpp" #include "ekat/util/ekat_test_utils.hpp" @@ -72,11 +73,15 @@ struct UnitWrap { struct Base { std::string m_baseline_path; + std::string m_test_name; BASELINE_ACTION m_baseline_action; + ekat::FILEPtr m_fid; Base() : m_baseline_path(""), - m_baseline_action(NONE) + m_test_name(Catch::getResultCapture().getCurrentTestName()), + m_baseline_action(NONE), + m_fid() { Functions::p3_init(); // many tests will need fortran table data auto& ts = ekat::TestSession::get(); @@ -104,12 +109,40 @@ struct UnitWrap { } EKAT_REQUIRE_MSG( !(m_baseline_action != NONE && m_baseline_path == ""), "P3 unit test flags problem: baseline actions were requested but no baseline path was provided"); + + std::string baseline_name = m_baseline_path + "/" + m_test_name; + if (m_baseline_action == COMPARE) { + m_fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); + } + else if (m_baseline_action == GENERATE) { + m_fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); + } } ~Base() { scream::p3::P3GlobalForFortran::deinit(); } + + std::mt19937_64 get_engine() + { + if (m_baseline_action != COMPARE) { + // We can use any seed + int seed; + auto engine = setup_random_test(nullptr, &seed); + if (m_baseline_action == GENERATE) { + // Write the seed + ekat::write(&seed, 1, m_fid); + } + return engine; + } + else { + // Read the seed + int seed; + ekat::read(&seed, 1, m_fid); + return setup_random_test(seed); + } + } }; // Put struct decls here diff --git a/components/eamxx/src/physics/p3/tests/p3_autoconversion_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_autoconversion_unit_tests.cpp index cb799a672873..bc99ac99150d 100644 --- a/components/eamxx/src/physics/p3/tests/p3_autoconversion_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_autoconversion_unit_tests.cpp @@ -60,9 +60,7 @@ void cloud_water_autoconversion_unit_bfb_tests() { Kokkos::deep_copy(cwadc_device, cwadc_host); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/cloud_water_autoconversion.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { cwadc[i].read(fid); } @@ -117,7 +115,6 @@ void cloud_water_autoconversion_unit_bfb_tests() { } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { cwadc_host(s).write(fid); } diff --git a/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp index aa70e7fe42cf..1e36a024508a 100644 --- a/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp @@ -5,7 +5,6 @@ #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" #include "p3_test_data.hpp" -#include "share/util/scream_setup_random_test.hpp" #include "p3_unit_tests_common.hpp" @@ -45,9 +44,7 @@ void run_bfb() Kokkos::deep_copy(device_data, host_data); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/back_to_cell_average.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { back_to_cell_average_data[i].read(fid); } @@ -176,7 +173,6 @@ void run_bfb() } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { host_data(s).write(fid); } diff --git a/components/eamxx/src/physics/p3/tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp index 7f3d7ee126f4..e528d27328d3 100644 --- a/components/eamxx/src/physics/p3/tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp @@ -5,7 +5,6 @@ #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" #include "p3_test_data.hpp" -#include "share/util/scream_setup_random_test.hpp" #include "p3_unit_tests_common.hpp" @@ -55,9 +54,7 @@ struct UnitWrap::UnitTest::TestCalcLiqRelaxationTimescale : public UnitWrap:: } // Read baseline data - std::string baseline_name = this->m_baseline_path + "/calc_liq_relaxation_timescale.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { self[i].read(fid); } @@ -108,7 +105,6 @@ struct UnitWrap::UnitTest::TestCalcLiqRelaxationTimescale : public UnitWrap:: } } else { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { self_host(s).write(fid); } diff --git a/components/eamxx/src/physics/p3/tests/p3_calc_rime_density_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_calc_rime_density_unit_tests.cpp index ef4cd6218436..bb186ac42720 100644 --- a/components/eamxx/src/physics/p3/tests/p3_calc_rime_density_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_calc_rime_density_unit_tests.cpp @@ -88,9 +88,7 @@ void run_bfb() Kokkos::deep_copy(device_data, host_data); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/calc_rime_density.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { calc_rime_density_data[i].read(fid); } @@ -137,7 +135,6 @@ void run_bfb() } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { host_data(s).write(fid); } diff --git a/components/eamxx/src/physics/p3/tests/p3_check_values_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_check_values_unit_tests.cpp index 2a858f86dfca..90c8d28be932 100644 --- a/components/eamxx/src/physics/p3/tests/p3_check_values_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_check_values_unit_tests.cpp @@ -6,7 +6,6 @@ #include "p3_functions.hpp" #include "p3_test_data.hpp" #include "p3_data.hpp" -#include "share/util/scream_setup_random_test.hpp" #include "p3_unit_tests_common.hpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_cldliq_imm_freezing_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_cldliq_imm_freezing_unit_tests.cpp index 5dacc132a87e..06c725d10a8e 100644 --- a/components/eamxx/src/physics/p3/tests/p3_cldliq_imm_freezing_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_cldliq_imm_freezing_unit_tests.cpp @@ -71,9 +71,7 @@ void run_bfb() Kokkos::deep_copy(device_data, host_data); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/cldliq_imm_freezing.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { cldliq_imm_freezing_data[i].read(fid); } @@ -120,7 +118,6 @@ void run_bfb() } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { host_data(s).write(fid); } diff --git a/components/eamxx/src/physics/p3/tests/p3_cloud_rain_acc_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_cloud_rain_acc_unit_tests.cpp index fff6784ab61d..011142942a72 100644 --- a/components/eamxx/src/physics/p3/tests/p3_cloud_rain_acc_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_cloud_rain_acc_unit_tests.cpp @@ -74,9 +74,7 @@ void run_bfb() Kokkos::deep_copy(device_data, host_data); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/cloud_rain_accretion.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { cloud_rain_acc_data[i].read(fid); } @@ -123,7 +121,6 @@ void run_bfb() } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { host_data(s).write(fid); } diff --git a/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp index 4f729d8fde66..0c60420f3d8d 100644 --- a/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp @@ -5,7 +5,6 @@ #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" #include "p3_test_data.hpp" -#include "share/util/scream_setup_random_test.hpp" #include "p3_unit_tests_common.hpp" @@ -57,9 +56,7 @@ void run_bfb() }; // Read baseline data - std::string baseline_name = this->m_baseline_path + "/cloud_sedimentation.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (auto& d : csds_baseline) { d.read(fid); } @@ -91,7 +88,6 @@ void run_bfb() } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int i = 0; i < num_runs; ++i) { csds_cxx[i].write(fid); } diff --git a/components/eamxx/src/physics/p3/tests/p3_droplet_self_coll_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_droplet_self_coll_unit_tests.cpp index b17d8309c3c0..a649d31a4897 100644 --- a/components/eamxx/src/physics/p3/tests/p3_droplet_self_coll_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_droplet_self_coll_unit_tests.cpp @@ -73,9 +73,7 @@ void run_bfb() Kokkos::deep_copy(device_data, host_data); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/droplet_self_collection.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { droplet_self_coll_data[i].read(fid); } @@ -117,7 +115,6 @@ void run_bfb() } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { host_data(s).write(fid); } diff --git a/components/eamxx/src/physics/p3/tests/p3_dsd2_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_dsd2_unit_tests.cpp index 5bf199fa85ab..93187632ced9 100644 --- a/components/eamxx/src/physics/p3/tests/p3_dsd2_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_dsd2_unit_tests.cpp @@ -61,9 +61,7 @@ struct UnitWrap::UnitTest::TestDsd2 : public UnitWrap::UnitTest::Base { Kokkos::deep_copy(gcdd_device, gcdd_host); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/get_cloud_dsd2.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { gcdd[i].read(fid); } @@ -110,7 +108,6 @@ struct UnitWrap::UnitTest::TestDsd2 : public UnitWrap::UnitTest::Base { } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { gcdd_host(s).write(fid); } @@ -155,9 +152,7 @@ struct UnitWrap::UnitTest::TestDsd2 : public UnitWrap::UnitTest::Base { Kokkos::deep_copy(grdd_device, grdd_host); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/get_rain_dsd2.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { grdd[i].read(fid); } @@ -203,7 +198,6 @@ struct UnitWrap::UnitTest::TestDsd2 : public UnitWrap::UnitTest::Base { } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { grdd_host(s).write(fid); } diff --git a/components/eamxx/src/physics/p3/tests/p3_evaporate_rain_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_evaporate_rain_unit_tests.cpp index 15efcd85fcae..005d13bda2de 100644 --- a/components/eamxx/src/physics/p3/tests/p3_evaporate_rain_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_evaporate_rain_unit_tests.cpp @@ -174,9 +174,7 @@ struct UnitWrap::UnitTest::TestEvapSublPrecip : public UnitWrap::UnitTest: Kokkos::deep_copy(espd_device, espd_host); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/evaporate_rain.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { espd[i].read(fid); } @@ -252,7 +250,6 @@ struct UnitWrap::UnitTest::TestEvapSublPrecip : public UnitWrap::UnitTest: } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { espd_host(s).write(fid); } diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_cldliq_wet_growth_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_cldliq_wet_growth_unit_tests.cpp index 3389b52efc60..26f5723ff1c9 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_cldliq_wet_growth_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_cldliq_wet_growth_unit_tests.cpp @@ -58,9 +58,7 @@ struct UnitWrap::UnitTest::TestIceCldliqWetGrowth : public UnitWrap::UnitTest Kokkos::deep_copy(self_device, self_host); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/ice_cldliq_wet_growth.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { self[i].read(fid); } @@ -130,7 +128,6 @@ struct UnitWrap::UnitTest::TestIceCldliqWetGrowth : public UnitWrap::UnitTest } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { self_host(s).write(fid); } diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_collection_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_collection_unit_tests.cpp index a2f3e7a8b726..a6e65426dbe7 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_collection_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_collection_unit_tests.cpp @@ -64,9 +64,7 @@ struct UnitWrap::UnitTest::TestIceCollection : public UnitWrap::UnitTest:: Kokkos::deep_copy(cldliq_device, cldliq_host); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/ice_cldliq_collection.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { cldliq[i].read(fid); } @@ -122,7 +120,6 @@ struct UnitWrap::UnitTest::TestIceCollection : public UnitWrap::UnitTest:: } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { cldliq_host(s).write(fid); } @@ -168,9 +165,7 @@ struct UnitWrap::UnitTest::TestIceCollection : public UnitWrap::UnitTest:: Kokkos::deep_copy(rain_device, rain_host); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/ice_rain_collection.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { rain[i].read(fid); } @@ -219,7 +214,6 @@ struct UnitWrap::UnitTest::TestIceCollection : public UnitWrap::UnitTest:: } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { rain_host(s).write(fid); } @@ -265,9 +259,7 @@ struct UnitWrap::UnitTest::TestIceCollection : public UnitWrap::UnitTest:: Kokkos::deep_copy(self_device, self_host); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/ice_self_collection.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { self[i].read(fid); } @@ -306,7 +298,6 @@ struct UnitWrap::UnitTest::TestIceCollection : public UnitWrap::UnitTest:: } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { self_host(s).write(fid); } diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_deposition_sublimation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_deposition_sublimation_tests.cpp index e5983fb8c748..2ef5e66803ad 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_deposition_sublimation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_deposition_sublimation_tests.cpp @@ -82,9 +82,7 @@ struct UnitWrap::UnitTest::TestIceDepositionSublimation : public UnitWrap::Un Kokkos::deep_copy(cxx_device, cxx_host); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/ice_deposition_sublimation.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { baseline_data[i].read(fid); } @@ -152,7 +150,6 @@ struct UnitWrap::UnitTest::TestIceDepositionSublimation : public UnitWrap::Un } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { cxx_host(s).write(fid); } diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_melting_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_melting_unit_tests.cpp index f3e57a415bd4..739f2a316296 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_melting_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_melting_unit_tests.cpp @@ -58,9 +58,7 @@ void ice_melting_bfb() { Kokkos::deep_copy(IceMelt_device, IceMelt_host); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/ice_melting.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { IceMelt[i].read(fid); } @@ -110,7 +108,6 @@ void ice_melting_bfb() { } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { IceMelt_host(s).write(fid); } diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_nucleation_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_nucleation_unit_tests.cpp index 47115afd4309..f0b4cc4a3242 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_nucleation_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_nucleation_unit_tests.cpp @@ -56,9 +56,7 @@ struct UnitWrap::UnitTest::TestIceNucleation : public UnitWrap::UnitTest:: std::string root_name = "ice_nucleation"; std::string file_name = root_name + (do_predict_nc ? "1" : "0") + (do_prescribed_CCN ? "1" : "0"); - std::string baseline_name = this->m_baseline_path + "/" + file_name + ".dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { self[i].read(fid); } @@ -106,7 +104,6 @@ struct UnitWrap::UnitTest::TestIceNucleation : public UnitWrap::UnitTest:: } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { self_host(s).write(fid); } diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_relaxation_timescale_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_relaxation_timescale_unit_tests.cpp index 08bded63ff4b..d0a9b3902f9b 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_relaxation_timescale_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_relaxation_timescale_unit_tests.cpp @@ -50,9 +50,7 @@ struct UnitWrap::UnitTest::TestIceRelaxationTimescale : public UnitWrap::Unit }; // Read baseline data - std::string baseline_name = this->m_baseline_path + "/ice_relaxation_timescale.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { self[i].read(fid); } @@ -104,7 +102,6 @@ struct UnitWrap::UnitTest::TestIceRelaxationTimescale : public UnitWrap::Unit } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { self_host(s).write(fid); } diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp index c250a15a6ff2..6f567a8ae64f 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp @@ -5,7 +5,6 @@ #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" #include "p3_test_data.hpp" -#include "share/util/scream_setup_random_test.hpp" #include "p3_unit_tests_common.hpp" @@ -79,9 +78,7 @@ void run_bfb_calc_bulk_rhime() Kokkos::deep_copy(cbrr_device, cbrr_host); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/calc_bulk_rho_rime.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { cbrr_baseline[i].read(fid); } @@ -124,7 +121,6 @@ void run_bfb_calc_bulk_rhime() } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { cbrr_host(s).write(fid); } @@ -160,9 +156,7 @@ void run_bfb_ice_sed() }; // Read baseline data - std::string baseline_name = this->m_baseline_path + "/ice_sedimentation.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < num_runs; ++i) { isds_baseline[i].read(fid); } @@ -198,7 +192,6 @@ void run_bfb_ice_sed() } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int i = 0; i < num_runs; ++i) { isds_cxx[i].write(fid); } @@ -243,9 +236,7 @@ void run_bfb_homogeneous_freezing() }; // Read baseline data - std::string baseline_name = this->m_baseline_path + "/homogeneous_freezing.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (auto& d : hfds_baseline) { d.read(fid); } @@ -277,7 +268,6 @@ void run_bfb_homogeneous_freezing() } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int i = 0; i < num_runs; ++i) { hfds_cxx[i].write(fid); } diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp index 0e56fb75bec1..0324bbf14982 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp @@ -5,7 +5,6 @@ #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" #include "p3_test_data.hpp" -#include "share/util/scream_setup_random_test.hpp" #include "p3_unit_tests_common.hpp" @@ -44,9 +43,7 @@ struct UnitWrap::UnitTest::TestIceSupersatConservation : public UnitWrap::Uni Kokkos::deep_copy(cxx_device, cxx_host); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/ice_supersat_conservation.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { baseline_data[i].read(fid); } @@ -90,7 +87,6 @@ struct UnitWrap::UnitTest::TestIceSupersatConservation : public UnitWrap::Uni } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { cxx_host(s).write(fid); } diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_tables_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_tables_unit_tests.cpp index 92097e57191b..22ac35475fb0 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_tables_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_tables_unit_tests.cpp @@ -210,9 +210,7 @@ struct UnitWrap::UnitTest::TestTableIce : public UnitWrap::UnitTest::Base Kokkos::deep_copy(lidb_device, lidb_host); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/p3_ice_tables_all.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { lid[i].read(fid); lidb[i].read(fid); @@ -296,7 +294,6 @@ struct UnitWrap::UnitTest::TestTableIce : public UnitWrap::UnitTest::Base } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { lid[s].dumi = int_results_mirror(0, s); lid[s].dumjj = int_results_mirror(1, s); diff --git a/components/eamxx/src/physics/p3/tests/p3_incloud_mixingratios_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_incloud_mixingratios_unit_tests.cpp index 2741992b90e9..79bffe1ac99b 100644 --- a/components/eamxx/src/physics/p3/tests/p3_incloud_mixingratios_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_incloud_mixingratios_unit_tests.cpp @@ -70,9 +70,7 @@ struct UnitWrap::UnitTest::TestIncloudMixing : public UnitWrap::UnitTest:: Kokkos::deep_copy(self_device, self_host); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/calculate_incloud_mixingratios.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { self[i].read(fid); } @@ -132,7 +130,6 @@ struct UnitWrap::UnitTest::TestIncloudMixing : public UnitWrap::UnitTest:: } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { self_host(s).write(fid); } diff --git a/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp index 136fdb2fbe2a..26f075dfef31 100644 --- a/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp @@ -5,7 +5,6 @@ #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" #include "p3_test_data.hpp" -#include "share/util/scream_setup_random_test.hpp" #include "p3_unit_tests_common.hpp" @@ -96,9 +95,7 @@ void run_bfb_p3_main_part1() }; // Read baseline data - std::string baseline_name = this->m_baseline_path + "/p3_main_part1.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (auto& d : isds_baseline) { d.read(fid); } @@ -153,7 +150,6 @@ void run_bfb_p3_main_part1() } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int i = 0; i < num_runs; ++i) { isds_cxx[i].write(fid); } @@ -208,9 +204,7 @@ void run_bfb_p3_main_part2() }; // Read baseline data - std::string baseline_name = this->m_baseline_path + "/p3_main_part2.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (auto& d : isds_baseline) { d.read(fid); } @@ -287,7 +281,6 @@ void run_bfb_p3_main_part2() } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int i = 0; i < num_runs; ++i) { isds_cxx[i].write(fid); } @@ -335,9 +328,7 @@ void run_bfb_p3_main_part3() }; // Read baseline data - std::string baseline_name = this->m_baseline_path + "/p3_main_part3.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (auto& d : isds_baseline) { d.read(fid); } @@ -392,7 +383,6 @@ void run_bfb_p3_main_part3() } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int i = 0; i < num_runs; ++i) { isds_cxx[i].write(fid); } @@ -447,9 +437,7 @@ void run_bfb_p3_main() }; // Read baseline data - std::string baseline_name = this->m_baseline_path + "/p3_main.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (auto& d : isds_baseline) { d.read(fid); } @@ -509,7 +497,6 @@ void run_bfb_p3_main() } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int i = 0; i < num_runs; ++i) { isds_cxx[i].write(fid); } diff --git a/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp index 26b9beecc7e3..288a52c4ad89 100644 --- a/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp @@ -5,7 +5,6 @@ #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" #include "p3_test_data.hpp" -#include "share/util/scream_setup_random_test.hpp" #include "p3_unit_tests_common.hpp" @@ -37,9 +36,7 @@ struct UnitWrap::UnitTest::TestNcConservation : public UnitWrap::UnitTest: Kokkos::deep_copy(cxx_device, cxx_host); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/nc_conservation.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { baseline_data[i].read(fid); } @@ -86,7 +83,6 @@ struct UnitWrap::UnitTest::TestNcConservation : public UnitWrap::UnitTest: } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { cxx_host(s).write(fid); } diff --git a/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp index 6c50154c0462..a721dc7b9afc 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp @@ -5,7 +5,6 @@ #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" #include "p3_test_data.hpp" -#include "share/util/scream_setup_random_test.hpp" #include "p3_unit_tests_common.hpp" @@ -37,9 +36,7 @@ struct UnitWrap::UnitTest::TestNiConservation : public UnitWrap::UnitTest: Kokkos::deep_copy(cxx_device, cxx_host); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/ni_conservation.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { baseline_data[i].read(fid); } @@ -85,7 +82,6 @@ struct UnitWrap::UnitTest::TestNiConservation : public UnitWrap::UnitTest: } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { cxx_host(s).write(fid); } diff --git a/components/eamxx/src/physics/p3/tests/p3_nr_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_nr_conservation_tests.cpp index b33dd02b0f04..e7a75821ae17 100644 --- a/components/eamxx/src/physics/p3/tests/p3_nr_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_nr_conservation_tests.cpp @@ -5,7 +5,6 @@ #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" #include "p3_test_data.hpp" -#include "share/util/scream_setup_random_test.hpp" #include "p3_unit_tests_common.hpp" @@ -38,9 +37,7 @@ struct UnitWrap::UnitTest::TestNrConservation : public UnitWrap::UnitTest: Kokkos::deep_copy(cxx_device, cxx_host); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/nr_conservation.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { baseline_data[i].read(fid); } @@ -90,7 +87,6 @@ struct UnitWrap::UnitTest::TestNrConservation : public UnitWrap::UnitTest: } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { cxx_host(s).write(fid); } diff --git a/components/eamxx/src/physics/p3/tests/p3_prevent_liq_supersaturation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_prevent_liq_supersaturation_tests.cpp index 31d18572f3b7..803d353eea29 100644 --- a/components/eamxx/src/physics/p3/tests/p3_prevent_liq_supersaturation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_prevent_liq_supersaturation_tests.cpp @@ -4,7 +4,6 @@ #include "ekat/kokkos/ekat_kokkos_utils.hpp" #include "p3_functions.hpp" #include "p3_test_data.hpp" -#include "share/util/scream_setup_random_test.hpp" #include "share/scream_types.hpp" #include "physics/share/physics_functions.hpp" @@ -124,9 +123,7 @@ struct UnitWrap::UnitTest::TestPreventLiqSupersaturation : public UnitWrap::U } // Read baseline data - std::string baseline_name = this->m_baseline_path + "/prevent_liq_supersaturation.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { baseline_data[i].read(fid); } @@ -180,7 +177,6 @@ struct UnitWrap::UnitTest::TestPreventLiqSupersaturation : public UnitWrap::U } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { cxx_host(s).write(fid); } diff --git a/components/eamxx/src/physics/p3/tests/p3_rain_imm_freezing_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_rain_imm_freezing_unit_tests.cpp index 875b47e47221..a391a863c72e 100644 --- a/components/eamxx/src/physics/p3/tests/p3_rain_imm_freezing_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_rain_imm_freezing_unit_tests.cpp @@ -70,9 +70,7 @@ void run_bfb() Kokkos::deep_copy(device_data, host_data); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/rain_immersion_freezing.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { rain_imm_freezing_data[i].read(fid); } @@ -117,7 +115,6 @@ void run_bfb() } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { host_data(s).write(fid); } diff --git a/components/eamxx/src/physics/p3/tests/p3_rain_sed_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_rain_sed_unit_tests.cpp index eac5c4827b62..cd4d1955aede 100644 --- a/components/eamxx/src/physics/p3/tests/p3_rain_sed_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_rain_sed_unit_tests.cpp @@ -6,7 +6,6 @@ #include "p3_functions.hpp" #include "p3_test_data.hpp" #include "p3_data.hpp" -#include "share/util/scream_setup_random_test.hpp" #include "p3_unit_tests_common.hpp" @@ -78,11 +77,9 @@ void run_bfb_rain_vel() Kokkos::deep_copy(crfv_device, crfv_host); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/rain_fall_velocity.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { - crfv_baseline[i].read(fid); + crfv_baseline[i].read(Base::m_fid); } } @@ -127,9 +124,8 @@ void run_bfb_rain_vel() } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { - crfv_host(s).write(fid); + crfv_host(s).write(Base::m_fid); } } } @@ -137,7 +133,7 @@ void run_bfb_rain_vel() void run_bfb_rain_sed() { // With stored baselines, we must use a fixed seed! - auto engine = setup_random_test(1267351); + auto engine = Base::get_engine(); // F90 is quite slow on weaver, so we decrease dt to reduce // the number of steps in rain_sed. @@ -172,11 +168,9 @@ void run_bfb_rain_sed() }; // Read baseline data - std::string baseline_name = this->m_baseline_path + "/rain_sed.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (auto& d : rsds_baseline) { - d.read(fid); + d.read(Base::m_fid); } } @@ -215,9 +209,8 @@ void run_bfb_rain_sed() } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int i = 0; i < num_runs; ++i) { - rsds_cxx[i].write(fid); + rsds_cxx[i].write(Base::m_fid); } } } diff --git a/components/eamxx/src/physics/p3/tests/p3_rain_self_collection_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_rain_self_collection_tests.cpp index c175f6915477..52ff887168b0 100644 --- a/components/eamxx/src/physics/p3/tests/p3_rain_self_collection_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_rain_self_collection_tests.cpp @@ -57,9 +57,7 @@ struct UnitWrap::UnitTest::TestRainSelfCollection : public UnitWrap::UnitTest Kokkos::deep_copy(dc_device, dc_host); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/rain_self_collection.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { dc[i].read(fid); } @@ -104,7 +102,6 @@ struct UnitWrap::UnitTest::TestRainSelfCollection : public UnitWrap::UnitTest } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { dc_host(s).write(fid); } diff --git a/components/eamxx/src/physics/p3/tests/p3_subgrid_variance_scaling_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_subgrid_variance_scaling_unit_tests.cpp index bf1c3543dd2d..c58ac68b4a6a 100644 --- a/components/eamxx/src/physics/p3/tests/p3_subgrid_variance_scaling_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_subgrid_variance_scaling_unit_tests.cpp @@ -42,23 +42,13 @@ struct UnitWrap::UnitTest::TestP3SubgridVarianceScaling : public UnitWrap::Un view_1d scaling_device("c scaling",1); auto scaling_host = Kokkos::create_mirror_view(scaling_device); - std::string baseline_name = this->m_baseline_path + "/subgrid_variance_scaling.dat"; - ekat::FILEPtr rfid = nullptr; - ekat::FILEPtr wfid = nullptr; - if (this->m_baseline_action == COMPARE) { - rfid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); - } - else if (this->m_baseline_action == GENERATE) { - wfid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); - } - for (Int i = 0; i < 3; ++i) { // loop over exponents for (Int j = 0; j < 16; ++j) { // loop over relvars // Get baseline solution // ---------------------------------- if (this->m_baseline_action == COMPARE) { - ekat::read(&baseline_scaling, 1, rfid); + ekat::read(&baseline_scaling, 1, Base::m_fid); } // Get C++ solution @@ -84,7 +74,7 @@ struct UnitWrap::UnitTest::TestP3SubgridVarianceScaling : public UnitWrap::Un REQUIRE(baseline_scaling == scaling_host(0) ); } else if (this->m_baseline_action == GENERATE) { - ekat::write(&scaling_host(0), 1, wfid); + ekat::write(&scaling_host(0), 1, Base::m_fid); } } //end loop over relvar[j] } //end loop over expons[i] diff --git a/components/eamxx/src/physics/p3/tests/p3_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_unit_tests.cpp index c3f8571d1173..5aed6dfe6892 100644 --- a/components/eamxx/src/physics/p3/tests/p3_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_unit_tests.cpp @@ -223,9 +223,7 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: Kokkos::deep_copy(cwdc_device, cwdc_host); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/cloud_water_conservation.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { cwdc[i].read(fid); } @@ -280,7 +278,6 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { cwdc_host(s).write(fid); } @@ -323,9 +320,7 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: Kokkos::deep_copy(iwdc_device, iwdc_host); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/ice_water_conservation.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { iwdc[i].read(fid); } @@ -385,7 +380,6 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { iwdc_host(s).write(fid); } @@ -428,9 +422,7 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: Kokkos::deep_copy(rwdc_device, rwdc_host); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/rain_water_conservation.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { rwdc[i].read(fid); } @@ -485,7 +477,6 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { rwdc_host(s).write(fid); } @@ -622,9 +613,7 @@ struct UnitWrap::UnitTest::TestP3UpdatePrognosticIce : public UnitWrap::UnitT Kokkos::deep_copy(pupidc_device, pupidc_host); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/update_prognostic_ice.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { pupidc[i].read(fid); } @@ -728,7 +717,6 @@ struct UnitWrap::UnitTest::TestP3UpdatePrognosticIce : public UnitWrap::UnitT } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { pupidc_host(s).write(fid); } @@ -778,9 +766,7 @@ struct UnitWrap::UnitTest::TestGetTimeSpacePhysVariables : public UnitWrap::U Kokkos::deep_copy(gtspvd_device, gtspvd_host); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/get_time_space_phys_variables.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { gtspvd[i].read(fid); } @@ -852,7 +838,6 @@ struct UnitWrap::UnitTest::TestGetTimeSpacePhysVariables : public UnitWrap::U } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { gtspvd_host(s).write(fid); } @@ -947,9 +932,7 @@ struct UnitWrap::UnitTest::TestP3UpdatePrognosticLiq : public UnitWrap::UnitT Kokkos::deep_copy(pupldc_device, pupldc_host); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/update_prognostic_liquid.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { pupldc[i].read(fid); } @@ -1036,7 +1019,6 @@ struct UnitWrap::UnitTest::TestP3UpdatePrognosticLiq : public UnitWrap::UnitT } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { pupldc_host(s).write(fid); } @@ -1087,9 +1069,7 @@ struct UnitWrap::UnitTest::TestP3FunctionsImposeMaxTotalNi : public UnitWrap: Kokkos::deep_copy(dc_device, dc_host); // Read baseline data - std::string baseline_name = this->m_baseline_path + "/impose_max_total_ni.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (Int i = 0; i < max_pack_size; ++i) { dc[i].read(fid); } @@ -1125,7 +1105,6 @@ struct UnitWrap::UnitTest::TestP3FunctionsImposeMaxTotalNi : public UnitWrap: } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int s = 0; s < max_pack_size; ++s) { dc_host(s).write(fid); } diff --git a/components/eamxx/src/physics/p3/tests/p3_upwind_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_upwind_unit_tests.cpp index 1f65984d727a..6e83a8ee4eaa 100644 --- a/components/eamxx/src/physics/p3/tests/p3_upwind_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_upwind_unit_tests.cpp @@ -6,8 +6,6 @@ #include "p3_test_data.hpp" #include "share/scream_types.hpp" -#include "share/util/scream_setup_random_test.hpp" -#include "share/util/scream_setup_random_test.hpp" #include "ekat/ekat_pack.hpp" #include "ekat/kokkos/ekat_kokkos_utils.hpp" @@ -204,7 +202,7 @@ void run_phys() void run_bfb() { // With stored baselines, we must use a fixed seed! - auto engine = setup_random_test(12345745); + auto engine = Base::get_engine(); CalcUpwindData cuds_baseline[] = { // kts, kte, kdir, kbot, k_qxtop, na, dt_sub, @@ -237,11 +235,9 @@ void run_bfb() }; // Read baseline data - std::string baseline_name = this->m_baseline_path + "/upwind.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (auto& d : cuds_baseline) { - d.read(fid); + d.read(Base::m_fid); } } @@ -275,9 +271,8 @@ void run_bfb() } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int i = 0; i < num_runs; ++i) { - cuds_cxx[i].write(fid); + cuds_cxx[i].write(Base::m_fid); } } } @@ -295,7 +290,7 @@ void run_phys() void run_bfb() { // With stored baselines, we must use a fixed seed! - auto engine = setup_random_test(2346563); + auto engine = Base::get_engine(); GenSedData gsds_baseline[] = { // kts, kte, kdir, k_qxtop, k_qxbot, kbot, Co_max, dt_left, prt_accum, num_arrays @@ -322,11 +317,9 @@ void run_bfb() }; // Read baseline data - std::string baseline_name = this->m_baseline_path + "/gen_sed.dat"; if (this->m_baseline_action == COMPARE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "r")); for (auto& d : gsds_baseline) { - d.read(fid); + d.read(Base::m_fid); } } @@ -363,9 +356,8 @@ void run_bfb() } } else if (this->m_baseline_action == GENERATE) { - auto fid = ekat::FILEPtr(fopen(baseline_name.c_str(), "w")); for (Int i = 0; i < num_runs; ++i) { - gsds_cxx[i].write(fid); + gsds_cxx[i].write(Base::m_fid); } } } diff --git a/components/eamxx/src/share/util/scream_setup_random_test.hpp b/components/eamxx/src/share/util/scream_setup_random_test.hpp index 419bd4ee64e9..09f3f3099d88 100644 --- a/components/eamxx/src/share/util/scream_setup_random_test.hpp +++ b/components/eamxx/src/share/util/scream_setup_random_test.hpp @@ -41,9 +41,13 @@ inline int get_random_test_seed(const ekat::Comm* comm=nullptr) } template -Engine setup_random_test(const ekat::Comm* comm=nullptr) +Engine setup_random_test(const ekat::Comm* comm=nullptr, int* return_seed=nullptr) { - return Engine (get_random_test_seed(comm)); + int seed = get_random_test_seed(comm); + if (return_seed != nullptr) { + *return_seed = seed; + } + return Engine (seed); } template From 68edf0cff83222d151209d622e4812902ee23b69 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Thu, 7 Nov 2024 15:57:00 -0700 Subject: [PATCH 044/147] seds --- .../p3/tests/p3_autoconversion_unit_tests.cpp | 4 +-- .../p3_back_to_cell_average_unit_tests.cpp | 4 +-- ...lc_liq_relaxation_timescale_unit_tests.cpp | 4 +-- .../tests/p3_calc_rime_density_unit_tests.cpp | 4 +-- .../p3_cldliq_imm_freezing_unit_tests.cpp | 4 +-- .../p3/tests/p3_cloud_rain_acc_unit_tests.cpp | 4 +-- .../p3/tests/p3_cloud_sed_unit_tests.cpp | 4 +-- .../tests/p3_droplet_self_coll_unit_tests.cpp | 4 +-- .../physics/p3/tests/p3_dsd2_unit_tests.cpp | 8 +++--- .../p3/tests/p3_evaporate_rain_unit_tests.cpp | 4 +-- .../p3_ice_cldliq_wet_growth_unit_tests.cpp | 4 +-- .../p3/tests/p3_ice_collection_unit_tests.cpp | 12 ++++---- .../p3_ice_deposition_sublimation_tests.cpp | 4 +-- .../p3/tests/p3_ice_melting_unit_tests.cpp | 4 +-- .../p3/tests/p3_ice_nucleation_unit_tests.cpp | 4 +-- ...p3_ice_relaxation_timescale_unit_tests.cpp | 4 +-- .../p3/tests/p3_ice_sed_unit_tests.cpp | 12 ++++---- .../p3_ice_supersat_conservation_tests.cpp | 4 +-- .../p3/tests/p3_ice_tables_unit_tests.cpp | 16 +++++------ .../p3_incloud_mixingratios_unit_tests.cpp | 4 +-- .../physics/p3/tests/p3_main_unit_tests.cpp | 16 +++++------ .../p3/tests/p3_nc_conservation_tests.cpp | 4 +-- .../p3/tests/p3_ni_conservation_tests.cpp | 4 +-- .../p3/tests/p3_nr_conservation_tests.cpp | 4 +-- .../p3_prevent_liq_supersaturation_tests.cpp | 4 +-- .../tests/p3_rain_imm_freezing_unit_tests.cpp | 4 +-- .../tests/p3_rain_self_collection_tests.cpp | 4 +-- .../src/physics/p3/tests/p3_unit_tests.cpp | 28 +++++++++---------- 28 files changed, 90 insertions(+), 90 deletions(-) diff --git a/components/eamxx/src/physics/p3/tests/p3_autoconversion_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_autoconversion_unit_tests.cpp index bc99ac99150d..be08e5b0d4f3 100644 --- a/components/eamxx/src/physics/p3/tests/p3_autoconversion_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_autoconversion_unit_tests.cpp @@ -62,7 +62,7 @@ void cloud_water_autoconversion_unit_bfb_tests() { // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - cwadc[i].read(fid); + cwadc[i].read(Base::m_fid); } } @@ -116,7 +116,7 @@ void cloud_water_autoconversion_unit_bfb_tests() { } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - cwadc_host(s).write(fid); + cwadc_host(s).write(Base::m_fid); } } } diff --git a/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp index 1e36a024508a..f13a0ca909a1 100644 --- a/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp @@ -46,7 +46,7 @@ void run_bfb() // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - back_to_cell_average_data[i].read(fid); + back_to_cell_average_data[i].read(Base::m_fid); } } @@ -174,7 +174,7 @@ void run_bfb() } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - host_data(s).write(fid); + host_data(s).write(Base::m_fid); } } } diff --git a/components/eamxx/src/physics/p3/tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp index e528d27328d3..56c2beafaedf 100644 --- a/components/eamxx/src/physics/p3/tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp @@ -56,7 +56,7 @@ struct UnitWrap::UnitTest::TestCalcLiqRelaxationTimescale : public UnitWrap:: // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - self[i].read(fid); + self[i].read(Base::m_fid); } } @@ -106,7 +106,7 @@ struct UnitWrap::UnitTest::TestCalcLiqRelaxationTimescale : public UnitWrap:: } else { for (Int s = 0; s < max_pack_size; ++s) { - self_host(s).write(fid); + self_host(s).write(Base::m_fid); } } } diff --git a/components/eamxx/src/physics/p3/tests/p3_calc_rime_density_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_calc_rime_density_unit_tests.cpp index bb186ac42720..9b7722895faf 100644 --- a/components/eamxx/src/physics/p3/tests/p3_calc_rime_density_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_calc_rime_density_unit_tests.cpp @@ -90,7 +90,7 @@ void run_bfb() // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - calc_rime_density_data[i].read(fid); + calc_rime_density_data[i].read(Base::m_fid); } } @@ -136,7 +136,7 @@ void run_bfb() } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - host_data(s).write(fid); + host_data(s).write(Base::m_fid); } } } diff --git a/components/eamxx/src/physics/p3/tests/p3_cldliq_imm_freezing_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_cldliq_imm_freezing_unit_tests.cpp index 06c725d10a8e..bbaa95e87a03 100644 --- a/components/eamxx/src/physics/p3/tests/p3_cldliq_imm_freezing_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_cldliq_imm_freezing_unit_tests.cpp @@ -73,7 +73,7 @@ void run_bfb() // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - cldliq_imm_freezing_data[i].read(fid); + cldliq_imm_freezing_data[i].read(Base::m_fid); } } @@ -119,7 +119,7 @@ void run_bfb() } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - host_data(s).write(fid); + host_data(s).write(Base::m_fid); } } } diff --git a/components/eamxx/src/physics/p3/tests/p3_cloud_rain_acc_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_cloud_rain_acc_unit_tests.cpp index 011142942a72..271f7e27bd61 100644 --- a/components/eamxx/src/physics/p3/tests/p3_cloud_rain_acc_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_cloud_rain_acc_unit_tests.cpp @@ -76,7 +76,7 @@ void run_bfb() // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - cloud_rain_acc_data[i].read(fid); + cloud_rain_acc_data[i].read(Base::m_fid); } } @@ -122,7 +122,7 @@ void run_bfb() } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - host_data(s).write(fid); + host_data(s).write(Base::m_fid); } } } diff --git a/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp index 0c60420f3d8d..db42d68e6bf7 100644 --- a/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp @@ -58,7 +58,7 @@ void run_bfb() // Read baseline data if (this->m_baseline_action == COMPARE) { for (auto& d : csds_baseline) { - d.read(fid); + d.read(Base::m_fid); } } @@ -89,7 +89,7 @@ void run_bfb() } else if (this->m_baseline_action == GENERATE) { for (Int i = 0; i < num_runs; ++i) { - csds_cxx[i].write(fid); + csds_cxx[i].write(Base::m_fid); } } } diff --git a/components/eamxx/src/physics/p3/tests/p3_droplet_self_coll_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_droplet_self_coll_unit_tests.cpp index a649d31a4897..f183bba65da6 100644 --- a/components/eamxx/src/physics/p3/tests/p3_droplet_self_coll_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_droplet_self_coll_unit_tests.cpp @@ -75,7 +75,7 @@ void run_bfb() // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - droplet_self_coll_data[i].read(fid); + droplet_self_coll_data[i].read(Base::m_fid); } } @@ -116,7 +116,7 @@ void run_bfb() } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - host_data(s).write(fid); + host_data(s).write(Base::m_fid); } } diff --git a/components/eamxx/src/physics/p3/tests/p3_dsd2_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_dsd2_unit_tests.cpp index 93187632ced9..268607645f04 100644 --- a/components/eamxx/src/physics/p3/tests/p3_dsd2_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_dsd2_unit_tests.cpp @@ -63,7 +63,7 @@ struct UnitWrap::UnitTest::TestDsd2 : public UnitWrap::UnitTest::Base { // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - gcdd[i].read(fid); + gcdd[i].read(Base::m_fid); } } @@ -109,7 +109,7 @@ struct UnitWrap::UnitTest::TestDsd2 : public UnitWrap::UnitTest::Base { } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - gcdd_host(s).write(fid); + gcdd_host(s).write(Base::m_fid); } } } @@ -154,7 +154,7 @@ struct UnitWrap::UnitTest::TestDsd2 : public UnitWrap::UnitTest::Base { // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - grdd[i].read(fid); + grdd[i].read(Base::m_fid); } } @@ -199,7 +199,7 @@ struct UnitWrap::UnitTest::TestDsd2 : public UnitWrap::UnitTest::Base { } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - grdd_host(s).write(fid); + grdd_host(s).write(Base::m_fid); } } } diff --git a/components/eamxx/src/physics/p3/tests/p3_evaporate_rain_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_evaporate_rain_unit_tests.cpp index 005d13bda2de..a84b1e0448ad 100644 --- a/components/eamxx/src/physics/p3/tests/p3_evaporate_rain_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_evaporate_rain_unit_tests.cpp @@ -176,7 +176,7 @@ struct UnitWrap::UnitTest::TestEvapSublPrecip : public UnitWrap::UnitTest: // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - espd[i].read(fid); + espd[i].read(Base::m_fid); } } @@ -251,7 +251,7 @@ struct UnitWrap::UnitTest::TestEvapSublPrecip : public UnitWrap::UnitTest: } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - espd_host(s).write(fid); + espd_host(s).write(Base::m_fid); } } } // end run_bfb diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_cldliq_wet_growth_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_cldliq_wet_growth_unit_tests.cpp index 26f5723ff1c9..cca204b9b3a3 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_cldliq_wet_growth_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_cldliq_wet_growth_unit_tests.cpp @@ -60,7 +60,7 @@ struct UnitWrap::UnitTest::TestIceCldliqWetGrowth : public UnitWrap::UnitTest // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - self[i].read(fid); + self[i].read(Base::m_fid); } } @@ -129,7 +129,7 @@ struct UnitWrap::UnitTest::TestIceCldliqWetGrowth : public UnitWrap::UnitTest } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - self_host(s).write(fid); + self_host(s).write(Base::m_fid); } } } diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_collection_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_collection_unit_tests.cpp index a6e65426dbe7..2561114b519c 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_collection_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_collection_unit_tests.cpp @@ -66,7 +66,7 @@ struct UnitWrap::UnitTest::TestIceCollection : public UnitWrap::UnitTest:: // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - cldliq[i].read(fid); + cldliq[i].read(Base::m_fid); } } @@ -121,7 +121,7 @@ struct UnitWrap::UnitTest::TestIceCollection : public UnitWrap::UnitTest:: } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - cldliq_host(s).write(fid); + cldliq_host(s).write(Base::m_fid); } } } @@ -167,7 +167,7 @@ struct UnitWrap::UnitTest::TestIceCollection : public UnitWrap::UnitTest:: // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - rain[i].read(fid); + rain[i].read(Base::m_fid); } } @@ -215,7 +215,7 @@ struct UnitWrap::UnitTest::TestIceCollection : public UnitWrap::UnitTest:: } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - rain_host(s).write(fid); + rain_host(s).write(Base::m_fid); } } } @@ -261,7 +261,7 @@ struct UnitWrap::UnitTest::TestIceCollection : public UnitWrap::UnitTest:: // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - self[i].read(fid); + self[i].read(Base::m_fid); } } @@ -299,7 +299,7 @@ struct UnitWrap::UnitTest::TestIceCollection : public UnitWrap::UnitTest:: } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - self_host(s).write(fid); + self_host(s).write(Base::m_fid); } } } diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_deposition_sublimation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_deposition_sublimation_tests.cpp index 2ef5e66803ad..9b261409ad09 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_deposition_sublimation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_deposition_sublimation_tests.cpp @@ -84,7 +84,7 @@ struct UnitWrap::UnitTest::TestIceDepositionSublimation : public UnitWrap::Un // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - baseline_data[i].read(fid); + baseline_data[i].read(Base::m_fid); } } @@ -151,7 +151,7 @@ struct UnitWrap::UnitTest::TestIceDepositionSublimation : public UnitWrap::Un } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - cxx_host(s).write(fid); + cxx_host(s).write(Base::m_fid); } } } // run_bfb diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_melting_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_melting_unit_tests.cpp index 739f2a316296..4e24cc8be0e0 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_melting_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_melting_unit_tests.cpp @@ -60,7 +60,7 @@ void ice_melting_bfb() { // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - IceMelt[i].read(fid); + IceMelt[i].read(Base::m_fid); } } @@ -109,7 +109,7 @@ void ice_melting_bfb() { } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - IceMelt_host(s).write(fid); + IceMelt_host(s).write(Base::m_fid); } } diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_nucleation_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_nucleation_unit_tests.cpp index f0b4cc4a3242..7eeb4fa875ec 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_nucleation_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_nucleation_unit_tests.cpp @@ -58,7 +58,7 @@ struct UnitWrap::UnitTest::TestIceNucleation : public UnitWrap::UnitTest:: std::string file_name = root_name + (do_predict_nc ? "1" : "0") + (do_prescribed_CCN ? "1" : "0"); if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - self[i].read(fid); + self[i].read(Base::m_fid); } } @@ -105,7 +105,7 @@ struct UnitWrap::UnitTest::TestIceNucleation : public UnitWrap::UnitTest:: } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - self_host(s).write(fid); + self_host(s).write(Base::m_fid); } } } //end for do_predict_nc diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_relaxation_timescale_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_relaxation_timescale_unit_tests.cpp index d0a9b3902f9b..59768bbf82c6 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_relaxation_timescale_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_relaxation_timescale_unit_tests.cpp @@ -52,7 +52,7 @@ struct UnitWrap::UnitTest::TestIceRelaxationTimescale : public UnitWrap::Unit // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - self[i].read(fid); + self[i].read(Base::m_fid); } } @@ -103,7 +103,7 @@ struct UnitWrap::UnitTest::TestIceRelaxationTimescale : public UnitWrap::Unit } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - self_host(s).write(fid); + self_host(s).write(Base::m_fid); } } } diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp index 6f567a8ae64f..45ea1e903233 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp @@ -80,7 +80,7 @@ void run_bfb_calc_bulk_rhime() // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - cbrr_baseline[i].read(fid); + cbrr_baseline[i].read(Base::m_fid); } } @@ -122,7 +122,7 @@ void run_bfb_calc_bulk_rhime() } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - cbrr_host(s).write(fid); + cbrr_host(s).write(Base::m_fid); } } } @@ -158,7 +158,7 @@ void run_bfb_ice_sed() // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < num_runs; ++i) { - isds_baseline[i].read(fid); + isds_baseline[i].read(Base::m_fid); } } @@ -193,7 +193,7 @@ void run_bfb_ice_sed() } else if (this->m_baseline_action == GENERATE) { for (Int i = 0; i < num_runs; ++i) { - isds_cxx[i].write(fid); + isds_cxx[i].write(Base::m_fid); } } } @@ -238,7 +238,7 @@ void run_bfb_homogeneous_freezing() // Read baseline data if (this->m_baseline_action == COMPARE) { for (auto& d : hfds_baseline) { - d.read(fid); + d.read(Base::m_fid); } } @@ -269,7 +269,7 @@ void run_bfb_homogeneous_freezing() } else if (this->m_baseline_action == GENERATE) { for (Int i = 0; i < num_runs; ++i) { - hfds_cxx[i].write(fid); + hfds_cxx[i].write(Base::m_fid); } } diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp index 0324bbf14982..b089fdf978fd 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp @@ -45,7 +45,7 @@ struct UnitWrap::UnitTest::TestIceSupersatConservation : public UnitWrap::Uni // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - baseline_data[i].read(fid); + baseline_data[i].read(Base::m_fid); } } @@ -88,7 +88,7 @@ struct UnitWrap::UnitTest::TestIceSupersatConservation : public UnitWrap::Uni } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - cxx_host(s).write(fid); + cxx_host(s).write(Base::m_fid); } } } // run_bfb diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_tables_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_tables_unit_tests.cpp index 22ac35475fb0..ea3fdaccf7e8 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_tables_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_tables_unit_tests.cpp @@ -212,10 +212,10 @@ struct UnitWrap::UnitTest::TestTableIce : public UnitWrap::UnitTest::Base // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - lid[i].read(fid); - lidb[i].read(fid); - altd[i].read(fid); - altcd[i].read(fid); + lid[i].read(Base::m_fid); + lidb[i].read(Base::m_fid); + altd[i].read(Base::m_fid); + altcd[i].read(Base::m_fid); } } @@ -313,10 +313,10 @@ struct UnitWrap::UnitTest::TestTableIce : public UnitWrap::UnitTest::Base altcd[s].proc = real_results_mirror(6, s); - lid[s].write(fid); - lidb[s].write(fid); - altd[s].write(fid); - altcd[s].write(fid); + lid[s].write(Base::m_fid); + lidb[s].write(Base::m_fid); + altd[s].write(Base::m_fid); + altcd[s].write(Base::m_fid); } } } diff --git a/components/eamxx/src/physics/p3/tests/p3_incloud_mixingratios_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_incloud_mixingratios_unit_tests.cpp index 79bffe1ac99b..eae1454c36a0 100644 --- a/components/eamxx/src/physics/p3/tests/p3_incloud_mixingratios_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_incloud_mixingratios_unit_tests.cpp @@ -72,7 +72,7 @@ struct UnitWrap::UnitTest::TestIncloudMixing : public UnitWrap::UnitTest:: // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - self[i].read(fid); + self[i].read(Base::m_fid); } } @@ -131,7 +131,7 @@ struct UnitWrap::UnitTest::TestIncloudMixing : public UnitWrap::UnitTest:: } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - self_host(s).write(fid); + self_host(s).write(Base::m_fid); } } } diff --git a/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp index 26f075dfef31..e694636806d6 100644 --- a/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp @@ -97,7 +97,7 @@ void run_bfb_p3_main_part1() // Read baseline data if (this->m_baseline_action == COMPARE) { for (auto& d : isds_baseline) { - d.read(fid); + d.read(Base::m_fid); } } @@ -151,7 +151,7 @@ void run_bfb_p3_main_part1() } else if (this->m_baseline_action == GENERATE) { for (Int i = 0; i < num_runs; ++i) { - isds_cxx[i].write(fid); + isds_cxx[i].write(Base::m_fid); } } } @@ -206,7 +206,7 @@ void run_bfb_p3_main_part2() // Read baseline data if (this->m_baseline_action == COMPARE) { for (auto& d : isds_baseline) { - d.read(fid); + d.read(Base::m_fid); } } @@ -282,7 +282,7 @@ void run_bfb_p3_main_part2() } else if (this->m_baseline_action == GENERATE) { for (Int i = 0; i < num_runs; ++i) { - isds_cxx[i].write(fid); + isds_cxx[i].write(Base::m_fid); } } } @@ -330,7 +330,7 @@ void run_bfb_p3_main_part3() // Read baseline data if (this->m_baseline_action == COMPARE) { for (auto& d : isds_baseline) { - d.read(fid); + d.read(Base::m_fid); } } @@ -384,7 +384,7 @@ void run_bfb_p3_main_part3() } else if (this->m_baseline_action == GENERATE) { for (Int i = 0; i < num_runs; ++i) { - isds_cxx[i].write(fid); + isds_cxx[i].write(Base::m_fid); } } } @@ -439,7 +439,7 @@ void run_bfb_p3_main() // Read baseline data if (this->m_baseline_action == COMPARE) { for (auto& d : isds_baseline) { - d.read(fid); + d.read(Base::m_fid); } } @@ -498,7 +498,7 @@ void run_bfb_p3_main() } else if (this->m_baseline_action == GENERATE) { for (Int i = 0; i < num_runs; ++i) { - isds_cxx[i].write(fid); + isds_cxx[i].write(Base::m_fid); } } } diff --git a/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp index 288a52c4ad89..04ad1a7f1122 100644 --- a/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp @@ -38,7 +38,7 @@ struct UnitWrap::UnitTest::TestNcConservation : public UnitWrap::UnitTest: // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - baseline_data[i].read(fid); + baseline_data[i].read(Base::m_fid); } } @@ -84,7 +84,7 @@ struct UnitWrap::UnitTest::TestNcConservation : public UnitWrap::UnitTest: } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - cxx_host(s).write(fid); + cxx_host(s).write(Base::m_fid); } } } // run_bfb diff --git a/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp index a721dc7b9afc..e165aca01bad 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp @@ -38,7 +38,7 @@ struct UnitWrap::UnitTest::TestNiConservation : public UnitWrap::UnitTest: // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - baseline_data[i].read(fid); + baseline_data[i].read(Base::m_fid); } } @@ -83,7 +83,7 @@ struct UnitWrap::UnitTest::TestNiConservation : public UnitWrap::UnitTest: } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - cxx_host(s).write(fid); + cxx_host(s).write(Base::m_fid); } } } // run_bfb diff --git a/components/eamxx/src/physics/p3/tests/p3_nr_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_nr_conservation_tests.cpp index e7a75821ae17..982840d2f40a 100644 --- a/components/eamxx/src/physics/p3/tests/p3_nr_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_nr_conservation_tests.cpp @@ -39,7 +39,7 @@ struct UnitWrap::UnitTest::TestNrConservation : public UnitWrap::UnitTest: // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - baseline_data[i].read(fid); + baseline_data[i].read(Base::m_fid); } } @@ -88,7 +88,7 @@ struct UnitWrap::UnitTest::TestNrConservation : public UnitWrap::UnitTest: } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - cxx_host(s).write(fid); + cxx_host(s).write(Base::m_fid); } } } // run_bfb diff --git a/components/eamxx/src/physics/p3/tests/p3_prevent_liq_supersaturation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_prevent_liq_supersaturation_tests.cpp index 803d353eea29..63e40f575e65 100644 --- a/components/eamxx/src/physics/p3/tests/p3_prevent_liq_supersaturation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_prevent_liq_supersaturation_tests.cpp @@ -125,7 +125,7 @@ struct UnitWrap::UnitTest::TestPreventLiqSupersaturation : public UnitWrap::U // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - baseline_data[i].read(fid); + baseline_data[i].read(Base::m_fid); } } @@ -178,7 +178,7 @@ struct UnitWrap::UnitTest::TestPreventLiqSupersaturation : public UnitWrap::U } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - cxx_host(s).write(fid); + cxx_host(s).write(Base::m_fid); } } } // run_bfb diff --git a/components/eamxx/src/physics/p3/tests/p3_rain_imm_freezing_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_rain_imm_freezing_unit_tests.cpp index a391a863c72e..935842cb6d98 100644 --- a/components/eamxx/src/physics/p3/tests/p3_rain_imm_freezing_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_rain_imm_freezing_unit_tests.cpp @@ -72,7 +72,7 @@ void run_bfb() // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - rain_imm_freezing_data[i].read(fid); + rain_imm_freezing_data[i].read(Base::m_fid); } } @@ -116,7 +116,7 @@ void run_bfb() } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - host_data(s).write(fid); + host_data(s).write(Base::m_fid); } } } diff --git a/components/eamxx/src/physics/p3/tests/p3_rain_self_collection_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_rain_self_collection_tests.cpp index 52ff887168b0..26440b6680bf 100644 --- a/components/eamxx/src/physics/p3/tests/p3_rain_self_collection_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_rain_self_collection_tests.cpp @@ -59,7 +59,7 @@ struct UnitWrap::UnitTest::TestRainSelfCollection : public UnitWrap::UnitTest // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - dc[i].read(fid); + dc[i].read(Base::m_fid); } } @@ -103,7 +103,7 @@ struct UnitWrap::UnitTest::TestRainSelfCollection : public UnitWrap::UnitTest } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - dc_host(s).write(fid); + dc_host(s).write(Base::m_fid); } } } diff --git a/components/eamxx/src/physics/p3/tests/p3_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_unit_tests.cpp index 5aed6dfe6892..91e3db2f2976 100644 --- a/components/eamxx/src/physics/p3/tests/p3_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_unit_tests.cpp @@ -225,7 +225,7 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - cwdc[i].read(fid); + cwdc[i].read(Base::m_fid); } } @@ -279,7 +279,7 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - cwdc_host(s).write(fid); + cwdc_host(s).write(Base::m_fid); } } } @@ -322,7 +322,7 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - iwdc[i].read(fid); + iwdc[i].read(Base::m_fid); } } @@ -381,7 +381,7 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - iwdc_host(s).write(fid); + iwdc_host(s).write(Base::m_fid); } } } @@ -424,7 +424,7 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - rwdc[i].read(fid); + rwdc[i].read(Base::m_fid); } } @@ -478,7 +478,7 @@ struct UnitWrap::UnitTest::TestP3Conservation : public UnitWrap::UnitTest: } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - rwdc_host(s).write(fid); + rwdc_host(s).write(Base::m_fid); } } } @@ -615,7 +615,7 @@ struct UnitWrap::UnitTest::TestP3UpdatePrognosticIce : public UnitWrap::UnitT // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - pupidc[i].read(fid); + pupidc[i].read(Base::m_fid); } } @@ -718,7 +718,7 @@ struct UnitWrap::UnitTest::TestP3UpdatePrognosticIce : public UnitWrap::UnitT } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - pupidc_host(s).write(fid); + pupidc_host(s).write(Base::m_fid); } } } @@ -768,7 +768,7 @@ struct UnitWrap::UnitTest::TestGetTimeSpacePhysVariables : public UnitWrap::U // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - gtspvd[i].read(fid); + gtspvd[i].read(Base::m_fid); } } @@ -839,7 +839,7 @@ struct UnitWrap::UnitTest::TestGetTimeSpacePhysVariables : public UnitWrap::U } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - gtspvd_host(s).write(fid); + gtspvd_host(s).write(Base::m_fid); } } } @@ -934,7 +934,7 @@ struct UnitWrap::UnitTest::TestP3UpdatePrognosticLiq : public UnitWrap::UnitT // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - pupldc[i].read(fid); + pupldc[i].read(Base::m_fid); } } @@ -1020,7 +1020,7 @@ struct UnitWrap::UnitTest::TestP3UpdatePrognosticLiq : public UnitWrap::UnitT } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - pupldc_host(s).write(fid); + pupldc_host(s).write(Base::m_fid); } } } @@ -1071,7 +1071,7 @@ struct UnitWrap::UnitTest::TestP3FunctionsImposeMaxTotalNi : public UnitWrap: // Read baseline data if (this->m_baseline_action == COMPARE) { for (Int i = 0; i < max_pack_size; ++i) { - dc[i].read(fid); + dc[i].read(Base::m_fid); } } @@ -1106,7 +1106,7 @@ struct UnitWrap::UnitTest::TestP3FunctionsImposeMaxTotalNi : public UnitWrap: } else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { - dc_host(s).write(fid); + dc_host(s).write(Base::m_fid); } } } From 037d5af9f188cbc25f40a4338cd6c0acba0321a9 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Thu, 7 Nov 2024 15:59:40 -0700 Subject: [PATCH 045/147] seds --- .../p3/tests/p3_back_to_cell_average_unit_tests.cpp | 2 +- .../tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp | 2 +- .../src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp | 2 +- .../eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp | 4 ++-- .../p3/tests/p3_ice_supersat_conservation_tests.cpp | 2 +- .../eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp | 8 ++++---- .../src/physics/p3/tests/p3_nc_conservation_tests.cpp | 2 +- .../src/physics/p3/tests/p3_ni_conservation_tests.cpp | 2 +- .../src/physics/p3/tests/p3_nr_conservation_tests.cpp | 2 +- .../p3/tests/p3_prevent_liq_supersaturation_tests.cpp | 2 +- 10 files changed, 14 insertions(+), 14 deletions(-) diff --git a/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp index f13a0ca909a1..b108ce329d3e 100644 --- a/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_back_to_cell_average_unit_tests.cpp @@ -27,7 +27,7 @@ void run_phys() void run_bfb() { - auto engine = setup_random_test(314552); + auto engine = Base::get_engine(); // Generate n test structs, each populated with random data (values within // [0,1]) by the default constructor. diff --git a/components/eamxx/src/physics/p3/tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp index 56c2beafaedf..ea217a4d0471 100644 --- a/components/eamxx/src/physics/p3/tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp @@ -28,7 +28,7 @@ struct UnitWrap::UnitTest::TestCalcLiqRelaxationTimescale : public UnitWrap:: void run_bfb() { - auto engine = setup_random_test(12354); + auto engine = Base::get_engine(); // Read in tables view_2d_table vn_table_vals, vm_table_vals, revap_table_vals; diff --git a/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp index db42d68e6bf7..b29bf11faa1c 100644 --- a/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_cloud_sed_unit_tests.cpp @@ -27,7 +27,7 @@ void run_phys() void run_bfb() { - auto engine = setup_random_test(23512); + auto engine = Base::get_engine(); CloudSedData csds_baseline[] = { // kts, kte, ktop, kbot, kdir, dt, inv_dt, do_predict_nc, precip_liq_surf, diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp index 45ea1e903233..faa6da1596ef 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_sed_unit_tests.cpp @@ -129,7 +129,7 @@ void run_bfb_calc_bulk_rhime() void run_bfb_ice_sed() { - auto engine = setup_random_test(124135); + auto engine = Base::get_engine(); IceSedData isds_baseline[] = { // kts, kte, ktop, kbot, kdir, dt, inv_dt, precip_ice_surf @@ -202,7 +202,7 @@ void run_bfb_homogeneous_freezing() { constexpr Scalar latice = C::LatIce; - auto engine = setup_random_test(13543563); + auto engine = Base::get_engine(); HomogeneousFreezingData hfds_baseline[] = { // kts, kte, ktop, kbot, kdir diff --git a/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp index b089fdf978fd..dcbdfc618263 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ice_supersat_conservation_tests.cpp @@ -20,7 +20,7 @@ struct UnitWrap::UnitTest::TestIceSupersatConservation : public UnitWrap::Uni constexpr Scalar latvap = C::LatVap; constexpr Scalar latice = C::LatIce; - auto engine = setup_random_test(124151); + auto engine = Base::get_engine(); IceSupersatConservationData baseline_data[max_pack_size]; diff --git a/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp index e694636806d6..4fb471c3cf5b 100644 --- a/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_main_unit_tests.cpp @@ -50,7 +50,7 @@ void run_phys() void run_bfb_p3_main_part1() { - auto engine = setup_random_test(125125); + auto engine = Base::get_engine(); constexpr Scalar qsmall = C::QSMALL; //PMC wouldn't it make more sense to define qsmall at a higher level since used in part1, part2, and part3? constexpr Scalar T_zerodegc = C::T_zerodegc; @@ -158,7 +158,7 @@ void run_bfb_p3_main_part1() void run_bfb_p3_main_part2() { - auto engine = setup_random_test(263267); + auto engine = Base::get_engine(); constexpr Scalar qsmall = C::QSMALL; constexpr Scalar T_zerodegc = C::T_zerodegc; @@ -292,7 +292,7 @@ void run_bfb_p3_main_part3() constexpr Scalar latvap = C::LatVap; constexpr Scalar latice = C::LatIce; - auto engine = setup_random_test(3734734); + auto engine = Base::get_engine(); constexpr Scalar qsmall = C::QSMALL; @@ -391,7 +391,7 @@ void run_bfb_p3_main_part3() void run_bfb_p3_main() { - auto engine = setup_random_test(3427727); + auto engine = Base::get_engine(); P3MainData isds_baseline[] = { // its, ite, kts, kte, it, dt, do_predict_nc, do_prescribed_CCN diff --git a/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp index 04ad1a7f1122..175247bb501d 100644 --- a/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_nc_conservation_tests.cpp @@ -17,7 +17,7 @@ struct UnitWrap::UnitTest::TestNcConservation : public UnitWrap::UnitTest: void run_bfb() { - auto engine = setup_random_test(1241556); + auto engine = Base::get_engine(); NcConservationData baseline_data[max_pack_size]; diff --git a/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp index e165aca01bad..b8cfdf4333a1 100644 --- a/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_ni_conservation_tests.cpp @@ -17,7 +17,7 @@ struct UnitWrap::UnitTest::TestNiConservation : public UnitWrap::UnitTest: void run_bfb() { - auto engine = setup_random_test(1925985); + auto engine = Base::get_engine(); NiConservationData baseline_data[max_pack_size]; diff --git a/components/eamxx/src/physics/p3/tests/p3_nr_conservation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_nr_conservation_tests.cpp index 982840d2f40a..dc9a44af88d0 100644 --- a/components/eamxx/src/physics/p3/tests/p3_nr_conservation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_nr_conservation_tests.cpp @@ -17,7 +17,7 @@ struct UnitWrap::UnitTest::TestNrConservation : public UnitWrap::UnitTest: void run_bfb() { - auto engine = setup_random_test(912874); + auto engine = Base::get_engine(); NrConservationData baseline_data[max_pack_size]; diff --git a/components/eamxx/src/physics/p3/tests/p3_prevent_liq_supersaturation_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_prevent_liq_supersaturation_tests.cpp index 63e40f575e65..1b439aca7aac 100644 --- a/components/eamxx/src/physics/p3/tests/p3_prevent_liq_supersaturation_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_prevent_liq_supersaturation_tests.cpp @@ -92,7 +92,7 @@ struct UnitWrap::UnitTest::TestPreventLiqSupersaturation : public UnitWrap::U constexpr Scalar latvap = C::LatVap; constexpr Scalar latice = C::LatIce; - auto engine = setup_random_test(1298758); + auto engine = Base::get_engine(); PreventLiqSupersaturationData baseline_data[max_pack_size]; From abf91a6499a917d65c473e1e12579df089dbc2d0 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Thu, 7 Nov 2024 16:04:27 -0700 Subject: [PATCH 046/147] Fix bug --- .../p3/tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eamxx/src/physics/p3/tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp b/components/eamxx/src/physics/p3/tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp index ea217a4d0471..2752746b7925 100644 --- a/components/eamxx/src/physics/p3/tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_calc_liq_relaxation_timescale_unit_tests.cpp @@ -104,7 +104,7 @@ struct UnitWrap::UnitTest::TestCalcLiqRelaxationTimescale : public UnitWrap:: REQUIRE(self[s].epsc == self_host(s).epsc); } } - else { + else if (this->m_baseline_action == GENERATE) { for (Int s = 0; s < max_pack_size; ++s) { self_host(s).write(Base::m_fid); } From 23dbd2eddad751a112a049afaee8951ff09a2295 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Thu, 7 Nov 2024 16:50:51 -0700 Subject: [PATCH 047/147] Minor fixes --- .../eamxx/src/physics/p3/tests/CMakeLists.txt | 14 ++++++++------ .../eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp | 13 ++++++++++--- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/components/eamxx/src/physics/p3/tests/CMakeLists.txt b/components/eamxx/src/physics/p3/tests/CMakeLists.txt index 70ac3947fa8b..784d3436c884 100644 --- a/components/eamxx/src/physics/p3/tests/CMakeLists.txt +++ b/components/eamxx/src/physics/p3/tests/CMakeLists.txt @@ -83,12 +83,14 @@ if (NOT SCREAM_P3_SMALL_KERNELS) # Make sure that a diff in the two implementation triggers a failed test (in debug only) # No need to run lots of different thread counts. - CreateUnitTest (p3_sk_tests_fail p3_rain_sed_unit_tests.cpp - LIBS p3_sk p3_test_infra - EXE_ARGS "--flags=\\'${BASELINE_FILE_ARG}\\'" - COMPILER_CXX_DEFS SCREAM_FORCE_RUN_DIFF - LABELS "p3_sk;physics;fail" - ${FORCE_RUN_DIFF_FAILS}) + if (SCREAM_ENABLE_BASELINE_TESTS) + CreateUnitTest (p3_sk_tests_fail p3_rain_sed_unit_tests.cpp + LIBS p3_sk p3_test_infra + EXE_ARGS "--flags=\\'${BASELINE_FILE_ARG}\\'" + COMPILER_CXX_DEFS SCREAM_FORCE_RUN_DIFF + LABELS "p3_sk;physics;fail" + ${FORCE_RUN_DIFF_FAILS}) + endif() endif() CreateUnitTest(p3_run_and_cmp "p3_run_and_cmp.cpp" diff --git a/components/eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp b/components/eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp index 4c0d5a214e04..f6d9be48c2a1 100644 --- a/components/eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp @@ -122,8 +122,11 @@ struct Baseline { } Int run_and_cmp (const std::string& filename, const double& tol, bool no_baseline) { - auto fid = ekat::FILEPtr(fopen(filename.c_str(), "r")); - EKAT_REQUIRE_MSG( fid, "generate_baseline can't read " << filename); + ekat::FILEPtr fid; + if (no_baseline) { + fid = ekat::FILEPtr(fopen(filename.c_str(), "r")); + EKAT_REQUIRE_MSG( fid, "generate_baseline can't read " << filename); + } Int nerr = 0, ne; int case_num = 0; for (auto ps : params_) { @@ -352,7 +355,11 @@ int main (int argc, char** argv) { if (generate) { std::cout << "Generating to " << baseline_fn << "\n"; nerr += bln.generate_baseline(baseline_fn); - } else { + } else if (no_baseline) { + printf("Running with no baseline actions\n"); + nerr += bln.run_and_cmp(baseline_fn, tol, no_baseline); + } + else { printf("Comparing with %s at tol %1.1e\n", baseline_fn.c_str(), tol); nerr += bln.run_and_cmp(baseline_fn, tol, no_baseline); } From 03630d39835cdc50f9347982acc2603abb282d64 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Thu, 7 Nov 2024 17:16:37 -0700 Subject: [PATCH 048/147] Another minor fix --- components/eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp b/components/eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp index f6d9be48c2a1..ed6f343fbcfe 100644 --- a/components/eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp @@ -123,7 +123,7 @@ struct Baseline { Int run_and_cmp (const std::string& filename, const double& tol, bool no_baseline) { ekat::FILEPtr fid; - if (no_baseline) { + if (!no_baseline) { fid = ekat::FILEPtr(fopen(filename.c_str(), "r")); EKAT_REQUIRE_MSG( fid, "generate_baseline can't read " << filename); } From a17807865bf2ac7c5a19eb5e07724bb5d13cbb74 Mon Sep 17 00:00:00 2001 From: Luca Bertagna Date: Fri, 8 Nov 2024 13:41:22 -0700 Subject: [PATCH 049/147] EAMxx: fix query-scream util script It's used by ekat when testing a PR --- components/eamxx/scripts/query_scream.py | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/components/eamxx/scripts/query_scream.py b/components/eamxx/scripts/query_scream.py index 4b26451c7cb2..a6fe5096bfb5 100644 --- a/components/eamxx/scripts/query_scream.py +++ b/components/eamxx/scripts/query_scream.py @@ -1,9 +1,5 @@ -from machines_specs import assert_machine_supported, \ - get_mach_cxx_compiler, get_mach_c_compiler, get_mach_f90_compiler, \ - get_mach_batch_command, get_mach_env_setup_command, \ - get_mach_baseline_root_dir, is_cuda_machine, \ - get_mach_compilation_resources, get_mach_testing_resources +from machines_specs import assert_machine_supported, get_machine, get_mach_env_setup_command from utils import expect CHOICES = ( @@ -24,23 +20,24 @@ def query_scream(machine, param): assert_machine_supported(machine) expect(param in CHOICES, f"Unknown param {param}") + mach = get_machine(machine) if param == "cxx_compiler": - return get_mach_cxx_compiler(machine) + return mach.cxx_compiler elif param == "c_compiler": - return get_mach_c_compiler(machine) + return mach.c_compiler elif param == "f90_compiler": - return get_mach_f90_compiler(machine) + return mach.ftn_compiler elif param == "batch": - return get_mach_batch_command(machine) + return mach.batch elif param == "env": return get_mach_env_setup_command(machine) elif param == "baseline_root": - return get_mach_baseline_root_dir(machine) + return mach.baselines_dir elif param == "cuda": - return str(is_cuda_machine(machine)) + return str(mach.gpu_arch == "cuda") elif param == "comp_j": - return get_mach_compilation_resources() + return num_bld_res elif param == "test_j": - return get_mach_testing_resources(machine) + return gnum_run_res else: expect(False, f"Unhandled param {param}") From 579850c0776cfbd80f8c55fe1b34728a3ab54c01 Mon Sep 17 00:00:00 2001 From: Luca Bertagna Date: Fri, 8 Nov 2024 15:38:42 -0700 Subject: [PATCH 050/147] Update .mergify.yml Fix required checks names --- .mergify.yml | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/.mergify.yml b/.mergify.yml index e931d54eb095..6c9318ce5b6e 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -1,21 +1,20 @@ merge_protections: - name: Enforce checks passing description: Make sure that checks are not failing on the PR, and reviewers approved - comment: false if: - base = master success_conditions: - "#approved-reviews-by >= 1" # At least 1 approval - "#changes-requested-reviews-by == 0" # No reviewer asked for changes - or: - - check-success=eamxx-sa/gcc-openmp/* - - check-skipped=eamxx-sa/gcc-openmp/* + - check-success="gcc-openmp / .*" + - check-skipped="gcc-openmp / .*" - or: - - check-success=eamxx-sa/gcc-cuda/* - - check-skipped=eamxx-sa/gcc-cuda/* + - check-success="gcc-cuda / .*" + - check-skipped="gcc-cuda / .*" - or: - - check-success=eamxx-v1/cpu-gcc/* - - check-skipped=eamxx-v1/cpu-gcc/* + - check-success="cpu-gcc / .*" + - check-skipped="cpu-gcc / .*" - or: - - check-success=eamxx-scripts/cpu-gcc - - check-skipped=eamxx-scripts/cpu-gcc + - check-success=cpu-gcc + - check-skipped=cpu-gcc From fefea965df034141d5bed9999db9295aa897ef68 Mon Sep 17 00:00:00 2001 From: Luca Bertagna Date: Fri, 8 Nov 2024 15:17:22 -0700 Subject: [PATCH 051/147] Update ekat submodule --- externals/ekat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/externals/ekat b/externals/ekat index 4e36a487d9ce..1d441b22df3e 160000 --- a/externals/ekat +++ b/externals/ekat @@ -1 +1 @@ -Subproject commit 4e36a487d9ced3951907b36a1a16b13325d796d1 +Subproject commit 1d441b22df3e4f8f8b3ea96099b0e848eb74afd7 From acd26a119487f9c3fe66ae4cb4063f709cce98e9 Mon Sep 17 00:00:00 2001 From: Luca Bertagna Date: Fri, 8 Nov 2024 15:18:38 -0700 Subject: [PATCH 052/147] EAMxx: adapt to changes in ekat's catch main logic --- .../src/physics/p3/tests/p3_run_and_cmp.cpp | 38 ++++--------------- .../src/physics/rrtmgp/tests/rrtmgp_tests.cpp | 14 +++---- .../physics/shoc/tests/shoc_run_and_cmp.cpp | 38 ++++--------------- .../eamxx/src/share/util/eamxx_ad_test.cpp | 2 +- .../model_restart/CMakeLists.txt | 6 +-- .../atm_proc_subcycling/CMakeLists.txt | 4 +- .../shoc_p3_nudging/CMakeLists.txt | 8 ++-- .../single-process/rrtmgp/CMakeLists.txt | 6 +-- .../rrtmgp/rrtmgp_standalone_unit.cpp | 4 +- 9 files changed, 34 insertions(+), 86 deletions(-) diff --git a/components/eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp b/components/eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp index 5bc12b2464db..ed252b5034c4 100644 --- a/components/eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp +++ b/components/eamxx/src/physics/p3/tests/p3_run_and_cmp.cpp @@ -279,10 +279,9 @@ int main (int argc, char** argv) { ++i; nlev = std::atoi(argv[i]); } - if (std::string(argv[i])=="--ekat-kokkos-device") { - expect_another_arg(i, argc); - ++i; - device = argv[i]; + if (std::string(argv[i])=="--kokkos-device-id=") { + auto tokens = ekat::split(argv[i],"="); + device = tokens[1]; } if (ekat::argv_matches(argv[i], "-r", "--repeat")) { expect_another_arg(i, argc); @@ -311,32 +310,8 @@ int main (int argc, char** argv) { // Decorate baseline name with precision. baseline_fn += std::to_string(sizeof(scream::Real)); - std::vector args; - for (int i=0; i" was specified, add kokkos - // initialization flag to argv - // Create it outside the if, so its c_str pointer survives - std::string dev_arg; - if (device!="") { - auto is_int = [] (const std::string& s)->bool { - std::istringstream is(s); - int d; - is >> d; - return !is.fail() && is.eof(); - }; - - EKAT_REQUIRE_MSG (is_int(device), "Error! Invalid device specification.\n"); - - if (std::stoi(device) != -1) { - dev_arg = "--kokkos-device-id=" + device; - args.push_back(const_cast(dev_arg.c_str())); - } - } - - scream::initialize_scream_session(args.size(), args.data()); { + scream::initialize_scream_session(argc, argv); + { Baseline bln(timesteps, static_cast(dt), ncol, nlev, repeat, predict_nc, prescribed_ccn); if (generate) { std::cout << "Generating to " << baseline_fn << "\n"; @@ -346,7 +321,8 @@ int main (int argc, char** argv) { nerr += bln.run_and_cmp(baseline_fn, tol, use_fortran); } P3GlobalForFortran::deinit(); - } scream::finalize_scream_session(); + } + scream::finalize_scream_session(); return nerr != 0 ? 1 : 0; } diff --git a/components/eamxx/src/physics/rrtmgp/tests/rrtmgp_tests.cpp b/components/eamxx/src/physics/rrtmgp/tests/rrtmgp_tests.cpp index 0d3f18e7d841..fedb8c3d0478 100644 --- a/components/eamxx/src/physics/rrtmgp/tests/rrtmgp_tests.cpp +++ b/components/eamxx/src/physics/rrtmgp/tests/rrtmgp_tests.cpp @@ -46,7 +46,7 @@ int run_yakl(int argc, char** argv) { logger->error(msg); return 1; } - std::string inputfile, baseline, device; + std::string inputfile, baseline; for (int i = 1; i < argc-1; ++i) { if (ekat::argv_matches(argv[i], "-b", "--baseline-file")) { @@ -60,10 +60,8 @@ int run_yakl(int argc, char** argv) { inputfile = argv[i]; } // RRTMGP baselines tests to not use kokoks. Swallow the arg, but ignore it - if (std::string(argv[i])=="--ekat-kokkos-device") { - expect_another_arg(i, argc); - ++i; - device = argv[i]; + if (std::string(argv[i])=="--kokkos-device-id=") { + continue; } } @@ -352,10 +350,8 @@ int run_kokkos(int argc, char** argv) { inputfile = argv[i]; } // RRTMGP baselines tests to not use kokoks. Swallow the arg, but ignore it - if (std::string(argv[i])=="--ekat-kokkos-device") { - expect_another_arg(i, argc); - ++i; - device = argv[i]; + if (std::string(argv[i])=="--kokkos-device-id=") { + continue; } } diff --git a/components/eamxx/src/physics/shoc/tests/shoc_run_and_cmp.cpp b/components/eamxx/src/physics/shoc/tests/shoc_run_and_cmp.cpp index a5198d959800..94a58b4de9c3 100644 --- a/components/eamxx/src/physics/shoc/tests/shoc_run_and_cmp.cpp +++ b/components/eamxx/src/physics/shoc/tests/shoc_run_and_cmp.cpp @@ -271,42 +271,17 @@ int main (int argc, char** argv) { generate = true; } } - if (std::string(argv[i])=="--ekat-kokkos-device") { - expect_another_arg(i, argc); - ++i; - device = argv[i]; + if (std::string(argv[i])=="--kokkos-device-id=") { + auto tokens = ekat::split(argv[i],"="); + device = tokens[1]; } } // Decorate baseline name with precision. baseline_fn += std::to_string(sizeof(scream::Real)); - std::vector args; - for (int i=0; i" was specified, add kokkos - // initialization flag to argv - // Create it outside the if, so its c_str pointer survives - std::string dev_arg; - if (device!="") { - auto is_int = [] (const std::string& s)->bool { - std::istringstream is(s); - int d; - is >> d; - return !is.fail() && is.eof(); - }; - - EKAT_REQUIRE_MSG (is_int(device), "Error! Invalid device specification.\n"); - - if (std::stoi(device) != -1) { - dev_arg = "--kokkos-device-id=" + device; - args.push_back(const_cast(dev_arg.c_str())); - } - } - - scream::initialize_scream_session(args.size(), args.data()); { + scream::initialize_scream_session(argc, argv); + { Baseline bln(nsteps, static_cast(dt), ncol, nlev, num_qtracers, nadv, repeat); if (generate) { std::cout << "Generating to " << baseline_fn << "\n"; @@ -315,7 +290,8 @@ int main (int argc, char** argv) { printf("Comparing with %s at tol %1.1e\n", baseline_fn.c_str(), tol); nerr += bln.run_and_cmp(baseline_fn, tol, use_fortran); } - } scream::finalize_scream_session(); + } + scream::finalize_scream_session(); return nerr != 0 ? 1 : 0; } diff --git a/components/eamxx/src/share/util/eamxx_ad_test.cpp b/components/eamxx/src/share/util/eamxx_ad_test.cpp index 0f64bd7c5ab3..ba4934788782 100644 --- a/components/eamxx/src/share/util/eamxx_ad_test.cpp +++ b/components/eamxx/src/share/util/eamxx_ad_test.cpp @@ -32,7 +32,7 @@ TEST_CASE("scream_ad_test") { // Create a comm ekat::Comm atm_comm (MPI_COMM_WORLD); - // User can prescribe input file name via --ekat-test-params ifile= + // User can prescribe input file name via --args --ifile auto& session = ekat::TestSession::get(); session.params.emplace("ifile","input.yaml"); std::string fname = session.params["ifile"]; diff --git a/components/eamxx/tests/multi-process/dynamics_physics/model_restart/CMakeLists.txt b/components/eamxx/tests/multi-process/dynamics_physics/model_restart/CMakeLists.txt index 5645a9383a7a..a0288b454b2c 100644 --- a/components/eamxx/tests/multi-process/dynamics_physics/model_restart/CMakeLists.txt +++ b/components/eamxx/tests/multi-process/dynamics_physics/model_restart/CMakeLists.txt @@ -24,20 +24,20 @@ set (CASE_TN 2023-01-01-00060) # Create the baseline (run all 6 timsteps in a single run) CreateUnitTestFromExec(model_baseline model_restart - EXE_ARGS "--use-colour no --ekat-test-params ifile=input_baseline.yaml" + EXE_ARGS "--args -ifile=input_baseline.yaml" MPI_RANKS ${SCREAM_TEST_MAX_RANKS} FIXTURES_SETUP baseline_run) # Start a simulation, but only run half of the time steps CreateUnitTestFromExec(model_initial model_restart - EXE_ARGS "--use-colour no --ekat-test-params ifile=input_initial.yaml" + EXE_ARGS "--args -ifile=input_initial.yaml" MPI_RANKS ${SCREAM_TEST_MAX_RANKS} FIXTURES_SETUP initial_run PROPERTIES RESOURCE_LOCK rpointer_file) # Restart the simulation, and run the second half of the time steps CreateUnitTestFromExec(model_restart model_restart - EXE_ARGS "--use-colour no --ekat-test-params ifile=input_restarted.yaml" + EXE_ARGS "--args -ifile=input_restarted.yaml" MPI_RANKS ${SCREAM_TEST_MAX_RANKS} FIXTURES_REQUIRED initial_run FIXTURES_SETUP restarted_run diff --git a/components/eamxx/tests/multi-process/physics_only/atm_proc_subcycling/CMakeLists.txt b/components/eamxx/tests/multi-process/physics_only/atm_proc_subcycling/CMakeLists.txt index 71fe2a5f43c2..88c5f1022f66 100644 --- a/components/eamxx/tests/multi-process/physics_only/atm_proc_subcycling/CMakeLists.txt +++ b/components/eamxx/tests/multi-process/physics_only/atm_proc_subcycling/CMakeLists.txt @@ -23,7 +23,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/output_tend.yaml ${CMAKE_CURRENT_BINARY_DIR}/output_tend_subcycled.yaml) CreateUnitTestFromExec (shoc_p3_subcycled shoc_p3 - EXE_ARGS "--use-colour no --ekat-test-params ifile=input_subcycled.yaml" + EXE_ARGS "--args -ifile=input_subcycled.yaml" FIXTURES_SETUP shoc_p3_subcycled) # Run a test without subcycling and more steps @@ -38,7 +38,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/output.yaml configure_file(${CMAKE_CURRENT_SOURCE_DIR}/output_tend.yaml ${CMAKE_CURRENT_BINARY_DIR}/output_tend_monolithic.yaml) CreateUnitTestFromExec (shoc_p3_monolithic shoc_p3 - EXE_ARGS "--use-colour no --ekat-test-params ifile=input_monolithic.yaml" + EXE_ARGS "--args -ifile=input_monolithic.yaml" FIXTURES_SETUP shoc_p3_monolithic) # Finally, compare output of the two tests diff --git a/components/eamxx/tests/multi-process/physics_only/shoc_p3_nudging/CMakeLists.txt b/components/eamxx/tests/multi-process/physics_only/shoc_p3_nudging/CMakeLists.txt index 62c4b6d2266e..16568dc55b3a 100644 --- a/components/eamxx/tests/multi-process/physics_only/shoc_p3_nudging/CMakeLists.txt +++ b/components/eamxx/tests/multi-process/physics_only/shoc_p3_nudging/CMakeLists.txt @@ -27,7 +27,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/output.yaml configure_file(${CMAKE_CURRENT_SOURCE_DIR}/output_remapped.yaml ${CMAKE_CURRENT_BINARY_DIR}/output_source_data_remapped.yaml) CreateUnitTestFromExec (shoc_p3_source shoc_p3_nudging - EXE_ARGS "--use-colour no --ekat-test-params ifile=input_source_data.yaml" + EXE_ARGS "--args -ifile=input_source_data.yaml" FIXTURES_SETUP shoc_p3_source_data FIXTURES_REQUIRED shoc_p3_create_vertical_remap_and_weights_file) @@ -41,7 +41,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/input_nudging.yaml configure_file(${CMAKE_CURRENT_SOURCE_DIR}/output.yaml ${CMAKE_CURRENT_BINARY_DIR}/output_nudged.yaml) CreateUnitTestFromExec (shoc_p3_nudged shoc_p3_nudging - EXE_ARGS "--use-colour no --ekat-test-params ifile=input_nudging.yaml" + EXE_ARGS "--args -ifile=input_nudging.yaml" FIXTURES_REQUIRED shoc_p3_source_data) # Run a test with nudging turned on using remapped source data for nudging: @@ -54,7 +54,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/input_nudging.yaml configure_file(${CMAKE_CURRENT_SOURCE_DIR}/output.yaml ${CMAKE_CURRENT_BINARY_DIR}/output_nudged_remapped.yaml) CreateUnitTestFromExec (shoc_p3_nudged_remapped shoc_p3_nudging - EXE_ARGS "--use-colour no --ekat-test-params ifile=input_nudging_remapped.yaml" + EXE_ARGS "--args -ifile=input_nudging_remapped.yaml" FIXTURES_REQUIRED shoc_p3_source_data) # Run a test with nudging using data read in glob pattern and skip vertical interpolation: @@ -67,6 +67,6 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/input_nudging_glob_novert.yaml configure_file(${CMAKE_CURRENT_SOURCE_DIR}/output.yaml ${CMAKE_CURRENT_BINARY_DIR}/output_nudged_glob_novert.yaml) CreateUnitTestFromExec (shoc_p3_nudging_glob_novert shoc_p3_nudging - EXE_ARGS "--use-colour no --ekat-test-params ifile=input_nudging_glob_novert.yaml" + EXE_ARGS "--args -ifile=input_nudging_glob_novert.yaml" FIXTURES_REQUIRED shoc_p3_source_data) diff --git a/components/eamxx/tests/single-process/rrtmgp/CMakeLists.txt b/components/eamxx/tests/single-process/rrtmgp/CMakeLists.txt index 792d3946a4c2..b16c2e732884 100644 --- a/components/eamxx/tests/single-process/rrtmgp/CMakeLists.txt +++ b/components/eamxx/tests/single-process/rrtmgp/CMakeLists.txt @@ -13,7 +13,7 @@ if (SCREAM_ENABLE_BASELINE_TESTS AND NOT SCREAM_ONLY_GENERATE_BASELINES) CreateUnitTest(${TEST_BASE_NAME}_unit rrtmgp_standalone_unit.cpp LABELS rrtmgp physics driver LIBS scream_rrtmgp rrtmgp scream_control yakl diagnostics rrtmgp_test_utils - EXE_ARGS "--ekat-test-params rrtmgp_inputfile=${SCREAM_DATA_DIR}/init/rrtmgp-allsky.nc,rrtmgp_baseline=${SCREAM_BASELINES_DIR}/data/rrtmgp-allsky-baseline.nc" + EXE_ARGS "--args --inputfile ${SCREAM_DATA_DIR}/init/rrtmgp-allsky.nc --baseline ${SCREAM_BASELINES_DIR}/data/rrtmgp-allsky-baseline.nc" ) endif() @@ -39,7 +39,7 @@ CreateUnitTestFromExec( ${TEST_BASE_NAME}_not_chunked ${TEST_BASE_NAME} LABELS rrtmgp physics driver MPI_RANKS ${TEST_RANK_START} ${TEST_RANK_END} - EXE_ARGS "--ekat-test-params inputfile=input_not_chunked.yaml" + EXE_ARGS "--args -inputfile input_not_chunked.yaml" FIXTURES_SETUP_INDIVIDUAL ${FIXTURES_BASE_NAME}_not_chunked ) @@ -70,7 +70,7 @@ CreateUnitTestFromExec( ${TEST_BASE_NAME}_chunked ${TEST_BASE_NAME} LABELS rrtmgp physics driver MPI_RANKS ${TEST_RANK_END} - EXE_ARGS "--ekat-test-params inputfile=input_chunked.yaml" + EXE_ARGS "--args --inputfile=input_chunked.yaml" FIXTURES_SETUP_INDIVIDUAL ${FIXTURES_BASE_NAME}_chunked PROPERTIES PASS_REGULAR_EXPRESSION "(beg.end: 0, ${COL_CHUNK_SIZE})" ) diff --git a/components/eamxx/tests/single-process/rrtmgp/rrtmgp_standalone_unit.cpp b/components/eamxx/tests/single-process/rrtmgp/rrtmgp_standalone_unit.cpp index dc1ece59b287..5be27ce2b1e2 100644 --- a/components/eamxx/tests/single-process/rrtmgp/rrtmgp_standalone_unit.cpp +++ b/components/eamxx/tests/single-process/rrtmgp/rrtmgp_standalone_unit.cpp @@ -49,8 +49,8 @@ using PC = scream::physics::Constants; #ifdef RRTMGP_ENABLE_YAKL TEST_CASE("rrtmgp_scream_standalone", "") { // Get baseline name (needs to be passed as an arg) - std::string inputfile = ekat::TestSession::get().params.at("rrtmgp_inputfile"); - std::string baseline = ekat::TestSession::get().params.at("rrtmgp_baseline"); + std::string inputfile = ekat::TestSession::get().params.at("inputfile"); + std::string baseline = ekat::TestSession::get().params.at("baseline"); // Check if files exists REQUIRE(rrtmgpTest::file_exists(inputfile.c_str())); From fa86f7a57e9a6cc8aba91aea1d53b20b86772165 Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Sat, 9 Nov 2024 15:46:42 -0800 Subject: [PATCH 053/147] EAMxx: Adds a SMS ne30 test that uses ne4 emission file --- .../scream/mam4xx/force_remap/shell_commands | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/force_remap/shell_commands diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/force_remap/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/force_remap/shell_commands new file mode 100644 index 000000000000..078b8e93a25b --- /dev/null +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/force_remap/shell_commands @@ -0,0 +1,26 @@ + +#!/bin/sh +#------------------------------------------------------ +# MAM4xx adds additionaltracers to the simulation +# Increase number of tracers for MAM4xx simulations +#------------------------------------------------------ + +$CIMEROOT/../components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/update_eamxx_num_tracers.sh -b + +#------------------------------------------------------ +#Update IC file and add drydep process +#------------------------------------------------------ +$CIMEROOT/../components/eamxx/scripts/atmchange physics::atm_procs_list="mac_aero_mic,rrtmgp,mam4_aero_microphys" -b + +$CIMEROOT/../components/eamxx/scripts/atmchange mam4_aero_microphys::mam4_so2_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_so2_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b +$CIMEROOT/../components/eamxx/scripts/atmchange mam4_aero_microphys::mam4_so4_a1_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_so4_a1_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b +$CIMEROOT/../components/eamxx/scripts/atmchange mam4_aero_microphys::mam4_so4_a2_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_so4_a2_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b +$CIMEROOT/../components/eamxx/scripts/atmchange mam4_aero_microphys::mam4_pom_a4_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_pom_a4_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b +$CIMEROOT/../components/eamxx/scripts/atmchange mam4_aero_microphys::mam4_bc_a4_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_bc_a4_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b +$CIMEROOT/../components/eamxx/scripts/atmchange mam4_aero_microphys::mam4_num_a1_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_num_a1_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b +$CIMEROOT/../components/eamxx/scripts/atmchange mam4_aero_microphys::mam4_num_a2_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_num_a2_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b +$CIMEROOT/../components/eamxx/scripts/atmchange mam4_aero_microphys::mam4_num_a4_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_num_a4_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b +$CIMEROOT/../components/eamxx/scripts/atmchange mam4_aero_microphys::mam4_soag_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_soag_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b +$CIMEROOT/../components/eamxx/scripts/atmchange mam4_aero_microphys::aero_microphys_remap_file='/qfs/people/sing201/eagles/refactor_mam/mam4xx_scream/nco_scripts_mapping_files/map_ne4pg2_to_ne30pg2_nco_c20241107.nc' -b + + From 9f6e83e422f5b5cb0969744d248f4086e570bdc0 Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Sat, 9 Nov 2024 15:57:05 -0800 Subject: [PATCH 054/147] EAMxx:Modified folder name nad uses alias for atmchange --- .../scream/mam4xx/force_remap/shell_commands | 26 ----------------- .../remap_emiss_ne4_ne30/shell_commands | 28 +++++++++++++++++++ 2 files changed, 28 insertions(+), 26 deletions(-) delete mode 100644 components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/force_remap/shell_commands create mode 100644 components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/remap_emiss_ne4_ne30/shell_commands diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/force_remap/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/force_remap/shell_commands deleted file mode 100644 index 078b8e93a25b..000000000000 --- a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/force_remap/shell_commands +++ /dev/null @@ -1,26 +0,0 @@ - -#!/bin/sh -#------------------------------------------------------ -# MAM4xx adds additionaltracers to the simulation -# Increase number of tracers for MAM4xx simulations -#------------------------------------------------------ - -$CIMEROOT/../components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/update_eamxx_num_tracers.sh -b - -#------------------------------------------------------ -#Update IC file and add drydep process -#------------------------------------------------------ -$CIMEROOT/../components/eamxx/scripts/atmchange physics::atm_procs_list="mac_aero_mic,rrtmgp,mam4_aero_microphys" -b - -$CIMEROOT/../components/eamxx/scripts/atmchange mam4_aero_microphys::mam4_so2_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_so2_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b -$CIMEROOT/../components/eamxx/scripts/atmchange mam4_aero_microphys::mam4_so4_a1_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_so4_a1_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b -$CIMEROOT/../components/eamxx/scripts/atmchange mam4_aero_microphys::mam4_so4_a2_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_so4_a2_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b -$CIMEROOT/../components/eamxx/scripts/atmchange mam4_aero_microphys::mam4_pom_a4_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_pom_a4_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b -$CIMEROOT/../components/eamxx/scripts/atmchange mam4_aero_microphys::mam4_bc_a4_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_bc_a4_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b -$CIMEROOT/../components/eamxx/scripts/atmchange mam4_aero_microphys::mam4_num_a1_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_num_a1_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b -$CIMEROOT/../components/eamxx/scripts/atmchange mam4_aero_microphys::mam4_num_a2_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_num_a2_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b -$CIMEROOT/../components/eamxx/scripts/atmchange mam4_aero_microphys::mam4_num_a4_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_num_a4_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b -$CIMEROOT/../components/eamxx/scripts/atmchange mam4_aero_microphys::mam4_soag_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_soag_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b -$CIMEROOT/../components/eamxx/scripts/atmchange mam4_aero_microphys::aero_microphys_remap_file='/qfs/people/sing201/eagles/refactor_mam/mam4xx_scream/nco_scripts_mapping_files/map_ne4pg2_to_ne30pg2_nco_c20241107.nc' -b - - diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/remap_emiss_ne4_ne30/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/remap_emiss_ne4_ne30/shell_commands new file mode 100644 index 000000000000..538fbcf1b189 --- /dev/null +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/remap_emiss_ne4_ne30/shell_commands @@ -0,0 +1,28 @@ + +#!/bin/sh +#------------------------------------------------------ +# MAM4xx adds additionaltracers to the simulation +# Increase number of tracers for MAM4xx simulations +#------------------------------------------------------ + +$CIMEROOT/../components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/update_eamxx_num_tracers.sh -b + +#------------------------------------------------------ +#Update IC file and add drydep process +#------------------------------------------------------ +ATMCHANGE=$CIMEROOT/../components/eamxx/scripts/atmchange + +ATMCHANGE physics::atm_procs_list="mac_aero_mic,rrtmgp,mam4_aero_microphys" -b + +ATMCHANGE mam4_aero_microphys::mam4_so2_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_so2_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b +ATMCHANGE mam4_aero_microphys::mam4_so4_a1_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_so4_a1_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b +ATMCHANGE mam4_aero_microphys::mam4_so4_a2_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_so4_a2_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b +ATMCHANGE mam4_aero_microphys::mam4_pom_a4_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_pom_a4_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b +ATMCHANGE mam4_aero_microphys::mam4_bc_a4_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_bc_a4_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b +ATMCHANGE mam4_aero_microphys::mam4_num_a1_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_num_a1_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b +ATMCHANGE mam4_aero_microphys::mam4_num_a2_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_num_a2_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b +ATMCHANGE mam4_aero_microphys::mam4_num_a4_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_num_a4_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b +ATMCHANGE mam4_aero_microphys::mam4_soag_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_soag_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b +ATMCHANGE mam4_aero_microphys::aero_microphys_remap_file='/qfs/people/sing201/eagles/refactor_mam/mam4xx_scream/nco_scripts_mapping_files/map_ne4pg2_to_ne30pg2_nco_c20241107.nc' -b + + From c07bc7283ada4535cba29ab068c8e4ce0d253669 Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Sat, 9 Nov 2024 16:41:32 -0800 Subject: [PATCH 055/147] EAMxx:Adds an alias and upload the mapping file ne4->ne30 --- .../scream/mam4xx/remap_emiss_ne4_ne30/shell_commands | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/remap_emiss_ne4_ne30/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/remap_emiss_ne4_ne30/shell_commands index 538fbcf1b189..da79db14fbec 100644 --- a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/remap_emiss_ne4_ne30/shell_commands +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/remap_emiss_ne4_ne30/shell_commands @@ -10,7 +10,7 @@ $CIMEROOT/../components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/u #------------------------------------------------------ #Update IC file and add drydep process #------------------------------------------------------ -ATMCHANGE=$CIMEROOT/../components/eamxx/scripts/atmchange +alias ATMCHANGE='$CIMEROOT/../components/eamxx/scripts/atmchange' ATMCHANGE physics::atm_procs_list="mac_aero_mic,rrtmgp,mam4_aero_microphys" -b @@ -23,6 +23,6 @@ ATMCHANGE mam4_aero_microphys::mam4_num_a1_verti_emiss_file_name='${DIN_LOC_ROOT ATMCHANGE mam4_aero_microphys::mam4_num_a2_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_num_a2_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b ATMCHANGE mam4_aero_microphys::mam4_num_a4_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_num_a4_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b ATMCHANGE mam4_aero_microphys::mam4_soag_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_soag_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b -ATMCHANGE mam4_aero_microphys::aero_microphys_remap_file='/qfs/people/sing201/eagles/refactor_mam/mam4xx_scream/nco_scripts_mapping_files/map_ne4pg2_to_ne30pg2_nco_c20241107.nc' -b +ATMCHANGE mam4_aero_microphys::aero_microphys_remap_file='${DIN_LOC_ROOT}/atm/scream/maps/map_ne4pg2_to_ne30pg2_nco_c20241108.nc' -b From e3f671730e16fdc706bfeb74057951ea21ab3473 Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Sat, 9 Nov 2024 16:44:37 -0800 Subject: [PATCH 056/147] EAMxx: Adds remap test to nightlies --- cime_config/tests.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cime_config/tests.py b/cime_config/tests.py index 3c89e8e90995..41270f6217cb 100644 --- a/cime_config/tests.py +++ b/cime_config/tests.py @@ -757,6 +757,7 @@ "SMS_D_Ln5.ne4pg2_oQU480.F2010-SCREAMv1-MPASSI.scream-mam4xx-aci", "SMS_D_Ln5.ne4pg2_oQU480.F2010-SCREAMv1-MPASSI.scream-mam4xx-wetscav", "SMS_D_Ln5.ne4pg2_oQU480.F2010-SCREAMv1-MPASSI.scream-mam4xx-drydep", + "SMS_D_Ln5.ne30pg2_oECv3.F2010-SCREAMv1-MPASSI.scream-mam4xx-remap_emiss_ne4_ne30" ) }, From 2508f4746571dd9c3aa0204b3deec79773c830cf Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Sat, 9 Nov 2024 16:46:03 -0800 Subject: [PATCH 057/147] EAMxx: Removes init file from mam4xx test as it is now picked automatically --- .../testmods_dirs/scream/mam4xx/aero_microphysics/shell_commands | 1 - 1 file changed, 1 deletion(-) diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/aero_microphysics/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/aero_microphysics/shell_commands index 1d6757a5bd95..56390e2c9b0a 100644 --- a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/aero_microphysics/shell_commands +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/aero_microphysics/shell_commands @@ -10,7 +10,6 @@ $CIMEROOT/../components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/u #------------------------------------------------------ #Update IC file and 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_aero_microphys" -b From 806a6f1e928750464e419d3580dbb6e84627bf99 Mon Sep 17 00:00:00 2001 From: singhbalwinder Date: Sat, 9 Nov 2024 17:28:22 -0800 Subject: [PATCH 058/147] EAMxx: Fix a comment in the shell script --- .../scream/mam4xx/remap_emiss_ne4_ne30/shell_commands | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/remap_emiss_ne4_ne30/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/remap_emiss_ne4_ne30/shell_commands index da79db14fbec..aa3affac25b7 100644 --- a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/remap_emiss_ne4_ne30/shell_commands +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/remap_emiss_ne4_ne30/shell_commands @@ -7,9 +7,9 @@ $CIMEROOT/../components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/update_eamxx_num_tracers.sh -b -#------------------------------------------------------ -#Update IC file and add drydep process -#------------------------------------------------------ +#---------------------------------------------------------------------------------------------------------- +# Add aerosol microphysics process, force ne4pg2 emissions files and provide a ne4pg2->ne30pg2 mapping file +#---------------------------------------------------------------------------------------------------------- alias ATMCHANGE='$CIMEROOT/../components/eamxx/scripts/atmchange' ATMCHANGE physics::atm_procs_list="mac_aero_mic,rrtmgp,mam4_aero_microphys" -b From 9788c5718aeca16bcdb2026de1df26e4dfe96303 Mon Sep 17 00:00:00 2001 From: singhbalwinder Date: Sat, 9 Nov 2024 17:29:28 -0800 Subject: [PATCH 059/147] EAMxx: Fixes a comment in the microphysics testmod file --- .../scream/mam4xx/aero_microphysics/shell_commands | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/aero_microphysics/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/aero_microphysics/shell_commands index 56390e2c9b0a..ac1709f7dca4 100644 --- a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/aero_microphysics/shell_commands +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/aero_microphysics/shell_commands @@ -8,7 +8,7 @@ $CIMEROOT/../components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/update_eamxx_num_tracers.sh -b #------------------------------------------------------ -#Update IC file and add drydep process +# Add microphysics process #------------------------------------------------------ $CIMEROOT/../components/eamxx/scripts/atmchange physics::atm_procs_list="mac_aero_mic,rrtmgp,mam4_aero_microphys" -b From 97b2dd76acc65627078a99da736000841876290e Mon Sep 17 00:00:00 2001 From: singhbalwinder Date: Sat, 9 Nov 2024 17:31:26 -0800 Subject: [PATCH 060/147] EAMxx: Fixes a comment in the newly added test --- .../scream/mam4xx/remap_emiss_ne4_ne30/shell_commands | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/remap_emiss_ne4_ne30/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/remap_emiss_ne4_ne30/shell_commands index aa3affac25b7..606ca463f26c 100644 --- a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/remap_emiss_ne4_ne30/shell_commands +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/remap_emiss_ne4_ne30/shell_commands @@ -7,9 +7,11 @@ $CIMEROOT/../components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/update_eamxx_num_tracers.sh -b -#---------------------------------------------------------------------------------------------------------- -# Add aerosol microphysics process, force ne4pg2 emissions files and provide a ne4pg2->ne30pg2 mapping file -#---------------------------------------------------------------------------------------------------------- +#------------------------------------------------------ +# Add aerosol microphysics process, force ne4pg2 +# emission files and provide a ne4pg2->ne30pg2 mapping +# file +#------------------------------------------------------ alias ATMCHANGE='$CIMEROOT/../components/eamxx/scripts/atmchange' ATMCHANGE physics::atm_procs_list="mac_aero_mic,rrtmgp,mam4_aero_microphys" -b From e95224ebe403de0edfde6f316efb82405aa0a8a7 Mon Sep 17 00:00:00 2001 From: Luca Bertagna Date: Mon, 11 Nov 2024 09:26:14 -0700 Subject: [PATCH 061/147] Workflows: fix logic to execute/skip eamxx testing workflows --- .github/workflows/eamxx-sa-testing.yml | 50 +++++++++++++---------- .github/workflows/eamxx-scripts-tests.yml | 3 ++ .github/workflows/eamxx-v1-testing.yml | 23 ++++++----- 3 files changed, 44 insertions(+), 32 deletions(-) diff --git a/.github/workflows/eamxx-sa-testing.yml b/.github/workflows/eamxx-sa-testing.yml index bbfa12b80acc..baa1508ea6ce 100644 --- a/.github/workflows/eamxx-sa-testing.yml +++ b/.github/workflows/eamxx-sa-testing.yml @@ -83,18 +83,21 @@ jobs: gcc-openmp: needs: [pre_process_pr] if: | - success() && github.event_name == 'schedule' || + !failure() && !cancelled() && ( - github.event_name == 'pull_request' && - needs.pre_process_pr.outputs.relevant_paths=='true' && - !contains(needs.pre_process_pr.outputs.labels,'CI: skip gcc') && - !contains(needs.pre_process_pr.outputs.labels,'CI: skip openmp') && - !contains(needs.pre_process_pr.outputs.labels,'CI: skip eamxx-sa') && - !contains(needs.pre_process_pr.outputs.labels,'CI: skip eamxx-all') - ) || ( - github.event_name == 'workflow_dispatch' && - github.event.inputs.job_to_run == 'gcc-openmp' || - github.event.inputs.job_to_run == 'all' + github.event_name == 'schedule' || + ( + github.event_name == 'pull_request' && + needs.pre_process_pr.outputs.relevant_paths=='true' && + !contains(needs.pre_process_pr.outputs.labels,'CI: skip gcc') && + !contains(needs.pre_process_pr.outputs.labels,'CI: skip openmp') && + !contains(needs.pre_process_pr.outputs.labels,'CI: skip eamxx-sa') && + !contains(needs.pre_process_pr.outputs.labels,'CI: skip eamxx-all') + ) || ( + github.event_name == 'workflow_dispatch' && + github.event.inputs.job_to_run == 'gcc-openmp' || + github.event.inputs.job_to_run == 'all' + ) ) runs-on: [self-hosted, ghci-snl-cpu, gcc] strategy: @@ -130,18 +133,21 @@ jobs: gcc-cuda: needs: [pre_process_pr] if: | - success() && github.event_name == 'schedule' || + !failure() && !cancelled() && ( - github.event_name == 'pull_request' && - needs.pre_process_pr.outputs.relevant_paths=='true' && - !contains(needs.pre_process_pr.outputs.labels,'CI: skip gcc') && - !contains(needs.pre_process_pr.outputs.labels,'CI: skip cuda') && - !contains(needs.pre_process_pr.outputs.labels,'CI: skip eamxx-sa') && - !contains(needs.pre_process_pr.outputs.labels,'CI: skip eamxx-all') - ) || ( - github.event_name == 'workflow_dispatch' && - github.event.inputs.job_to_run == 'gcc-cuda' || - github.event.inputs.job_to_run == 'all' + github.event_name == 'schedule' || + ( + github.event_name == 'pull_request' && + needs.pre_process_pr.outputs.relevant_paths=='true' && + !contains(needs.pre_process_pr.outputs.labels,'CI: skip gcc') && + !contains(needs.pre_process_pr.outputs.labels,'CI: skip cuda') && + !contains(needs.pre_process_pr.outputs.labels,'CI: skip eamxx-sa') && + !contains(needs.pre_process_pr.outputs.labels,'CI: skip eamxx-all') + ) || ( + github.event_name == 'workflow_dispatch' && + github.event.inputs.job_to_run == 'gcc-cuda' || + github.event.inputs.job_to_run == 'all' + ) ) runs-on: [self-hosted, ghci-snl-cuda, cuda, gcc] strategy: diff --git a/.github/workflows/eamxx-scripts-tests.yml b/.github/workflows/eamxx-scripts-tests.yml index 6d39200e2739..8de453de3879 100644 --- a/.github/workflows/eamxx-scripts-tests.yml +++ b/.github/workflows/eamxx-scripts-tests.yml @@ -62,11 +62,14 @@ jobs: cpu-gcc: needs: [pre_process_pr] if: | + !failure() && !cancelled() && + ( github.event_name != 'pull_request' || ( needs.pre_process_pr.outputs.relevant_paths == 'true' && !contains(needs.pre_process_pr.outputs.labels, 'CI: skip eamxx-all') ) + ) runs-on: [self-hosted, gcc, ghci-snl-cpu] steps: - name: Check out the repository diff --git a/.github/workflows/eamxx-v1-testing.yml b/.github/workflows/eamxx-v1-testing.yml index 3a4b28cfed32..43cc7623f882 100644 --- a/.github/workflows/eamxx-v1-testing.yml +++ b/.github/workflows/eamxx-v1-testing.yml @@ -75,17 +75,20 @@ jobs: cpu-gcc: needs: [pre_process_pr] if: | - github.event_name == 'schedule' || + !failure() && !cancelled() && ( - github.event_name == 'pull_request' && - needs.pre_process_pr.outputs.relevant_paths=='true' && - !contains(needs.pre_process_pr.outputs.labels,'CI: skip gcc') && - !contains(needs.pre_process_pr.outputs.labels,'CI: skip eamxx-v1') && - !contains(needs.pre_process_pr.outputs.labels,'CI: skip eamxx-all') - ) || ( - github.event_name == 'workflow_dispatch' && - github.event.inputs.job_to_run == 'cpu-gcc' || - github.event.inputs.job_to_run == 'all' + github.event_name == 'schedule' || + ( + github.event_name == 'pull_request' && + needs.pre_process_pr.outputs.relevant_paths=='true' && + !contains(needs.pre_process_pr.outputs.labels,'CI: skip gcc') && + !contains(needs.pre_process_pr.outputs.labels,'CI: skip eamxx-v1') && + !contains(needs.pre_process_pr.outputs.labels,'CI: skip eamxx-all') + ) || ( + github.event_name == 'workflow_dispatch' && + github.event.inputs.job_to_run == 'cpu-gcc' || + github.event.inputs.job_to_run == 'all' + ) ) runs-on: [self-hosted, gcc, ghci-snl-cpu] strategy: From 37ae73afd8bc8f92c70946bdfd9b3d8f7ccaa309 Mon Sep 17 00:00:00 2001 From: Oscar Diaz-Ibarra Date: Mon, 11 Nov 2024 10:22:52 -0700 Subject: [PATCH 062/147] EMAxx - Update comment in enum TracerFileType to avoid confusion. --- .../physics/mam/readfiles/tracer_reader_utils.hpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/components/eamxx/src/physics/mam/readfiles/tracer_reader_utils.hpp b/components/eamxx/src/physics/mam/readfiles/tracer_reader_utils.hpp index bec628b1f965..c5d573e06ff4 100644 --- a/components/eamxx/src/physics/mam/readfiles/tracer_reader_utils.hpp +++ b/components/eamxx/src/physics/mam/readfiles/tracer_reader_utils.hpp @@ -66,13 +66,18 @@ struct ForcingHelper { }; enum TracerFileType { - // file with PS ncol, lev, and time + // file with ncol, lev, ilev, time and has P0 and PS as variables + // example: oxidants FORMULA_PS, - // nc zonal file from ncremap - ZONAL, // vertical emission files + // example: linoz + ZONAL, + // file with ncol, altitude, altitude_int, time + // example: elevated (at a height) emissions of aerosols and precursors + // NOTE: we must rename the default vertical tags when horiz remapping + // NOTE: we vert remap in a different routine in mam4xx VERT_EMISSION, - // + // Placeholder for cases where no file type is applicable NONE }; From e779856aeff251199442d694d124073c876b7dde Mon Sep 17 00:00:00 2001 From: James Foucar Date: Mon, 11 Nov 2024 11:28:52 -0700 Subject: [PATCH 063/147] Update based on better ekat flag handling --- .../eamxx/src/physics/p3/tests/CMakeLists.txt | 8 ++--- .../p3/tests/infra/p3_unit_tests_common.hpp | 31 ++++++------------- 2 files changed, 14 insertions(+), 25 deletions(-) diff --git a/components/eamxx/src/physics/p3/tests/CMakeLists.txt b/components/eamxx/src/physics/p3/tests/CMakeLists.txt index 784d3436c884..129e3c455e26 100644 --- a/components/eamxx/src/physics/p3/tests/CMakeLists.txt +++ b/components/eamxx/src/physics/p3/tests/CMakeLists.txt @@ -59,7 +59,7 @@ endif() CreateUnitTest(p3_tests "${P3_TESTS_SRCS}" LIBS p3 p3_test_infra - EXE_ARGS "--flags=\\'${BASELINE_FILE_ARG}\\'" + EXE_ARGS "--args ${BASELINE_FILE_ARG}" THREADS 1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC} LABELS "p3;physics") @@ -68,7 +68,7 @@ CreateUnitTest(p3_tests "${P3_TESTS_SRCS}" if (SCREAM_ENABLE_BASELINE_TESTS) CreateUnitTest (p3_tests_fail p3_rain_sed_unit_tests.cpp LIBS p3 p3_test_infra - EXE_ARGS "--flags=\\'${BASELINE_FILE_ARG}\\'" + EXE_ARGS "--args ${BASELINE_FILE_ARG}" COMPILER_CXX_DEFS SCREAM_FORCE_RUN_DIFF LABELS "p3;physics;fail" ${FORCE_RUN_DIFF_FAILS}) @@ -77,7 +77,7 @@ endif() if (NOT SCREAM_P3_SMALL_KERNELS) CreateUnitTest(p3_sk_tests "${P3_TESTS_SRCS}" LIBS p3_sk p3_test_infra - EXE_ARGS "--flags=\\'${BASELINE_FILE_ARG}\\'" + EXE_ARGS "--args ${BASELINE_FILE_ARG}" THREADS 1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC} LABELS "p3_sk;physics") @@ -86,7 +86,7 @@ if (NOT SCREAM_P3_SMALL_KERNELS) if (SCREAM_ENABLE_BASELINE_TESTS) CreateUnitTest (p3_sk_tests_fail p3_rain_sed_unit_tests.cpp LIBS p3_sk p3_test_infra - EXE_ARGS "--flags=\\'${BASELINE_FILE_ARG}\\'" + EXE_ARGS "--args ${BASELINE_FILE_ARG}" COMPILER_CXX_DEFS SCREAM_FORCE_RUN_DIFF LABELS "p3_sk;physics;fail" ${FORCE_RUN_DIFF_FAILS}) diff --git a/components/eamxx/src/physics/p3/tests/infra/p3_unit_tests_common.hpp b/components/eamxx/src/physics/p3/tests/infra/p3_unit_tests_common.hpp index 523315ae5ecc..9dd7dee95b31 100644 --- a/components/eamxx/src/physics/p3/tests/infra/p3_unit_tests_common.hpp +++ b/components/eamxx/src/physics/p3/tests/infra/p3_unit_tests_common.hpp @@ -85,28 +85,17 @@ struct UnitWrap { { Functions::p3_init(); // many tests will need fortran table data auto& ts = ekat::TestSession::get(); - auto raw_flags = ts.flags.begin()->first; - std::stringstream ss(raw_flags); - std::string flag; - bool next_token_is_path = false; - while (ss >> flag) { - if (flag == "-c") { - m_baseline_action = COMPARE; - } - else if (flag == "-g") { - m_baseline_action = GENERATE; - } - else if (flag == "-n") { - m_baseline_action = NONE; - } - else if (flag == "-b") { - next_token_is_path = true; - } - else if (next_token_is_path) { - m_baseline_path = flag; - next_token_is_path = false; - } + if (ts.flags["c"]) { + m_baseline_action = COMPARE; + } + else if (ts.flags["g"]) { + m_baseline_action = GENERATE; } + else if (ts.flags["n"]) { + m_baseline_action = NONE; + } + m_baseline_path = ts.params["b"]; + EKAT_REQUIRE_MSG( !(m_baseline_action != NONE && m_baseline_path == ""), "P3 unit test flags problem: baseline actions were requested but no baseline path was provided"); From 1062373c639fdf3a5c8860f9bf80e1266b3b2986 Mon Sep 17 00:00:00 2001 From: Aaron Donahue Date: Tue, 5 Nov 2024 14:38:08 -0800 Subject: [PATCH 064/147] Expose EAMxx to the git-version hash saved in the component cpl. This commit retrieves the git-hash saved in the component coupler and makes sure it is passed into the atmosphere driver. This is then used to improve the netcdf metadata in all EAMxx output files. --- components/eamxx/src/control/atmosphere_driver.cpp | 7 +++++-- components/eamxx/src/control/atmosphere_driver.hpp | 3 ++- components/eamxx/src/mct_coupling/atm_comp_mct.F90 | 10 ++++++---- .../src/mct_coupling/scream_cxx_f90_interface.cpp | 5 +++-- components/eamxx/src/mct_coupling/scream_f2c_mod.F90 | 6 ++++-- 5 files changed, 20 insertions(+), 11 deletions(-) diff --git a/components/eamxx/src/control/atmosphere_driver.cpp b/components/eamxx/src/control/atmosphere_driver.cpp index 9cf2b48e3586..0f1cb1e31ab0 100644 --- a/components/eamxx/src/control/atmosphere_driver.cpp +++ b/components/eamxx/src/control/atmosphere_driver.cpp @@ -807,7 +807,8 @@ void AtmosphereDriver:: set_provenance_data (std::string caseid, std::string rest_caseid, std::string hostname, - std::string username) + std::string username, + std::string versionid) { #ifdef SCREAM_CIME_BUILD // Check the inputs are valid @@ -816,6 +817,7 @@ set_provenance_data (std::string caseid, "Error! Invalid restart case id: " + rest_caseid + "\n"); EKAT_REQUIRE_MSG (hostname!="", "Error! Invalid hostname: " + hostname + "\n"); EKAT_REQUIRE_MSG (username!="", "Error! Invalid username: " + username + "\n"); + EKAT_REQUIRE_MSG (versionid!="", "Error! Invalid version: " + versionid + "\n"); #else caseid = rest_caseid = m_casename; char* user = new char[32]; @@ -835,13 +837,14 @@ set_provenance_data (std::string caseid, } delete[] user; delete[] host; + versionid = EAMXX_GIT_VERSION; #endif auto& provenance = m_atm_params.sublist("provenance"); provenance.set("caseid",caseid); provenance.set("rest_caseid",rest_caseid); provenance.set("hostname",hostname); provenance.set("username",username); - provenance.set("version",std::string(EAMXX_GIT_VERSION)); + provenance.set("git_version",versionid); } void AtmosphereDriver:: diff --git a/components/eamxx/src/control/atmosphere_driver.hpp b/components/eamxx/src/control/atmosphere_driver.hpp index 41801745ea23..a3acfba5d945 100644 --- a/components/eamxx/src/control/atmosphere_driver.hpp +++ b/components/eamxx/src/control/atmosphere_driver.hpp @@ -116,7 +116,8 @@ class AtmosphereDriver void set_provenance_data (std::string caseid = "", std::string rest_caseid = "", std::string hostname = "", - std::string username = ""); + std::string username = "", + std::string versionid = ""); // Load initial conditions for atm inputs void initialize_fields (); diff --git a/components/eamxx/src/mct_coupling/atm_comp_mct.F90 b/components/eamxx/src/mct_coupling/atm_comp_mct.F90 index eb9165c2acb2..0a248a2b6085 100644 --- a/components/eamxx/src/mct_coupling/atm_comp_mct.F90 +++ b/components/eamxx/src/mct_coupling/atm_comp_mct.F90 @@ -137,8 +137,8 @@ subroutine atm_init_mct( EClock, cdata, x2a, a2x, NLFilename ) ! TODO: read this from the namelist? character(len=256) :: yaml_fname = "./data/scream_input.yaml" character(kind=c_char,len=256), target :: yaml_fname_c, atm_log_fname_c - character(len=256) :: caseid, username, hostname, rest_caseid - character(kind=c_char,len=256), target :: caseid_c, username_c, hostname_c, calendar_c, rest_caseid_c + character(len=256) :: caseid, username, hostname, rest_caseid, versionid + character(kind=c_char,len=256), target :: caseid_c, username_c, hostname_c, calendar_c, rest_caseid_c, versionid_c integer (kind=c_int) :: run_type_c !------------------------------------------------------------------------------- @@ -151,7 +151,8 @@ subroutine atm_init_mct( EClock, cdata, x2a, a2x, NLFilename ) infodata=infodata) call seq_infodata_getData(infodata, atm_phase=phase, start_type=run_type, & username=username, case_name=caseid, & - rest_case_name=rest_caseid, hostname=hostname) + rest_case_name=rest_caseid, hostname=hostname, & + model_version=versionid) call seq_infodata_PutData(infodata, atm_aero=.true.) call seq_infodata_PutData(infodata, atm_prognostic=.true.) @@ -213,10 +214,11 @@ subroutine atm_init_mct( EClock, cdata, x2a, a2x, NLFilename ) call string_f2c(trim(rest_caseid),rest_caseid_c) call string_f2c(trim(hostname),hostname_c) call string_f2c(trim(username),username_c) + call string_f2c(trim(versionid),versionid_c) call scream_create_atm_instance (mpicom_atm, ATM_ID, yaml_fname_c, atm_log_fname_c, run_type_c, & INT(cur_ymd,kind=C_INT), INT(cur_tod,kind=C_INT), & INT(case_start_ymd,kind=C_INT), INT(case_start_tod,kind=C_INT), & - calendar_c, caseid_c, rest_caseid_c, hostname_c, username_c) + calendar_c, caseid_c, rest_caseid_c, hostname_c, username_c, versionid_c) ! Init MCT gsMap call atm_Set_gsMap_mct (mpicom_atm, ATM_ID, gsMap_atm) diff --git a/components/eamxx/src/mct_coupling/scream_cxx_f90_interface.cpp b/components/eamxx/src/mct_coupling/scream_cxx_f90_interface.cpp index 1e51aa47a36f..8d2edd5ee9ff 100644 --- a/components/eamxx/src/mct_coupling/scream_cxx_f90_interface.cpp +++ b/components/eamxx/src/mct_coupling/scream_cxx_f90_interface.cpp @@ -110,7 +110,8 @@ void scream_create_atm_instance (const MPI_Fint f_comm, const int atm_id, const char* caseid, const char* rest_caseid, const char* hostname, - const char* username) + const char* username, + const char* versionid) { using namespace scream; using namespace scream::control; @@ -176,7 +177,7 @@ void scream_create_atm_instance (const MPI_Fint f_comm, const int atm_id, ad.set_params(scream_params); ad.init_scorpio(atm_id); ad.init_time_stamps(run_t0,case_t0,run_type); - ad.set_provenance_data (caseid,rest_caseid,hostname,username); + ad.set_provenance_data (caseid,rest_caseid,hostname,username,versionid); ad.create_output_managers (); ad.create_atm_processes (); ad.create_grids (); diff --git a/components/eamxx/src/mct_coupling/scream_f2c_mod.F90 b/components/eamxx/src/mct_coupling/scream_f2c_mod.F90 index 5adb08250418..434639e8f823 100644 --- a/components/eamxx/src/mct_coupling/scream_f2c_mod.F90 +++ b/components/eamxx/src/mct_coupling/scream_f2c_mod.F90 @@ -18,7 +18,8 @@ subroutine scream_create_atm_instance (f_comm,atm_id,yaml_fname,atm_log_fname, & run_start_ymd,run_start_tod, & case_start_ymd,case_start_tod, & calendar_name, & - caseid, rest_caseid, hostname, username) bind(c) + caseid, rest_caseid, hostname, username, & + versionid) bind(c) use iso_c_binding, only: c_int, c_char ! ! Input(s) @@ -27,7 +28,8 @@ subroutine scream_create_atm_instance (f_comm,atm_id,yaml_fname,atm_log_fname, & integer (kind=c_int), value, intent(in) :: run_start_tod, run_start_ymd integer (kind=c_int), value, intent(in) :: case_start_tod, case_start_ymd character(kind=c_char), target, intent(in) :: yaml_fname(*), atm_log_fname(*), calendar_name(*), & - caseid(*), rest_caseid(*), hostname(*), username(*) + caseid(*), rest_caseid(*), hostname(*), username(*), & + versionid(*) end subroutine scream_create_atm_instance subroutine scream_get_cols_latlon (lat, lon) bind(c) From 342958c701c7a53e17f022b06de3d85db201b8e0 Mon Sep 17 00:00:00 2001 From: Oscar Diaz-Ibarra Date: Mon, 11 Nov 2024 11:35:30 -0700 Subject: [PATCH 065/147] EAMxx - Rename enum VERT_EMISSION to ELEVATED_EMISSIONS. --- .../eamxx_mam_microphysics_process_interface.cpp | 6 +++--- .../eamxx_mam_microphysics_process_interface.hpp | 2 +- .../mam/readfiles/tracer_reader_utils.hpp | 16 ++++++++-------- 3 files changed, 12 insertions(+), 12 deletions(-) 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 6f26646ad6fa..cc2cbbb2a6df 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 @@ -326,10 +326,10 @@ void MAMMicrophysics::set_grids( ++i; } // end i EKAT_REQUIRE_MSG( - offset_emis_ver <= int(mam_coupling::MAX_NUM_VERT_EMISSION_FIELDS), + offset_emis_ver <= int(mam_coupling::MAX_NUM_ELEVATED_EMISSIONS_FIELDS), "Error! Number of fields is bigger than " - "MAX_NUM_VERT_EMISSION_FIELDS. Increase the " - "MAX_NUM_VERT_EMISSION_FIELDS in tracer_reader_utils.hpp \n"); + "MAX_NUM_ELEVATED_EMISSIONS_FIELDS. Increase the " + "MAX_NUM_ELEVATED_EMISSIONS_FIELDS in tracer_reader_utils.hpp \n"); } // Tracer external forcing data } // set_grids diff --git a/components/eamxx/src/physics/mam/eamxx_mam_microphysics_process_interface.hpp b/components/eamxx/src/physics/mam/eamxx_mam_microphysics_process_interface.hpp index 6b1dd33dfaa2..5ecd8c624618 100644 --- a/components/eamxx/src/physics/mam/eamxx_mam_microphysics_process_interface.hpp +++ b/components/eamxx/src/physics/mam/eamxx_mam_microphysics_process_interface.hpp @@ -232,7 +232,7 @@ class MAMMicrophysics final : public scream::AtmosphereProcess { std::vector vert_emis_data_; std::map vert_emis_file_name_; std::map> vert_emis_var_names_; - view_2d vert_emis_output_[mam_coupling::MAX_NUM_VERT_EMISSION_FIELDS]; + view_2d vert_emis_output_[mam_coupling::MAX_NUM_ELEVATED_EMISSIONS_FIELDS]; view_3d extfrc_; mam_coupling::ForcingHelper forcings_[mam4::gas_chemistry::extcnt]; diff --git a/components/eamxx/src/physics/mam/readfiles/tracer_reader_utils.hpp b/components/eamxx/src/physics/mam/readfiles/tracer_reader_utils.hpp index c5d573e06ff4..c605d3a0b9f3 100644 --- a/components/eamxx/src/physics/mam/readfiles/tracer_reader_utils.hpp +++ b/components/eamxx/src/physics/mam/readfiles/tracer_reader_utils.hpp @@ -69,14 +69,14 @@ enum TracerFileType { // file with ncol, lev, ilev, time and has P0 and PS as variables // example: oxidants FORMULA_PS, - // vertical emission files + // file with ncol, lev, ilev, time // example: linoz ZONAL, // file with ncol, altitude, altitude_int, time // example: elevated (at a height) emissions of aerosols and precursors // NOTE: we must rename the default vertical tags when horiz remapping // NOTE: we vert remap in a different routine in mam4xx - VERT_EMISSION, + ELEVATED_EMISSIONS, // Placeholder for cases where no file type is applicable NONE }; @@ -88,7 +88,7 @@ enum TracerDataIndex { BEG = 0, END = 1, OUT = 2 }; Therefore, if a file contains more than this number, it is acceptable to increase this limit. Currently, Linoz files have 8 fields. */ constexpr int MAX_NVARS_TRACER = 10; -constexpr int MAX_NUM_VERT_EMISSION_FIELDS = 25; +constexpr int MAX_NUM_ELEVATED_EMISSIONS_FIELDS = 25; // Linoz structures to help manage all of the variables: struct TracerTimeState { @@ -307,7 +307,7 @@ inline void setup_tracer_data(TracerData &tracer_data, // out // This type of files use altitude (zi) for vertical interpolation if(has_altitude) { nlevs_data = scorpio::get_dimlen(trace_data_file, "altitude"); - tracer_file_type = VERT_EMISSION; + tracer_file_type = ELEVATED_EMISSIONS; } EKAT_REQUIRE_MSG( nlevs_data != -1, @@ -339,7 +339,7 @@ inline void setup_tracer_data(TracerData &tracer_data, // out tracer_data.zonal_levs_ = levs; } - if(tracer_file_type == VERT_EMISSION) { + if(tracer_file_type == ELEVATED_EMISSIONS) { const int nilevs_data = scorpio::get_dimlen(trace_data_file, "altitude_int"); view_1d_host altitude_int_host("altitude_int_host", nilevs_data); @@ -448,7 +448,7 @@ inline std::shared_ptr create_tracer_data_reader( io_fields.push_back(horiz_remapper->get_src_field(i)); } const auto io_grid = horiz_remapper->get_src_grid(); - if(file_type == VERT_EMISSION ){ + if(file_type == ELEVATED_EMISSIONS ){ // NOTE: If we are using a vertical emission nc file with altitude instead of lev, // we must rename this tag. // We need to perform a shallow clone of io_grid because tags are const in this object. @@ -672,7 +672,7 @@ inline void perform_vertical_interpolation(const const_view_1d &altitude_int, const TracerData &input, const view_2d output[]) { EKAT_REQUIRE_MSG( - input.file_type == VERT_EMISSION, + input.file_type == ELEVATED_EMISSIONS, "Error! vertical interpolation only with altitude variable. \n"); const int ncols = input.ncol_; const int num_vars = input.nvars_; @@ -749,7 +749,7 @@ inline void advance_tracer_data( if(data_tracer.file_type == FORMULA_PS || data_tracer.file_type == ZONAL) { perform_vertical_interpolation(data_tracer.p_src_, p_tgt, data_tracer, output); - } else if(data_tracer.file_type == VERT_EMISSION) { + } else if(data_tracer.file_type == ELEVATED_EMISSIONS) { perform_vertical_interpolation(data_tracer.altitude_int_, zi_tgt, data_tracer, output); } From 3eb6d04c9ec31ab128a5d3544f636b5a602e0f4a Mon Sep 17 00:00:00 2001 From: Oscar Diaz-Ibarra Date: Mon, 11 Nov 2024 11:53:05 -0700 Subject: [PATCH 066/147] EAMxx - Rename variables: 'elevated_' prefix replaces 'vert_'. --- ...mxx_mam_microphysics_process_interface.cpp | 76 +++++++++---------- ...mxx_mam_microphysics_process_interface.hpp | 14 ++-- 2 files changed, 45 insertions(+), 45 deletions(-) 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 cc2cbbb2a6df..39734fadf89c 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 @@ -260,67 +260,67 @@ void MAMMicrophysics::set_grids( for(const auto &var_name : extfrc_lst_) { std::string item_name = "mam4_" + var_name + "_verti_emiss_file_name"; const auto file_name = m_params.get(item_name); - vert_emis_file_name_[var_name] = file_name; + elevated_emis_file_name_[var_name] = file_name; } - vert_emis_var_names_["so2"] = {"BB", "ENE_ELEV", "IND_ELEV", "contvolc"}; - vert_emis_var_names_["so4_a1"] = {"BB", "ENE_ELEV", "IND_ELEV", "contvolc"}; - vert_emis_var_names_["so4_a2"] = {"contvolc"}; - vert_emis_var_names_["pom_a4"] = {"BB"}; - vert_emis_var_names_["bc_a4"] = {"BB"}; - vert_emis_var_names_["num_a1"] = { + elevated_emis_var_names_["so2"] = {"BB", "ENE_ELEV", "IND_ELEV", "contvolc"}; + elevated_emis_var_names_["so4_a1"] = {"BB", "ENE_ELEV", "IND_ELEV", "contvolc"}; + elevated_emis_var_names_["so4_a2"] = {"contvolc"}; + elevated_emis_var_names_["pom_a4"] = {"BB"}; + elevated_emis_var_names_["bc_a4"] = {"BB"}; + elevated_emis_var_names_["num_a1"] = { "num_a1_SO4_ELEV_BB", "num_a1_SO4_ELEV_ENE", "num_a1_SO4_ELEV_IND", "num_a1_SO4_ELEV_contvolc"}; - vert_emis_var_names_["num_a2"] = {"num_a2_SO4_ELEV_contvolc"}; + elevated_emis_var_names_["num_a2"] = {"num_a2_SO4_ELEV_contvolc"}; // num_a4 // FIXME: why the sectors in this files are num_a1; // I guess this should be num_a4? Is this a bug in the orginal nc files? - vert_emis_var_names_["num_a4"] = {"num_a1_BC_ELEV_BB", + elevated_emis_var_names_["num_a4"] = {"num_a1_BC_ELEV_BB", "num_a1_POM_ELEV_BB"}; - vert_emis_var_names_["soag"] = {"SOAbb_src", "SOAbg_src", "SOAff_src"}; + elevated_emis_var_names_["soag"] = {"SOAbb_src", "SOAbg_src", "SOAff_src"}; - int verti_emiss_cyclical_ymd = m_params.get("verti_emiss_ymd"); + int elevated_emiss_cyclical_ymd = m_params.get("verti_emiss_ymd"); for(const auto &var_name : extfrc_lst_) { - const auto file_name = vert_emis_file_name_[var_name]; - const auto var_names = vert_emis_var_names_[var_name]; + const auto file_name = elevated_emis_file_name_[var_name]; + const auto var_names = elevated_emis_var_names_[var_name]; scream::mam_coupling::TracerData data_tracer; scream::mam_coupling::setup_tracer_data(data_tracer, file_name, - verti_emiss_cyclical_ymd); + elevated_emiss_cyclical_ymd); auto hor_rem = scream::mam_coupling::create_horiz_remapper( grid_, file_name, extfrc_map_file, var_names, data_tracer); auto file_reader = scream::mam_coupling::create_tracer_data_reader(hor_rem, file_name, data_tracer.file_type); - VertEmissionsHorizInterp_.push_back(hor_rem); - VertEmissionsDataReader_.push_back(file_reader); - vert_emis_data_.push_back(data_tracer); - } // var_name vert emissions + ElevatedEmissionsHorizInterp_.push_back(hor_rem); + ElevatedEmissionsDataReader_.push_back(file_reader); + elevated_emis_data_.push_back(data_tracer); + } // var_name elevated emissions int i = 0; int offset_emis_ver = 0; for(const auto &var_name : extfrc_lst_) { - const auto file_name = vert_emis_file_name_[var_name]; - const auto var_names = vert_emis_var_names_[var_name]; + const auto file_name = elevated_emis_file_name_[var_name]; + const auto var_names = elevated_emis_var_names_[var_name]; const int nvars = static_cast(var_names.size()); forcings_[i].nsectors = nvars; // I am assuming the order of species in extfrc_lst_. // Indexing in mam4xx is fortran. forcings_[i].frc_ndx = i + 1; - const auto io_grid_emis = VertEmissionsHorizInterp_[i]->get_tgt_grid(); + const auto io_grid_emis = ElevatedEmissionsHorizInterp_[i]->get_tgt_grid(); const int num_cols_io_emis = io_grid_emis->get_num_local_dofs(); // Number of columns on this rank const int num_levs_io_emis = io_grid_emis ->get_num_vertical_levels(); // Number of levels per column - vert_emis_data_[i].init(num_cols_io_emis, num_levs_io_emis, nvars); - vert_emis_data_[i].allocate_temporal_views(); - forcings_[i].file_alt_data = vert_emis_data_[i].has_altitude_; + elevated_emis_data_[i].init(num_cols_io_emis, num_levs_io_emis, nvars); + elevated_emis_data_[i].allocate_temporal_views(); + forcings_[i].file_alt_data = elevated_emis_data_[i].has_altitude_; for(int isp = 0; isp < nvars; ++isp) { forcings_[i].offset = offset_emis_ver; - vert_emis_output_[isp + offset_emis_ver] = - view_2d("vert_emis_output_", ncol_, nlev_); + elevated_emis_output_[isp + offset_emis_ver] = + view_2d("elevated_emis_output_", ncol_, nlev_); } offset_emis_ver += nvars; ++i; @@ -520,8 +520,8 @@ void MAMMicrophysics::initialize_impl(const RunType run_type) { for(int i = 0; i < static_cast(extfrc_lst_.size()); ++i) { scream::mam_coupling::update_tracer_data_from_file( - VertEmissionsDataReader_[i], curr_month, *VertEmissionsHorizInterp_[i], - vert_emis_data_[i]); + ElevatedEmissionsDataReader_[i], curr_month, *ElevatedEmissionsHorizInterp_[i], + elevated_emis_data_[i]); } invariants_ = view_3d("invarians", ncol_, nlev_, mam4::gas_chemistry::nfs); @@ -618,20 +618,20 @@ void MAMMicrophysics::run_impl(const double dt) { linoz_output); // out Kokkos::fence(); - vert_emiss_time_state_.t_now = ts.frac_of_year_in_days(); + elevated_emiss_time_state_.t_now = ts.frac_of_year_in_days(); int i = 0; for(const auto &var_name : extfrc_lst_) { - const auto file_name = vert_emis_file_name_[var_name]; - const auto var_names = vert_emis_var_names_[var_name]; + const auto file_name = elevated_emis_file_name_[var_name]; + const auto var_names = elevated_emis_var_names_[var_name]; const int nsectors = int(var_names.size()); - view_2d vert_emis_output[nsectors]; + view_2d elevated_emis_output[nsectors]; for(int isp = 0; isp < nsectors; ++isp) { - vert_emis_output[isp] = vert_emis_output_[isp + forcings_[i].offset]; + elevated_emis_output[isp] = elevated_emis_output_[isp + forcings_[i].offset]; } scream::mam_coupling::advance_tracer_data( - VertEmissionsDataReader_[i], *VertEmissionsHorizInterp_[i], ts, - vert_emiss_time_state_, vert_emis_data_[i], dry_atm_.p_mid, - dry_atm_.z_iface, vert_emis_output); + ElevatedEmissionsDataReader_[i], *ElevatedEmissionsHorizInterp_[i], ts, + elevated_emiss_time_state_, elevated_emis_data_[i], dry_atm_.p_mid, + dry_atm_.z_iface, elevated_emis_output); i++; Kokkos::fence(); } @@ -706,7 +706,7 @@ void MAMMicrophysics::run_impl(const double dt) { const auto zenith_angle = acos_cosine_zenith_; constexpr int gas_pcnst = mam_coupling::gas_pcnst(); - const auto& vert_emis_output = vert_emis_output_; + const auto& elevated_emis_output = elevated_emis_output_; const auto& extfrc = extfrc_; const auto& forcings = forcings_; constexpr int extcnt = mam4::gas_chemistry::extcnt; @@ -758,7 +758,7 @@ void MAMMicrophysics::run_impl(const double dt) { // We may need to move this line where we read files. forcings_in[i].file_alt_data = file_alt_data; for(int isec = 0; isec < forcings[i].nsectors; ++isec) { - const auto field = vert_emis_output[isec + forcings[i].offset]; + const auto field = elevated_emis_output[isec + forcings[i].offset]; forcings_in[i].fields_data[isec] = ekat::subview(field, icol); } } // extcnt for loop diff --git a/components/eamxx/src/physics/mam/eamxx_mam_microphysics_process_interface.hpp b/components/eamxx/src/physics/mam/eamxx_mam_microphysics_process_interface.hpp index 5ecd8c624618..6be8f3e7fb5d 100644 --- a/components/eamxx/src/physics/mam/eamxx_mam_microphysics_process_interface.hpp +++ b/components/eamxx/src/physics/mam/eamxx_mam_microphysics_process_interface.hpp @@ -225,14 +225,14 @@ class MAMMicrophysics final : public scream::AtmosphereProcess { // Vertical emission uses 9 files, here I am using std::vector to stote // instance of each file. - mam_coupling::TracerTimeState vert_emiss_time_state_; - std::vector> VertEmissionsDataReader_; - std::vector> VertEmissionsHorizInterp_; + mam_coupling::TracerTimeState elevated_emiss_time_state_; + std::vector> ElevatedEmissionsDataReader_; + std::vector> ElevatedEmissionsHorizInterp_; std::vector extfrc_lst_; - std::vector vert_emis_data_; - std::map vert_emis_file_name_; - std::map> vert_emis_var_names_; - view_2d vert_emis_output_[mam_coupling::MAX_NUM_ELEVATED_EMISSIONS_FIELDS]; + std::vector elevated_emis_data_; + std::map elevated_emis_file_name_; + std::map> elevated_emis_var_names_; + view_2d elevated_emis_output_[mam_coupling::MAX_NUM_ELEVATED_EMISSIONS_FIELDS]; view_3d extfrc_; mam_coupling::ForcingHelper forcings_[mam4::gas_chemistry::extcnt]; From a596e6bdc0f019c29d0712f8184f1a0b5efe7ad2 Mon Sep 17 00:00:00 2001 From: Oscar Diaz-Ibarra Date: Mon, 11 Nov 2024 12:04:09 -0700 Subject: [PATCH 067/147] EAMxx - Rename tag names: 'elevated' replaces 'verti' --- .../cime_config/namelist_defaults_scream.xml | 40 +++++++++---------- ...mxx_mam_microphysics_process_interface.cpp | 4 +- .../mam/aero_microphys/input.yaml | 20 +++++----- 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/components/eamxx/cime_config/namelist_defaults_scream.xml b/components/eamxx/cime_config/namelist_defaults_scream.xml index a1435b03de1c..9506cbdf3ab2 100644 --- a/components/eamxx/cime_config/namelist_defaults_scream.xml +++ b/components/eamxx/cime_config/namelist_defaults_scream.xml @@ -293,29 +293,29 @@ be lost if SCREAM_HACK_XML is not enabled. ${DIN_LOC_ROOT}/atm/scream/mam4xx/photolysis/RSF_GT200nm_v3.0_c080811.nc ${DIN_LOC_ROOT}/atm/scream/mam4xx/photolysis/temp_prs_GT200nm_JPL10_c130206.nc - - 20100101 + + 20100101 - ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/elevated/cmip6_mam4_so2_elev_1x1_2010_clim_ne30pg2_c20241008.nc - ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/elevated/cmip6_mam4_so4_a1_elev_1x1_2010_clim_ne30pg2_c20241008.nc - ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/elevated/cmip6_mam4_so4_a2_elev_1x1_2010_clim_ne30pg2_c20241008.nc - ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/elevated/cmip6_mam4_pom_a4_elev_1x1_2010_clim_ne30pg2_c20241008.nc - ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/elevated/cmip6_mam4_bc_a4_elev_1x1_2010_clim_ne30pg2_c20241008.nc - ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/elevated/cmip6_mam4_num_a1_elev_1x1_2010_clim_ne30pg2_c20241008.nc - ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/elevated/cmip6_mam4_num_a2_elev_1x1_2010_clim_ne30pg2_c20241008.nc - ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/elevated/cmip6_mam4_num_a4_elev_1x1_2010_clim_ne30pg2_c20241008.nc - ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/elevated/cmip6_mam4_soag_elev_1x1_2010_clim_ne30pg2_c20241008.nc + ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/elevated/cmip6_mam4_so2_elev_1x1_2010_clim_ne30pg2_c20241008.nc + ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/elevated/cmip6_mam4_so4_a1_elev_1x1_2010_clim_ne30pg2_c20241008.nc + ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/elevated/cmip6_mam4_so4_a2_elev_1x1_2010_clim_ne30pg2_c20241008.nc + ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/elevated/cmip6_mam4_pom_a4_elev_1x1_2010_clim_ne30pg2_c20241008.nc + ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/elevated/cmip6_mam4_bc_a4_elev_1x1_2010_clim_ne30pg2_c20241008.nc + ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/elevated/cmip6_mam4_num_a1_elev_1x1_2010_clim_ne30pg2_c20241008.nc + ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/elevated/cmip6_mam4_num_a2_elev_1x1_2010_clim_ne30pg2_c20241008.nc + ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/elevated/cmip6_mam4_num_a4_elev_1x1_2010_clim_ne30pg2_c20241008.nc + ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/elevated/cmip6_mam4_soag_elev_1x1_2010_clim_ne30pg2_c20241008.nc - ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_so2_elev_1x1_2010_clim_ne4pg2_c20241008.nc - ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_so4_a1_elev_1x1_2010_clim_ne4pg2_c20241008.nc - ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_so4_a2_elev_1x1_2010_clim_ne4pg2_c20241008.nc - ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_pom_a4_elev_1x1_2010_clim_ne4pg2_c20241008.nc - ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_bc_a4_elev_1x1_2010_clim_ne4pg2_c20241008.nc - ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_num_a1_elev_1x1_2010_clim_ne4pg2_c20241008.nc - ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_num_a2_elev_1x1_2010_clim_ne4pg2_c20241008.nc - ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_num_a4_elev_1x1_2010_clim_ne4pg2_c20241008.nc - ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_soag_elev_1x1_2010_clim_ne4pg2_c20241008.nc + ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_so2_elev_1x1_2010_clim_ne4pg2_c20241008.nc + ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_so4_a1_elev_1x1_2010_clim_ne4pg2_c20241008.nc + ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_so4_a2_elev_1x1_2010_clim_ne4pg2_c20241008.nc + ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_pom_a4_elev_1x1_2010_clim_ne4pg2_c20241008.nc + ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_bc_a4_elev_1x1_2010_clim_ne4pg2_c20241008.nc + ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_num_a1_elev_1x1_2010_clim_ne4pg2_c20241008.nc + ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_num_a2_elev_1x1_2010_clim_ne4pg2_c20241008.nc + ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_num_a4_elev_1x1_2010_clim_ne4pg2_c20241008.nc + ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_soag_elev_1x1_2010_clim_ne4pg2_c20241008.nc 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 39734fadf89c..c53052b57aec 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 @@ -258,7 +258,7 @@ void MAMMicrophysics::set_grids( "num_a1", "num_a2", "num_a4", "soag"}; for(const auto &var_name : extfrc_lst_) { - std::string item_name = "mam4_" + var_name + "_verti_emiss_file_name"; + std::string item_name = "mam4_" + var_name + "_elevated_emiss_file_name"; const auto file_name = m_params.get(item_name); elevated_emis_file_name_[var_name] = file_name; } @@ -278,7 +278,7 @@ void MAMMicrophysics::set_grids( "num_a1_POM_ELEV_BB"}; elevated_emis_var_names_["soag"] = {"SOAbb_src", "SOAbg_src", "SOAff_src"}; - int elevated_emiss_cyclical_ymd = m_params.get("verti_emiss_ymd"); + int elevated_emiss_cyclical_ymd = m_params.get("elevated_emiss_ymd"); for(const auto &var_name : extfrc_lst_) { const auto file_name = elevated_emis_file_name_[var_name]; diff --git a/components/eamxx/tests/single-process/mam/aero_microphys/input.yaml b/components/eamxx/tests/single-process/mam/aero_microphys/input.yaml index fa4538bb75a9..d4d29091df4b 100644 --- a/components/eamxx/tests/single-process/mam/aero_microphys/input.yaml +++ b/components/eamxx/tests/single-process/mam/aero_microphys/input.yaml @@ -27,16 +27,16 @@ atmosphere_processes: mam4_chlorine_loading_ymd : 20100101 mam4_rsf_file : ${SCREAM_DATA_DIR}/mam4xx/photolysis/RSF_GT200nm_v3.0_c080811.nc mam4_xs_long_file : ${SCREAM_DATA_DIR}/mam4xx/photolysis/temp_prs_GT200nm_JPL10_c130206.nc - verti_emiss_ymd : 20100101 - mam4_so2_verti_emiss_file_name : ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/elevated/cmip6_mam4_so2_elev_ne2np4_2010_clim_c20240726.nc - mam4_so4_a1_verti_emiss_file_name : ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/elevated//cmip6_mam4_so4_a1_elev_ne2np4_2010_clim_c20240823.nc - mam4_so4_a2_verti_emiss_file_name : ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/elevated//cmip6_mam4_so4_a2_elev_ne2np4_2010_clim_c20240823.nc - mam4_pom_a4_verti_emiss_file_name : ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/elevated//cmip6_mam4_pom_a4_elev_ne2np4_2010_clim_c20240823.nc - mam4_bc_a4_verti_emiss_file_name : ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/elevated/cmip6_mam4_bc_a4_elev_ne2np4_2010_clim_c20240823.nc - mam4_num_a1_verti_emiss_file_name : ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/elevated//cmip6_mam4_num_a1_elev_ne2np4_2010_clim_c20240823.nc - mam4_num_a2_verti_emiss_file_name : ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/elevated//cmip6_mam4_num_a2_elev_ne2np4_2010_clim_c20240823.nc - mam4_num_a4_verti_emiss_file_name : ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/elevated//cmip6_mam4_num_a4_elev_ne2np4_2010_clim_c20240823.nc - mam4_soag_verti_emiss_file_name : ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/elevated//cmip6_mam4_soag_elev_ne2np4_2010_clim_c20240823.nc + elevated_emiss_ymd : 20100101 + mam4_so2_elevated_emiss_file_name : ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/elevated/cmip6_mam4_so2_elev_ne2np4_2010_clim_c20240726.nc + mam4_so4_a1_elevated_emiss_file_name : ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/elevated/cmip6_mam4_so4_a1_elev_ne2np4_2010_clim_c20240823.nc + mam4_so4_a2_elevated_emiss_file_name : ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/elevated/cmip6_mam4_so4_a2_elev_ne2np4_2010_clim_c20240823.nc + mam4_pom_a4_elevated_emiss_file_name : ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/elevated/cmip6_mam4_pom_a4_elev_ne2np4_2010_clim_c20240823.nc + mam4_bc_a4_elevated_emiss_file_name : ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/elevated/cmip6_mam4_bc_a4_elev_ne2np4_2010_clim_c20240823.nc + mam4_num_a1_elevated_emiss_file_name : ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/elevated/cmip6_mam4_num_a1_elev_ne2np4_2010_clim_c20240823.nc + mam4_num_a2_elevated_emiss_file_name : ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/elevated/cmip6_mam4_num_a2_elev_ne2np4_2010_clim_c20240823.nc + mam4_num_a4_elevated_emiss_file_name : ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/elevated/cmip6_mam4_num_a4_elev_ne2np4_2010_clim_c20240823.nc + mam4_soag_elevated_emiss_file_name : ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/elevated/cmip6_mam4_soag_elev_ne2np4_2010_clim_c20240823.nc grids_manager: Type: Mesh Free From 589742d2e9ec5a28763c93c1c84aa450e0fa7db2 Mon Sep 17 00:00:00 2001 From: Oscar Diaz-Ibarra Date: Mon, 11 Nov 2024 12:23:12 -0700 Subject: [PATCH 068/147] EAMxx - Replace 'verti' with 'elevated' in tag names; add missing lines. --- .../remap_emiss_ne4_ne30/shell_commands | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/remap_emiss_ne4_ne30/shell_commands b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/remap_emiss_ne4_ne30/shell_commands index 606ca463f26c..b2d0286b8700 100644 --- a/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/remap_emiss_ne4_ne30/shell_commands +++ b/components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/remap_emiss_ne4_ne30/shell_commands @@ -8,7 +8,7 @@ $CIMEROOT/../components/eamxx/cime_config/testdefs/testmods_dirs/scream/mam4xx/update_eamxx_num_tracers.sh -b #------------------------------------------------------ -# Add aerosol microphysics process, force ne4pg2 +# Add aerosol microphysics process, force ne4pg2 # emission files and provide a ne4pg2->ne30pg2 mapping # file #------------------------------------------------------ @@ -16,15 +16,13 @@ alias ATMCHANGE='$CIMEROOT/../components/eamxx/scripts/atmchange' ATMCHANGE physics::atm_procs_list="mac_aero_mic,rrtmgp,mam4_aero_microphys" -b -ATMCHANGE mam4_aero_microphys::mam4_so2_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_so2_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b -ATMCHANGE mam4_aero_microphys::mam4_so4_a1_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_so4_a1_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b -ATMCHANGE mam4_aero_microphys::mam4_so4_a2_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_so4_a2_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b -ATMCHANGE mam4_aero_microphys::mam4_pom_a4_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_pom_a4_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b -ATMCHANGE mam4_aero_microphys::mam4_bc_a4_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_bc_a4_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b -ATMCHANGE mam4_aero_microphys::mam4_num_a1_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_num_a1_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b -ATMCHANGE mam4_aero_microphys::mam4_num_a2_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_num_a2_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b -ATMCHANGE mam4_aero_microphys::mam4_num_a4_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_num_a4_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b -ATMCHANGE mam4_aero_microphys::mam4_soag_verti_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_soag_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b +ATMCHANGE mam4_aero_microphys::mam4_so2_elevated_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_so2_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b +ATMCHANGE mam4_aero_microphys::mam4_so4_a1_elevated_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_so4_a1_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b +ATMCHANGE mam4_aero_microphys::mam4_so4_a2_elevated_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_so4_a2_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b +ATMCHANGE mam4_aero_microphys::mam4_pom_a4_elevated_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_pom_a4_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b +ATMCHANGE mam4_aero_microphys::mam4_bc_a4_elevated_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_bc_a4_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b +ATMCHANGE mam4_aero_microphys::mam4_num_a1_elevated_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_num_a1_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b +ATMCHANGE mam4_aero_microphys::mam4_num_a2_elevated_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_num_a2_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b +ATMCHANGE mam4_aero_microphys::mam4_num_a4_elevated_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_num_a4_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b +ATMCHANGE mam4_aero_microphys::mam4_soag_elevated_emiss_file_name='${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/elevated/cmip6_mam4_soag_elev_1x1_2010_clim_ne4pg2_c20241008.nc' -b ATMCHANGE mam4_aero_microphys::aero_microphys_remap_file='${DIN_LOC_ROOT}/atm/scream/maps/map_ne4pg2_to_ne30pg2_nco_c20241108.nc' -b - - From c43116be9c3863eb9bd6357dfb191b56c0581885 Mon Sep 17 00:00:00 2001 From: AaronDonahue Date: Mon, 11 Nov 2024 16:00:09 -0700 Subject: [PATCH 069/147] This commit fixes a bug in defining an int layout for hyai and hybi --- components/eamxx/src/share/grid/mesh_free_grids_manager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/eamxx/src/share/grid/mesh_free_grids_manager.cpp b/components/eamxx/src/share/grid/mesh_free_grids_manager.cpp index 446fba5229ff..b083dfcfa48b 100644 --- a/components/eamxx/src/share/grid/mesh_free_grids_manager.cpp +++ b/components/eamxx/src/share/grid/mesh_free_grids_manager.cpp @@ -147,7 +147,7 @@ add_geo_data (const nonconstgrid_ptr_type& grid) const if (geo_data_source=="CREATE_EMPTY_DATA") { using namespace ShortFieldTagsNames; FieldLayout layout_mid ({LEV},{grid->get_num_vertical_levels()}); - FieldLayout layout_int ({ILEV},{grid->get_num_vertical_levels()}); + FieldLayout layout_int ({ILEV},{grid->get_num_vertical_levels()+1}); const auto units = ekat::units::Units::nondimensional(); auto lat = grid->create_geometry_data("lat" , grid->get_2d_scalar_layout(), units); @@ -242,7 +242,7 @@ load_vertical_coordinates (const nonconstgrid_ptr_type& grid, const std::string& using namespace ekat::units; FieldLayout layout_mid ({LEV},{grid->get_num_vertical_levels()}); - FieldLayout layout_int ({ILEV},{grid->get_num_vertical_levels()}); + FieldLayout layout_int ({ILEV},{grid->get_num_vertical_levels()+1}); Units nondim = Units::nondimensional(); Units mbar (100*Pa,"mb"); From a1705ddd0710a5b17aee43904c931ab05185e560 Mon Sep 17 00:00:00 2001 From: Luca Bertagna Date: Tue, 12 Nov 2024 10:08:32 -0700 Subject: [PATCH 070/147] Update .mergify.yml List all checks individually --- .mergify.yml | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/.mergify.yml b/.mergify.yml index 6c9318ce5b6e..ce6a74d904a6 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -7,14 +7,38 @@ merge_protections: - "#approved-reviews-by >= 1" # At least 1 approval - "#changes-requested-reviews-by == 0" # No reviewer asked for changes - or: - - check-success="gcc-openmp / .*" - - check-skipped="gcc-openmp / .*" + - check-success="gcc-openmp / dbg" + - check-skipped="gcc-openmp / dbg" - or: - - check-success="gcc-cuda / .*" - - check-skipped="gcc-cuda / .*" + - check-success="gcc-openmp / sp" + - check-skipped="gcc-openmp / sp" - or: - - check-success="cpu-gcc / .*" - - check-skipped="cpu-gcc / .*" + - check-success="gcc-openmp / fpe" + - check-skipped="gcc-openmp / fpe" + - or: + - check-success="gcc-openmp / opt" + - check-skipped="gcc-openmp / opt" + - or: + - check-success="gcc-cuda / dbg" + - check-skipped="gcc-cuda / dbg" + - or: + - check-success="gcc-cuda / sp" + - check-skipped="gcc-cuda / sp" + - or: + - check-success="gcc-cuda / opt" + - check-skipped="gcc-cuda / opt" + - or: + - check-success="cpu-gcc / ERS_Ln9.ne4_ne4.F2000-SCREAMv1-AQP1.scream-output-preset-2" + - check-skipped="cpu-gcc / ERS_Ln9.ne4_ne4.F2000-SCREAMv1-AQP1.scream-output-preset-2" + - or: + - check-success="cpu-gcc / ERS_P16_Ln22.ne30pg2_ne30pg2.FIOP-SCREAMv1-DP.scream-dpxx-arm97" + - check-skipped="cpu-gcc / ERS_P16_Ln22.ne30pg2_ne30pg2.FIOP-SCREAMv1-DP.scream-dpxx-arm97" + - or: + - check-success="cpu-gcc / ERS_Ln22.ne4pg2_ne4pg2.F2010-SCREAMv1.scream-small_kernels--scream-output-preset-5" + - check-skipped="cpu-gcc / ERS_Ln22.ne4pg2_ne4pg2.F2010-SCREAMv1.scream-small_kernels--scream-output-preset-5" + - or: + - check-success="cpu-gcc / SMS_D_Ln5.ne4pg2_oQU480.F2010-SCREAMv1-MPASSI.scream-mam4xx-all_mam4xx_procs" + - check-skipped="cpu-gcc / SMS_D_Ln5.ne4pg2_oQU480.F2010-SCREAMv1-MPASSI.scream-mam4xx-all_mam4xx_procs" - or: - check-success=cpu-gcc - check-skipped=cpu-gcc From 0939ad35b71e8976b047068e0e4d3a91b9f99051 Mon Sep 17 00:00:00 2001 From: Luca Bertagna Date: Tue, 12 Nov 2024 10:32:06 -0700 Subject: [PATCH 071/147] Mergify: enable pull request automerge --- .mergify.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.mergify.yml b/.mergify.yml index ce6a74d904a6..e46f2208ed5b 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -42,3 +42,13 @@ merge_protections: - or: - check-success=cpu-gcc - check-skipped=cpu-gcc + +pull_request_rules: + - name: Automatic merge when CI passes and approved + conditions: + - check-success="Mergify Merge Protections" # Pass if merge protection rule passes + - "label=CI: automerge" + - base=master + actions: + merge: + method: merge From 035d8c2ae5a453e64ae6f20931a33aa71c39d9b3 Mon Sep 17 00:00:00 2001 From: Luca Bertagna Date: Tue, 12 Nov 2024 13:54:03 -0700 Subject: [PATCH 072/147] Mergify: set commit message for automerge --- .mergify.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.mergify.yml b/.mergify.yml index e46f2208ed5b..314459ef1c8e 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -52,3 +52,10 @@ pull_request_rules: actions: merge: method: merge + commit_message_template: | + Merge pull request #{{number}} from {{head}} + + Automatically merged using mergify + PR title: {{title}} + PR author: {{author}} + PR labels: {{label}} From b4e18d2d7fc08fd32ef1489b54726328f610f6aa Mon Sep 17 00:00:00 2001 From: Luca Bertagna Date: Tue, 12 Nov 2024 15:35:32 -0700 Subject: [PATCH 073/147] Mergify: remove redundant merge protection condition in automerge rule Mergify already includes merge protection rules inside the pull request rules --- .mergify.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.mergify.yml b/.mergify.yml index 314459ef1c8e..ee3e186f5093 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -46,7 +46,6 @@ merge_protections: pull_request_rules: - name: Automatic merge when CI passes and approved conditions: - - check-success="Mergify Merge Protections" # Pass if merge protection rule passes - "label=CI: automerge" - base=master actions: From 2bb921e202de32c9801f389d3546bd4cbfb55e62 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Wed, 13 Nov 2024 10:32:04 -0700 Subject: [PATCH 074/147] Quick fix for baseline generation The seperate small kernel testing does not need to be (and should not) run when generating baselines. --- components/eamxx/src/physics/p3/CMakeLists.txt | 2 ++ components/eamxx/src/physics/p3/tests/CMakeLists.txt | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/components/eamxx/src/physics/p3/CMakeLists.txt b/components/eamxx/src/physics/p3/CMakeLists.txt index 2a630438049d..58a026e1601a 100644 --- a/components/eamxx/src/physics/p3/CMakeLists.txt +++ b/components/eamxx/src/physics/p3/CMakeLists.txt @@ -69,6 +69,8 @@ if (SCREAM_P3_SMALL_KERNELS) add_library(p3 ${P3_SRCS} ${P3_SK_SRCS}) else() add_library(p3 ${P3_SRCS}) + # If small kernels are ON, we don't need a separate executable to test them. + # Also, we never want to generate baselines with this separate executable if (NOT SCREAM_LIBS_ONLY AND NOT SCREAM_ONLY_GENERATE_BASELINES) add_library(p3_sk ${P3_SRCS} ${P3_SK_SRCS}) # Always build p3_sk with SCREAM_P3_SMALL_KERNELS on diff --git a/components/eamxx/src/physics/p3/tests/CMakeLists.txt b/components/eamxx/src/physics/p3/tests/CMakeLists.txt index 129e3c455e26..d4fb90b1be30 100644 --- a/components/eamxx/src/physics/p3/tests/CMakeLists.txt +++ b/components/eamxx/src/physics/p3/tests/CMakeLists.txt @@ -74,7 +74,9 @@ if (SCREAM_ENABLE_BASELINE_TESTS) ${FORCE_RUN_DIFF_FAILS}) endif() -if (NOT SCREAM_P3_SMALL_KERNELS) +# If small kernels are ON, we don't need a separate executable to test them. +# Also, we never want to generate baselines with this separate executable +if (NOT SCREAM_P3_SMALL_KERNELS AND NOT SCREAM_ONLY_GENERATE_BASELINES) CreateUnitTest(p3_sk_tests "${P3_TESTS_SRCS}" LIBS p3_sk p3_test_infra EXE_ARGS "--args ${BASELINE_FILE_ARG}" From 5dc66fc292bb39d9317fe49710f8691747ff2f8d Mon Sep 17 00:00:00 2001 From: James Foucar Date: Wed, 13 Nov 2024 12:55:38 -0700 Subject: [PATCH 075/147] Fixup small kernel situation --- .../p3/disp/p3_check_values_impl_disp.cpp | 3 +-- .../physics/p3/disp/p3_cloud_sed_impl_disp.cpp | 3 +-- .../physics/p3/disp/p3_rain_sed_impl_disp.cpp | 10 +++++----- .../eamxx/src/physics/p3/tests/CMakeLists.txt | 17 +++++------------ 4 files changed, 12 insertions(+), 21 deletions(-) diff --git a/components/eamxx/src/physics/p3/disp/p3_check_values_impl_disp.cpp b/components/eamxx/src/physics/p3/disp/p3_check_values_impl_disp.cpp index cc13e99bc91d..5bac83064778 100644 --- a/components/eamxx/src/physics/p3/disp/p3_check_values_impl_disp.cpp +++ b/components/eamxx/src/physics/p3/disp/p3_check_values_impl_disp.cpp @@ -16,7 +16,7 @@ ::check_values_disp(const uview_2d& qv, const uview_2d using ExeSpace = typename KT::ExeSpace; const Int nk_pack = ekat::npack(nk); const auto policy = ekat::ExeSpaceUtils::get_default_team_policy(nj, nk_pack); - + Kokkos::parallel_for( "p3_check_values", policy, KOKKOS_LAMBDA(const MemberType& team) { @@ -32,4 +32,3 @@ ::check_values_disp(const uview_2d& qv, const uview_2d } // namespace p3 } // namespace scream - diff --git a/components/eamxx/src/physics/p3/disp/p3_cloud_sed_impl_disp.cpp b/components/eamxx/src/physics/p3/disp/p3_cloud_sed_impl_disp.cpp index 8b755be4857f..4b528663d236 100644 --- a/components/eamxx/src/physics/p3/disp/p3_cloud_sed_impl_disp.cpp +++ b/components/eamxx/src/physics/p3/disp/p3_cloud_sed_impl_disp.cpp @@ -48,7 +48,7 @@ ::cloud_sedimentation_disp( } cloud_sedimentation( - ekat::subview(qc_incld, i), ekat::subview(rho, i), ekat::subview(inv_rho, i), ekat::subview(cld_frac_l, i), + ekat::subview(qc_incld, i), ekat::subview(rho, i), ekat::subview(inv_rho, i), ekat::subview(cld_frac_l, i), ekat::subview(acn, i), ekat::subview(inv_dz, i), dnu, team, workspace, nk, ktop, kbot, kdir, dt, inv_dt, do_predict_nc, ekat::subview(qc, i), ekat::subview(nc, i), ekat::subview(nc_incld, i), ekat::subview(mu_c, i), ekat::subview(lamc, i), ekat::subview(qc_tend, i), @@ -60,4 +60,3 @@ ::cloud_sedimentation_disp( } // namespace p3 } // namespace scream - diff --git a/components/eamxx/src/physics/p3/disp/p3_rain_sed_impl_disp.cpp b/components/eamxx/src/physics/p3/disp/p3_rain_sed_impl_disp.cpp index d152313dc7fd..a1b38afe8edd 100644 --- a/components/eamxx/src/physics/p3/disp/p3_rain_sed_impl_disp.cpp +++ b/components/eamxx/src/physics/p3/disp/p3_rain_sed_impl_disp.cpp @@ -45,11 +45,11 @@ ::rain_sedimentation_disp( // Rain sedimentation: (adaptive substepping) rain_sedimentation( - ekat::subview(rho, i), ekat::subview(inv_rho, i), ekat::subview(rhofacr, i), ekat::subview(cld_frac_r, i), - ekat::subview(inv_dz, i), ekat::subview(qr_incld, i), - team, workspace, vn_table_vals, vm_table_vals, nk, ktop, kbot, kdir, dt, inv_dt, - ekat::subview(qr, i), ekat::subview(nr, i), ekat::subview(nr_incld, i), ekat::subview(mu_r, i), - ekat::subview(lamr, i), ekat::subview(precip_liq_flux, i), + ekat::subview(rho, i), ekat::subview(inv_rho, i), ekat::subview(rhofacr, i), ekat::subview(cld_frac_r, i), + ekat::subview(inv_dz, i), ekat::subview(qr_incld, i), + team, workspace, vn_table_vals, vm_table_vals, nk, ktop, kbot, kdir, dt, inv_dt, + ekat::subview(qr, i), ekat::subview(nr, i), ekat::subview(nr_incld, i), ekat::subview(mu_r, i), + ekat::subview(lamr, i), ekat::subview(precip_liq_flux, i), ekat::subview(qr_tend, i), ekat::subview(nr_tend, i), precip_liq_surf(i), runtime_options); }); diff --git a/components/eamxx/src/physics/p3/tests/CMakeLists.txt b/components/eamxx/src/physics/p3/tests/CMakeLists.txt index d4fb90b1be30..d45314ccb9c3 100644 --- a/components/eamxx/src/physics/p3/tests/CMakeLists.txt +++ b/components/eamxx/src/physics/p3/tests/CMakeLists.txt @@ -77,22 +77,15 @@ endif() # If small kernels are ON, we don't need a separate executable to test them. # Also, we never want to generate baselines with this separate executable if (NOT SCREAM_P3_SMALL_KERNELS AND NOT SCREAM_ONLY_GENERATE_BASELINES) - CreateUnitTest(p3_sk_tests "${P3_TESTS_SRCS}" + # Note: Only the p3_main test does something different when + # small kernels are on. The SK dispatch routines are mostly trivial + # and it's not worth adding tons of test infrastructure to support + # BFB unit tests for these. + CreateUnitTest(p3_sk_tests "p3_main_unit_tests.cpp" LIBS p3_sk p3_test_infra EXE_ARGS "--args ${BASELINE_FILE_ARG}" THREADS 1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC} LABELS "p3_sk;physics") - - # Make sure that a diff in the two implementation triggers a failed test (in debug only) - # No need to run lots of different thread counts. - if (SCREAM_ENABLE_BASELINE_TESTS) - CreateUnitTest (p3_sk_tests_fail p3_rain_sed_unit_tests.cpp - LIBS p3_sk p3_test_infra - EXE_ARGS "--args ${BASELINE_FILE_ARG}" - COMPILER_CXX_DEFS SCREAM_FORCE_RUN_DIFF - LABELS "p3_sk;physics;fail" - ${FORCE_RUN_DIFF_FAILS}) - endif() endif() CreateUnitTest(p3_run_and_cmp "p3_run_and_cmp.cpp" From 6318f41520e74a266ffe89ea60342372c8eb7f31 Mon Sep 17 00:00:00 2001 From: Luca Bertagna Date: Wed, 13 Nov 2024 12:26:02 -0700 Subject: [PATCH 076/147] Mergify: fix merge proteciton rule The name of skipped jobs from a matrix needed to be fixed --- .mergify.yml | 51 +++++++++++++++++++-------------------------------- 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/.mergify.yml b/.mergify.yml index ee3e186f5093..315cad81cc6c 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -7,38 +7,25 @@ merge_protections: - "#approved-reviews-by >= 1" # At least 1 approval - "#changes-requested-reviews-by == 0" # No reviewer asked for changes - or: - - check-success="gcc-openmp / dbg" - - check-skipped="gcc-openmp / dbg" - - or: - - check-success="gcc-openmp / sp" - - check-skipped="gcc-openmp / sp" - - or: - - check-success="gcc-openmp / fpe" - - check-skipped="gcc-openmp / fpe" - - or: - - check-success="gcc-openmp / opt" - - check-skipped="gcc-openmp / opt" - - or: - - check-success="gcc-cuda / dbg" - - check-skipped="gcc-cuda / dbg" - - or: - - check-success="gcc-cuda / sp" - - check-skipped="gcc-cuda / sp" - - or: - - check-success="gcc-cuda / opt" - - check-skipped="gcc-cuda / opt" - - or: - - check-success="cpu-gcc / ERS_Ln9.ne4_ne4.F2000-SCREAMv1-AQP1.scream-output-preset-2" - - check-skipped="cpu-gcc / ERS_Ln9.ne4_ne4.F2000-SCREAMv1-AQP1.scream-output-preset-2" - - or: - - check-success="cpu-gcc / ERS_P16_Ln22.ne30pg2_ne30pg2.FIOP-SCREAMv1-DP.scream-dpxx-arm97" - - check-skipped="cpu-gcc / ERS_P16_Ln22.ne30pg2_ne30pg2.FIOP-SCREAMv1-DP.scream-dpxx-arm97" - - or: - - check-success="cpu-gcc / ERS_Ln22.ne4pg2_ne4pg2.F2010-SCREAMv1.scream-small_kernels--scream-output-preset-5" - - check-skipped="cpu-gcc / ERS_Ln22.ne4pg2_ne4pg2.F2010-SCREAMv1.scream-small_kernels--scream-output-preset-5" - - or: - - check-success="cpu-gcc / SMS_D_Ln5.ne4pg2_oQU480.F2010-SCREAMv1-MPASSI.scream-mam4xx-all_mam4xx_procs" - - check-skipped="cpu-gcc / SMS_D_Ln5.ne4pg2_oQU480.F2010-SCREAMv1-MPASSI.scream-mam4xx-all_mam4xx_procs" + - and: + - check-success="gcc-openmp / dbg" + - check-success="gcc-openmp / sp" + - check-success="gcc-openmp / fpe" + - check-success="gcc-openmp / opt" + - check-skipped~="gcc-openmp / .*" + - or: + - and: + - check-success="gcc-cuda / dbg" + - check-success="gcc-cuda / sp" + - check-success="gcc-cuda / opt" + - check-skipped~="gcc-cuda / .*" + - or: + - and: + - check-success="cpu-gcc / ERS_Ln9.ne4_ne4.F2000-SCREAMv1-AQP1.scream-output-preset-2" + - check-success="cpu-gcc / ERS_P16_Ln22.ne30pg2_ne30pg2.FIOP-SCREAMv1-DP.scream-dpxx-arm97" + - check-success="cpu-gcc / ERS_Ln22.ne4pg2_ne4pg2.F2010-SCREAMv1.scream-small_kernels--scream-output-preset-5" + - check-success="cpu-gcc / SMS_D_Ln5.ne4pg2_oQU480.F2010-SCREAMv1-MPASSI.scream-mam4xx-all_mam4xx_procs" + - check-skipped~="cpu-gcc / .*" - or: - check-success=cpu-gcc - check-skipped=cpu-gcc From dfbfcfd324aee44ddd39a27b76b2c8848fe64a8c Mon Sep 17 00:00:00 2001 From: Peter Andrew Bogenschutz Date: Wed, 13 Nov 2024 13:34:33 -0800 Subject: [PATCH 077/147] make latitude absolute value in the relative checking to make it compatible for southern hemisphere cases --- components/eamxx/src/share/iop/intensive_observation_period.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eamxx/src/share/iop/intensive_observation_period.cpp b/components/eamxx/src/share/iop/intensive_observation_period.cpp index 32b120c57002..1d5f7c7ba336 100644 --- a/components/eamxx/src/share/iop/intensive_observation_period.cpp +++ b/components/eamxx/src/share/iop/intensive_observation_period.cpp @@ -270,7 +270,7 @@ initialize_iop_file(const util::TimeStamp& run_t0, scorpio::read_var(iop_file,"lon",&iop_file_lon); const Real rel_lat_err = std::fabs(iop_file_lat - m_params.get("target_latitude"))/ - std::max(m_params.get("target_latitude"),(Real)0.1); + std::max(std::fabs(m_params.get("target_latitude")),(Real)0.1); const Real rel_lon_err = std::fabs(std::fmod(iop_file_lon + 360.0, 360.0)-m_params.get("target_longitude"))/ std::max(m_params.get("target_longitude"),(Real)0.1); EKAT_REQUIRE_MSG(rel_lat_err < std::numeric_limits::epsilon(), From db5b35dbb7ccf9dda2f7c7759870945938f73aa0 Mon Sep 17 00:00:00 2001 From: Luca Bertagna Date: Wed, 13 Nov 2024 12:26:02 -0700 Subject: [PATCH 078/147] Mergify: fix merge proteciton rule The name of skipped jobs from a matrix needed to be fixed --- .mergify.yml | 51 +++++++++++++++++++-------------------------------- 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/.mergify.yml b/.mergify.yml index ee3e186f5093..9c2b8fe13f1a 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -7,38 +7,25 @@ merge_protections: - "#approved-reviews-by >= 1" # At least 1 approval - "#changes-requested-reviews-by == 0" # No reviewer asked for changes - or: - - check-success="gcc-openmp / dbg" - - check-skipped="gcc-openmp / dbg" - - or: - - check-success="gcc-openmp / sp" - - check-skipped="gcc-openmp / sp" - - or: - - check-success="gcc-openmp / fpe" - - check-skipped="gcc-openmp / fpe" - - or: - - check-success="gcc-openmp / opt" - - check-skipped="gcc-openmp / opt" - - or: - - check-success="gcc-cuda / dbg" - - check-skipped="gcc-cuda / dbg" - - or: - - check-success="gcc-cuda / sp" - - check-skipped="gcc-cuda / sp" - - or: - - check-success="gcc-cuda / opt" - - check-skipped="gcc-cuda / opt" - - or: - - check-success="cpu-gcc / ERS_Ln9.ne4_ne4.F2000-SCREAMv1-AQP1.scream-output-preset-2" - - check-skipped="cpu-gcc / ERS_Ln9.ne4_ne4.F2000-SCREAMv1-AQP1.scream-output-preset-2" - - or: - - check-success="cpu-gcc / ERS_P16_Ln22.ne30pg2_ne30pg2.FIOP-SCREAMv1-DP.scream-dpxx-arm97" - - check-skipped="cpu-gcc / ERS_P16_Ln22.ne30pg2_ne30pg2.FIOP-SCREAMv1-DP.scream-dpxx-arm97" - - or: - - check-success="cpu-gcc / ERS_Ln22.ne4pg2_ne4pg2.F2010-SCREAMv1.scream-small_kernels--scream-output-preset-5" - - check-skipped="cpu-gcc / ERS_Ln22.ne4pg2_ne4pg2.F2010-SCREAMv1.scream-small_kernels--scream-output-preset-5" - - or: - - check-success="cpu-gcc / SMS_D_Ln5.ne4pg2_oQU480.F2010-SCREAMv1-MPASSI.scream-mam4xx-all_mam4xx_procs" - - check-skipped="cpu-gcc / SMS_D_Ln5.ne4pg2_oQU480.F2010-SCREAMv1-MPASSI.scream-mam4xx-all_mam4xx_procs" + - and: + - check-success="gcc-openmp / dbg" + - check-success="gcc-openmp / sp" + - check-success="gcc-openmp / fpe" + - check-success="gcc-openmp / opt" + - check-skipped={% raw %}gcc-openmp / ${{ matrix.build_type }}{% endraw %} + - or: + - and: + - check-success="gcc-cuda / dbg" + - check-success="gcc-cuda / sp" + - check-success="gcc-cuda / opt" + - check-skipped={% raw %}gcc-cuda / ${{ matrix.build_type }}{% endraw %} + - or: + - and: + - check-success="cpu-gcc / ERS_Ln9.ne4_ne4.F2000-SCREAMv1-AQP1.scream-output-preset-2" + - check-success="cpu-gcc / ERS_P16_Ln22.ne30pg2_ne30pg2.FIOP-SCREAMv1-DP.scream-dpxx-arm97" + - check-success="cpu-gcc / ERS_Ln22.ne4pg2_ne4pg2.F2010-SCREAMv1.scream-small_kernels--scream-output-preset-5" + - check-success="cpu-gcc / SMS_D_Ln5.ne4pg2_oQU480.F2010-SCREAMv1-MPASSI.scream-mam4xx-all_mam4xx_procs" + - check-skipped={% raw %}cpu-gcc / ${{ matrix.test.short_name }}{% endraw %} - or: - check-success=cpu-gcc - check-skipped=cpu-gcc From b7211bd09f8b368a86227dbb390b21f0078854cf Mon Sep 17 00:00:00 2001 From: Peter Andrew Bogenschutz Date: Wed, 13 Nov 2024 15:56:01 -0800 Subject: [PATCH 079/147] add option to prescribe an invariant solar constant --- .../eamxx/cime_config/namelist_defaults_scream.xml | 5 +++++ .../physics/rrtmgp/eamxx_rrtmgp_process_interface.cpp | 10 ++++++++++ .../physics/rrtmgp/eamxx_rrtmgp_process_interface.hpp | 5 +++++ 3 files changed, 20 insertions(+) diff --git a/components/eamxx/cime_config/namelist_defaults_scream.xml b/components/eamxx/cime_config/namelist_defaults_scream.xml index 9506cbdf3ab2..4ab040a194b0 100644 --- a/components/eamxx/cime_config/namelist_defaults_scream.xml +++ b/components/eamxx/cime_config/namelist_defaults_scream.xml @@ -495,6 +495,11 @@ be lost if SCREAM_HACK_XML is not enabled. 0.0 -9999.0 0.0 + + + -9999.0 + 551.58 + 1 2 4 diff --git a/components/eamxx/src/physics/rrtmgp/eamxx_rrtmgp_process_interface.cpp b/components/eamxx/src/physics/rrtmgp/eamxx_rrtmgp_process_interface.cpp index 758baa80b7d8..1634473b9f8d 100644 --- a/components/eamxx/src/physics/rrtmgp/eamxx_rrtmgp_process_interface.cpp +++ b/components/eamxx/src/physics/rrtmgp/eamxx_rrtmgp_process_interface.cpp @@ -620,6 +620,10 @@ void RRTMGPRadiation::initialize_impl(const RunType /* run_type */) { m_orbital_obliq = m_params.get("orbital_obliquity" ,-9999); m_orbital_mvelp = m_params.get("orbital_mvelp" ,-9999); + // Value for prescribing an invariant solar constant (i.e. total solar irradiance at + // TOA). Used for idealized experiments such as RCE. Disabled when value is less than 0. + m_fixed_total_solar_irradiance = m_params.get("fixed_total_solar_irradiance", -9999); + // Determine whether or not we are using a fixed solar zenith angle (positive value) m_fixed_solar_zenith_angle = m_params.get("Fixed Solar Zenith Angle", -9999); @@ -823,6 +827,7 @@ void RRTMGPRadiation::run_impl (const double dt) { auto eccen = m_orbital_eccen; auto obliq = m_orbital_obliq; auto mvelp = m_orbital_mvelp; + auto fixed_total_solar_irradiance = m_fixed_total_solar_irradiance; if (eccen >= 0 && obliq >= 0 && mvelp >= 0) { // use fixed orbital parameters; to force this, we need to set // orbital_year to SHR_ORB_UNDEF_INT, which is exposed through @@ -840,6 +845,11 @@ void RRTMGPRadiation::run_impl (const double dt) { shr_orb_decl_c2f(calday, eccen, mvelpp, lambm0, obliqr, &delta, &eccf); + // Overwrite eccf if using a fixed solar constant. + if (fixed_total_solar_irradiance >= 0){ + eccf = fixed_total_solar_irradiance/1360.9; + } + // Precompute VMR for all gases, on all cols, before starting the chunks loop // // h2o is taken from qv diff --git a/components/eamxx/src/physics/rrtmgp/eamxx_rrtmgp_process_interface.hpp b/components/eamxx/src/physics/rrtmgp/eamxx_rrtmgp_process_interface.hpp index 329c7eeaba8d..02a047cce598 100644 --- a/components/eamxx/src/physics/rrtmgp/eamxx_rrtmgp_process_interface.hpp +++ b/components/eamxx/src/physics/rrtmgp/eamxx_rrtmgp_process_interface.hpp @@ -95,6 +95,11 @@ class RRTMGPRadiation : public AtmosphereProcess { Real m_orbital_obliq; // Obliquity Real m_orbital_mvelp; // Vernal Equinox Mean Longitude of Perihelion + // Value for prescribing an invariant solar constant (i.e. total solar irradiance + // at TOA). Used for idealized experiments such as RCE. This is only used when a + // positive value is supplied. + Real m_fixed_total_solar_irradiance; + // Fixed solar zenith angle to use for shortwave calculations // This is only used if a positive value is supplied Real m_fixed_solar_zenith_angle; From 50815e27dd000745d273ef8da91fdfb9d3cbdd04 Mon Sep 17 00:00:00 2001 From: Peter Andrew Bogenschutz Date: Wed, 13 Nov 2024 16:01:02 -0800 Subject: [PATCH 080/147] move placement of line where fixed solar irradiance is defined --- .../eamxx/src/physics/rrtmgp/eamxx_rrtmgp_process_interface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eamxx/src/physics/rrtmgp/eamxx_rrtmgp_process_interface.cpp b/components/eamxx/src/physics/rrtmgp/eamxx_rrtmgp_process_interface.cpp index 1634473b9f8d..0709bb1a37ff 100644 --- a/components/eamxx/src/physics/rrtmgp/eamxx_rrtmgp_process_interface.cpp +++ b/components/eamxx/src/physics/rrtmgp/eamxx_rrtmgp_process_interface.cpp @@ -827,7 +827,6 @@ void RRTMGPRadiation::run_impl (const double dt) { auto eccen = m_orbital_eccen; auto obliq = m_orbital_obliq; auto mvelp = m_orbital_mvelp; - auto fixed_total_solar_irradiance = m_fixed_total_solar_irradiance; if (eccen >= 0 && obliq >= 0 && mvelp >= 0) { // use fixed orbital parameters; to force this, we need to set // orbital_year to SHR_ORB_UNDEF_INT, which is exposed through @@ -846,6 +845,7 @@ void RRTMGPRadiation::run_impl (const double dt) { obliqr, &delta, &eccf); // Overwrite eccf if using a fixed solar constant. + auto fixed_total_solar_irradiance = m_fixed_total_solar_irradiance; if (fixed_total_solar_irradiance >= 0){ eccf = fixed_total_solar_irradiance/1360.9; } From 8e72936483027815eddc124c97316e4191232192 Mon Sep 17 00:00:00 2001 From: Oscar Diaz-Ibarra Date: Mon, 11 Nov 2024 20:10:50 -0700 Subject: [PATCH 081/147] EAMxx: Interface for reading file and setting index_season_lai --- ...mxx_mam_microphysics_process_interface.cpp | 9 +++ ...mxx_mam_microphysics_process_interface.hpp | 4 ++ .../mam/readfiles/find_season_index_utils.hpp | 62 +++++++++++++++++++ externals/mam4xx | 2 +- 4 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 components/eamxx/src/physics/mam/readfiles/find_season_index_utils.hpp 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 c53052b57aec..a284178a8b31 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 @@ -3,6 +3,7 @@ // impl namespace for some driver level functions for microphysics #include "readfiles/photo_table_utils.cpp" +#include "readfiles/find_season_index_utils.hpp" #include "physics/rrtmgp/shr_orb_mod_c2f.hpp" namespace scream { @@ -332,6 +333,14 @@ void MAMMicrophysics::set_grids( "MAX_NUM_ELEVATED_EMISSIONS_FIELDS in tracer_reader_utils.hpp \n"); } // Tracer external forcing data + + { + std::string season_wes_file ="season_wes.nc"; + const auto& clat = col_latitudes_; + mam_coupling::find_season_index_reader(season_wes_file, + clat, + index_season_lai_); + } } // set_grids // ================================================================ diff --git a/components/eamxx/src/physics/mam/eamxx_mam_microphysics_process_interface.hpp b/components/eamxx/src/physics/mam/eamxx_mam_microphysics_process_interface.hpp index 6be8f3e7fb5d..d555fe820242 100644 --- a/components/eamxx/src/physics/mam/eamxx_mam_microphysics_process_interface.hpp +++ b/components/eamxx/src/physics/mam/eamxx_mam_microphysics_process_interface.hpp @@ -25,6 +25,8 @@ class MAMMicrophysics final : public scream::AtmosphereProcess { using view_1d_host = typename KT::view_1d::HostMirror; + using view_int_2d = typename KT::template view_2d; + // a thread team dispatched to a single vertical column using ThreadTeam = mam4::ThreadTeam; @@ -239,6 +241,8 @@ class MAMMicrophysics final : public scream::AtmosphereProcess { view_1d_host acos_cosine_zenith_host_; view_1d acos_cosine_zenith_; + view_int_2d index_season_lai_; + }; // MAMMicrophysics } // namespace scream diff --git a/components/eamxx/src/physics/mam/readfiles/find_season_index_utils.hpp b/components/eamxx/src/physics/mam/readfiles/find_season_index_utils.hpp new file mode 100644 index 000000000000..70f743b23769 --- /dev/null +++ b/components/eamxx/src/physics/mam/readfiles/find_season_index_utils.hpp @@ -0,0 +1,62 @@ +#ifndef EAMXX_MAM_FIND_SEASON_INDEX_UTILS +#define EAMXX_MAM_FIND_SEASON_INDEX_UTILS + +#include +#include "share/io/scorpio_input.hpp" +#include "share/io/scream_scorpio_interface.hpp" +#include + +namespace scream::mam_coupling { + +using ExeSpace = typename KT::ExeSpace; +using ESU = ekat::ExeSpaceUtils; + +// views for single- and multi-column data +using view_1d = typename KT::template view_1d; +using const_view_1d = typename KT::template view_1d; + +using view_int_1d = typename KT::template view_1d; +using view_int_2d = typename KT::template view_2d; +using view_int_3d = typename KT::template view_3d; + +using view_1d_host = typename KT::view_1d::HostMirror; +using view_3d_host = typename KT::view_3d::HostMirror; +using view_int_3d_host = typename KT::view_3d::HostMirror; + + +inline void find_season_index_reader(const std::string& season_wes_file, + const const_view_1d& clat, + view_int_2d &index_season_lai) +{ + const int plon= clat.extent(0); + scorpio::register_file(season_wes_file, scorpio::Read); + + const int nlat_lai = scorpio::get_dimlen(season_wes_file, "lat"); + const int npft_lai = scorpio::get_dimlen(season_wes_file, "pft"); + view_1d_host lat_lai_host("lat_lai_host", nlat_lai); + view_int_3d_host wk_lai_host("wk_lai_host", nlat_lai, npft_lai, 12); + + scorpio::read_var(season_wes_file, "lat", lat_lai_host.data()); + scorpio::read_var(season_wes_file, "season_wes", wk_lai_host.data()); + scorpio::release_file(season_wes_file); + + view_int_3d wk_lai("wk_lai", nlat_lai, npft_lai, 12); + + view_1d lat_lai("lat_lai", nlat_lai); + Kokkos::deep_copy(lat_lai, lat_lai_host); + Kokkos::deep_copy(wk_lai, wk_lai_host); + + // output + index_season_lai=view_int_2d("index_season_lai", plon,12); + const auto policy = ESU::get_default_team_policy(plon, 1); + Kokkos::parallel_for( + policy, KOKKOS_LAMBDA(const Team &team) { + const int j = team.league_rank(); + const auto index_season_lai_at_j = ekat::subview(index_season_lai, j); + mam4::mo_drydep::find_season_index(clat(j), lat_lai, nlat_lai, wk_lai, + index_season_lai_at_j); + }); +} + +} // namespace scream::mam_coupling +#endif // diff --git a/externals/mam4xx b/externals/mam4xx index aae46807bf58..5e21c26f0662 160000 --- a/externals/mam4xx +++ b/externals/mam4xx @@ -1 +1 @@ -Subproject commit aae46807bf58d6ffcbc6db620c27568450b2d040 +Subproject commit 5e21c26f0662641cfd6522d5e96315f67cd7a4b4 From 79cb356562f29c049175ffb51555bf9cd348a9b3 Mon Sep 17 00:00:00 2001 From: Oscar Diaz-Ibarra Date: Wed, 13 Nov 2024 09:45:12 -0700 Subject: [PATCH 082/147] Use host version for find_season_index and add function description --- .../mam/readfiles/find_season_index_utils.hpp | 67 ++++++++++++------- externals/mam4xx | 2 +- 2 files changed, 43 insertions(+), 26 deletions(-) diff --git a/components/eamxx/src/physics/mam/readfiles/find_season_index_utils.hpp b/components/eamxx/src/physics/mam/readfiles/find_season_index_utils.hpp index 70f743b23769..c7778b744213 100644 --- a/components/eamxx/src/physics/mam/readfiles/find_season_index_utils.hpp +++ b/components/eamxx/src/physics/mam/readfiles/find_season_index_utils.hpp @@ -12,17 +12,22 @@ using ExeSpace = typename KT::ExeSpace; using ESU = ekat::ExeSpaceUtils; // views for single- and multi-column data -using view_1d = typename KT::template view_1d; -using const_view_1d = typename KT::template view_1d; -using view_int_1d = typename KT::template view_1d; +using const_view_1d = typename KT::template view_1d; using view_int_2d = typename KT::template view_2d; -using view_int_3d = typename KT::template view_3d; using view_1d_host = typename KT::view_1d::HostMirror; using view_3d_host = typename KT::view_3d::HostMirror; using view_int_3d_host = typename KT::view_3d::HostMirror; +using view_int_2d_host = typename KT::view_2d::HostMirror; +/** + * @brief Reads the season index from the given file and computes the season indices based on latitudes. + * + * @param[in] season_wes_file The path to the season_wes.nc file. + * @param[in] clat A 1D view of latitude values in degrees. + * @param[out] index_season_lai A 2D view to store the computed season indices. Note that indices are in C++ (starting from zero). + */ inline void find_season_index_reader(const std::string& season_wes_file, const const_view_1d& clat, @@ -33,30 +38,42 @@ inline void find_season_index_reader(const std::string& season_wes_file, const int nlat_lai = scorpio::get_dimlen(season_wes_file, "lat"); const int npft_lai = scorpio::get_dimlen(season_wes_file, "pft"); - view_1d_host lat_lai_host("lat_lai_host", nlat_lai); - view_int_3d_host wk_lai_host("wk_lai_host", nlat_lai, npft_lai, 12); - scorpio::read_var(season_wes_file, "lat", lat_lai_host.data()); - scorpio::read_var(season_wes_file, "season_wes", wk_lai_host.data()); - scorpio::release_file(season_wes_file); + view_1d_host lat_lai("lat_lai", nlat_lai); + view_int_2d_host wk_lai_temp("wk_lai", npft_lai, nlat_lai); + view_int_3d_host wk_lai("wk_lai", nlat_lai, npft_lai, 12); - view_int_3d wk_lai("wk_lai", nlat_lai, npft_lai, 12); - - view_1d lat_lai("lat_lai", nlat_lai); - Kokkos::deep_copy(lat_lai, lat_lai_host); - Kokkos::deep_copy(wk_lai, wk_lai_host); - - // output - index_season_lai=view_int_2d("index_season_lai", plon,12); - const auto policy = ESU::get_default_team_policy(plon, 1); - Kokkos::parallel_for( - policy, KOKKOS_LAMBDA(const Team &team) { - const int j = team.league_rank(); - const auto index_season_lai_at_j = ekat::subview(index_season_lai, j); - mam4::mo_drydep::find_season_index(clat(j), lat_lai, nlat_lai, wk_lai, - index_season_lai_at_j); + scorpio::read_var(season_wes_file, "lat", lat_lai.data()); + + Kokkos::MDRangePolicy> + policy_wk_lai({0, 0}, {nlat_lai, npft_lai}); + + // loop over time to get all 12 instantence of season_wes + for (int itime = 0; itime < 12; ++itime) + { + scorpio::read_var(season_wes_file, "season_wes", wk_lai_temp.data(),itime); + // copy data from wk_lai_temp to wk_lai. + // NOTE: season_wes has different layout that wk_lai + Kokkos::parallel_for("copy_to_wk_lai", policy_wk_lai, + [&](const int j, const int k) { + wk_lai(j, k, itime) = wk_lai_temp(k, j); }); -} + Kokkos::fence(); + } + scorpio::release_file(season_wes_file); + + index_season_lai =view_int_2d("index_season_lai", plon, 12); + const view_int_2d_host index_season_lai_host= Kokkos::create_mirror_view(index_season_lai); + + const view_1d_host clat_host= Kokkos::create_mirror_view(clat); + Kokkos::deep_copy(clat_host, clat); + // Computation is performed on the host + mam4::mo_drydep::find_season_index(clat_host, lat_lai, nlat_lai, wk_lai, + index_season_lai_host); + Kokkos::deep_copy(index_season_lai, index_season_lai_host); + + +} } // namespace scream::mam_coupling #endif // diff --git a/externals/mam4xx b/externals/mam4xx index 5e21c26f0662..d6cb4c004a68 160000 --- a/externals/mam4xx +++ b/externals/mam4xx @@ -1 +1 @@ -Subproject commit 5e21c26f0662641cfd6522d5e96315f67cd7a4b4 +Subproject commit d6cb4c004a686664dc9d5885837f69c46be2f611 From a97a7730dad27dde08fb313440c368afa8c298e1 Mon Sep 17 00:00:00 2001 From: Oscar Diaz-Ibarra Date: Wed, 13 Nov 2024 11:39:41 -0700 Subject: [PATCH 083/147] EAMxx: Obtain season_wes_file from input file and use MAM4xx main branch --- components/eamxx/cime_config/namelist_defaults_scream.xml | 2 ++ .../physics/mam/eamxx_mam_microphysics_process_interface.cpp | 2 +- .../eamxx/tests/single-process/mam/aero_microphys/input.yaml | 2 +- externals/mam4xx | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/components/eamxx/cime_config/namelist_defaults_scream.xml b/components/eamxx/cime_config/namelist_defaults_scream.xml index 9506cbdf3ab2..195f46847ef2 100644 --- a/components/eamxx/cime_config/namelist_defaults_scream.xml +++ b/components/eamxx/cime_config/namelist_defaults_scream.xml @@ -295,6 +295,8 @@ be lost if SCREAM_HACK_XML is not enabled. ${DIN_LOC_ROOT}/atm/scream/mam4xx/photolysis/temp_prs_GT200nm_JPL10_c130206.nc 20100101 + + ${DIN_LOC_ROOT}/atm/scream/mam4xx/drydep/season_wes.nc ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/elevated/cmip6_mam4_so2_elev_1x1_2010_clim_ne30pg2_c20241008.nc ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/elevated/cmip6_mam4_so4_a1_elev_1x1_2010_clim_ne30pg2_c20241008.nc 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 a284178a8b31..57eaf9275483 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 @@ -335,7 +335,7 @@ void MAMMicrophysics::set_grids( } // Tracer external forcing data { - std::string season_wes_file ="season_wes.nc"; + const std::string season_wes_file = m_params.get("mam4_season_wes_file"); const auto& clat = col_latitudes_; mam_coupling::find_season_index_reader(season_wes_file, clat, diff --git a/components/eamxx/tests/single-process/mam/aero_microphys/input.yaml b/components/eamxx/tests/single-process/mam/aero_microphys/input.yaml index d4d29091df4b..9348a04a21d9 100644 --- a/components/eamxx/tests/single-process/mam/aero_microphys/input.yaml +++ b/components/eamxx/tests/single-process/mam/aero_microphys/input.yaml @@ -37,7 +37,7 @@ atmosphere_processes: mam4_num_a2_elevated_emiss_file_name : ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/elevated/cmip6_mam4_num_a2_elev_ne2np4_2010_clim_c20240823.nc mam4_num_a4_elevated_emiss_file_name : ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/elevated/cmip6_mam4_num_a4_elev_ne2np4_2010_clim_c20240823.nc mam4_soag_elevated_emiss_file_name : ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/elevated/cmip6_mam4_soag_elev_ne2np4_2010_clim_c20240823.nc - + mam4_season_wes_file : ${SCREAM_DATA_DIR}/mam4xx/drydep/season_wes.nc grids_manager: Type: Mesh Free geo_data_source: IC_FILE diff --git a/externals/mam4xx b/externals/mam4xx index d6cb4c004a68..4431bbd1eef4 160000 --- a/externals/mam4xx +++ b/externals/mam4xx @@ -1 +1 @@ -Subproject commit d6cb4c004a686664dc9d5885837f69c46be2f611 +Subproject commit 4431bbd1eef46de25be3a04e7091c9255bd0b819 From 1f9563a722ff4e72f1c8dd93012b7c13b4646f4b Mon Sep 17 00:00:00 2001 From: Oscar Diaz-Ibarra Date: Wed, 13 Nov 2024 11:44:09 -0700 Subject: [PATCH 084/147] EAMxx: apply clang format to find_season_index_utils.hpp. --- .../mam/readfiles/find_season_index_utils.hpp | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/components/eamxx/src/physics/mam/readfiles/find_season_index_utils.hpp b/components/eamxx/src/physics/mam/readfiles/find_season_index_utils.hpp index c7778b744213..2550673bd9ca 100644 --- a/components/eamxx/src/physics/mam/readfiles/find_season_index_utils.hpp +++ b/components/eamxx/src/physics/mam/readfiles/find_season_index_utils.hpp @@ -2,9 +2,10 @@ #define EAMXX_MAM_FIND_SEASON_INDEX_UTILS #include +#include + #include "share/io/scorpio_input.hpp" #include "share/io/scream_scorpio_interface.hpp" -#include namespace scream::mam_coupling { @@ -13,27 +14,28 @@ using ESU = ekat::ExeSpaceUtils; // views for single- and multi-column data -using const_view_1d = typename KT::template view_1d; -using view_int_2d = typename KT::template view_2d; +using const_view_1d = typename KT::template view_1d; +using view_int_2d = typename KT::template view_2d; -using view_1d_host = typename KT::view_1d::HostMirror; -using view_3d_host = typename KT::view_3d::HostMirror; +using view_1d_host = typename KT::view_1d::HostMirror; +using view_3d_host = typename KT::view_3d::HostMirror; using view_int_3d_host = typename KT::view_3d::HostMirror; using view_int_2d_host = typename KT::view_2d::HostMirror; /** - * @brief Reads the season index from the given file and computes the season indices based on latitudes. + * @brief Reads the season index from the given file and computes the season + * indices based on latitudes. * * @param[in] season_wes_file The path to the season_wes.nc file. * @param[in] clat A 1D view of latitude values in degrees. - * @param[out] index_season_lai A 2D view to store the computed season indices. Note that indices are in C++ (starting from zero). + * @param[out] index_season_lai A 2D view to store the computed season indices. + * Note that indices are in C++ (starting from zero). */ -inline void find_season_index_reader(const std::string& season_wes_file, - const const_view_1d& clat, - view_int_2d &index_season_lai) -{ - const int plon= clat.extent(0); +inline void find_season_index_reader(const std::string &season_wes_file, + const const_view_1d &clat, + view_int_2d &index_season_lai) { + const int plon = clat.extent(0); scorpio::register_file(season_wes_file, scorpio::Read); const int nlat_lai = scorpio::get_dimlen(season_wes_file, "lat"); @@ -46,34 +48,32 @@ inline void find_season_index_reader(const std::string& season_wes_file, scorpio::read_var(season_wes_file, "lat", lat_lai.data()); Kokkos::MDRangePolicy> - policy_wk_lai({0, 0}, {nlat_lai, npft_lai}); + policy_wk_lai({0, 0}, {nlat_lai, npft_lai}); // loop over time to get all 12 instantence of season_wes - for (int itime = 0; itime < 12; ++itime) - { - scorpio::read_var(season_wes_file, "season_wes", wk_lai_temp.data(),itime); - // copy data from wk_lai_temp to wk_lai. - // NOTE: season_wes has different layout that wk_lai - Kokkos::parallel_for("copy_to_wk_lai", policy_wk_lai, - [&](const int j, const int k) { - wk_lai(j, k, itime) = wk_lai_temp(k, j); - }); - Kokkos::fence(); + for(int itime = 0; itime < 12; ++itime) { + scorpio::read_var(season_wes_file, "season_wes", wk_lai_temp.data(), itime); + // copy data from wk_lai_temp to wk_lai. + // NOTE: season_wes has different layout that wk_lai + Kokkos::parallel_for("copy_to_wk_lai", policy_wk_lai, + [&](const int j, const int k) { + wk_lai(j, k, itime) = wk_lai_temp(k, j); + }); + Kokkos::fence(); } scorpio::release_file(season_wes_file); - index_season_lai =view_int_2d("index_season_lai", plon, 12); - const view_int_2d_host index_season_lai_host= Kokkos::create_mirror_view(index_season_lai); + index_season_lai = view_int_2d("index_season_lai", plon, 12); + const view_int_2d_host index_season_lai_host = + Kokkos::create_mirror_view(index_season_lai); - const view_1d_host clat_host= Kokkos::create_mirror_view(clat); + const view_1d_host clat_host = Kokkos::create_mirror_view(clat); Kokkos::deep_copy(clat_host, clat); // Computation is performed on the host mam4::mo_drydep::find_season_index(clat_host, lat_lai, nlat_lai, wk_lai, - index_season_lai_host); + index_season_lai_host); Kokkos::deep_copy(index_season_lai, index_season_lai_host); - - } } // namespace scream::mam_coupling #endif // From 0d1fdc3448ca4d76b0c2fc344520de36a2cebd66 Mon Sep 17 00:00:00 2001 From: Oscar Diaz-Ibarra Date: Wed, 13 Nov 2024 13:21:52 -0700 Subject: [PATCH 085/147] EAMxx: Obtain season_wes.nc file. --- .../eamxx/tests/single-process/mam/aero_microphys/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/components/eamxx/tests/single-process/mam/aero_microphys/CMakeLists.txt b/components/eamxx/tests/single-process/mam/aero_microphys/CMakeLists.txt index e1ba85a685ff..6f6f8b364b8a 100644 --- a/components/eamxx/tests/single-process/mam/aero_microphys/CMakeLists.txt +++ b/components/eamxx/tests/single-process/mam/aero_microphys/CMakeLists.txt @@ -39,6 +39,7 @@ set (TEST_INPUT_FILES scream/mam4xx/emissions/ne2np4/elevated/cmip6_mam4_num_a2_elev_ne2np4_2010_clim_c20240823.nc scream/mam4xx/emissions/ne2np4/elevated/cmip6_mam4_num_a4_elev_ne2np4_2010_clim_c20240823.nc scream/mam4xx/emissions/ne2np4/elevated/cmip6_mam4_soag_elev_ne2np4_2010_clim_c20240823.nc + scream/mam4xx/drydep/season_wes.nc ) foreach (file IN ITEMS ${TEST_INPUT_FILES}) GetInputFile(${file}) From 9fbdbb39e864b46c108b35d068c729060e7840d9 Mon Sep 17 00:00:00 2001 From: Oscar Diaz-Ibarra Date: Wed, 13 Nov 2024 16:22:28 -0700 Subject: [PATCH 086/147] EAMxx: remove unused code. --- .../src/physics/mam/readfiles/find_season_index_utils.hpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/components/eamxx/src/physics/mam/readfiles/find_season_index_utils.hpp b/components/eamxx/src/physics/mam/readfiles/find_season_index_utils.hpp index 2550673bd9ca..2e930cc65cbf 100644 --- a/components/eamxx/src/physics/mam/readfiles/find_season_index_utils.hpp +++ b/components/eamxx/src/physics/mam/readfiles/find_season_index_utils.hpp @@ -9,16 +9,12 @@ namespace scream::mam_coupling { -using ExeSpace = typename KT::ExeSpace; -using ESU = ekat::ExeSpaceUtils; - // views for single- and multi-column data using const_view_1d = typename KT::template view_1d; using view_int_2d = typename KT::template view_2d; using view_1d_host = typename KT::view_1d::HostMirror; -using view_3d_host = typename KT::view_3d::HostMirror; using view_int_3d_host = typename KT::view_3d::HostMirror; using view_int_2d_host = typename KT::view_2d::HostMirror; From a9850ad7484c9c4088cfd93838df109fc52a0750 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Thu, 14 Nov 2024 11:24:40 -0700 Subject: [PATCH 087/147] Fixes for p3 tests CMake settings p3_tests needs to have baseline_gen label. Also, avoid doing thread spreads when generating. --- .../eamxx/src/physics/p3/tests/CMakeLists.txt | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/components/eamxx/src/physics/p3/tests/CMakeLists.txt b/components/eamxx/src/physics/p3/tests/CMakeLists.txt index d45314ccb9c3..9d2b2419c971 100644 --- a/components/eamxx/src/physics/p3/tests/CMakeLists.txt +++ b/components/eamxx/src/physics/p3/tests/CMakeLists.txt @@ -50,18 +50,23 @@ endif() if (SCREAM_ENABLE_BASELINE_TESTS) if (SCREAM_ONLY_GENERATE_BASELINES) set(BASELINE_FILE_ARG "-g -b ${SCREAM_BASELINES_DIR}/data") + # We don't want to do thread spreads when generating. That + # could cause race conditions in the file system. + set(P3_THREADS "${SCREAM_TEST_MAX_THREADS}") else() set(BASELINE_FILE_ARG "-c -b ${SCREAM_BASELINES_DIR}/data") + set(P3_THREADS "1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC}") endif() else() set(BASELINE_FILE_ARG "-n") # no baselines + set(P3_THREADS "1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC}") endif() CreateUnitTest(p3_tests "${P3_TESTS_SRCS}" LIBS p3 p3_test_infra EXE_ARGS "--args ${BASELINE_FILE_ARG}" - THREADS 1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC} - LABELS "p3;physics") + THREADS ${P3_THREADS} + LABELS "p3;physics;baseline_gen;baseline_cmp") # Make sure that a diff in the two implementation triggers a failed test (in debug only) # No need to run lots of different thread counts. @@ -85,15 +90,16 @@ if (NOT SCREAM_P3_SMALL_KERNELS AND NOT SCREAM_ONLY_GENERATE_BASELINES) LIBS p3_sk p3_test_infra EXE_ARGS "--args ${BASELINE_FILE_ARG}" THREADS 1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC} - LABELS "p3_sk;physics") + LABELS "p3_sk;physics;baseline_cmp") endif() +# Note: the baseline_gen label label is really only used if SCREAM_ONLY_GENERATE_BASELINES=ON, but no harm adding it CreateUnitTest(p3_run_and_cmp "p3_run_and_cmp.cpp" LIBS p3 p3_test_infra EXCLUDE_MAIN_CPP THREADS ${SCREAM_TEST_MAX_THREADS} EXE_ARGS "${BASELINE_FILE_ARG}" - LABELS "p3;physics") + LABELS "p3;physics;baseline_gen;baseline_cmp") # Make sure that a diff from baselines triggers a failed test (in debug only) if (SCREAM_ENABLE_BASELINE_TESTS) @@ -106,11 +112,3 @@ if (SCREAM_ENABLE_BASELINE_TESTS) EXCLUDE_MAIN_CPP ${FORCE_RUN_DIFF_FAILS}) endif() - -# Note: the baseline_gen label label is really only used if SCREAM_ONLY_GENERATE_BASELINES=ON, but no harm adding it -if (SCREAM_TEST_MAX_THREADS GREATER 1) - # ECUT only adds _ompX if we have more than one value of X, or if X>1 - set (TEST_SUFFIX _omp${SCREAM_TEST_MAX_THREADS}) -endif() - -set_tests_properties (p3_run_and_cmp${TEST_SUFFIX} PROPERTIES LABELS "baseline_gen;cxx baseline_cmp") From d86865e814ca6031063ac0ef3aa9a7e7fa7e8946 Mon Sep 17 00:00:00 2001 From: James Foucar Date: Thu, 14 Nov 2024 11:30:51 -0700 Subject: [PATCH 088/147] Fix threads arg --- components/eamxx/src/physics/p3/tests/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/eamxx/src/physics/p3/tests/CMakeLists.txt b/components/eamxx/src/physics/p3/tests/CMakeLists.txt index 9d2b2419c971..d705b30cc4e1 100644 --- a/components/eamxx/src/physics/p3/tests/CMakeLists.txt +++ b/components/eamxx/src/physics/p3/tests/CMakeLists.txt @@ -55,11 +55,11 @@ if (SCREAM_ENABLE_BASELINE_TESTS) set(P3_THREADS "${SCREAM_TEST_MAX_THREADS}") else() set(BASELINE_FILE_ARG "-c -b ${SCREAM_BASELINES_DIR}/data") - set(P3_THREADS "1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC}") + set(P3_THREADS 1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC}) endif() else() set(BASELINE_FILE_ARG "-n") # no baselines - set(P3_THREADS "1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC}") + set(P3_THREADS 1 ${SCREAM_TEST_MAX_THREADS} ${SCREAM_TEST_THREAD_INC}) endif() CreateUnitTest(p3_tests "${P3_TESTS_SRCS}" From 6ce5b69e4a7fa02c2efb25efaade26e0827728ca Mon Sep 17 00:00:00 2001 From: James Foucar Date: Thu, 14 Nov 2024 14:05:19 -0700 Subject: [PATCH 089/147] Turn YAKL back on by default for now --- components/eamxx/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/eamxx/CMakeLists.txt b/components/eamxx/CMakeLists.txt index 5a7149234a5f..07c3cda76728 100644 --- a/components/eamxx/CMakeLists.txt +++ b/components/eamxx/CMakeLists.txt @@ -212,8 +212,8 @@ endif() # #cmakedefine RRTMGP_EXPENSIVE_CHECKS option (SCREAM_RRTMGP_DEBUG "Turn on extra debug checks in RRTMGP" ${SCREAM_DEBUG}) -option(SCREAM_RRTMGP_ENABLE_YAKL "Use YAKL under rrtmgp" FALSE) -option(SCREAM_RRTMGP_ENABLE_KOKKOS "Use Kokkos under rrtmgp" TRUE) +option(SCREAM_RRTMGP_ENABLE_YAKL "Use YAKL under rrtmgp" TRUE) +option(SCREAM_RRTMGP_ENABLE_KOKKOS "Use Kokkos under rrtmgp" FALSE) if (SCREAM_RRTMGP_ENABLE_YAKL) add_definitions("-DRRTMGP_ENABLE_YAKL") endif() From f83702325bec771ec711bbe7c12f77dbeb88e40f Mon Sep 17 00:00:00 2001 From: James Foucar Date: Thu, 14 Nov 2024 16:04:03 -0700 Subject: [PATCH 090/147] Remove some debugging stuff --- components/eamxx/CMakeLists.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/components/eamxx/CMakeLists.txt b/components/eamxx/CMakeLists.txt index 9b6f54e5b056..07c3cda76728 100644 --- a/components/eamxx/CMakeLists.txt +++ b/components/eamxx/CMakeLists.txt @@ -200,9 +200,6 @@ option(SCREAM_MPI_ON_DEVICE "Whether to use device pointers for MPI calls" ON) option(SCREAM_ENABLE_MAM "Whether to enable MAM aerosol support" ON) set(SCREAM_SMALL_KERNELS ${DEFAULT_SMALL_KERNELS} CACHE STRING "Use small, non-monolothic kokkos kernels for ALL components that support them") set(SCREAM_P3_SMALL_KERNELS ${SCREAM_SMALL_KERNELS} CACHE STRING "Use small, non-monolothic kokkos kernels for P3 only") -message("JGF DEFAUL_SMALL_KERNELS is ${DEFAULT_SMALL_KERNELS}") -message("JGF SCREAM_SMALL_KERNELS is ${SCREAM_SMALL_KERNELS}") -message("JGF SCREAM_P3_SMALL_KERNELS is ${SCREAM_P3_SMALL_KERNELS}") set(SCREAM_SHOC_SMALL_KERNELS ${SCREAM_SMALL_KERNELS} CACHE STRING "Use small, non-monolothic kokkos kernels for SHOC only") if (NOT SCREAM_P3_SMALL_KERNELS AND NOT SCREAM_SHOC_SMALL_KERNELS) set(EKAT_DISABLE_WORKSPACE_SHARING TRUE CACHE STRING "") From 03ab7123b68663846ecd738d512d3587b3a09226 Mon Sep 17 00:00:00 2001 From: Naser Mahfouz Date: Thu, 14 Nov 2024 18:16:14 -0500 Subject: [PATCH 091/147] typo in links in eamxx docs --- components/eamxx/docs/developer/kokkos_ekat.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/components/eamxx/docs/developer/kokkos_ekat.md b/components/eamxx/docs/developer/kokkos_ekat.md index 2432290a67a0..a736384b2c6b 100644 --- a/components/eamxx/docs/developer/kokkos_ekat.md +++ b/components/eamxx/docs/developer/kokkos_ekat.md @@ -56,8 +56,9 @@ where - `DataType`: scalar type of the view, given as `ScalarType`+`*`(x's number of run-time dimensions). E.g., a 2D view of doubles will have `DataType = double**`. There is also an ability to define compile-time dimensions by - using `[]`, see [Kokkos wiki section on views]( - wiki/API/core/view/view.html). + using `[]`, see + [Kokkos wiki section on views] + (). - `LayoutType`: mapping of indices into the underlying 1D memory storage. Types are: - `LayoutRight` (used in EAMxx): strides increase from the right most to the From 235493640b26533d6af8f812f23c8f1117ade2cd Mon Sep 17 00:00:00 2001 From: Luca Bertagna Date: Thu, 14 Nov 2024 11:11:56 -0700 Subject: [PATCH 092/147] EAMxx: change ghci-snl-cuda specs Grab number of gpus without hard-coding it --- components/eamxx/scripts/machines_specs.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/eamxx/scripts/machines_specs.py b/components/eamxx/scripts/machines_specs.py index 41d09f4683e8..66026191e051 100644 --- a/components/eamxx/scripts/machines_specs.py +++ b/components/eamxx/scripts/machines_specs.py @@ -221,9 +221,10 @@ class GHCISNLCuda(Machine): concrete = True @classmethod def setup(cls): - super().setup_base(name="ghci-snl-cuda",num_bld_res=16,num_run_res=1) + super().setup_base(name="ghci-snl-cuda") cls.baselines_dir = "/projects/e3sm/baselines/scream/ghci-snl-cuda" cls.gpu_arch = "cuda" + cls.num_run_res = int(run_cmd_no_fail("nvidia-smi --query-gpu=name --format=csv,noheader | wc -l")) ############################################################################### class Lassen(Machine): From 93a99aac5856d9dc3dab5d67d4a81c631e5f60e2 Mon Sep 17 00:00:00 2001 From: Luca Bertagna Date: Thu, 14 Nov 2024 11:12:18 -0700 Subject: [PATCH 093/147] Workflows: get Cuda arch from nvidia-smi in eamxx-sa-XYZ.yml --- .github/workflows/eamxx-sa-coverage.yml | 34 +++++++++++++++++++++++- .github/workflows/eamxx-sa-sanitizer.yml | 34 +++++++++++++++++++++++- .github/workflows/eamxx-sa-testing.yml | 34 +++++++++++++++++++++++- 3 files changed, 99 insertions(+), 3 deletions(-) diff --git a/.github/workflows/eamxx-sa-coverage.yml b/.github/workflows/eamxx-sa-coverage.yml index aa69d6263e6e..1904b8e58df2 100644 --- a/.github/workflows/eamxx-sa-coverage.yml +++ b/.github/workflows/eamxx-sa-coverage.yml @@ -48,6 +48,38 @@ jobs: submodules: recursive - name: Show action trigger uses: ./.github/actions/show-workflow-trigger + - name: Get CUDA Arch + run: | + # Ensure nvidia-smi is available + if ! command -v nvidia-smi &> /dev/null; then + echo "nvidia-smi could not be found. Please ensure you have Nvidia drivers installed." + exit 1 + fi + + # Get the GPU model from nvidia-smi + gpu_model=$(nvidia-smi --query-gpu=name --format=csv,noheader | head -n 1) + case "$gpu_model" in + *"H100"*) + Hopper=ON + ARCH=90 + ;; + *"A100"*) + Amper=ON + ARCH=80 + ;; + *"V100"*) + Volta=ON + ARCH=70 + ;; + *) + echo "Unsupported GPU model: $gpu_model" + exit 1 + ;; + esac + + # Set the output variables for the next step + echo "KOKKOS_ARCH=${KOKKOS_ARCH}" >> $GITHUB_ENV + echo "CMAKE_CUDA_ARCHITECTURES=${CMAKE_CUDA_ARCHITECTURES}" >> $GITHUB_ENV - name: Run tests uses: ./.github/actions/test-all-scream with: @@ -55,4 +87,4 @@ jobs: machine: ghci-snl-cuda generate: false submit: ${{ env.submit }} - cmake-configs: Kokkos_ARCH_VOLTA70=ON;CMAKE_CUDA_ARCHITECTURES=70 + cmake-configs: Kokkos_ARCH_HOPPER90=${{ env.Hopper }};Kokkos_ARCH_AMPERE80=${{ env.Ampere }};Kokkos_ARCH_VOLTA70=${{ env.Volta }};CMAKE_CUDA_ARCHITECTURES=${{ env.ARCH }} diff --git a/.github/workflows/eamxx-sa-sanitizer.yml b/.github/workflows/eamxx-sa-sanitizer.yml index 7e3a1a49fcfb..77b44d447f3f 100644 --- a/.github/workflows/eamxx-sa-sanitizer.yml +++ b/.github/workflows/eamxx-sa-sanitizer.yml @@ -52,6 +52,38 @@ jobs: submodules: recursive - name: Show action trigger uses: ./.github/actions/show-workflow-trigger + - name: Get CUDA Arch + run: | + # Ensure nvidia-smi is available + if ! command -v nvidia-smi &> /dev/null; then + echo "nvidia-smi could not be found. Please ensure you have Nvidia drivers installed." + exit 1 + fi + + # Get the GPU model from nvidia-smi + gpu_model=$(nvidia-smi --query-gpu=name --format=csv,noheader | head -n 1) + case "$gpu_model" in + *"H100"*) + Hopper=ON + ARCH=90 + ;; + *"A100"*) + Amper=ON + ARCH=80 + ;; + *"V100"*) + Volta=ON + ARCH=70 + ;; + *) + echo "Unsupported GPU model: $gpu_model" + exit 1 + ;; + esac + + # Set the output variables for the next step + echo "KOKKOS_ARCH=${KOKKOS_ARCH}" >> $GITHUB_ENV + echo "CMAKE_CUDA_ARCHITECTURES=${CMAKE_CUDA_ARCHITECTURES}" >> $GITHUB_ENV - name: Run tests uses: ./.github/actions/test-all-scream with: @@ -59,4 +91,4 @@ jobs: machine: ghci-snl-cuda generate: false submit: ${{ env.submit }} - cmake-configs: Kokkos_ARCH_VOLTA70=ON;CMAKE_CUDA_ARCHITECTURES=70 + cmake-configs: Kokkos_ARCH_HOPPER90=${{ env.Hopper }};Kokkos_ARCH_AMPERE80=${{ env.Ampere }};Kokkos_ARCH_VOLTA70=${{ env.Volta }};CMAKE_CUDA_ARCHITECTURES=${{ env.ARCH }} diff --git a/.github/workflows/eamxx-sa-testing.yml b/.github/workflows/eamxx-sa-testing.yml index baa1508ea6ce..22b8e1e360f9 100644 --- a/.github/workflows/eamxx-sa-testing.yml +++ b/.github/workflows/eamxx-sa-testing.yml @@ -172,6 +172,38 @@ jobs: echo "generate=true" >> $GITHUB_ENV fi fi + - name: Get CUDA Arch + run: | + # Ensure nvidia-smi is available + if ! command -v nvidia-smi &> /dev/null; then + echo "nvidia-smi could not be found. Please ensure you have Nvidia drivers installed." + exit 1 + fi + + # Get the GPU model from nvidia-smi + gpu_model=$(nvidia-smi --query-gpu=name --format=csv,noheader | head -n 1) + case "$gpu_model" in + *"H100"*) + Hopper=ON + ARCH=90 + ;; + *"A100"*) + Amper=ON + ARCH=80 + ;; + *"V100"*) + Volta=ON + ARCH=70 + ;; + *) + echo "Unsupported GPU model: $gpu_model" + exit 1 + ;; + esac + + # Set the output variables for the next step + echo "KOKKOS_ARCH=${KOKKOS_ARCH}" >> $GITHUB_ENV + echo "CMAKE_CUDA_ARCHITECTURES=${CMAKE_CUDA_ARCHITECTURES}" >> $GITHUB_ENV - name: Run tests uses: ./.github/actions/test-all-scream with: @@ -179,4 +211,4 @@ jobs: machine: ghci-snl-cuda generate: ${{ env.generate }} submit: ${{ env.submit }} - cmake-configs: Kokkos_ARCH_VOLTA70=ON;CMAKE_CUDA_ARCHITECTURES=70 + cmake-configs: Kokkos_ARCH_HOPPER90=${{ env.Hopper }};Kokkos_ARCH_AMPERE80=${{ env.Ampere }};Kokkos_ARCH_VOLTA70=${{ env.Volta }};CMAKE_CUDA_ARCHITECTURES=${{ env.ARCH }} From 4625182ff5d486311469fb12aa6ec2f933618f2b Mon Sep 17 00:00:00 2001 From: Luca Bertagna Date: Thu, 14 Nov 2024 21:59:07 -0700 Subject: [PATCH 094/147] Workflows: fetch changed files in chunks There are page size limits when using rest API --- .github/workflows/eamxx-sa-testing.yml | 19 ++++++++++++++++--- .github/workflows/eamxx-scripts-tests.yml | 19 ++++++++++++++++--- .github/workflows/eamxx-v1-testing.yml | 19 ++++++++++++++++--- 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/.github/workflows/eamxx-sa-testing.yml b/.github/workflows/eamxx-sa-testing.yml index baa1508ea6ce..88cd5e17a9e4 100644 --- a/.github/workflows/eamxx-sa-testing.yml +++ b/.github/workflows/eamxx-sa-testing.yml @@ -62,9 +62,22 @@ jobs: pattern=$(IFS=\|; echo "${paths[*]}") # Use the GitHub API to get the list of changed files - response=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ - "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.number }}/files") - changed_files=$(echo "$response" | grep -o '"filename": *"[^"]*"' | sed 's/"filename": *//; s/"//g') + # There are page size limits, so do it in chunks + page=1 + while true; do + response=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + "https://api.github.com/repos/E3SM-Project/scream/pulls/${{ github.event.number }}/files?per_page=100&page=$page") + + # Check if the response is empty, and break if it is + [ -z "$response" ] && break + + changed_files+=$(echo "$response" | grep -o '"filename": *"[^"]*"' | sed 's/"filename": *//; s/"//g')$'\n' + + # Check if there are more pages, and quite if there aren't + [[ $(echo "$response" | jq '. | length') -lt 100 ]] && break + + page=$((page + 1)) + done # Check for matches and echo the matching files (or "" if none) matching_files=$(echo "$changed_files" | grep -E "^($pattern)" || echo "") diff --git a/.github/workflows/eamxx-scripts-tests.yml b/.github/workflows/eamxx-scripts-tests.yml index 8de453de3879..52d856f84598 100644 --- a/.github/workflows/eamxx-scripts-tests.yml +++ b/.github/workflows/eamxx-scripts-tests.yml @@ -41,9 +41,22 @@ jobs: pattern=$(IFS=\|; echo "${paths[*]}") # Use the GitHub API to get the list of changed files - response=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ - "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.number }}/files") - changed_files=$(echo "$response" | grep -o '"filename": *"[^"]*"' | sed 's/"filename": *//; s/"//g') + # There are page size limits, so do it in chunks + page=1 + while true; do + response=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + "https://api.github.com/repos/E3SM-Project/scream/pulls/${{ github.event.number }}/files?per_page=100&page=$page") + + # Check if the response is empty, and break if it is + [ -z "$response" ] && break + + changed_files+=$(echo "$response" | grep -o '"filename": *"[^"]*"' | sed 's/"filename": *//; s/"//g')$'\n' + + # Check if there are more pages, and quite if there aren't + [[ $(echo "$response" | jq '. | length') -lt 100 ]] && break + + page=$((page + 1)) + done # Check for matches and echo the matching files (or "" if none) matching_files=$(echo "$changed_files" | grep -E "^($pattern)" || echo "") diff --git a/.github/workflows/eamxx-v1-testing.yml b/.github/workflows/eamxx-v1-testing.yml index 43cc7623f882..d55ed8252a50 100644 --- a/.github/workflows/eamxx-v1-testing.yml +++ b/.github/workflows/eamxx-v1-testing.yml @@ -54,9 +54,22 @@ jobs: pattern=$(IFS=\|; echo "${paths[*]}") # Use the GitHub API to get the list of changed files - response=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ - "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.number }}/files") - changed_files=$(echo "$response" | grep -o '"filename": *"[^"]*"' | sed 's/"filename": *//; s/"//g') + # There are page size limits, so do it in chunks + page=1 + while true; do + response=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + "https://api.github.com/repos/E3SM-Project/scream/pulls/${{ github.event.number }}/files?per_page=100&page=$page") + + # Check if the response is empty, and break if it is + [ -z "$response" ] && break + + changed_files+=$(echo "$response" | grep -o '"filename": *"[^"]*"' | sed 's/"filename": *//; s/"//g')$'\n' + + # Check if there are more pages, and quite if there aren't + [[ $(echo "$response" | jq '. | length') -lt 100 ]] && break + + page=$((page + 1)) + done # Check for matches and echo the matching files (or "" if none) matching_files=$(echo "$changed_files" | grep -E "^($pattern)" || echo "") From 0f2c4ba917473374f727e4a527d85005bf8cdc6e Mon Sep 17 00:00:00 2001 From: Luca Bertagna Date: Thu, 14 Nov 2024 22:18:55 -0700 Subject: [PATCH 095/147] Workflows: fix job name --- .github/workflows/eamxx-sa-sanitizer.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/eamxx-sa-sanitizer.yml b/.github/workflows/eamxx-sa-sanitizer.yml index 7e3a1a49fcfb..14195e7ba3a8 100644 --- a/.github/workflows/eamxx-sa-sanitizer.yml +++ b/.github/workflows/eamxx-sa-sanitizer.yml @@ -18,7 +18,7 @@ env: jobs: gcc-openmp: runs-on: [self-hosted, ghci-snl-cpu, gcc] - name: gcc-openmp / cov + name: gcc-openmp / valg steps: - name: Check out the repository uses: actions/checkout@v4 From 49d89f96e773cf7165f92c552d2afb6636dfac30 Mon Sep 17 00:00:00 2001 From: Luca Bertagna Date: Fri, 15 Nov 2024 10:16:41 -0700 Subject: [PATCH 096/147] Workflows: fix detection of CUDA arch in eamxx-sa workflows --- .github/workflows/eamxx-sa-coverage.yml | 19 ++++++++----------- .github/workflows/eamxx-sa-sanitizer.yml | 19 ++++++++----------- .github/workflows/eamxx-sa-testing.yml | 19 ++++++++----------- 3 files changed, 24 insertions(+), 33 deletions(-) diff --git a/.github/workflows/eamxx-sa-coverage.yml b/.github/workflows/eamxx-sa-coverage.yml index 1904b8e58df2..6e767021c5ee 100644 --- a/.github/workflows/eamxx-sa-coverage.yml +++ b/.github/workflows/eamxx-sa-coverage.yml @@ -56,30 +56,27 @@ jobs: exit 1 fi - # Get the GPU model from nvidia-smi + # Get the GPU model from nvidia-smi, and set env for next step gpu_model=$(nvidia-smi --query-gpu=name --format=csv,noheader | head -n 1) case "$gpu_model" in *"H100"*) - Hopper=ON + echo "Hopper=ON" >> $GITHUB_ENV + echo "CUDA_ARCH=90" >> $GITHUB_ENV ARCH=90 ;; *"A100"*) - Amper=ON - ARCH=80 + echo "Ampere=ON" >> $GITHUB_ENV + echo "CUDA_ARCH=80" >> $GITHUB_ENV ;; *"V100"*) - Volta=ON - ARCH=70 + echo "Volta=ON" >> $GITHUB_ENV + echo "CUDA_ARCH=70" >> $GITHUB_ENV ;; *) echo "Unsupported GPU model: $gpu_model" exit 1 ;; esac - - # Set the output variables for the next step - echo "KOKKOS_ARCH=${KOKKOS_ARCH}" >> $GITHUB_ENV - echo "CMAKE_CUDA_ARCHITECTURES=${CMAKE_CUDA_ARCHITECTURES}" >> $GITHUB_ENV - name: Run tests uses: ./.github/actions/test-all-scream with: @@ -87,4 +84,4 @@ jobs: machine: ghci-snl-cuda generate: false submit: ${{ env.submit }} - cmake-configs: Kokkos_ARCH_HOPPER90=${{ env.Hopper }};Kokkos_ARCH_AMPERE80=${{ env.Ampere }};Kokkos_ARCH_VOLTA70=${{ env.Volta }};CMAKE_CUDA_ARCHITECTURES=${{ env.ARCH }} + cmake-configs: Kokkos_ARCH_HOPPER90=${{ env.Hopper }};Kokkos_ARCH_AMPERE80=${{ env.Ampere }};Kokkos_ARCH_VOLTA70=${{ env.Volta }};CMAKE_CUDA_ARCHITECTURES=${{ env.CUDA_ARCH }} diff --git a/.github/workflows/eamxx-sa-sanitizer.yml b/.github/workflows/eamxx-sa-sanitizer.yml index 77b44d447f3f..2800716e88cd 100644 --- a/.github/workflows/eamxx-sa-sanitizer.yml +++ b/.github/workflows/eamxx-sa-sanitizer.yml @@ -60,30 +60,27 @@ jobs: exit 1 fi - # Get the GPU model from nvidia-smi + # Get the GPU model from nvidia-smi, and set env for next step gpu_model=$(nvidia-smi --query-gpu=name --format=csv,noheader | head -n 1) case "$gpu_model" in *"H100"*) - Hopper=ON + echo "Hopper=ON" >> $GITHUB_ENV + echo "CUDA_ARCH=90" >> $GITHUB_ENV ARCH=90 ;; *"A100"*) - Amper=ON - ARCH=80 + echo "Ampere=ON" >> $GITHUB_ENV + echo "CUDA_ARCH=80" >> $GITHUB_ENV ;; *"V100"*) - Volta=ON - ARCH=70 + echo "Volta=ON" >> $GITHUB_ENV + echo "CUDA_ARCH=70" >> $GITHUB_ENV ;; *) echo "Unsupported GPU model: $gpu_model" exit 1 ;; esac - - # Set the output variables for the next step - echo "KOKKOS_ARCH=${KOKKOS_ARCH}" >> $GITHUB_ENV - echo "CMAKE_CUDA_ARCHITECTURES=${CMAKE_CUDA_ARCHITECTURES}" >> $GITHUB_ENV - name: Run tests uses: ./.github/actions/test-all-scream with: @@ -91,4 +88,4 @@ jobs: machine: ghci-snl-cuda generate: false submit: ${{ env.submit }} - cmake-configs: Kokkos_ARCH_HOPPER90=${{ env.Hopper }};Kokkos_ARCH_AMPERE80=${{ env.Ampere }};Kokkos_ARCH_VOLTA70=${{ env.Volta }};CMAKE_CUDA_ARCHITECTURES=${{ env.ARCH }} + cmake-configs: Kokkos_ARCH_HOPPER90=${{ env.Hopper }};Kokkos_ARCH_AMPERE80=${{ env.Ampere }};Kokkos_ARCH_VOLTA70=${{ env.Volta }};CMAKE_CUDA_ARCHITECTURES=${{ env.CUDA_ARCH }} diff --git a/.github/workflows/eamxx-sa-testing.yml b/.github/workflows/eamxx-sa-testing.yml index 22b8e1e360f9..901ba87fcd5a 100644 --- a/.github/workflows/eamxx-sa-testing.yml +++ b/.github/workflows/eamxx-sa-testing.yml @@ -180,30 +180,27 @@ jobs: exit 1 fi - # Get the GPU model from nvidia-smi + # Get the GPU model from nvidia-smi, and set env for next step gpu_model=$(nvidia-smi --query-gpu=name --format=csv,noheader | head -n 1) case "$gpu_model" in *"H100"*) - Hopper=ON + echo "Hopper=ON" >> $GITHUB_ENV + echo "CUDA_ARCH=90" >> $GITHUB_ENV ARCH=90 ;; *"A100"*) - Amper=ON - ARCH=80 + echo "Ampere=ON" >> $GITHUB_ENV + echo "CUDA_ARCH=80" >> $GITHUB_ENV ;; *"V100"*) - Volta=ON - ARCH=70 + echo "Volta=ON" >> $GITHUB_ENV + echo "CUDA_ARCH=70" >> $GITHUB_ENV ;; *) echo "Unsupported GPU model: $gpu_model" exit 1 ;; esac - - # Set the output variables for the next step - echo "KOKKOS_ARCH=${KOKKOS_ARCH}" >> $GITHUB_ENV - echo "CMAKE_CUDA_ARCHITECTURES=${CMAKE_CUDA_ARCHITECTURES}" >> $GITHUB_ENV - name: Run tests uses: ./.github/actions/test-all-scream with: @@ -211,4 +208,4 @@ jobs: machine: ghci-snl-cuda generate: ${{ env.generate }} submit: ${{ env.submit }} - cmake-configs: Kokkos_ARCH_HOPPER90=${{ env.Hopper }};Kokkos_ARCH_AMPERE80=${{ env.Ampere }};Kokkos_ARCH_VOLTA70=${{ env.Volta }};CMAKE_CUDA_ARCHITECTURES=${{ env.ARCH }} + cmake-configs: Kokkos_ARCH_HOPPER90=${{ env.Hopper }};Kokkos_ARCH_AMPERE80=${{ env.Ampere }};Kokkos_ARCH_VOLTA70=${{ env.Volta }};CMAKE_CUDA_ARCHITECTURES=${{ env.CUDA_ARCH }} From b2e02ea9f16b09cc11cc0bf7f45d91603aa21d6b Mon Sep 17 00:00:00 2001 From: Luca Bertagna Date: Fri, 15 Nov 2024 10:28:58 -0700 Subject: [PATCH 097/147] Workflows: allow to force cdash submission via workflow_dispatch for eamxx --- .github/workflows/eamxx-sa-coverage.yml | 8 +++++++- .github/workflows/eamxx-sa-sanitizer.yml | 8 +++++++- .github/workflows/eamxx-sa-testing.yml | 7 ++++++- .github/workflows/eamxx-scripts-tests.yml | 11 ++++++++++- 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/.github/workflows/eamxx-sa-coverage.yml b/.github/workflows/eamxx-sa-coverage.yml index 6e767021c5ee..46e87f8b8b0c 100644 --- a/.github/workflows/eamxx-sa-coverage.yml +++ b/.github/workflows/eamxx-sa-coverage.yml @@ -2,6 +2,11 @@ name: eamxx-sa-coverage on: workflow_dispatch: + inputs: + submit: + description: 'Force cdash submission' + required: true + type: boolean # Add schedule trigger for nightly runs at midnight MT (Standard Time) schedule: @@ -13,7 +18,8 @@ concurrency: cancel-in-progress: true env: - submit: ${{ github.event_name == 'schedule' && 'true' || 'false' }} # Submit to cdash only for nightlies + # Submit to cdash only for nightlies or if the user explicitly forced a submission via workflow dispatch + submit: ${{ github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.submit) }} jobs: gcc-openmp: diff --git a/.github/workflows/eamxx-sa-sanitizer.yml b/.github/workflows/eamxx-sa-sanitizer.yml index 2800716e88cd..7684f076341d 100644 --- a/.github/workflows/eamxx-sa-sanitizer.yml +++ b/.github/workflows/eamxx-sa-sanitizer.yml @@ -2,6 +2,11 @@ name: eamxx-sa-sanitizer on: workflow_dispatch: + inputs: + submit: + description: 'Force cdash submission' + required: true + type: boolean # Add schedule trigger for nightly runs at midnight MT (Standard Time) schedule: @@ -13,7 +18,8 @@ concurrency: cancel-in-progress: true env: - submit: ${{ github.event_name == 'schedule' && 'true' || 'false' }} # Submit to cdash only for nightlies + # Submit to cdash only for nightlies or if the user explicitly forced a submission via workflow dispatch + submit: ${{ github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.submit) }} jobs: gcc-openmp: diff --git a/.github/workflows/eamxx-sa-testing.yml b/.github/workflows/eamxx-sa-testing.yml index 901ba87fcd5a..831a9e6fc693 100644 --- a/.github/workflows/eamxx-sa-testing.yml +++ b/.github/workflows/eamxx-sa-testing.yml @@ -21,6 +21,10 @@ on: description: 'Generate baselines' required: true type: boolean + submit: + description: 'Force cdash submission' + required: true + type: boolean # Add schedule trigger for nightly runs at midnight MT (Standard Time) schedule: @@ -34,7 +38,8 @@ concurrency: cancel-in-progress: true env: - submit: ${{ github.event_name == 'schedule' && 'true' || 'false' }} # Submit to cdash only for nightlies + # Submit to cdash only for nightlies or if the user explicitly forced a submission via workflow dispatch + submit: ${{ github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.submit) }} jobs: pre_process_pr: diff --git a/.github/workflows/eamxx-scripts-tests.yml b/.github/workflows/eamxx-scripts-tests.yml index 8de453de3879..860f75fa93c2 100644 --- a/.github/workflows/eamxx-scripts-tests.yml +++ b/.github/workflows/eamxx-scripts-tests.yml @@ -8,6 +8,11 @@ on: # Manual run for debug purposes only workflow_dispatch: + inputs: + submit: + description: 'Force cdash submission' + required: true + type: boolean # Add schedule trigger for nightly runs at midnight MT (Standard Time) schedule: @@ -20,6 +25,10 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +env: + # Submit to cdash only for nightlies or if the user explicitly forced a submission via workflow dispatch + submit: ${{ github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.submit) }} + jobs: pre_process_pr: if: ${{ github.event_name == 'pull_request' }} @@ -83,7 +92,7 @@ jobs: - name: Run test run: | cd components/eamxx - if [ ${{ github.event_name == 'schedule' }} ]; then + if [ "${{ env.submit }}" == "true" ]; then ./scripts/scripts-ctest-driver -s -m ghci-snl-cpu else ./scripts/scripts-tests -f -m ghci-snl-cpu From 9673d6bddd699d8c5987a18720f8e5fea9309bf6 Mon Sep 17 00:00:00 2001 From: Michael J Schmidt Date: Tue, 10 Sep 2024 01:17:58 -0600 Subject: [PATCH 098/147] emissions interface--running and calling mam4xx. next diagnose error --- ...and_online_emissions_process_interface.cpp | 131 ++++++++++++------ ...and_online_emissions_process_interface.hpp | 33 +++-- .../eamxx/src/physics/mam/online_emission.hpp | 102 ++++++++++++++ .../src/physics/mam/online_emission_impl.hpp | 60 ++++++++ .../single-process/mam/emissions/input.yaml | 28 ++-- 5 files changed, 293 insertions(+), 61 deletions(-) create mode 100644 components/eamxx/src/physics/mam/online_emission.hpp create mode 100644 components/eamxx/src/physics/mam/online_emission_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 850a82d0896d..7f85e9310807 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 @@ -19,11 +19,11 @@ MAMSrfOnlineEmiss::MAMSrfOnlineEmiss(const ekat::Comm &comm, // ================================================================ void MAMSrfOnlineEmiss::set_grids( const std::shared_ptr grids_manager) { - grid_ = grids_manager->get_grid("Physics"); + grid_ = grids_manager->get_grid("Physics"); const auto &grid_name = grid_->name(); - ncol_ = grid_->get_num_local_dofs(); // Number of columns on this rank - nlev_ = grid_->get_num_vertical_levels(); // Number of levels per column + ncol_ = grid_->get_num_local_dofs(); // Number of columns on this rank + nlev_ = grid_->get_num_vertical_levels(); // Number of levels per column using namespace ekat::units; @@ -49,20 +49,21 @@ void MAMSrfOnlineEmiss::set_grids( //-------------------------------------------------------------------- srf_emiss_ dms; // File name, name and sectors - dms.data_file = m_params.get("srf_emis_specifier_for_DMS"); + dms.data_file = m_params.get("srf_emis_specifier_for_DMS"); dms.species_name = "dms"; - dms.sectors = {"DMS"}; - srf_emiss_species_.push_back(dms); // add to the vector + dms.sectors = {"DMS"}; + srf_emiss_species_.push_back(dms); // add to the vector //-------------------------------------------------------------------- // Init so2 srf emiss data structures //-------------------------------------------------------------------- srf_emiss_ so2; // File name, name and sectors - so2.data_file = m_params.get("srf_emis_specifier_for_SO2"); + so2.data_file = m_params.get("srf_emis_specifier_for_SO2"); so2.species_name = "so2"; - so2.sectors = {"AGR", "RCO", "SHP", "SLV", "TRA", "WST"}; - srf_emiss_species_.push_back(so2); // add to the vector + so2.sectors = {"AGR", "RCO", "SHP", "SLV", "TRA", "WST"}; + srf_emiss_species_.push_back(so2); // add to the vector + //-------------------------------------------------------------------- // Init bc_a4 srf emiss data structures //-------------------------------------------------------------------- @@ -70,8 +71,8 @@ void MAMSrfOnlineEmiss::set_grids( // File name, name and sectors bc_a4.data_file = m_params.get("srf_emis_specifier_for_bc_a4"); bc_a4.species_name = "bc_a4"; - bc_a4.sectors = {"AGR", "ENE", "IND", "RCO", "SHP", "SLV", "TRA", "WST"}; - srf_emiss_species_.push_back(bc_a4); // add to the vector + bc_a4.sectors = {"AGR", "ENE", "IND", "RCO", "SHP", "SLV", "TRA", "WST"}; + srf_emiss_species_.push_back(bc_a4); // add to the vector //-------------------------------------------------------------------- // Init num_a1 srf emiss data structures @@ -80,9 +81,9 @@ void MAMSrfOnlineEmiss::set_grids( // File name, name and sectors num_a1.data_file = m_params.get("srf_emis_specifier_for_num_a1"); num_a1.species_name = "num_a1"; - num_a1.sectors = {"num_a1_SO4_AGR", "num_a1_SO4_SHP", "num_a1_SO4_SLV", - "num_a1_SO4_WST"}; - srf_emiss_species_.push_back(num_a1); // add to the vector + num_a1.sectors = {"num_a1_SO4_AGR", "num_a1_SO4_SHP", "num_a1_SO4_SLV", + "num_a1_SO4_WST"}; + srf_emiss_species_.push_back(num_a1); // add to the vector //-------------------------------------------------------------------- // Init num_a2 srf emiss data structures @@ -91,8 +92,8 @@ void MAMSrfOnlineEmiss::set_grids( // File name, name and sectors num_a2.data_file = m_params.get("srf_emis_specifier_for_num_a2"); num_a2.species_name = "num_a2"; - num_a2.sectors = {"num_a2_SO4_RCO", "num_a2_SO4_TRA"}; - srf_emiss_species_.push_back(num_a2); // add to the vector + num_a2.sectors = {"num_a2_SO4_RCO", "num_a2_SO4_TRA"}; + srf_emiss_species_.push_back(num_a2); // add to the vector //-------------------------------------------------------------------- // Init num_a4 srf emiss data structures @@ -101,12 +102,12 @@ void MAMSrfOnlineEmiss::set_grids( // File name, name and sectors num_a4.data_file = m_params.get("srf_emis_specifier_for_num_a4"); num_a4.species_name = "num_a4"; - num_a4.sectors = { - "num_a1_BC_AGR", "num_a1_BC_ENE", "num_a1_BC_IND", "num_a1_BC_RCO", - "num_a1_BC_SHP", "num_a1_BC_SLV", "num_a1_BC_TRA", "num_a1_BC_WST", - "num_a1_POM_AGR", "num_a1_POM_ENE", "num_a1_POM_IND", "num_a1_POM_RCO", - "num_a1_POM_SHP", "num_a1_POM_SLV", "num_a1_POM_TRA", "num_a1_POM_WST"}; - srf_emiss_species_.push_back(num_a4); // add to the vector + num_a4.sectors = { + "num_a1_BC_AGR", "num_a1_BC_ENE", "num_a1_BC_IND", "num_a1_BC_RCO", + "num_a1_BC_SHP", "num_a1_BC_SLV", "num_a1_BC_TRA", "num_a1_BC_WST", + "num_a1_POM_AGR", "num_a1_POM_ENE", "num_a1_POM_IND", "num_a1_POM_RCO", + "num_a1_POM_SHP", "num_a1_POM_SLV", "num_a1_POM_TRA", "num_a1_POM_WST"}; + srf_emiss_species_.push_back(num_a4); // add to the vector //-------------------------------------------------------------------- // Init pom_a4 srf emiss data structures @@ -116,7 +117,7 @@ void MAMSrfOnlineEmiss::set_grids( pom_a4.data_file = m_params.get("srf_emis_specifier_for_pom_a4"); pom_a4.species_name = "pom_a4"; pom_a4.sectors = {"AGR", "ENE", "IND", "RCO", "SHP", "SLV", "TRA", "WST"}; - srf_emiss_species_.push_back(pom_a4); // add to the vector + srf_emiss_species_.push_back(pom_a4); // add to the vector //-------------------------------------------------------------------- // Init so4_a1 srf emiss data structures @@ -125,7 +126,7 @@ void MAMSrfOnlineEmiss::set_grids( // File name, name and sectors so4_a1.data_file = m_params.get("srf_emis_specifier_for_so4_a1"); so4_a1.species_name = "so4_a1"; - so4_a1.sectors = {"AGR", "SHP", "SLV", "WST"}; + so4_a1.sectors = {"AGR", "SHP", "SLV", "WST"}; srf_emiss_species_.push_back(so4_a1); //-------------------------------------------------------------------- @@ -135,21 +136,20 @@ void MAMSrfOnlineEmiss::set_grids( // File name, name and sectors so4_a2.data_file = m_params.get("srf_emis_specifier_for_so4_a2"); so4_a2.species_name = "so4_a2"; - so4_a2.sectors = {"RCO", "TRA"}; + so4_a2.sectors = {"RCO", "TRA"}; srf_emiss_species_.push_back(so4_a2); //-------------------------------------------------------------------- // Init data structures to read and interpolate //-------------------------------------------------------------------- - for(srf_emiss_ &ispec_srf : srf_emiss_species_) { + for (srf_emiss_ &ispec_srf : srf_emiss_species_) { srfEmissFunc::init_srf_emiss_objects( ncol_, grid_, ispec_srf.data_file, ispec_srf.sectors, srf_map_file, // output ispec_srf.horizInterp_, ispec_srf.data_start_, ispec_srf.data_end_, ispec_srf.data_out_, ispec_srf.dataReader_); } - -} // set_grid ends +} // set_grid ends // ================================================================ // REQUEST_BUFFER_SIZE_IN_BYTES @@ -167,9 +167,9 @@ size_t MAMSrfOnlineEmiss::requested_buffer_size_in_bytes() const { // intermediate (dry) quantities on the given number of columns with the given // number of vertical levels. Returns the number of bytes allocated. void MAMSrfOnlineEmiss::init_buffers(const ATMBufferManager &buffer_manager) { - EKAT_REQUIRE_MSG( - buffer_manager.allocated_bytes() >= requested_buffer_size_in_bytes(), - "Error! Insufficient buffer size.\n"); + EKAT_REQUIRE_MSG(buffer_manager.allocated_bytes() >= + requested_buffer_size_in_bytes(), + "Error! Insufficient buffer size.\n"); size_t used_mem = mam_coupling::init_buffer(buffer_manager, ncol_, nlev_, buffer_); @@ -206,18 +206,26 @@ void MAMSrfOnlineEmiss::initialize_impl(const RunType run_type) { //-------------------------------------------------------------------- // Update surface emissions from file //-------------------------------------------------------------------- - for(srf_emiss_ &ispec_srf : srf_emiss_species_) { + for (srf_emiss_ &ispec_srf : srf_emiss_species_) { srfEmissFunc::update_srfEmiss_data_from_file( ispec_srf.dataReader_, timestamp(), curr_month, *ispec_srf.horizInterp_, - ispec_srf.data_end_); // output + ispec_srf.data_end_); // output } + //-------------------------------------------------------------------- + // Initialize online emissions from file + //-------------------------------------------------------------------- + online_emis_data.init(ncol_); + onlineEmiss::init_from_input_file(m_params, online_emis_data); + //----------------------------------------------------------------- // Setup preprocessing and post processing //----------------------------------------------------------------- preprocess_.initialize(constituent_fluxes_); + onlineEmiss::transfer_to_cflux(online_emis_data, spcIndex_in_pcnst_, + constituent_fluxes_); -} // end initialize_impl() +} // end initialize_impl() // ================================================================ // RUN_IMPL @@ -225,15 +233,60 @@ void MAMSrfOnlineEmiss::initialize_impl(const RunType run_type) { void MAMSrfOnlineEmiss::run_impl(const double dt) { // Zero-out output Kokkos::deep_copy(preprocess_.constituent_fluxes_pre_, 0); + // copy current values to online-emissions-local version + Kokkos::deep_copy(online_emis_data.constituent_fluxes, constituent_fluxes_); // Gather time and state information for interpolation auto ts = timestamp() + dt; + // Parallel loop over all the columns to update units + Kokkos::parallel_for( + "fluxes", ncol_, KOKKOS_LAMBDA(int icol) { + // need to initialize values for: + // SeasaltEmissionsData.{mpoly, mprot, mlip} + // DustEmissionsData.dust_dmt_vwr (done here for now) + // OnlineEmissionsData.{dust_flux_in, surface_temp, u_bottom, + // v_bottom, z_bottom, ocean_frac} + // NOTE: fortran mam4 gets dust_flux_in and ocean_frac from cam_in, + // which is a chunk-wise variable at this point + // (see: physpkg.F90:{1605 & 1327}) otherwise grabs the end/bottom + // col-value once inside aero_model_emissions() + + view_1d fluxes_col = Kokkos::subview(online_emis_data.constituent_fluxes, + icol, Kokkos::ALL()); + mam4::aero_model_emissions::aero_model_emissions(fluxes_col); + }); + + // for (onlineEmissData &ispec_online : online_emis_data) { + // //-------------------------------------------------------------------- + // // Modify units to MKS units (from molecules/cm2/s to kg/m2/s) + // //-------------------------------------------------------------------- + // // Get species index in array with pcnst dimension + // // (e.g., state_q or constituent_fluxes_) + // const int species_index = + // spcIndex_in_pcnst_.at(ispec_online.species_name); + + // // modify units from molecules/cm2/s to kg/m2/s + // auto fluxes_in_mks_units = this->fluxes_in_mks_units_; + // auto constituent_fluxes = this->constituent_fluxes_; + // const Real mfactor = + // amufac * mam4::gas_chemistry::adv_mass[species_index - offset_]; + // // Parallel loop over all the columns to update units + // Kokkos::parallel_for( + // "fluxes", ncol_, KOKKOS_LAMBDA(int icol) { + // fluxes_in_mks_units(icol) = + // ispec_online.data_out_.emiss_sectors(0, icol) * mfactor; + // constituent_fluxes(icol, species_index) = + // fluxes_in_mks_units(icol); + // }); + + // } // for loop for species + //-------------------------------------------------------------------- // Interpolate srf emiss data //-------------------------------------------------------------------- - for(srf_emiss_ &ispec_srf : srf_emiss_species_) { + for (srf_emiss_ &ispec_srf : srf_emiss_species_) { // Update TimeState, note the addition of dt ispec_srf.timeState_.t_now = ts.frac_of_year_in_days(); @@ -256,7 +309,7 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { // modify units from molecules/cm2/s to kg/m2/s auto fluxes_in_mks_units = this->fluxes_in_mks_units_; - auto constituent_fluxes = this->constituent_fluxes_; + auto constituent_fluxes = this->constituent_fluxes_; const Real mfactor = amufac * mam4::gas_chemistry::adv_mass[species_index - offset_]; // Parallel loop over all the columns to update units @@ -267,9 +320,9 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { constituent_fluxes(icol, species_index) = fluxes_in_mks_units(icol); }); - } // for loop for species + } // for loop for species Kokkos::fence(); -} // run_imple ends +} // run_impl ends // ============================================================================= -} // namespace scream +} // namespace scream 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 031fb62d8b75..65ac4f6375e1 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 @@ -6,6 +6,7 @@ // For MAM4 aerosol configuration #include +#include #include // For declaring surface and online emission class derived from atm process @@ -20,7 +21,7 @@ namespace scream { // The process responsible for handling MAM4 surface and online emissions. The // AD stores exactly ONE instance of this class in its list of subcomponents. class MAMSrfOnlineEmiss final : public scream::AtmosphereProcess { - using KT = ekat::KokkosTypes; + using KT = ekat::KokkosTypes; using view_1d = typename KT::template view_1d; using view_2d = typename KT::template view_2d; @@ -40,10 +41,12 @@ class MAMSrfOnlineEmiss final : public scream::AtmosphereProcess { view_1d fluxes_in_mks_units_; // Unified atomic mass unit used for unit conversion (BAD constant) - static constexpr Real amufac = 1.65979e-23; // 1.e4* kg / amu + static constexpr Real amufac = 1.65979e-23; // 1.e4* kg / amu - public: +public: using srfEmissFunc = mam_coupling::srfEmissFunctions; + using onlineEmiss = + mam_coupling::onlineEmissions; // Constructor MAMSrfOnlineEmiss(const ekat::Comm &comm, const ekat::ParameterList ¶ms); @@ -59,8 +62,8 @@ class MAMSrfOnlineEmiss final : public scream::AtmosphereProcess { std::string name() const { return "mam_srf_online_emissions"; } // grid - void set_grids( - const std::shared_ptr grids_manager) override; + void + set_grids(const std::shared_ptr grids_manager) override; // management of common atm process memory size_t requested_buffer_size_in_bytes() const override; @@ -85,9 +88,9 @@ class MAMSrfOnlineEmiss final : public scream::AtmosphereProcess { } // local variables for preprocess struct view_2d constituent_fluxes_pre_; - }; // MAMSrfOnlineEmiss::Preprocess + }; // MAMSrfOnlineEmiss::Preprocess - private: +private: // preprocessing scratch pad Preprocess preprocess_; @@ -95,9 +98,11 @@ class MAMSrfOnlineEmiss final : public scream::AtmosphereProcess { // FIXME: Remove the hardwired indices and use a function // to find them from an array. const std::map spcIndex_in_pcnst_ = { - {"so2", 12}, {"dms", 13}, {"so4_a1", 15}, - {"num_a1", 22}, {"so4_a2", 23}, {"num_a2", 27}, - {"pom_a4", 36}, {"bc_a4", 37}, {"num_a4", 39}}; + {"so2", 12}, {"dms", 13}, {"so4_a1", 15}, {"dst_a1", 19}, + {"ncl_a1", 20}, {"mom_a1", 21}, {"num_a1", 22}, {"so4_a2", 23}, + {"ncl_a2", 25}, {"mom_a2", 26}, {"num_a2", 27}, {"dst_a3", 28}, + {"ncl_a3", 29}, {"num_a3", 35}, {"pom_a4", 36}, {"bc_a4", 37}, + {"mom_a4", 38}, {"num_a4", 39}}; // A struct carrying all the fields needed to read // surface emissions of a species @@ -122,12 +127,14 @@ class MAMSrfOnlineEmiss final : public scream::AtmosphereProcess { // A vector for carrying emissions for all the species std::vector srf_emiss_species_; + onlineEmiss::onlineEmissData online_emis_data; + // offset for converting pcnst index to gas_pcnst index static constexpr int offset_ = mam4::aero_model::pcnst - mam4::gas_chemistry::gas_pcnst; -}; // MAMSrfOnlineEmiss +}; // MAMSrfOnlineEmiss -} // namespace scream +} // namespace scream -#endif // EAMXX_MAM_SRF_ONLINE_EMISS_HPP +#endif // EAMXX_MAM_SRF_ONLINE_EMISS_HPP diff --git a/components/eamxx/src/physics/mam/online_emission.hpp b/components/eamxx/src/physics/mam/online_emission.hpp new file mode 100644 index 000000000000..0a2b3290e685 --- /dev/null +++ b/components/eamxx/src/physics/mam/online_emission.hpp @@ -0,0 +1,102 @@ +#ifndef ONLINE_EMISSION_HPP +#define ONLINE_EMISSION_HPP + +#include "share/util/scream_timing.hpp" + +namespace scream::mam_coupling { +namespace { + +template struct onlineEmissions { + using Device = DeviceType; + + using KT = KokkosTypes; + using MemberType = typename KT::MemberType; + + struct onlineEmissTimeState { + onlineEmissTimeState() = 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/scream_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; + }; // onlineEmissTimeState + + struct onlineEmissData { + // Basic spatial dimensions of the data + int ncols; + view_2d flux_data; + // local copy of main fluxes array + view_2d constituent_fluxes; + // FIXME: read this from input or get from mam4xx::aero_model_emissions? + const std::vector spec_names = {"so2", "soag", "bc_a4", + "num_a1", "num_a2", "num_a4", + "pom_a4", "so4_a1", "so4_a2"}; + // FIXME: change this when the above is dynamically-determined + int nspec = 9; + const std::string root_IC_str = "initial_condition_"; + + onlineEmissData() = default; + onlineEmissData(const int ncol_, const int nspec_) + : ncols(ncol_), nspec(nspec_) { + init(ncols, nspec, true); + } + + onlineEmissData(const int ncol_) : ncols(ncol_) { + init(ncols, nspec, true); + } + + void init(const int ncol_, const int nspec_, const bool allocate_) { + ncols = ncol_; + nspec = nspec_; + if (allocate_) + flux_data = view_2d("onlineEmissData", nspec, ncols); + } // onlineEmissData init + void init(const int ncol_, const bool allocate_) { + ncols = ncol_; + if (allocate_) + flux_data = view_2d("onlineEmissData", nspec, ncols); + } // onlineEmissData init + void init(const int ncol_) { + ncols = ncol_; + flux_data = view_2d("onlineEmissData", nspec, ncols); + } // onlineEmissData init + }; // onlineEmissData + + // The output is really just onlineEmissData, but for clarity it might + // help to see a onlineEmissOutput along a onlineEmissInput in functions + // signatures + // using onlineEmissOutput = onlineEmissData; + + // --------------------------------------------------------------------------- + // Online emissions routines + // --------------------------------------------------------------------------- + // FIXME: + // static void onlineEmiss_main(const onlineEmissTimeState &time_state, + // const onlineEmissInput &data_beg, + // const onlineEmissInput &data_end, + // const onlineEmissOutput &data_out); + + static void init_from_input_file(const ekat::ParameterList &m_params, + onlineEmissData &data); + static void + transfer_to_cflux(const onlineEmissData &data, + const std::map idx_map, + view_2d &fluxes); + // static void update_onlineEmiss_timestate( + // std::shared_ptr &scorpio_reader, + // const util::TimeStamp &ts, AbstractRemapper &onlineEmiss_horiz_interp, + // onlineEmissTimeState &time_state, onlineEmissInput &onlineEmiss_beg, + // onlineEmissInput &onlineEmiss_end); + +}; // struct onlineEmissions +} // namespace +} // namespace scream::mam_coupling +#endif // ONLINE_EMISSION_HPP + +#include "online_emission_impl.hpp" diff --git a/components/eamxx/src/physics/mam/online_emission_impl.hpp b/components/eamxx/src/physics/mam/online_emission_impl.hpp new file mode 100644 index 000000000000..5d374bfba767 --- /dev/null +++ b/components/eamxx/src/physics/mam/online_emission_impl.hpp @@ -0,0 +1,60 @@ +#ifndef ONLINE_EMISSION_IMPL_HPP +#define ONLINE_EMISSION_IMPL_HPP + +namespace scream::mam_coupling { +namespace { + +template +void onlineEmissions::init_from_input_file( + const ekat::ParameterList ¶ms, onlineEmissData &data) { + + const int nspec = data.nspec; + const int ncols = data.ncols; + using ExeSpace = typename KT::ExeSpace; + using ESU = ekat::ExeSpaceUtils; + const auto policy = ESU::get_default_team_policy(ncols, nspec); + + start_timer("EAMxx::onlineEmiss::init_onlineEmiss_data_from_input_file"); + // 1. Read from input file + // FIXME: currently reading a single placeholder scalar--should be + // ncols-sized array + for (int ispec = 0; ispec < nspec; ++ispec) { + Real init_cond_val = + params.get(data.root_IC_str + data.spec_names[ispec]); + // FIXME: is this overkill--i.e., would a mirror/deep_copy make more sense? + Kokkos::parallel_for( + policy, KOKKOS_LAMBDA(const MemberType &team) { + const int jcol = team.league_rank(); // column index + data.flux_data(ispec, jcol) = init_cond_val; + }); + } + stop_timer("EAMxx::onlineEmiss::init_onlineEmiss_data_from_input_file"); + +} // end init_from_input_file() + +template +void onlineEmissions::transfer_to_cflux( + const onlineEmissData &data, const std::map idx_map, + view_2d &fluxes) { + // FIXME: move out to onlineEmissions struct? + const int nspec = data.nspec; + const int ncols = data.ncols; + using ExeSpace = typename KT::ExeSpace; + using ESU = ekat::ExeSpaceUtils; + const auto policy = ESU::get_default_team_policy(ncols, nspec); + + Kokkos::parallel_for( + policy, KOKKOS_LAMBDA(const MemberType &team) { + const int jcol = team.league_rank(); // column index + Kokkos::parallel_for( + Kokkos::TeamThreadRange(team, nspec), [&](const int ispec) { + auto s_idx = idx_map.at(data.spec_names[ispec]); + fluxes(jcol, s_idx) = data.flux_data(ispec, jcol); + }); + }); +} + +} // namespace +} // namespace scream::mam_coupling + +#endif // ONLINE_EMISSION_IMPL_HPP diff --git a/components/eamxx/tests/single-process/mam/emissions/input.yaml b/components/eamxx/tests/single-process/mam/emissions/input.yaml index e7af45178aa5..3c7bd352f72f 100644 --- a/components/eamxx/tests/single-process/mam/emissions/input.yaml +++ b/components/eamxx/tests/single-process/mam/emissions/input.yaml @@ -13,15 +13,25 @@ atmosphere_processes: mam4_srf_online_emiss: # MAM4xx-Surface-Emissions srf_remap_file: "" - srf_emis_specifier_for_DMS: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/surface/DMSflux.2010.ne2np4_conserv.POPmonthlyClimFromACES4BGC_c20240726.nc - srf_emis_specifier_for_SO2: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/surface/cmip6_mam4_so2_surf_ne2np4_2010_clim_c20240723.nc - srf_emis_specifier_for_bc_a4: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/surface/cmip6_mam4_bc_a4_surf_ne2np4_2010_clim_c20240726.nc - srf_emis_specifier_for_num_a1: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/surface/cmip6_mam4_num_a1_surf_ne2np4_2010_clim_c20240726.nc - srf_emis_specifier_for_num_a2: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/surface/cmip6_mam4_num_a2_surf_ne2np4_2010_clim_c20240726.nc - srf_emis_specifier_for_num_a4: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/surface/cmip6_mam4_num_a4_surf_ne2np4_2010_clim_c20240726.nc - srf_emis_specifier_for_pom_a4: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/surface/cmip6_mam4_pom_a4_surf_ne2np4_2010_clim_c20240726.nc - srf_emis_specifier_for_so4_a1: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/surface/cmip6_mam4_so4_a1_surf_ne2np4_2010_clim_c20240726.nc - srf_emis_specifier_for_so4_a2: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/surface/cmip6_mam4_so4_a2_surf_ne2np4_2010_clim_c20240726.nc + srf_emis_specifier_for_DMS: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/DMSflux.2010.ne2np4_conserv.POPmonthlyClimFromACES4BGC_c20240726.nc + srf_emis_specifier_for_SO2: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/cmip6_mam4_so2_surf_ne2np4_2010_clim_c20240723.nc + srf_emis_specifier_for_bc_a4: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/cmip6_mam4_bc_a4_surf_ne2np4_2010_clim_c20240726.nc + srf_emis_specifier_for_num_a1: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/cmip6_mam4_num_a1_surf_ne2np4_2010_clim_c20240726.nc + srf_emis_specifier_for_num_a2: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/cmip6_mam4_num_a2_surf_ne2np4_2010_clim_c20240726.nc + srf_emis_specifier_for_num_a4: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/cmip6_mam4_num_a4_surf_ne2np4_2010_clim_c20240726.nc + srf_emis_specifier_for_pom_a4: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/cmip6_mam4_pom_a4_surf_ne2np4_2010_clim_c20240726.nc + srf_emis_specifier_for_so4_a1: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/cmip6_mam4_so4_a1_surf_ne2np4_2010_clim_c20240726.nc + srf_emis_specifier_for_so4_a2: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/cmip6_mam4_so4_a2_surf_ne2np4_2010_clim_c20240726.nc + # FIXME: just set everything to a constant scalar for testing + initial_condition_so2: 1.0 + initial_condition_soag: 2.0 + initial_condition_bc_a4: 3.0 + initial_condition_num_a1: 4.0 + initial_condition_num_a2: 5.0 + initial_condition_num_a4: 6.0 + initial_condition_pom_a4: 7.0 + initial_condition_so4_a1: 8.0 + initial_condition_so4_a2: 9.0 grids_manager: Type: Mesh Free From c3f2ebff570a2ab8bcc576fbcf92eaba8c621e2c Mon Sep 17 00:00:00 2001 From: Michael J Schmidt Date: Wed, 9 Oct 2024 15:47:02 -0600 Subject: [PATCH 099/147] cleanup to fix warnings and change path to emissions input files --- .../eamxx/src/physics/mam/online_emission.hpp | 9 -------- .../src/physics/mam/online_emission_impl.hpp | 4 ---- .../eamxx/src/physics/mam/srf_emission.hpp | 3 --- .../src/physics/mam/srf_emission_impl.hpp | 21 ++++++++++++------- .../single-process/mam/emissions/input.yaml | 18 ++++++++-------- 5 files changed, 22 insertions(+), 33 deletions(-) diff --git a/components/eamxx/src/physics/mam/online_emission.hpp b/components/eamxx/src/physics/mam/online_emission.hpp index 0a2b3290e685..bc5a510ccf76 100644 --- a/components/eamxx/src/physics/mam/online_emission.hpp +++ b/components/eamxx/src/physics/mam/online_emission.hpp @@ -4,8 +4,6 @@ #include "share/util/scream_timing.hpp" namespace scream::mam_coupling { -namespace { - template struct onlineEmissions { using Device = DeviceType; @@ -88,14 +86,7 @@ template struct onlineEmissions { transfer_to_cflux(const onlineEmissData &data, const std::map idx_map, view_2d &fluxes); - // static void update_onlineEmiss_timestate( - // std::shared_ptr &scorpio_reader, - // const util::TimeStamp &ts, AbstractRemapper &onlineEmiss_horiz_interp, - // onlineEmissTimeState &time_state, onlineEmissInput &onlineEmiss_beg, - // onlineEmissInput &onlineEmiss_end); - }; // struct onlineEmissions -} // namespace } // namespace scream::mam_coupling #endif // ONLINE_EMISSION_HPP diff --git a/components/eamxx/src/physics/mam/online_emission_impl.hpp b/components/eamxx/src/physics/mam/online_emission_impl.hpp index 5d374bfba767..860a4cac2be4 100644 --- a/components/eamxx/src/physics/mam/online_emission_impl.hpp +++ b/components/eamxx/src/physics/mam/online_emission_impl.hpp @@ -2,8 +2,6 @@ #define ONLINE_EMISSION_IMPL_HPP namespace scream::mam_coupling { -namespace { - template void onlineEmissions::init_from_input_file( const ekat::ParameterList ¶ms, onlineEmissData &data) { @@ -53,8 +51,6 @@ void onlineEmissions::transfer_to_cflux( }); }); } - -} // namespace } // namespace scream::mam_coupling #endif // ONLINE_EMISSION_IMPL_HPP diff --git a/components/eamxx/src/physics/mam/srf_emission.hpp b/components/eamxx/src/physics/mam/srf_emission.hpp index 29aaca421ea9..8dc5be1d05a6 100644 --- a/components/eamxx/src/physics/mam/srf_emission.hpp +++ b/components/eamxx/src/physics/mam/srf_emission.hpp @@ -4,8 +4,6 @@ #include "share/util/scream_timing.hpp" namespace scream::mam_coupling { -namespace { - template struct srfEmissFunctions { using Device = DeviceType; @@ -131,7 +129,6 @@ struct srfEmissFunctions { std::shared_ptr &SrfEmissDataReader); }; // struct srfEmissFunctions -} // namespace } // namespace scream::mam_coupling #endif // SRF_EMISSION_HPP diff --git a/components/eamxx/src/physics/mam/srf_emission_impl.hpp b/components/eamxx/src/physics/mam/srf_emission_impl.hpp index 48dc1fa70874..b090e3746cb7 100644 --- a/components/eamxx/src/physics/mam/srf_emission_impl.hpp +++ b/components/eamxx/src/physics/mam/srf_emission_impl.hpp @@ -6,8 +6,6 @@ #include "share/io/scream_scorpio_interface.hpp" namespace scream::mam_coupling { -namespace { - template std::shared_ptr srfEmissFunctions::create_horiz_remapper( @@ -104,6 +102,9 @@ void srfEmissFunctions::perform_time_interpolation( // NOTE: we *assume* data_beg and data_end have the *same* hybrid v coords. // IF this ever ceases to be the case, you can interp those too. + using ExeSpace = typename KT::ExeSpace; + using ESU = ekat::ExeSpaceUtils; + // Gather time stamp info auto &t_now = time_state.t_now; auto &t_beg = time_state.t_beg_month; @@ -181,6 +182,9 @@ void srfEmissFunctions::update_srfEmiss_data_from_file( const int time_index, // zero-based AbstractRemapper &srfEmiss_horiz_interp, srfEmissInput &srfEmiss_input) { using namespace ShortFieldTagsNames; + // NOTE: these are currently unused + // using ESU = ekat::ExeSpaceUtils; + // using Member = typename KokkosTypes::MemberType; start_timer("EAMxx::srfEmiss::update_srfEmiss_data_from_file"); @@ -201,10 +205,13 @@ void srfEmissFunctions::update_srfEmiss_data_from_file( // Recall, the fields are registered in the order: ps, ccn3, g_sw, ssa_sw, // tau_sw, tau_lw - const auto &layout = srfEmiss_horiz_interp.get_tgt_field(0) - .get_header() - .get_identifier() - .get_layout(); + // NOTE: these are currently unused + // const auto &layout = srfEmiss_horiz_interp.get_tgt_field(0) + // .get_header() + // .get_identifier() + // .get_layout(); + + const int ncols = layout.dim(COL); // Read fields from the file for(int i = 0; i < srfEmiss_horiz_interp.get_num_fields(); ++i) { @@ -279,8 +286,6 @@ void srfEmissFunctions::init_srf_emiss_objects( SrfEmissDataReader = create_srfEmiss_data_reader(SrfEmissHorizInterp, data_file); } // init_srf_emiss_objects - -} // namespace } // namespace scream::mam_coupling #endif // SRF_EMISSION_IMPL_HPP diff --git a/components/eamxx/tests/single-process/mam/emissions/input.yaml b/components/eamxx/tests/single-process/mam/emissions/input.yaml index 3c7bd352f72f..93f187e7de30 100644 --- a/components/eamxx/tests/single-process/mam/emissions/input.yaml +++ b/components/eamxx/tests/single-process/mam/emissions/input.yaml @@ -13,15 +13,15 @@ atmosphere_processes: mam4_srf_online_emiss: # MAM4xx-Surface-Emissions srf_remap_file: "" - srf_emis_specifier_for_DMS: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/DMSflux.2010.ne2np4_conserv.POPmonthlyClimFromACES4BGC_c20240726.nc - srf_emis_specifier_for_SO2: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/cmip6_mam4_so2_surf_ne2np4_2010_clim_c20240723.nc - srf_emis_specifier_for_bc_a4: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/cmip6_mam4_bc_a4_surf_ne2np4_2010_clim_c20240726.nc - srf_emis_specifier_for_num_a1: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/cmip6_mam4_num_a1_surf_ne2np4_2010_clim_c20240726.nc - srf_emis_specifier_for_num_a2: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/cmip6_mam4_num_a2_surf_ne2np4_2010_clim_c20240726.nc - srf_emis_specifier_for_num_a4: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/cmip6_mam4_num_a4_surf_ne2np4_2010_clim_c20240726.nc - srf_emis_specifier_for_pom_a4: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/cmip6_mam4_pom_a4_surf_ne2np4_2010_clim_c20240726.nc - srf_emis_specifier_for_so4_a1: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/cmip6_mam4_so4_a1_surf_ne2np4_2010_clim_c20240726.nc - srf_emis_specifier_for_so4_a2: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/cmip6_mam4_so4_a2_surf_ne2np4_2010_clim_c20240726.nc + srf_emis_specifier_for_DMS: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/surface/DMSflux.2010.ne2np4_conserv.POPmonthlyClimFromACES4BGC_c20240726.nc + srf_emis_specifier_for_SO2: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/surface/cmip6_mam4_so2_surf_ne2np4_2010_clim_c20240723.nc + srf_emis_specifier_for_bc_a4: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/surface/cmip6_mam4_bc_a4_surf_ne2np4_2010_clim_c20240726.nc + srf_emis_specifier_for_num_a1: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/surface/cmip6_mam4_num_a1_surf_ne2np4_2010_clim_c20240726.nc + srf_emis_specifier_for_num_a2: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/surface/cmip6_mam4_num_a2_surf_ne2np4_2010_clim_c20240726.nc + srf_emis_specifier_for_num_a4: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/surface/cmip6_mam4_num_a4_surf_ne2np4_2010_clim_c20240726.nc + srf_emis_specifier_for_pom_a4: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/surface/cmip6_mam4_pom_a4_surf_ne2np4_2010_clim_c20240726.nc + srf_emis_specifier_for_so4_a1: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/surface/cmip6_mam4_so4_a1_surf_ne2np4_2010_clim_c20240726.nc + srf_emis_specifier_for_so4_a2: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/surface/cmip6_mam4_so4_a2_surf_ne2np4_2010_clim_c20240726.nc # FIXME: just set everything to a constant scalar for testing initial_condition_so2: 1.0 initial_condition_soag: 2.0 From 749f2076bf667c874f9d6c541b0b44e839f3a464 Mon Sep 17 00:00:00 2001 From: Michael J Schmidt Date: Tue, 15 Oct 2024 06:59:46 -0600 Subject: [PATCH 100/147] got online emis. interface working --- ...and_online_emissions_process_interface.cpp | 78 +++++++------------ ...and_online_emissions_process_interface.hpp | 2 +- .../eamxx/src/physics/mam/online_emission.hpp | 42 ++++++---- .../src/physics/mam/online_emission_impl.hpp | 19 +++-- .../single-process/mam/emissions/input.yaml | 21 ++--- 5 files changed, 79 insertions(+), 83 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 7f85e9310807..b50da0d4445d 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 @@ -33,6 +33,9 @@ void MAMSrfOnlineEmiss::set_grids( // ------------------------------------------------------------- // These variables are "Computed" or outputs for the process + // FIXME: check into whether this should be an "Updated" field because + // I haven't yet determined if an updated field needs to be output + // as a tendency, and thus the flux would need dt [s] factored out // ------------------------------------------------------------- static constexpr Units m2(m * m, "m2"); // Constituent fluxes of species in [kg/m2/s] @@ -215,15 +218,13 @@ void MAMSrfOnlineEmiss::initialize_impl(const RunType run_type) { //-------------------------------------------------------------------- // Initialize online emissions from file //-------------------------------------------------------------------- - online_emis_data.init(ncol_); - onlineEmiss::init_from_input_file(m_params, online_emis_data); + online_emissions.online_emis_data.init(ncol_); + online_emissions.init_from_input_file(m_params); //----------------------------------------------------------------- // Setup preprocessing and post processing //----------------------------------------------------------------- preprocess_.initialize(constituent_fluxes_); - onlineEmiss::transfer_to_cflux(online_emis_data, spcIndex_in_pcnst_, - constituent_fluxes_); } // end initialize_impl() @@ -233,55 +234,10 @@ void MAMSrfOnlineEmiss::initialize_impl(const RunType run_type) { void MAMSrfOnlineEmiss::run_impl(const double dt) { // Zero-out output Kokkos::deep_copy(preprocess_.constituent_fluxes_pre_, 0); - // copy current values to online-emissions-local version - Kokkos::deep_copy(online_emis_data.constituent_fluxes, constituent_fluxes_); // Gather time and state information for interpolation auto ts = timestamp() + dt; - // Parallel loop over all the columns to update units - Kokkos::parallel_for( - "fluxes", ncol_, KOKKOS_LAMBDA(int icol) { - // need to initialize values for: - // SeasaltEmissionsData.{mpoly, mprot, mlip} - // DustEmissionsData.dust_dmt_vwr (done here for now) - // OnlineEmissionsData.{dust_flux_in, surface_temp, u_bottom, - // v_bottom, z_bottom, ocean_frac} - // NOTE: fortran mam4 gets dust_flux_in and ocean_frac from cam_in, - // which is a chunk-wise variable at this point - // (see: physpkg.F90:{1605 & 1327}) otherwise grabs the end/bottom - // col-value once inside aero_model_emissions() - - view_1d fluxes_col = Kokkos::subview(online_emis_data.constituent_fluxes, - icol, Kokkos::ALL()); - mam4::aero_model_emissions::aero_model_emissions(fluxes_col); - }); - - // for (onlineEmissData &ispec_online : online_emis_data) { - // //-------------------------------------------------------------------- - // // Modify units to MKS units (from molecules/cm2/s to kg/m2/s) - // //-------------------------------------------------------------------- - // // Get species index in array with pcnst dimension - // // (e.g., state_q or constituent_fluxes_) - // const int species_index = - // spcIndex_in_pcnst_.at(ispec_online.species_name); - - // // modify units from molecules/cm2/s to kg/m2/s - // auto fluxes_in_mks_units = this->fluxes_in_mks_units_; - // auto constituent_fluxes = this->constituent_fluxes_; - // const Real mfactor = - // amufac * mam4::gas_chemistry::adv_mass[species_index - offset_]; - // // Parallel loop over all the columns to update units - // Kokkos::parallel_for( - // "fluxes", ncol_, KOKKOS_LAMBDA(int icol) { - // fluxes_in_mks_units(icol) = - // ispec_online.data_out_.emiss_sectors(0, icol) * mfactor; - // constituent_fluxes(icol, species_index) = - // fluxes_in_mks_units(icol); - // }); - - // } // for loop for species - //-------------------------------------------------------------------- // Interpolate srf emiss data //-------------------------------------------------------------------- @@ -314,13 +270,35 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { amufac * mam4::gas_chemistry::adv_mass[species_index - offset_]; // Parallel loop over all the columns to update units Kokkos::parallel_for( - "fluxes", ncol_, KOKKOS_LAMBDA(int icol) { + "srf_emis_fluxes", ncol_, KOKKOS_LAMBDA(int icol) { fluxes_in_mks_units(icol) = ispec_srf.data_out_.emiss_sectors(0, icol) * mfactor; constituent_fluxes(icol, species_index) = fluxes_in_mks_units(icol); }); } // for loop for species + + // TODO: check that units are consistent with srf emissions! + // copy current values to online-emissions-local version + Kokkos::deep_copy(online_emis_data.cfluxes, constituent_fluxes_); + // TODO: potentially combine with above parfor(icol) loop? + Kokkos::parallel_for( + "online_emis_fluxes", ncol_, KOKKOS_LAMBDA(int icol) { + // need to initialize values for: + // SeasaltEmissionsData.{mpoly, mprot, mlip} + // DustEmissionsData.dust_dmt_vwr + // OnlineEmissionsData.{dust_flux_in, surface_temp, u_bottom, + // v_bottom, z_bottom, ocean_frac} + // NOTE: fortran mam4 gets dust_flux_in and ocean_frac from cam_in, + // which is a chunk-wise variable at this point + // (see: physpkg.F90:{1605 & 1327}) otherwise grabs the end/bottom + // col-value once inside aero_model_emissions() + + view_1d fluxes_col = Kokkos::subview( + online_emissions.online_emis_data.cfluxes, icol, Kokkos::ALL()); + mam4::aero_model_emissions::aero_model_emissions(fluxes_col); + }); + Kokkos::deep_copy(constituent_fluxes_, online_emis_data.cfluxes); Kokkos::fence(); } // run_impl ends 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 65ac4f6375e1..8bfee35f2d9d 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 @@ -127,7 +127,7 @@ class MAMSrfOnlineEmiss final : public scream::AtmosphereProcess { // A vector for carrying emissions for all the species std::vector srf_emiss_species_; - onlineEmiss::onlineEmissData online_emis_data; + onlineEmiss online_emissions; // offset for converting pcnst index to gas_pcnst index static constexpr int offset_ = diff --git a/components/eamxx/src/physics/mam/online_emission.hpp b/components/eamxx/src/physics/mam/online_emission.hpp index bc5a510ccf76..9841c874f85c 100644 --- a/components/eamxx/src/physics/mam/online_emission.hpp +++ b/components/eamxx/src/physics/mam/online_emission.hpp @@ -9,6 +9,7 @@ template struct onlineEmissions { using KT = KokkosTypes; using MemberType = typename KT::MemberType; + static constexpr int pcnst = mam4::aero_model::pcnst; struct onlineEmissTimeState { onlineEmissTimeState() = default; @@ -30,14 +31,14 @@ template struct onlineEmissions { int ncols; view_2d flux_data; // local copy of main fluxes array - view_2d constituent_fluxes; + view_2d cfluxes; // FIXME: read this from input or get from mam4xx::aero_model_emissions? - const std::vector spec_names = {"so2", "soag", "bc_a4", - "num_a1", "num_a2", "num_a4", - "pom_a4", "so4_a1", "so4_a2"}; + const std::vector spec_names = { + "ncl_a1", "ncl_a2", "ncl_a3", "mom_a1", "mom_a2", "mom_a4", + "num_a1", "num_a2", "num_a3", "num_a4", "dst_a1", "dst_a3"}; // FIXME: change this when the above is dynamically-determined - int nspec = 9; - const std::string root_IC_str = "initial_condition_"; + int nspec = spec_names.size(); + const std::string root_IC_str = "online_emis_IC_"; onlineEmissData() = default; onlineEmissData(const int ncol_, const int nspec_) @@ -52,22 +53,29 @@ template struct onlineEmissions { void init(const int ncol_, const int nspec_, const bool allocate_) { ncols = ncol_; nspec = nspec_; - if (allocate_) + if (allocate_) { flux_data = view_2d("onlineEmissData", nspec, ncols); + cfluxes = view_2d("onlineEmisLocalCflux", ncols, pcnst); + } } // onlineEmissData init void init(const int ncol_, const bool allocate_) { ncols = ncol_; - if (allocate_) + if (allocate_) { flux_data = view_2d("onlineEmissData", nspec, ncols); + cfluxes = view_2d("onlineEmisLocalCflux", ncols, pcnst); + } } // onlineEmissData init void init(const int ncol_) { ncols = ncol_; flux_data = view_2d("onlineEmissData", nspec, ncols); + cfluxes = view_2d("onlineEmisLocalCflux", ncols, pcnst); } // onlineEmissData init }; // onlineEmissData + onlineEmissData online_emis_data; + // The output is really just onlineEmissData, but for clarity it might - // help to see a onlineEmissOutput along a onlineEmissInput in functions + // help to see a onlineEmissOutput along with onlineEmissInput in functions // signatures // using onlineEmissOutput = onlineEmissData; @@ -80,12 +88,16 @@ template struct onlineEmissions { // const onlineEmissInput &data_end, // const onlineEmissOutput &data_out); - static void init_from_input_file(const ekat::ParameterList &m_params, - onlineEmissData &data); - static void - transfer_to_cflux(const onlineEmissData &data, - const std::map idx_map, - view_2d &fluxes); + void init_from_input_file(const ekat::ParameterList &m_params); + void transfer_to_cflux(const onlineEmissData &data, + const std::map idx_map, + view_2d &fluxes); + // static void update_onlineEmiss_timestate( + // std::shared_ptr &scorpio_reader, + // const util::TimeStamp &ts, AbstractRemapper &onlineEmiss_horiz_interp, + // onlineEmissTimeState &time_state, onlineEmissInput &onlineEmiss_beg, + // onlineEmissInput &onlineEmiss_end); + }; // struct onlineEmissions } // namespace scream::mam_coupling #endif // ONLINE_EMISSION_HPP diff --git a/components/eamxx/src/physics/mam/online_emission_impl.hpp b/components/eamxx/src/physics/mam/online_emission_impl.hpp index 860a4cac2be4..ec415c036a38 100644 --- a/components/eamxx/src/physics/mam/online_emission_impl.hpp +++ b/components/eamxx/src/physics/mam/online_emission_impl.hpp @@ -3,11 +3,9 @@ namespace scream::mam_coupling { template -void onlineEmissions::init_from_input_file( - const ekat::ParameterList ¶ms, onlineEmissData &data) { - - const int nspec = data.nspec; - const int ncols = data.ncols; +void onlineEmissions::init_from_input_file(const ekat::ParameterList ¶ms) { + const int nspec = online_emis_data.nspec; + const int ncols = online_emis_data.ncols; using ExeSpace = typename KT::ExeSpace; using ESU = ekat::ExeSpaceUtils; const auto policy = ESU::get_default_team_policy(ncols, nspec); @@ -18,12 +16,12 @@ void onlineEmissions::init_from_input_file( // ncols-sized array for (int ispec = 0; ispec < nspec; ++ispec) { Real init_cond_val = - params.get(data.root_IC_str + data.spec_names[ispec]); + params.get(online_emis_data.root_IC_str + online_emis_data.spec_names[ispec]); // FIXME: is this overkill--i.e., would a mirror/deep_copy make more sense? Kokkos::parallel_for( policy, KOKKOS_LAMBDA(const MemberType &team) { const int jcol = team.league_rank(); // column index - data.flux_data(ispec, jcol) = init_cond_val; + online_emis_data.flux_data(ispec, jcol) = init_cond_val; }); } stop_timer("EAMxx::onlineEmiss::init_onlineEmiss_data_from_input_file"); @@ -47,9 +45,14 @@ void onlineEmissions::transfer_to_cflux( Kokkos::parallel_for( Kokkos::TeamThreadRange(team, nspec), [&](const int ispec) { auto s_idx = idx_map.at(data.spec_names[ispec]); - fluxes(jcol, s_idx) = data.flux_data(ispec, jcol); + data.cfluxes(jcol, s_idx) = data.flux_data(ispec, jcol); + std::cout << "=========================================" << "\n"; + std::cout << "data.cfluxes(jcol, s_idx) = " << data.cfluxes(jcol, s_idx) << "\n"; + std::cout << "=========================================" << "\n"; }); }); + + Kokkos::deep_copy(fluxes, data.cfluxes); } } // namespace scream::mam_coupling diff --git a/components/eamxx/tests/single-process/mam/emissions/input.yaml b/components/eamxx/tests/single-process/mam/emissions/input.yaml index 93f187e7de30..589f08fba476 100644 --- a/components/eamxx/tests/single-process/mam/emissions/input.yaml +++ b/components/eamxx/tests/single-process/mam/emissions/input.yaml @@ -23,15 +23,18 @@ atmosphere_processes: srf_emis_specifier_for_so4_a1: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/surface/cmip6_mam4_so4_a1_surf_ne2np4_2010_clim_c20240726.nc srf_emis_specifier_for_so4_a2: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/surface/cmip6_mam4_so4_a2_surf_ne2np4_2010_clim_c20240726.nc # FIXME: just set everything to a constant scalar for testing - initial_condition_so2: 1.0 - initial_condition_soag: 2.0 - initial_condition_bc_a4: 3.0 - initial_condition_num_a1: 4.0 - initial_condition_num_a2: 5.0 - initial_condition_num_a4: 6.0 - initial_condition_pom_a4: 7.0 - initial_condition_so4_a1: 8.0 - initial_condition_so4_a2: 9.0 + online_emis_IC_ncl_a1: 1.0 + online_emis_IC_ncl_a2: 2.0 + online_emis_IC_ncl_a3: 3.0 + online_emis_IC_mom_a1: 4.0 + online_emis_IC_mom_a2: 5.0 + online_emis_IC_mom_a4: 6.0 + online_emis_IC_num_a1: 7.0 + online_emis_IC_num_a2: 8.0 + online_emis_IC_num_a3: 9.0 + online_emis_IC_num_a4: 10.0 + online_emis_IC_dst_a1: 11.0 + online_emis_IC_dst_a3: 12.0 grids_manager: Type: Mesh Free From 484d2c17d009dbb6eb96f1a3c0a538d7fac47930 Mon Sep 17 00:00:00 2001 From: Michael J Schmidt Date: Wed, 16 Oct 2024 16:42:59 -0600 Subject: [PATCH 101/147] online emissions interface appears to be working --- ...and_online_emissions_process_interface.cpp | 28 +++++++------ ...and_online_emissions_process_interface.hpp | 4 +- .../eamxx/src/physics/mam/online_emission.hpp | 39 ++----------------- .../src/physics/mam/online_emission_impl.hpp | 17 +++----- .../single-process/mam/emissions/input.yaml | 38 ++++++++++++------ externals/mam4xx | 2 +- 6 files changed, 54 insertions(+), 74 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 b50da0d4445d..1db0535cce83 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 @@ -33,9 +33,13 @@ void MAMSrfOnlineEmiss::set_grids( // ------------------------------------------------------------- // These variables are "Computed" or outputs for the process - // FIXME: check into whether this should be an "Updated" field because - // I haven't yet determined if an updated field needs to be output - // as a tendency, and thus the flux would need dt [s] factored out + // FIXME: this should likely be an updated field, since online emissisons + // expects input values for constituent_fluxes + // NOTE: the other option is that we do something like: + // add_field("constituent_fluxes_input", scalar2d_pcnct, + // kg / m2 / s, grid_name); + // and then bundle the online emissions computations as tendencies into the + // Computed constituent_fluxes field // ------------------------------------------------------------- static constexpr Units m2(m * m, "m2"); // Constituent fluxes of species in [kg/m2/s] @@ -275,16 +279,19 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { ispec_srf.data_out_.emiss_sectors(0, icol) * mfactor; constituent_fluxes(icol, species_index) = fluxes_in_mks_units(icol); }); - } // for loop for species + auto &online_data = online_emissions.online_emis_data; // TODO: check that units are consistent with srf emissions! // copy current values to online-emissions-local version - Kokkos::deep_copy(online_emis_data.cfluxes, constituent_fluxes_); + Kokkos::deep_copy(online_data.cfluxes, constituent_fluxes_); // TODO: potentially combine with above parfor(icol) loop? Kokkos::parallel_for( "online_emis_fluxes", ncol_, KOKKOS_LAMBDA(int icol) { - // need to initialize values for: + // NOTE: calling aero_model_emissions() this way hides the fact that + // some hard-coded data is initialized within mam4::aero_model_emissions + // some of these values definitely need to be read from here column-wise + // the structs.{values} holding the above are: // SeasaltEmissionsData.{mpoly, mprot, mlip} // DustEmissionsData.dust_dmt_vwr // OnlineEmissionsData.{dust_flux_in, surface_temp, u_bottom, @@ -293,14 +300,13 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { // which is a chunk-wise variable at this point // (see: physpkg.F90:{1605 & 1327}) otherwise grabs the end/bottom // col-value once inside aero_model_emissions() - - view_1d fluxes_col = Kokkos::subview( - online_emissions.online_emis_data.cfluxes, icol, Kokkos::ALL()); + view_1d fluxes_col = Kokkos::subview(online_data.cfluxes, icol, Kokkos::ALL()); mam4::aero_model_emissions::aero_model_emissions(fluxes_col); }); - Kokkos::deep_copy(constituent_fluxes_, online_emis_data.cfluxes); + // 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 + Kokkos::deep_copy(constituent_fluxes_, online_data.cfluxes); Kokkos::fence(); } // run_impl ends - // ============================================================================= } // namespace scream 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 8bfee35f2d9d..80c2efcccd73 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 @@ -13,7 +13,6 @@ // class #include -// #include #include namespace scream { @@ -45,8 +44,7 @@ class MAMSrfOnlineEmiss final : public scream::AtmosphereProcess { public: using srfEmissFunc = mam_coupling::srfEmissFunctions; - using onlineEmiss = - mam_coupling::onlineEmissions; + using onlineEmiss = mam_coupling::onlineEmissions; // Constructor MAMSrfOnlineEmiss(const ekat::Comm &comm, const ekat::ParameterList ¶ms); diff --git a/components/eamxx/src/physics/mam/online_emission.hpp b/components/eamxx/src/physics/mam/online_emission.hpp index 9841c874f85c..b844f5b18e64 100644 --- a/components/eamxx/src/physics/mam/online_emission.hpp +++ b/components/eamxx/src/physics/mam/online_emission.hpp @@ -6,37 +6,21 @@ namespace scream::mam_coupling { template struct onlineEmissions { using Device = DeviceType; - using KT = KokkosTypes; using MemberType = typename KT::MemberType; static constexpr int pcnst = mam4::aero_model::pcnst; - struct onlineEmissTimeState { - onlineEmissTimeState() = 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/scream_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; - }; // onlineEmissTimeState - struct onlineEmissData { // Basic spatial dimensions of the data int ncols; view_2d flux_data; // local copy of main fluxes array view_2d cfluxes; - // FIXME: read this from input or get from mam4xx::aero_model_emissions? + // FIXME: read this from elsewhere? input? const std::vector spec_names = { "ncl_a1", "ncl_a2", "ncl_a3", "mom_a1", "mom_a2", "mom_a4", "num_a1", "num_a2", "num_a3", "num_a4", "dst_a1", "dst_a3"}; - // FIXME: change this when the above is dynamically-determined + // FIXME: change this when/if the above is dynamically-determined int nspec = spec_names.size(); const std::string root_IC_str = "online_emis_IC_"; @@ -50,6 +34,8 @@ template struct onlineEmissions { init(ncols, nspec, true); } + // overloads of init() in case npsec is not hard-coded, or if you want to + // control allocation via bool flag void init(const int ncol_, const int nspec_, const bool allocate_) { ncols = ncol_; nspec = nspec_; @@ -74,30 +60,13 @@ template struct onlineEmissions { onlineEmissData online_emis_data; - // The output is really just onlineEmissData, but for clarity it might - // help to see a onlineEmissOutput along with onlineEmissInput in functions - // signatures - // using onlineEmissOutput = onlineEmissData; - // --------------------------------------------------------------------------- // Online emissions routines // --------------------------------------------------------------------------- - // FIXME: - // static void onlineEmiss_main(const onlineEmissTimeState &time_state, - // const onlineEmissInput &data_beg, - // const onlineEmissInput &data_end, - // const onlineEmissOutput &data_out); - void init_from_input_file(const ekat::ParameterList &m_params); void transfer_to_cflux(const onlineEmissData &data, const std::map idx_map, view_2d &fluxes); - // static void update_onlineEmiss_timestate( - // std::shared_ptr &scorpio_reader, - // const util::TimeStamp &ts, AbstractRemapper &onlineEmiss_horiz_interp, - // onlineEmissTimeState &time_state, onlineEmissInput &onlineEmiss_beg, - // onlineEmissInput &onlineEmiss_end); - }; // struct onlineEmissions } // namespace scream::mam_coupling #endif // ONLINE_EMISSION_HPP diff --git a/components/eamxx/src/physics/mam/online_emission_impl.hpp b/components/eamxx/src/physics/mam/online_emission_impl.hpp index ec415c036a38..1f0ac91a8548 100644 --- a/components/eamxx/src/physics/mam/online_emission_impl.hpp +++ b/components/eamxx/src/physics/mam/online_emission_impl.hpp @@ -4,35 +4,32 @@ namespace scream::mam_coupling { template void onlineEmissions::init_from_input_file(const ekat::ParameterList ¶ms) { + // FIXME: move this out to the onlineEmissions struct to avoid extra work + // by doing it again below? const int nspec = online_emis_data.nspec; const int ncols = online_emis_data.ncols; using ExeSpace = typename KT::ExeSpace; using ESU = ekat::ExeSpaceUtils; const auto policy = ESU::get_default_team_policy(ncols, nspec); - - start_timer("EAMxx::onlineEmiss::init_onlineEmiss_data_from_input_file"); - // 1. Read from input file + // Read from input file // FIXME: currently reading a single placeholder scalar--should be - // ncols-sized array + // ncols-sized array when we know what the input data looks like for (int ispec = 0; ispec < nspec; ++ispec) { Real init_cond_val = params.get(online_emis_data.root_IC_str + online_emis_data.spec_names[ispec]); - // FIXME: is this overkill--i.e., would a mirror/deep_copy make more sense? + // TODO: is this overkill?--i.e., would a mirror/deep_copy make more sense? Kokkos::parallel_for( policy, KOKKOS_LAMBDA(const MemberType &team) { const int jcol = team.league_rank(); // column index online_emis_data.flux_data(ispec, jcol) = init_cond_val; }); } - stop_timer("EAMxx::onlineEmiss::init_onlineEmiss_data_from_input_file"); - } // end init_from_input_file() template void onlineEmissions::transfer_to_cflux( const onlineEmissData &data, const std::map idx_map, view_2d &fluxes) { - // FIXME: move out to onlineEmissions struct? const int nspec = data.nspec; const int ncols = data.ncols; using ExeSpace = typename KT::ExeSpace; @@ -46,12 +43,8 @@ void onlineEmissions::transfer_to_cflux( Kokkos::TeamThreadRange(team, nspec), [&](const int ispec) { auto s_idx = idx_map.at(data.spec_names[ispec]); data.cfluxes(jcol, s_idx) = data.flux_data(ispec, jcol); - std::cout << "=========================================" << "\n"; - std::cout << "data.cfluxes(jcol, s_idx) = " << data.cfluxes(jcol, s_idx) << "\n"; - std::cout << "=========================================" << "\n"; }); }); - Kokkos::deep_copy(fluxes, data.cfluxes); } } // namespace scream::mam_coupling diff --git a/components/eamxx/tests/single-process/mam/emissions/input.yaml b/components/eamxx/tests/single-process/mam/emissions/input.yaml index 589f08fba476..7a3dfb43f222 100644 --- a/components/eamxx/tests/single-process/mam/emissions/input.yaml +++ b/components/eamxx/tests/single-process/mam/emissions/input.yaml @@ -23,18 +23,32 @@ atmosphere_processes: srf_emis_specifier_for_so4_a1: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/surface/cmip6_mam4_so4_a1_surf_ne2np4_2010_clim_c20240726.nc srf_emis_specifier_for_so4_a2: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/surface/cmip6_mam4_so4_a2_surf_ne2np4_2010_clim_c20240726.nc # FIXME: just set everything to a constant scalar for testing - online_emis_IC_ncl_a1: 1.0 - online_emis_IC_ncl_a2: 2.0 - online_emis_IC_ncl_a3: 3.0 - online_emis_IC_mom_a1: 4.0 - online_emis_IC_mom_a2: 5.0 - online_emis_IC_mom_a4: 6.0 - online_emis_IC_num_a1: 7.0 - online_emis_IC_num_a2: 8.0 - online_emis_IC_num_a3: 9.0 - online_emis_IC_num_a4: 10.0 - online_emis_IC_dst_a1: 11.0 - online_emis_IC_dst_a3: 12.0 + online_emis_IC_ncl_a1: 0.0 + online_emis_IC_ncl_a2: 0.0 + online_emis_IC_ncl_a3: 0.0 + online_emis_IC_mom_a1: 0.16838301005552275E-013 + online_emis_IC_mom_a2: 0.26554873160224250E-016 + online_emis_IC_mom_a4: 0.0 + online_emis_IC_num_a1: 0.0 + online_emis_IC_num_a2: 0.0 + online_emis_IC_num_a3: 0.0 + online_emis_IC_num_a4: 0.0 + online_emis_IC_dst_a1: 0.0 + online_emis_IC_dst_a3: 0.18720550166902007E+003 + +# NOTE: these are the single-call results from the mam validation test +# (20) ncl_a1: 2.659900637e-13 +# (25) ncl_a2: 0 +# (29) ncl_a3: 2.391492482e-11 +# (21) mom_a1: 1.683830101e-14 +# (26) mom_a2: 2.655487316e-17 +# (38) mom_a4: 0 +# (22) num_a1: 2.594942753e-15 +# (27) num_a2: 4.092359179e-18 +# (35) num_a3: 0 +# (39) num_a4: 0 +# (19) dst_a1: 0 +# (28) dst_a3: 403.2611563 grids_manager: Type: Mesh Free diff --git a/externals/mam4xx b/externals/mam4xx index 4431bbd1eef4..c537bab2695a 160000 --- a/externals/mam4xx +++ b/externals/mam4xx @@ -1 +1 @@ -Subproject commit 4431bbd1eef46de25be3a04e7091c9255bd0b819 +Subproject commit c537bab2695af76290cc0b82462393761b5820ed From 829c560df200b3c7dcd7ef012e557948be909f6f Mon Sep 17 00:00:00 2001 From: Michael J Schmidt Date: Wed, 16 Oct 2024 17:34:24 -0600 Subject: [PATCH 102/147] bump mam4xx submodule, add comments to srf_online_emis_interface --- ..._mam_srf_and_online_emissions_process_interface.cpp | 10 ++++++++++ externals/mam4xx | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) 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 1db0535cce83..c84bb8034408 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 @@ -30,6 +30,16 @@ void MAMSrfOnlineEmiss::set_grids( static constexpr int pcnst = mam4::aero_model::pcnst; const FieldLayout scalar2d_pcnct = grid_->get_2d_vector_layout(pcnst, "num_phys_constituents"); + // auto vector3d_mid = grid_->get_3d_vector_layout(true, 2); + + // FIXME: online emissions requires the following quantities for the + // OnlineEmissionsData struct: {surface_temp, u_bottom, v_bottom, z_bottom, + // ocean_frac} + // // Temperature + // add_field("T_mid", scalar3d_layout_mid, K, grid_name); + // add_field("horiz_winds", vector3d_mid, m/s, grid_name); + // vertical wind? + // ocean_frac? // ------------------------------------------------------------- // These variables are "Computed" or outputs for the process diff --git a/externals/mam4xx b/externals/mam4xx index c537bab2695a..67c309117abe 160000 --- a/externals/mam4xx +++ b/externals/mam4xx @@ -1 +1 @@ -Subproject commit c537bab2695af76290cc0b82462393761b5820ed +Subproject commit 67c309117abe0be649d085c7aeaeb1e949f6b550 From b2dbb85c4b7bee72cd88b26f16bbbed936479aaa Mon Sep 17 00:00:00 2001 From: Michael J Schmidt Date: Wed, 16 Oct 2024 20:43:48 -0600 Subject: [PATCH 103/147] update mam4xx to main --- externals/mam4xx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/externals/mam4xx b/externals/mam4xx index 67c309117abe..6bc2697f84b3 160000 --- a/externals/mam4xx +++ b/externals/mam4xx @@ -1 +1 @@ -Subproject commit 67c309117abe0be649d085c7aeaeb1e949f6b550 +Subproject commit 6bc2697f84b38503cc8fe638a6281ea107180e40 From 24d3e11c04506a572e04de5718d048e531754401 Mon Sep 17 00:00:00 2001 From: Michael J Schmidt Date: Mon, 21 Oct 2024 13:00:52 -0600 Subject: [PATCH 104/147] comment out error-inducing code in mam4_amicphys.cpp and small reorg change in online_emission.hpp --- ...mxx_mam_microphysics_process_interface.cpp | 11 + .../src/physics/mam/impl/mam4_amicphys.cpp | 1819 +++++++++++++++++ .../eamxx/src/physics/mam/online_emission.hpp | 26 +- .../src/physics/mam/online_emission_impl.hpp | 52 - 4 files changed, 1850 insertions(+), 58 deletions(-) create mode 100644 components/eamxx/src/physics/mam/impl/mam4_amicphys.cpp delete mode 100644 components/eamxx/src/physics/mam/online_emission_impl.hpp 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 57eaf9275483..41713b97735e 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 @@ -70,9 +70,20 @@ void MAMMicrophysics::set_grids( const FieldLayout scalar3d_mid = grid_->get_3d_scalar_layout(true); const FieldLayout scalar3d_int = grid_->get_3d_scalar_layout(false); +<<<<<<< HEAD using namespace ekat::units; constexpr auto q_unit = kg / kg; // units of mass mixing ratios of tracers constexpr auto n_unit = 1 / kg; // units of number mixing ratios of tracers +======= + config_.amicphys.nucleation = {}; + // config_.amicphys.nucleation.dens_so4a_host = 1770.0; + // config_.amicphys.nucleation.mw_so4a_host = 115.0; + // config_.amicphys.nucleation.newnuc_method_user_choice = 2; + // config_.amicphys.nucleation.pbl_nuc_wang2008_user_choice = 1; + // config_.amicphys.nucleation.adjust_factor_pbl_ratenucl = 1.0; + // config_.amicphys.nucleation.accom_coef_h2so4 = 1.0; + config_.amicphys.nucleation.newnuc_adjust_factor_dnaitdt = 1.0; +>>>>>>> comment out error-inducing code in mam4_amicphys.cpp and small reorg change in online_emission.hpp // -------------------------------------------------------------------------- // These variables are "Required" or pure inputs for the process diff --git a/components/eamxx/src/physics/mam/impl/mam4_amicphys.cpp b/components/eamxx/src/physics/mam/impl/mam4_amicphys.cpp new file mode 100644 index 000000000000..e241b5ec428f --- /dev/null +++ b/components/eamxx/src/physics/mam/impl/mam4_amicphys.cpp @@ -0,0 +1,1819 @@ +#include +#include +#include +#include +#include +#include + +namespace scream::impl { + +#define MAX_FILENAME_LEN 256 + +using namespace mam4; + +// number of constituents in gas chemistry "work arrays" +KOKKOS_INLINE_FUNCTION +constexpr int gas_pcnst() { + constexpr int gas_pcnst_ = mam4::gas_chemistry::gas_pcnst; + return gas_pcnst_; +} + +// number of aerosol/gas species tendencies +KOKKOS_INLINE_FUNCTION +constexpr int nqtendbb() { return 4; } + +// MAM4 aerosol microphysics configuration data +struct AmicPhysConfig { + // these switches activate various aerosol microphysics processes + bool do_cond; // condensation (a.k.a gas-aerosol exchange) + bool do_rename; // mode "renaming" + bool do_newnuc; // gas -> aerosol nucleation + bool do_coag; // aerosol coagulation + + // configurations for specific aerosol microphysics + mam4::GasAerExchProcess::ProcessConfig condensation; + mam4::NucleationProcess::ProcessConfig nucleation; + + // controls treatment of h2so4 condensation in mam_gasaerexch_1subarea + // 1 = sequential calc. of gas-chem prod then condensation loss + // 2 = simultaneous calc. of gas-chem prod and condensation loss + int gaexch_h2so4_uptake_optaa; + + // controls how nucleation interprets h2so4 concentrations + int newnuc_h2so4_conc_optaa; +}; + +namespace { + +KOKKOS_INLINE_FUNCTION constexpr int nqtendaa() { return 5; } +KOKKOS_INLINE_FUNCTION constexpr int nqqcwtendaa() { return 1; } +KOKKOS_INLINE_FUNCTION constexpr int nqqcwtendbb() { return 1; } +KOKKOS_INLINE_FUNCTION constexpr int iqtend_cond() { return 0; } +KOKKOS_INLINE_FUNCTION constexpr int iqtend_rnam() { return 1; } +KOKKOS_INLINE_FUNCTION constexpr int iqtend_nnuc() { return 2; } +KOKKOS_INLINE_FUNCTION constexpr int iqtend_coag() { return 3; } +KOKKOS_INLINE_FUNCTION constexpr int iqtend_cond_only() { return 4; } +KOKKOS_INLINE_FUNCTION constexpr int iqqcwtend_rnam() { return 0; } +KOKKOS_INLINE_FUNCTION constexpr int maxsubarea() { return 2; } + +// conversion factors +KOKKOS_INLINE_FUNCTION Real fcvt_gas(int gas_id) { + static const Real fcvt_gas_[AeroConfig::num_gas_ids()] = {1, 1, 1}; + return fcvt_gas_[gas_id]; +} +KOKKOS_INLINE_FUNCTION Real fcvt_aer(int aero_id) { + static const Real fcvt_aer_[AeroConfig::num_aerosol_ids()] = {1, 1, 1, 1, 1, 1, 1}; + return fcvt_aer_[aero_id]; +} + +// leave number mix-ratios unchanged (#/kmol-air) +KOKKOS_INLINE_FUNCTION Real fcvt_num() { return 1.0; } +// factor for converting aerosol water mix-ratios from (kg/kg) to (mol/mol) +KOKKOS_INLINE_FUNCTION Real fcvt_wtr() { return 1.0; } + +KOKKOS_INLINE_FUNCTION constexpr int lmapcc_val_nul() { return 0; } +KOKKOS_INLINE_FUNCTION constexpr int lmapcc_val_gas() { return 1; } +KOKKOS_INLINE_FUNCTION constexpr int lmapcc_val_aer() { return 2; } +KOKKOS_INLINE_FUNCTION constexpr int lmapcc_val_num() { return 3; } +KOKKOS_INLINE_FUNCTION int lmapcc_all(int index) { + static const int lmapcc_all_[gas_pcnst()] = { + lmapcc_val_nul(), lmapcc_val_gas(), lmapcc_val_nul(), lmapcc_val_nul(), + lmapcc_val_gas(), lmapcc_val_aer(), lmapcc_val_aer(), lmapcc_val_aer(), + lmapcc_val_aer(), lmapcc_val_aer(), lmapcc_val_aer(), lmapcc_val_aer(), + lmapcc_val_num(), lmapcc_val_aer(), lmapcc_val_aer(), lmapcc_val_aer(), + lmapcc_val_aer(), lmapcc_val_num(), lmapcc_val_aer(), lmapcc_val_aer(), + lmapcc_val_aer(), lmapcc_val_aer(), lmapcc_val_aer(), lmapcc_val_aer(), + lmapcc_val_aer(), lmapcc_val_num(), lmapcc_val_aer(), lmapcc_val_aer(), + lmapcc_val_aer(), lmapcc_val_num()}; + return lmapcc_all_[index]; +} + +// Where lmapcc_val_num are defined in lmapcc_all +KOKKOS_INLINE_FUNCTION int numptr_amode(int mode) { + static const int numptr_amode_[AeroConfig::num_modes()] = {12, 17, 25, 29}; + return numptr_amode_[mode]; +} + +// Where lmapcc_val_gas are defined in lmapcc_all +KOKKOS_INLINE_FUNCTION int lmap_gas(int mode) { + static const int lmap_gas_[AeroConfig::num_modes()] = {4, 1}; + return lmap_gas_[mode]; +} +// Where lmapcc_val_aer are defined in lmapcc_all +KOKKOS_INLINE_FUNCTION int lmassptr_amode(int aero_id, int mode) { + static const int lmassptr_amode_[AeroConfig::num_aerosol_ids()][AeroConfig::num_modes()] = { + {5, 13, 18, 26}, {6, 14, 19, 27}, {7, 15, 20, 28}, {8, 16, 21, -6}, + {9, -6, 22, -6}, {10, -6, 23, -6}, {11, -6, 24, -6}}; + return lmassptr_amode_[aero_id][mode]; +} + +KOKKOS_INLINE_FUNCTION +void subarea_partition_factors( + const Real + q_int_cell_avg, // in grid cell mean interstitial aerosol mixing ratio + const Real + q_cbn_cell_avg, // in grid cell mean cloud-borne aerosol mixing ratio + const Real fcldy, // in cloudy fraction of the grid cell + const Real fclea, // in clear fraction of the grid cell + Real &part_fac_q_int_clea, // out + Real &part_fac_q_int_cldy) // out +{ + // Calculate mixing ratios of each subarea + + // cloud-borne, cloudy subarea + const Real tmp_q_cbn_cldy = q_cbn_cell_avg / fcldy; + // interstitial, cloudy subarea + const Real tmp_q_int_cldy = + haero::max(0.0, ((q_int_cell_avg + q_cbn_cell_avg) - tmp_q_cbn_cldy)); + // interstitial, clear subarea + const Real tmp_q_int_clea = (q_int_cell_avg - fcldy * tmp_q_int_cldy) / fclea; + + // Calculate the corresponding paritioning factors for interstitial aerosols + // using the above-derived subarea mixing ratios plus the constraint that + // the cloud fraction weighted average of subarea mean need to match grid box + // mean. + + // *** question *** + // use same part_fac_q_int_clea/cldy for everything ? + // use one for number and one for all masses (based on total mass) ? + // use separate ones for everything ? + // maybe one for number and one for all masses is best, + // because number and mass have different activation fractions + // *** question *** + + Real tmp_aa = haero::max(1.e-35, tmp_q_int_clea * fclea) / + haero::max(1.e-35, q_int_cell_avg); + tmp_aa = haero::max(0.0, haero::min(1.0, tmp_aa)); + + part_fac_q_int_clea = tmp_aa / fclea; + part_fac_q_int_cldy = (1.0 - tmp_aa) / fcldy; +} + +KOKKOS_INLINE_FUNCTION +void construct_subareas_1gridcell( + const Real cld, // in + const Real relhumgcm, // in + const Real q_pregaschem[gas_pcnst()], // in q TMRs before + // gas-phase chemistry + const Real q_precldchem[gas_pcnst()], // in q TMRs before + // cloud chemistry + const Real qqcw_precldchem[gas_pcnst()], // in qqcw TMRs before + // cloud chemistry + const Real q[gas_pcnst()], // in current tracer mixing ratios (TMRs) + // *** MUST BE #/kmol-air for number + // *** MUST BE mol/mol-air for mass + const Real qqcw[gas_pcnst()], // in like q but for + // cloud-borner tracers + int &nsubarea, // out + int &ncldy_subarea, // out + int &jclea, // out + int &jcldy, // out + bool iscldy_subarea[maxsubarea()], // out + Real afracsub[maxsubarea()], // out + Real relhumsub[maxsubarea()], // out + Real qsub1[gas_pcnst()][maxsubarea()], // out interstitial + Real qsub2[gas_pcnst()][maxsubarea()], // out interstitial + Real qsub3[gas_pcnst()][maxsubarea()], // out interstitial + Real qqcwsub1[gas_pcnst()][maxsubarea()], // out cloud-borne + Real qqcwsub2[gas_pcnst()][maxsubarea()], // out cloud-borne + Real qqcwsub3[gas_pcnst()][maxsubarea()], // outcloud-borne + Real qaerwatsub3[AeroConfig::num_modes()] + [maxsubarea()], // out aerosol water mixing ratios (mol/mol) + Real qaerwat[AeroConfig::num_modes()] // in aerosol water mixing ratio + // (kg/kg, NOT mol/mol) +) { + static constexpr int num_modes = AeroConfig::num_modes(); + // cloud chemistry is only on when cld(i,k) >= 1.0e-5_wp + // it may be that the macrophysics has a higher threshold that this + const Real fcld_locutoff = 1.0e-5; + const Real fcld_hicutoff = 0.999; + + // qgcmN and qqcwgcmN (N=1:4) are grid-cell mean tracer mixing ratios (TMRs, + // mol/mol or #/kmol) + // N=1 - before gas-phase chemistry + // N=2 - before cloud chemistry + // N=3 - incoming values (before gas-aerosol exchange, newnuc, coag) + // qgcm1, qgcm2, qgcm3 + // qqcwgcm2, qqcwgcm3 + // qaerwatgcm3 ! aerosol water mixing ratios (mol/mol) + + // -------------------------------------------------------------------------------------- + // Determine the number of sub-areas, their fractional areas, and relative + // humidities + // -------------------------------------------------------------------------------------- + // if cloud fraction ~= 0, the grid-cell has a single clear sub-area + // (nsubarea = 1) if cloud fraction ~= 1, the grid-cell has a single cloudy + // sub-area (nsubarea = 1) otherwise, the grid-cell has a + // clear and a cloudy sub-area (nsubarea = 2) + + Real zfcldy = 0; + nsubarea = 0; + ncldy_subarea = 0; + jclea = 0; + jcldy = 0; + + if (cld < fcld_locutoff) { + nsubarea = 1; + jclea = 1; + } else if (cld > fcld_hicutoff) { + zfcldy = 1.0; + nsubarea = 1; + ncldy_subarea = 1; + jcldy = 1; + } else { + zfcldy = cld; + nsubarea = 2; + ncldy_subarea = 1; + jclea = 1; + jcldy = 2; + } + + const Real zfclea = 1.0 - zfcldy; + for (int i = 0; i < maxsubarea(); ++i) + iscldy_subarea[i] = false; + if (jcldy > 0) + iscldy_subarea[jcldy - 1] = true; + for (int i = 0; i < maxsubarea(); ++i) + afracsub[i] = 0.0; + if (jclea > 0) + afracsub[jclea - 1] = zfclea; + if (jcldy > 0) + afracsub[jcldy - 1] = zfcldy; + + // cldy_rh_sameas_clear is just to match mam_refactor. Compiler should + // optimize away. + const int cldy_rh_sameas_clear = 0; + if (ncldy_subarea <= 0) { + for (int i = 0; i < maxsubarea(); ++i) + relhumsub[i] = relhumgcm; + } else if (cldy_rh_sameas_clear > 0) { + for (int i = 0; i < maxsubarea(); ++i) + relhumsub[i] = relhumgcm; + } else { + if (jcldy > 0) { + relhumsub[jcldy - 1] = 1.0; + if (jclea > 0) { + const Real tmpa = + (relhumgcm - afracsub[jcldy - 1]) / afracsub[jclea - 1]; + relhumsub[jclea - 1] = haero::max(0.0, haero::min(1.0, tmpa)); + } + } + } + + // ---------------------------------------------------------------------------- + // Copy grid cell mean mixing ratios. + // These values, together with cloud fraction and a few assumptions, are used + // in the remainder of the subroutine to calculate the sub-area mean mixing + // ratios. + // ---------------------------------------------------------------------------- + // Interstitial aerosols + Real qgcm1[gas_pcnst()], qgcm2[gas_pcnst()], qgcm3[gas_pcnst()]; + for (int i = 0; i < gas_pcnst(); ++i) { + qgcm1[i] = haero::max(0.0, q_pregaschem[i]); + qgcm2[i] = haero::max(0.0, q_precldchem[i]); + qgcm3[i] = haero::max(0.0, q[i]); + } + + // Cloud-borne aerosols + Real qqcwgcm2[gas_pcnst()], qqcwgcm3[gas_pcnst()]; + for (int i = 0; i < gas_pcnst(); ++i) { + qqcwgcm2[i] = haero::max(0.0, qqcw_precldchem[i]); + qqcwgcm3[i] = haero::max(0.0, qqcw[i]); + } + + // aerosol water + Real qaerwatgcm3[num_modes] = {}; + for (int i = 0; i < num_modes; ++i) { + qaerwatgcm3[i] = haero::max(0.0, qaerwat[i]); + } + + // ---------------------------------------------------------------------------- + // Initialize the subarea mean mixing ratios + // ---------------------------------------------------------------------------- + { + const int n = haero::min(maxsubarea(), nsubarea + 1); + for (int i = 0; i < n; ++i) { + for (int j = 0; j < gas_pcnst(); ++j) { + qsub1[j][i] = 0.0; + qsub2[j][i] = 0.0; + qsub3[j][i] = 0.0; + qqcwsub1[j][i] = 0.0; + qqcwsub2[j][i] = 0.0; + qqcwsub3[j][i] = 0.0; + } + for (int j = 0; j < num_modes; ++j) { + qaerwatsub3[j][i] = 0.0; + } + } + } + + // ************************************************************************************************* + // Calculate initial (i.e., before cond/rnam/nnuc/coag) tracer mixing + // ratios within the sub-areas + // - for all-clear or all-cloudy cases, the sub-area TMRs are equal to the + // grid-cell means + // - for partly cloudy case, they are different. This is primarily + // because the + // interstitial aerosol mixing ratios are assumed lower in the cloudy + // sub-area than in the clear sub-area, because much of the aerosol is + // activated in the cloudy sub-area. + // ************************************************************************************************* + // Category I: partly cloudy case + // ************************************************************************************************* + if ((jclea > 0) && (jcldy > 0) && (jclea + jcldy == 3) && (nsubarea == 2)) { + + // --------------------------------------------------------------------- + // Set GAS mixing ratios in sub-areas (for the condensing gases only!!) + // --------------------------------------------------------------------- + for (int lmz = 0; lmz < gas_pcnst(); ++lmz) { + if (lmapcc_all(lmz) == lmapcc_val_gas()) { + + // assume gas in both sub-areas before gas-chem and cloud-chem equal + // grid-cell mean + for (int i = 0; i < nsubarea; ++i) { + qsub1[lmz][i] = qgcm1[lmz]; + qsub2[lmz][i] = qgcm2[lmz]; + } + // assume gas in clear sub-area after cloud-chem equals before + // cloud-chem value + qsub3[lmz][jclea - 1] = qsub2[lmz][jclea - 1]; + // gas in cloud sub-area then determined by grid-cell mean and clear + // values + qsub3[lmz][jcldy - 1] = + (qgcm3[lmz] - zfclea * qsub3[lmz][jclea - 1]) / zfcldy; + + // check that this does not produce a negative value + if (qsub3[lmz][jcldy - 1] < 0.0) { + qsub3[lmz][jcldy - 1] = 0.0; + qsub3[lmz][jclea - 1] = qgcm3[lmz] / zfclea; + } + } + } + // --------------------------------------------------------------------- + // Set CLOUD-BORNE AEROSOL mixing ratios in sub-areas. + // This is straightforward, as the same partitioning factors (0 or 1/f) + // are applied to all mass and number mixing ratios in all modes. + // --------------------------------------------------------------------- + // loop thru log-normal modes + for (int n = 0; n < num_modes; ++n) { + // number - then mass of individual species - of a mode + for (int l2 = -1; l2 < num_species_mode(n); ++l2) { + int lc; + if (l2 == -1) + lc = numptr_amode(n); + else + lc = lmassptr_amode(l2, n); + qqcwsub2[lc][jclea - 1] = 0.0; + qqcwsub2[lc][jcldy - 1] = qqcwgcm2[lc] / zfcldy; + qqcwsub3[lc][jclea - 1] = 0.0; + qqcwsub3[lc][jcldy - 1] = qqcwgcm3[lc] / zfcldy; + } + } + + // --------------------------------------------------------------------- + // Set INTERSTITIAL AEROSOL mixing ratios in sub-areas. + // --------------------------------------------------------------------- + for (int n = 0; n < num_modes; ++n) { + // ------------------------------------- + // Aerosol number + // ------------------------------------- + // grid cell mean, interstitial + Real tmp_q_cellavg_int = qgcm2[numptr_amode(n)]; + // grid cell mean, cloud-borne + Real tmp_q_cellavg_cbn = qqcwgcm2[numptr_amode(n)]; + + Real nmbr_part_fac_clea = 0; + Real nmbr_part_fac_cldy = 0; + subarea_partition_factors(tmp_q_cellavg_int, tmp_q_cellavg_cbn, zfcldy, + zfclea, nmbr_part_fac_clea, nmbr_part_fac_cldy); + + // Apply the partitioning factors to calculate sub-area mean number + // mixing ratios + + const int la = numptr_amode(n); + + qsub2[la][jclea - 1] = qgcm2[la] * nmbr_part_fac_clea; + qsub2[la][jcldy - 1] = qgcm2[la] * nmbr_part_fac_cldy; + qsub3[la][jclea - 1] = qgcm3[la] * nmbr_part_fac_clea; + qsub3[la][jcldy - 1] = qgcm3[la] * nmbr_part_fac_cldy; + + //------------------------------------- + // Aerosol mass + //------------------------------------- + // For aerosol mass, we use the total grid cell mean + // interstitial/cloud-borne mass mixing ratios to come up with the same + // partitioning for all species in the mode. + + // Compute the total mixing ratios by summing up the individual species + + tmp_q_cellavg_int = 0.0; // grid cell mean, interstitial + tmp_q_cellavg_cbn = 0.0; // grid cell mean, cloud-borne + + for (int l2 = 0; l2 < num_species_mode(n); ++l2) { + tmp_q_cellavg_int += qgcm2[lmassptr_amode(l2, n)]; + tmp_q_cellavg_cbn += qqcwgcm2[lmassptr_amode(l2, n)]; + } + Real mass_part_fac_clea = 0; + Real mass_part_fac_cldy = 0; + // Calculate the partitioning factors + subarea_partition_factors(tmp_q_cellavg_int, tmp_q_cellavg_cbn, zfcldy, + zfclea, mass_part_fac_clea, mass_part_fac_cldy); + + // Apply the partitioning factors to calculate sub-area mean mass mixing + // ratios + + for (int l2 = 0; l2 < num_species_mode(n); ++l2) { + const int la = lmassptr_amode(l2, n); + + qsub2[la][jclea - 1] = qgcm2[la] * mass_part_fac_clea; + qsub2[la][jcldy - 1] = qgcm2[la] * mass_part_fac_cldy; + qsub3[la][jclea - 1] = qgcm3[la] * mass_part_fac_clea; + qsub3[la][jcldy - 1] = qgcm3[la] * mass_part_fac_cldy; + } + } + + // ************************************************************************************************* + // Category II: all clear, or cld < 1e-5 + // In this case, zfclea=1 and zfcldy=0 + // ************************************************************************************************* + } else if ((jclea == 1) && (jcldy == 0) && (nsubarea == 1)) { + // + // put all the gases and interstitial aerosols in the clear sub-area + // and set mix-ratios = 0 in cloudy sub-area + // for cloud-borne aerosol, do nothing + // because the grid-cell-mean cloud-borne aerosol will be left + // unchanged (i.e., this routine only changes qqcw when cld >= 1e-5) + // + + for (int lmz = 0; lmz < gas_pcnst(); ++lmz) { + if (0 < lmapcc_all(lmz)) { + qsub1[lmz][jclea - 1] = qgcm1[lmz]; + qsub2[lmz][jclea - 1] = qgcm2[lmz]; + qsub3[lmz][jclea - 1] = qgcm3[lmz]; + qqcwsub2[lmz][jclea - 1] = qqcwgcm2[lmz]; + qqcwsub3[lmz][jclea - 1] = qqcwgcm3[lmz]; + } + } + // ************************************************************************************************* + // Category III: all cloudy, or cld > 0.999 + // in this case, zfcldy= and zfclea=0 + // ************************************************************************************************* + } else if ((jclea == 0) && (jcldy == 1) && (nsubarea == 1)) { + // + // put all the gases and interstitial aerosols in the cloudy sub-area + // and set mix-ratios = 0 in clear sub-area + // + for (int lmz = 0; lmz < gas_pcnst(); ++lmz) { + if (0 < lmapcc_all(lmz)) { + qsub1[lmz][jcldy - 1] = qgcm1[lmz]; + qsub2[lmz][jcldy - 1] = qgcm2[lmz]; + qsub3[lmz][jcldy - 1] = qgcm3[lmz]; + qqcwsub2[lmz][jcldy - 1] = qqcwgcm2[lmz]; + qqcwsub3[lmz][jcldy - 1] = qqcwgcm3[lmz]; + } + } + // ************************************************************************************************* + } else { // this should not happen + EKAT_KERNEL_REQUIRE_MSG(false, "*** modal_aero_amicphys - bad jclea, jcldy, nsubarea!"); + } + // ************************************************************************************************* + + // ------------------------------------------------------------------------------------ + // aerosol water -- how to treat this in sub-areas needs more work/thinking + // currently modal_aero_water_uptake calculates qaerwat using + // the grid-cell mean interstital-aerosol mix-rats and the clear-area rh + for (int jsub = 0; jsub < nsubarea; ++jsub) + for (int i = 0; i < num_modes; ++i) + qaerwatsub3[i][jsub] = qaerwatgcm3[i]; + + // ------------------------------------------------------------------------------------ + if (nsubarea == 1) { + // the j=1 subarea is used for some diagnostics + // but is not used in actual calculations + const int j = 1; + for (int i = 0; i < gas_pcnst(); ++i) { + qsub1[i][j] = 0.0; + qsub2[i][j] = 0.0; + qsub3[i][j] = 0.0; + qqcwsub2[i][j] = 0.0; + qqcwsub3[i][j] = 0.0; + } + } +} + +KOKKOS_INLINE_FUNCTION +void mam_amicphys_1subarea_clear( + const AmicPhysConfig& config, const int nstep, const Real deltat, const int jsub, + const int nsubarea, const bool iscldy_subarea, const Real afracsub, + const Real temp, const Real pmid, const Real pdel, const Real zmid, + const Real pblh, const Real relhum, Real dgn_a[AeroConfig::num_modes()], + Real dgn_awet[AeroConfig::num_modes()], + Real wetdens[AeroConfig::num_modes()], + const Real qgas1[AeroConfig::num_gas_ids()], + const Real qgas3[AeroConfig::num_gas_ids()], + Real qgas4[AeroConfig::num_gas_ids()], + Real qgas_delaa[AeroConfig::num_gas_ids()][nqtendaa()], + const Real qnum3[AeroConfig::num_modes()], + Real qnum4[AeroConfig::num_modes()], + Real qnum_delaa[AeroConfig::num_modes()][nqtendaa()], + const Real qaer3[AeroConfig::num_aerosol_ids()][AeroConfig::num_modes()], + Real qaer4[AeroConfig::num_aerosol_ids()][AeroConfig::num_modes()], + Real qaer_delaa[AeroConfig::num_aerosol_ids()][AeroConfig::num_modes()] + [nqtendaa()], + const Real qwtr3[AeroConfig::num_modes()], + Real qwtr4[AeroConfig::num_modes()]) { + static constexpr int num_gas_ids = AeroConfig::num_gas_ids(); + static constexpr int num_modes = AeroConfig::num_modes(); + static constexpr int num_aerosol_ids = AeroConfig::num_aerosol_ids(); + + static constexpr int igas_h2so4 = static_cast(GasId::H2SO4); + // Turn off nh3 for now. This is a future enhancement. + static constexpr int igas_nh3 = -999888777; // Same as mam_refactor + static constexpr int iaer_so4 = static_cast(AeroId::SO4); + static constexpr int iaer_pom = static_cast(AeroId::POM); + + const AeroId gas_to_aer[num_gas_ids] = {AeroId::SOA, AeroId::SO4, + AeroId::None}; + + const bool l_gas_condense_to_mode[num_gas_ids][num_modes] = { + {true, true, true, true}, + {true, true, true, true}, + {false, false, false, false}}; + enum { NA, ANAL, IMPL }; + const int eqn_and_numerics_category[num_gas_ids] = {IMPL, ANAL, ANAL}; + + // air molar density (kmol/m3) + // const Real r_universal = Constants::r_gas; // [mJ/(K mol)] + const Real r_universal = 8.314467591; // [mJ/(mol)] as in mam_refactor + const Real aircon = pmid / (1000 * r_universal * temp); + const Real alnsg_aer[num_modes] = {0.58778666490211906, 0.47000362924573563, + 0.58778666490211906, 0.47000362924573563}; + const Real uptk_rate_factor[num_gas_ids] = {0.81, 1.0, 1.0}; + // calculates changes to gas and aerosol sub-area TMRs (tracer mixing ratios) + // qgas3, qaer3, qnum3 are the current incoming TMRs + // qgas4, qaer4, qnum4 are the updated outgoing TMRs + // + // this routine calculates changes involving + // gas-aerosol exchange (condensation/evaporation) + // growth from smaller to larger modes (renaming) due to condensation + // new particle nucleation + // coagulation + // transfer of particles from hydrophobic modes to hydrophilic modes + // (aging) + // due to condensation and coagulation + // + // qXXXN (X=gas,aer,wat,num; N=1:4) are sub-area mixing ratios + // XXX=gas - gas species + // XXX=aer - aerosol mass species (excluding water) + // XXX=wat - aerosol water + // XXX=num - aerosol number + // N=1 - before gas-phase chemistry + // N=2 - before cloud chemistry + // N=3 - current incoming values (before gas-aerosol exchange, newnuc, + // coag) N=4 - updated outgoing values (after gas-aerosol exchange, + // newnuc, coag) + // + // qXXX_delaa are TMR changes (not tendencies) + // for different processes, which are used to produce history output + // for a clear sub-area, the processes are condensation/evaporation (and + // associated aging), renaming, coagulation, and nucleation + + Real qgas_cur[num_gas_ids]; + for (int i = 0; i < num_gas_ids; ++i) + qgas_cur[i] = qgas3[i]; + Real qaer_cur[num_aerosol_ids][num_modes]; + for (int i = 0; i < num_aerosol_ids; ++i) + for (int j = 0; j < num_modes; ++j) + qaer_cur[i][j] = qaer3[i][j]; + + Real qnum_cur[num_modes]; + for (int j = 0; j < num_modes; ++j) + qnum_cur[j] = qnum3[j]; + Real qwtr_cur[num_modes]; + for (int j = 0; j < num_modes; ++j) + qwtr_cur[j] = qwtr3[j]; + + // qgas_netprod_otrproc = gas net production rate from other processes + // such as gas-phase chemistry and emissions (mol/mol/s) + // this allows the condensation (gasaerexch) routine to apply production and + // condensation loss + // together, which is more accurate numerically + // NOTE - must be >= zero, as numerical method can fail when it is negative + // NOTE - currently only the values for h2so4 and nh3 should be non-zero + Real qgas_netprod_otrproc[num_gas_ids] = {}; + if (config.do_cond && config.gaexch_h2so4_uptake_optaa == 2) { + for (int igas = 0; igas < num_gas_ids; ++igas) { + if (igas == igas_h2so4 || igas == igas_nh3) { + // if config.gaexch_h2so4_uptake_optaa == 2, then + // if qgas increases from pre-gaschem to post-cldchem, + // start from the pre-gaschem mix-ratio and add in the production + // during the integration + // if it decreases, + // start from post-cldchem mix-ratio + // *** currently just do this for h2so4 and nh3 + qgas_netprod_otrproc[igas] = (qgas3[igas] - qgas1[igas]) / deltat; + if (qgas_netprod_otrproc[igas] >= 0.0) + qgas_cur[igas] = qgas1[igas]; + else + qgas_netprod_otrproc[igas] = 0.0; + } + } + } + Real qgas_del_cond[num_gas_ids] = {}; + Real qgas_del_nnuc[num_gas_ids] = {}; + Real qgas_del_cond_only[num_gas_ids] = {}; + Real qaer_del_cond[num_aerosol_ids][num_modes] = {}; + Real qaer_del_rnam[num_aerosol_ids][num_modes] = {}; + Real qaer_del_nnuc[num_aerosol_ids][num_modes] = {}; + Real qaer_del_coag[num_aerosol_ids][num_modes] = {}; + Real qaer_delsub_coag_in[num_aerosol_ids][AeroConfig::max_agepair()] = {}; + Real qaer_delsub_cond[num_aerosol_ids][num_modes] = {}; + Real qaer_delsub_coag[num_aerosol_ids][num_modes] = {}; + Real qaer_del_cond_only[num_aerosol_ids][num_modes] = {}; + Real qnum_del_cond[num_modes] = {}; + Real qnum_del_rnam[num_modes] = {}; + Real qnum_del_nnuc[num_modes] = {}; + Real qnum_del_coag[num_modes] = {}; + Real qnum_delsub_cond[num_modes] = {}; + Real qnum_delsub_coag[num_modes] = {}; + Real qnum_del_cond_only[num_modes] = {}; + Real dnclusterdt = 0.0; + + const int ntsubstep = 1; + Real dtsubstep = deltat; + if (ntsubstep > 1) + dtsubstep = deltat / ntsubstep; + Real del_h2so4_gasprod = + haero::max(qgas3[igas_h2so4] - qgas1[igas_h2so4], 0.0) / ntsubstep; + + // loop over multiple time sub-steps + for (int jtsubstep = 1; jtsubstep <= ntsubstep; ++jtsubstep) { + // gas-aerosol exchange + Real uptkrate_h2so4 = 0.0; + Real del_h2so4_aeruptk = 0.0; + Real qaer_delsub_grow4rnam[num_aerosol_ids][num_modes] = {}; + Real qgas_avg[num_gas_ids] = {}; + Real qnum_sv1[num_modes] = {}; + Real qaer_sv1[num_aerosol_ids][num_modes] = {}; + Real qgas_sv1[num_gas_ids] = {}; + + if (config.do_cond) { + + const bool l_calc_gas_uptake_coeff = jtsubstep == 1; + Real uptkaer[num_gas_ids][num_modes] = {}; + + for (int i = 0; i < num_gas_ids; ++i) + qgas_sv1[i] = qgas_cur[i]; + for (int i = 0; i < num_modes; ++i) + qnum_sv1[i] = qnum_cur[i]; + for (int j = 0; j < num_aerosol_ids; ++j) + for (int i = 0; i < num_modes; ++i) + qaer_sv1[j][i] = qaer_cur[j][i]; + + // time sub-step + const Real dtsub_soa_fixed = -1.0; + // Integration order + const int nghq = 2; + const int ntot_soamode = 4; + int niter_out = 0; + Real g0_soa_out = 0; + // gasaerexch::mam_gasaerexch_1subarea( + // nghq, igas_h2so4, igas_nh3, ntot_soamode, gas_to_aer, iaer_so4, + // iaer_pom, l_calc_gas_uptake_coeff, l_gas_condense_to_mode, + // eqn_and_numerics_category, dtsubstep, dtsub_soa_fixed, temp, pmid, + // aircon, num_gas_ids, qgas_cur, qgas_avg, qgas_netprod_otrproc, + // qaer_cur, qnum_cur, dgn_awet, alnsg_aer, uptk_rate_factor, uptkaer, + // uptkrate_h2so4, niter_out, g0_soa_out); + + if (config.newnuc_h2so4_conc_optaa == 11) + qgas_avg[igas_h2so4] = + 0.5 * (qgas_sv1[igas_h2so4] + qgas_cur[igas_h2so4]); + else if (config.newnuc_h2so4_conc_optaa == 12) + qgas_avg[igas_h2so4] = qgas_cur[igas_h2so4]; + + for (int i = 0; i < num_gas_ids; ++i) + qgas_del_cond[i] += + (qgas_cur[i] - (qgas_sv1[i] + qgas_netprod_otrproc[i] * dtsubstep)); + + for (int i = 0; i < num_modes; ++i) + qnum_delsub_cond[i] = qnum_cur[i] - qnum_sv1[i]; + for (int i = 0; i < num_aerosol_ids; ++i) + for (int j = 0; j < num_modes; ++j) + qaer_delsub_cond[i][j] = qaer_cur[i][j] - qaer_sv1[i][j]; + + // qaer_del_grow4rnam = change in qaer_del_cond during latest condensation + // calculations + for (int i = 0; i < num_aerosol_ids; ++i) + for (int j = 0; j < num_modes; ++j) + qaer_delsub_grow4rnam[i][j] = qaer_cur[i][j] - qaer_sv1[i][j]; + for (int i = 0; i < num_gas_ids; ++i) + qgas_del_cond_only[i] = qgas_del_cond[i]; + for (int i = 0; i < num_aerosol_ids; ++i) + for (int j = 0; j < num_modes; ++j) + qaer_del_cond_only[i][j] = qaer_delsub_cond[i][j]; + for (int i = 0; i < num_modes; ++i) + qnum_del_cond_only[i] = qnum_delsub_cond[i]; + del_h2so4_aeruptk = + qgas_cur[igas_h2so4] - + (qgas_sv1[igas_h2so4] + qgas_netprod_otrproc[igas_h2so4] * dtsubstep); + } else { + for (int i = 0; i < num_gas_ids; ++i) + qgas_avg[i] = qgas_cur[i]; + } + + // renaming after "continuous growth" + if (config.do_rename) { + constexpr int nmodes = AeroConfig::num_modes(); + constexpr int naerosol_species = AeroConfig::num_aerosol_ids(); + const Real smallest_dryvol_value = 1.0e-25; // BAD_CONSTANT + const int dest_mode_of_mode[nmodes] = {-1, 0, -1, -1}; + + Real qnumcw_cur[num_modes] = {}; + Real qaercw_cur[num_aerosol_ids][num_modes] = {}; + Real qaercw_delsub_grow4rnam[num_aerosol_ids][num_modes] = {}; + Real mean_std_dev[nmodes]; + Real fmode_dist_tail_fac[nmodes]; + Real v2n_lo_rlx[nmodes]; + Real v2n_hi_rlx[nmodes]; + Real ln_diameter_tail_fac[nmodes]; + int num_pairs = 0; + Real diameter_cutoff[nmodes]; + Real ln_dia_cutoff[nmodes]; + Real diameter_threshold[nmodes]; + Real mass_2_vol[naerosol_species] = {0.15, + 6.4971751412429377e-002, + 0.15, + 7.0588235294117650e-003, + 3.0789473684210526e-002, + 5.1923076923076926e-002, + 156.20986883198000}; + + rename::find_renaming_pairs(dest_mode_of_mode, // in + mean_std_dev, // out + fmode_dist_tail_fac, // out + v2n_lo_rlx, // out + v2n_hi_rlx, // out + ln_diameter_tail_fac, // out + num_pairs, // out + diameter_cutoff, // out + ln_dia_cutoff, diameter_threshold); + + for (int i = 0; i < num_modes; ++i) + qnum_sv1[i] = qnum_cur[i]; + for (int j = 0; j < num_aerosol_ids; ++j) + for (int i = 0; i < num_modes; ++i) + qaer_sv1[j][i] = qaer_cur[j][i]; + Real dgnum_amode[nmodes]; + for (int m = 0; m < nmodes; ++m) { + dgnum_amode[m] = modes(m).nom_diameter; + } + + { + Real qmol_i_cur[num_modes][num_aerosol_ids]; + Real qmol_i_del[num_modes][num_aerosol_ids]; + Real qmol_c_cur[num_modes][num_aerosol_ids]; + Real qmol_c_del[num_modes][num_aerosol_ids]; + for (int j = 0; j < num_aerosol_ids; ++j) + for (int i = 0; i < num_modes; ++i) { + qmol_i_cur[i][j] = qaer_cur[j][i]; + qmol_i_del[i][j] = qaer_delsub_grow4rnam[j][i]; + qmol_c_cur[i][j] = qaercw_cur[j][i]; + qmol_c_del[i][j] = qaercw_delsub_grow4rnam[j][i]; + } + Rename rename; + rename.mam_rename_1subarea_( + iscldy_subarea, smallest_dryvol_value, dest_mode_of_mode, + mean_std_dev, fmode_dist_tail_fac, v2n_lo_rlx, v2n_hi_rlx, + ln_diameter_tail_fac, num_pairs, diameter_cutoff, ln_dia_cutoff, + diameter_threshold, mass_2_vol, dgnum_amode, qnum_cur, qmol_i_cur, + qmol_i_del, qnumcw_cur, qmol_c_cur, qmol_c_del); + + for (int j = 0; j < num_aerosol_ids; ++j) + for (int i = 0; i < num_modes; ++i) { + qaer_cur[j][i] = qmol_i_cur[i][j]; + qaer_delsub_grow4rnam[j][i] = qmol_i_del[i][j]; + qaercw_cur[j][i] = qmol_c_cur[i][j]; + qaercw_delsub_grow4rnam[j][i] = qmol_c_del[i][j]; + } + } + + for (int i = 0; i < num_modes; ++i) + qnum_del_rnam[i] += qnum_cur[i] - qnum_sv1[i]; + for (int i = 0; i < num_aerosol_ids; ++i) + for (int j = 0; j < num_modes; ++j) + qaer_del_rnam[i][j] += qaer_cur[i][j] - qaer_sv1[i][j]; + } + + // new particle formation (nucleation) + if (config.do_newnuc) { + for (int i = 0; i < num_gas_ids; ++i) + qgas_sv1[i] = qgas_cur[i]; + for (int i = 0; i < num_modes; ++i) + qnum_sv1[i] = qnum_cur[i]; + Real qaer_cur_tmp[num_modes][num_aerosol_ids]; + for (int j = 0; j < num_aerosol_ids; ++j) + for (int i = 0; i < num_modes; ++i) { + qaer_sv1[j][i] = qaer_cur[j][i]; + qaer_cur_tmp[i][j] = qaer_cur[j][i]; + } + Real dnclusterdt_substep = 0; + Real dndt_ait = 0; + Real dmdt_ait = 0; + Real dso4dt_ait = 0; + Real dnh4dt_ait = 0; + Nucleation nucleation; + Nucleation::Config config; + // config.dens_so4a_host = 1770; + config.mw_nh4a_host = 115; + config.mw_so4a_host = 115; + // config.accom_coef_h2so4 = 0.65; + AeroConfig aero_config; + nucleation.init(aero_config, config); + // new version after switching from box model version of nucleation + // compute_tendencies_( + // // Real deltat, + // // Real temp_in, + // // Real press_in, + // // Real zm_in, + // // Real pblh_in, + // // Real relhum, + // // Real uptkrate_h2so4, + // const int nsize, // missing? + // const Real dp_lo_mode, + // const Real dp_hi_mode, + // // const Real qgas_cur[num_gases], + // // const Real qgas_avg[num_gases], + // int &isize_nuc, + // // Real &qnuma_del, + // // Real &qso4a_del, + // // Real &qnh4a_del, + // // Real &qh2so4_del, + // Real &qnh3_del, + // // Real &dnclusterdt + // ) + // old, box-model-based version + // nucleation.compute_tendencies_( + // dtsubstep, temp, pmid, aircon, zmid, pblh, relhum, uptkrate_h2so4, + // del_h2so4_gasprod, del_h2so4_aeruptk, qgas_cur, qgas_avg, qnum_cur, + // qaer_cur_tmp, qwtr_cur, dndt_ait, dmdt_ait, dso4dt_ait, dnh4dt_ait, + // dnclusterdt_substep); + // nucleation.compute_tendencies_( + // dtsubstep, // deltat + // temp, // temp_in + // pmid, // press_in + // aircon, // ? + // zmid, // zm_in + // pblh, // pblh_in + // relhum, // relhum + // uptkrate_h2so4, // uptkrate_h2so4 + // // nsize? + // // dp_lo_mode? + // // dp_hi_mode? + // del_h2so4_aeruptk, // uptkrate_h2so4? + // qgas_cur, // qgas_cur[num_gases]? + // qgas_avg, // qgas_avg[num_gases]? + // // isize_nuc? + // qnum_cur, // qnuma_del? + // qaer_cur_tmp, // ? + // qwtr_cur, // ? + // dndt_ait, // + // dmdt_ait, // + // dso4dt_ait, // qso4a_del + // dnh4dt_ait, // qnh4a_del + // del_h2so4_gasprod, // qh2so4_del? + // // qnh3_del? + // dnclusterdt_substep // dnclusterdt + // ); + for (int j = 0; j < num_aerosol_ids; ++j) + for (int i = 0; i < num_modes; ++i) + qaer_cur[j][i] = qaer_cur_tmp[i][j]; + + //! Apply the tendencies to the prognostics. + const int nait = static_cast(ModeIndex::Aitken); + qnum_cur[nait] += dndt_ait * dtsubstep; + + if (dso4dt_ait > 0.0) { + static constexpr int iaer_so4 = static_cast(AeroId::SO4); + static constexpr int igas_h2so4 = static_cast(GasId::H2SO4); + + Real delta_q = dso4dt_ait * dtsubstep; + qaer_cur[iaer_so4][nait] += delta_q; + delta_q = haero::min(delta_q, qgas_cur[igas_h2so4]); + qgas_cur[igas_h2so4] -= delta_q; + } + + if (igas_nh3 > 0 && dnh4dt_ait > 0.0) { + static constexpr int iaer_nh4 = + -9999999; // static_cast(AeroId::NH4); + + Real delta_q = dnh4dt_ait * dtsubstep; + qaer_cur[iaer_nh4][nait] += delta_q; + delta_q = haero::min(delta_q, qgas_cur[igas_nh3]); + qgas_cur[igas_nh3] -= delta_q; + } + for (int i = 0; i < num_gas_ids; ++i) + qgas_del_nnuc[i] += (qgas_cur[i] - qgas_sv1[i]); + for (int i = 0; i < num_modes; ++i) + qnum_del_nnuc[i] += (qnum_cur[i] - qnum_sv1[i]); + for (int j = 0; j < num_aerosol_ids; ++j) + for (int i = 0; i < num_modes; ++i) + qaer_del_nnuc[j][i] += (qaer_cur[j][i] - qaer_sv1[j][i]); + + dnclusterdt = dnclusterdt + dnclusterdt_substep * (dtsubstep / deltat); + } + + // coagulation part + if (config.do_coag) { + for (int i = 0; i < num_modes; ++i) + qnum_sv1[i] = qnum_cur[i]; + for (int j = 0; j < num_aerosol_ids; ++j) + for (int i = 0; i < num_modes; ++i) + qaer_sv1[j][i] = qaer_cur[j][i]; + // coagulation::mam_coag_1subarea(dtsubstep, temp, pmid, aircon, dgn_a, + // dgn_awet, wetdens, qnum_cur, qaer_cur, + // qaer_delsub_coag_in); + for (int i = 0; i < num_modes; ++i) + qnum_delsub_coag[i] = qnum_cur[i] - qnum_sv1[i]; + for (int j = 0; j < num_aerosol_ids; ++j) + for (int i = 0; i < num_modes; ++i) + qaer_delsub_coag[j][i] = qaer_cur[j][i] - qaer_sv1[j][i]; + } + + // primary carbon aging + + aging::mam_pcarbon_aging_1subarea( + dgn_a, qnum_cur, qnum_delsub_cond, qnum_delsub_coag, qaer_cur, + qaer_delsub_cond, qaer_delsub_coag, qaer_delsub_coag_in); + + // accumulate sub-step q-dels + if (config.do_coag) { + for (int i = 0; i < num_modes; ++i) + qnum_del_coag[i] += qnum_delsub_coag[i]; + for (int j = 0; j < num_aerosol_ids; ++j) + for (int i = 0; i < num_modes; ++i) + qaer_del_coag[j][i] += qaer_delsub_coag[j][i]; + } + if (config.do_cond) { + for (int i = 0; i < num_modes; ++i) + qnum_del_cond[i] += qnum_delsub_cond[i]; + for (int j = 0; j < num_aerosol_ids; ++j) + for (int i = 0; i < num_modes; ++i) + qaer_del_cond[j][i] += qaer_delsub_cond[j][i]; + } + } + + // final mix ratios + for (int i = 0; i < num_gas_ids; ++i) + qgas4[i] = qgas_cur[i]; + for (int j = 0; j < num_aerosol_ids; ++j) + for (int i = 0; i < num_modes; ++i) + qaer4[j][i] = qaer_cur[j][i]; + for (int i = 0; i < num_modes; ++i) + qnum4[i] = qnum_cur[i]; + for (int i = 0; i < num_modes; ++i) + qwtr4[i] = qwtr_cur[i]; + + // final mix ratio changes + for (int i = 0; i < num_gas_ids; ++i) { + qgas_delaa[i][iqtend_cond()] = qgas_del_cond[i]; + qgas_delaa[i][iqtend_rnam()] = 0.0; + qgas_delaa[i][iqtend_nnuc()] = qgas_del_nnuc[i]; + qgas_delaa[i][iqtend_coag()] = 0.0; + qgas_delaa[i][iqtend_cond_only()] = qgas_del_cond_only[i]; + } + for (int i = 0; i < num_modes; ++i) { + qnum_delaa[i][iqtend_cond()] = qnum_del_cond[i]; + qnum_delaa[i][iqtend_rnam()] = qnum_del_rnam[i]; + qnum_delaa[i][iqtend_nnuc()] = qnum_del_nnuc[i]; + qnum_delaa[i][iqtend_coag()] = qnum_del_coag[i]; + qnum_delaa[i][iqtend_cond_only()] = qnum_del_cond_only[i]; + } + for (int j = 0; j < num_aerosol_ids; ++j) { + for (int i = 0; i < num_modes; ++i) { + qaer_delaa[j][i][iqtend_cond()] = qaer_del_cond[j][i]; + qaer_delaa[j][i][iqtend_rnam()] = qaer_del_rnam[j][i]; + qaer_delaa[j][i][iqtend_nnuc()] = qaer_del_nnuc[j][i]; + qaer_delaa[j][i][iqtend_coag()] = qaer_del_coag[j][i]; + qaer_delaa[j][i][iqtend_cond_only()] = qaer_del_cond_only[j][i]; + } + } +} + +KOKKOS_INLINE_FUNCTION +void mam_amicphys_1subarea_cloudy( + const AmicPhysConfig& config, const int nstep, const Real deltat, const int jsub, + const int nsubarea, const bool iscldy_subarea, const Real afracsub, + const Real temp, const Real pmid, const Real pdel, const Real zmid, + const Real pblh, const Real relhum, Real dgn_a[AeroConfig::num_modes()], + Real dgn_awet[AeroConfig::num_modes()], + Real wetdens[AeroConfig::num_modes()], + const Real qgas1[AeroConfig::num_gas_ids()], + const Real qgas3[AeroConfig::num_gas_ids()], + Real qgas4[AeroConfig::num_gas_ids()], + Real qgas_delaa[AeroConfig::num_gas_ids()][nqtendaa()], + const Real qnum3[AeroConfig::num_modes()], + Real qnum4[AeroConfig::num_modes()], + Real qnum_delaa[AeroConfig::num_modes()][nqtendaa()], + const Real qaer2[AeroConfig::num_aerosol_ids()][AeroConfig::num_modes()], + const Real qaer3[AeroConfig::num_aerosol_ids()][AeroConfig::num_modes()], + Real qaer4[AeroConfig::num_aerosol_ids()][AeroConfig::num_modes()], + Real qaer_delaa[AeroConfig::num_aerosol_ids()][AeroConfig::num_modes()] + [nqtendaa()], + const Real qwtr3[AeroConfig::num_modes()], + Real qwtr4[AeroConfig::num_modes()], + const Real qnumcw3[AeroConfig::num_modes()], + Real qnumcw4[AeroConfig::num_modes()], + Real qnumcw_delaa[AeroConfig::num_modes()][nqqcwtendaa()], + const Real qaercw2[AeroConfig::num_gas_ids()][AeroConfig::num_modes()], + const Real qaercw3[AeroConfig::num_gas_ids()][AeroConfig::num_modes()], + Real qaercw4[AeroConfig::num_gas_ids()][AeroConfig::num_modes()], + Real qaercw_delaa[AeroConfig::num_gas_ids()][AeroConfig::num_modes()] + [nqqcwtendaa()]) { + + // + // calculates changes to gas and aerosol sub-area TMRs (tracer mixing ratios) + // qgas3, qaer3, qaercw3, qnum3, qnumcw3 are the current incoming TMRs + // qgas4, qaer4, qaercw4, qnum4, qnumcw4 are the updated outgoing TMRs + // + // when config.do_cond = false, this routine only calculates changes involving + // growth from smaller to larger modes (renaming) following cloud chemistry + // so gas TMRs are not changed + // when config.do_cond = true, this routine also calculates changes involving + // gas-aerosol exchange (condensation/evaporation) + // transfer of particles from hydrophobic modes to hydrophilic modes + // (aging) + // due to condensation + // currently this routine does not do + // new particle nucleation - because h2so4 gas conc. should be very low in + // cloudy air coagulation - because cloud-borne aerosol would need to be + // included + // + + // qXXXN (X=gas,aer,wat,num; N=1:4) are sub-area mixing ratios + // XXX=gas - gas species + // XXX=aer - aerosol mass species (excluding water) + // XXX=wat - aerosol water + // XXX=num - aerosol number + // N=1 - before gas-phase chemistry + // N=2 - before cloud chemistry + // N=3 - current incoming values (before gas-aerosol exchange, newnuc, + // coag) N=4 - updated outgoing values (after gas-aerosol exchange, + // newnuc, coag) + // + // qXXX_delaa are TMR changes (not tendencies) + // for different processes, which are used to produce history output + // for a clear sub-area, the processes are condensation/evaporation (and + // associated aging), + // renaming, coagulation, and nucleation + + // qxxx_del_yyyy are mix-ratio changes over full time step (deltat) + // qxxx_delsub_yyyy are mix-ratio changes over time sub-step (dtsubstep) + + static constexpr int num_gas_ids = AeroConfig::num_gas_ids(); + static constexpr int num_modes = AeroConfig::num_modes(); + static constexpr int num_aerosol_ids = AeroConfig::num_aerosol_ids(); + + static constexpr int igas_h2so4 = static_cast(GasId::H2SO4); + // Turn off nh3 for now. This is a future enhancement. + static constexpr int igas_nh3 = -999888777; // Same as mam_refactor + static constexpr int iaer_so4 = static_cast(AeroId::SO4); + static constexpr int iaer_pom = static_cast(AeroId::POM); + + const AeroId gas_to_aer[num_gas_ids] = {AeroId::SOA, AeroId::SO4, + AeroId::None}; + const bool l_gas_condense_to_mode[num_gas_ids][num_modes] = { + {true, true, true, true}, + {true, true, true, true}, + {false, false, false, false}}; + enum { NA, ANAL, IMPL }; + const int eqn_and_numerics_category[num_gas_ids] = {IMPL, ANAL, ANAL}; + // air molar density (kmol/m3) + // In order to try to match the results in mam_refactor + // set r_universal as [mJ/(mol)] as in mam_refactor. + // const Real r_universal = Constants::r_gas; // [mJ/(K mol)] + const Real r_universal = 8.314467591; // [mJ/(mol)] as in mam_refactor + const Real aircon = pmid / (1000 * r_universal * temp); + const Real alnsg_aer[num_modes] = {0.58778666490211906, 0.47000362924573563, + 0.58778666490211906, 0.47000362924573563}; + const Real uptk_rate_factor[num_gas_ids] = {0.81, 1.0, 1.0}; + + Real qgas_cur[num_gas_ids]; + for (int i = 0; i < num_gas_ids; ++i) + qgas_cur[i] = qgas3[i]; + Real qaer_cur[num_aerosol_ids][num_modes]; + for (int i = 0; i < num_aerosol_ids; ++i) + for (int j = 0; j < num_modes; ++j) + qaer_cur[i][j] = qaer3[i][j]; + + Real qnum_cur[num_modes]; + for (int j = 0; j < num_modes; ++j) + qnum_cur[j] = qnum3[j]; + Real qwtr_cur[num_modes]; + for (int j = 0; j < num_modes; ++j) + qwtr_cur[j] = qwtr3[j]; + + Real qnumcw_cur[num_modes]; + for (int j = 0; j < num_modes; ++j) + qnumcw_cur[j] = qnumcw3[j]; + + Real qaercw_cur[num_gas_ids][num_modes]; + for (int i = 0; i < num_gas_ids; ++i) + for (int j = 0; j < num_modes; ++j) + qaercw_cur[i][j] = qaercw3[i][j]; + + Real qgas_netprod_otrproc[num_gas_ids] = {}; + if (config.do_cond && config.gaexch_h2so4_uptake_optaa == 2) { + for (int igas = 0; igas < num_gas_ids; ++igas) { + if (igas == igas_h2so4 || igas == igas_nh3) { + // if gaexch_h2so4_uptake_optaa == 2, then + // if qgas increases from pre-gaschem to post-cldchem, + // start from the pre-gaschem mix-ratio and add in the production + // during the integration + // if it decreases, + // start from post-cldchem mix-ratio + // *** currently just do this for h2so4 and nh3 + qgas_netprod_otrproc[igas] = (qgas3[igas] - qgas1[igas]) / deltat; + if (qgas_netprod_otrproc[igas] >= 0.0) + qgas_cur[igas] = qgas1[igas]; + else + qgas_netprod_otrproc[igas] = 0.0; + } + } + } + Real qgas_del_cond[num_gas_ids] = {}; + Real qgas_del_nnuc[num_gas_ids] = {}; + Real qgas_del_cond_only[num_gas_ids] = {}; + Real qaer_del_cond[num_aerosol_ids][num_modes] = {}; + Real qaer_del_rnam[num_aerosol_ids][num_modes] = {}; + Real qaer_del_nnuc[num_aerosol_ids][num_modes] = {}; + Real qaer_del_coag[num_aerosol_ids][num_modes] = {}; + Real qaer_delsub_cond[num_aerosol_ids][num_modes] = {}; + Real qaer_delsub_coag[num_aerosol_ids][num_modes] = {}; + Real qaer_del_cond_only[num_aerosol_ids][num_modes] = {}; + Real qaercw_del_rnam[num_aerosol_ids][num_modes] = {}; + Real qnum_del_cond[num_modes] = {}; + Real qnum_del_rnam[num_modes] = {}; + Real qnum_del_nnuc[num_modes] = {}; + Real qnum_del_coag[num_modes] = {}; + Real qnum_delsub_cond[num_modes] = {}; + Real qnum_delsub_coag[num_modes] = {}; + Real qnum_del_cond_only[num_modes] = {}; + Real qnumcw_del_rnam[num_modes] = {}; + Real qaer_delsub_coag_in[num_aerosol_ids][AeroConfig::max_agepair()] = {}; + + const int ntsubstep = 1; + Real dtsubstep = deltat; + if (ntsubstep > 1) + dtsubstep = deltat / ntsubstep; + + // loop over multiple time sub-steps + + for (int jtsubstep = 1; jtsubstep <= ntsubstep; ++jtsubstep) { + // gas-aerosol exchange + Real uptkrate_h2so4 = 0.0; + Real qgas_avg[num_gas_ids] = {}; + Real qgas_sv1[num_gas_ids] = {}; + Real qnum_sv1[num_modes] = {}; + Real qaer_sv1[num_aerosol_ids][num_modes] = {}; + Real qaer_delsub_grow4rnam[num_aerosol_ids][num_modes] = {}; + + if (config.do_cond) { + + const bool l_calc_gas_uptake_coeff = jtsubstep == 1; + Real uptkaer[num_gas_ids][num_modes] = {}; + + for (int i = 0; i < num_gas_ids; ++i) + qgas_sv1[i] = qgas_cur[i]; + for (int i = 0; i < num_modes; ++i) + qnum_sv1[i] = qnum_cur[i]; + for (int j = 0; j < num_aerosol_ids; ++j) + for (int i = 0; i < num_modes; ++i) + qaer_sv1[j][i] = qaer_cur[j][i]; + + const int nghq = 2; + const int ntot_soamode = 4; + int niter_out = 0; + Real g0_soa_out = 0; + // time sub-step + const Real dtsub_soa_fixed = -1.0; + // gasaerexch::mam_gasaerexch_1subarea( + // nghq, igas_h2so4, igas_nh3, ntot_soamode, gas_to_aer, iaer_so4, + // iaer_pom, l_calc_gas_uptake_coeff, l_gas_condense_to_mode, + // eqn_and_numerics_category, dtsubstep, dtsub_soa_fixed, temp, pmid, + // aircon, num_gas_ids, qgas_cur, qgas_avg, qgas_netprod_otrproc, + // qaer_cur, qnum_cur, dgn_awet, alnsg_aer, uptk_rate_factor, uptkaer, + // uptkrate_h2so4, niter_out, g0_soa_out); + + if (config.newnuc_h2so4_conc_optaa == 11) + qgas_avg[igas_h2so4] = + 0.5 * (qgas_sv1[igas_h2so4] + qgas_cur[igas_h2so4]); + else if (config.newnuc_h2so4_conc_optaa == 12) + qgas_avg[igas_h2so4] = qgas_cur[igas_h2so4]; + + for (int i = 0; i < num_gas_ids; ++i) + qgas_del_cond[i] += + (qgas_cur[i] - (qgas_sv1[i] + qgas_netprod_otrproc[i] * dtsubstep)); + + for (int i = 0; i < num_modes; ++i) + qnum_delsub_cond[i] = qnum_cur[i] - qnum_sv1[i]; + for (int i = 0; i < num_aerosol_ids; ++i) + for (int j = 0; j < num_modes; ++j) + qaer_delsub_cond[i][j] = qaer_cur[i][j] - qaer_sv1[i][j]; + + // qaer_del_grow4rnam = change in qaer_del_cond during latest condensation + // calculations + for (int i = 0; i < num_aerosol_ids; ++i) + for (int j = 0; j < num_modes; ++j) + qaer_delsub_grow4rnam[i][j] = qaer_cur[i][j] - qaer_sv1[i][j]; + for (int i = 0; i < num_gas_ids; ++i) + qgas_del_cond_only[i] = qgas_del_cond[i]; + for (int i = 0; i < num_aerosol_ids; ++i) + for (int j = 0; j < num_modes; ++j) + qaer_del_cond_only[i][j] = qaer_delsub_cond[i][j]; + for (int i = 0; i < num_modes; ++i) + qnum_del_cond_only[i] = qnum_delsub_cond[i]; + + } else { + for (int i = 0; i < num_gas_ids; ++i) + qgas_avg[i] = qgas_cur[i]; + } + // renaming after "continuous growth" + if (config.do_rename) { + constexpr int nmodes = AeroConfig::num_modes(); + constexpr int naerosol_species = AeroConfig::num_aerosol_ids(); + const Real smallest_dryvol_value = 1.0e-25; // BAD_CONSTANT + const int dest_mode_of_mode[nmodes] = {-1, 0, -1, -1}; + + Real qnumcw_cur[num_modes] = {}; + Real qaercw_cur[num_aerosol_ids][num_modes] = {}; + Real qaercw_delsub_grow4rnam[num_aerosol_ids][num_modes] = {}; + Real mean_std_dev[nmodes]; + Real fmode_dist_tail_fac[nmodes]; + Real v2n_lo_rlx[nmodes]; + Real v2n_hi_rlx[nmodes]; + Real ln_diameter_tail_fac[nmodes]; + int num_pairs = 0; + Real diameter_cutoff[nmodes]; + Real ln_dia_cutoff[nmodes]; + Real diameter_threshold[nmodes]; + Real mass_2_vol[naerosol_species] = {0.15, + 6.4971751412429377e-002, + 0.15, + 7.0588235294117650e-003, + 3.0789473684210526e-002, + 5.1923076923076926e-002, + 156.20986883198000}; + + rename::find_renaming_pairs(dest_mode_of_mode, // in + mean_std_dev, // out + fmode_dist_tail_fac, // out + v2n_lo_rlx, // out + v2n_hi_rlx, // out + ln_diameter_tail_fac, // out + num_pairs, // out + diameter_cutoff, // out + ln_dia_cutoff, diameter_threshold); + + for (int i = 0; i < num_modes; ++i) + qnum_sv1[i] = qnum_cur[i]; + for (int j = 0; j < num_aerosol_ids; ++j) + for (int i = 0; i < num_modes; ++i) + qaer_sv1[j][i] = qaer_cur[j][i]; + Real dgnum_amode[nmodes]; + for (int m = 0; m < nmodes; ++m) { + dgnum_amode[m] = modes(m).nom_diameter; + } + + // qaercw_delsub_grow4rnam = change in qaercw from cloud chemistry + for (int i = 0; i < num_aerosol_ids; ++i) + for (int j = 0; j < num_modes; ++j) + qaercw_delsub_grow4rnam[i][j] = + (qaercw3[i][j] - qaercw2[i][j]) / ntsubstep; + Real qnumcw_sv1[num_modes]; + for (int i = 0; i < num_modes; ++i) + qnumcw_sv1[i] = qnumcw_cur[i]; + Real qaercw_sv1[num_aerosol_ids][num_modes]; + for (int i = 0; i < num_aerosol_ids; ++i) + for (int j = 0; j < num_modes; ++j) + qaercw_sv1[i][j] = qaercw_cur[i][j]; + + { + Real qmol_i_cur[num_modes][num_aerosol_ids]; + Real qmol_i_del[num_modes][num_aerosol_ids]; + Real qmol_c_cur[num_modes][num_aerosol_ids]; + Real qmol_c_del[num_modes][num_aerosol_ids]; + for (int j = 0; j < num_aerosol_ids; ++j) + for (int i = 0; i < num_modes; ++i) { + qmol_i_cur[i][j] = qaer_cur[j][i]; + qmol_i_del[i][j] = qaer_delsub_grow4rnam[j][i]; + qmol_c_cur[i][j] = qaercw_cur[j][i]; + qmol_c_del[i][j] = qaercw_delsub_grow4rnam[j][i]; + } + + Rename rename; + rename.mam_rename_1subarea_( + iscldy_subarea, smallest_dryvol_value, dest_mode_of_mode, + mean_std_dev, fmode_dist_tail_fac, v2n_lo_rlx, v2n_hi_rlx, + ln_diameter_tail_fac, num_pairs, diameter_cutoff, ln_dia_cutoff, + diameter_threshold, mass_2_vol, dgnum_amode, qnum_cur, qmol_i_cur, + qmol_i_del, qnumcw_cur, qmol_c_cur, qmol_c_del); + + for (int j = 0; j < num_aerosol_ids; ++j) + for (int i = 0; i < num_modes; ++i) { + qaer_cur[j][i] = qmol_i_cur[i][j]; + qaer_delsub_grow4rnam[j][i] = qmol_i_del[i][j]; + qaercw_cur[j][i] = qmol_c_cur[i][j]; + qaercw_delsub_grow4rnam[j][i] = qmol_c_del[i][j]; + } + } + for (int i = 0; i < num_modes; ++i) + qnum_del_rnam[i] += qnum_cur[i] - qnum_sv1[i]; + for (int i = 0; i < num_aerosol_ids; ++i) + for (int j = 0; j < num_modes; ++j) + qaer_del_rnam[i][j] += qaer_cur[i][j] - qaer_sv1[i][j]; + for (int i = 0; i < num_modes; ++i) + qnumcw_del_rnam[i] += qnumcw_cur[i] - qnumcw_sv1[i]; + for (int i = 0; i < num_aerosol_ids; ++i) + for (int j = 0; j < num_modes; ++j) + qaercw_del_rnam[i][j] += qaercw_cur[i][j] - qaercw_sv1[i][j]; + } + + // primary carbon aging + if (config.do_cond) { + aging::mam_pcarbon_aging_1subarea( + dgn_a, qnum_cur, qnum_delsub_cond, qnum_delsub_coag, qaer_cur, + qaer_delsub_cond, qaer_delsub_coag, qaer_delsub_coag_in); + } + // accumulate sub-step q-dels + if (config.do_cond) { + for (int i = 0; i < num_modes; ++i) + qnum_del_cond[i] += qnum_delsub_cond[i]; + for (int j = 0; j < num_aerosol_ids; ++j) + for (int i = 0; i < num_modes; ++i) + qaer_del_cond[j][i] += qaer_delsub_cond[j][i]; + } + } + // final mix ratios + for (int i = 0; i < num_gas_ids; ++i) + qgas4[i] = qgas_cur[i]; + for (int j = 0; j < num_aerosol_ids; ++j) + for (int i = 0; i < num_modes; ++i) + qaer4[j][i] = qaer_cur[j][i]; + for (int i = 0; i < num_modes; ++i) + qnum4[i] = qnum_cur[i]; + for (int i = 0; i < num_modes; ++i) + qwtr4[i] = qwtr_cur[i]; + for (int i = 0; i < num_modes; ++i) + qnumcw4[i] = qnumcw_cur[i]; + for (int i = 0; i < num_gas_ids; ++i) + for (int j = 0; j < num_modes; ++j) + qaercw4[i][j] = qaercw_cur[i][j]; + + // final mix ratio changes + for (int i = 0; i < num_gas_ids; ++i) { + qgas_delaa[i][iqtend_cond()] = qgas_del_cond[i]; + qgas_delaa[i][iqtend_rnam()] = 0.0; + qgas_delaa[i][iqtend_nnuc()] = qgas_del_nnuc[i]; + qgas_delaa[i][iqtend_coag()] = 0.0; + qgas_delaa[i][iqtend_cond_only()] = qgas_del_cond_only[i]; + } + for (int i = 0; i < num_modes; ++i) { + qnum_delaa[i][iqtend_cond()] = qnum_del_cond[i]; + qnum_delaa[i][iqtend_rnam()] = qnum_del_rnam[i]; + qnum_delaa[i][iqtend_nnuc()] = qnum_del_nnuc[i]; + qnum_delaa[i][iqtend_coag()] = qnum_del_coag[i]; + qnum_delaa[i][iqtend_cond_only()] = qnum_del_cond_only[i]; + } + for (int j = 0; j < num_aerosol_ids; ++j) { + for (int i = 0; i < num_modes; ++i) { + qaer_delaa[j][i][iqtend_cond()] = qaer_del_cond[j][i]; + qaer_delaa[j][i][iqtend_rnam()] = qaer_del_rnam[j][i]; + qaer_delaa[j][i][iqtend_nnuc()] = qaer_del_nnuc[j][i]; + qaer_delaa[j][i][iqtend_coag()] = qaer_del_coag[j][i]; + qaer_delaa[j][i][iqtend_cond_only()] = qaer_del_cond_only[j][i]; + } + } + for (int i = 0; i < num_modes; ++i) + qnumcw_delaa[i][iqqcwtend_rnam()] = qnumcw_del_rnam[i]; + for (int i = 0; i < num_aerosol_ids; ++i) + for (int j = 0; j < num_modes; ++j) + qaercw_delaa[i][j][iqqcwtend_rnam()] = qaercw_del_rnam[i][j]; +} + +KOKKOS_INLINE_FUNCTION +void mam_amicphys_1gridcell( + const AmicPhysConfig& config, const int nstep, const Real deltat, const int nsubarea, + const int ncldy_subarea, const bool iscldy_subarea[maxsubarea()], + const Real afracsub[maxsubarea()], const Real temp, const Real pmid, + const Real pdel, const Real zmid, const Real pblh, + const Real relhumsub[maxsubarea()], Real dgn_a[AeroConfig::num_modes()], + Real dgn_awet[AeroConfig::num_modes()], + Real wetdens[AeroConfig::num_modes()], + const Real qsub1[AeroConfig::num_gas_ids()][maxsubarea()], + const Real qsub2[AeroConfig::num_gas_ids()][maxsubarea()], + const Real qqcwsub2[AeroConfig::num_gas_ids()][maxsubarea()], + const Real qsub3[AeroConfig::num_gas_ids()][maxsubarea()], + const Real qqcwsub3[AeroConfig::num_gas_ids()][maxsubarea()], + Real qaerwatsub3[AeroConfig::num_modes()][maxsubarea()], + Real qsub4[AeroConfig::num_gas_ids()][maxsubarea()], + Real qqcwsub4[AeroConfig::num_gas_ids()][maxsubarea()], + Real qaerwatsub4[AeroConfig::num_modes()][maxsubarea()], + Real qsub_tendaa[AeroConfig::num_gas_ids()][nqtendaa()][maxsubarea()], + Real qqcwsub_tendaa[AeroConfig::num_gas_ids()][nqqcwtendaa()][maxsubarea()]) { + + // + // calculates changes to gas and aerosol sub-area TMRs (tracer mixing ratios) + // qsub3 and qqcwsub3 are the incoming current TMRs + // qsub4 and qqcwsub4 are the outgoing updated TMRs + // + // qsubN and qqcwsubN (N=1:4) are tracer mixing ratios (TMRs, mol/mol or + // #/kmol) in sub-areas + // currently there are just clear and cloudy sub-areas + // the N=1:4 have same meanings as for qgcmN + // N=1 - before gas-phase chemistry + // N=2 - before cloud chemistry + // N=3 - incoming values (before gas-aerosol exchange, newnuc, coag) + // N=4 - outgoing values (after gas-aerosol exchange, newnuc, coag) + // qsub_tendaa and qqcwsub_tendaa are TMR tendencies + // for different processes, which are used to produce history output + // the processes are condensation/evaporation (and associated aging), + // renaming, coagulation, and nucleation + + static constexpr int num_gas_ids = AeroConfig::num_gas_ids(); + static constexpr int num_modes = AeroConfig::num_modes(); + static constexpr int num_aerosol_ids = AeroConfig::num_aerosol_ids(); + + // the q--4 values will be equal to q--3 values unless they get changed + for (int i = 0; i < num_gas_ids; ++i) + for (int j = 0; j < maxsubarea(); ++j) { + qsub4[i][j] = qsub3[i][j]; + qqcwsub4[i][j] = qqcwsub3[i][j]; + } + for (int i = 0; i < num_modes; ++i) + for (int j = 0; j < maxsubarea(); ++j) + qaerwatsub4[i][j] = qaerwatsub3[i][j]; + for (int i = 0; i < num_gas_ids; ++i) + for (int j = 0; j < nqtendaa(); ++j) + for (int k = 0; k < maxsubarea(); ++k) + qsub_tendaa[i][j][k] = 0; + for (int i = 0; i < num_gas_ids; ++i) + for (int j = 0; j < nqqcwtendaa(); ++j) + for (int k = 0; k < maxsubarea(); ++k) + qqcwsub_tendaa[i][j][k] = 0.0; + + for (int jsub = 0; jsub < nsubarea; ++jsub) { + AmicPhysConfig sub_config = config; + if (iscldy_subarea[jsub]) { + sub_config.do_cond = config.do_cond; + sub_config.do_rename = config.do_rename; + sub_config.do_newnuc = false; + sub_config.do_coag = false; + } + const bool do_map_gas_sub = sub_config.do_cond || sub_config.do_newnuc; + + // map incoming sub-area mix-ratios to gas/aer/num arrays + Real qgas1[num_gas_ids] = {}; + Real qgas3[num_gas_ids] = {}; + Real qgas4[num_gas_ids] = {}; + if (do_map_gas_sub) { + // for cldy subarea, only do gases if doing gaexch + for (int igas = 0; igas < 2; ++igas) { + const int l = lmap_gas(igas); + qgas1[igas] = qsub1[l][jsub] * fcvt_gas(igas); + qgas3[igas] = qsub3[l][jsub] * fcvt_gas(igas); + qgas4[igas] = qgas3[igas]; + } + } + Real qaer2[num_aerosol_ids][num_modes] = {}; + Real qaer3[num_aerosol_ids][num_modes] = {}; + Real qnum3[num_modes] = {}; + Real qaer4[num_aerosol_ids][num_modes] = {}; + Real qnum4[num_modes] = {}; + Real qwtr3[num_modes] = {}; + Real qwtr4[num_modes] = {}; + for (int n = 0; n < num_modes; ++n) { + qnum3[n] = qsub3[n][jsub] * fcvt_num(); + qnum4[n] = qnum3[n]; + for (int iaer = 0; iaer < num_aerosol_ids; ++iaer) { + qaer2[iaer][n] = qsub2[iaer][jsub] * fcvt_aer(iaer); + qaer3[iaer][n] = qsub3[iaer][jsub] * fcvt_aer(iaer); + qaer4[iaer][n] = qaer3[iaer][n]; + } + qwtr3[n] = qaerwatsub3[n][jsub] * fcvt_wtr(); + qwtr4[n] = qwtr3[n]; + } + Real qaercw2[num_aerosol_ids][num_modes] = {}; + Real qaercw3[num_aerosol_ids][num_modes] = {}; + Real qnumcw3[num_modes] = {}; + Real qaercw4[num_aerosol_ids][num_modes] = {}; + Real qnumcw4[num_modes] = {}; + if (iscldy_subarea[jsub]) { + // only do cloud-borne for cloudy + for (int n = 0; n < num_modes; ++n) { + qnumcw3[n] = qqcwsub3[n][jsub] * fcvt_num(); + qnumcw4[n] = qnumcw3[n]; + for (int iaer = 0; iaer < num_aerosol_ids; ++iaer) { + qaercw2[iaer][n] = qqcwsub2[n][jsub] * fcvt_aer(iaer); + qaercw3[iaer][n] = qqcwsub3[n][jsub] * fcvt_aer(iaer); + qaercw4[iaer][n] = qaercw3[iaer][n]; + } + } + } + + Real qgas_delaa[num_gas_ids][nqtendaa()] = {}; + Real qnum_delaa[num_modes][nqtendaa()] = {}; + Real qnumcw_delaa[num_modes][nqqcwtendaa()] = {}; + Real qaer_delaa[num_aerosol_ids][num_modes][nqtendaa()] = {}; + Real qaercw_delaa[num_aerosol_ids][num_modes][nqqcwtendaa()] = {}; + + if (iscldy_subarea[jsub]) { + mam_amicphys_1subarea_cloudy(sub_config, nstep, deltat, + jsub, nsubarea, iscldy_subarea[jsub], afracsub[jsub], temp, pmid, + pdel, zmid, pblh, relhumsub[jsub], dgn_a, dgn_awet, wetdens, qgas1, + qgas3, qgas4, qgas_delaa, qnum3, qnum4, qnum_delaa, qaer2, qaer3, + qaer4, qaer_delaa, qwtr3, qwtr4, qnumcw3, qnumcw4, qnumcw_delaa, + qaercw2, qaercw3, qaercw4, qaercw_delaa); + } else { + mam_amicphys_1subarea_clear(sub_config, nstep, deltat, + jsub, nsubarea, iscldy_subarea[jsub], afracsub[jsub], temp, pmid, + pdel, zmid, pblh, relhumsub[jsub], dgn_a, dgn_awet, wetdens, qgas1, + qgas3, qgas4, qgas_delaa, qnum3, qnum4, qnum_delaa, qaer3, qaer4, + qaer_delaa, qwtr3, qwtr4); + // map gas/aer/num arrays (mix-ratio and del=change) back to sub-area + // arrays + + if (do_map_gas_sub) { + for (int igas = 0; igas < 2; ++igas) { + const int l = lmap_gas(igas); + qsub4[l][jsub] = qgas4[igas] / fcvt_gas(igas); + for (int i = 0; i < nqtendaa(); ++i) + qsub_tendaa[l][i][jsub] = + qgas_delaa[igas][i] / (fcvt_gas(igas) * deltat); + } + } + for (int n = 0; n < num_modes; ++n) { + qsub4[n][jsub] = qnum4[n] / fcvt_num(); + for (int i = 0; i < nqtendaa(); ++i) + qsub_tendaa[n][i][jsub] = qnum_delaa[n][i] / (fcvt_num() * deltat); + for (int iaer = 0; iaer < num_aerosol_ids; ++iaer) { + qsub4[iaer][jsub] = qaer4[iaer][n] / fcvt_aer(iaer); + for (int i = 0; i < nqtendaa(); ++i) + qsub_tendaa[iaer][i][jsub] = + qaer_delaa[iaer][n][i] / (fcvt_aer(iaer) * deltat); + } + qaerwatsub4[n][jsub] = qwtr4[n] / fcvt_wtr(); + + if (iscldy_subarea[jsub]) { + qqcwsub4[n][jsub] = qnumcw4[n] / fcvt_num(); + for (int i = 0; i < nqqcwtendaa(); ++i) + qqcwsub_tendaa[n][i][jsub] = + qnumcw_delaa[n][i] / (fcvt_num() * deltat); + for (int iaer = 0; iaer < num_aerosol_ids; ++iaer) { + qqcwsub4[iaer][jsub] = qaercw4[iaer][n] / fcvt_aer(iaer); + for (int i = 0; i < nqqcwtendaa(); ++i) + qqcwsub_tendaa[iaer][i][jsub] = + qaercw_delaa[iaer][n][i] / (fcvt_aer(iaer) * deltat); + } + } + } + } + } +} + +} // anonymous namespace + +KOKKOS_INLINE_FUNCTION +void modal_aero_amicphys_intr( + const AmicPhysConfig& config, const int nstep, const Real deltat, const Real t, const Real pmid, const Real pdel, + const Real zm, const Real pblh, const Real qv, const Real cld, + Real q[gas_pcnst()], Real qqcw[gas_pcnst()], const Real q_pregaschem[gas_pcnst()], + const Real q_precldchem[gas_pcnst()], const Real qqcw_precldchem[gas_pcnst()], + Real q_tendbb[gas_pcnst()][nqtendbb()], Real qqcw_tendbb[gas_pcnst()][nqtendbb()], + Real dgncur_a[AeroConfig::num_modes()], + Real dgncur_awet[AeroConfig::num_modes()], + Real wetdens_host[AeroConfig::num_modes()], + Real qaerwat[AeroConfig::num_modes()]) { + + /* + nstep ! model time-step number + nqtendbb ! dimension for q_tendbb + nqqcwtendbb ! dimension f + deltat ! + q(ncol,pver,pcnstxx) ! current tracer mixing ratios (TMRs) + these values are updated (so out /= in) + *** MUST BE #/kmol-air for number + *** MUST BE mol/mol-air for mass + *** NOTE ncol dimension + qqcw(ncol,pver,pcnstxx) + like q but for cloud-borner tracers + these values are updated + q_pregaschem(ncol,pver,pcnstxx) ! q TMRs before gas-phase + chemistry q_precldchem(ncol,pver,pcnstxx) ! q TMRs before cloud + chemistry qqcw_precldchem(ncol,pver,pcnstxx) ! qqcw TMRs before cloud + chemistry q_tendbb(ncol,pver,pcnstxx,nqtendbb()) ! TMR tendencies for + box-model diagnostic output qqcw_tendbb(ncol,pver,pcnstx t(pcols,pver) ! + temperature at model levels (K) pmid(pcols,pver) ! pressure at model + level centers (Pa) pdel(pcols,pver) ! pressure thickness of levels + (Pa) zm(pcols,pver) ! altitude (above ground) at level centers (m) + pblh(pcols) ! planetary boundary layer depth (m) + qv(pcols,pver) ! specific humidity (kg/kg) + cld(ncol,pver) ! cloud fraction (-) *** NOTE ncol dimension + dgncur_a(pcols,pver,ntot_amode) + dgncur_awet(pcols,pver,ntot_amode) + ! dry & wet geo. mean dia. (m) of + number distrib. wetdens_host(pcols,pver,ntot_amode) ! interstitial + aerosol wet density (kg/m3) + + qaerwat(pcols,pver,ntot_amode aerosol water mixing ratio (kg/kg, + NOT mol/mol) + + */ + + // !DESCRIPTION: + // calculates changes to gas and aerosol TMRs (tracer mixing ratios) from + // gas-aerosol exchange (condensation/evaporation) + // growth from smaller to larger modes (renaming) due to both + // condensation and cloud chemistry + // new particle nucleation + // coagulation + // transfer of particles from hydrophobic modes to hydrophilic modes + // (aging) + // due to condensation and coagulation + // + // the incoming mixing ratios (q and qqcw) are updated before output + // + // !REVISION HISTORY: + // RCE 07.04.13: Adapted from earlier version of CAM5 modal aerosol + // routines + // for these processes + // + + static constexpr int num_modes = AeroConfig::num_modes(); + + // qgcmN and qqcwgcmN (N=1:4) are grid-cell mean tracer mixing ratios + // (TMRs, mol/mol or #/kmol) + // N=1 - before gas-phase chemistry + // N=2 - before cloud chemistry + // N=3 - incoming values (before gas-aerosol exchange, newnuc, coag) + // N=4 - outgoing values (after gas-aerosol exchange, newnuc, coag) + + // qsubN and qqcwsubN (N=1:4) are TMRs in sub-areas + // currently there are just clear and cloudy sub-areas + // the N=1:4 have same meanings as for qgcmN + + // q_coltendaa and qqcw_coltendaa are column-integrated tendencies + // for different processes, which are output to history + // the processes are condensation/evaporation (and associated aging), + // renaming, coagulation, and nucleation + + for (int i = 0; i < gas_pcnst(); ++i) + for (int j = 0; j < nqtendbb(); ++j) + q_tendbb[i][j] = 0.0, qqcw_tendbb[i][j] = 0.0; + + // get saturation mixing ratio + // call qsat( t(1:ncol,1:pver), pmid(1:ncol,1:pvnner), & + // ev_sat(1:ncol,1:pver), qv_sat(1:ncol,1:pver) ) + const Real epsqs = haero::Constants::weight_ratio_h2o_air; + // Saturation vapor pressure + const Real ev_sat = conversions::vapor_saturation_pressure_magnus(t, pmid); + // Saturation specific humidity + const Real qv_sat = epsqs * ev_sat / (pmid - (1 - epsqs) * ev_sat); + + const Real relhumgcm = haero::max(0.0, haero::min(1.0, qv / qv_sat)); + + // Set up cloudy/clear subareas inside a grid cell + int nsubarea, ncldy_subarea, jclea, jcldy; + bool iscldy_subarea[maxsubarea()]; + Real afracsub[maxsubarea()]; + Real relhumsub[maxsubarea()]; + Real qsub1[gas_pcnst()][maxsubarea()]; + Real qsub2[gas_pcnst()][maxsubarea()]; + Real qsub3[gas_pcnst()][maxsubarea()]; + Real qqcwsub1[gas_pcnst()][maxsubarea()]; + Real qqcwsub2[gas_pcnst()][maxsubarea()]; + Real qqcwsub3[gas_pcnst()][maxsubarea()]; + // aerosol water mixing ratios (mol/mol) + Real qaerwatsub3[AeroConfig::num_modes()][maxsubarea()]; + construct_subareas_1gridcell(cld, relhumgcm, // in + q_pregaschem, q_precldchem, // in + qqcw_precldchem, // in + q, qqcw, // in + nsubarea, ncldy_subarea, jclea, jcldy, // out + iscldy_subarea, afracsub, relhumsub, // out + qsub1, qsub2, qsub3, // out + qqcwsub1, qqcwsub2, qqcwsub3, qaerwatsub3, // out + qaerwat // in + ); + + // Initialize the "after-amicphys" values + Real qsub4[gas_pcnst()][maxsubarea()] = {}; + Real qqcwsub4[gas_pcnst()][maxsubarea()] = {}; + Real qaerwatsub4[AeroConfig::num_modes()][maxsubarea()] = {}; + + // + // start integration + // + Real dgn_a[num_modes], dgn_awet[num_modes], wetdens[num_modes]; + for (int n = 0; n < num_modes; ++n) { + dgn_a[n] = dgncur_a[n]; + dgn_awet[n] = dgncur_awet[n]; + wetdens[n] = haero::max(1000.0, wetdens_host[n]); + } + Real qsub_tendaa[gas_pcnst()][nqtendaa()][maxsubarea()] = {}; + Real qqcwsub_tendaa[gas_pcnst()][nqqcwtendaa()][maxsubarea()] = {}; + mam_amicphys_1gridcell(config, nstep, deltat, + nsubarea, ncldy_subarea, iscldy_subarea, afracsub, t, + pmid, pdel, zm, pblh, relhumsub, dgn_a, dgn_awet, + wetdens, qsub1, qsub2, qqcwsub2, qsub3, qqcwsub3, + qaerwatsub3, qsub4, qqcwsub4, qaerwatsub4, qsub_tendaa, + qqcwsub_tendaa); + + // + // form new grid-mean mix-ratios + Real qgcm4[gas_pcnst()]; + Real qgcm_tendaa[gas_pcnst()][nqtendaa()]; + Real qaerwatgcm4[num_modes]; + if (nsubarea == 1) { + for (int i = 0; i < gas_pcnst(); ++i) + qgcm4[i] = qsub4[i][0]; + for (int i = 0; i < gas_pcnst(); ++i) + for (int j = 0; j < nqtendaa(); ++j) + qgcm_tendaa[i][j] = qsub_tendaa[i][j][0]; + for (int i = 0; i < num_modes; ++i) + qaerwatgcm4[i] = qaerwatsub4[i][0]; + } else { + for (int i = 0; i < gas_pcnst(); ++i) + qgcm4[i] = 0.0; + for (int i = 0; i < gas_pcnst(); ++i) + for (int j = 0; j < nqtendaa(); ++j) + qgcm_tendaa[i][j] = 0.0; + for (int n = 0; n < nsubarea; ++n) { + for (int i = 0; i < gas_pcnst(); ++i) + qgcm4[i] += qsub4[i][n] * afracsub[n]; + for (int i = 0; i < gas_pcnst(); ++i) + for (int j = 0; j < nqtendaa(); ++j) + qgcm_tendaa[i][j] = + qgcm_tendaa[i][j] + qsub_tendaa[i][j][n] * afracsub[n]; + } + for (int i = 0; i < num_modes; ++i) + // for aerosol water use the clear sub-area value + qaerwatgcm4[i] = qaerwatsub4[i][jclea - 1]; + } + Real qqcwgcm4[gas_pcnst()]; + Real qqcwgcm_tendaa[gas_pcnst()][nqqcwtendaa()]; + if (ncldy_subarea <= 0) { + for (int i = 0; i < gas_pcnst(); ++i) + qqcwgcm4[i] = haero::max(0.0, qqcw[i]); + for (int i = 0; i < gas_pcnst(); ++i) + for (int j = 0; j < nqqcwtendaa(); ++j) + qqcwgcm_tendaa[i][j] = 0.0; + } else if (nsubarea == 1) { + for (int i = 0; i < gas_pcnst(); ++i) + qqcwgcm4[i] = qqcwsub4[i][0]; + for (int i = 0; i < gas_pcnst(); ++i) + for (int j = 0; j < nqqcwtendaa(); ++j) + qqcwgcm_tendaa[i][j] = qqcwsub_tendaa[i][j][0]; + } else { + for (int i = 0; i < gas_pcnst(); ++i) + qqcwgcm4[i] = 0.0; + for (int i = 0; i < gas_pcnst(); ++i) + for (int j = 0; j < nqqcwtendaa(); ++j) + qqcwgcm_tendaa[i][j] = 0.0; + for (int n = 0; n < nsubarea; ++n) { + if (iscldy_subarea[n]) { + for (int i = 0; i < gas_pcnst(); ++i) + qqcwgcm4[i] += qqcwsub4[i][n] * afracsub[n]; + for (int i = 0; i < gas_pcnst(); ++i) + for (int j = 0; j < nqqcwtendaa(); ++j) + qqcwgcm_tendaa[i][j] += qqcwsub_tendaa[i][j][n] * afracsub[n]; + } + } + } + + for (int lmz = 0; lmz < gas_pcnst(); ++lmz) { + if (lmapcc_all(lmz) > 0) { + // HW, to ensure non-negative + q[lmz] = haero::max(qgcm4[lmz], 0.0); + if (lmapcc_all(lmz) >= lmapcc_val_aer()) { + // HW, to ensure non-negative + qqcw[lmz] = haero::max(qqcwgcm4[lmz], 0.0); + } + } + } + for (int i = 0; i < gas_pcnst(); ++i) { + if (iqtend_cond() < nqtendbb()) + q_tendbb[i][iqtend_cond()] = qgcm_tendaa[i][iqtend_cond()]; + if (iqtend_rnam() < nqtendbb()) + q_tendbb[i][iqtend_rnam()] = qgcm_tendaa[i][iqtend_rnam()]; + if (iqtend_nnuc() < nqtendbb()) + q_tendbb[i][iqtend_nnuc()] = qgcm_tendaa[i][iqtend_nnuc()]; + if (iqtend_coag() < nqtendbb()) + q_tendbb[i][iqtend_coag()] = qgcm_tendaa[i][iqtend_coag()]; + if (iqqcwtend_rnam() < nqqcwtendbb()) + qqcw_tendbb[i][iqqcwtend_rnam()] = qqcwgcm_tendaa[i][iqqcwtend_rnam()]; + } + for (int i = 0; i < num_modes; ++i) + qaerwat[i] = qaerwatgcm4[i]; +} + +} // namespace scream::impl diff --git a/components/eamxx/src/physics/mam/online_emission.hpp b/components/eamxx/src/physics/mam/online_emission.hpp index b844f5b18e64..c8318dcc05cb 100644 --- a/components/eamxx/src/physics/mam/online_emission.hpp +++ b/components/eamxx/src/physics/mam/online_emission.hpp @@ -63,12 +63,26 @@ template struct onlineEmissions { // --------------------------------------------------------------------------- // Online emissions routines // --------------------------------------------------------------------------- - void init_from_input_file(const ekat::ParameterList &m_params); - void transfer_to_cflux(const onlineEmissData &data, - const std::map idx_map, - view_2d &fluxes); + void init_from_input_file(const ekat::ParameterList ¶ms) { + const int nspec = online_emis_data.nspec; + const int ncols = online_emis_data.ncols; + using ExeSpace = typename KT::ExeSpace; + using ESU = ekat::ExeSpaceUtils; + const auto policy = ESU::get_default_team_policy(ncols, nspec); + // Read from input file + // FIXME: currently reading a single placeholder scalar--should be + // ncols-sized array when we know what the input data looks like + for (int ispec = 0; ispec < nspec; ++ispec) { + Real init_cond_val = + params.get(online_emis_data.root_IC_str + online_emis_data.spec_names[ispec]); + // TODO: is this overkill?--i.e., would a mirror/deep_copy make more sense? + Kokkos::parallel_for( + policy, KOKKOS_LAMBDA(const MemberType &team) { + const int jcol = team.league_rank(); // column index + online_emis_data.flux_data(ispec, jcol) = init_cond_val; + }); + } + } // end init_from_input_file() }; // struct onlineEmissions } // namespace scream::mam_coupling #endif // ONLINE_EMISSION_HPP - -#include "online_emission_impl.hpp" diff --git a/components/eamxx/src/physics/mam/online_emission_impl.hpp b/components/eamxx/src/physics/mam/online_emission_impl.hpp deleted file mode 100644 index 1f0ac91a8548..000000000000 --- a/components/eamxx/src/physics/mam/online_emission_impl.hpp +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef ONLINE_EMISSION_IMPL_HPP -#define ONLINE_EMISSION_IMPL_HPP - -namespace scream::mam_coupling { -template -void onlineEmissions::init_from_input_file(const ekat::ParameterList ¶ms) { - // FIXME: move this out to the onlineEmissions struct to avoid extra work - // by doing it again below? - const int nspec = online_emis_data.nspec; - const int ncols = online_emis_data.ncols; - using ExeSpace = typename KT::ExeSpace; - using ESU = ekat::ExeSpaceUtils; - const auto policy = ESU::get_default_team_policy(ncols, nspec); - // Read from input file - // FIXME: currently reading a single placeholder scalar--should be - // ncols-sized array when we know what the input data looks like - for (int ispec = 0; ispec < nspec; ++ispec) { - Real init_cond_val = - params.get(online_emis_data.root_IC_str + online_emis_data.spec_names[ispec]); - // TODO: is this overkill?--i.e., would a mirror/deep_copy make more sense? - Kokkos::parallel_for( - policy, KOKKOS_LAMBDA(const MemberType &team) { - const int jcol = team.league_rank(); // column index - online_emis_data.flux_data(ispec, jcol) = init_cond_val; - }); - } -} // end init_from_input_file() - -template -void onlineEmissions::transfer_to_cflux( - const onlineEmissData &data, const std::map idx_map, - view_2d &fluxes) { - const int nspec = data.nspec; - const int ncols = data.ncols; - using ExeSpace = typename KT::ExeSpace; - using ESU = ekat::ExeSpaceUtils; - const auto policy = ESU::get_default_team_policy(ncols, nspec); - - Kokkos::parallel_for( - policy, KOKKOS_LAMBDA(const MemberType &team) { - const int jcol = team.league_rank(); // column index - Kokkos::parallel_for( - Kokkos::TeamThreadRange(team, nspec), [&](const int ispec) { - auto s_idx = idx_map.at(data.spec_names[ispec]); - data.cfluxes(jcol, s_idx) = data.flux_data(ispec, jcol); - }); - }); - Kokkos::deep_copy(fluxes, data.cfluxes); -} -} // namespace scream::mam_coupling - -#endif // ONLINE_EMISSION_IMPL_HPP From 405ce81346acd04960adbcb5acc8a6863045e77e Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Sat, 26 Oct 2024 12:38:49 -0700 Subject: [PATCH 105/147] Adds sst variable from the ocean model in EAMxx via coupler --- .../src/control/atmosphere_surface_coupling_importer.cpp | 3 +++ components/eamxx/src/mct_coupling/scream_cpl_indices.F90 | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/components/eamxx/src/control/atmosphere_surface_coupling_importer.cpp b/components/eamxx/src/control/atmosphere_surface_coupling_importer.cpp index ee3e21e7461b..f0eca885ddce 100644 --- a/components/eamxx/src/control/atmosphere_surface_coupling_importer.cpp +++ b/components/eamxx/src/control/atmosphere_surface_coupling_importer.cpp @@ -57,6 +57,9 @@ void SurfaceCouplingImporter::set_grids(const std::shared_ptr("fv", scalar2d_layout, m/s, grid_name); // Aerodynamical resistance add_field("ram1", scalar2d_layout, s/m, grid_name); + // Sea surface temperature [K] + //FIXME: Verify the units + add_field("sst", scalar2d_layout, K, grid_name); } // ========================================================================================= void SurfaceCouplingImporter::setup_surface_coupling_data(const SCDataManager &sc_data_manager) diff --git a/components/eamxx/src/mct_coupling/scream_cpl_indices.F90 b/components/eamxx/src/mct_coupling/scream_cpl_indices.F90 index dc5be4de373f..2627ac722fd3 100644 --- a/components/eamxx/src/mct_coupling/scream_cpl_indices.F90 +++ b/components/eamxx/src/mct_coupling/scream_cpl_indices.F90 @@ -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 = 20 integer, parameter, public :: num_scream_exports = 17 integer, public :: num_cpl_imports, num_cpl_exports, import_field_size, export_field_size @@ -92,6 +92,7 @@ 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' ! CPL indices import_cpl_indices(1) = mct_avect_indexra(x2a,'Sx_avsdr') @@ -113,6 +114,7 @@ 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') + import_cpl_indices(20) = mct_avect_indexra(x2a,'So_t') ! Vector components import_vector_components(11) = 0 From e38b45bd7caf336280e36a61cfa5298d3960be61 Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Sat, 26 Oct 2024 13:22:22 -0700 Subject: [PATCH 106/147] Adds dstfluxes (4 values per col) from coupler to eamxx --- .../atmosphere_surface_coupling_importer.cpp | 52 ++++++++++--------- .../src/mct_coupling/scream_cpl_indices.F90 | 14 ++++- ...and_online_emissions_process_interface.cpp | 2 +- 3 files changed, 42 insertions(+), 26 deletions(-) diff --git a/components/eamxx/src/control/atmosphere_surface_coupling_importer.cpp b/components/eamxx/src/control/atmosphere_surface_coupling_importer.cpp index f0eca885ddce..e87bebd34e1c 100644 --- a/components/eamxx/src/control/atmosphere_surface_coupling_importer.cpp +++ b/components/eamxx/src/control/atmosphere_surface_coupling_importer.cpp @@ -28,38 +28,42 @@ void SurfaceCouplingImporter::set_grids(const std::shared_ptr("sfc_alb_dir_vis", scalar2d_layout, nondim, grid_name); - add_field("sfc_alb_dir_nir", scalar2d_layout, nondim, grid_name); - add_field("sfc_alb_dif_vis", scalar2d_layout, nondim, grid_name); - add_field("sfc_alb_dif_nir", scalar2d_layout, nondim, grid_name); - add_field("surf_lw_flux_up", scalar2d_layout, W/m2, grid_name); - add_field("surf_sens_flux", scalar2d_layout, W/m2, grid_name); - add_field("surf_evap", scalar2d_layout, kg/m2/s, grid_name); - add_field("surf_mom_flux", vector2d_layout, N/m2, grid_name); - add_field("surf_radiative_T", scalar2d_layout, K, grid_name); - add_field("T_2m", scalar2d_layout, K, grid_name); - add_field("qv_2m", scalar2d_layout, kg/kg, grid_name); - add_field("wind_speed_10m", scalar2d_layout, m/s, grid_name); - add_field("snow_depth_land", scalar2d_layout, m, grid_name); - add_field("ocnfrac", scalar2d_layout, nondim, grid_name); - add_field("landfrac", scalar2d_layout, nondim, grid_name); - add_field("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("sfc_alb_dir_vis", scalar2d, nondim, grid_name); + add_field("sfc_alb_dir_nir", scalar2d, nondim, grid_name); + add_field("sfc_alb_dif_vis", scalar2d, nondim, grid_name); + add_field("sfc_alb_dif_nir", scalar2d, nondim, grid_name); + add_field("surf_lw_flux_up", scalar2d, W/m2, grid_name); + add_field("surf_sens_flux", scalar2d, W/m2, grid_name); + add_field("surf_evap", scalar2d, kg/m2/s, grid_name); + add_field("surf_mom_flux", vector2d, N/m2, grid_name); + add_field("surf_radiative_T", scalar2d, K, grid_name); + add_field("T_2m", scalar2d, K, grid_name); + add_field("qv_2m", scalar2d, kg/kg, grid_name); + add_field("wind_speed_10m", scalar2d, m/s, grid_name); + add_field("snow_depth_land", scalar2d, m, grid_name); + add_field("ocnfrac", scalar2d, nondim, grid_name); + add_field("landfrac", scalar2d, nondim, grid_name); + add_field("icefrac", scalar2d, nondim, grid_name); // Friction velocity [m/s] - add_field("fv", scalar2d_layout, m/s, grid_name); + add_field("fv", scalar2d, m/s, grid_name); // Aerodynamical resistance - add_field("ram1", scalar2d_layout, s/m, grid_name); + add_field("ram1", scalar2d, s/m, grid_name); // Sea surface temperature [K] //FIXME: Verify the units - add_field("sst", scalar2d_layout, K, grid_name); + add_field("sst", scalar2d, K, grid_name); + //dust fluxes [kg/m^2/s]: Four flux values for eacch column + add_field("dstflx", vector4d, kg/m2/s, grid_name); + } // ========================================================================================= void SurfaceCouplingImporter::setup_surface_coupling_data(const SCDataManager &sc_data_manager) diff --git a/components/eamxx/src/mct_coupling/scream_cpl_indices.F90 b/components/eamxx/src/mct_coupling/scream_cpl_indices.F90 index 2627ac722fd3..15df178d29e5 100644 --- a/components/eamxx/src/mct_coupling/scream_cpl_indices.F90 +++ b/components/eamxx/src/mct_coupling/scream_cpl_indices.F90 @@ -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 = 20 + 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 @@ -93,6 +93,10 @@ subroutine scream_set_cpl_indices (x2a, a2x) 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') @@ -114,7 +118,15 @@ 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 import_vector_components(11) = 0 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 c84bb8034408..5e44fd1e35e0 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 @@ -51,7 +51,7 @@ void MAMSrfOnlineEmiss::set_grids( // and then bundle the online emissions computations as tendencies into the // Computed constituent_fluxes field // ------------------------------------------------------------- - static constexpr Units m2(m * m, "m2"); + constexpr auto m2 = pow(m, 2); // Constituent fluxes of species in [kg/m2/s] add_field("constituent_fluxes", scalar2d_pcnct, kg / m2 / s, grid_name); From 13f6cfcfb939b7f90a42ce16b553d9fb41520bb2 Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Sun, 27 Oct 2024 22:48:21 -0700 Subject: [PATCH 107/147] Adds all input variables for online emissions into the interface cpp --- .../atmosphere_surface_coupling_importer.cpp | 1 - ...and_online_emissions_process_interface.cpp | 223 +++++++++++++----- ...and_online_emissions_process_interface.hpp | 68 ++++-- .../single-process/mam/emissions/input.yaml | 4 + 4 files changed, 217 insertions(+), 79 deletions(-) diff --git a/components/eamxx/src/control/atmosphere_surface_coupling_importer.cpp b/components/eamxx/src/control/atmosphere_surface_coupling_importer.cpp index e87bebd34e1c..2c3360a3b4f7 100644 --- a/components/eamxx/src/control/atmosphere_surface_coupling_importer.cpp +++ b/components/eamxx/src/control/atmosphere_surface_coupling_importer.cpp @@ -59,7 +59,6 @@ void SurfaceCouplingImporter::set_grids(const std::shared_ptr("ram1", scalar2d, s/m, grid_name); // Sea surface temperature [K] - //FIXME: Verify the units add_field("sst", scalar2d, K, grid_name); //dust fluxes [kg/m^2/s]: Four flux values for eacch column add_field("dstflx", vector4d, kg/m2/s, grid_name); 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 5e44fd1e35e0..b495c6614ef2 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 @@ -19,41 +19,101 @@ MAMSrfOnlineEmiss::MAMSrfOnlineEmiss(const ekat::Comm &comm, // ================================================================ void MAMSrfOnlineEmiss::set_grids( const std::shared_ptr grids_manager) { - grid_ = grids_manager->get_grid("Physics"); + grid_ = grids_manager->get_grid("Physics"); const auto &grid_name = grid_->name(); - ncol_ = grid_->get_num_local_dofs(); // Number of columns on this rank - nlev_ = grid_->get_num_vertical_levels(); // Number of levels per column + ncol_ = grid_->get_num_local_dofs(); // Number of columns on this rank + nlev_ = grid_->get_num_vertical_levels(); // Number of levels per column using namespace ekat::units; + constexpr auto m2 = pow(m, 2); + constexpr auto s2 = pow(s, 2); + constexpr auto q_unit = kg / kg; // units of mass mixing ratios of tracers + constexpr auto n_unit = 1 / kg; // units of number mixing ratios of tracers + constexpr auto nondim = ekat::units::Units::nondimensional(); - static constexpr int pcnst = mam4::aero_model::pcnst; - const FieldLayout scalar2d_pcnct = - grid_->get_2d_vector_layout(pcnst, "num_phys_constituents"); - // auto vector3d_mid = grid_->get_3d_vector_layout(true, 2); + const FieldLayout scalar2d = grid_->get_2d_scalar_layout(); + const FieldLayout scalar3d_m = grid_->get_3d_scalar_layout(true); // mid + const FieldLayout scalar3d_i = grid_->get_3d_scalar_layout(false); // int + + // For U and V components of wind + const FieldLayout vector3d = grid_->get_3d_vector_layout(true, 2); + + // For components of dust flux + const FieldLayout vector4d = grid_->get_2d_vector_layout(4); + + // -------------------------------------------------------------------------- + // These variables are "Required" or pure inputs for the process + // -------------------------------------------------------------------------- + + // ----------- Atmospheric quantities ------------- + + // -- Variables required for building DS to compute z_mid -- + // Specific humidity [kg/kg] + // FIXME: Comply with add_tracer calls + add_field("qv", scalar3d_m, q_unit, grid_name, "tracers"); + + // Cloud liquid mass mixing ratio [kg/kg] + add_field("qc", scalar3d_m, q_unit, grid_name, "tracers"); + + // Cloud ice mass mixing ratio [kg/kg] + add_field("qi", scalar3d_m, q_unit, grid_name, "tracers"); + + // Cloud liquid number mixing ratio [1/kg] + add_field("nc", scalar3d_m, n_unit, grid_name, "tracers"); + + // Cloud ice number mixing ratio [1/kg] + add_field("ni", scalar3d_m, n_unit, grid_name, "tracers"); + + // Temperature[K] at midpoints + add_field("T_mid", scalar3d_m, K, grid_name); + + // Vertical pressure velocity [Pa/s] at midpoints (Require only for building + // DS) + add_field("omega", scalar3d_m, Pa / s, grid_name); + + // Total pressure [Pa] at midpoints + add_field("p_mid", scalar3d_m, Pa, grid_name); + + // Total pressure [Pa] at interfaces + add_field("p_int", scalar3d_i, Pa, grid_name); + + // Layer thickness(pdel) [Pa] at midpoints + add_field("pseudo_density", scalar3d_m, Pa, grid_name); - // FIXME: online emissions requires the following quantities for the - // OnlineEmissionsData struct: {surface_temp, u_bottom, v_bottom, z_bottom, - // ocean_frac} - // // Temperature - // add_field("T_mid", scalar3d_layout_mid, K, grid_name); - // add_field("horiz_winds", vector3d_mid, m/s, grid_name); - // vertical wind? - // ocean_frac? + // Planetary boundary layer height [m] + add_field("pbl_height", scalar2d, m, grid_name); + + // Surface geopotential [m2/s2] + add_field("phis", scalar2d, m2 / s2, grid_name); + + //----------- Variables from microphysics scheme ------------- + + // Total cloud fraction [fraction] (Require only for building DS) + add_field("cldfrac_tot", scalar3d_m, nondim, grid_name); + + // -- Variables required for online dust and sea salt emissions -- + + // U and V components of the wind[m/s] + add_field("horiz_winds", vector3d, m / s, grid_name); + + // Sea surface temperature [K] + add_field("sst", scalar2d, K, grid_name); + + // dust fluxes [kg/m^2/s]: Four flux values for eacch column + add_field("dstflx", vector4d, kg / m2 / s, grid_name); // ------------------------------------------------------------- - // These variables are "Computed" or outputs for the process - // FIXME: this should likely be an updated field, since online emissisons - // expects input values for constituent_fluxes - // NOTE: the other option is that we do something like: - // add_field("constituent_fluxes_input", scalar2d_pcnct, - // kg / m2 / s, grid_name); - // and then bundle the online emissions computations as tendencies into the - // Computed constituent_fluxes field + // These variables are "Updated" or input-outputs for the process // ------------------------------------------------------------- - constexpr auto m2 = pow(m, 2); + + constexpr int pcnst = mam4::aero_model::pcnst; + const FieldLayout vector2d_pcnst = + grid_->get_2d_vector_layout(pcnst, "num_phys_constituents"); + // Constituent fluxes of species in [kg/m2/s] - add_field("constituent_fluxes", scalar2d_pcnct, kg / m2 / s, + // FIXME: confirm if it is Updated or Computed + add_field("constituent_fluxes", vector2d_pcnst, kg / m2 / s, grid_name); // Surface emissions remapping file @@ -66,20 +126,20 @@ void MAMSrfOnlineEmiss::set_grids( //-------------------------------------------------------------------- srf_emiss_ dms; // File name, name and sectors - dms.data_file = m_params.get("srf_emis_specifier_for_DMS"); + dms.data_file = m_params.get("srf_emis_specifier_for_DMS"); dms.species_name = "dms"; - dms.sectors = {"DMS"}; - srf_emiss_species_.push_back(dms); // add to the vector + dms.sectors = {"DMS"}; + srf_emiss_species_.push_back(dms); // add to the vector //-------------------------------------------------------------------- // Init so2 srf emiss data structures //-------------------------------------------------------------------- srf_emiss_ so2; // File name, name and sectors - so2.data_file = m_params.get("srf_emis_specifier_for_SO2"); + so2.data_file = m_params.get("srf_emis_specifier_for_SO2"); so2.species_name = "so2"; - so2.sectors = {"AGR", "RCO", "SHP", "SLV", "TRA", "WST"}; - srf_emiss_species_.push_back(so2); // add to the vector + so2.sectors = {"AGR", "RCO", "SHP", "SLV", "TRA", "WST"}; + srf_emiss_species_.push_back(so2); // add to the vector //-------------------------------------------------------------------- // Init bc_a4 srf emiss data structures @@ -88,8 +148,8 @@ void MAMSrfOnlineEmiss::set_grids( // File name, name and sectors bc_a4.data_file = m_params.get("srf_emis_specifier_for_bc_a4"); bc_a4.species_name = "bc_a4"; - bc_a4.sectors = {"AGR", "ENE", "IND", "RCO", "SHP", "SLV", "TRA", "WST"}; - srf_emiss_species_.push_back(bc_a4); // add to the vector + bc_a4.sectors = {"AGR", "ENE", "IND", "RCO", "SHP", "SLV", "TRA", "WST"}; + srf_emiss_species_.push_back(bc_a4); // add to the vector //-------------------------------------------------------------------- // Init num_a1 srf emiss data structures @@ -98,9 +158,9 @@ void MAMSrfOnlineEmiss::set_grids( // File name, name and sectors num_a1.data_file = m_params.get("srf_emis_specifier_for_num_a1"); num_a1.species_name = "num_a1"; - num_a1.sectors = {"num_a1_SO4_AGR", "num_a1_SO4_SHP", "num_a1_SO4_SLV", - "num_a1_SO4_WST"}; - srf_emiss_species_.push_back(num_a1); // add to the vector + num_a1.sectors = {"num_a1_SO4_AGR", "num_a1_SO4_SHP", "num_a1_SO4_SLV", + "num_a1_SO4_WST"}; + srf_emiss_species_.push_back(num_a1); // add to the vector //-------------------------------------------------------------------- // Init num_a2 srf emiss data structures @@ -109,8 +169,8 @@ void MAMSrfOnlineEmiss::set_grids( // File name, name and sectors num_a2.data_file = m_params.get("srf_emis_specifier_for_num_a2"); num_a2.species_name = "num_a2"; - num_a2.sectors = {"num_a2_SO4_RCO", "num_a2_SO4_TRA"}; - srf_emiss_species_.push_back(num_a2); // add to the vector + num_a2.sectors = {"num_a2_SO4_RCO", "num_a2_SO4_TRA"}; + srf_emiss_species_.push_back(num_a2); // add to the vector //-------------------------------------------------------------------- // Init num_a4 srf emiss data structures @@ -119,12 +179,12 @@ void MAMSrfOnlineEmiss::set_grids( // File name, name and sectors num_a4.data_file = m_params.get("srf_emis_specifier_for_num_a4"); num_a4.species_name = "num_a4"; - num_a4.sectors = { - "num_a1_BC_AGR", "num_a1_BC_ENE", "num_a1_BC_IND", "num_a1_BC_RCO", - "num_a1_BC_SHP", "num_a1_BC_SLV", "num_a1_BC_TRA", "num_a1_BC_WST", - "num_a1_POM_AGR", "num_a1_POM_ENE", "num_a1_POM_IND", "num_a1_POM_RCO", - "num_a1_POM_SHP", "num_a1_POM_SLV", "num_a1_POM_TRA", "num_a1_POM_WST"}; - srf_emiss_species_.push_back(num_a4); // add to the vector + num_a4.sectors = { + "num_a1_BC_AGR", "num_a1_BC_ENE", "num_a1_BC_IND", "num_a1_BC_RCO", + "num_a1_BC_SHP", "num_a1_BC_SLV", "num_a1_BC_TRA", "num_a1_BC_WST", + "num_a1_POM_AGR", "num_a1_POM_ENE", "num_a1_POM_IND", "num_a1_POM_RCO", + "num_a1_POM_SHP", "num_a1_POM_SLV", "num_a1_POM_TRA", "num_a1_POM_WST"}; + srf_emiss_species_.push_back(num_a4); // add to the vector //-------------------------------------------------------------------- // Init pom_a4 srf emiss data structures @@ -134,7 +194,7 @@ void MAMSrfOnlineEmiss::set_grids( pom_a4.data_file = m_params.get("srf_emis_specifier_for_pom_a4"); pom_a4.species_name = "pom_a4"; pom_a4.sectors = {"AGR", "ENE", "IND", "RCO", "SHP", "SLV", "TRA", "WST"}; - srf_emiss_species_.push_back(pom_a4); // add to the vector + srf_emiss_species_.push_back(pom_a4); // add to the vector //-------------------------------------------------------------------- // Init so4_a1 srf emiss data structures @@ -143,7 +203,7 @@ void MAMSrfOnlineEmiss::set_grids( // File name, name and sectors so4_a1.data_file = m_params.get("srf_emis_specifier_for_so4_a1"); so4_a1.species_name = "so4_a1"; - so4_a1.sectors = {"AGR", "SHP", "SLV", "WST"}; + so4_a1.sectors = {"AGR", "SHP", "SLV", "WST"}; srf_emiss_species_.push_back(so4_a1); //-------------------------------------------------------------------- @@ -153,20 +213,20 @@ void MAMSrfOnlineEmiss::set_grids( // File name, name and sectors so4_a2.data_file = m_params.get("srf_emis_specifier_for_so4_a2"); so4_a2.species_name = "so4_a2"; - so4_a2.sectors = {"RCO", "TRA"}; + so4_a2.sectors = {"RCO", "TRA"}; srf_emiss_species_.push_back(so4_a2); //-------------------------------------------------------------------- // Init data structures to read and interpolate //-------------------------------------------------------------------- - for (srf_emiss_ &ispec_srf : srf_emiss_species_) { + for(srf_emiss_ &ispec_srf : srf_emiss_species_) { srfEmissFunc::init_srf_emiss_objects( ncol_, grid_, ispec_srf.data_file, ispec_srf.sectors, srf_map_file, // output ispec_srf.horizInterp_, ispec_srf.data_start_, ispec_srf.data_end_, ispec_srf.data_out_, ispec_srf.dataReader_); } -} // set_grid ends +} // set_grid ends // ================================================================ // REQUEST_BUFFER_SIZE_IN_BYTES @@ -184,9 +244,9 @@ size_t MAMSrfOnlineEmiss::requested_buffer_size_in_bytes() const { // intermediate (dry) quantities on the given number of columns with the given // number of vertical levels. Returns the number of bytes allocated. void MAMSrfOnlineEmiss::init_buffers(const ATMBufferManager &buffer_manager) { - EKAT_REQUIRE_MSG(buffer_manager.allocated_bytes() >= - requested_buffer_size_in_bytes(), - "Error! Insufficient buffer size.\n"); + EKAT_REQUIRE_MSG( + buffer_manager.allocated_bytes() >= requested_buffer_size_in_bytes(), + "Error! Insufficient buffer size.\n"); size_t used_mem = mam_coupling::init_buffer(buffer_manager, ncol_, nlev_, buffer_); @@ -199,6 +259,42 @@ void MAMSrfOnlineEmiss::init_buffers(const ATMBufferManager &buffer_manager) { // INITIALIZE_IMPL // ================================================================ void MAMSrfOnlineEmiss::initialize_impl(const RunType run_type) { + // --------------------------------------------------------------- + // Input fields read in from IC file, namelist or other processes + // --------------------------------------------------------------- + + // Populate the wet atmosphere state with views from fields + wet_atm_.qv = get_field_in("qv").get_view(); + + // Following wet_atm vars are required only for building DS + wet_atm_.qc = get_field_in("qc").get_view(); + wet_atm_.nc = get_field_in("nc").get_view(); + wet_atm_.qi = get_field_in("qi").get_view(); + wet_atm_.ni = get_field_in("ni").get_view(); + + // Populate the dry atmosphere state with views from fields + dry_atm_.T_mid = get_field_in("T_mid").get_view(); + dry_atm_.p_mid = get_field_in("p_mid").get_view(); + dry_atm_.p_del = get_field_in("pseudo_density").get_view(); + dry_atm_.p_int = get_field_in("p_int").get_view(); + + // Following dry_atm vars are required only for building DS + dry_atm_.cldfrac = get_field_in("cldfrac_tot").get_view(); + dry_atm_.pblh = get_field_in("pbl_height").get_view(); + dry_atm_.omega = get_field_in("omega").get_view(); + + // store fields converted to dry mmr from wet mmr in dry_atm_ + dry_atm_.z_mid = buffer_.z_mid; + dry_atm_.z_iface = buffer_.z_iface; + dry_atm_.dz = buffer_.dz; + dry_atm_.qv = buffer_.qv_dry; + dry_atm_.qc = buffer_.qc_dry; + dry_atm_.nc = buffer_.nc_dry; + dry_atm_.qi = buffer_.qi_dry; + dry_atm_.ni = buffer_.ni_dry; + dry_atm_.w_updraft = buffer_.w_updraft; + dry_atm_.z_surf = 0.0; // FIXME: for now + // --------------------------------------------------------------- // Output fields // --------------------------------------------------------------- @@ -223,10 +319,10 @@ void MAMSrfOnlineEmiss::initialize_impl(const RunType run_type) { //-------------------------------------------------------------------- // Update surface emissions from file //-------------------------------------------------------------------- - for (srf_emiss_ &ispec_srf : srf_emiss_species_) { + for(srf_emiss_ &ispec_srf : srf_emiss_species_) { srfEmissFunc::update_srfEmiss_data_from_file( ispec_srf.dataReader_, timestamp(), curr_month, *ispec_srf.horizInterp_, - ispec_srf.data_end_); // output + ispec_srf.data_end_); // output } //-------------------------------------------------------------------- @@ -238,15 +334,17 @@ void MAMSrfOnlineEmiss::initialize_impl(const RunType run_type) { //----------------------------------------------------------------- // Setup preprocessing and post processing //----------------------------------------------------------------- - preprocess_.initialize(constituent_fluxes_); + preprocess_.initialize(ncol_, nlev_, wet_atm_, dry_atm_, constituent_fluxes_); -} // end initialize_impl() +} // end initialize_impl() // ================================================================ // RUN_IMPL // ================================================================ void MAMSrfOnlineEmiss::run_impl(const double dt) { // Zero-out output + // FIXME: Find out if we do it in the fortran code + // if we do, this should be a "Computed" field Kokkos::deep_copy(preprocess_.constituent_fluxes_pre_, 0); // Gather time and state information for interpolation @@ -256,7 +354,7 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { // Interpolate srf emiss data //-------------------------------------------------------------------- - for (srf_emiss_ &ispec_srf : srf_emiss_species_) { + for(srf_emiss_ &ispec_srf : srf_emiss_species_) { // Update TimeState, note the addition of dt ispec_srf.timeState_.t_now = ts.frac_of_year_in_days(); @@ -279,7 +377,7 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { // modify units from molecules/cm2/s to kg/m2/s auto fluxes_in_mks_units = this->fluxes_in_mks_units_; - auto constituent_fluxes = this->constituent_fluxes_; + auto constituent_fluxes = this->constituent_fluxes_; const Real mfactor = amufac * mam4::gas_chemistry::adv_mass[species_index - offset_]; // Parallel loop over all the columns to update units @@ -289,7 +387,7 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { ispec_srf.data_out_.emiss_sectors(0, icol) * mfactor; constituent_fluxes(icol, species_index) = fluxes_in_mks_units(icol); }); - } // for loop for species + } // for loop for species auto &online_data = online_emissions.online_emis_data; // TODO: check that units are consistent with srf emissions! @@ -310,13 +408,14 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { // which is a chunk-wise variable at this point // (see: physpkg.F90:{1605 & 1327}) otherwise grabs the end/bottom // col-value once inside aero_model_emissions() - view_1d fluxes_col = Kokkos::subview(online_data.cfluxes, icol, Kokkos::ALL()); + view_1d fluxes_col = + Kokkos::subview(online_data.cfluxes, icol, Kokkos::ALL()); mam4::aero_model_emissions::aero_model_emissions(fluxes_col); }); // 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 Kokkos::deep_copy(constituent_fluxes_, online_data.cfluxes); Kokkos::fence(); -} // run_impl ends +} // run_impl ends // ============================================================================= -} // namespace scream +} // namespace scream 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 80c2efcccd73..97fbbda5acac 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 @@ -12,7 +12,6 @@ // For declaring surface and online emission class derived from atm process // class #include - #include namespace scream { @@ -20,19 +19,31 @@ namespace scream { // The process responsible for handling MAM4 surface and online emissions. The // AD stores exactly ONE instance of this class in its list of subcomponents. class MAMSrfOnlineEmiss final : public scream::AtmosphereProcess { - using KT = ekat::KokkosTypes; - using view_1d = typename KT::template view_1d; - using view_2d = typename KT::template view_2d; + using KT = ekat::KokkosTypes; + using view_1d = typename KT::template view_1d; + using view_2d = typename KT::template view_2d; + using const_view_1d = typename KT::template view_1d; + using const_view_2d = typename KT::template view_2d; // number of horizontal columns and vertical levels int ncol_, nlev_; + // Wet and dry states of atmosphere + mam_coupling::WetAtmosphere wet_atm_; + mam_coupling::DryAtmosphere dry_atm_; + // buffer for sotring temporary variables mam_coupling::Buffer buffer_; // physics grid for column information std::shared_ptr grid_; + // Sea surface temoerature [K] + const_view_1d sst_; + + // Dust fluxes (four values for each col) [kg/m2/s] + const_view_2d dust_fluxes_; + // Constituent fluxes of species in [kg/m2/s] view_2d constituent_fluxes_; @@ -40,11 +51,11 @@ class MAMSrfOnlineEmiss final : public scream::AtmosphereProcess { view_1d fluxes_in_mks_units_; // Unified atomic mass unit used for unit conversion (BAD constant) - static constexpr Real amufac = 1.65979e-23; // 1.e4* kg / amu + static constexpr Real amufac = 1.65979e-23; // 1.e4* kg / amu -public: + public: using srfEmissFunc = mam_coupling::srfEmissFunctions; - using onlineEmiss = mam_coupling::onlineEmissions; + using onlineEmiss = mam_coupling::onlineEmissions; // Constructor MAMSrfOnlineEmiss(const ekat::Comm &comm, const ekat::ParameterList ¶ms); @@ -60,8 +71,8 @@ class MAMSrfOnlineEmiss final : public scream::AtmosphereProcess { std::string name() const { return "mam_srf_online_emissions"; } // grid - void - set_grids(const std::shared_ptr grids_manager) override; + void set_grids( + const std::shared_ptr grids_manager) override; // management of common atm process memory size_t requested_buffer_size_in_bytes() const override; @@ -81,14 +92,39 @@ class MAMSrfOnlineEmiss final : public scream::AtmosphereProcess { struct Preprocess { Preprocess() = default; // on host: initializes preprocess functor with necessary state data - void initialize(const view_2d &constituent_fluxes) { + void initialize(const int ncol, const int nlev, + const mam_coupling::WetAtmosphere &wet_atm, + const mam_coupling::DryAtmosphere &dry_atm, + const view_2d &constituent_fluxes) { + ncol_pre_ = ncol; + nlev_pre_ = nlev; + wet_atm_pre_ = wet_atm; + dry_atm_pre_ = dry_atm; constituent_fluxes_pre_ = constituent_fluxes; } + KOKKOS_INLINE_FUNCTION + void operator()( + const Kokkos::TeamPolicy::member_type &team) const { + const int i = team.league_rank(); // column index + + compute_dry_mixing_ratios(team, wet_atm_pre_, dry_atm_pre_, i); + team.team_barrier(); + // vertical heights has to be computed after computing dry mixing ratios + // for atmosphere + compute_vertical_layer_heights(team, dry_atm_pre_, i); + compute_updraft_velocities(team, wet_atm_pre_, dry_atm_pre_, i); + } // Preprocess operator() + // local variables for preprocess struct - view_2d constituent_fluxes_pre_; - }; // MAMSrfOnlineEmiss::Preprocess + // number of horizontal columns and vertical levels + int ncol_pre_, nlev_pre_; -private: + // local atmospheric and aerosol state data + mam_coupling::WetAtmosphere wet_atm_pre_; + mam_coupling::DryAtmosphere dry_atm_pre_; + view_2d constituent_fluxes_pre_; + }; // MAMSrfOnlineEmiss::Preprocess + private: // preprocessing scratch pad Preprocess preprocess_; @@ -131,8 +167,8 @@ class MAMSrfOnlineEmiss final : public scream::AtmosphereProcess { static constexpr int offset_ = mam4::aero_model::pcnst - mam4::gas_chemistry::gas_pcnst; -}; // MAMSrfOnlineEmiss +}; // MAMSrfOnlineEmiss -} // namespace scream +} // namespace scream -#endif // EAMXX_MAM_SRF_ONLINE_EMISS_HPP +#endif // EAMXX_MAM_SRF_ONLINE_EMISS_HPP diff --git a/components/eamxx/tests/single-process/mam/emissions/input.yaml b/components/eamxx/tests/single-process/mam/emissions/input.yaml index 7a3dfb43f222..b337ce3a503d 100644 --- a/components/eamxx/tests/single-process/mam/emissions/input.yaml +++ b/components/eamxx/tests/single-process/mam/emissions/input.yaml @@ -69,6 +69,10 @@ initial_conditions: #we should get the following variables from other processes pbl_height : 1.0 + dstflx : [ -0.99391637990504811E-011, -0.53350997938896468E-010, -0.12510222703847123E-009, -0.11784238261270793E-009] + ocnfrc: 0.99999999999999989E+000 + sst: 0.30196620710190155E+003 + cldfrac_tot: 0.138584624960092 # The parameters for I/O control Scorpio: From 52afd72edeea8bc59545330623a551cca2fd17fd Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Mon, 28 Oct 2024 11:17:35 -0700 Subject: [PATCH 108/147] Commits changes in submodule MAM4xx --- ...and_online_emissions_process_interface.cpp | 76 +++++++++++-------- externals/mam4xx | 2 +- 2 files changed, 44 insertions(+), 34 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 b495c6614ef2..d2221690c5d4 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 @@ -342,17 +342,43 @@ void MAMSrfOnlineEmiss::initialize_impl(const RunType run_type) { // RUN_IMPL // ================================================================ void MAMSrfOnlineEmiss::run_impl(const double dt) { + const auto scan_policy = ekat::ExeSpaceUtils< + KT::ExeSpace>::get_thread_range_parallel_scan_team_policy(ncol_, nlev_); + + // preprocess input -- needs a scan for the calculation of atm height + Kokkos::parallel_for("preprocess", scan_policy, preprocess_); + Kokkos::fence(); + // Zero-out output // FIXME: Find out if we do it in the fortran code - // if we do, this should be a "Computed" field + // if we do, this should be a "Computed" field, + // ALSO this code should in the preprocessor struct now Kokkos::deep_copy(preprocess_.constituent_fluxes_pre_, 0); - // Gather time and state information for interpolation - auto ts = timestamp() + dt; + //-------------------------------------------------------------------- + // Online emissions from dust and sea salt + //-------------------------------------------------------------------- + + const const_view_2d dstflx = get_field_in("dstflx").get_view(); + auto constituent_fluxes = this->constituent_fluxes_; + // TODO: check that units are consistent with srf emissions! + // copy current values to online-emissions-local version + // TODO: potentially combine with below parfor(icol) loop? + Kokkos::parallel_for( + "online_emis_fluxes", ncol_, KOKKOS_LAMBDA(int icol) { + view_1d fluxes_col = ekat::subview(constituent_fluxes, icol); + mam4::aero_model_emissions::aero_model_emissions(dstflx, fluxes_col); + }); + // 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 + //Kokkos::deep_copy(constituent_fluxes_, online_data.cfluxes); + //Kokkos::fence(); //-------------------------------------------------------------------- - // Interpolate srf emiss data + // Interpolate srf emiss data read in from emissions files //-------------------------------------------------------------------- + // Gather time and state information for interpolation + auto ts = timestamp() + dt; for(srf_emiss_ &ispec_srf : srf_emiss_species_) { // Update TimeState, note the addition of dt @@ -377,7 +403,6 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { // modify units from molecules/cm2/s to kg/m2/s auto fluxes_in_mks_units = this->fluxes_in_mks_units_; - auto constituent_fluxes = this->constituent_fluxes_; const Real mfactor = amufac * mam4::gas_chemistry::adv_mass[species_index - offset_]; // Parallel loop over all the columns to update units @@ -388,34 +413,19 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { constituent_fluxes(icol, species_index) = fluxes_in_mks_units(icol); }); } // for loop for species - - auto &online_data = online_emissions.online_emis_data; - // TODO: check that units are consistent with srf emissions! - // copy current values to online-emissions-local version - Kokkos::deep_copy(online_data.cfluxes, constituent_fluxes_); - // TODO: potentially combine with above parfor(icol) loop? - Kokkos::parallel_for( - "online_emis_fluxes", ncol_, KOKKOS_LAMBDA(int icol) { - // NOTE: calling aero_model_emissions() this way hides the fact that - // some hard-coded data is initialized within mam4::aero_model_emissions - // some of these values definitely need to be read from here column-wise - // the structs.{values} holding the above are: - // SeasaltEmissionsData.{mpoly, mprot, mlip} - // DustEmissionsData.dust_dmt_vwr - // OnlineEmissionsData.{dust_flux_in, surface_temp, u_bottom, - // v_bottom, z_bottom, ocean_frac} - // NOTE: fortran mam4 gets dust_flux_in and ocean_frac from cam_in, - // which is a chunk-wise variable at this point - // (see: physpkg.F90:{1605 & 1327}) otherwise grabs the end/bottom - // col-value once inside aero_model_emissions() - view_1d fluxes_col = - Kokkos::subview(online_data.cfluxes, icol, Kokkos::ALL()); - mam4::aero_model_emissions::aero_model_emissions(fluxes_col); - }); - // 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 - Kokkos::deep_copy(constituent_fluxes_, online_data.cfluxes); - Kokkos::fence(); } // run_impl ends // ============================================================================= } // namespace scream + +// NOTE: calling aero_model_emissions() this way hides the fact that +// some hard-coded data is initialized within mam4::aero_model_emissions +// some of these values definitely need to be read from here column-wise +// the structs.{values} holding the above are: +// SeasaltEmissionsData.{mpoly, mprot, mlip} +// DustEmissionsData.dust_dmt_vwr +// OnlineEmissionsData.{dust_flux_in, surface_temp, u_bottom, +// v_bottom, z_bottom, ocean_frac} +// NOTE: fortran mam4 gets dust_flux_in and ocean_frac from cam_in, +// which is a chunk-wise variable at this point +// (see: physpkg.F90:{1605 & 1327}) otherwise grabs the end/bottom +// col-value once inside aero_model_emissions() \ No newline at end of file diff --git a/externals/mam4xx b/externals/mam4xx index 6bc2697f84b3..c837e32f0f3e 160000 --- a/externals/mam4xx +++ b/externals/mam4xx @@ -1 +1 @@ -Subproject commit 6bc2697f84b38503cc8fe638a6281ea107180e40 +Subproject commit c837e32f0f3ee63d2a7b50bd5bcf9e9b29845265 From 16a12172565d78664dc9eef5d6b90151e9a4b0dc Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Mon, 28 Oct 2024 18:07:49 -0700 Subject: [PATCH 109/147] EAMxx:Adds soil erodibility file read and sent to online emission read --- .../cime_config/namelist_defaults_scream.xml | 9 ++ ...and_online_emissions_process_interface.cpp | 48 +++++- ...and_online_emissions_process_interface.hpp | 5 + .../mam/readfiles/soil_erodibility.hpp | 57 +++++++ .../mam/readfiles/soil_erodibility_impl.hpp | 145 ++++++++++++++++++ .../single-process/mam/emissions/input.yaml | 2 + 6 files changed, 260 insertions(+), 6 deletions(-) create mode 100644 components/eamxx/src/physics/mam/readfiles/soil_erodibility.hpp create mode 100644 components/eamxx/src/physics/mam/readfiles/soil_erodibility_impl.hpp diff --git a/components/eamxx/cime_config/namelist_defaults_scream.xml b/components/eamxx/cime_config/namelist_defaults_scream.xml index 195f46847ef2..402113613760 100644 --- a/components/eamxx/cime_config/namelist_defaults_scream.xml +++ b/components/eamxx/cime_config/namelist_defaults_scream.xml @@ -371,7 +371,16 @@ be lost if SCREAM_HACK_XML is not enabled. ${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 +<<<<<<< HEAD +======= + + + ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/dst_ne30pg2_c20241028.nc + + + ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/dst_ne4pg2_c20241028.nc +>>>>>>> EAMxx:Adds soil erodibility file read and sent to online emission read ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/surface/DMSflux.2010.ne4pg2_conserv.POPmonthlyClimFromACES4BGC_c20240814.nc 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 d2221690c5d4..f6ce5dc9f826 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 @@ -1,8 +1,13 @@ -//#include + #include +// For reading soil erodibility file +#include + namespace scream { +using soilErodibilityFunc = + soil_erodibility::soilErodibilityFunctions; // ================================================================ // Constructor // ================================================================ @@ -225,7 +230,27 @@ void MAMSrfOnlineEmiss::set_grids( // output ispec_srf.horizInterp_, ispec_srf.data_start_, ispec_srf.data_end_, ispec_srf.data_out_, ispec_srf.dataReader_); - } + } // srf emissions file read init + + // ------------------------------------------------------------- + // setup to enable reading soil erodibility file + // ------------------------------------------------------------- + + const std::string soil_erodibility_data_file = + m_params.get("soil_erodibility_file"); + // /compyfs/inputdata/atm/cam/dst/dst_1.9x2.5_c090203.nc + + // Field to be read from file + const std::string field_name = "mbl_bsn_fct_geo"; + + // Dimensions of the filed + const std::string dim_name1 = "ncol"; + + // initialize the file read + soilErodibilityFunc::init_soil_erodibility_file_read( + ncol_, field_name, dim_name1, grid_, soil_erodibility_data_file, + srf_map_file, horizInterp_, dataReader_); // output + } // set_grid ends // ================================================================ @@ -325,6 +350,15 @@ void MAMSrfOnlineEmiss::initialize_impl(const RunType run_type) { ispec_srf.data_end_); // output } + //----------------------------------------------------------------- + // Read Soil erodibility data + //----------------------------------------------------------------- + // This data is time-independent, we read all data here for the + // entire simulation + soilErodibilityFunc::update_soil_erodibility_data_from_file( + dataReader_, *horizInterp_, + soil_erodibility_); // output + //-------------------------------------------------------------------- // Initialize online emissions from file //-------------------------------------------------------------------- @@ -360,19 +394,21 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { //-------------------------------------------------------------------- const const_view_2d dstflx = get_field_in("dstflx").get_view(); - auto constituent_fluxes = this->constituent_fluxes_; + auto constituent_fluxes = this->constituent_fluxes_; + auto soil_erodibility = this->soil_erodibility_; // TODO: check that units are consistent with srf emissions! // copy current values to online-emissions-local version // TODO: potentially combine with below parfor(icol) loop? Kokkos::parallel_for( "online_emis_fluxes", ncol_, KOKKOS_LAMBDA(int icol) { view_1d fluxes_col = ekat::subview(constituent_fluxes, icol); - mam4::aero_model_emissions::aero_model_emissions(dstflx, fluxes_col); + mam4::aero_model_emissions::aero_model_emissions( + dstflx, soil_erodibility, fluxes_col); }); // 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 - //Kokkos::deep_copy(constituent_fluxes_, online_data.cfluxes); - //Kokkos::fence(); + // Kokkos::deep_copy(constituent_fluxes_, online_data.cfluxes); + // Kokkos::fence(); //-------------------------------------------------------------------- // Interpolate srf emiss data read in from emissions files 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 97fbbda5acac..c1915cd81ba1 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 @@ -53,6 +53,11 @@ class MAMSrfOnlineEmiss final : public scream::AtmosphereProcess { // 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 + std::shared_ptr horizInterp_; + std::shared_ptr dataReader_; + const_view_1d soil_erodibility_; + public: using srfEmissFunc = mam_coupling::srfEmissFunctions; using onlineEmiss = mam_coupling::onlineEmissions; diff --git a/components/eamxx/src/physics/mam/readfiles/soil_erodibility.hpp b/components/eamxx/src/physics/mam/readfiles/soil_erodibility.hpp new file mode 100644 index 000000000000..9be7c0f817bc --- /dev/null +++ b/components/eamxx/src/physics/mam/readfiles/soil_erodibility.hpp @@ -0,0 +1,57 @@ +#ifndef SOIL_ERODIBILITY_HPP +#define SOIL_ERODIBILITY_HPP + +// For AtmosphereInput +#include "share/io/scorpio_input.hpp" + +namespace scream { +namespace soil_erodibility { + +template +struct soilErodibilityFunctions { + using Device = DeviceType; + + using KT = KokkosTypes; + using const_view_1d = typename KT::template view_1d; + + // ------------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------------------------- + + // Soil erodibility routines + 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 &scorpio_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_erodibilty +} // namespace scream +#endif // SOIL_ERODIBILITY_HPP + +#include "soil_erodibility_impl.hpp" \ No newline at end of file diff --git a/components/eamxx/src/physics/mam/readfiles/soil_erodibility_impl.hpp b/components/eamxx/src/physics/mam/readfiles/soil_erodibility_impl.hpp new file mode 100644 index 000000000000..2f6a5da6888b --- /dev/null +++ b/components/eamxx/src/physics/mam/readfiles/soil_erodibility_impl.hpp @@ -0,0 +1,145 @@ +#ifndef SOIL_ERODIBILITY_IMPL_HPP +#define SOIL_ERODIBILITY_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 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; + + scorpio::register_file(data_file, scorpio::Read); + const int ncols_data = scorpio::get_dimlen(data_file, dim_name1); + + 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("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); + } + + remapper->registration_begins(); + + const auto tgt_grid = remapper->get_tgt_grid(); + + const auto layout_2d = tgt_grid->get_2d_scalar_layout(); + const auto nondim = ekat::units::Units::nondimensional(); + + Field soil_erodibility( + FieldIdentifier(field_name, layout_2d, nondim, 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(); + return std::make_shared(data_file, io_grid, io_fields, true); +} // create_data_reader + +// ------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------- + +template +void soilErodibilityFunctions::update_soil_erodibility_data_from_file( + std::shared_ptr &scorpio_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"); + scorpio_reader->read_variables(); + 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(/*forward = */ true); + 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 AtmosphereInput object) + soilErodibilityDataReader = create_data_reader(soilErodibilityHorizInterp, data_file); +} // init_soil_erodibility_file_read +} // namespace soil_erodibility +} // namespace scream + +#endif // SOIL_ERODIBILITY_IMPL_HPP diff --git a/components/eamxx/tests/single-process/mam/emissions/input.yaml b/components/eamxx/tests/single-process/mam/emissions/input.yaml index b337ce3a503d..8a109337eec6 100644 --- a/components/eamxx/tests/single-process/mam/emissions/input.yaml +++ b/components/eamxx/tests/single-process/mam/emissions/input.yaml @@ -22,6 +22,8 @@ atmosphere_processes: srf_emis_specifier_for_pom_a4: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/surface/cmip6_mam4_pom_a4_surf_ne2np4_2010_clim_c20240726.nc srf_emis_specifier_for_so4_a1: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/surface/cmip6_mam4_so4_a1_surf_ne2np4_2010_clim_c20240726.nc srf_emis_specifier_for_so4_a2: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/surface/cmip6_mam4_so4_a2_surf_ne2np4_2010_clim_c20240726.nc + + soil_erodibility_file: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/dst_ne2np4_c20241028.nc # FIXME: just set everything to a constant scalar for testing online_emis_IC_ncl_a1: 0.0 online_emis_IC_ncl_a2: 0.0 From 52f32c0015574e43572d19578e95ee5a3ed88a6d Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Tue, 29 Oct 2024 12:13:54 -0700 Subject: [PATCH 110/147] Changes needed to start validatioon with EAM --- ...and_online_emissions_process_interface.cpp | 31 ++++++++++++++++++- .../mam/emissions/CMakeLists.txt | 3 +- .../single-process/mam/emissions/input.yaml | 8 +++-- externals/mam4xx | 2 +- 4 files changed, 38 insertions(+), 6 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 f6ce5dc9f826..5a327f4b1d44 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,14 +6,17 @@ namespace scream { +// For reading soil erodibility file using soilErodibilityFunc = soil_erodibility::soilErodibilityFunctions; + // ================================================================ // Constructor // ================================================================ MAMSrfOnlineEmiss::MAMSrfOnlineEmiss(const ekat::Comm &comm, const ekat::ParameterList ¶ms) : AtmosphereProcess(comm, params) { + // FIXME: Do we want to read dust emiss factor hfrom namelist?? /* Anything that can be initialized without grid information can be * initialized here. Like universal constants. */ @@ -47,6 +50,16 @@ void MAMSrfOnlineEmiss::set_grids( // For components of dust flux const FieldLayout vector4d = grid_->get_2d_vector_layout(4); + // FIXME: The following variables are used for validation ONLY!!! REMOVE + // THEM!!! + add_field("dstflx1", scalar2d, kg / m2 / s, grid_name); + add_field("dstflx2", scalar2d, kg / m2 / s, grid_name); + add_field("dstflx3", scalar2d, kg / m2 / s, grid_name); + add_field("dstflx4", scalar2d, kg / m2 / s, grid_name); + add_field("z_mid", scalar3d_m, kg / m2 / s, grid_name); + add_field("u_wind", scalar3d_m, kg / m2 / s, grid_name); + add_field("v_wind", scalar3d_m, kg / m2 / s, grid_name); + // -------------------------------------------------------------------------- // These variables are "Required" or pure inputs for the process // -------------------------------------------------------------------------- @@ -393,6 +406,20 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { // Online emissions from dust and sea salt //-------------------------------------------------------------------- + // FIXME: Remove the following vars as they are used only for validation + const const_view_2d z_mid = get_field_in("z_mid").get_view(); + const const_view_2d u_wind = get_field_in("u_wind").get_view(); + const const_view_2d v_wind = get_field_in("v_wind").get_view(); + const const_view_1d dstflx1 = + get_field_in("dstflx1").get_view(); + const const_view_1d dstflx2 = + get_field_in("dstflx2").get_view(); + const const_view_1d dstflx3 = + get_field_in("dstflx3").get_view(); + const const_view_1d dstflx4 = + get_field_in("dstflx4").get_view(); + // FIXME: Remove ^^^^^^ + const const_view_2d dstflx = get_field_in("dstflx").get_view(); auto constituent_fluxes = this->constituent_fluxes_; auto soil_erodibility = this->soil_erodibility_; @@ -400,11 +427,13 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { // copy current values to online-emissions-local version // TODO: potentially combine with below parfor(icol) loop? Kokkos::parallel_for( - "online_emis_fluxes", ncol_, KOKKOS_LAMBDA(int icol) { + // "online_emis_fluxes", ncol_, KOKKOS_LAMBDA(int icol) { + "online_emis_fluxes", 1, KOKKOS_LAMBDA(int icol) { view_1d fluxes_col = ekat::subview(constituent_fluxes, icol); mam4::aero_model_emissions::aero_model_emissions( dstflx, soil_erodibility, fluxes_col); }); + // 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 // Kokkos::deep_copy(constituent_fluxes_, online_data.cfluxes); diff --git a/components/eamxx/tests/single-process/mam/emissions/CMakeLists.txt b/components/eamxx/tests/single-process/mam/emissions/CMakeLists.txt index c8e690b929fc..8191338fb661 100644 --- a/components/eamxx/tests/single-process/mam/emissions/CMakeLists.txt +++ b/components/eamxx/tests/single-process/mam/emissions/CMakeLists.txt @@ -13,7 +13,8 @@ CreateADUnitTest(${TEST_BASE_NAME} # Set AD configurable options set (ATM_TIME_STEP 1800) -SetVarDependingOnTestSize(NUM_STEPS 2 5 48) # 1h 2.5h 24h +#SetVarDependingOnTestSize(NUM_STEPS 2 5 48) # 1h 2.5h 24h +SetVarDependingOnTestSize(NUM_STEPS 1 1 1) set (RUN_T0 2021-10-12-45000) ## Copy (and configure) yaml files needed by tests diff --git a/components/eamxx/tests/single-process/mam/emissions/input.yaml b/components/eamxx/tests/single-process/mam/emissions/input.yaml index 8a109337eec6..48a658ab1512 100644 --- a/components/eamxx/tests/single-process/mam/emissions/input.yaml +++ b/components/eamxx/tests/single-process/mam/emissions/input.yaml @@ -64,17 +64,19 @@ grids_manager: initial_conditions: # The name of the file containing the initial conditions for this test. - Filename: ${SCREAM_DATA_DIR}/init/${EAMxx_tests_IC_FILE_MAM4xx_72lev} + #Filename: ${SCREAM_DATA_DIR}/init/${EAMxx_tests_IC_FILE_MAM4xx_72lev} + Filename: /qfs/people/sing201/eagles/refactor_mam/mam4xx_scream/4src/screami_unit_tests_mam4xx_ne2np4L72_LAT_81p6352444000824_LON_44p7676953136545_ONLINE_EMISS_1st.nc topography_filename: ${TOPO_DATA_DIR}/${EAMxx_tests_TOPO_FILE} phis : 1.0 #These should come from the input file #we should get the following variables from other processes pbl_height : 1.0 - dstflx : [ -0.99391637990504811E-011, -0.53350997938896468E-010, -0.12510222703847123E-009, -0.11784238261270793E-009] + dstflx : [-0.21955382571753977E-009, -0.11785111846584436E-008, -0.27634792128795150E-008, -0.26031109314006694E-008] ocnfrc: 0.99999999999999989E+000 - sst: 0.30196620710190155E+003 + sst: 0.27286547802237800E+003 cldfrac_tot: 0.138584624960092 + horiz_winds: [-0.63549092155149021E+001, 0.10220040376206645E+001] # The parameters for I/O control Scorpio: diff --git a/externals/mam4xx b/externals/mam4xx index c837e32f0f3e..16f1ab9d97c1 160000 --- a/externals/mam4xx +++ b/externals/mam4xx @@ -1 +1 @@ -Subproject commit c837e32f0f3ee63d2a7b50bd5bcf9e9b29845265 +Subproject commit 16f1ab9d97c10faa0bbd50755b7d1e08506aa01a From dd258dff26f9e213ea79fd9de3fcef609e78fbd3 Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Tue, 29 Oct 2024 18:13:25 -0700 Subject: [PATCH 111/147] EAMxx: dust emissions matches EAMvs grdi cell --- ...and_online_emissions_process_interface.cpp | 45 +++++++++++++++++-- .../single-process/mam/emissions/input.yaml | 10 ++--- 2 files changed, 46 insertions(+), 9 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 5a327f4b1d44..c82665361b12 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 @@ -115,10 +115,14 @@ void MAMSrfOnlineEmiss::set_grids( // U and V components of the wind[m/s] add_field("horiz_winds", vector3d, m / s, grid_name); + //----------- Variables from coupler (ocean component)--------- + // Ocean fraction [unitless] + add_field("ocnfrac", scalar2d, nondim, grid_name); + // Sea surface temperature [K] add_field("sst", scalar2d, K, grid_name); - // dust fluxes [kg/m^2/s]: Four flux values for eacch column + // dust fluxes [kg/m^2/s]: Four flux values for each column add_field("dstflx", vector4d, kg / m2 / s, grid_name); // ------------------------------------------------------------- @@ -420,18 +424,51 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { get_field_in("dstflx4").get_view(); // FIXME: Remove ^^^^^^ + // dust fluxes [kg/m^2/s]: Four flux values for each column const const_view_2d dstflx = get_field_in("dstflx").get_view(); - auto constituent_fluxes = this->constituent_fluxes_; - auto soil_erodibility = this->soil_erodibility_; + + // Ocean fraction [unitless] + const const_view_1d ocnfrac = + get_field_in("ocnfrac").get_view(); + + // Sea surface temperature [K] + const const_view_1d sst = get_field_in("sst").get_view(); + + // U wind component [m/s] + const const_view_2d u_bottom = + get_field_in("horiz_winds").get_component(0).get_view(); + + // V wind component [m/s] + const const_view_2d v_bottom = + get_field_in("horiz_winds").get_component(1).get_view(); + + // Constituent fluxes [kg/m^2/s] + auto constituent_fluxes = this->constituent_fluxes_; + + // Soil edodibility [fraction] + auto soil_erodibility = this->soil_erodibility_; + // TODO: check that units are consistent with srf emissions! // copy current values to online-emissions-local version // TODO: potentially combine with below parfor(icol) loop? + const int surf_lev = nlev_ - 1; + Kokkos::parallel_for( // "online_emis_fluxes", ncol_, KOKKOS_LAMBDA(int icol) { "online_emis_fluxes", 1, KOKKOS_LAMBDA(int icol) { + // gather all input + const const_view_1d dstflx_icol = ekat::subview(dstflx, icol); + const const_view_1d u_bottom_icol = ekat::subview(u_bottom, icol); + const const_view_1d v_bottom_icol = ekat::subview(v_bottom, icol); + + // output view_1d fluxes_col = ekat::subview(constituent_fluxes, icol); + + // comput online emissions mam4::aero_model_emissions::aero_model_emissions( - dstflx, soil_erodibility, fluxes_col); + sst(icol), ocnfrac(icol), u_bottom(icol, surf_lev), + v_bottom(icol, surf_lev), dstflx_icol, soil_erodibility(icol), + fluxes_col); }); // NOTE: mam4::aero_model_emissions calculates mass and number emission fluxes diff --git a/components/eamxx/tests/single-process/mam/emissions/input.yaml b/components/eamxx/tests/single-process/mam/emissions/input.yaml index 48a658ab1512..3f41c3d91801 100644 --- a/components/eamxx/tests/single-process/mam/emissions/input.yaml +++ b/components/eamxx/tests/single-process/mam/emissions/input.yaml @@ -65,18 +65,18 @@ grids_manager: initial_conditions: # The name of the file containing the initial conditions for this test. #Filename: ${SCREAM_DATA_DIR}/init/${EAMxx_tests_IC_FILE_MAM4xx_72lev} - Filename: /qfs/people/sing201/eagles/refactor_mam/mam4xx_scream/4src/screami_unit_tests_mam4xx_ne2np4L72_LAT_81p6352444000824_LON_44p7676953136545_ONLINE_EMISS_1st.nc + Filename: /qfs/people/sing201/eagles/refactor_mam/mam4xx_scream/4src/screami_unit_tests_mam4xx_ne2np4L72_LAT_39p0553303768561_LON_83p8339931334693_ONLINE_EMISS_1st.nc topography_filename: ${TOPO_DATA_DIR}/${EAMxx_tests_TOPO_FILE} phis : 1.0 #These should come from the input file #we should get the following variables from other processes pbl_height : 1.0 - dstflx : [-0.21955382571753977E-009, -0.11785111846584436E-008, -0.27634792128795150E-008, -0.26031109314006694E-008] - ocnfrc: 0.99999999999999989E+000 - sst: 0.27286547802237800E+003 + dstflx : [ -0.15639291491198312E-010, -0.83947887868839890E-010, -0.19684857140996447E-009, -0.18542519360366344E-009] + ocnfrac: 0.0 + sst: 0.0 cldfrac_tot: 0.138584624960092 - horiz_winds: [-0.63549092155149021E+001, 0.10220040376206645E+001] + horiz_winds: [0.70975328186226694E+001, 0.83157735469095362E+000] # The parameters for I/O control Scorpio: From 9e0ad96960f1fe94a944d61e0d7e57c03ca29028 Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Tue, 29 Oct 2024 19:09:14 -0700 Subject: [PATCH 112/147] EAMxx:calculate_seasalt_numflux_in_bins validated --- ...and_online_emissions_process_interface.cpp | 30 ++++++++----------- externals/mam4xx | 2 +- 2 files changed, 14 insertions(+), 18 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 c82665361b12..ff239861dd44 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 @@ -57,9 +57,6 @@ void MAMSrfOnlineEmiss::set_grids( add_field("dstflx3", scalar2d, kg / m2 / s, grid_name); add_field("dstflx4", scalar2d, kg / m2 / s, grid_name); add_field("z_mid", scalar3d_m, kg / m2 / s, grid_name); - add_field("u_wind", scalar3d_m, kg / m2 / s, grid_name); - add_field("v_wind", scalar3d_m, kg / m2 / s, grid_name); - // -------------------------------------------------------------------------- // These variables are "Required" or pure inputs for the process // -------------------------------------------------------------------------- @@ -411,9 +408,7 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { //-------------------------------------------------------------------- // FIXME: Remove the following vars as they are used only for validation - const const_view_2d z_mid = get_field_in("z_mid").get_view(); - const const_view_2d u_wind = get_field_in("u_wind").get_view(); - const const_view_2d v_wind = get_field_in("v_wind").get_view(); + const const_view_2d z_mid2 = get_field_in("z_mid").get_view(); const const_view_1d dstflx1 = get_field_in("dstflx1").get_view(); const const_view_1d dstflx2 = @@ -435,11 +430,11 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { const const_view_1d sst = get_field_in("sst").get_view(); // U wind component [m/s] - const const_view_2d u_bottom = + const const_view_2d u_wind = get_field_in("horiz_winds").get_component(0).get_view(); // V wind component [m/s] - const const_view_2d v_bottom = + const const_view_2d v_wind = get_field_in("horiz_winds").get_component(1).get_view(); // Constituent fluxes [kg/m^2/s] @@ -448,6 +443,9 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { // Soil edodibility [fraction] auto soil_erodibility = this->soil_erodibility_; + // Vertical layer height at midpoints + const const_view_2d z_mid = dry_atm_.z_mid; + // TODO: check that units are consistent with srf emissions! // copy current values to online-emissions-local version // TODO: potentially combine with below parfor(icol) loop? @@ -456,19 +454,17 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { Kokkos::parallel_for( // "online_emis_fluxes", ncol_, KOKKOS_LAMBDA(int icol) { "online_emis_fluxes", 1, KOKKOS_LAMBDA(int icol) { - // gather all input - const const_view_1d dstflx_icol = ekat::subview(dstflx, icol); - const const_view_1d u_bottom_icol = ekat::subview(u_bottom, icol); - const const_view_1d v_bottom_icol = ekat::subview(v_bottom, icol); + // input + const const_view_1d dstflx_icol = ekat::subview(dstflx, icol); // output view_1d fluxes_col = ekat::subview(constituent_fluxes, icol); // comput online emissions mam4::aero_model_emissions::aero_model_emissions( - sst(icol), ocnfrac(icol), u_bottom(icol, surf_lev), - v_bottom(icol, surf_lev), dstflx_icol, soil_erodibility(icol), - fluxes_col); + sst(icol), ocnfrac(icol), u_wind(icol, surf_lev), + v_wind(icol, surf_lev), z_mid(icol, surf_lev), dstflx_icol, + soil_erodibility(icol), fluxes_col); }); // NOTE: mam4::aero_model_emissions calculates mass and number emission fluxes @@ -525,8 +521,8 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { // the structs.{values} holding the above are: // SeasaltEmissionsData.{mpoly, mprot, mlip} // DustEmissionsData.dust_dmt_vwr -// OnlineEmissionsData.{dust_flux_in, surface_temp, u_bottom, -// v_bottom, z_bottom, ocean_frac} +// OnlineEmissionsData.{dust_flux_in, surface_temp, u_wind, +// v_wind, z_bottom, ocean_frac} // NOTE: fortran mam4 gets dust_flux_in and ocean_frac from cam_in, // which is a chunk-wise variable at this point // (see: physpkg.F90:{1605 & 1327}) otherwise grabs the end/bottom diff --git a/externals/mam4xx b/externals/mam4xx index 16f1ab9d97c1..328abdcc7fba 160000 --- a/externals/mam4xx +++ b/externals/mam4xx @@ -1 +1 @@ -Subproject commit 16f1ab9d97c10faa0bbd50755b7d1e08506aa01a +Subproject commit 328abdcc7fba6ca9f122cb204da2773b1e7792cf From a7d47e949f778efd34e28f2650af84a97c0563b9 Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Wed, 30 Oct 2024 11:17:01 -0700 Subject: [PATCH 113/147] EAMxx: marine_organic_emis validated with hardwired file read mom --- ...and_online_emissions_process_interface.cpp | 39 +++++++++++-------- .../single-process/mam/emissions/input.yaml | 10 ++--- externals/mam4xx | 2 +- 3 files changed, 29 insertions(+), 22 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 ff239861dd44..75524dbdc539 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 @@ -52,10 +52,6 @@ void MAMSrfOnlineEmiss::set_grids( // FIXME: The following variables are used for validation ONLY!!! REMOVE // THEM!!! - add_field("dstflx1", scalar2d, kg / m2 / s, grid_name); - add_field("dstflx2", scalar2d, kg / m2 / s, grid_name); - add_field("dstflx3", scalar2d, kg / m2 / s, grid_name); - add_field("dstflx4", scalar2d, kg / m2 / s, grid_name); add_field("z_mid", scalar3d_m, kg / m2 / s, grid_name); // -------------------------------------------------------------------------- // These variables are "Required" or pure inputs for the process @@ -252,18 +248,37 @@ void MAMSrfOnlineEmiss::set_grids( const std::string soil_erodibility_data_file = m_params.get("soil_erodibility_file"); - // /compyfs/inputdata/atm/cam/dst/dst_1.9x2.5_c090203.nc // Field to be read from file - const std::string field_name = "mbl_bsn_fct_geo"; + const std::string soil_erod_fld_name = "mbl_bsn_fct_geo"; // Dimensions of the filed - const std::string dim_name1 = "ncol"; + const std::string soil_erod_dname = "ncol"; // initialize the file read soilErodibilityFunc::init_soil_erodibility_file_read( - ncol_, field_name, dim_name1, grid_, soil_erodibility_data_file, + ncol_, soil_erod_fld_name, soil_erod_dname, grid_, + soil_erodibility_data_file, srf_map_file, horizInterp_, + dataReader_); // output + // ------------------------------------------------------------- + // setup to enable reading marine organics file + // ------------------------------------------------------------- +#if 0 + const std::string marine_organics_data_file = + m_params.get("marine_organics_file"); + + // Field to be read from file + const std::vector marine_org_fld_name = { + "CHL1", "TRUEPOLYC", "TRUEPROTC", "TRUELIPC"}; + + // Dimensions of the filed + const std::string marine_org_dname = "ncol"; + + // initialize the file read + soilErodibilityFunc::init_soil_erodibility_file_read( + ncol_, marine_org_fld_name, marine_org_dname, grid_, marine_organics_data_file, srf_map_file, horizInterp_, dataReader_); // output +#endif } // set_grid ends @@ -409,14 +424,6 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { // FIXME: Remove the following vars as they are used only for validation const const_view_2d z_mid2 = get_field_in("z_mid").get_view(); - const const_view_1d dstflx1 = - get_field_in("dstflx1").get_view(); - const const_view_1d dstflx2 = - get_field_in("dstflx2").get_view(); - const const_view_1d dstflx3 = - get_field_in("dstflx3").get_view(); - const const_view_1d dstflx4 = - get_field_in("dstflx4").get_view(); // FIXME: Remove ^^^^^^ // dust fluxes [kg/m^2/s]: Four flux values for each column diff --git a/components/eamxx/tests/single-process/mam/emissions/input.yaml b/components/eamxx/tests/single-process/mam/emissions/input.yaml index 3f41c3d91801..b8b97e11185e 100644 --- a/components/eamxx/tests/single-process/mam/emissions/input.yaml +++ b/components/eamxx/tests/single-process/mam/emissions/input.yaml @@ -65,18 +65,18 @@ grids_manager: initial_conditions: # The name of the file containing the initial conditions for this test. #Filename: ${SCREAM_DATA_DIR}/init/${EAMxx_tests_IC_FILE_MAM4xx_72lev} - Filename: /qfs/people/sing201/eagles/refactor_mam/mam4xx_scream/4src/screami_unit_tests_mam4xx_ne2np4L72_LAT_39p0553303768561_LON_83p8339931334693_ONLINE_EMISS_1st.nc + Filename: /qfs/people/sing201/eagles/refactor_mam/mam4xx_scream/4src/screami_unit_tests_mam4xx_ne2np4L72_LAT_m5p57727434969464_LON_83p9312243922771_ONLINE_EMISS_1st.nc topography_filename: ${TOPO_DATA_DIR}/${EAMxx_tests_TOPO_FILE} phis : 1.0 #These should come from the input file #we should get the following variables from other processes pbl_height : 1.0 - dstflx : [ -0.15639291491198312E-010, -0.83947887868839890E-010, -0.19684857140996447E-009, -0.18542519360366344E-009] - ocnfrac: 0.0 - sst: 0.0 + dstflx : [ 0.00000000000000000E+000, 0.00000000000000000E+000, 0.00000000000000000E+000, 0.00000000000000000E+000] + ocnfrac: 0.10000000000000000E+001 + sst: 0.30178553874977507E+003 cldfrac_tot: 0.138584624960092 - horiz_winds: [0.70975328186226694E+001, 0.83157735469095362E+000] + horiz_winds: [-0.24988988196194634E+000, -0.23959782871450760E+000] # The parameters for I/O control Scorpio: diff --git a/externals/mam4xx b/externals/mam4xx index 328abdcc7fba..4f6259f61aed 160000 --- a/externals/mam4xx +++ b/externals/mam4xx @@ -1 +1 @@ -Subproject commit 328abdcc7fba6ca9f122cb204da2773b1e7792cf +Subproject commit 4f6259f61aeda3814df542e541a7a48de35e255e From 059466761743ff86359241a83d02da13897e7c49 Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Wed, 30 Oct 2024 17:05:37 -0700 Subject: [PATCH 114/147] EAMxx: Partial implementation of marine orgaics file read --- .../cime_config/namelist_defaults_scream.xml | 16 +- ...and_online_emissions_process_interface.cpp | 21 ++- ...and_online_emissions_process_interface.hpp | 17 +- .../physics/mam/readfiles/marine_organics.hpp | 111 ++++++++++++ .../mam/readfiles/marine_organics_impl.hpp | 169 ++++++++++++++++++ .../mam/readfiles/soil_erodibility.hpp | 2 +- .../mam/readfiles/soil_erodibility_impl.hpp | 34 ++-- .../mam/emissions/CMakeLists.txt | 2 + .../single-process/mam/emissions/input.yaml | 1 + 9 files changed, 338 insertions(+), 35 deletions(-) create mode 100644 components/eamxx/src/physics/mam/readfiles/marine_organics.hpp create mode 100644 components/eamxx/src/physics/mam/readfiles/marine_organics_impl.hpp diff --git a/components/eamxx/cime_config/namelist_defaults_scream.xml b/components/eamxx/cime_config/namelist_defaults_scream.xml index 402113613760..8b3a1131d2a7 100644 --- a/components/eamxx/cime_config/namelist_defaults_scream.xml +++ b/components/eamxx/cime_config/namelist_defaults_scream.xml @@ -382,16 +382,10 @@ be lost if SCREAM_HACK_XML is not enabled. ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/dst_ne4pg2_c20241028.nc >>>>>>> EAMxx:Adds soil erodibility file read and sent to online emission read - - ${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/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 @@ -618,6 +612,7 @@ be lost if SCREAM_HACK_XML is not enabled. ${DIN_LOC_ROOT}/atm/cam/topo/USGS-gtopo30_CA_ne32_x32_v1_pg2_16xdel2.nc + ${CASE}.scream 0.0 0.0 @@ -703,6 +698,7 @@ be lost if SCREAM_HACK_XML is not enabled. + ./${CASE}.scream default ${REST_N} 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 75524dbdc539..a7514c7ee5d0 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 @@ -258,27 +258,30 @@ void MAMSrfOnlineEmiss::set_grids( // 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, horizInterp_, - dataReader_); // output + soil_erodibility_data_file, srf_map_file, serod_horizInterp_, + serod_dataReader_); // output // ------------------------------------------------------------- // setup to enable reading marine organics file // ------------------------------------------------------------- -#if 0 + const std::string marine_organics_data_file = m_params.get("marine_organics_file"); + // /compyfs/inputdata/atm/cam/chem/trop_mam/marine_BGC/monthly_macromolecules_0.1deg_bilinear_latlon_year01_merge_date.nc // Field to be read from file const std::vector marine_org_fld_name = { - "CHL1", "TRUEPOLYC", "TRUEPROTC", "TRUELIPC"}; + "TRUEPOLYC", "TRUEPROTC", "TRUELIPC"}; // Dimensions of the filed const std::string marine_org_dname = "ncol"; // initialize the file read - soilErodibilityFunc::init_soil_erodibility_file_read( - ncol_, marine_org_fld_name, marine_org_dname, grid_, marine_organics_data_file, - srf_map_file, horizInterp_, dataReader_); // output -#endif + 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_); } // set_grid ends @@ -385,7 +388,7 @@ void MAMSrfOnlineEmiss::initialize_impl(const RunType run_type) { // This data is time-independent, we read all data here for the // entire simulation soilErodibilityFunc::update_soil_erodibility_data_from_file( - dataReader_, *horizInterp_, + serod_dataReader_, *serod_horizInterp_, soil_erodibility_); // output //-------------------------------------------------------------------- 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 c1915cd81ba1..fb162ee94e44 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 @@ -9,6 +9,9 @@ #include #include +// For reading marine organics file +#include + // For declaring surface and online emission class derived from atm process // class #include @@ -54,13 +57,16 @@ class MAMSrfOnlineEmiss final : public scream::AtmosphereProcess { static constexpr Real amufac = 1.65979e-23; // 1.e4* kg / amu // For reading soil erodibility file - std::shared_ptr horizInterp_; - std::shared_ptr dataReader_; + std::shared_ptr serod_horizInterp_; + std::shared_ptr serod_dataReader_; const_view_1d soil_erodibility_; public: using srfEmissFunc = mam_coupling::srfEmissFunctions; using onlineEmiss = mam_coupling::onlineEmissions; + // For reading marine organics file + using marineOrganicsFunc = + marine_organics::marineOrganicsFunctions; // Constructor MAMSrfOnlineEmiss(const ekat::Comm &comm, const ekat::ParameterList ¶ms); @@ -168,6 +174,13 @@ class MAMSrfOnlineEmiss final : public scream::AtmosphereProcess { onlineEmiss online_emissions; + // 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_; + // offset for converting pcnst index to gas_pcnst index static constexpr int offset_ = mam4::aero_model::pcnst - mam4::gas_chemistry::gas_pcnst; diff --git a/components/eamxx/src/physics/mam/readfiles/marine_organics.hpp b/components/eamxx/src/physics/mam/readfiles/marine_organics.hpp new file mode 100644 index 000000000000..0c472fdb44c5 --- /dev/null +++ b/components/eamxx/src/physics/mam/readfiles/marine_organics.hpp @@ -0,0 +1,111 @@ +#ifndef MARINE_ORGANICS_HPP +#define MARINE_ORGANICS_HPP + +// For AtmosphereInput +#include "share/io/scorpio_input.hpp" + +namespace scream { +namespace marine_organics { + +template +struct marineOrganicsFunctions { + using Device = DeviceType; + + using KT = KokkosTypes; + 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/scream_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 nsectors_) + : ncols(ncol_), nsectors(nsectors_) { + 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 nsectors_) { + init(ncols_, nsectors_); + } + + void init(const int ncols_, const int nsectors_) { + data.init(ncols_, nsectors_, 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); + + // ------------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------------------------- +#if 0 + static void update_marine_organics_data_from_file( + std::shared_ptr &scorpio_reader, + AbstractRemapper &horiz_interp, const_view_1d &input); +#endif + // ------------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------------------------- + + 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" \ No newline at end of file diff --git a/components/eamxx/src/physics/mam/readfiles/marine_organics_impl.hpp b/components/eamxx/src/physics/mam/readfiles/marine_organics_impl.hpp new file mode 100644 index 000000000000..ba97affafd59 --- /dev/null +++ b/components/eamxx/src/physics/mam/readfiles/marine_organics_impl.hpp @@ -0,0 +1,169 @@ +#ifndef MARINE_ORGANICS_IMPL_HPP +#define MARINE_ORGANICS_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 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; + + scorpio::register_file(data_file, scorpio::Read); + const int ncols_data = scorpio::get_dimlen(data_file, dim_name1); + + 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("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); + } + + remapper->registration_begins(); + + const auto tgt_grid = remapper->get_tgt_grid(); + + const auto layout_2d = tgt_grid->get_2d_scalar_layout(); + const auto nondim = ekat::units::Units::nondimensional(); + + 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, nondim, 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 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 + +// ------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------- +#if 0 +template +void marineOrganicsFunctions::update_marine_organics_data_from_file( + std::shared_ptr &scorpio_reader, + AbstractRemapper &horiz_interp, const_view_1d &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"); + scorpio_reader->read_variables(); + 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(/*forward = */ true); + 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 + input = horiz_interp.get_tgt_field(0).get_view(); + 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 +#endif +// ------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------- + +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, 1, true); + + // Create reader (an AtmosphereInput object) + marineOrganicsDataReader = + create_data_reader(marineOrganicsHorizInterp, data_file); + +} // init_marine_organics_file_read +} // namespace marine_organics +} // namespace scream + +#endif // MARINE_ORGANICS_IMPL_HPP \ No newline at end of file diff --git a/components/eamxx/src/physics/mam/readfiles/soil_erodibility.hpp b/components/eamxx/src/physics/mam/readfiles/soil_erodibility.hpp index 9be7c0f817bc..223fb78cfc14 100644 --- a/components/eamxx/src/physics/mam/readfiles/soil_erodibility.hpp +++ b/components/eamxx/src/physics/mam/readfiles/soil_erodibility.hpp @@ -50,7 +50,7 @@ struct soilErodibilityFunctions { }; // struct soilErodilityFunctions -} // namespace soil_erodibilty +} // namespace soil_erodibility } // namespace scream #endif // SOIL_ERODIBILITY_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 index 2f6a5da6888b..a685134419fe 100644 --- a/components/eamxx/src/physics/mam/readfiles/soil_erodibility_impl.hpp +++ b/components/eamxx/src/physics/mam/readfiles/soil_erodibility_impl.hpp @@ -15,11 +15,10 @@ 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; scorpio::register_file(data_file, scorpio::Read); - const int ncols_data = scorpio::get_dimlen(data_file, dim_name1); + const int ncols_data = scorpio::get_dimlen(data_file, dim_name1); scorpio::release_file(data_file); @@ -44,7 +43,8 @@ soilErodibilityFunctions::create_horiz_remapper( 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."); + " but remap file is missing from soil erodibility " + "parameter list."); remapper = std::make_shared(horiz_interp_tgt_grid, map_file); @@ -73,7 +73,8 @@ soilErodibilityFunctions::create_horiz_remapper( // ------------------------------------------------------------------------------------------- template -std::shared_ptr soilErodibilityFunctions::create_data_reader( +std::shared_ptr +soilErodibilityFunctions::create_data_reader( const std::shared_ptr &horiz_remapper, const std::string &data_file) { std::vector io_fields; @@ -95,27 +96,33 @@ void soilErodibilityFunctions::update_soil_erodibility_data_from_file( // 1. Read from file start_timer( - "EAMxx::soilErodibility::update_soil_erodibility_data_from_file::read_data"); + "EAMxx::soilErodibility::update_soil_erodibility_data_from_file::read_" + "data"); scorpio_reader->read_variables(); stop_timer( - "EAMxx::soilErodibility::update_soil_erodibility_data_from_file::read_data"); + "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) + // 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"); + "EAMxx::soilErodibility::update_soil_erodibility_data_from_file::horiz_" + "remap"); horiz_interp.remap(/*forward = */ true); stop_timer( - "EAMxx::soilErodibility::update_soil_erodibility_data_from_file::horiz_remap"); + "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"); + "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"); + "EAMxx::soilErodibility::update_soil_erodibility_data_from_file::get_" + "field"); stop_timer("EAMxx::soilErodibility::update_soil_erodibility_data_from_file"); @@ -137,7 +144,8 @@ void soilErodibilityFunctions::init_soil_erodibility_file_read( grid, data_file, mapping_file, field_name, dim_name1); // Create reader (an AtmosphereInput object) - soilErodibilityDataReader = create_data_reader(soilErodibilityHorizInterp, data_file); + soilErodibilityDataReader = + create_data_reader(soilErodibilityHorizInterp, data_file); } // init_soil_erodibility_file_read } // namespace soil_erodibility } // namespace scream diff --git a/components/eamxx/tests/single-process/mam/emissions/CMakeLists.txt b/components/eamxx/tests/single-process/mam/emissions/CMakeLists.txt index 8191338fb661..4b7350a1bb95 100644 --- a/components/eamxx/tests/single-process/mam/emissions/CMakeLists.txt +++ b/components/eamxx/tests/single-process/mam/emissions/CMakeLists.txt @@ -37,6 +37,8 @@ set (TEST_INPUT_FILES 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/dst_ne2np4_c20241028.nc + scream/mam4xx/emissions/ne2np4/monthly_macromolecules_0.1deg_bilinear_year01_merge_ne2np4_c20241030.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 b8b97e11185e..ce103765b703 100644 --- a/components/eamxx/tests/single-process/mam/emissions/input.yaml +++ b/components/eamxx/tests/single-process/mam/emissions/input.yaml @@ -24,6 +24,7 @@ atmosphere_processes: srf_emis_specifier_for_so4_a2: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/surface/cmip6_mam4_so4_a2_surf_ne2np4_2010_clim_c20240726.nc soil_erodibility_file: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/dst_ne2np4_c20241028.nc + marine_organics_file: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/monthly_macromolecules_0.1deg_bilinear_year01_merge_ne2np4_c20241030.nc # FIXME: just set everything to a constant scalar for testing online_emis_IC_ncl_a1: 0.0 online_emis_IC_ncl_a2: 0.0 From 2f0d6c8c84d913556b9277dab038e154c1d79bbb Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Wed, 30 Oct 2024 20:10:28 -0700 Subject: [PATCH 115/147] EAMxx:Reading and interpolation of mariane organic file works, not tested yet --- ...and_online_emissions_process_interface.cpp | 31 +++- .../physics/mam/readfiles/marine_organics.hpp | 68 +++++--- .../mam/readfiles/marine_organics_impl.hpp | 150 ++++++++++++++++-- 3 files changed, 217 insertions(+), 32 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 a7514c7ee5d0..cdabc48a7d98 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 @@ -260,10 +260,10 @@ void MAMSrfOnlineEmiss::set_grids( ncol_, soil_erod_fld_name, soil_erod_dname, grid_, soil_erodibility_data_file, srf_map_file, serod_horizInterp_, serod_dataReader_); // output + // ------------------------------------------------------------- // setup to enable reading marine organics file // ------------------------------------------------------------- - const std::string marine_organics_data_file = m_params.get("marine_organics_file"); // /compyfs/inputdata/atm/cam/chem/trop_mam/marine_BGC/monthly_macromolecules_0.1deg_bilinear_latlon_year01_merge_date.nc @@ -282,6 +282,7 @@ void MAMSrfOnlineEmiss::set_grids( // output morg_horizInterp_, morg_data_start_, morg_data_end_, morg_data_out_, morg_dataReader_); + printf("END SIZE:%i,%i\n", morg_data_end_.data.ncols, ncol_); } // set_grid ends @@ -391,6 +392,14 @@ void MAMSrfOnlineEmiss::initialize_impl(const RunType run_type) { serod_dataReader_, *serod_horizInterp_, soil_erodibility_); // output + //-------------------------------------------------------------------- + // Update marine orgaincs from file + //-------------------------------------------------------------------- + + marineOrganicsFunc::update_marine_organics_data_from_file( + morg_dataReader_, timestamp(), curr_month, *morg_horizInterp_, + morg_data_end_); // output + //-------------------------------------------------------------------- // Initialize online emissions from file //-------------------------------------------------------------------- @@ -421,10 +430,28 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { // ALSO this code should in the preprocessor struct now Kokkos::deep_copy(preprocess_.constituent_fluxes_pre_, 0); + // Gather time and state information for interpolation + const auto ts = timestamp() + dt; + //-------------------------------------------------------------------- // Online emissions from dust and sea salt //-------------------------------------------------------------------- + // --- Interpolate mariane 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 marineOrganics routine to get interpolated aerosol forcings. + marineOrganicsFunc::marineOrganics_main(morg_timeState_, morg_data_start_, + morg_data_end_, morg_data_out_); + // FIXME: Remove the following vars as they are used only for validation const const_view_2d z_mid2 = get_field_in("z_mid").get_view(); // FIXME: Remove ^^^^^^ @@ -486,7 +513,7 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { // Interpolate srf emiss data read in from emissions files //-------------------------------------------------------------------- // Gather time and state information for interpolation - auto ts = timestamp() + dt; + // auto ts = timestamp() + dt; for(srf_emiss_ &ispec_srf : srf_emiss_species_) { // Update TimeState, note the addition of dt diff --git a/components/eamxx/src/physics/mam/readfiles/marine_organics.hpp b/components/eamxx/src/physics/mam/readfiles/marine_organics.hpp index 0c472fdb44c5..92136d315f51 100644 --- a/components/eamxx/src/physics/mam/readfiles/marine_organics.hpp +++ b/components/eamxx/src/physics/mam/readfiles/marine_organics.hpp @@ -11,9 +11,12 @@ template struct marineOrganicsFunctions { using Device = DeviceType; - using KT = KokkosTypes; - using view_2d = typename KT::template view_2d; + 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. @@ -31,12 +34,12 @@ struct marineOrganicsFunctions { struct marineOrganicsData { marineOrganicsData() = default; - marineOrganicsData(const int ncol_, const int nsectors_) - : ncols(ncol_), nsectors(nsectors_) { + 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) { + void init(const int &ncol, const int &nsector, const bool allocate) { ncols = ncol; nsectors = nsector; if(allocate) emiss_sectors = view_2d("morgAllSectors", nsectors, ncols); @@ -51,12 +54,12 @@ struct marineOrganicsFunctions { // ------------------------------------------------------------------------------------------- struct marineOrganicsInput { marineOrganicsInput() = default; - marineOrganicsInput(const int ncols_, const int nsectors_) { - init(ncols_, nsectors_); + marineOrganicsInput(const int &ncols_, const int &nfields_) { + init(ncols_, nfields_); } - void init(const int ncols_, const int nsectors_) { - data.init(ncols_, nsectors_, true); + void init(const int &ncols_, const int &nfields_) { + data.init(ncols_, nfields_, true); } marineOrganicsData data; // All marineOrganics fields }; // marineOrganicsInput @@ -68,7 +71,6 @@ struct marineOrganicsFunctions { // ------------------------------------------------------------------------------------------- // ------------------------------------------------------------------------------------------- - static std::shared_ptr create_horiz_remapper( const std::shared_ptr &model_grid, const std::string &marineOrganics_data_file, const std::string &map_file, @@ -76,30 +78,60 @@ struct marineOrganicsFunctions { // ------------------------------------------------------------------------------------------- // ------------------------------------------------------------------------------------------- - static std::shared_ptr create_data_reader( const std::shared_ptr &horiz_remapper, const std::string &data_file); // ------------------------------------------------------------------------------------------- // ------------------------------------------------------------------------------------------- -#if 0 static void update_marine_organics_data_from_file( std::shared_ptr &scorpio_reader, - AbstractRemapper &horiz_interp, const_view_1d &input); -#endif + 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 &scorpio_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 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_, + marineOrganicsInput &morg_data_start_, + marineOrganicsInput &morg_data_end_, marineOrganicsData &morg_data_out_, std::shared_ptr &marineOrganicsDataReader); }; // struct marineOrganicsFunctions diff --git a/components/eamxx/src/physics/mam/readfiles/marine_organics_impl.hpp b/components/eamxx/src/physics/mam/readfiles/marine_organics_impl.hpp index ba97affafd59..8f532d5342ab 100644 --- a/components/eamxx/src/physics/mam/readfiles/marine_organics_impl.hpp +++ b/components/eamxx/src/physics/mam/readfiles/marine_organics_impl.hpp @@ -22,9 +22,8 @@ marineOrganicsFunctions::create_horiz_remapper( 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) + // 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); @@ -93,11 +92,11 @@ marineOrganicsFunctions::create_data_reader( // ------------------------------------------------------------------------------------------- // ------------------------------------------------------------------------------------------- -#if 0 template void marineOrganicsFunctions::update_marine_organics_data_from_file( - std::shared_ptr &scorpio_reader, - AbstractRemapper &horiz_interp, const_view_1d &input) { + std::shared_ptr &scorpio_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 @@ -125,7 +124,9 @@ void marineOrganicsFunctions::update_marine_organics_data_from_file( "field"); // Recall, the fields are registered in the order: // Read the field from the file +#if 0 input = horiz_interp.get_tgt_field(0).get_view(); +#endif stop_timer( "EAMxx::marineOrganics::update_marine_organics_data_from_file::get_" "field"); @@ -133,20 +134,145 @@ void marineOrganicsFunctions::update_marine_organics_data_from_file( stop_timer("EAMxx::marineOrganics::update_marine_organics_data_from_file"); } // END update_marine_organics_data_from_file -#endif + +// ------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------- +template +void marineOrganicsFunctions::update_marine_organics_timestate( + std::shared_ptr &scorpio_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 = + util::TimeStamp({ts.get_year(), month + 1, 1}, {0, 0, 0}) + .frac_of_year_in_days(); + time_state.days_this_month = util::days_in_month(ts.get_year(), month + 1); + + // 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(scorpio_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 ESU = ekat::ExeSpaceUtils; + + // 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; + using ExeSpace = typename KT::ExeSpace; + using ESU = ekat::ExeSpaceUtils; + const auto policy = ESU::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 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_, + marineOrganicsInput &data_start_, marineOrganicsInput &data_end_, + marineOrganicsData &data_out_, std::shared_ptr &marineOrganicsDataReader) { // Init horizontal remap @@ -156,7 +282,7 @@ void marineOrganicsFunctions::init_marine_organics_file_read( // 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, 1, true); + data_out_.init(ncol, field_name.size(), true); // Create reader (an AtmosphereInput object) marineOrganicsDataReader = From 82e843b479ea22cae32755fb25c61aa1ce43c2ac Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Wed, 30 Oct 2024 20:42:03 -0700 Subject: [PATCH 116/147] EAMxx: Connects marine organics emiss with MAM4xx codes --- ...am_srf_and_online_emissions_process_interface.cpp | 12 +++++++++--- externals/mam4xx | 2 +- 2 files changed, 10 insertions(+), 4 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 cdabc48a7d98..4b3a7470d1fb 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 @@ -268,7 +268,7 @@ void MAMSrfOnlineEmiss::set_grids( m_params.get("marine_organics_file"); // /compyfs/inputdata/atm/cam/chem/trop_mam/marine_BGC/monthly_macromolecules_0.1deg_bilinear_latlon_year01_merge_date.nc - // Field to be read from file + // Field to be read from file (order matters as they are read in same order) const std::vector marine_org_fld_name = { "TRUEPOLYC", "TRUEPROTC", "TRUELIPC"}; @@ -282,7 +282,6 @@ void MAMSrfOnlineEmiss::set_grids( // output morg_horizInterp_, morg_data_start_, morg_data_end_, morg_data_out_, morg_dataReader_); - printf("END SIZE:%i,%i\n", morg_data_end_.data.ncols, ncol_); } // set_grid ends @@ -452,6 +451,11 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { marineOrganicsFunc::marineOrganics_main(morg_timeState_, morg_data_start_, morg_data_end_, morg_data_out_); + // Marine organics emission data read from the file + 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); + // FIXME: Remove the following vars as they are used only for validation const const_view_2d z_mid2 = get_field_in("z_mid").get_view(); // FIXME: Remove ^^^^^^ @@ -501,7 +505,9 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { 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), fluxes_col); + soil_erodibility(icol), mpoly(icol), mprot(icol), mlip(icol), + // out + fluxes_col); }); // NOTE: mam4::aero_model_emissions calculates mass and number emission fluxes diff --git a/externals/mam4xx b/externals/mam4xx index 4f6259f61aed..7d6a52bec710 160000 --- a/externals/mam4xx +++ b/externals/mam4xx @@ -1 +1 @@ -Subproject commit 4f6259f61aeda3814df542e541a7a48de35e255e +Subproject commit 7d6a52bec71003de7da14433db1577042ff77218 From 5d8341f6402620be7b01347e7e91756ea17ce254 Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Wed, 30 Oct 2024 21:18:57 -0700 Subject: [PATCH 117/147] EAMxx:Fixes units for marine organic emissions --- ...and_online_emissions_process_interface.cpp | 41 ++++++------------- ...and_online_emissions_process_interface.hpp | 2 - .../mam/readfiles/marine_organics_impl.hpp | 6 ++- 3 files changed, 16 insertions(+), 33 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 4b3a7470d1fb..a67ddf616049 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 @@ -50,9 +50,6 @@ void MAMSrfOnlineEmiss::set_grids( // For components of dust flux const FieldLayout vector4d = grid_->get_2d_vector_layout(4); - // FIXME: The following variables are used for validation ONLY!!! REMOVE - // THEM!!! - add_field("z_mid", scalar3d_m, kg / m2 / s, grid_name); // -------------------------------------------------------------------------- // These variables are "Required" or pure inputs for the process // -------------------------------------------------------------------------- @@ -79,8 +76,7 @@ void MAMSrfOnlineEmiss::set_grids( // Temperature[K] at midpoints add_field("T_mid", scalar3d_m, K, grid_name); - // Vertical pressure velocity [Pa/s] at midpoints (Require only for building - // DS) + // Vertical pressure velocity [Pa/s] at midpoints add_field("omega", scalar3d_m, Pa / s, grid_name); // Total pressure [Pa] at midpoints @@ -266,9 +262,9 @@ void MAMSrfOnlineEmiss::set_grids( // ------------------------------------------------------------- const std::string marine_organics_data_file = m_params.get("marine_organics_file"); - // /compyfs/inputdata/atm/cam/chem/trop_mam/marine_BGC/monthly_macromolecules_0.1deg_bilinear_latlon_year01_merge_date.nc - // Field to be read from file (order matters as they are read in same order) + // Field 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"}; @@ -394,17 +390,11 @@ 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_, timestamp(), curr_month, *morg_horizInterp_, morg_data_end_); // output - //-------------------------------------------------------------------- - // Initialize online emissions from file - //-------------------------------------------------------------------- - online_emissions.online_emis_data.init(ncol_); - online_emissions.init_from_input_file(m_params); - //----------------------------------------------------------------- // Setup preprocessing and post processing //----------------------------------------------------------------- @@ -436,7 +426,7 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { // Online emissions from dust and sea salt //-------------------------------------------------------------------- - // --- Interpolate mariane organics data -- + // --- Interpolate marine organics data -- // Update TimeState, note the addition of dt morg_timeState_.t_now = ts.frac_of_year_in_days(); @@ -447,22 +437,15 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { // output morg_timeState_, morg_data_start_, morg_data_end_); - // Call the main marineOrganics routine to get interpolated aerosol forcings. + // Call the main marine organics routine to get interpolated forcings. marineOrganicsFunc::marineOrganics_main(morg_timeState_, morg_data_start_, morg_data_end_, morg_data_out_); - // Marine organics emission data read from the file + // 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); - // FIXME: Remove the following vars as they are used only for validation - const const_view_2d z_mid2 = get_field_in("z_mid").get_view(); - // FIXME: Remove ^^^^^^ - - // dust fluxes [kg/m^2/s]: Four flux values for each column - const const_view_2d dstflx = get_field_in("dstflx").get_view(); - // Ocean fraction [unitless] const const_view_1d ocnfrac = get_field_in("ocnfrac").get_view(); @@ -478,6 +461,9 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { const const_view_2d v_wind = get_field_in("horiz_winds").get_component(1).get_view(); + // Dust fluxes [kg/m^2/s]: Four flux values for each column + const const_view_2d dstflx = get_field_in("dstflx").get_view(); + // Constituent fluxes [kg/m^2/s] auto constituent_fluxes = this->constituent_fluxes_; @@ -490,11 +476,10 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { // TODO: check that units are consistent with srf emissions! // copy current values to online-emissions-local version // TODO: potentially combine with below parfor(icol) loop? - const int surf_lev = nlev_ - 1; + const int surf_lev = nlev_ - 1; // surface level Kokkos::parallel_for( - // "online_emis_fluxes", ncol_, KOKKOS_LAMBDA(int icol) { - "online_emis_fluxes", 1, KOKKOS_LAMBDA(int icol) { + "online_emis_fluxes", ncol_, KOKKOS_LAMBDA(int icol) { // input const const_view_1d dstflx_icol = ekat::subview(dstflx, icol); @@ -518,8 +503,6 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { //-------------------------------------------------------------------- // Interpolate srf emiss data read in from emissions files //-------------------------------------------------------------------- - // Gather time and state information for interpolation - // auto ts = timestamp() + dt; for(srf_emiss_ &ispec_srf : srf_emiss_species_) { // Update TimeState, note the addition of dt 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 fb162ee94e44..16cf6dcb74aa 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 @@ -172,8 +172,6 @@ class MAMSrfOnlineEmiss final : public scream::AtmosphereProcess { // A vector for carrying emissions for all the species std::vector srf_emiss_species_; - onlineEmiss online_emissions; - // For reading marine organics file std::shared_ptr morg_horizInterp_; std::shared_ptr morg_dataReader_; diff --git a/components/eamxx/src/physics/mam/readfiles/marine_organics_impl.hpp b/components/eamxx/src/physics/mam/readfiles/marine_organics_impl.hpp index 8f532d5342ab..100b432cb745 100644 --- a/components/eamxx/src/physics/mam/readfiles/marine_organics_impl.hpp +++ b/components/eamxx/src/physics/mam/readfiles/marine_organics_impl.hpp @@ -54,7 +54,9 @@ marineOrganicsFunctions::create_horiz_remapper( const auto tgt_grid = remapper->get_tgt_grid(); const auto layout_2d = tgt_grid->get_2d_scalar_layout(); - const auto nondim = ekat::units::Units::nondimensional(); + using namespace ekat::units; + using namespace ekat::prefixes; + Units umolC(micro * mol, "umol C"); std::vector fields_vector; @@ -62,7 +64,7 @@ marineOrganicsFunctions::create_horiz_remapper( 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, nondim, tgt_grid->name())); + 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); From c681f075a5c5677417c4b7986a3722c1cee6caf9 Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Wed, 30 Oct 2024 21:58:08 -0700 Subject: [PATCH 118/147] EAMxx: Adds logic to zero out constituent fluxes, cleanup --- ...and_online_emissions_process_interface.cpp | 39 ++++--------------- ...and_online_emissions_process_interface.hpp | 21 +++++++--- externals/mam4xx | 2 +- 3 files changed, 25 insertions(+), 37 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 a67ddf616049..1d931435d063 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 @@ -413,12 +413,6 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { Kokkos::parallel_for("preprocess", scan_policy, preprocess_); Kokkos::fence(); - // Zero-out output - // FIXME: Find out if we do it in the fortran code - // if we do, this should be a "Computed" field, - // ALSO this code should in the preprocessor struct now - Kokkos::deep_copy(preprocess_.constituent_fluxes_pre_, 0); - // Gather time and state information for interpolation const auto ts = timestamp() + dt; @@ -468,25 +462,25 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { auto constituent_fluxes = this->constituent_fluxes_; // Soil edodibility [fraction] - auto soil_erodibility = this->soil_erodibility_; + const const_view_1d soil_erodibility = this->soil_erodibility_; // Vertical layer height at midpoints const const_view_2d z_mid = dry_atm_.z_mid; - // TODO: check that units are consistent with srf emissions! - // copy current values to online-emissions-local version // TODO: potentially combine with below parfor(icol) loop? const int surf_lev = nlev_ - 1; // surface level Kokkos::parallel_for( "online_emis_fluxes", ncol_, KOKKOS_LAMBDA(int icol) { - // input + // Input const const_view_1d dstflx_icol = ekat::subview(dstflx, icol); - // output + // Output view_1d fluxes_col = ekat::subview(constituent_fluxes, icol); - // comput online emissions + // Comput 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, @@ -494,11 +488,7 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { // out fluxes_col); }); - - // 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 - // Kokkos::deep_copy(constituent_fluxes_, online_data.cfluxes); - // Kokkos::fence(); + Kokkos::fence(); //-------------------------------------------------------------------- // Interpolate srf emiss data read in from emissions files @@ -539,17 +529,4 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { } // for loop for species } // run_impl ends // ============================================================================= -} // namespace scream - -// NOTE: calling aero_model_emissions() this way hides the fact that -// some hard-coded data is initialized within mam4::aero_model_emissions -// some of these values definitely need to be read from here column-wise -// the structs.{values} holding the above are: -// SeasaltEmissionsData.{mpoly, mprot, mlip} -// DustEmissionsData.dust_dmt_vwr -// OnlineEmissionsData.{dust_flux_in, surface_temp, u_wind, -// v_wind, z_bottom, ocean_frac} -// NOTE: fortran mam4 gets dust_flux_in and ocean_frac from cam_in, -// which is a chunk-wise variable at this point -// (see: physpkg.F90:{1605 & 1327}) otherwise grabs the end/bottom -// col-value once inside aero_model_emissions() \ No newline at end of file +} // namespace scream \ No newline at end of file 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 16cf6dcb74aa..063efad22d4d 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 @@ -103,7 +103,7 @@ class MAMSrfOnlineEmiss final : public scream::AtmosphereProcess { struct Preprocess { Preprocess() = default; // on host: initializes preprocess functor with necessary state data - void initialize(const int ncol, const int nlev, + void initialize(const int &ncol, const int &nlev, const mam_coupling::WetAtmosphere &wet_atm, const mam_coupling::DryAtmosphere &dry_atm, const view_2d &constituent_fluxes) { @@ -116,14 +116,25 @@ class MAMSrfOnlineEmiss final : public scream::AtmosphereProcess { KOKKOS_INLINE_FUNCTION void operator()( const Kokkos::TeamPolicy::member_type &team) const { - const int i = team.league_rank(); // column index + const int icol = team.league_rank(); // column index - compute_dry_mixing_ratios(team, wet_atm_pre_, dry_atm_pre_, i); + compute_dry_mixing_ratios(team, wet_atm_pre_, dry_atm_pre_, icol); team.team_barrier(); // vertical heights has to be computed after computing dry mixing ratios // for atmosphere - compute_vertical_layer_heights(team, dry_atm_pre_, i); - compute_updraft_velocities(team, wet_atm_pre_, dry_atm_pre_, i); + compute_vertical_layer_heights(team, dry_atm_pre_, icol); + compute_updraft_velocities(team, wet_atm_pre_, dry_atm_pre_, icol); + + view_1d flux_col = ekat::subview(constituent_fluxes_pre_, icol); + + // Zero out constituent fluxes only for gasses and aerosols + const int pcnst = mam4::aero_model::pcnst; + const int gas_start_ind = mam4::utils::gasses_start_ind(); + + // FIXME: Is there a better way to zero out a select indices? + for(int ispc = gas_start_ind; ispc < pcnst; ++ispc) { + flux_col(ispc) = 0; + } } // Preprocess operator() // local variables for preprocess struct diff --git a/externals/mam4xx b/externals/mam4xx index 7d6a52bec710..419e04b4943a 160000 --- a/externals/mam4xx +++ b/externals/mam4xx @@ -1 +1 @@ -Subproject commit 7d6a52bec71003de7da14433db1577042ff77218 +Subproject commit 419e04b4943ac4a69d867f6087ca43652a0689a2 From a150d9d53ad5c389ffe4db178d99bd6265e67278 Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Wed, 30 Oct 2024 22:18:26 -0700 Subject: [PATCH 119/147] EAMxx: Reverts input yaml and CMake, changes cons fluxes to updated --- ...and_online_emissions_process_interface.cpp | 5 ++- .../mam/emissions/CMakeLists.txt | 3 +- .../single-process/mam/emissions/input.yaml | 36 ++----------------- 3 files changed, 6 insertions(+), 38 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 1d931435d063..f849595ff343 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 @@ -1,4 +1,3 @@ - #include // For reading soil erodibility file @@ -124,8 +123,8 @@ void MAMSrfOnlineEmiss::set_grids( // 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); + add_field("constituent_fluxes", vector2d_pcnst, kg / m2 / s, + grid_name); // Surface emissions remapping file auto srf_map_file = m_params.get("srf_remap_file", ""); diff --git a/components/eamxx/tests/single-process/mam/emissions/CMakeLists.txt b/components/eamxx/tests/single-process/mam/emissions/CMakeLists.txt index 4b7350a1bb95..65f377b4db1f 100644 --- a/components/eamxx/tests/single-process/mam/emissions/CMakeLists.txt +++ b/components/eamxx/tests/single-process/mam/emissions/CMakeLists.txt @@ -13,8 +13,7 @@ CreateADUnitTest(${TEST_BASE_NAME} # Set AD configurable options set (ATM_TIME_STEP 1800) -#SetVarDependingOnTestSize(NUM_STEPS 2 5 48) # 1h 2.5h 24h -SetVarDependingOnTestSize(NUM_STEPS 1 1 1) +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 diff --git a/components/eamxx/tests/single-process/mam/emissions/input.yaml b/components/eamxx/tests/single-process/mam/emissions/input.yaml index ce103765b703..64a07b844052 100644 --- a/components/eamxx/tests/single-process/mam/emissions/input.yaml +++ b/components/eamxx/tests/single-process/mam/emissions/input.yaml @@ -25,34 +25,6 @@ atmosphere_processes: soil_erodibility_file: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/dst_ne2np4_c20241028.nc marine_organics_file: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/monthly_macromolecules_0.1deg_bilinear_year01_merge_ne2np4_c20241030.nc - # FIXME: just set everything to a constant scalar for testing - online_emis_IC_ncl_a1: 0.0 - online_emis_IC_ncl_a2: 0.0 - online_emis_IC_ncl_a3: 0.0 - online_emis_IC_mom_a1: 0.16838301005552275E-013 - online_emis_IC_mom_a2: 0.26554873160224250E-016 - online_emis_IC_mom_a4: 0.0 - online_emis_IC_num_a1: 0.0 - online_emis_IC_num_a2: 0.0 - online_emis_IC_num_a3: 0.0 - online_emis_IC_num_a4: 0.0 - online_emis_IC_dst_a1: 0.0 - online_emis_IC_dst_a3: 0.18720550166902007E+003 - -# NOTE: these are the single-call results from the mam validation test -# (20) ncl_a1: 2.659900637e-13 -# (25) ncl_a2: 0 -# (29) ncl_a3: 2.391492482e-11 -# (21) mom_a1: 1.683830101e-14 -# (26) mom_a2: 2.655487316e-17 -# (38) mom_a4: 0 -# (22) num_a1: 2.594942753e-15 -# (27) num_a2: 4.092359179e-18 -# (35) num_a3: 0 -# (39) num_a4: 0 -# (19) dst_a1: 0 -# (28) dst_a3: 403.2611563 - grids_manager: Type: Mesh Free geo_data_source: IC_FILE @@ -65,12 +37,10 @@ grids_manager: initial_conditions: # The name of the file containing the initial conditions for this test. - #Filename: ${SCREAM_DATA_DIR}/init/${EAMxx_tests_IC_FILE_MAM4xx_72lev} - Filename: /qfs/people/sing201/eagles/refactor_mam/mam4xx_scream/4src/screami_unit_tests_mam4xx_ne2np4L72_LAT_m5p57727434969464_LON_83p9312243922771_ONLINE_EMISS_1st.nc + Filename: ${SCREAM_DATA_DIR}/init/${EAMxx_tests_IC_FILE_MAM4xx_72lev} topography_filename: ${TOPO_DATA_DIR}/${EAMxx_tests_TOPO_FILE} phis : 1.0 - #These should come from the input file - + #we should get the following variables from other processes pbl_height : 1.0 dstflx : [ 0.00000000000000000E+000, 0.00000000000000000E+000, 0.00000000000000000E+000, 0.00000000000000000E+000] @@ -78,7 +48,7 @@ initial_conditions: sst: 0.30178553874977507E+003 cldfrac_tot: 0.138584624960092 horiz_winds: [-0.24988988196194634E+000, -0.23959782871450760E+000] - + constituent_fluxes: 0.0 # The parameters for I/O control Scorpio: output_yaml_files: ["output.yaml"] From f0a33da27edd95cfde8d670cfe73521d93f041ca Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Wed, 30 Oct 2024 22:33:32 -0700 Subject: [PATCH 120/147] EAMxx: Some fixes after rebase --- .../eamxx_mam_microphysics_process_interface.cpp | 2 +- .../eamxx/src/physics/mam/srf_emission_impl.hpp | 13 +------------ 2 files changed, 2 insertions(+), 13 deletions(-) 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 41713b97735e..5fb4dccb2c8e 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 @@ -76,7 +76,7 @@ void MAMMicrophysics::set_grids( constexpr auto n_unit = 1 / kg; // units of number mixing ratios of tracers ======= config_.amicphys.nucleation = {}; - // config_.amicphys.nucleation.dens_so4a_host = 1770.0; + //config_.amicphys.nucleation.dens_so4a_host = 1770.0; // config_.amicphys.nucleation.mw_so4a_host = 115.0; // config_.amicphys.nucleation.newnuc_method_user_choice = 2; // config_.amicphys.nucleation.pbl_nuc_wang2008_user_choice = 1; diff --git a/components/eamxx/src/physics/mam/srf_emission_impl.hpp b/components/eamxx/src/physics/mam/srf_emission_impl.hpp index b090e3746cb7..4e7f7c14424e 100644 --- a/components/eamxx/src/physics/mam/srf_emission_impl.hpp +++ b/components/eamxx/src/physics/mam/srf_emission_impl.hpp @@ -182,10 +182,7 @@ void srfEmissFunctions::update_srfEmiss_data_from_file( const int time_index, // zero-based AbstractRemapper &srfEmiss_horiz_interp, srfEmissInput &srfEmiss_input) { using namespace ShortFieldTagsNames; - // NOTE: these are currently unused - // using ESU = ekat::ExeSpaceUtils; - // using Member = typename KokkosTypes::MemberType; - + start_timer("EAMxx::srfEmiss::update_srfEmiss_data_from_file"); // 1. Read from file @@ -205,14 +202,6 @@ void srfEmissFunctions::update_srfEmiss_data_from_file( // Recall, the fields are registered in the order: ps, ccn3, g_sw, ssa_sw, // tau_sw, tau_lw - // NOTE: these are currently unused - // const auto &layout = srfEmiss_horiz_interp.get_tgt_field(0) - // .get_header() - // .get_identifier() - // .get_layout(); - - const int ncols = layout.dim(COL); - // Read fields from the file for(int i = 0; i < srfEmiss_horiz_interp.get_num_fields(); ++i) { auto sector = From 80a57f053ecf36f4737d4425c08f512de573f2e4 Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Wed, 30 Oct 2024 23:02:18 -0700 Subject: [PATCH 121/147] EAMxx:Adds loop to update file read for marine organics, cleanup --- .../cime_config/namelist_defaults_scream.xml | 2 - ...and_online_emissions_process_interface.cpp | 5 +- ...and_online_emissions_process_interface.hpp | 4 +- .../eamxx/src/physics/mam/online_emission.hpp | 88 ------------------- .../mam/readfiles/marine_organics_impl.hpp | 17 ++-- .../src/physics/mam/srf_emission_impl.hpp | 3 - 6 files changed, 16 insertions(+), 103 deletions(-) delete mode 100644 components/eamxx/src/physics/mam/online_emission.hpp diff --git a/components/eamxx/cime_config/namelist_defaults_scream.xml b/components/eamxx/cime_config/namelist_defaults_scream.xml index 8b3a1131d2a7..b57a57462532 100644 --- a/components/eamxx/cime_config/namelist_defaults_scream.xml +++ b/components/eamxx/cime_config/namelist_defaults_scream.xml @@ -612,7 +612,6 @@ be lost if SCREAM_HACK_XML is not enabled. ${DIN_LOC_ROOT}/atm/cam/topo/USGS-gtopo30_CA_ne32_x32_v1_pg2_16xdel2.nc - ${CASE}.scream 0.0 0.0 @@ -698,7 +697,6 @@ be lost if SCREAM_HACK_XML is not enabled. - ./${CASE}.scream default ${REST_N} 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 f849595ff343..190dc1da27d9 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 @@ -247,7 +247,7 @@ void MAMSrfOnlineEmiss::set_grids( // Field to be read from file const std::string soil_erod_fld_name = "mbl_bsn_fct_geo"; - // Dimensions of the filed + // Dimensions of the field const std::string soil_erod_dname = "ncol"; // initialize the file read @@ -267,7 +267,7 @@ void MAMSrfOnlineEmiss::set_grids( const std::vector marine_org_fld_name = { "TRUEPOLYC", "TRUEPROTC", "TRUELIPC"}; - // Dimensions of the filed + // Dimensions of the field const std::string marine_org_dname = "ncol"; // initialize the file read @@ -526,6 +526,7 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { constituent_fluxes(icol, species_index) = fluxes_in_mks_units(icol); }); } // for loop for species + Kokkos::fence(); } // run_impl ends // ============================================================================= } // namespace scream \ No newline at end of file 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 063efad22d4d..b1cba682bb62 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 @@ -6,7 +6,6 @@ // For MAM4 aerosol configuration #include -#include #include // For reading marine organics file @@ -62,9 +61,8 @@ class MAMSrfOnlineEmiss final : public scream::AtmosphereProcess { const_view_1d soil_erodibility_; public: + // For reading surface emissions and marine organics file using srfEmissFunc = mam_coupling::srfEmissFunctions; - using onlineEmiss = mam_coupling::onlineEmissions; - // For reading marine organics file using marineOrganicsFunc = marine_organics::marineOrganicsFunctions; diff --git a/components/eamxx/src/physics/mam/online_emission.hpp b/components/eamxx/src/physics/mam/online_emission.hpp deleted file mode 100644 index c8318dcc05cb..000000000000 --- a/components/eamxx/src/physics/mam/online_emission.hpp +++ /dev/null @@ -1,88 +0,0 @@ -#ifndef ONLINE_EMISSION_HPP -#define ONLINE_EMISSION_HPP - -#include "share/util/scream_timing.hpp" - -namespace scream::mam_coupling { -template struct onlineEmissions { - using Device = DeviceType; - using KT = KokkosTypes; - using MemberType = typename KT::MemberType; - static constexpr int pcnst = mam4::aero_model::pcnst; - - struct onlineEmissData { - // Basic spatial dimensions of the data - int ncols; - view_2d flux_data; - // local copy of main fluxes array - view_2d cfluxes; - // FIXME: read this from elsewhere? input? - const std::vector spec_names = { - "ncl_a1", "ncl_a2", "ncl_a3", "mom_a1", "mom_a2", "mom_a4", - "num_a1", "num_a2", "num_a3", "num_a4", "dst_a1", "dst_a3"}; - // FIXME: change this when/if the above is dynamically-determined - int nspec = spec_names.size(); - const std::string root_IC_str = "online_emis_IC_"; - - onlineEmissData() = default; - onlineEmissData(const int ncol_, const int nspec_) - : ncols(ncol_), nspec(nspec_) { - init(ncols, nspec, true); - } - - onlineEmissData(const int ncol_) : ncols(ncol_) { - init(ncols, nspec, true); - } - - // overloads of init() in case npsec is not hard-coded, or if you want to - // control allocation via bool flag - void init(const int ncol_, const int nspec_, const bool allocate_) { - ncols = ncol_; - nspec = nspec_; - if (allocate_) { - flux_data = view_2d("onlineEmissData", nspec, ncols); - cfluxes = view_2d("onlineEmisLocalCflux", ncols, pcnst); - } - } // onlineEmissData init - void init(const int ncol_, const bool allocate_) { - ncols = ncol_; - if (allocate_) { - flux_data = view_2d("onlineEmissData", nspec, ncols); - cfluxes = view_2d("onlineEmisLocalCflux", ncols, pcnst); - } - } // onlineEmissData init - void init(const int ncol_) { - ncols = ncol_; - flux_data = view_2d("onlineEmissData", nspec, ncols); - cfluxes = view_2d("onlineEmisLocalCflux", ncols, pcnst); - } // onlineEmissData init - }; // onlineEmissData - - onlineEmissData online_emis_data; - - // --------------------------------------------------------------------------- - // Online emissions routines - // --------------------------------------------------------------------------- - void init_from_input_file(const ekat::ParameterList ¶ms) { - const int nspec = online_emis_data.nspec; - const int ncols = online_emis_data.ncols; - using ExeSpace = typename KT::ExeSpace; - using ESU = ekat::ExeSpaceUtils; - const auto policy = ESU::get_default_team_policy(ncols, nspec); - // Read from input file - // FIXME: currently reading a single placeholder scalar--should be - // ncols-sized array when we know what the input data looks like - for (int ispec = 0; ispec < nspec; ++ispec) { - Real init_cond_val = - params.get(online_emis_data.root_IC_str + online_emis_data.spec_names[ispec]); - // TODO: is this overkill?--i.e., would a mirror/deep_copy make more sense? - Kokkos::parallel_for( - policy, KOKKOS_LAMBDA(const MemberType &team) { - const int jcol = team.league_rank(); // column index - online_emis_data.flux_data(ispec, jcol) = init_cond_val; - }); - } - } // end init_from_input_file() -}; // struct onlineEmissions -} // namespace scream::mam_coupling -#endif // ONLINE_EMISSION_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 index 100b432cb745..6eda3a47e724 100644 --- a/components/eamxx/src/physics/mam/readfiles/marine_organics_impl.hpp +++ b/components/eamxx/src/physics/mam/readfiles/marine_organics_impl.hpp @@ -85,8 +85,8 @@ marineOrganicsFunctions::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)); + 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(); return std::make_shared(data_file, io_grid, io_fields, true); @@ -126,9 +126,16 @@ void marineOrganicsFunctions::update_marine_organics_data_from_file( "field"); // Recall, the fields are registered in the order: // Read the field from the file -#if 0 - input = horiz_interp.get_tgt_field(0).get_view(); -#endif + + 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"); diff --git a/components/eamxx/src/physics/mam/srf_emission_impl.hpp b/components/eamxx/src/physics/mam/srf_emission_impl.hpp index 4e7f7c14424e..fa037dc281d0 100644 --- a/components/eamxx/src/physics/mam/srf_emission_impl.hpp +++ b/components/eamxx/src/physics/mam/srf_emission_impl.hpp @@ -102,9 +102,6 @@ void srfEmissFunctions::perform_time_interpolation( // NOTE: we *assume* data_beg and data_end have the *same* hybrid v coords. // IF this ever ceases to be the case, you can interp those too. - using ExeSpace = typename KT::ExeSpace; - using ESU = ekat::ExeSpaceUtils; - // Gather time stamp info auto &t_now = time_state.t_now; auto &t_beg = time_state.t_beg_month; From 15f44fd3101cd3a67a634af34e498fc1736362e7 Mon Sep 17 00:00:00 2001 From: Michael J Schmidt Date: Thu, 31 Oct 2024 16:43:23 -0600 Subject: [PATCH 122/147] fixup! EAMxx: Some fixes after rebase small change to kickoff AT --- components/eamxx/tests/single-process/mam/emissions/input.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eamxx/tests/single-process/mam/emissions/input.yaml b/components/eamxx/tests/single-process/mam/emissions/input.yaml index 64a07b844052..a4564cb3949a 100644 --- a/components/eamxx/tests/single-process/mam/emissions/input.yaml +++ b/components/eamxx/tests/single-process/mam/emissions/input.yaml @@ -41,7 +41,7 @@ initial_conditions: topography_filename: ${TOPO_DATA_DIR}/${EAMxx_tests_TOPO_FILE} phis : 1.0 - #we should get the following variables from other processes + # we should get the following variables from other processes pbl_height : 1.0 dstflx : [ 0.00000000000000000E+000, 0.00000000000000000E+000, 0.00000000000000000E+000, 0.00000000000000000E+000] ocnfrac: 0.10000000000000000E+001 From bdd475f60e4fbd7703159f2e1217f43391f6623b Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Fri, 1 Nov 2024 06:59:01 -0700 Subject: [PATCH 123/147] EAMxx:Fixes file path and specify vector components for dust flux --- components/eamxx/cime_config/namelist_defaults_scream.xml | 7 ++++++- components/eamxx/src/mct_coupling/scream_cpl_indices.F90 | 8 ++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/components/eamxx/cime_config/namelist_defaults_scream.xml b/components/eamxx/cime_config/namelist_defaults_scream.xml index b57a57462532..9cc917a8c880 100644 --- a/components/eamxx/cime_config/namelist_defaults_scream.xml +++ b/components/eamxx/cime_config/namelist_defaults_scream.xml @@ -376,12 +376,17 @@ be lost if SCREAM_HACK_XML is not enabled. ======= - ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/dst_ne30pg2_c20241028.nc + ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/dst_ne30pg2_c20241028.nc +<<<<<<< HEAD ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/dst_ne4pg2_c20241028.nc >>>>>>> EAMxx:Adds soil erodibility file read and sent to online emission read +======= + ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/dst_ne4pg2_c20241028.nc + +>>>>>>> EAMxx:Fixes file path and specify vector components for dust flux ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/monthly_macromolecules_0.1deg_bilinear_year01_merge_ne30pg2_c20241030.nc diff --git a/components/eamxx/src/mct_coupling/scream_cpl_indices.F90 b/components/eamxx/src/mct_coupling/scream_cpl_indices.F90 index 15df178d29e5..9462750297fb 100644 --- a/components/eamxx/src/mct_coupling/scream_cpl_indices.F90 +++ b/components/eamxx/src/mct_coupling/scream_cpl_indices.F90 @@ -125,12 +125,16 @@ subroutine scream_set_cpl_indices (x2a, a2x) 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 From 4e120c747c038559b90f9424e895f6795c7c4cfd Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Mon, 4 Nov 2024 11:06:50 -0800 Subject: [PATCH 124/147] EAMxx: MAM4xx submodule pointing to main that include GPU fixes --- ...mxx_mam_microphysics_process_interface.cpp | 102 ++++++++++++++++++ externals/mam4xx | 2 +- 2 files changed, 103 insertions(+), 1 deletion(-) 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 5fb4dccb2c8e..875d63432f8a 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 @@ -611,6 +611,7 @@ void MAMMicrophysics::run_impl(const double dt) { // allocation perspective auto o3_col_dens = buffer_.scratch[8]; +<<<<<<< HEAD /* Gather time and state information for interpolation */ const auto ts = timestamp() + dt; @@ -628,6 +629,107 @@ void MAMMicrophysics::run_impl(const double dt) { dry_atm_.p_mid, dry_atm_.z_iface, // in cnst_offline_); // out Kokkos::fence(); +======= + const_view_1d &col_latitudes = col_latitudes_; + mam_coupling::DryAtmosphere &dry_atm = dry_atm_; + mam_coupling::AerosolState &dry_aero = dry_aero_; + mam4::mo_photo::PhotoTableData &photo_table = photo_table_; + const int nlev = nlev_; + const Config &config = config_; + // FIXME: read relevant linoz climatology data from file(s) based on time + + // FIXME: read relevant chlorine loading data from file based on time + + // loop over atmosphere columns and compute aerosol microphyscs + auto some_step = step_; + + Kokkos::parallel_for(policy, KOKKOS_LAMBDA(const ThreadTeam& team) { + const int icol = team.league_rank(); // column index + + Real col_lat = col_latitudes(icol); // column latitude (degrees?) + + // fetch column-specific atmosphere state data + auto atm = mam_coupling::atmosphere_for_column(dry_atm, icol); + auto z_iface = ekat::subview(dry_atm.z_iface, icol); + Real phis = dry_atm.phis(icol); + + // set surface state data + haero::Surface sfc{}; + + // fetch column-specific subviews into aerosol prognostics + mam4::Prognostics progs = mam_coupling::interstitial_aerosols_for_column(dry_aero, icol); + + // set up diagnostics + mam4::Diagnostics diags(nlev); + + // calculate o3 column densities (first component of col_dens in Fortran code) + auto o3_col_dens_i = ekat::subview(o3_col_dens, icol); + impl::compute_o3_column_density(team, atm, progs, o3_col_dens_i); + + // set up photolysis work arrays for this column. + mam4::mo_photo::PhotoTableWorkArrays photo_work_arrays; + // FIXME: set views here + + // ... look up photolysis rates from our table + // NOTE: the table interpolation operates on an entire column of data, so we + // NOTE: must do it before dispatching to individual vertical levels + Real zenith_angle = 0.0; // FIXME: need to get this from EAMxx [radians] + Real surf_albedo = 0.0; // FIXME: surface albedo + Real esfact = 0.0; // FIXME: earth-sun distance factor + mam4::ColumnView lwc; // FIXME: liquid water cloud content: where do we get this? + //mam4::mo_photo::table_photo(photo_rates, atm.pressure, atm.hydrostatic_dp, + // atm.temperature, o3_col_dens_i, zenith_angle, surf_albedo, lwc, + // atm.cloud_fraction, esfact, photo_table, photo_work_arrays); + + // compute external forcings at time t(n+1) [molecules/cm^3/s] + constexpr int extcnt = mam4::gas_chemistry::extcnt; + view_2d extfrc; // FIXME: where to allocate? (nlev, extcnt) + mam4::mo_setext::Forcing forcings[extcnt]; // FIXME: forcings seem to require file data + mam4::mo_setext::extfrc_set(forcings, extfrc); + + // compute aerosol microphysics on each vertical level within this column + Kokkos::parallel_for(Kokkos::TeamThreadRange(team, nlev), [&](const int k) { + + constexpr int num_modes = mam4::AeroConfig::num_modes(); + constexpr int gas_pcnst = mam_coupling::gas_pcnst(); + constexpr int nqtendbb = mam_coupling::nqtendbb(); + + // extract atm state variables (input) + Real temp = atm.temperature(k); + Real pmid = atm.pressure(k); + Real pdel = atm.hydrostatic_dp(k); + Real zm = atm.height(k); + Real zi = z_iface(k); + Real pblh = atm.planetary_boundary_layer_height; + Real qv = atm.vapor_mixing_ratio(k); + Real cldfrac = atm.cloud_fraction(k); + + // extract aerosol state variables into "working arrays" (mass mixing ratios) + // (in EAM, this is done in the gas_phase_chemdr subroutine defined within + // mozart/mo_gas_phase_chemdr.F90) + Real q[gas_pcnst] = {}; + Real qqcw[gas_pcnst] = {}; + mam_coupling::transfer_prognostics_to_work_arrays(progs, k, q, qqcw); + + // convert mass mixing ratios to volume mixing ratios (VMR), equivalent + // to tracer mixing ratios (TMR)) + Real vmr[gas_pcnst], vmrcw[gas_pcnst]; + mam_coupling::convert_work_arrays_to_vmr(q, qqcw, vmr, vmrcw); + + // aerosol/gas species tendencies (output) + Real vmr_tendbb[gas_pcnst][nqtendbb] = {}; + Real vmrcw_tendbb[gas_pcnst][nqtendbb] = {}; + + // create work array copies to retain "pre-chemistry" values + Real vmr_pregaschem[gas_pcnst] = {}; + Real vmr_precldchem[gas_pcnst] = {}; + Real vmrcw_precldchem[gas_pcnst] = {}; + for (int i = 0; i < gas_pcnst; ++i) { + vmr_pregaschem[i] = vmr[i]; + vmr_precldchem[i] = vmr[i]; + vmrcw_precldchem[i] = vmrcw[i]; + } +>>>>>>> EAMxx: MAM4xx submodule pointing to main that include GPU fixes scream::mam_coupling::advance_tracer_data( LinozDataReader_, // in diff --git a/externals/mam4xx b/externals/mam4xx index 419e04b4943a..59990d402f41 160000 --- a/externals/mam4xx +++ b/externals/mam4xx @@ -1 +1 @@ -Subproject commit 419e04b4943ac4a69d867f6087ca43652a0689a2 +Subproject commit 59990d402f4115ce3a36a8c00eb4d059e703a583 From 7b8f7fdd2871018dabeeae8a53dd76f4333905f9 Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Mon, 4 Nov 2024 13:26:15 -0800 Subject: [PATCH 125/147] EAMxx: Some codes re-arranged after rebase --- .../cime_config/namelist_defaults_scream.xml | 9 -- ...mxx_mam_microphysics_process_interface.cpp | 113 ------------------ 2 files changed, 122 deletions(-) diff --git a/components/eamxx/cime_config/namelist_defaults_scream.xml b/components/eamxx/cime_config/namelist_defaults_scream.xml index 9cc917a8c880..fd62cdc01e37 100644 --- a/components/eamxx/cime_config/namelist_defaults_scream.xml +++ b/components/eamxx/cime_config/namelist_defaults_scream.xml @@ -371,22 +371,13 @@ be lost if SCREAM_HACK_XML is not enabled. ${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 -<<<<<<< HEAD -======= - ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/dst_ne30pg2_c20241028.nc -<<<<<<< HEAD ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/dst_ne4pg2_c20241028.nc ->>>>>>> EAMxx:Adds soil erodibility file read and sent to online emission read -======= - ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne4pg2/dst_ne4pg2_c20241028.nc - ->>>>>>> EAMxx:Fixes file path and specify vector components for dust flux ${DIN_LOC_ROOT}/atm/scream/mam4xx/emissions/ne30pg2/monthly_macromolecules_0.1deg_bilinear_year01_merge_ne30pg2_c20241030.nc 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 875d63432f8a..57eaf9275483 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 @@ -70,20 +70,9 @@ void MAMMicrophysics::set_grids( const FieldLayout scalar3d_mid = grid_->get_3d_scalar_layout(true); const FieldLayout scalar3d_int = grid_->get_3d_scalar_layout(false); -<<<<<<< HEAD using namespace ekat::units; constexpr auto q_unit = kg / kg; // units of mass mixing ratios of tracers constexpr auto n_unit = 1 / kg; // units of number mixing ratios of tracers -======= - config_.amicphys.nucleation = {}; - //config_.amicphys.nucleation.dens_so4a_host = 1770.0; - // config_.amicphys.nucleation.mw_so4a_host = 115.0; - // config_.amicphys.nucleation.newnuc_method_user_choice = 2; - // config_.amicphys.nucleation.pbl_nuc_wang2008_user_choice = 1; - // config_.amicphys.nucleation.adjust_factor_pbl_ratenucl = 1.0; - // config_.amicphys.nucleation.accom_coef_h2so4 = 1.0; - config_.amicphys.nucleation.newnuc_adjust_factor_dnaitdt = 1.0; ->>>>>>> comment out error-inducing code in mam4_amicphys.cpp and small reorg change in online_emission.hpp // -------------------------------------------------------------------------- // These variables are "Required" or pure inputs for the process @@ -611,7 +600,6 @@ void MAMMicrophysics::run_impl(const double dt) { // allocation perspective auto o3_col_dens = buffer_.scratch[8]; -<<<<<<< HEAD /* Gather time and state information for interpolation */ const auto ts = timestamp() + dt; @@ -629,107 +617,6 @@ void MAMMicrophysics::run_impl(const double dt) { dry_atm_.p_mid, dry_atm_.z_iface, // in cnst_offline_); // out Kokkos::fence(); -======= - const_view_1d &col_latitudes = col_latitudes_; - mam_coupling::DryAtmosphere &dry_atm = dry_atm_; - mam_coupling::AerosolState &dry_aero = dry_aero_; - mam4::mo_photo::PhotoTableData &photo_table = photo_table_; - const int nlev = nlev_; - const Config &config = config_; - // FIXME: read relevant linoz climatology data from file(s) based on time - - // FIXME: read relevant chlorine loading data from file based on time - - // loop over atmosphere columns and compute aerosol microphyscs - auto some_step = step_; - - Kokkos::parallel_for(policy, KOKKOS_LAMBDA(const ThreadTeam& team) { - const int icol = team.league_rank(); // column index - - Real col_lat = col_latitudes(icol); // column latitude (degrees?) - - // fetch column-specific atmosphere state data - auto atm = mam_coupling::atmosphere_for_column(dry_atm, icol); - auto z_iface = ekat::subview(dry_atm.z_iface, icol); - Real phis = dry_atm.phis(icol); - - // set surface state data - haero::Surface sfc{}; - - // fetch column-specific subviews into aerosol prognostics - mam4::Prognostics progs = mam_coupling::interstitial_aerosols_for_column(dry_aero, icol); - - // set up diagnostics - mam4::Diagnostics diags(nlev); - - // calculate o3 column densities (first component of col_dens in Fortran code) - auto o3_col_dens_i = ekat::subview(o3_col_dens, icol); - impl::compute_o3_column_density(team, atm, progs, o3_col_dens_i); - - // set up photolysis work arrays for this column. - mam4::mo_photo::PhotoTableWorkArrays photo_work_arrays; - // FIXME: set views here - - // ... look up photolysis rates from our table - // NOTE: the table interpolation operates on an entire column of data, so we - // NOTE: must do it before dispatching to individual vertical levels - Real zenith_angle = 0.0; // FIXME: need to get this from EAMxx [radians] - Real surf_albedo = 0.0; // FIXME: surface albedo - Real esfact = 0.0; // FIXME: earth-sun distance factor - mam4::ColumnView lwc; // FIXME: liquid water cloud content: where do we get this? - //mam4::mo_photo::table_photo(photo_rates, atm.pressure, atm.hydrostatic_dp, - // atm.temperature, o3_col_dens_i, zenith_angle, surf_albedo, lwc, - // atm.cloud_fraction, esfact, photo_table, photo_work_arrays); - - // compute external forcings at time t(n+1) [molecules/cm^3/s] - constexpr int extcnt = mam4::gas_chemistry::extcnt; - view_2d extfrc; // FIXME: where to allocate? (nlev, extcnt) - mam4::mo_setext::Forcing forcings[extcnt]; // FIXME: forcings seem to require file data - mam4::mo_setext::extfrc_set(forcings, extfrc); - - // compute aerosol microphysics on each vertical level within this column - Kokkos::parallel_for(Kokkos::TeamThreadRange(team, nlev), [&](const int k) { - - constexpr int num_modes = mam4::AeroConfig::num_modes(); - constexpr int gas_pcnst = mam_coupling::gas_pcnst(); - constexpr int nqtendbb = mam_coupling::nqtendbb(); - - // extract atm state variables (input) - Real temp = atm.temperature(k); - Real pmid = atm.pressure(k); - Real pdel = atm.hydrostatic_dp(k); - Real zm = atm.height(k); - Real zi = z_iface(k); - Real pblh = atm.planetary_boundary_layer_height; - Real qv = atm.vapor_mixing_ratio(k); - Real cldfrac = atm.cloud_fraction(k); - - // extract aerosol state variables into "working arrays" (mass mixing ratios) - // (in EAM, this is done in the gas_phase_chemdr subroutine defined within - // mozart/mo_gas_phase_chemdr.F90) - Real q[gas_pcnst] = {}; - Real qqcw[gas_pcnst] = {}; - mam_coupling::transfer_prognostics_to_work_arrays(progs, k, q, qqcw); - - // convert mass mixing ratios to volume mixing ratios (VMR), equivalent - // to tracer mixing ratios (TMR)) - Real vmr[gas_pcnst], vmrcw[gas_pcnst]; - mam_coupling::convert_work_arrays_to_vmr(q, qqcw, vmr, vmrcw); - - // aerosol/gas species tendencies (output) - Real vmr_tendbb[gas_pcnst][nqtendbb] = {}; - Real vmrcw_tendbb[gas_pcnst][nqtendbb] = {}; - - // create work array copies to retain "pre-chemistry" values - Real vmr_pregaschem[gas_pcnst] = {}; - Real vmr_precldchem[gas_pcnst] = {}; - Real vmrcw_precldchem[gas_pcnst] = {}; - for (int i = 0; i < gas_pcnst; ++i) { - vmr_pregaschem[i] = vmr[i]; - vmr_precldchem[i] = vmr[i]; - vmrcw_precldchem[i] = vmrcw[i]; - } ->>>>>>> EAMxx: MAM4xx submodule pointing to main that include GPU fixes scream::mam_coupling::advance_tracer_data( LinozDataReader_, // in From 4195b419bee625fb962646433b58ca3c4747f252 Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Mon, 4 Nov 2024 13:29:00 -0800 Subject: [PATCH 126/147] EAMxx:Removes accidently added file --- .../src/physics/mam/impl/mam4_amicphys.cpp | 1819 ----------------- 1 file changed, 1819 deletions(-) delete mode 100644 components/eamxx/src/physics/mam/impl/mam4_amicphys.cpp diff --git a/components/eamxx/src/physics/mam/impl/mam4_amicphys.cpp b/components/eamxx/src/physics/mam/impl/mam4_amicphys.cpp deleted file mode 100644 index e241b5ec428f..000000000000 --- a/components/eamxx/src/physics/mam/impl/mam4_amicphys.cpp +++ /dev/null @@ -1,1819 +0,0 @@ -#include -#include -#include -#include -#include -#include - -namespace scream::impl { - -#define MAX_FILENAME_LEN 256 - -using namespace mam4; - -// number of constituents in gas chemistry "work arrays" -KOKKOS_INLINE_FUNCTION -constexpr int gas_pcnst() { - constexpr int gas_pcnst_ = mam4::gas_chemistry::gas_pcnst; - return gas_pcnst_; -} - -// number of aerosol/gas species tendencies -KOKKOS_INLINE_FUNCTION -constexpr int nqtendbb() { return 4; } - -// MAM4 aerosol microphysics configuration data -struct AmicPhysConfig { - // these switches activate various aerosol microphysics processes - bool do_cond; // condensation (a.k.a gas-aerosol exchange) - bool do_rename; // mode "renaming" - bool do_newnuc; // gas -> aerosol nucleation - bool do_coag; // aerosol coagulation - - // configurations for specific aerosol microphysics - mam4::GasAerExchProcess::ProcessConfig condensation; - mam4::NucleationProcess::ProcessConfig nucleation; - - // controls treatment of h2so4 condensation in mam_gasaerexch_1subarea - // 1 = sequential calc. of gas-chem prod then condensation loss - // 2 = simultaneous calc. of gas-chem prod and condensation loss - int gaexch_h2so4_uptake_optaa; - - // controls how nucleation interprets h2so4 concentrations - int newnuc_h2so4_conc_optaa; -}; - -namespace { - -KOKKOS_INLINE_FUNCTION constexpr int nqtendaa() { return 5; } -KOKKOS_INLINE_FUNCTION constexpr int nqqcwtendaa() { return 1; } -KOKKOS_INLINE_FUNCTION constexpr int nqqcwtendbb() { return 1; } -KOKKOS_INLINE_FUNCTION constexpr int iqtend_cond() { return 0; } -KOKKOS_INLINE_FUNCTION constexpr int iqtend_rnam() { return 1; } -KOKKOS_INLINE_FUNCTION constexpr int iqtend_nnuc() { return 2; } -KOKKOS_INLINE_FUNCTION constexpr int iqtend_coag() { return 3; } -KOKKOS_INLINE_FUNCTION constexpr int iqtend_cond_only() { return 4; } -KOKKOS_INLINE_FUNCTION constexpr int iqqcwtend_rnam() { return 0; } -KOKKOS_INLINE_FUNCTION constexpr int maxsubarea() { return 2; } - -// conversion factors -KOKKOS_INLINE_FUNCTION Real fcvt_gas(int gas_id) { - static const Real fcvt_gas_[AeroConfig::num_gas_ids()] = {1, 1, 1}; - return fcvt_gas_[gas_id]; -} -KOKKOS_INLINE_FUNCTION Real fcvt_aer(int aero_id) { - static const Real fcvt_aer_[AeroConfig::num_aerosol_ids()] = {1, 1, 1, 1, 1, 1, 1}; - return fcvt_aer_[aero_id]; -} - -// leave number mix-ratios unchanged (#/kmol-air) -KOKKOS_INLINE_FUNCTION Real fcvt_num() { return 1.0; } -// factor for converting aerosol water mix-ratios from (kg/kg) to (mol/mol) -KOKKOS_INLINE_FUNCTION Real fcvt_wtr() { return 1.0; } - -KOKKOS_INLINE_FUNCTION constexpr int lmapcc_val_nul() { return 0; } -KOKKOS_INLINE_FUNCTION constexpr int lmapcc_val_gas() { return 1; } -KOKKOS_INLINE_FUNCTION constexpr int lmapcc_val_aer() { return 2; } -KOKKOS_INLINE_FUNCTION constexpr int lmapcc_val_num() { return 3; } -KOKKOS_INLINE_FUNCTION int lmapcc_all(int index) { - static const int lmapcc_all_[gas_pcnst()] = { - lmapcc_val_nul(), lmapcc_val_gas(), lmapcc_val_nul(), lmapcc_val_nul(), - lmapcc_val_gas(), lmapcc_val_aer(), lmapcc_val_aer(), lmapcc_val_aer(), - lmapcc_val_aer(), lmapcc_val_aer(), lmapcc_val_aer(), lmapcc_val_aer(), - lmapcc_val_num(), lmapcc_val_aer(), lmapcc_val_aer(), lmapcc_val_aer(), - lmapcc_val_aer(), lmapcc_val_num(), lmapcc_val_aer(), lmapcc_val_aer(), - lmapcc_val_aer(), lmapcc_val_aer(), lmapcc_val_aer(), lmapcc_val_aer(), - lmapcc_val_aer(), lmapcc_val_num(), lmapcc_val_aer(), lmapcc_val_aer(), - lmapcc_val_aer(), lmapcc_val_num()}; - return lmapcc_all_[index]; -} - -// Where lmapcc_val_num are defined in lmapcc_all -KOKKOS_INLINE_FUNCTION int numptr_amode(int mode) { - static const int numptr_amode_[AeroConfig::num_modes()] = {12, 17, 25, 29}; - return numptr_amode_[mode]; -} - -// Where lmapcc_val_gas are defined in lmapcc_all -KOKKOS_INLINE_FUNCTION int lmap_gas(int mode) { - static const int lmap_gas_[AeroConfig::num_modes()] = {4, 1}; - return lmap_gas_[mode]; -} -// Where lmapcc_val_aer are defined in lmapcc_all -KOKKOS_INLINE_FUNCTION int lmassptr_amode(int aero_id, int mode) { - static const int lmassptr_amode_[AeroConfig::num_aerosol_ids()][AeroConfig::num_modes()] = { - {5, 13, 18, 26}, {6, 14, 19, 27}, {7, 15, 20, 28}, {8, 16, 21, -6}, - {9, -6, 22, -6}, {10, -6, 23, -6}, {11, -6, 24, -6}}; - return lmassptr_amode_[aero_id][mode]; -} - -KOKKOS_INLINE_FUNCTION -void subarea_partition_factors( - const Real - q_int_cell_avg, // in grid cell mean interstitial aerosol mixing ratio - const Real - q_cbn_cell_avg, // in grid cell mean cloud-borne aerosol mixing ratio - const Real fcldy, // in cloudy fraction of the grid cell - const Real fclea, // in clear fraction of the grid cell - Real &part_fac_q_int_clea, // out - Real &part_fac_q_int_cldy) // out -{ - // Calculate mixing ratios of each subarea - - // cloud-borne, cloudy subarea - const Real tmp_q_cbn_cldy = q_cbn_cell_avg / fcldy; - // interstitial, cloudy subarea - const Real tmp_q_int_cldy = - haero::max(0.0, ((q_int_cell_avg + q_cbn_cell_avg) - tmp_q_cbn_cldy)); - // interstitial, clear subarea - const Real tmp_q_int_clea = (q_int_cell_avg - fcldy * tmp_q_int_cldy) / fclea; - - // Calculate the corresponding paritioning factors for interstitial aerosols - // using the above-derived subarea mixing ratios plus the constraint that - // the cloud fraction weighted average of subarea mean need to match grid box - // mean. - - // *** question *** - // use same part_fac_q_int_clea/cldy for everything ? - // use one for number and one for all masses (based on total mass) ? - // use separate ones for everything ? - // maybe one for number and one for all masses is best, - // because number and mass have different activation fractions - // *** question *** - - Real tmp_aa = haero::max(1.e-35, tmp_q_int_clea * fclea) / - haero::max(1.e-35, q_int_cell_avg); - tmp_aa = haero::max(0.0, haero::min(1.0, tmp_aa)); - - part_fac_q_int_clea = tmp_aa / fclea; - part_fac_q_int_cldy = (1.0 - tmp_aa) / fcldy; -} - -KOKKOS_INLINE_FUNCTION -void construct_subareas_1gridcell( - const Real cld, // in - const Real relhumgcm, // in - const Real q_pregaschem[gas_pcnst()], // in q TMRs before - // gas-phase chemistry - const Real q_precldchem[gas_pcnst()], // in q TMRs before - // cloud chemistry - const Real qqcw_precldchem[gas_pcnst()], // in qqcw TMRs before - // cloud chemistry - const Real q[gas_pcnst()], // in current tracer mixing ratios (TMRs) - // *** MUST BE #/kmol-air for number - // *** MUST BE mol/mol-air for mass - const Real qqcw[gas_pcnst()], // in like q but for - // cloud-borner tracers - int &nsubarea, // out - int &ncldy_subarea, // out - int &jclea, // out - int &jcldy, // out - bool iscldy_subarea[maxsubarea()], // out - Real afracsub[maxsubarea()], // out - Real relhumsub[maxsubarea()], // out - Real qsub1[gas_pcnst()][maxsubarea()], // out interstitial - Real qsub2[gas_pcnst()][maxsubarea()], // out interstitial - Real qsub3[gas_pcnst()][maxsubarea()], // out interstitial - Real qqcwsub1[gas_pcnst()][maxsubarea()], // out cloud-borne - Real qqcwsub2[gas_pcnst()][maxsubarea()], // out cloud-borne - Real qqcwsub3[gas_pcnst()][maxsubarea()], // outcloud-borne - Real qaerwatsub3[AeroConfig::num_modes()] - [maxsubarea()], // out aerosol water mixing ratios (mol/mol) - Real qaerwat[AeroConfig::num_modes()] // in aerosol water mixing ratio - // (kg/kg, NOT mol/mol) -) { - static constexpr int num_modes = AeroConfig::num_modes(); - // cloud chemistry is only on when cld(i,k) >= 1.0e-5_wp - // it may be that the macrophysics has a higher threshold that this - const Real fcld_locutoff = 1.0e-5; - const Real fcld_hicutoff = 0.999; - - // qgcmN and qqcwgcmN (N=1:4) are grid-cell mean tracer mixing ratios (TMRs, - // mol/mol or #/kmol) - // N=1 - before gas-phase chemistry - // N=2 - before cloud chemistry - // N=3 - incoming values (before gas-aerosol exchange, newnuc, coag) - // qgcm1, qgcm2, qgcm3 - // qqcwgcm2, qqcwgcm3 - // qaerwatgcm3 ! aerosol water mixing ratios (mol/mol) - - // -------------------------------------------------------------------------------------- - // Determine the number of sub-areas, their fractional areas, and relative - // humidities - // -------------------------------------------------------------------------------------- - // if cloud fraction ~= 0, the grid-cell has a single clear sub-area - // (nsubarea = 1) if cloud fraction ~= 1, the grid-cell has a single cloudy - // sub-area (nsubarea = 1) otherwise, the grid-cell has a - // clear and a cloudy sub-area (nsubarea = 2) - - Real zfcldy = 0; - nsubarea = 0; - ncldy_subarea = 0; - jclea = 0; - jcldy = 0; - - if (cld < fcld_locutoff) { - nsubarea = 1; - jclea = 1; - } else if (cld > fcld_hicutoff) { - zfcldy = 1.0; - nsubarea = 1; - ncldy_subarea = 1; - jcldy = 1; - } else { - zfcldy = cld; - nsubarea = 2; - ncldy_subarea = 1; - jclea = 1; - jcldy = 2; - } - - const Real zfclea = 1.0 - zfcldy; - for (int i = 0; i < maxsubarea(); ++i) - iscldy_subarea[i] = false; - if (jcldy > 0) - iscldy_subarea[jcldy - 1] = true; - for (int i = 0; i < maxsubarea(); ++i) - afracsub[i] = 0.0; - if (jclea > 0) - afracsub[jclea - 1] = zfclea; - if (jcldy > 0) - afracsub[jcldy - 1] = zfcldy; - - // cldy_rh_sameas_clear is just to match mam_refactor. Compiler should - // optimize away. - const int cldy_rh_sameas_clear = 0; - if (ncldy_subarea <= 0) { - for (int i = 0; i < maxsubarea(); ++i) - relhumsub[i] = relhumgcm; - } else if (cldy_rh_sameas_clear > 0) { - for (int i = 0; i < maxsubarea(); ++i) - relhumsub[i] = relhumgcm; - } else { - if (jcldy > 0) { - relhumsub[jcldy - 1] = 1.0; - if (jclea > 0) { - const Real tmpa = - (relhumgcm - afracsub[jcldy - 1]) / afracsub[jclea - 1]; - relhumsub[jclea - 1] = haero::max(0.0, haero::min(1.0, tmpa)); - } - } - } - - // ---------------------------------------------------------------------------- - // Copy grid cell mean mixing ratios. - // These values, together with cloud fraction and a few assumptions, are used - // in the remainder of the subroutine to calculate the sub-area mean mixing - // ratios. - // ---------------------------------------------------------------------------- - // Interstitial aerosols - Real qgcm1[gas_pcnst()], qgcm2[gas_pcnst()], qgcm3[gas_pcnst()]; - for (int i = 0; i < gas_pcnst(); ++i) { - qgcm1[i] = haero::max(0.0, q_pregaschem[i]); - qgcm2[i] = haero::max(0.0, q_precldchem[i]); - qgcm3[i] = haero::max(0.0, q[i]); - } - - // Cloud-borne aerosols - Real qqcwgcm2[gas_pcnst()], qqcwgcm3[gas_pcnst()]; - for (int i = 0; i < gas_pcnst(); ++i) { - qqcwgcm2[i] = haero::max(0.0, qqcw_precldchem[i]); - qqcwgcm3[i] = haero::max(0.0, qqcw[i]); - } - - // aerosol water - Real qaerwatgcm3[num_modes] = {}; - for (int i = 0; i < num_modes; ++i) { - qaerwatgcm3[i] = haero::max(0.0, qaerwat[i]); - } - - // ---------------------------------------------------------------------------- - // Initialize the subarea mean mixing ratios - // ---------------------------------------------------------------------------- - { - const int n = haero::min(maxsubarea(), nsubarea + 1); - for (int i = 0; i < n; ++i) { - for (int j = 0; j < gas_pcnst(); ++j) { - qsub1[j][i] = 0.0; - qsub2[j][i] = 0.0; - qsub3[j][i] = 0.0; - qqcwsub1[j][i] = 0.0; - qqcwsub2[j][i] = 0.0; - qqcwsub3[j][i] = 0.0; - } - for (int j = 0; j < num_modes; ++j) { - qaerwatsub3[j][i] = 0.0; - } - } - } - - // ************************************************************************************************* - // Calculate initial (i.e., before cond/rnam/nnuc/coag) tracer mixing - // ratios within the sub-areas - // - for all-clear or all-cloudy cases, the sub-area TMRs are equal to the - // grid-cell means - // - for partly cloudy case, they are different. This is primarily - // because the - // interstitial aerosol mixing ratios are assumed lower in the cloudy - // sub-area than in the clear sub-area, because much of the aerosol is - // activated in the cloudy sub-area. - // ************************************************************************************************* - // Category I: partly cloudy case - // ************************************************************************************************* - if ((jclea > 0) && (jcldy > 0) && (jclea + jcldy == 3) && (nsubarea == 2)) { - - // --------------------------------------------------------------------- - // Set GAS mixing ratios in sub-areas (for the condensing gases only!!) - // --------------------------------------------------------------------- - for (int lmz = 0; lmz < gas_pcnst(); ++lmz) { - if (lmapcc_all(lmz) == lmapcc_val_gas()) { - - // assume gas in both sub-areas before gas-chem and cloud-chem equal - // grid-cell mean - for (int i = 0; i < nsubarea; ++i) { - qsub1[lmz][i] = qgcm1[lmz]; - qsub2[lmz][i] = qgcm2[lmz]; - } - // assume gas in clear sub-area after cloud-chem equals before - // cloud-chem value - qsub3[lmz][jclea - 1] = qsub2[lmz][jclea - 1]; - // gas in cloud sub-area then determined by grid-cell mean and clear - // values - qsub3[lmz][jcldy - 1] = - (qgcm3[lmz] - zfclea * qsub3[lmz][jclea - 1]) / zfcldy; - - // check that this does not produce a negative value - if (qsub3[lmz][jcldy - 1] < 0.0) { - qsub3[lmz][jcldy - 1] = 0.0; - qsub3[lmz][jclea - 1] = qgcm3[lmz] / zfclea; - } - } - } - // --------------------------------------------------------------------- - // Set CLOUD-BORNE AEROSOL mixing ratios in sub-areas. - // This is straightforward, as the same partitioning factors (0 or 1/f) - // are applied to all mass and number mixing ratios in all modes. - // --------------------------------------------------------------------- - // loop thru log-normal modes - for (int n = 0; n < num_modes; ++n) { - // number - then mass of individual species - of a mode - for (int l2 = -1; l2 < num_species_mode(n); ++l2) { - int lc; - if (l2 == -1) - lc = numptr_amode(n); - else - lc = lmassptr_amode(l2, n); - qqcwsub2[lc][jclea - 1] = 0.0; - qqcwsub2[lc][jcldy - 1] = qqcwgcm2[lc] / zfcldy; - qqcwsub3[lc][jclea - 1] = 0.0; - qqcwsub3[lc][jcldy - 1] = qqcwgcm3[lc] / zfcldy; - } - } - - // --------------------------------------------------------------------- - // Set INTERSTITIAL AEROSOL mixing ratios in sub-areas. - // --------------------------------------------------------------------- - for (int n = 0; n < num_modes; ++n) { - // ------------------------------------- - // Aerosol number - // ------------------------------------- - // grid cell mean, interstitial - Real tmp_q_cellavg_int = qgcm2[numptr_amode(n)]; - // grid cell mean, cloud-borne - Real tmp_q_cellavg_cbn = qqcwgcm2[numptr_amode(n)]; - - Real nmbr_part_fac_clea = 0; - Real nmbr_part_fac_cldy = 0; - subarea_partition_factors(tmp_q_cellavg_int, tmp_q_cellavg_cbn, zfcldy, - zfclea, nmbr_part_fac_clea, nmbr_part_fac_cldy); - - // Apply the partitioning factors to calculate sub-area mean number - // mixing ratios - - const int la = numptr_amode(n); - - qsub2[la][jclea - 1] = qgcm2[la] * nmbr_part_fac_clea; - qsub2[la][jcldy - 1] = qgcm2[la] * nmbr_part_fac_cldy; - qsub3[la][jclea - 1] = qgcm3[la] * nmbr_part_fac_clea; - qsub3[la][jcldy - 1] = qgcm3[la] * nmbr_part_fac_cldy; - - //------------------------------------- - // Aerosol mass - //------------------------------------- - // For aerosol mass, we use the total grid cell mean - // interstitial/cloud-borne mass mixing ratios to come up with the same - // partitioning for all species in the mode. - - // Compute the total mixing ratios by summing up the individual species - - tmp_q_cellavg_int = 0.0; // grid cell mean, interstitial - tmp_q_cellavg_cbn = 0.0; // grid cell mean, cloud-borne - - for (int l2 = 0; l2 < num_species_mode(n); ++l2) { - tmp_q_cellavg_int += qgcm2[lmassptr_amode(l2, n)]; - tmp_q_cellavg_cbn += qqcwgcm2[lmassptr_amode(l2, n)]; - } - Real mass_part_fac_clea = 0; - Real mass_part_fac_cldy = 0; - // Calculate the partitioning factors - subarea_partition_factors(tmp_q_cellavg_int, tmp_q_cellavg_cbn, zfcldy, - zfclea, mass_part_fac_clea, mass_part_fac_cldy); - - // Apply the partitioning factors to calculate sub-area mean mass mixing - // ratios - - for (int l2 = 0; l2 < num_species_mode(n); ++l2) { - const int la = lmassptr_amode(l2, n); - - qsub2[la][jclea - 1] = qgcm2[la] * mass_part_fac_clea; - qsub2[la][jcldy - 1] = qgcm2[la] * mass_part_fac_cldy; - qsub3[la][jclea - 1] = qgcm3[la] * mass_part_fac_clea; - qsub3[la][jcldy - 1] = qgcm3[la] * mass_part_fac_cldy; - } - } - - // ************************************************************************************************* - // Category II: all clear, or cld < 1e-5 - // In this case, zfclea=1 and zfcldy=0 - // ************************************************************************************************* - } else if ((jclea == 1) && (jcldy == 0) && (nsubarea == 1)) { - // - // put all the gases and interstitial aerosols in the clear sub-area - // and set mix-ratios = 0 in cloudy sub-area - // for cloud-borne aerosol, do nothing - // because the grid-cell-mean cloud-borne aerosol will be left - // unchanged (i.e., this routine only changes qqcw when cld >= 1e-5) - // - - for (int lmz = 0; lmz < gas_pcnst(); ++lmz) { - if (0 < lmapcc_all(lmz)) { - qsub1[lmz][jclea - 1] = qgcm1[lmz]; - qsub2[lmz][jclea - 1] = qgcm2[lmz]; - qsub3[lmz][jclea - 1] = qgcm3[lmz]; - qqcwsub2[lmz][jclea - 1] = qqcwgcm2[lmz]; - qqcwsub3[lmz][jclea - 1] = qqcwgcm3[lmz]; - } - } - // ************************************************************************************************* - // Category III: all cloudy, or cld > 0.999 - // in this case, zfcldy= and zfclea=0 - // ************************************************************************************************* - } else if ((jclea == 0) && (jcldy == 1) && (nsubarea == 1)) { - // - // put all the gases and interstitial aerosols in the cloudy sub-area - // and set mix-ratios = 0 in clear sub-area - // - for (int lmz = 0; lmz < gas_pcnst(); ++lmz) { - if (0 < lmapcc_all(lmz)) { - qsub1[lmz][jcldy - 1] = qgcm1[lmz]; - qsub2[lmz][jcldy - 1] = qgcm2[lmz]; - qsub3[lmz][jcldy - 1] = qgcm3[lmz]; - qqcwsub2[lmz][jcldy - 1] = qqcwgcm2[lmz]; - qqcwsub3[lmz][jcldy - 1] = qqcwgcm3[lmz]; - } - } - // ************************************************************************************************* - } else { // this should not happen - EKAT_KERNEL_REQUIRE_MSG(false, "*** modal_aero_amicphys - bad jclea, jcldy, nsubarea!"); - } - // ************************************************************************************************* - - // ------------------------------------------------------------------------------------ - // aerosol water -- how to treat this in sub-areas needs more work/thinking - // currently modal_aero_water_uptake calculates qaerwat using - // the grid-cell mean interstital-aerosol mix-rats and the clear-area rh - for (int jsub = 0; jsub < nsubarea; ++jsub) - for (int i = 0; i < num_modes; ++i) - qaerwatsub3[i][jsub] = qaerwatgcm3[i]; - - // ------------------------------------------------------------------------------------ - if (nsubarea == 1) { - // the j=1 subarea is used for some diagnostics - // but is not used in actual calculations - const int j = 1; - for (int i = 0; i < gas_pcnst(); ++i) { - qsub1[i][j] = 0.0; - qsub2[i][j] = 0.0; - qsub3[i][j] = 0.0; - qqcwsub2[i][j] = 0.0; - qqcwsub3[i][j] = 0.0; - } - } -} - -KOKKOS_INLINE_FUNCTION -void mam_amicphys_1subarea_clear( - const AmicPhysConfig& config, const int nstep, const Real deltat, const int jsub, - const int nsubarea, const bool iscldy_subarea, const Real afracsub, - const Real temp, const Real pmid, const Real pdel, const Real zmid, - const Real pblh, const Real relhum, Real dgn_a[AeroConfig::num_modes()], - Real dgn_awet[AeroConfig::num_modes()], - Real wetdens[AeroConfig::num_modes()], - const Real qgas1[AeroConfig::num_gas_ids()], - const Real qgas3[AeroConfig::num_gas_ids()], - Real qgas4[AeroConfig::num_gas_ids()], - Real qgas_delaa[AeroConfig::num_gas_ids()][nqtendaa()], - const Real qnum3[AeroConfig::num_modes()], - Real qnum4[AeroConfig::num_modes()], - Real qnum_delaa[AeroConfig::num_modes()][nqtendaa()], - const Real qaer3[AeroConfig::num_aerosol_ids()][AeroConfig::num_modes()], - Real qaer4[AeroConfig::num_aerosol_ids()][AeroConfig::num_modes()], - Real qaer_delaa[AeroConfig::num_aerosol_ids()][AeroConfig::num_modes()] - [nqtendaa()], - const Real qwtr3[AeroConfig::num_modes()], - Real qwtr4[AeroConfig::num_modes()]) { - static constexpr int num_gas_ids = AeroConfig::num_gas_ids(); - static constexpr int num_modes = AeroConfig::num_modes(); - static constexpr int num_aerosol_ids = AeroConfig::num_aerosol_ids(); - - static constexpr int igas_h2so4 = static_cast(GasId::H2SO4); - // Turn off nh3 for now. This is a future enhancement. - static constexpr int igas_nh3 = -999888777; // Same as mam_refactor - static constexpr int iaer_so4 = static_cast(AeroId::SO4); - static constexpr int iaer_pom = static_cast(AeroId::POM); - - const AeroId gas_to_aer[num_gas_ids] = {AeroId::SOA, AeroId::SO4, - AeroId::None}; - - const bool l_gas_condense_to_mode[num_gas_ids][num_modes] = { - {true, true, true, true}, - {true, true, true, true}, - {false, false, false, false}}; - enum { NA, ANAL, IMPL }; - const int eqn_and_numerics_category[num_gas_ids] = {IMPL, ANAL, ANAL}; - - // air molar density (kmol/m3) - // const Real r_universal = Constants::r_gas; // [mJ/(K mol)] - const Real r_universal = 8.314467591; // [mJ/(mol)] as in mam_refactor - const Real aircon = pmid / (1000 * r_universal * temp); - const Real alnsg_aer[num_modes] = {0.58778666490211906, 0.47000362924573563, - 0.58778666490211906, 0.47000362924573563}; - const Real uptk_rate_factor[num_gas_ids] = {0.81, 1.0, 1.0}; - // calculates changes to gas and aerosol sub-area TMRs (tracer mixing ratios) - // qgas3, qaer3, qnum3 are the current incoming TMRs - // qgas4, qaer4, qnum4 are the updated outgoing TMRs - // - // this routine calculates changes involving - // gas-aerosol exchange (condensation/evaporation) - // growth from smaller to larger modes (renaming) due to condensation - // new particle nucleation - // coagulation - // transfer of particles from hydrophobic modes to hydrophilic modes - // (aging) - // due to condensation and coagulation - // - // qXXXN (X=gas,aer,wat,num; N=1:4) are sub-area mixing ratios - // XXX=gas - gas species - // XXX=aer - aerosol mass species (excluding water) - // XXX=wat - aerosol water - // XXX=num - aerosol number - // N=1 - before gas-phase chemistry - // N=2 - before cloud chemistry - // N=3 - current incoming values (before gas-aerosol exchange, newnuc, - // coag) N=4 - updated outgoing values (after gas-aerosol exchange, - // newnuc, coag) - // - // qXXX_delaa are TMR changes (not tendencies) - // for different processes, which are used to produce history output - // for a clear sub-area, the processes are condensation/evaporation (and - // associated aging), renaming, coagulation, and nucleation - - Real qgas_cur[num_gas_ids]; - for (int i = 0; i < num_gas_ids; ++i) - qgas_cur[i] = qgas3[i]; - Real qaer_cur[num_aerosol_ids][num_modes]; - for (int i = 0; i < num_aerosol_ids; ++i) - for (int j = 0; j < num_modes; ++j) - qaer_cur[i][j] = qaer3[i][j]; - - Real qnum_cur[num_modes]; - for (int j = 0; j < num_modes; ++j) - qnum_cur[j] = qnum3[j]; - Real qwtr_cur[num_modes]; - for (int j = 0; j < num_modes; ++j) - qwtr_cur[j] = qwtr3[j]; - - // qgas_netprod_otrproc = gas net production rate from other processes - // such as gas-phase chemistry and emissions (mol/mol/s) - // this allows the condensation (gasaerexch) routine to apply production and - // condensation loss - // together, which is more accurate numerically - // NOTE - must be >= zero, as numerical method can fail when it is negative - // NOTE - currently only the values for h2so4 and nh3 should be non-zero - Real qgas_netprod_otrproc[num_gas_ids] = {}; - if (config.do_cond && config.gaexch_h2so4_uptake_optaa == 2) { - for (int igas = 0; igas < num_gas_ids; ++igas) { - if (igas == igas_h2so4 || igas == igas_nh3) { - // if config.gaexch_h2so4_uptake_optaa == 2, then - // if qgas increases from pre-gaschem to post-cldchem, - // start from the pre-gaschem mix-ratio and add in the production - // during the integration - // if it decreases, - // start from post-cldchem mix-ratio - // *** currently just do this for h2so4 and nh3 - qgas_netprod_otrproc[igas] = (qgas3[igas] - qgas1[igas]) / deltat; - if (qgas_netprod_otrproc[igas] >= 0.0) - qgas_cur[igas] = qgas1[igas]; - else - qgas_netprod_otrproc[igas] = 0.0; - } - } - } - Real qgas_del_cond[num_gas_ids] = {}; - Real qgas_del_nnuc[num_gas_ids] = {}; - Real qgas_del_cond_only[num_gas_ids] = {}; - Real qaer_del_cond[num_aerosol_ids][num_modes] = {}; - Real qaer_del_rnam[num_aerosol_ids][num_modes] = {}; - Real qaer_del_nnuc[num_aerosol_ids][num_modes] = {}; - Real qaer_del_coag[num_aerosol_ids][num_modes] = {}; - Real qaer_delsub_coag_in[num_aerosol_ids][AeroConfig::max_agepair()] = {}; - Real qaer_delsub_cond[num_aerosol_ids][num_modes] = {}; - Real qaer_delsub_coag[num_aerosol_ids][num_modes] = {}; - Real qaer_del_cond_only[num_aerosol_ids][num_modes] = {}; - Real qnum_del_cond[num_modes] = {}; - Real qnum_del_rnam[num_modes] = {}; - Real qnum_del_nnuc[num_modes] = {}; - Real qnum_del_coag[num_modes] = {}; - Real qnum_delsub_cond[num_modes] = {}; - Real qnum_delsub_coag[num_modes] = {}; - Real qnum_del_cond_only[num_modes] = {}; - Real dnclusterdt = 0.0; - - const int ntsubstep = 1; - Real dtsubstep = deltat; - if (ntsubstep > 1) - dtsubstep = deltat / ntsubstep; - Real del_h2so4_gasprod = - haero::max(qgas3[igas_h2so4] - qgas1[igas_h2so4], 0.0) / ntsubstep; - - // loop over multiple time sub-steps - for (int jtsubstep = 1; jtsubstep <= ntsubstep; ++jtsubstep) { - // gas-aerosol exchange - Real uptkrate_h2so4 = 0.0; - Real del_h2so4_aeruptk = 0.0; - Real qaer_delsub_grow4rnam[num_aerosol_ids][num_modes] = {}; - Real qgas_avg[num_gas_ids] = {}; - Real qnum_sv1[num_modes] = {}; - Real qaer_sv1[num_aerosol_ids][num_modes] = {}; - Real qgas_sv1[num_gas_ids] = {}; - - if (config.do_cond) { - - const bool l_calc_gas_uptake_coeff = jtsubstep == 1; - Real uptkaer[num_gas_ids][num_modes] = {}; - - for (int i = 0; i < num_gas_ids; ++i) - qgas_sv1[i] = qgas_cur[i]; - for (int i = 0; i < num_modes; ++i) - qnum_sv1[i] = qnum_cur[i]; - for (int j = 0; j < num_aerosol_ids; ++j) - for (int i = 0; i < num_modes; ++i) - qaer_sv1[j][i] = qaer_cur[j][i]; - - // time sub-step - const Real dtsub_soa_fixed = -1.0; - // Integration order - const int nghq = 2; - const int ntot_soamode = 4; - int niter_out = 0; - Real g0_soa_out = 0; - // gasaerexch::mam_gasaerexch_1subarea( - // nghq, igas_h2so4, igas_nh3, ntot_soamode, gas_to_aer, iaer_so4, - // iaer_pom, l_calc_gas_uptake_coeff, l_gas_condense_to_mode, - // eqn_and_numerics_category, dtsubstep, dtsub_soa_fixed, temp, pmid, - // aircon, num_gas_ids, qgas_cur, qgas_avg, qgas_netprod_otrproc, - // qaer_cur, qnum_cur, dgn_awet, alnsg_aer, uptk_rate_factor, uptkaer, - // uptkrate_h2so4, niter_out, g0_soa_out); - - if (config.newnuc_h2so4_conc_optaa == 11) - qgas_avg[igas_h2so4] = - 0.5 * (qgas_sv1[igas_h2so4] + qgas_cur[igas_h2so4]); - else if (config.newnuc_h2so4_conc_optaa == 12) - qgas_avg[igas_h2so4] = qgas_cur[igas_h2so4]; - - for (int i = 0; i < num_gas_ids; ++i) - qgas_del_cond[i] += - (qgas_cur[i] - (qgas_sv1[i] + qgas_netprod_otrproc[i] * dtsubstep)); - - for (int i = 0; i < num_modes; ++i) - qnum_delsub_cond[i] = qnum_cur[i] - qnum_sv1[i]; - for (int i = 0; i < num_aerosol_ids; ++i) - for (int j = 0; j < num_modes; ++j) - qaer_delsub_cond[i][j] = qaer_cur[i][j] - qaer_sv1[i][j]; - - // qaer_del_grow4rnam = change in qaer_del_cond during latest condensation - // calculations - for (int i = 0; i < num_aerosol_ids; ++i) - for (int j = 0; j < num_modes; ++j) - qaer_delsub_grow4rnam[i][j] = qaer_cur[i][j] - qaer_sv1[i][j]; - for (int i = 0; i < num_gas_ids; ++i) - qgas_del_cond_only[i] = qgas_del_cond[i]; - for (int i = 0; i < num_aerosol_ids; ++i) - for (int j = 0; j < num_modes; ++j) - qaer_del_cond_only[i][j] = qaer_delsub_cond[i][j]; - for (int i = 0; i < num_modes; ++i) - qnum_del_cond_only[i] = qnum_delsub_cond[i]; - del_h2so4_aeruptk = - qgas_cur[igas_h2so4] - - (qgas_sv1[igas_h2so4] + qgas_netprod_otrproc[igas_h2so4] * dtsubstep); - } else { - for (int i = 0; i < num_gas_ids; ++i) - qgas_avg[i] = qgas_cur[i]; - } - - // renaming after "continuous growth" - if (config.do_rename) { - constexpr int nmodes = AeroConfig::num_modes(); - constexpr int naerosol_species = AeroConfig::num_aerosol_ids(); - const Real smallest_dryvol_value = 1.0e-25; // BAD_CONSTANT - const int dest_mode_of_mode[nmodes] = {-1, 0, -1, -1}; - - Real qnumcw_cur[num_modes] = {}; - Real qaercw_cur[num_aerosol_ids][num_modes] = {}; - Real qaercw_delsub_grow4rnam[num_aerosol_ids][num_modes] = {}; - Real mean_std_dev[nmodes]; - Real fmode_dist_tail_fac[nmodes]; - Real v2n_lo_rlx[nmodes]; - Real v2n_hi_rlx[nmodes]; - Real ln_diameter_tail_fac[nmodes]; - int num_pairs = 0; - Real diameter_cutoff[nmodes]; - Real ln_dia_cutoff[nmodes]; - Real diameter_threshold[nmodes]; - Real mass_2_vol[naerosol_species] = {0.15, - 6.4971751412429377e-002, - 0.15, - 7.0588235294117650e-003, - 3.0789473684210526e-002, - 5.1923076923076926e-002, - 156.20986883198000}; - - rename::find_renaming_pairs(dest_mode_of_mode, // in - mean_std_dev, // out - fmode_dist_tail_fac, // out - v2n_lo_rlx, // out - v2n_hi_rlx, // out - ln_diameter_tail_fac, // out - num_pairs, // out - diameter_cutoff, // out - ln_dia_cutoff, diameter_threshold); - - for (int i = 0; i < num_modes; ++i) - qnum_sv1[i] = qnum_cur[i]; - for (int j = 0; j < num_aerosol_ids; ++j) - for (int i = 0; i < num_modes; ++i) - qaer_sv1[j][i] = qaer_cur[j][i]; - Real dgnum_amode[nmodes]; - for (int m = 0; m < nmodes; ++m) { - dgnum_amode[m] = modes(m).nom_diameter; - } - - { - Real qmol_i_cur[num_modes][num_aerosol_ids]; - Real qmol_i_del[num_modes][num_aerosol_ids]; - Real qmol_c_cur[num_modes][num_aerosol_ids]; - Real qmol_c_del[num_modes][num_aerosol_ids]; - for (int j = 0; j < num_aerosol_ids; ++j) - for (int i = 0; i < num_modes; ++i) { - qmol_i_cur[i][j] = qaer_cur[j][i]; - qmol_i_del[i][j] = qaer_delsub_grow4rnam[j][i]; - qmol_c_cur[i][j] = qaercw_cur[j][i]; - qmol_c_del[i][j] = qaercw_delsub_grow4rnam[j][i]; - } - Rename rename; - rename.mam_rename_1subarea_( - iscldy_subarea, smallest_dryvol_value, dest_mode_of_mode, - mean_std_dev, fmode_dist_tail_fac, v2n_lo_rlx, v2n_hi_rlx, - ln_diameter_tail_fac, num_pairs, diameter_cutoff, ln_dia_cutoff, - diameter_threshold, mass_2_vol, dgnum_amode, qnum_cur, qmol_i_cur, - qmol_i_del, qnumcw_cur, qmol_c_cur, qmol_c_del); - - for (int j = 0; j < num_aerosol_ids; ++j) - for (int i = 0; i < num_modes; ++i) { - qaer_cur[j][i] = qmol_i_cur[i][j]; - qaer_delsub_grow4rnam[j][i] = qmol_i_del[i][j]; - qaercw_cur[j][i] = qmol_c_cur[i][j]; - qaercw_delsub_grow4rnam[j][i] = qmol_c_del[i][j]; - } - } - - for (int i = 0; i < num_modes; ++i) - qnum_del_rnam[i] += qnum_cur[i] - qnum_sv1[i]; - for (int i = 0; i < num_aerosol_ids; ++i) - for (int j = 0; j < num_modes; ++j) - qaer_del_rnam[i][j] += qaer_cur[i][j] - qaer_sv1[i][j]; - } - - // new particle formation (nucleation) - if (config.do_newnuc) { - for (int i = 0; i < num_gas_ids; ++i) - qgas_sv1[i] = qgas_cur[i]; - for (int i = 0; i < num_modes; ++i) - qnum_sv1[i] = qnum_cur[i]; - Real qaer_cur_tmp[num_modes][num_aerosol_ids]; - for (int j = 0; j < num_aerosol_ids; ++j) - for (int i = 0; i < num_modes; ++i) { - qaer_sv1[j][i] = qaer_cur[j][i]; - qaer_cur_tmp[i][j] = qaer_cur[j][i]; - } - Real dnclusterdt_substep = 0; - Real dndt_ait = 0; - Real dmdt_ait = 0; - Real dso4dt_ait = 0; - Real dnh4dt_ait = 0; - Nucleation nucleation; - Nucleation::Config config; - // config.dens_so4a_host = 1770; - config.mw_nh4a_host = 115; - config.mw_so4a_host = 115; - // config.accom_coef_h2so4 = 0.65; - AeroConfig aero_config; - nucleation.init(aero_config, config); - // new version after switching from box model version of nucleation - // compute_tendencies_( - // // Real deltat, - // // Real temp_in, - // // Real press_in, - // // Real zm_in, - // // Real pblh_in, - // // Real relhum, - // // Real uptkrate_h2so4, - // const int nsize, // missing? - // const Real dp_lo_mode, - // const Real dp_hi_mode, - // // const Real qgas_cur[num_gases], - // // const Real qgas_avg[num_gases], - // int &isize_nuc, - // // Real &qnuma_del, - // // Real &qso4a_del, - // // Real &qnh4a_del, - // // Real &qh2so4_del, - // Real &qnh3_del, - // // Real &dnclusterdt - // ) - // old, box-model-based version - // nucleation.compute_tendencies_( - // dtsubstep, temp, pmid, aircon, zmid, pblh, relhum, uptkrate_h2so4, - // del_h2so4_gasprod, del_h2so4_aeruptk, qgas_cur, qgas_avg, qnum_cur, - // qaer_cur_tmp, qwtr_cur, dndt_ait, dmdt_ait, dso4dt_ait, dnh4dt_ait, - // dnclusterdt_substep); - // nucleation.compute_tendencies_( - // dtsubstep, // deltat - // temp, // temp_in - // pmid, // press_in - // aircon, // ? - // zmid, // zm_in - // pblh, // pblh_in - // relhum, // relhum - // uptkrate_h2so4, // uptkrate_h2so4 - // // nsize? - // // dp_lo_mode? - // // dp_hi_mode? - // del_h2so4_aeruptk, // uptkrate_h2so4? - // qgas_cur, // qgas_cur[num_gases]? - // qgas_avg, // qgas_avg[num_gases]? - // // isize_nuc? - // qnum_cur, // qnuma_del? - // qaer_cur_tmp, // ? - // qwtr_cur, // ? - // dndt_ait, // - // dmdt_ait, // - // dso4dt_ait, // qso4a_del - // dnh4dt_ait, // qnh4a_del - // del_h2so4_gasprod, // qh2so4_del? - // // qnh3_del? - // dnclusterdt_substep // dnclusterdt - // ); - for (int j = 0; j < num_aerosol_ids; ++j) - for (int i = 0; i < num_modes; ++i) - qaer_cur[j][i] = qaer_cur_tmp[i][j]; - - //! Apply the tendencies to the prognostics. - const int nait = static_cast(ModeIndex::Aitken); - qnum_cur[nait] += dndt_ait * dtsubstep; - - if (dso4dt_ait > 0.0) { - static constexpr int iaer_so4 = static_cast(AeroId::SO4); - static constexpr int igas_h2so4 = static_cast(GasId::H2SO4); - - Real delta_q = dso4dt_ait * dtsubstep; - qaer_cur[iaer_so4][nait] += delta_q; - delta_q = haero::min(delta_q, qgas_cur[igas_h2so4]); - qgas_cur[igas_h2so4] -= delta_q; - } - - if (igas_nh3 > 0 && dnh4dt_ait > 0.0) { - static constexpr int iaer_nh4 = - -9999999; // static_cast(AeroId::NH4); - - Real delta_q = dnh4dt_ait * dtsubstep; - qaer_cur[iaer_nh4][nait] += delta_q; - delta_q = haero::min(delta_q, qgas_cur[igas_nh3]); - qgas_cur[igas_nh3] -= delta_q; - } - for (int i = 0; i < num_gas_ids; ++i) - qgas_del_nnuc[i] += (qgas_cur[i] - qgas_sv1[i]); - for (int i = 0; i < num_modes; ++i) - qnum_del_nnuc[i] += (qnum_cur[i] - qnum_sv1[i]); - for (int j = 0; j < num_aerosol_ids; ++j) - for (int i = 0; i < num_modes; ++i) - qaer_del_nnuc[j][i] += (qaer_cur[j][i] - qaer_sv1[j][i]); - - dnclusterdt = dnclusterdt + dnclusterdt_substep * (dtsubstep / deltat); - } - - // coagulation part - if (config.do_coag) { - for (int i = 0; i < num_modes; ++i) - qnum_sv1[i] = qnum_cur[i]; - for (int j = 0; j < num_aerosol_ids; ++j) - for (int i = 0; i < num_modes; ++i) - qaer_sv1[j][i] = qaer_cur[j][i]; - // coagulation::mam_coag_1subarea(dtsubstep, temp, pmid, aircon, dgn_a, - // dgn_awet, wetdens, qnum_cur, qaer_cur, - // qaer_delsub_coag_in); - for (int i = 0; i < num_modes; ++i) - qnum_delsub_coag[i] = qnum_cur[i] - qnum_sv1[i]; - for (int j = 0; j < num_aerosol_ids; ++j) - for (int i = 0; i < num_modes; ++i) - qaer_delsub_coag[j][i] = qaer_cur[j][i] - qaer_sv1[j][i]; - } - - // primary carbon aging - - aging::mam_pcarbon_aging_1subarea( - dgn_a, qnum_cur, qnum_delsub_cond, qnum_delsub_coag, qaer_cur, - qaer_delsub_cond, qaer_delsub_coag, qaer_delsub_coag_in); - - // accumulate sub-step q-dels - if (config.do_coag) { - for (int i = 0; i < num_modes; ++i) - qnum_del_coag[i] += qnum_delsub_coag[i]; - for (int j = 0; j < num_aerosol_ids; ++j) - for (int i = 0; i < num_modes; ++i) - qaer_del_coag[j][i] += qaer_delsub_coag[j][i]; - } - if (config.do_cond) { - for (int i = 0; i < num_modes; ++i) - qnum_del_cond[i] += qnum_delsub_cond[i]; - for (int j = 0; j < num_aerosol_ids; ++j) - for (int i = 0; i < num_modes; ++i) - qaer_del_cond[j][i] += qaer_delsub_cond[j][i]; - } - } - - // final mix ratios - for (int i = 0; i < num_gas_ids; ++i) - qgas4[i] = qgas_cur[i]; - for (int j = 0; j < num_aerosol_ids; ++j) - for (int i = 0; i < num_modes; ++i) - qaer4[j][i] = qaer_cur[j][i]; - for (int i = 0; i < num_modes; ++i) - qnum4[i] = qnum_cur[i]; - for (int i = 0; i < num_modes; ++i) - qwtr4[i] = qwtr_cur[i]; - - // final mix ratio changes - for (int i = 0; i < num_gas_ids; ++i) { - qgas_delaa[i][iqtend_cond()] = qgas_del_cond[i]; - qgas_delaa[i][iqtend_rnam()] = 0.0; - qgas_delaa[i][iqtend_nnuc()] = qgas_del_nnuc[i]; - qgas_delaa[i][iqtend_coag()] = 0.0; - qgas_delaa[i][iqtend_cond_only()] = qgas_del_cond_only[i]; - } - for (int i = 0; i < num_modes; ++i) { - qnum_delaa[i][iqtend_cond()] = qnum_del_cond[i]; - qnum_delaa[i][iqtend_rnam()] = qnum_del_rnam[i]; - qnum_delaa[i][iqtend_nnuc()] = qnum_del_nnuc[i]; - qnum_delaa[i][iqtend_coag()] = qnum_del_coag[i]; - qnum_delaa[i][iqtend_cond_only()] = qnum_del_cond_only[i]; - } - for (int j = 0; j < num_aerosol_ids; ++j) { - for (int i = 0; i < num_modes; ++i) { - qaer_delaa[j][i][iqtend_cond()] = qaer_del_cond[j][i]; - qaer_delaa[j][i][iqtend_rnam()] = qaer_del_rnam[j][i]; - qaer_delaa[j][i][iqtend_nnuc()] = qaer_del_nnuc[j][i]; - qaer_delaa[j][i][iqtend_coag()] = qaer_del_coag[j][i]; - qaer_delaa[j][i][iqtend_cond_only()] = qaer_del_cond_only[j][i]; - } - } -} - -KOKKOS_INLINE_FUNCTION -void mam_amicphys_1subarea_cloudy( - const AmicPhysConfig& config, const int nstep, const Real deltat, const int jsub, - const int nsubarea, const bool iscldy_subarea, const Real afracsub, - const Real temp, const Real pmid, const Real pdel, const Real zmid, - const Real pblh, const Real relhum, Real dgn_a[AeroConfig::num_modes()], - Real dgn_awet[AeroConfig::num_modes()], - Real wetdens[AeroConfig::num_modes()], - const Real qgas1[AeroConfig::num_gas_ids()], - const Real qgas3[AeroConfig::num_gas_ids()], - Real qgas4[AeroConfig::num_gas_ids()], - Real qgas_delaa[AeroConfig::num_gas_ids()][nqtendaa()], - const Real qnum3[AeroConfig::num_modes()], - Real qnum4[AeroConfig::num_modes()], - Real qnum_delaa[AeroConfig::num_modes()][nqtendaa()], - const Real qaer2[AeroConfig::num_aerosol_ids()][AeroConfig::num_modes()], - const Real qaer3[AeroConfig::num_aerosol_ids()][AeroConfig::num_modes()], - Real qaer4[AeroConfig::num_aerosol_ids()][AeroConfig::num_modes()], - Real qaer_delaa[AeroConfig::num_aerosol_ids()][AeroConfig::num_modes()] - [nqtendaa()], - const Real qwtr3[AeroConfig::num_modes()], - Real qwtr4[AeroConfig::num_modes()], - const Real qnumcw3[AeroConfig::num_modes()], - Real qnumcw4[AeroConfig::num_modes()], - Real qnumcw_delaa[AeroConfig::num_modes()][nqqcwtendaa()], - const Real qaercw2[AeroConfig::num_gas_ids()][AeroConfig::num_modes()], - const Real qaercw3[AeroConfig::num_gas_ids()][AeroConfig::num_modes()], - Real qaercw4[AeroConfig::num_gas_ids()][AeroConfig::num_modes()], - Real qaercw_delaa[AeroConfig::num_gas_ids()][AeroConfig::num_modes()] - [nqqcwtendaa()]) { - - // - // calculates changes to gas and aerosol sub-area TMRs (tracer mixing ratios) - // qgas3, qaer3, qaercw3, qnum3, qnumcw3 are the current incoming TMRs - // qgas4, qaer4, qaercw4, qnum4, qnumcw4 are the updated outgoing TMRs - // - // when config.do_cond = false, this routine only calculates changes involving - // growth from smaller to larger modes (renaming) following cloud chemistry - // so gas TMRs are not changed - // when config.do_cond = true, this routine also calculates changes involving - // gas-aerosol exchange (condensation/evaporation) - // transfer of particles from hydrophobic modes to hydrophilic modes - // (aging) - // due to condensation - // currently this routine does not do - // new particle nucleation - because h2so4 gas conc. should be very low in - // cloudy air coagulation - because cloud-borne aerosol would need to be - // included - // - - // qXXXN (X=gas,aer,wat,num; N=1:4) are sub-area mixing ratios - // XXX=gas - gas species - // XXX=aer - aerosol mass species (excluding water) - // XXX=wat - aerosol water - // XXX=num - aerosol number - // N=1 - before gas-phase chemistry - // N=2 - before cloud chemistry - // N=3 - current incoming values (before gas-aerosol exchange, newnuc, - // coag) N=4 - updated outgoing values (after gas-aerosol exchange, - // newnuc, coag) - // - // qXXX_delaa are TMR changes (not tendencies) - // for different processes, which are used to produce history output - // for a clear sub-area, the processes are condensation/evaporation (and - // associated aging), - // renaming, coagulation, and nucleation - - // qxxx_del_yyyy are mix-ratio changes over full time step (deltat) - // qxxx_delsub_yyyy are mix-ratio changes over time sub-step (dtsubstep) - - static constexpr int num_gas_ids = AeroConfig::num_gas_ids(); - static constexpr int num_modes = AeroConfig::num_modes(); - static constexpr int num_aerosol_ids = AeroConfig::num_aerosol_ids(); - - static constexpr int igas_h2so4 = static_cast(GasId::H2SO4); - // Turn off nh3 for now. This is a future enhancement. - static constexpr int igas_nh3 = -999888777; // Same as mam_refactor - static constexpr int iaer_so4 = static_cast(AeroId::SO4); - static constexpr int iaer_pom = static_cast(AeroId::POM); - - const AeroId gas_to_aer[num_gas_ids] = {AeroId::SOA, AeroId::SO4, - AeroId::None}; - const bool l_gas_condense_to_mode[num_gas_ids][num_modes] = { - {true, true, true, true}, - {true, true, true, true}, - {false, false, false, false}}; - enum { NA, ANAL, IMPL }; - const int eqn_and_numerics_category[num_gas_ids] = {IMPL, ANAL, ANAL}; - // air molar density (kmol/m3) - // In order to try to match the results in mam_refactor - // set r_universal as [mJ/(mol)] as in mam_refactor. - // const Real r_universal = Constants::r_gas; // [mJ/(K mol)] - const Real r_universal = 8.314467591; // [mJ/(mol)] as in mam_refactor - const Real aircon = pmid / (1000 * r_universal * temp); - const Real alnsg_aer[num_modes] = {0.58778666490211906, 0.47000362924573563, - 0.58778666490211906, 0.47000362924573563}; - const Real uptk_rate_factor[num_gas_ids] = {0.81, 1.0, 1.0}; - - Real qgas_cur[num_gas_ids]; - for (int i = 0; i < num_gas_ids; ++i) - qgas_cur[i] = qgas3[i]; - Real qaer_cur[num_aerosol_ids][num_modes]; - for (int i = 0; i < num_aerosol_ids; ++i) - for (int j = 0; j < num_modes; ++j) - qaer_cur[i][j] = qaer3[i][j]; - - Real qnum_cur[num_modes]; - for (int j = 0; j < num_modes; ++j) - qnum_cur[j] = qnum3[j]; - Real qwtr_cur[num_modes]; - for (int j = 0; j < num_modes; ++j) - qwtr_cur[j] = qwtr3[j]; - - Real qnumcw_cur[num_modes]; - for (int j = 0; j < num_modes; ++j) - qnumcw_cur[j] = qnumcw3[j]; - - Real qaercw_cur[num_gas_ids][num_modes]; - for (int i = 0; i < num_gas_ids; ++i) - for (int j = 0; j < num_modes; ++j) - qaercw_cur[i][j] = qaercw3[i][j]; - - Real qgas_netprod_otrproc[num_gas_ids] = {}; - if (config.do_cond && config.gaexch_h2so4_uptake_optaa == 2) { - for (int igas = 0; igas < num_gas_ids; ++igas) { - if (igas == igas_h2so4 || igas == igas_nh3) { - // if gaexch_h2so4_uptake_optaa == 2, then - // if qgas increases from pre-gaschem to post-cldchem, - // start from the pre-gaschem mix-ratio and add in the production - // during the integration - // if it decreases, - // start from post-cldchem mix-ratio - // *** currently just do this for h2so4 and nh3 - qgas_netprod_otrproc[igas] = (qgas3[igas] - qgas1[igas]) / deltat; - if (qgas_netprod_otrproc[igas] >= 0.0) - qgas_cur[igas] = qgas1[igas]; - else - qgas_netprod_otrproc[igas] = 0.0; - } - } - } - Real qgas_del_cond[num_gas_ids] = {}; - Real qgas_del_nnuc[num_gas_ids] = {}; - Real qgas_del_cond_only[num_gas_ids] = {}; - Real qaer_del_cond[num_aerosol_ids][num_modes] = {}; - Real qaer_del_rnam[num_aerosol_ids][num_modes] = {}; - Real qaer_del_nnuc[num_aerosol_ids][num_modes] = {}; - Real qaer_del_coag[num_aerosol_ids][num_modes] = {}; - Real qaer_delsub_cond[num_aerosol_ids][num_modes] = {}; - Real qaer_delsub_coag[num_aerosol_ids][num_modes] = {}; - Real qaer_del_cond_only[num_aerosol_ids][num_modes] = {}; - Real qaercw_del_rnam[num_aerosol_ids][num_modes] = {}; - Real qnum_del_cond[num_modes] = {}; - Real qnum_del_rnam[num_modes] = {}; - Real qnum_del_nnuc[num_modes] = {}; - Real qnum_del_coag[num_modes] = {}; - Real qnum_delsub_cond[num_modes] = {}; - Real qnum_delsub_coag[num_modes] = {}; - Real qnum_del_cond_only[num_modes] = {}; - Real qnumcw_del_rnam[num_modes] = {}; - Real qaer_delsub_coag_in[num_aerosol_ids][AeroConfig::max_agepair()] = {}; - - const int ntsubstep = 1; - Real dtsubstep = deltat; - if (ntsubstep > 1) - dtsubstep = deltat / ntsubstep; - - // loop over multiple time sub-steps - - for (int jtsubstep = 1; jtsubstep <= ntsubstep; ++jtsubstep) { - // gas-aerosol exchange - Real uptkrate_h2so4 = 0.0; - Real qgas_avg[num_gas_ids] = {}; - Real qgas_sv1[num_gas_ids] = {}; - Real qnum_sv1[num_modes] = {}; - Real qaer_sv1[num_aerosol_ids][num_modes] = {}; - Real qaer_delsub_grow4rnam[num_aerosol_ids][num_modes] = {}; - - if (config.do_cond) { - - const bool l_calc_gas_uptake_coeff = jtsubstep == 1; - Real uptkaer[num_gas_ids][num_modes] = {}; - - for (int i = 0; i < num_gas_ids; ++i) - qgas_sv1[i] = qgas_cur[i]; - for (int i = 0; i < num_modes; ++i) - qnum_sv1[i] = qnum_cur[i]; - for (int j = 0; j < num_aerosol_ids; ++j) - for (int i = 0; i < num_modes; ++i) - qaer_sv1[j][i] = qaer_cur[j][i]; - - const int nghq = 2; - const int ntot_soamode = 4; - int niter_out = 0; - Real g0_soa_out = 0; - // time sub-step - const Real dtsub_soa_fixed = -1.0; - // gasaerexch::mam_gasaerexch_1subarea( - // nghq, igas_h2so4, igas_nh3, ntot_soamode, gas_to_aer, iaer_so4, - // iaer_pom, l_calc_gas_uptake_coeff, l_gas_condense_to_mode, - // eqn_and_numerics_category, dtsubstep, dtsub_soa_fixed, temp, pmid, - // aircon, num_gas_ids, qgas_cur, qgas_avg, qgas_netprod_otrproc, - // qaer_cur, qnum_cur, dgn_awet, alnsg_aer, uptk_rate_factor, uptkaer, - // uptkrate_h2so4, niter_out, g0_soa_out); - - if (config.newnuc_h2so4_conc_optaa == 11) - qgas_avg[igas_h2so4] = - 0.5 * (qgas_sv1[igas_h2so4] + qgas_cur[igas_h2so4]); - else if (config.newnuc_h2so4_conc_optaa == 12) - qgas_avg[igas_h2so4] = qgas_cur[igas_h2so4]; - - for (int i = 0; i < num_gas_ids; ++i) - qgas_del_cond[i] += - (qgas_cur[i] - (qgas_sv1[i] + qgas_netprod_otrproc[i] * dtsubstep)); - - for (int i = 0; i < num_modes; ++i) - qnum_delsub_cond[i] = qnum_cur[i] - qnum_sv1[i]; - for (int i = 0; i < num_aerosol_ids; ++i) - for (int j = 0; j < num_modes; ++j) - qaer_delsub_cond[i][j] = qaer_cur[i][j] - qaer_sv1[i][j]; - - // qaer_del_grow4rnam = change in qaer_del_cond during latest condensation - // calculations - for (int i = 0; i < num_aerosol_ids; ++i) - for (int j = 0; j < num_modes; ++j) - qaer_delsub_grow4rnam[i][j] = qaer_cur[i][j] - qaer_sv1[i][j]; - for (int i = 0; i < num_gas_ids; ++i) - qgas_del_cond_only[i] = qgas_del_cond[i]; - for (int i = 0; i < num_aerosol_ids; ++i) - for (int j = 0; j < num_modes; ++j) - qaer_del_cond_only[i][j] = qaer_delsub_cond[i][j]; - for (int i = 0; i < num_modes; ++i) - qnum_del_cond_only[i] = qnum_delsub_cond[i]; - - } else { - for (int i = 0; i < num_gas_ids; ++i) - qgas_avg[i] = qgas_cur[i]; - } - // renaming after "continuous growth" - if (config.do_rename) { - constexpr int nmodes = AeroConfig::num_modes(); - constexpr int naerosol_species = AeroConfig::num_aerosol_ids(); - const Real smallest_dryvol_value = 1.0e-25; // BAD_CONSTANT - const int dest_mode_of_mode[nmodes] = {-1, 0, -1, -1}; - - Real qnumcw_cur[num_modes] = {}; - Real qaercw_cur[num_aerosol_ids][num_modes] = {}; - Real qaercw_delsub_grow4rnam[num_aerosol_ids][num_modes] = {}; - Real mean_std_dev[nmodes]; - Real fmode_dist_tail_fac[nmodes]; - Real v2n_lo_rlx[nmodes]; - Real v2n_hi_rlx[nmodes]; - Real ln_diameter_tail_fac[nmodes]; - int num_pairs = 0; - Real diameter_cutoff[nmodes]; - Real ln_dia_cutoff[nmodes]; - Real diameter_threshold[nmodes]; - Real mass_2_vol[naerosol_species] = {0.15, - 6.4971751412429377e-002, - 0.15, - 7.0588235294117650e-003, - 3.0789473684210526e-002, - 5.1923076923076926e-002, - 156.20986883198000}; - - rename::find_renaming_pairs(dest_mode_of_mode, // in - mean_std_dev, // out - fmode_dist_tail_fac, // out - v2n_lo_rlx, // out - v2n_hi_rlx, // out - ln_diameter_tail_fac, // out - num_pairs, // out - diameter_cutoff, // out - ln_dia_cutoff, diameter_threshold); - - for (int i = 0; i < num_modes; ++i) - qnum_sv1[i] = qnum_cur[i]; - for (int j = 0; j < num_aerosol_ids; ++j) - for (int i = 0; i < num_modes; ++i) - qaer_sv1[j][i] = qaer_cur[j][i]; - Real dgnum_amode[nmodes]; - for (int m = 0; m < nmodes; ++m) { - dgnum_amode[m] = modes(m).nom_diameter; - } - - // qaercw_delsub_grow4rnam = change in qaercw from cloud chemistry - for (int i = 0; i < num_aerosol_ids; ++i) - for (int j = 0; j < num_modes; ++j) - qaercw_delsub_grow4rnam[i][j] = - (qaercw3[i][j] - qaercw2[i][j]) / ntsubstep; - Real qnumcw_sv1[num_modes]; - for (int i = 0; i < num_modes; ++i) - qnumcw_sv1[i] = qnumcw_cur[i]; - Real qaercw_sv1[num_aerosol_ids][num_modes]; - for (int i = 0; i < num_aerosol_ids; ++i) - for (int j = 0; j < num_modes; ++j) - qaercw_sv1[i][j] = qaercw_cur[i][j]; - - { - Real qmol_i_cur[num_modes][num_aerosol_ids]; - Real qmol_i_del[num_modes][num_aerosol_ids]; - Real qmol_c_cur[num_modes][num_aerosol_ids]; - Real qmol_c_del[num_modes][num_aerosol_ids]; - for (int j = 0; j < num_aerosol_ids; ++j) - for (int i = 0; i < num_modes; ++i) { - qmol_i_cur[i][j] = qaer_cur[j][i]; - qmol_i_del[i][j] = qaer_delsub_grow4rnam[j][i]; - qmol_c_cur[i][j] = qaercw_cur[j][i]; - qmol_c_del[i][j] = qaercw_delsub_grow4rnam[j][i]; - } - - Rename rename; - rename.mam_rename_1subarea_( - iscldy_subarea, smallest_dryvol_value, dest_mode_of_mode, - mean_std_dev, fmode_dist_tail_fac, v2n_lo_rlx, v2n_hi_rlx, - ln_diameter_tail_fac, num_pairs, diameter_cutoff, ln_dia_cutoff, - diameter_threshold, mass_2_vol, dgnum_amode, qnum_cur, qmol_i_cur, - qmol_i_del, qnumcw_cur, qmol_c_cur, qmol_c_del); - - for (int j = 0; j < num_aerosol_ids; ++j) - for (int i = 0; i < num_modes; ++i) { - qaer_cur[j][i] = qmol_i_cur[i][j]; - qaer_delsub_grow4rnam[j][i] = qmol_i_del[i][j]; - qaercw_cur[j][i] = qmol_c_cur[i][j]; - qaercw_delsub_grow4rnam[j][i] = qmol_c_del[i][j]; - } - } - for (int i = 0; i < num_modes; ++i) - qnum_del_rnam[i] += qnum_cur[i] - qnum_sv1[i]; - for (int i = 0; i < num_aerosol_ids; ++i) - for (int j = 0; j < num_modes; ++j) - qaer_del_rnam[i][j] += qaer_cur[i][j] - qaer_sv1[i][j]; - for (int i = 0; i < num_modes; ++i) - qnumcw_del_rnam[i] += qnumcw_cur[i] - qnumcw_sv1[i]; - for (int i = 0; i < num_aerosol_ids; ++i) - for (int j = 0; j < num_modes; ++j) - qaercw_del_rnam[i][j] += qaercw_cur[i][j] - qaercw_sv1[i][j]; - } - - // primary carbon aging - if (config.do_cond) { - aging::mam_pcarbon_aging_1subarea( - dgn_a, qnum_cur, qnum_delsub_cond, qnum_delsub_coag, qaer_cur, - qaer_delsub_cond, qaer_delsub_coag, qaer_delsub_coag_in); - } - // accumulate sub-step q-dels - if (config.do_cond) { - for (int i = 0; i < num_modes; ++i) - qnum_del_cond[i] += qnum_delsub_cond[i]; - for (int j = 0; j < num_aerosol_ids; ++j) - for (int i = 0; i < num_modes; ++i) - qaer_del_cond[j][i] += qaer_delsub_cond[j][i]; - } - } - // final mix ratios - for (int i = 0; i < num_gas_ids; ++i) - qgas4[i] = qgas_cur[i]; - for (int j = 0; j < num_aerosol_ids; ++j) - for (int i = 0; i < num_modes; ++i) - qaer4[j][i] = qaer_cur[j][i]; - for (int i = 0; i < num_modes; ++i) - qnum4[i] = qnum_cur[i]; - for (int i = 0; i < num_modes; ++i) - qwtr4[i] = qwtr_cur[i]; - for (int i = 0; i < num_modes; ++i) - qnumcw4[i] = qnumcw_cur[i]; - for (int i = 0; i < num_gas_ids; ++i) - for (int j = 0; j < num_modes; ++j) - qaercw4[i][j] = qaercw_cur[i][j]; - - // final mix ratio changes - for (int i = 0; i < num_gas_ids; ++i) { - qgas_delaa[i][iqtend_cond()] = qgas_del_cond[i]; - qgas_delaa[i][iqtend_rnam()] = 0.0; - qgas_delaa[i][iqtend_nnuc()] = qgas_del_nnuc[i]; - qgas_delaa[i][iqtend_coag()] = 0.0; - qgas_delaa[i][iqtend_cond_only()] = qgas_del_cond_only[i]; - } - for (int i = 0; i < num_modes; ++i) { - qnum_delaa[i][iqtend_cond()] = qnum_del_cond[i]; - qnum_delaa[i][iqtend_rnam()] = qnum_del_rnam[i]; - qnum_delaa[i][iqtend_nnuc()] = qnum_del_nnuc[i]; - qnum_delaa[i][iqtend_coag()] = qnum_del_coag[i]; - qnum_delaa[i][iqtend_cond_only()] = qnum_del_cond_only[i]; - } - for (int j = 0; j < num_aerosol_ids; ++j) { - for (int i = 0; i < num_modes; ++i) { - qaer_delaa[j][i][iqtend_cond()] = qaer_del_cond[j][i]; - qaer_delaa[j][i][iqtend_rnam()] = qaer_del_rnam[j][i]; - qaer_delaa[j][i][iqtend_nnuc()] = qaer_del_nnuc[j][i]; - qaer_delaa[j][i][iqtend_coag()] = qaer_del_coag[j][i]; - qaer_delaa[j][i][iqtend_cond_only()] = qaer_del_cond_only[j][i]; - } - } - for (int i = 0; i < num_modes; ++i) - qnumcw_delaa[i][iqqcwtend_rnam()] = qnumcw_del_rnam[i]; - for (int i = 0; i < num_aerosol_ids; ++i) - for (int j = 0; j < num_modes; ++j) - qaercw_delaa[i][j][iqqcwtend_rnam()] = qaercw_del_rnam[i][j]; -} - -KOKKOS_INLINE_FUNCTION -void mam_amicphys_1gridcell( - const AmicPhysConfig& config, const int nstep, const Real deltat, const int nsubarea, - const int ncldy_subarea, const bool iscldy_subarea[maxsubarea()], - const Real afracsub[maxsubarea()], const Real temp, const Real pmid, - const Real pdel, const Real zmid, const Real pblh, - const Real relhumsub[maxsubarea()], Real dgn_a[AeroConfig::num_modes()], - Real dgn_awet[AeroConfig::num_modes()], - Real wetdens[AeroConfig::num_modes()], - const Real qsub1[AeroConfig::num_gas_ids()][maxsubarea()], - const Real qsub2[AeroConfig::num_gas_ids()][maxsubarea()], - const Real qqcwsub2[AeroConfig::num_gas_ids()][maxsubarea()], - const Real qsub3[AeroConfig::num_gas_ids()][maxsubarea()], - const Real qqcwsub3[AeroConfig::num_gas_ids()][maxsubarea()], - Real qaerwatsub3[AeroConfig::num_modes()][maxsubarea()], - Real qsub4[AeroConfig::num_gas_ids()][maxsubarea()], - Real qqcwsub4[AeroConfig::num_gas_ids()][maxsubarea()], - Real qaerwatsub4[AeroConfig::num_modes()][maxsubarea()], - Real qsub_tendaa[AeroConfig::num_gas_ids()][nqtendaa()][maxsubarea()], - Real qqcwsub_tendaa[AeroConfig::num_gas_ids()][nqqcwtendaa()][maxsubarea()]) { - - // - // calculates changes to gas and aerosol sub-area TMRs (tracer mixing ratios) - // qsub3 and qqcwsub3 are the incoming current TMRs - // qsub4 and qqcwsub4 are the outgoing updated TMRs - // - // qsubN and qqcwsubN (N=1:4) are tracer mixing ratios (TMRs, mol/mol or - // #/kmol) in sub-areas - // currently there are just clear and cloudy sub-areas - // the N=1:4 have same meanings as for qgcmN - // N=1 - before gas-phase chemistry - // N=2 - before cloud chemistry - // N=3 - incoming values (before gas-aerosol exchange, newnuc, coag) - // N=4 - outgoing values (after gas-aerosol exchange, newnuc, coag) - // qsub_tendaa and qqcwsub_tendaa are TMR tendencies - // for different processes, which are used to produce history output - // the processes are condensation/evaporation (and associated aging), - // renaming, coagulation, and nucleation - - static constexpr int num_gas_ids = AeroConfig::num_gas_ids(); - static constexpr int num_modes = AeroConfig::num_modes(); - static constexpr int num_aerosol_ids = AeroConfig::num_aerosol_ids(); - - // the q--4 values will be equal to q--3 values unless they get changed - for (int i = 0; i < num_gas_ids; ++i) - for (int j = 0; j < maxsubarea(); ++j) { - qsub4[i][j] = qsub3[i][j]; - qqcwsub4[i][j] = qqcwsub3[i][j]; - } - for (int i = 0; i < num_modes; ++i) - for (int j = 0; j < maxsubarea(); ++j) - qaerwatsub4[i][j] = qaerwatsub3[i][j]; - for (int i = 0; i < num_gas_ids; ++i) - for (int j = 0; j < nqtendaa(); ++j) - for (int k = 0; k < maxsubarea(); ++k) - qsub_tendaa[i][j][k] = 0; - for (int i = 0; i < num_gas_ids; ++i) - for (int j = 0; j < nqqcwtendaa(); ++j) - for (int k = 0; k < maxsubarea(); ++k) - qqcwsub_tendaa[i][j][k] = 0.0; - - for (int jsub = 0; jsub < nsubarea; ++jsub) { - AmicPhysConfig sub_config = config; - if (iscldy_subarea[jsub]) { - sub_config.do_cond = config.do_cond; - sub_config.do_rename = config.do_rename; - sub_config.do_newnuc = false; - sub_config.do_coag = false; - } - const bool do_map_gas_sub = sub_config.do_cond || sub_config.do_newnuc; - - // map incoming sub-area mix-ratios to gas/aer/num arrays - Real qgas1[num_gas_ids] = {}; - Real qgas3[num_gas_ids] = {}; - Real qgas4[num_gas_ids] = {}; - if (do_map_gas_sub) { - // for cldy subarea, only do gases if doing gaexch - for (int igas = 0; igas < 2; ++igas) { - const int l = lmap_gas(igas); - qgas1[igas] = qsub1[l][jsub] * fcvt_gas(igas); - qgas3[igas] = qsub3[l][jsub] * fcvt_gas(igas); - qgas4[igas] = qgas3[igas]; - } - } - Real qaer2[num_aerosol_ids][num_modes] = {}; - Real qaer3[num_aerosol_ids][num_modes] = {}; - Real qnum3[num_modes] = {}; - Real qaer4[num_aerosol_ids][num_modes] = {}; - Real qnum4[num_modes] = {}; - Real qwtr3[num_modes] = {}; - Real qwtr4[num_modes] = {}; - for (int n = 0; n < num_modes; ++n) { - qnum3[n] = qsub3[n][jsub] * fcvt_num(); - qnum4[n] = qnum3[n]; - for (int iaer = 0; iaer < num_aerosol_ids; ++iaer) { - qaer2[iaer][n] = qsub2[iaer][jsub] * fcvt_aer(iaer); - qaer3[iaer][n] = qsub3[iaer][jsub] * fcvt_aer(iaer); - qaer4[iaer][n] = qaer3[iaer][n]; - } - qwtr3[n] = qaerwatsub3[n][jsub] * fcvt_wtr(); - qwtr4[n] = qwtr3[n]; - } - Real qaercw2[num_aerosol_ids][num_modes] = {}; - Real qaercw3[num_aerosol_ids][num_modes] = {}; - Real qnumcw3[num_modes] = {}; - Real qaercw4[num_aerosol_ids][num_modes] = {}; - Real qnumcw4[num_modes] = {}; - if (iscldy_subarea[jsub]) { - // only do cloud-borne for cloudy - for (int n = 0; n < num_modes; ++n) { - qnumcw3[n] = qqcwsub3[n][jsub] * fcvt_num(); - qnumcw4[n] = qnumcw3[n]; - for (int iaer = 0; iaer < num_aerosol_ids; ++iaer) { - qaercw2[iaer][n] = qqcwsub2[n][jsub] * fcvt_aer(iaer); - qaercw3[iaer][n] = qqcwsub3[n][jsub] * fcvt_aer(iaer); - qaercw4[iaer][n] = qaercw3[iaer][n]; - } - } - } - - Real qgas_delaa[num_gas_ids][nqtendaa()] = {}; - Real qnum_delaa[num_modes][nqtendaa()] = {}; - Real qnumcw_delaa[num_modes][nqqcwtendaa()] = {}; - Real qaer_delaa[num_aerosol_ids][num_modes][nqtendaa()] = {}; - Real qaercw_delaa[num_aerosol_ids][num_modes][nqqcwtendaa()] = {}; - - if (iscldy_subarea[jsub]) { - mam_amicphys_1subarea_cloudy(sub_config, nstep, deltat, - jsub, nsubarea, iscldy_subarea[jsub], afracsub[jsub], temp, pmid, - pdel, zmid, pblh, relhumsub[jsub], dgn_a, dgn_awet, wetdens, qgas1, - qgas3, qgas4, qgas_delaa, qnum3, qnum4, qnum_delaa, qaer2, qaer3, - qaer4, qaer_delaa, qwtr3, qwtr4, qnumcw3, qnumcw4, qnumcw_delaa, - qaercw2, qaercw3, qaercw4, qaercw_delaa); - } else { - mam_amicphys_1subarea_clear(sub_config, nstep, deltat, - jsub, nsubarea, iscldy_subarea[jsub], afracsub[jsub], temp, pmid, - pdel, zmid, pblh, relhumsub[jsub], dgn_a, dgn_awet, wetdens, qgas1, - qgas3, qgas4, qgas_delaa, qnum3, qnum4, qnum_delaa, qaer3, qaer4, - qaer_delaa, qwtr3, qwtr4); - // map gas/aer/num arrays (mix-ratio and del=change) back to sub-area - // arrays - - if (do_map_gas_sub) { - for (int igas = 0; igas < 2; ++igas) { - const int l = lmap_gas(igas); - qsub4[l][jsub] = qgas4[igas] / fcvt_gas(igas); - for (int i = 0; i < nqtendaa(); ++i) - qsub_tendaa[l][i][jsub] = - qgas_delaa[igas][i] / (fcvt_gas(igas) * deltat); - } - } - for (int n = 0; n < num_modes; ++n) { - qsub4[n][jsub] = qnum4[n] / fcvt_num(); - for (int i = 0; i < nqtendaa(); ++i) - qsub_tendaa[n][i][jsub] = qnum_delaa[n][i] / (fcvt_num() * deltat); - for (int iaer = 0; iaer < num_aerosol_ids; ++iaer) { - qsub4[iaer][jsub] = qaer4[iaer][n] / fcvt_aer(iaer); - for (int i = 0; i < nqtendaa(); ++i) - qsub_tendaa[iaer][i][jsub] = - qaer_delaa[iaer][n][i] / (fcvt_aer(iaer) * deltat); - } - qaerwatsub4[n][jsub] = qwtr4[n] / fcvt_wtr(); - - if (iscldy_subarea[jsub]) { - qqcwsub4[n][jsub] = qnumcw4[n] / fcvt_num(); - for (int i = 0; i < nqqcwtendaa(); ++i) - qqcwsub_tendaa[n][i][jsub] = - qnumcw_delaa[n][i] / (fcvt_num() * deltat); - for (int iaer = 0; iaer < num_aerosol_ids; ++iaer) { - qqcwsub4[iaer][jsub] = qaercw4[iaer][n] / fcvt_aer(iaer); - for (int i = 0; i < nqqcwtendaa(); ++i) - qqcwsub_tendaa[iaer][i][jsub] = - qaercw_delaa[iaer][n][i] / (fcvt_aer(iaer) * deltat); - } - } - } - } - } -} - -} // anonymous namespace - -KOKKOS_INLINE_FUNCTION -void modal_aero_amicphys_intr( - const AmicPhysConfig& config, const int nstep, const Real deltat, const Real t, const Real pmid, const Real pdel, - const Real zm, const Real pblh, const Real qv, const Real cld, - Real q[gas_pcnst()], Real qqcw[gas_pcnst()], const Real q_pregaschem[gas_pcnst()], - const Real q_precldchem[gas_pcnst()], const Real qqcw_precldchem[gas_pcnst()], - Real q_tendbb[gas_pcnst()][nqtendbb()], Real qqcw_tendbb[gas_pcnst()][nqtendbb()], - Real dgncur_a[AeroConfig::num_modes()], - Real dgncur_awet[AeroConfig::num_modes()], - Real wetdens_host[AeroConfig::num_modes()], - Real qaerwat[AeroConfig::num_modes()]) { - - /* - nstep ! model time-step number - nqtendbb ! dimension for q_tendbb - nqqcwtendbb ! dimension f - deltat ! - q(ncol,pver,pcnstxx) ! current tracer mixing ratios (TMRs) - these values are updated (so out /= in) - *** MUST BE #/kmol-air for number - *** MUST BE mol/mol-air for mass - *** NOTE ncol dimension - qqcw(ncol,pver,pcnstxx) - like q but for cloud-borner tracers - these values are updated - q_pregaschem(ncol,pver,pcnstxx) ! q TMRs before gas-phase - chemistry q_precldchem(ncol,pver,pcnstxx) ! q TMRs before cloud - chemistry qqcw_precldchem(ncol,pver,pcnstxx) ! qqcw TMRs before cloud - chemistry q_tendbb(ncol,pver,pcnstxx,nqtendbb()) ! TMR tendencies for - box-model diagnostic output qqcw_tendbb(ncol,pver,pcnstx t(pcols,pver) ! - temperature at model levels (K) pmid(pcols,pver) ! pressure at model - level centers (Pa) pdel(pcols,pver) ! pressure thickness of levels - (Pa) zm(pcols,pver) ! altitude (above ground) at level centers (m) - pblh(pcols) ! planetary boundary layer depth (m) - qv(pcols,pver) ! specific humidity (kg/kg) - cld(ncol,pver) ! cloud fraction (-) *** NOTE ncol dimension - dgncur_a(pcols,pver,ntot_amode) - dgncur_awet(pcols,pver,ntot_amode) - ! dry & wet geo. mean dia. (m) of - number distrib. wetdens_host(pcols,pver,ntot_amode) ! interstitial - aerosol wet density (kg/m3) - - qaerwat(pcols,pver,ntot_amode aerosol water mixing ratio (kg/kg, - NOT mol/mol) - - */ - - // !DESCRIPTION: - // calculates changes to gas and aerosol TMRs (tracer mixing ratios) from - // gas-aerosol exchange (condensation/evaporation) - // growth from smaller to larger modes (renaming) due to both - // condensation and cloud chemistry - // new particle nucleation - // coagulation - // transfer of particles from hydrophobic modes to hydrophilic modes - // (aging) - // due to condensation and coagulation - // - // the incoming mixing ratios (q and qqcw) are updated before output - // - // !REVISION HISTORY: - // RCE 07.04.13: Adapted from earlier version of CAM5 modal aerosol - // routines - // for these processes - // - - static constexpr int num_modes = AeroConfig::num_modes(); - - // qgcmN and qqcwgcmN (N=1:4) are grid-cell mean tracer mixing ratios - // (TMRs, mol/mol or #/kmol) - // N=1 - before gas-phase chemistry - // N=2 - before cloud chemistry - // N=3 - incoming values (before gas-aerosol exchange, newnuc, coag) - // N=4 - outgoing values (after gas-aerosol exchange, newnuc, coag) - - // qsubN and qqcwsubN (N=1:4) are TMRs in sub-areas - // currently there are just clear and cloudy sub-areas - // the N=1:4 have same meanings as for qgcmN - - // q_coltendaa and qqcw_coltendaa are column-integrated tendencies - // for different processes, which are output to history - // the processes are condensation/evaporation (and associated aging), - // renaming, coagulation, and nucleation - - for (int i = 0; i < gas_pcnst(); ++i) - for (int j = 0; j < nqtendbb(); ++j) - q_tendbb[i][j] = 0.0, qqcw_tendbb[i][j] = 0.0; - - // get saturation mixing ratio - // call qsat( t(1:ncol,1:pver), pmid(1:ncol,1:pvnner), & - // ev_sat(1:ncol,1:pver), qv_sat(1:ncol,1:pver) ) - const Real epsqs = haero::Constants::weight_ratio_h2o_air; - // Saturation vapor pressure - const Real ev_sat = conversions::vapor_saturation_pressure_magnus(t, pmid); - // Saturation specific humidity - const Real qv_sat = epsqs * ev_sat / (pmid - (1 - epsqs) * ev_sat); - - const Real relhumgcm = haero::max(0.0, haero::min(1.0, qv / qv_sat)); - - // Set up cloudy/clear subareas inside a grid cell - int nsubarea, ncldy_subarea, jclea, jcldy; - bool iscldy_subarea[maxsubarea()]; - Real afracsub[maxsubarea()]; - Real relhumsub[maxsubarea()]; - Real qsub1[gas_pcnst()][maxsubarea()]; - Real qsub2[gas_pcnst()][maxsubarea()]; - Real qsub3[gas_pcnst()][maxsubarea()]; - Real qqcwsub1[gas_pcnst()][maxsubarea()]; - Real qqcwsub2[gas_pcnst()][maxsubarea()]; - Real qqcwsub3[gas_pcnst()][maxsubarea()]; - // aerosol water mixing ratios (mol/mol) - Real qaerwatsub3[AeroConfig::num_modes()][maxsubarea()]; - construct_subareas_1gridcell(cld, relhumgcm, // in - q_pregaschem, q_precldchem, // in - qqcw_precldchem, // in - q, qqcw, // in - nsubarea, ncldy_subarea, jclea, jcldy, // out - iscldy_subarea, afracsub, relhumsub, // out - qsub1, qsub2, qsub3, // out - qqcwsub1, qqcwsub2, qqcwsub3, qaerwatsub3, // out - qaerwat // in - ); - - // Initialize the "after-amicphys" values - Real qsub4[gas_pcnst()][maxsubarea()] = {}; - Real qqcwsub4[gas_pcnst()][maxsubarea()] = {}; - Real qaerwatsub4[AeroConfig::num_modes()][maxsubarea()] = {}; - - // - // start integration - // - Real dgn_a[num_modes], dgn_awet[num_modes], wetdens[num_modes]; - for (int n = 0; n < num_modes; ++n) { - dgn_a[n] = dgncur_a[n]; - dgn_awet[n] = dgncur_awet[n]; - wetdens[n] = haero::max(1000.0, wetdens_host[n]); - } - Real qsub_tendaa[gas_pcnst()][nqtendaa()][maxsubarea()] = {}; - Real qqcwsub_tendaa[gas_pcnst()][nqqcwtendaa()][maxsubarea()] = {}; - mam_amicphys_1gridcell(config, nstep, deltat, - nsubarea, ncldy_subarea, iscldy_subarea, afracsub, t, - pmid, pdel, zm, pblh, relhumsub, dgn_a, dgn_awet, - wetdens, qsub1, qsub2, qqcwsub2, qsub3, qqcwsub3, - qaerwatsub3, qsub4, qqcwsub4, qaerwatsub4, qsub_tendaa, - qqcwsub_tendaa); - - // - // form new grid-mean mix-ratios - Real qgcm4[gas_pcnst()]; - Real qgcm_tendaa[gas_pcnst()][nqtendaa()]; - Real qaerwatgcm4[num_modes]; - if (nsubarea == 1) { - for (int i = 0; i < gas_pcnst(); ++i) - qgcm4[i] = qsub4[i][0]; - for (int i = 0; i < gas_pcnst(); ++i) - for (int j = 0; j < nqtendaa(); ++j) - qgcm_tendaa[i][j] = qsub_tendaa[i][j][0]; - for (int i = 0; i < num_modes; ++i) - qaerwatgcm4[i] = qaerwatsub4[i][0]; - } else { - for (int i = 0; i < gas_pcnst(); ++i) - qgcm4[i] = 0.0; - for (int i = 0; i < gas_pcnst(); ++i) - for (int j = 0; j < nqtendaa(); ++j) - qgcm_tendaa[i][j] = 0.0; - for (int n = 0; n < nsubarea; ++n) { - for (int i = 0; i < gas_pcnst(); ++i) - qgcm4[i] += qsub4[i][n] * afracsub[n]; - for (int i = 0; i < gas_pcnst(); ++i) - for (int j = 0; j < nqtendaa(); ++j) - qgcm_tendaa[i][j] = - qgcm_tendaa[i][j] + qsub_tendaa[i][j][n] * afracsub[n]; - } - for (int i = 0; i < num_modes; ++i) - // for aerosol water use the clear sub-area value - qaerwatgcm4[i] = qaerwatsub4[i][jclea - 1]; - } - Real qqcwgcm4[gas_pcnst()]; - Real qqcwgcm_tendaa[gas_pcnst()][nqqcwtendaa()]; - if (ncldy_subarea <= 0) { - for (int i = 0; i < gas_pcnst(); ++i) - qqcwgcm4[i] = haero::max(0.0, qqcw[i]); - for (int i = 0; i < gas_pcnst(); ++i) - for (int j = 0; j < nqqcwtendaa(); ++j) - qqcwgcm_tendaa[i][j] = 0.0; - } else if (nsubarea == 1) { - for (int i = 0; i < gas_pcnst(); ++i) - qqcwgcm4[i] = qqcwsub4[i][0]; - for (int i = 0; i < gas_pcnst(); ++i) - for (int j = 0; j < nqqcwtendaa(); ++j) - qqcwgcm_tendaa[i][j] = qqcwsub_tendaa[i][j][0]; - } else { - for (int i = 0; i < gas_pcnst(); ++i) - qqcwgcm4[i] = 0.0; - for (int i = 0; i < gas_pcnst(); ++i) - for (int j = 0; j < nqqcwtendaa(); ++j) - qqcwgcm_tendaa[i][j] = 0.0; - for (int n = 0; n < nsubarea; ++n) { - if (iscldy_subarea[n]) { - for (int i = 0; i < gas_pcnst(); ++i) - qqcwgcm4[i] += qqcwsub4[i][n] * afracsub[n]; - for (int i = 0; i < gas_pcnst(); ++i) - for (int j = 0; j < nqqcwtendaa(); ++j) - qqcwgcm_tendaa[i][j] += qqcwsub_tendaa[i][j][n] * afracsub[n]; - } - } - } - - for (int lmz = 0; lmz < gas_pcnst(); ++lmz) { - if (lmapcc_all(lmz) > 0) { - // HW, to ensure non-negative - q[lmz] = haero::max(qgcm4[lmz], 0.0); - if (lmapcc_all(lmz) >= lmapcc_val_aer()) { - // HW, to ensure non-negative - qqcw[lmz] = haero::max(qqcwgcm4[lmz], 0.0); - } - } - } - for (int i = 0; i < gas_pcnst(); ++i) { - if (iqtend_cond() < nqtendbb()) - q_tendbb[i][iqtend_cond()] = qgcm_tendaa[i][iqtend_cond()]; - if (iqtend_rnam() < nqtendbb()) - q_tendbb[i][iqtend_rnam()] = qgcm_tendaa[i][iqtend_rnam()]; - if (iqtend_nnuc() < nqtendbb()) - q_tendbb[i][iqtend_nnuc()] = qgcm_tendaa[i][iqtend_nnuc()]; - if (iqtend_coag() < nqtendbb()) - q_tendbb[i][iqtend_coag()] = qgcm_tendaa[i][iqtend_coag()]; - if (iqqcwtend_rnam() < nqqcwtendbb()) - qqcw_tendbb[i][iqqcwtend_rnam()] = qqcwgcm_tendaa[i][iqqcwtend_rnam()]; - } - for (int i = 0; i < num_modes; ++i) - qaerwat[i] = qaerwatgcm4[i]; -} - -} // namespace scream::impl From e715b8b471a5173c1efc3668f54b6056a2884e47 Mon Sep 17 00:00:00 2001 From: Michael J Schmidt Date: Mon, 4 Nov 2024 17:33:17 -0700 Subject: [PATCH 127/147] update mam4xx submodule to fix gpu compilation error --- externals/mam4xx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/externals/mam4xx b/externals/mam4xx index 59990d402f41..d1c70ab972bc 160000 --- a/externals/mam4xx +++ b/externals/mam4xx @@ -1 +1 @@ -Subproject commit 59990d402f4115ce3a36a8c00eb4d059e703a583 +Subproject commit d1c70ab972bc00269939fd3296d93a719f273105 From cc63e5d67ed616b06a58514a44f3326322438bfe Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Mon, 4 Nov 2024 20:24:40 -0800 Subject: [PATCH 128/147] EAMxx: Fixes a gpu bug requiring a particular format for dstflx --- components/eamxx/tests/single-process/mam/emissions/input.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/eamxx/tests/single-process/mam/emissions/input.yaml b/components/eamxx/tests/single-process/mam/emissions/input.yaml index a4564cb3949a..0819562d9590 100644 --- a/components/eamxx/tests/single-process/mam/emissions/input.yaml +++ b/components/eamxx/tests/single-process/mam/emissions/input.yaml @@ -43,7 +43,7 @@ initial_conditions: # we should get the following variables from other processes pbl_height : 1.0 - dstflx : [ 0.00000000000000000E+000, 0.00000000000000000E+000, 0.00000000000000000E+000, 0.00000000000000000E+000] + dstflx : 0.0 ocnfrac: 0.10000000000000000E+001 sst: 0.30178553874977507E+003 cldfrac_tot: 0.138584624960092 From 40a6190f5557002f1429c36a4249663fc378a1a7 Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Mon, 4 Nov 2024 20:39:44 -0800 Subject: [PATCH 129/147] EAMxx: Clang format --- ...mxx_mam_microphysics_process_interface.cpp | 34 +++++++++++++------ 1 file changed, 23 insertions(+), 11 deletions(-) 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 57eaf9275483..328afc896900 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 @@ -2,9 +2,13 @@ // impl namespace for some driver level functions for microphysics +<<<<<<< HEAD #include "readfiles/photo_table_utils.cpp" #include "readfiles/find_season_index_utils.hpp" +======= +>>>>>>> EAMxx: Clang format #include "physics/rrtmgp/shr_orb_mod_c2f.hpp" +#include "readfiles/photo_table_utils.cpp" namespace scream { @@ -36,7 +40,7 @@ MAMMicrophysics::MAMMicrophysics(const ekat::Comm &comm, config_.linoz.o3_lbl = m_params.get("mam4_o3_lbl"); config_.linoz.o3_tau = m_params.get("mam4_o3_tau"); config_.linoz.o3_sfc = m_params.get("mam4_o3_sfc"); - config_.linoz.psc_T = m_params.get("mam4_psc_T"); + config_.linoz.psc_T = m_params.get("mam4_psc_T"); } AtmosphereProcessType MAMMicrophysics::type() const { @@ -81,19 +85,20 @@ void MAMMicrophysics::set_grids( // ----------- Atmospheric quantities ------------- // Specific humidity [kg/kg](Require only for building DS) - add_tracer("qv", grid_, kg/kg); // specific humidity + add_tracer("qv", grid_, kg / kg); // specific humidity // Cloud liquid mass mixing ratio [kg/kg](Require only for building DS) - add_tracer("qc", grid_, kg/kg); // cloud liquid wet mixing ratio + add_tracer("qc", grid_, kg / kg); // cloud liquid wet mixing ratio // Cloud ice mass mixing ratio [kg/kg](Require only for building DS) - add_tracer("qi", grid_, kg/kg); // ice wet mixing ratio + add_tracer("qi", grid_, kg / kg); // ice wet mixing ratio // Cloud liquid number mixing ratio [1/kg](Require only for building DS) - add_tracer("nc", grid_, n_unit); // cloud liquid wet number mixing ratio + add_tracer("nc", grid_, + n_unit); // cloud liquid wet number mixing ratio // Cloud ice number mixing ratio [1/kg](Require only for building DS) - add_tracer("ni", grid_, n_unit); // ice number mixing ratio + add_tracer("ni", grid_, n_unit); // ice number mixing ratio // Temperature[K] at midpoints add_field("T_mid", scalar3d_mid, K, grid_name); @@ -161,7 +166,7 @@ void MAMMicrophysics::set_grids( mam_coupling::int_aero_mmr_field_name(m, a); if(strlen(int_mmr_field_name) > 0) { - add_tracer(int_mmr_field_name, grid_, kg/kg); + add_tracer(int_mmr_field_name, grid_, kg / kg); } } // for loop species } // for loop nmodes interstitial @@ -183,7 +188,7 @@ void MAMMicrophysics::set_grids( // aerosol-related gases: mass mixing ratios for(int g = 0; g < mam_coupling::num_aero_gases(); ++g) { const char *gas_mmr_field_name = mam_coupling::gas_mmr_field_name(g); - add_tracer(gas_mmr_field_name, grid_, kg/kg); + add_tracer(gas_mmr_field_name, grid_, kg / kg); } // Creating a Linoz reader and setting Linoz parameters involves reading data @@ -715,10 +720,17 @@ void MAMMicrophysics::run_impl(const double dt) { const auto zenith_angle = acos_cosine_zenith_; constexpr int gas_pcnst = mam_coupling::gas_pcnst(); +<<<<<<< HEAD const auto& elevated_emis_output = elevated_emis_output_; const auto& extfrc = extfrc_; const auto& forcings = forcings_; constexpr int extcnt = mam4::gas_chemistry::extcnt; +======= + const auto &vert_emis_output = vert_emis_output_; + const auto &extfrc = extfrc_; + const auto &forcings = forcings_; + constexpr int extcnt = mam4::gas_chemistry::extcnt; +>>>>>>> EAMxx: Clang format const int offset_aerosol = mam4::utils::gasses_start_ind(); Real adv_mass_kg_per_moles[gas_pcnst]; @@ -809,9 +821,9 @@ void MAMMicrophysics::run_impl(const double dt) { linoz_o3col_clim_icol, linoz_PmL_clim_icol, linoz_dPmL_dO3_icol, linoz_dPmL_dT_icol, linoz_dPmL_dO3col_icol, linoz_cariolle_pscs_icol, eccf, adv_mass_kg_per_moles, clsmap_4, - permute_4, offset_aerosol, - config.linoz.o3_sfc, config.linoz.o3_tau, config.linoz.o3_lbl, - dry_diameter_icol, wet_diameter_icol, wetdens_icol); + permute_4, offset_aerosol, config.linoz.o3_sfc, config.linoz.o3_tau, + config.linoz.o3_lbl, dry_diameter_icol, wet_diameter_icol, + wetdens_icol); }); // parallel_for for the column loop Kokkos::fence(); From f3a29b109af2891bb212d233cca88e3880d1bdf2 Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Mon, 4 Nov 2024 20:50:43 -0800 Subject: [PATCH 130/147] EAMxx: Fixed some comments paths and other minor cleanup --- .../eamxx/cime_config/namelist_defaults_scream.xml | 2 +- ...m_srf_and_online_emissions_process_interface.cpp | 10 +++++----- ...m_srf_and_online_emissions_process_interface.hpp | 1 + .../src/physics/mam/readfiles/marine_organics.hpp | 10 ---------- .../physics/mam/readfiles/marine_organics_impl.hpp | 8 -------- .../src/physics/mam/readfiles/soil_erodibility.hpp | 13 ------------- .../physics/mam/readfiles/soil_erodibility_impl.hpp | 6 ------ 7 files changed, 7 insertions(+), 43 deletions(-) diff --git a/components/eamxx/cime_config/namelist_defaults_scream.xml b/components/eamxx/cime_config/namelist_defaults_scream.xml index fd62cdc01e37..9c11c76aea1f 100644 --- a/components/eamxx/cime_config/namelist_defaults_scream.xml +++ b/components/eamxx/cime_config/namelist_defaults_scream.xml @@ -376,7 +376,7 @@ 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/dst_ne4pg2_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 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 190dc1da27d9..a3efea7d32d9 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 @@ -15,7 +15,7 @@ using soilErodibilityFunc = MAMSrfOnlineEmiss::MAMSrfOnlineEmiss(const ekat::Comm &comm, const ekat::ParameterList ¶ms) : AtmosphereProcess(comm, params) { - // FIXME: Do we want to read dust emiss factor hfrom namelist?? + // FIXME: Do we want to read dust emiss factor from the namelist?? /* Anything that can be initialized without grid information can be * initialized here. Like universal constants. */ @@ -238,7 +238,7 @@ void MAMSrfOnlineEmiss::set_grids( } // srf emissions file read init // ------------------------------------------------------------- - // setup to enable reading soil erodibility file + // Setup to enable reading soil erodibility file // ------------------------------------------------------------- const std::string soil_erodibility_data_file = @@ -257,12 +257,12 @@ void MAMSrfOnlineEmiss::set_grids( serod_dataReader_); // output // ------------------------------------------------------------- - // setup to enable reading marine organics file + // Setup to enable reading marine organics file // ------------------------------------------------------------- const std::string marine_organics_data_file = m_params.get("marine_organics_file"); - // Field to be read from file (order matters as they are read in the same + // 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"}; @@ -477,7 +477,7 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { // Output view_1d fluxes_col = ekat::subview(constituent_fluxes, icol); - // Comput online emissions + // 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( 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 b1cba682bb62..ae00098b0793 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 @@ -130,6 +130,7 @@ class MAMSrfOnlineEmiss final : public scream::AtmosphereProcess { const int gas_start_ind = mam4::utils::gasses_start_ind(); // FIXME: Is there a better way to zero out a select indices? + // We should probably do it in run_impl directly for(int ispc = gas_start_ind; ispc < pcnst; ++ispc) { flux_col(ispc) = 0; } diff --git a/components/eamxx/src/physics/mam/readfiles/marine_organics.hpp b/components/eamxx/src/physics/mam/readfiles/marine_organics.hpp index 92136d315f51..a04dff129f49 100644 --- a/components/eamxx/src/physics/mam/readfiles/marine_organics.hpp +++ b/components/eamxx/src/physics/mam/readfiles/marine_organics.hpp @@ -15,7 +15,6 @@ struct marineOrganicsFunctions { using MemberType = typename KT::MemberType; using view_2d = typename KT::template view_2d; - // ------------------------------------------------------------------------------------------- // ------------------------------------------------------------------------------------------- struct marineOrganicsTimeState { marineOrganicsTimeState() = default; @@ -50,7 +49,6 @@ struct marineOrganicsFunctions { view_2d emiss_sectors; }; // marineOrganicsData - // ------------------------------------------------------------------------------------------- // ------------------------------------------------------------------------------------------- struct marineOrganicsInput { marineOrganicsInput() = default; @@ -69,20 +67,17 @@ struct marineOrganicsFunctions { // 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 &scorpio_reader, @@ -91,7 +86,6 @@ struct marineOrganicsFunctions { AbstractRemapper &horiz_interp, marineOrganicsInput &marineOrganics_input); - // ------------------------------------------------------------------------------------------- // ------------------------------------------------------------------------------------------- static void update_marine_organics_timestate( std::shared_ptr &scorpio_reader, @@ -99,21 +93,18 @@ struct marineOrganicsFunctions { 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 @@ -121,7 +112,6 @@ struct marineOrganicsFunctions { const ScalarX &x1, const ScalarT &t); - // ------------------------------------------------------------------------------------------- // ------------------------------------------------------------------------------------------- static void init_marine_organics_file_read( const int &ncol, const std::vector &field_name, diff --git a/components/eamxx/src/physics/mam/readfiles/marine_organics_impl.hpp b/components/eamxx/src/physics/mam/readfiles/marine_organics_impl.hpp index 6eda3a47e724..389445fa024d 100644 --- a/components/eamxx/src/physics/mam/readfiles/marine_organics_impl.hpp +++ b/components/eamxx/src/physics/mam/readfiles/marine_organics_impl.hpp @@ -77,8 +77,6 @@ marineOrganicsFunctions::create_horiz_remapper( } // create_horiz_remapper // ------------------------------------------------------------------------------------------- -// ------------------------------------------------------------------------------------------- - template std::shared_ptr marineOrganicsFunctions::create_data_reader( @@ -92,7 +90,6 @@ marineOrganicsFunctions::create_data_reader( return std::make_shared(data_file, io_grid, io_fields, true); } // create_data_reader -// ------------------------------------------------------------------------------------------- // ------------------------------------------------------------------------------------------- template void marineOrganicsFunctions::update_marine_organics_data_from_file( @@ -144,7 +141,6 @@ void marineOrganicsFunctions::update_marine_organics_data_from_file( } // END update_marine_organics_data_from_file -// ------------------------------------------------------------------------------------------- // ------------------------------------------------------------------------------------------- template void marineOrganicsFunctions::update_marine_organics_timestate( @@ -180,7 +176,6 @@ void marineOrganicsFunctions::update_marine_organics_timestate( } // END updata_marine_organics_timestate -// ------------------------------------------------------------------------------------------- // ------------------------------------------------------------------------------------------- template template @@ -189,7 +184,6 @@ KOKKOS_INLINE_FUNCTION ScalarX marineOrganicsFunctions::linear_interp( return (1 - t) * x0 + t * x1; } // linear_interp -// ------------------------------------------------------------------------------------------- // ------------------------------------------------------------------------------------------- template void marineOrganicsFunctions::perform_time_interpolation( @@ -239,7 +233,6 @@ void marineOrganicsFunctions::perform_time_interpolation( } // perform_time_interpolation -// ------------------------------------------------------------------------------------------- // ------------------------------------------------------------------------------------------- template void marineOrganicsFunctions::marineOrganics_main( @@ -270,7 +263,6 @@ void marineOrganicsFunctions::marineOrganics_main( perform_time_interpolation(time_state, data_beg, data_end, data_out); } // marineOrganics_main -// ------------------------------------------------------------------------------------------- // ------------------------------------------------------------------------------------------- template void marineOrganicsFunctions::init_marine_organics_file_read( diff --git a/components/eamxx/src/physics/mam/readfiles/soil_erodibility.hpp b/components/eamxx/src/physics/mam/readfiles/soil_erodibility.hpp index 223fb78cfc14..8b47c81d9073 100644 --- a/components/eamxx/src/physics/mam/readfiles/soil_erodibility.hpp +++ b/components/eamxx/src/physics/mam/readfiles/soil_erodibility.hpp @@ -14,32 +14,19 @@ struct soilErodibilityFunctions { using KT = KokkosTypes; using const_view_1d = typename KT::template view_1d; - // ------------------------------------------------------------------------------------------- - // ------------------------------------------------------------------------------------------- - - // Soil erodibility routines 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 &scorpio_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, diff --git a/components/eamxx/src/physics/mam/readfiles/soil_erodibility_impl.hpp b/components/eamxx/src/physics/mam/readfiles/soil_erodibility_impl.hpp index a685134419fe..af0c4d73c174 100644 --- a/components/eamxx/src/physics/mam/readfiles/soil_erodibility_impl.hpp +++ b/components/eamxx/src/physics/mam/readfiles/soil_erodibility_impl.hpp @@ -70,8 +70,6 @@ soilErodibilityFunctions::create_horiz_remapper( } // create_horiz_remapper // ------------------------------------------------------------------------------------------- -// ------------------------------------------------------------------------------------------- - template std::shared_ptr soilErodibilityFunctions::create_data_reader( @@ -86,8 +84,6 @@ soilErodibilityFunctions::create_data_reader( } // create_data_reader // ------------------------------------------------------------------------------------------- -// ------------------------------------------------------------------------------------------- - template void soilErodibilityFunctions::update_soil_erodibility_data_from_file( std::shared_ptr &scorpio_reader, @@ -129,8 +125,6 @@ void soilErodibilityFunctions::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, From 8d4ca7677e6cde97fccf948a1685e42744b68188 Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Mon, 4 Nov 2024 22:33:36 -0800 Subject: [PATCH 131/147] EAMxx: Moves online emiss and constituent init to a new function hpp file --- ...mam_srf_and_online_emissions_functions.hpp | 76 +++++++++++++++++++ ...and_online_emissions_process_interface.cpp | 45 +++++------ ...and_online_emissions_process_interface.hpp | 25 ++---- 3 files changed, 99 insertions(+), 47 deletions(-) create mode 100644 components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_functions.hpp diff --git a/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_functions.hpp b/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_functions.hpp new file mode 100644 index 000000000000..c1414d2077ff --- /dev/null +++ b/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_functions.hpp @@ -0,0 +1,76 @@ +#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; +using view_1d = typename KT::template view_1d; +using view_2d = typename KT::template view_2d; +using const_view_1d = typename KT::template view_1d; +using const_view_2d = typename KT::template view_2d; + +//-------- 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::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; }); + }); + Kokkos::fence(); +} // 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); + }); + Kokkos::fence(); + +} // compute_online_dust_nacl_emiss ends + +} // namespace +} // namespace scream + +#endif // EAMXX_MAM_SRF_AND_ONLINE_EMISSIONS_FUNCTIONS_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 a3efea7d32d9..d410bb01d6e9 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 @@ -1,5 +1,8 @@ #include +// For surface and online emission functions +#include + // For reading soil erodibility file #include @@ -397,7 +400,7 @@ void MAMSrfOnlineEmiss::initialize_impl(const RunType run_type) { //----------------------------------------------------------------- // Setup preprocessing and post processing //----------------------------------------------------------------- - preprocess_.initialize(ncol_, nlev_, wet_atm_, dry_atm_, constituent_fluxes_); + preprocess_.initialize(ncol_, nlev_, wet_atm_, dry_atm_); } // end initialize_impl() @@ -412,6 +415,13 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { Kokkos::parallel_for("preprocess", scan_policy, preprocess_); Kokkos::fence(); + // Constituent fluxes [kg/m^2/s] + auto constituent_fluxes = this->constituent_fluxes_; + + // Zero out constituent fluxes only for gasses and aerosols + init_fluxes(ncol_, // in + constituent_fluxes); // in-out + // Gather time and state information for interpolation const auto ts = timestamp() + dt; @@ -419,6 +429,8 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { // Online emissions from dust and sea salt //-------------------------------------------------------------------- + // compute_online_dust_nacl_emiss(); + // --- Interpolate marine organics data -- // Update TimeState, note the addition of dt @@ -457,38 +469,17 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { // Dust fluxes [kg/m^2/s]: Four flux values for each column const const_view_2d dstflx = get_field_in("dstflx").get_view(); - // Constituent fluxes [kg/m^2/s] - auto constituent_fluxes = this->constituent_fluxes_; - // Soil edodibility [fraction] const const_view_1d soil_erodibility = this->soil_erodibility_; // Vertical layer height at midpoints const const_view_2d z_mid = dry_atm_.z_mid; - // TODO: potentially combine with below parfor(icol) loop? - 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); - }); - Kokkos::fence(); - + compute_online_dust_nacl_emiss(ncol_, nlev_, ocnfrac, sst, u_wind, v_wind, + dstflx, mpoly, mprot, mlip, soil_erodibility, + z_mid, + // output + constituent_fluxes); //-------------------------------------------------------------------- // Interpolate srf emiss data read in from emissions files //-------------------------------------------------------------------- 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 ae00098b0793..1a3bb4f36e3f 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 @@ -103,13 +103,11 @@ class MAMSrfOnlineEmiss final : public scream::AtmosphereProcess { // on host: initializes preprocess functor with necessary state data void initialize(const int &ncol, const int &nlev, const mam_coupling::WetAtmosphere &wet_atm, - const mam_coupling::DryAtmosphere &dry_atm, - const view_2d &constituent_fluxes) { - ncol_pre_ = ncol; - nlev_pre_ = nlev; - wet_atm_pre_ = wet_atm; - dry_atm_pre_ = dry_atm; - constituent_fluxes_pre_ = constituent_fluxes; + const mam_coupling::DryAtmosphere &dry_atm) { + ncol_pre_ = ncol; + nlev_pre_ = nlev; + wet_atm_pre_ = wet_atm; + dry_atm_pre_ = dry_atm; } KOKKOS_INLINE_FUNCTION void operator()( @@ -122,18 +120,6 @@ class MAMSrfOnlineEmiss final : public scream::AtmosphereProcess { // for atmosphere compute_vertical_layer_heights(team, dry_atm_pre_, icol); compute_updraft_velocities(team, wet_atm_pre_, dry_atm_pre_, icol); - - view_1d flux_col = ekat::subview(constituent_fluxes_pre_, icol); - - // Zero out constituent fluxes only for gasses and aerosols - const int pcnst = mam4::aero_model::pcnst; - const int gas_start_ind = mam4::utils::gasses_start_ind(); - - // FIXME: Is there a better way to zero out a select indices? - // We should probably do it in run_impl directly - for(int ispc = gas_start_ind; ispc < pcnst; ++ispc) { - flux_col(ispc) = 0; - } } // Preprocess operator() // local variables for preprocess struct @@ -143,7 +129,6 @@ class MAMSrfOnlineEmiss final : public scream::AtmosphereProcess { // local atmospheric and aerosol state data mam_coupling::WetAtmosphere wet_atm_pre_; mam_coupling::DryAtmosphere dry_atm_pre_; - view_2d constituent_fluxes_pre_; }; // MAMSrfOnlineEmiss::Preprocess private: // preprocessing scratch pad From a20712c19505fbcf1025d5d6ce1d29952c25a772 Mon Sep 17 00:00:00 2001 From: Michael J Schmidt Date: Tue, 5 Nov 2024 11:57:27 -0700 Subject: [PATCH 132/147] fix cuda compile warnings --- ...amxx_mam_srf_and_online_emissions_process_interface.cpp | 7 ++++--- components/eamxx/src/physics/mam/srf_emission_impl.hpp | 2 +- 2 files changed, 5 insertions(+), 4 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 d410bb01d6e9..58a1c341fa54 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 @@ -509,15 +509,16 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { auto fluxes_in_mks_units = this->fluxes_in_mks_units_; const Real mfactor = amufac * mam4::gas_chemistry::adv_mass[species_index - offset_]; + const view_1d ispec_outdata0 = + ekat::subview(ispec_srf.data_out_.emiss_sectors, 0); // Parallel loop over all the columns to update units Kokkos::parallel_for( "srf_emis_fluxes", ncol_, KOKKOS_LAMBDA(int icol) { - fluxes_in_mks_units(icol) = - ispec_srf.data_out_.emiss_sectors(0, icol) * mfactor; + fluxes_in_mks_units(icol) = ispec_outdata0(icol) * mfactor; constituent_fluxes(icol, species_index) = fluxes_in_mks_units(icol); }); } // for loop for species Kokkos::fence(); } // run_impl ends // ============================================================================= -} // namespace scream \ No newline at end of file +} // namespace scream diff --git a/components/eamxx/src/physics/mam/srf_emission_impl.hpp b/components/eamxx/src/physics/mam/srf_emission_impl.hpp index fa037dc281d0..b8ebfdbe5017 100644 --- a/components/eamxx/src/physics/mam/srf_emission_impl.hpp +++ b/components/eamxx/src/physics/mam/srf_emission_impl.hpp @@ -179,7 +179,7 @@ void srfEmissFunctions::update_srfEmiss_data_from_file( const int time_index, // zero-based AbstractRemapper &srfEmiss_horiz_interp, srfEmissInput &srfEmiss_input) { using namespace ShortFieldTagsNames; - + start_timer("EAMxx::srfEmiss::update_srfEmiss_data_from_file"); // 1. Read from file From a40341e657253fd3b810a3c2eb3b6f3682e2f249 Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Wed, 13 Nov 2024 12:54:49 -0800 Subject: [PATCH 133/147] EAMxx:Inits constituent fluxes to zero --- components/eamxx/cime_config/namelist_defaults_scream.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/components/eamxx/cime_config/namelist_defaults_scream.xml b/components/eamxx/cime_config/namelist_defaults_scream.xml index 9c11c76aea1f..d23169173ce4 100644 --- a/components/eamxx/cime_config/namelist_defaults_scream.xml +++ b/components/eamxx/cime_config/namelist_defaults_scream.xml @@ -638,6 +638,7 @@ be lost if SCREAM_HACK_XML is not enabled. 1.37146e-07 ,3.45899e-08 ,1.00000e-06 ,9.99601e-08 1.37452e-07 ,3.46684e-08 ,1.00900e-06 ,9.99601e-08 5.08262e-12 ,1.54035e-13 ,3.09018e-13 ,9.14710e-22 + 0.0 0.0 0.0 0.0 From df4f13c1942429b87f049e5326ac5b01d24ec58f Mon Sep 17 00:00:00 2001 From: Michael J Schmidt Date: Fri, 15 Nov 2024 13:01:30 -0700 Subject: [PATCH 134/147] Revert "EAMxx: Clang format" This reverts commit 22086f144e9a8ef9264c383f5487b39d8de37319. --- ...mxx_mam_microphysics_process_interface.cpp | 109 +++++++----------- 1 file changed, 44 insertions(+), 65 deletions(-) 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 328afc896900..35f27e1db008 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 @@ -2,11 +2,7 @@ // impl namespace for some driver level functions for microphysics -<<<<<<< HEAD #include "readfiles/photo_table_utils.cpp" -#include "readfiles/find_season_index_utils.hpp" -======= ->>>>>>> EAMxx: Clang format #include "physics/rrtmgp/shr_orb_mod_c2f.hpp" #include "readfiles/photo_table_utils.cpp" @@ -211,7 +207,7 @@ void MAMMicrophysics::set_grids( LinozHorizInterp_, linoz_file_name_); // linoz reader - const auto io_grid_linoz = LinozHorizInterp_->get_tgt_grid(); + const auto io_grid_linoz = LinozHorizInterp_->get_src_grid(); const int num_cols_io_linoz = io_grid_linoz->get_num_local_dofs(); // Number of columns on this rank const int num_levs_io_linoz = @@ -239,7 +235,7 @@ void MAMMicrophysics::set_grids( TracerHorizInterp_, oxid_file_name_); const int nvars = int(var_names.size()); - const auto io_grid = TracerHorizInterp_->get_tgt_grid(); + const auto io_grid = TracerHorizInterp_->get_src_grid(); const int num_cols_io = io_grid->get_num_local_dofs(); // Number of columns on this rank const int num_levs_io = @@ -264,88 +260,78 @@ void MAMMicrophysics::set_grids( "num_a1", "num_a2", "num_a4", "soag"}; for(const auto &var_name : extfrc_lst_) { - std::string item_name = "mam4_" + var_name + "_elevated_emiss_file_name"; + std::string item_name = "mam4_" + var_name + "_verti_emiss_file_name"; const auto file_name = m_params.get(item_name); - elevated_emis_file_name_[var_name] = file_name; + vert_emis_file_name_[var_name] = file_name; } - elevated_emis_var_names_["so2"] = {"BB", "ENE_ELEV", "IND_ELEV", "contvolc"}; - elevated_emis_var_names_["so4_a1"] = {"BB", "ENE_ELEV", "IND_ELEV", "contvolc"}; - elevated_emis_var_names_["so4_a2"] = {"contvolc"}; - elevated_emis_var_names_["pom_a4"] = {"BB"}; - elevated_emis_var_names_["bc_a4"] = {"BB"}; - elevated_emis_var_names_["num_a1"] = { + vert_emis_var_names_["so2"] = {"BB", "ENE_ELEV", "IND_ELEV", "contvolc"}; + vert_emis_var_names_["so4_a1"] = {"BB", "ENE_ELEV", "IND_ELEV", "contvolc"}; + vert_emis_var_names_["so4_a2"] = {"contvolc"}; + vert_emis_var_names_["pom_a4"] = {"BB"}; + vert_emis_var_names_["bc_a4"] = {"BB"}; + vert_emis_var_names_["num_a1"] = { "num_a1_SO4_ELEV_BB", "num_a1_SO4_ELEV_ENE", "num_a1_SO4_ELEV_IND", "num_a1_SO4_ELEV_contvolc"}; - elevated_emis_var_names_["num_a2"] = {"num_a2_SO4_ELEV_contvolc"}; + vert_emis_var_names_["num_a2"] = {"num_a2_SO4_ELEV_contvolc"}; // num_a4 // FIXME: why the sectors in this files are num_a1; // I guess this should be num_a4? Is this a bug in the orginal nc files? - elevated_emis_var_names_["num_a4"] = {"num_a1_BC_ELEV_BB", + vert_emis_var_names_["num_a4"] = {"num_a1_BC_ELEV_BB", "num_a1_POM_ELEV_BB"}; - elevated_emis_var_names_["soag"] = {"SOAbb_src", "SOAbg_src", "SOAff_src"}; + vert_emis_var_names_["soag"] = {"SOAbb_src", "SOAbg_src", "SOAff_src"}; - int elevated_emiss_cyclical_ymd = m_params.get("elevated_emiss_ymd"); + int verti_emiss_cyclical_ymd = m_params.get("verti_emiss_ymd"); for(const auto &var_name : extfrc_lst_) { - const auto file_name = elevated_emis_file_name_[var_name]; - const auto var_names = elevated_emis_var_names_[var_name]; + const auto file_name = vert_emis_file_name_[var_name]; + const auto var_names = vert_emis_var_names_[var_name]; scream::mam_coupling::TracerData data_tracer; scream::mam_coupling::setup_tracer_data(data_tracer, file_name, - elevated_emiss_cyclical_ymd); + verti_emiss_cyclical_ymd); auto hor_rem = scream::mam_coupling::create_horiz_remapper( grid_, file_name, extfrc_map_file, var_names, data_tracer); - auto file_reader = - scream::mam_coupling::create_tracer_data_reader(hor_rem, file_name, - data_tracer.file_type); - ElevatedEmissionsHorizInterp_.push_back(hor_rem); - ElevatedEmissionsDataReader_.push_back(file_reader); - elevated_emis_data_.push_back(data_tracer); - } // var_name elevated emissions + scream::mam_coupling::create_tracer_data_reader(hor_rem, file_name); + VertEmissionsHorizInterp_.push_back(hor_rem); + VertEmissionsDataReader_.push_back(file_reader); + vert_emis_data_.push_back(data_tracer); + } // var_name vert emissions int i = 0; int offset_emis_ver = 0; for(const auto &var_name : extfrc_lst_) { - const auto file_name = elevated_emis_file_name_[var_name]; - const auto var_names = elevated_emis_var_names_[var_name]; + const auto file_name = vert_emis_file_name_[var_name]; + const auto var_names = vert_emis_var_names_[var_name]; const int nvars = static_cast(var_names.size()); forcings_[i].nsectors = nvars; // I am assuming the order of species in extfrc_lst_. // Indexing in mam4xx is fortran. forcings_[i].frc_ndx = i + 1; - const auto io_grid_emis = ElevatedEmissionsHorizInterp_[i]->get_tgt_grid(); + const auto io_grid_emis = VertEmissionsHorizInterp_[i]->get_src_grid(); const int num_cols_io_emis = io_grid_emis->get_num_local_dofs(); // Number of columns on this rank const int num_levs_io_emis = io_grid_emis ->get_num_vertical_levels(); // Number of levels per column - elevated_emis_data_[i].init(num_cols_io_emis, num_levs_io_emis, nvars); - elevated_emis_data_[i].allocate_temporal_views(); - forcings_[i].file_alt_data = elevated_emis_data_[i].has_altitude_; + vert_emis_data_[i].init(num_cols_io_emis, num_levs_io_emis, nvars); + vert_emis_data_[i].allocate_temporal_views(); + forcings_[i].file_alt_data = vert_emis_data_[i].has_altitude_; for(int isp = 0; isp < nvars; ++isp) { forcings_[i].offset = offset_emis_ver; - elevated_emis_output_[isp + offset_emis_ver] = - view_2d("elevated_emis_output_", ncol_, nlev_); + vert_emis_output_[isp + offset_emis_ver] = + view_2d("vert_emis_output_", ncol_, nlev_); } offset_emis_ver += nvars; ++i; } // end i EKAT_REQUIRE_MSG( - offset_emis_ver <= int(mam_coupling::MAX_NUM_ELEVATED_EMISSIONS_FIELDS), + offset_emis_ver <= int(mam_coupling::MAX_NUM_VERT_EMISSION_FIELDS), "Error! Number of fields is bigger than " - "MAX_NUM_ELEVATED_EMISSIONS_FIELDS. Increase the " - "MAX_NUM_ELEVATED_EMISSIONS_FIELDS in tracer_reader_utils.hpp \n"); + "MAX_NUM_VERT_EMISSION_FIELDS. Increase the " + "MAX_NUM_VERT_EMISSION_FIELDS in tracer_reader_utils.hpp \n"); } // Tracer external forcing data - - { - const std::string season_wes_file = m_params.get("mam4_season_wes_file"); - const auto& clat = col_latitudes_; - mam_coupling::find_season_index_reader(season_wes_file, - clat, - index_season_lai_); - } } // set_grids // ================================================================ @@ -534,8 +520,8 @@ void MAMMicrophysics::initialize_impl(const RunType run_type) { for(int i = 0; i < static_cast(extfrc_lst_.size()); ++i) { scream::mam_coupling::update_tracer_data_from_file( - ElevatedEmissionsDataReader_[i], curr_month, *ElevatedEmissionsHorizInterp_[i], - elevated_emis_data_[i]); + VertEmissionsDataReader_[i], curr_month, *VertEmissionsHorizInterp_[i], + vert_emis_data_[i]); } invariants_ = view_3d("invarians", ncol_, nlev_, mam4::gas_chemistry::nfs); @@ -632,20 +618,20 @@ void MAMMicrophysics::run_impl(const double dt) { linoz_output); // out Kokkos::fence(); - elevated_emiss_time_state_.t_now = ts.frac_of_year_in_days(); + vert_emiss_time_state_.t_now = ts.frac_of_year_in_days(); int i = 0; for(const auto &var_name : extfrc_lst_) { - const auto file_name = elevated_emis_file_name_[var_name]; - const auto var_names = elevated_emis_var_names_[var_name]; + const auto file_name = vert_emis_file_name_[var_name]; + const auto var_names = vert_emis_var_names_[var_name]; const int nsectors = int(var_names.size()); - view_2d elevated_emis_output[nsectors]; + view_2d vert_emis_output[nsectors]; for(int isp = 0; isp < nsectors; ++isp) { - elevated_emis_output[isp] = elevated_emis_output_[isp + forcings_[i].offset]; + vert_emis_output[isp] = vert_emis_output_[isp + forcings_[i].offset]; } scream::mam_coupling::advance_tracer_data( - ElevatedEmissionsDataReader_[i], *ElevatedEmissionsHorizInterp_[i], ts, - elevated_emiss_time_state_, elevated_emis_data_[i], dry_atm_.p_mid, - dry_atm_.z_iface, elevated_emis_output); + VertEmissionsDataReader_[i], *VertEmissionsHorizInterp_[i], ts, + vert_emiss_time_state_, vert_emis_data_[i], dry_atm_.p_mid, + dry_atm_.z_iface, vert_emis_output); i++; Kokkos::fence(); } @@ -720,17 +706,10 @@ void MAMMicrophysics::run_impl(const double dt) { const auto zenith_angle = acos_cosine_zenith_; constexpr int gas_pcnst = mam_coupling::gas_pcnst(); -<<<<<<< HEAD - const auto& elevated_emis_output = elevated_emis_output_; - const auto& extfrc = extfrc_; - const auto& forcings = forcings_; - constexpr int extcnt = mam4::gas_chemistry::extcnt; -======= const auto &vert_emis_output = vert_emis_output_; const auto &extfrc = extfrc_; const auto &forcings = forcings_; constexpr int extcnt = mam4::gas_chemistry::extcnt; ->>>>>>> EAMxx: Clang format const int offset_aerosol = mam4::utils::gasses_start_ind(); Real adv_mass_kg_per_moles[gas_pcnst]; @@ -779,7 +758,7 @@ void MAMMicrophysics::run_impl(const double dt) { // We may need to move this line where we read files. forcings_in[i].file_alt_data = file_alt_data; for(int isec = 0; isec < forcings[i].nsectors; ++isec) { - const auto field = elevated_emis_output[isec + forcings[i].offset]; + const auto field = vert_emis_output[isec + forcings[i].offset]; forcings_in[i].fields_data[isec] = ekat::subview(field, icol); } } // extcnt for loop From 60a90e92b05069ab136fccbf464486eb7976b3e5 Mon Sep 17 00:00:00 2001 From: Michael J Schmidt Date: Fri, 15 Nov 2024 15:44:22 -0700 Subject: [PATCH 135/147] ff mam4xx to current main --- externals/mam4xx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/externals/mam4xx b/externals/mam4xx index d1c70ab972bc..e26b5b6faa5c 160000 --- a/externals/mam4xx +++ b/externals/mam4xx @@ -1 +1 @@ -Subproject commit d1c70ab972bc00269939fd3296d93a719f273105 +Subproject commit e26b5b6faa5cdf39a5421328165c49bdb728b038 From c8c4d6592bd32f88fd3c6bb23a41ebea566b591b Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Fri, 15 Nov 2024 15:54:39 -0800 Subject: [PATCH 136/147] EAMxx: Remove all diffs from microphysics cpp file --- ...mxx_mam_microphysics_process_interface.cpp | 131 ++++++++++-------- 1 file changed, 70 insertions(+), 61 deletions(-) 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 35f27e1db008..57eaf9275483 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 @@ -3,8 +3,8 @@ // impl namespace for some driver level functions for microphysics #include "readfiles/photo_table_utils.cpp" +#include "readfiles/find_season_index_utils.hpp" #include "physics/rrtmgp/shr_orb_mod_c2f.hpp" -#include "readfiles/photo_table_utils.cpp" namespace scream { @@ -36,7 +36,7 @@ MAMMicrophysics::MAMMicrophysics(const ekat::Comm &comm, config_.linoz.o3_lbl = m_params.get("mam4_o3_lbl"); config_.linoz.o3_tau = m_params.get("mam4_o3_tau"); config_.linoz.o3_sfc = m_params.get("mam4_o3_sfc"); - config_.linoz.psc_T = m_params.get("mam4_psc_T"); + config_.linoz.psc_T = m_params.get("mam4_psc_T"); } AtmosphereProcessType MAMMicrophysics::type() const { @@ -81,20 +81,19 @@ void MAMMicrophysics::set_grids( // ----------- Atmospheric quantities ------------- // Specific humidity [kg/kg](Require only for building DS) - add_tracer("qv", grid_, kg / kg); // specific humidity + add_tracer("qv", grid_, kg/kg); // specific humidity // Cloud liquid mass mixing ratio [kg/kg](Require only for building DS) - add_tracer("qc", grid_, kg / kg); // cloud liquid wet mixing ratio + add_tracer("qc", grid_, kg/kg); // cloud liquid wet mixing ratio // Cloud ice mass mixing ratio [kg/kg](Require only for building DS) - add_tracer("qi", grid_, kg / kg); // ice wet mixing ratio + add_tracer("qi", grid_, kg/kg); // ice wet mixing ratio // Cloud liquid number mixing ratio [1/kg](Require only for building DS) - add_tracer("nc", grid_, - n_unit); // cloud liquid wet number mixing ratio + add_tracer("nc", grid_, n_unit); // cloud liquid wet number mixing ratio // Cloud ice number mixing ratio [1/kg](Require only for building DS) - add_tracer("ni", grid_, n_unit); // ice number mixing ratio + add_tracer("ni", grid_, n_unit); // ice number mixing ratio // Temperature[K] at midpoints add_field("T_mid", scalar3d_mid, K, grid_name); @@ -162,7 +161,7 @@ void MAMMicrophysics::set_grids( mam_coupling::int_aero_mmr_field_name(m, a); if(strlen(int_mmr_field_name) > 0) { - add_tracer(int_mmr_field_name, grid_, kg / kg); + add_tracer(int_mmr_field_name, grid_, kg/kg); } } // for loop species } // for loop nmodes interstitial @@ -184,7 +183,7 @@ void MAMMicrophysics::set_grids( // aerosol-related gases: mass mixing ratios for(int g = 0; g < mam_coupling::num_aero_gases(); ++g) { const char *gas_mmr_field_name = mam_coupling::gas_mmr_field_name(g); - add_tracer(gas_mmr_field_name, grid_, kg / kg); + add_tracer(gas_mmr_field_name, grid_, kg/kg); } // Creating a Linoz reader and setting Linoz parameters involves reading data @@ -207,7 +206,7 @@ void MAMMicrophysics::set_grids( LinozHorizInterp_, linoz_file_name_); // linoz reader - const auto io_grid_linoz = LinozHorizInterp_->get_src_grid(); + const auto io_grid_linoz = LinozHorizInterp_->get_tgt_grid(); const int num_cols_io_linoz = io_grid_linoz->get_num_local_dofs(); // Number of columns on this rank const int num_levs_io_linoz = @@ -235,7 +234,7 @@ void MAMMicrophysics::set_grids( TracerHorizInterp_, oxid_file_name_); const int nvars = int(var_names.size()); - const auto io_grid = TracerHorizInterp_->get_src_grid(); + const auto io_grid = TracerHorizInterp_->get_tgt_grid(); const int num_cols_io = io_grid->get_num_local_dofs(); // Number of columns on this rank const int num_levs_io = @@ -260,78 +259,88 @@ void MAMMicrophysics::set_grids( "num_a1", "num_a2", "num_a4", "soag"}; for(const auto &var_name : extfrc_lst_) { - std::string item_name = "mam4_" + var_name + "_verti_emiss_file_name"; + std::string item_name = "mam4_" + var_name + "_elevated_emiss_file_name"; const auto file_name = m_params.get(item_name); - vert_emis_file_name_[var_name] = file_name; + elevated_emis_file_name_[var_name] = file_name; } - vert_emis_var_names_["so2"] = {"BB", "ENE_ELEV", "IND_ELEV", "contvolc"}; - vert_emis_var_names_["so4_a1"] = {"BB", "ENE_ELEV", "IND_ELEV", "contvolc"}; - vert_emis_var_names_["so4_a2"] = {"contvolc"}; - vert_emis_var_names_["pom_a4"] = {"BB"}; - vert_emis_var_names_["bc_a4"] = {"BB"}; - vert_emis_var_names_["num_a1"] = { + elevated_emis_var_names_["so2"] = {"BB", "ENE_ELEV", "IND_ELEV", "contvolc"}; + elevated_emis_var_names_["so4_a1"] = {"BB", "ENE_ELEV", "IND_ELEV", "contvolc"}; + elevated_emis_var_names_["so4_a2"] = {"contvolc"}; + elevated_emis_var_names_["pom_a4"] = {"BB"}; + elevated_emis_var_names_["bc_a4"] = {"BB"}; + elevated_emis_var_names_["num_a1"] = { "num_a1_SO4_ELEV_BB", "num_a1_SO4_ELEV_ENE", "num_a1_SO4_ELEV_IND", "num_a1_SO4_ELEV_contvolc"}; - vert_emis_var_names_["num_a2"] = {"num_a2_SO4_ELEV_contvolc"}; + elevated_emis_var_names_["num_a2"] = {"num_a2_SO4_ELEV_contvolc"}; // num_a4 // FIXME: why the sectors in this files are num_a1; // I guess this should be num_a4? Is this a bug in the orginal nc files? - vert_emis_var_names_["num_a4"] = {"num_a1_BC_ELEV_BB", + elevated_emis_var_names_["num_a4"] = {"num_a1_BC_ELEV_BB", "num_a1_POM_ELEV_BB"}; - vert_emis_var_names_["soag"] = {"SOAbb_src", "SOAbg_src", "SOAff_src"}; + elevated_emis_var_names_["soag"] = {"SOAbb_src", "SOAbg_src", "SOAff_src"}; - int verti_emiss_cyclical_ymd = m_params.get("verti_emiss_ymd"); + int elevated_emiss_cyclical_ymd = m_params.get("elevated_emiss_ymd"); for(const auto &var_name : extfrc_lst_) { - const auto file_name = vert_emis_file_name_[var_name]; - const auto var_names = vert_emis_var_names_[var_name]; + const auto file_name = elevated_emis_file_name_[var_name]; + const auto var_names = elevated_emis_var_names_[var_name]; scream::mam_coupling::TracerData data_tracer; scream::mam_coupling::setup_tracer_data(data_tracer, file_name, - verti_emiss_cyclical_ymd); + elevated_emiss_cyclical_ymd); auto hor_rem = scream::mam_coupling::create_horiz_remapper( grid_, file_name, extfrc_map_file, var_names, data_tracer); + auto file_reader = - scream::mam_coupling::create_tracer_data_reader(hor_rem, file_name); - VertEmissionsHorizInterp_.push_back(hor_rem); - VertEmissionsDataReader_.push_back(file_reader); - vert_emis_data_.push_back(data_tracer); - } // var_name vert emissions + scream::mam_coupling::create_tracer_data_reader(hor_rem, file_name, + data_tracer.file_type); + ElevatedEmissionsHorizInterp_.push_back(hor_rem); + ElevatedEmissionsDataReader_.push_back(file_reader); + elevated_emis_data_.push_back(data_tracer); + } // var_name elevated emissions int i = 0; int offset_emis_ver = 0; for(const auto &var_name : extfrc_lst_) { - const auto file_name = vert_emis_file_name_[var_name]; - const auto var_names = vert_emis_var_names_[var_name]; + const auto file_name = elevated_emis_file_name_[var_name]; + const auto var_names = elevated_emis_var_names_[var_name]; const int nvars = static_cast(var_names.size()); forcings_[i].nsectors = nvars; // I am assuming the order of species in extfrc_lst_. // Indexing in mam4xx is fortran. forcings_[i].frc_ndx = i + 1; - const auto io_grid_emis = VertEmissionsHorizInterp_[i]->get_src_grid(); + const auto io_grid_emis = ElevatedEmissionsHorizInterp_[i]->get_tgt_grid(); const int num_cols_io_emis = io_grid_emis->get_num_local_dofs(); // Number of columns on this rank const int num_levs_io_emis = io_grid_emis ->get_num_vertical_levels(); // Number of levels per column - vert_emis_data_[i].init(num_cols_io_emis, num_levs_io_emis, nvars); - vert_emis_data_[i].allocate_temporal_views(); - forcings_[i].file_alt_data = vert_emis_data_[i].has_altitude_; + elevated_emis_data_[i].init(num_cols_io_emis, num_levs_io_emis, nvars); + elevated_emis_data_[i].allocate_temporal_views(); + forcings_[i].file_alt_data = elevated_emis_data_[i].has_altitude_; for(int isp = 0; isp < nvars; ++isp) { forcings_[i].offset = offset_emis_ver; - vert_emis_output_[isp + offset_emis_ver] = - view_2d("vert_emis_output_", ncol_, nlev_); + elevated_emis_output_[isp + offset_emis_ver] = + view_2d("elevated_emis_output_", ncol_, nlev_); } offset_emis_ver += nvars; ++i; } // end i EKAT_REQUIRE_MSG( - offset_emis_ver <= int(mam_coupling::MAX_NUM_VERT_EMISSION_FIELDS), + offset_emis_ver <= int(mam_coupling::MAX_NUM_ELEVATED_EMISSIONS_FIELDS), "Error! Number of fields is bigger than " - "MAX_NUM_VERT_EMISSION_FIELDS. Increase the " - "MAX_NUM_VERT_EMISSION_FIELDS in tracer_reader_utils.hpp \n"); + "MAX_NUM_ELEVATED_EMISSIONS_FIELDS. Increase the " + "MAX_NUM_ELEVATED_EMISSIONS_FIELDS in tracer_reader_utils.hpp \n"); } // Tracer external forcing data + + { + const std::string season_wes_file = m_params.get("mam4_season_wes_file"); + const auto& clat = col_latitudes_; + mam_coupling::find_season_index_reader(season_wes_file, + clat, + index_season_lai_); + } } // set_grids // ================================================================ @@ -520,8 +529,8 @@ void MAMMicrophysics::initialize_impl(const RunType run_type) { for(int i = 0; i < static_cast(extfrc_lst_.size()); ++i) { scream::mam_coupling::update_tracer_data_from_file( - VertEmissionsDataReader_[i], curr_month, *VertEmissionsHorizInterp_[i], - vert_emis_data_[i]); + ElevatedEmissionsDataReader_[i], curr_month, *ElevatedEmissionsHorizInterp_[i], + elevated_emis_data_[i]); } invariants_ = view_3d("invarians", ncol_, nlev_, mam4::gas_chemistry::nfs); @@ -618,20 +627,20 @@ void MAMMicrophysics::run_impl(const double dt) { linoz_output); // out Kokkos::fence(); - vert_emiss_time_state_.t_now = ts.frac_of_year_in_days(); + elevated_emiss_time_state_.t_now = ts.frac_of_year_in_days(); int i = 0; for(const auto &var_name : extfrc_lst_) { - const auto file_name = vert_emis_file_name_[var_name]; - const auto var_names = vert_emis_var_names_[var_name]; + const auto file_name = elevated_emis_file_name_[var_name]; + const auto var_names = elevated_emis_var_names_[var_name]; const int nsectors = int(var_names.size()); - view_2d vert_emis_output[nsectors]; + view_2d elevated_emis_output[nsectors]; for(int isp = 0; isp < nsectors; ++isp) { - vert_emis_output[isp] = vert_emis_output_[isp + forcings_[i].offset]; + elevated_emis_output[isp] = elevated_emis_output_[isp + forcings_[i].offset]; } scream::mam_coupling::advance_tracer_data( - VertEmissionsDataReader_[i], *VertEmissionsHorizInterp_[i], ts, - vert_emiss_time_state_, vert_emis_data_[i], dry_atm_.p_mid, - dry_atm_.z_iface, vert_emis_output); + ElevatedEmissionsDataReader_[i], *ElevatedEmissionsHorizInterp_[i], ts, + elevated_emiss_time_state_, elevated_emis_data_[i], dry_atm_.p_mid, + dry_atm_.z_iface, elevated_emis_output); i++; Kokkos::fence(); } @@ -706,10 +715,10 @@ void MAMMicrophysics::run_impl(const double dt) { const auto zenith_angle = acos_cosine_zenith_; constexpr int gas_pcnst = mam_coupling::gas_pcnst(); - const auto &vert_emis_output = vert_emis_output_; - const auto &extfrc = extfrc_; - const auto &forcings = forcings_; - constexpr int extcnt = mam4::gas_chemistry::extcnt; + const auto& elevated_emis_output = elevated_emis_output_; + const auto& extfrc = extfrc_; + const auto& forcings = forcings_; + constexpr int extcnt = mam4::gas_chemistry::extcnt; const int offset_aerosol = mam4::utils::gasses_start_ind(); Real adv_mass_kg_per_moles[gas_pcnst]; @@ -758,7 +767,7 @@ void MAMMicrophysics::run_impl(const double dt) { // We may need to move this line where we read files. forcings_in[i].file_alt_data = file_alt_data; for(int isec = 0; isec < forcings[i].nsectors; ++isec) { - const auto field = vert_emis_output[isec + forcings[i].offset]; + const auto field = elevated_emis_output[isec + forcings[i].offset]; forcings_in[i].fields_data[isec] = ekat::subview(field, icol); } } // extcnt for loop @@ -800,9 +809,9 @@ void MAMMicrophysics::run_impl(const double dt) { linoz_o3col_clim_icol, linoz_PmL_clim_icol, linoz_dPmL_dO3_icol, linoz_dPmL_dT_icol, linoz_dPmL_dO3col_icol, linoz_cariolle_pscs_icol, eccf, adv_mass_kg_per_moles, clsmap_4, - permute_4, offset_aerosol, config.linoz.o3_sfc, config.linoz.o3_tau, - config.linoz.o3_lbl, dry_diameter_icol, wet_diameter_icol, - wetdens_icol); + permute_4, offset_aerosol, + config.linoz.o3_sfc, config.linoz.o3_tau, config.linoz.o3_lbl, + dry_diameter_icol, wet_diameter_icol, wetdens_icol); }); // parallel_for for the column loop Kokkos::fence(); From e02b76cdf93a8c1ce09e06b9fbfa26de3856ae73 Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Fri, 15 Nov 2024 20:18:34 -0800 Subject: [PATCH 137/147] EAMxx: Adds missing namelist entries for multi process test --- .../input.yaml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) 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 55c62d69aa24..48045295050b 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 @@ -23,7 +23,9 @@ atmosphere_processes: srf_emis_specifier_for_pom_a4: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/surface/cmip6_mam4_pom_a4_surf_ne2np4_2010_clim_c20240726.nc srf_emis_specifier_for_so4_a1: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/surface/cmip6_mam4_so4_a1_surf_ne2np4_2010_clim_c20240726.nc srf_emis_specifier_for_so4_a2: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/surface/cmip6_mam4_so4_a2_surf_ne2np4_2010_clim_c20240726.nc - + + soil_erodibility_file: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/dst_ne2np4_c20241028.nc + marine_organics_file: ${SCREAM_DATA_DIR}/mam4xx/emissions/ne2np4/monthly_macromolecules_0.1deg_bilinear_year01_merge_ne2np4_c20241030.nc grids_manager: Type: Mesh Free geo_data_source: IC_FILE @@ -40,6 +42,13 @@ initial_conditions: topography_filename: ${TOPO_DATA_DIR}/${EAMxx_tests_TOPO_FILE} pbl_height: 0.0 + dstflx : 0.0 + ocnfrac: 0.10000000000000000E+001 + sst: 0.30178553874977507E+003 + cldfrac_tot: 0.138584624960092 + horiz_winds: [-0.24988988196194634E+000, -0.23959782871450760E+000] + constituent_fluxes: 0.0 + # The parameters for I/O control Scorpio: From 71e4bc5059aebad00c8c7ae82309422b4fc1cb06 Mon Sep 17 00:00:00 2001 From: Balwinder Singh Date: Sat, 16 Nov 2024 10:59:15 -0800 Subject: [PATCH 138/147] EAMxx: Moves fences into the interface and remove extra comments --- components/eamxx/cime_config/namelist_defaults_scream.xml | 5 ----- .../mam/eamxx_mam_srf_and_online_emissions_functions.hpp | 3 --- .../eamxx_mam_srf_and_online_emissions_process_interface.cpp | 5 ++--- 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/components/eamxx/cime_config/namelist_defaults_scream.xml b/components/eamxx/cime_config/namelist_defaults_scream.xml index d23169173ce4..771928a81226 100644 --- a/components/eamxx/cime_config/namelist_defaults_scream.xml +++ b/components/eamxx/cime_config/namelist_defaults_scream.xml @@ -372,15 +372,10 @@ be lost if SCREAM_HACK_XML is not enabled. ${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/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 diff --git a/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_functions.hpp b/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_functions.hpp index c1414d2077ff..9c01daf8223c 100644 --- a/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_functions.hpp +++ b/components/eamxx/src/physics/mam/eamxx_mam_srf_and_online_emissions_functions.hpp @@ -33,7 +33,6 @@ void init_fluxes(const int &ncol, Kokkos::TeamVectorRange(team, gas_start_ind, pcnst), [&](int icnst) { flux_col(icnst) = 0; }); }); - Kokkos::fence(); } // init_fluxes ends //-------- compute online emissions for dust, sea salt and marine organics ----- @@ -66,8 +65,6 @@ void compute_online_dust_nacl_emiss( // out fluxes_col); }); - Kokkos::fence(); - } // compute_online_dust_nacl_emiss ends } // namespace 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 58a1c341fa54..fd3ebf79700f 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 @@ -421,7 +421,7 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { // Zero out constituent fluxes only for gasses and aerosols init_fluxes(ncol_, // in constituent_fluxes); // in-out - + Kokkos::fence(); // Gather time and state information for interpolation const auto ts = timestamp() + dt; @@ -429,8 +429,6 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { // Online emissions from dust and sea salt //-------------------------------------------------------------------- - // compute_online_dust_nacl_emiss(); - // --- Interpolate marine organics data -- // Update TimeState, note the addition of dt @@ -480,6 +478,7 @@ void MAMSrfOnlineEmiss::run_impl(const double dt) { z_mid, // output constituent_fluxes); + Kokkos::fence(); //-------------------------------------------------------------------- // Interpolate srf emiss data read in from emissions files //-------------------------------------------------------------------- From b9333f513e64a92ed275d022f8ae650656b53b86 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 16:51:43 +0000 Subject: [PATCH 139/147] Bump DavidAnson/markdownlint-cli2-action from 17 to 18 Bumps [DavidAnson/markdownlint-cli2-action](https://github.com/davidanson/markdownlint-cli2-action) from 17 to 18. - [Release notes](https://github.com/davidanson/markdownlint-cli2-action/releases) - [Commits](https://github.com/davidanson/markdownlint-cli2-action/compare/v17...v18) --- updated-dependencies: - dependency-name: DavidAnson/markdownlint-cli2-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/e3sm-gh-md-linter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e3sm-gh-md-linter.yml b/.github/workflows/e3sm-gh-md-linter.yml index 46319b08658b..ad24487695e2 100644 --- a/.github/workflows/e3sm-gh-md-linter.yml +++ b/.github/workflows/e3sm-gh-md-linter.yml @@ -27,7 +27,7 @@ jobs: with: files: '**/*.md' separator: "," - - uses: DavidAnson/markdownlint-cli2-action@v17 + - uses: DavidAnson/markdownlint-cli2-action@v18 if: steps.changed-files.outputs.any_changed == 'true' with: config: 'docs/.markdownlint.json' From d0f2a5058196c6b984f89c537709f1794d7e37da Mon Sep 17 00:00:00 2001 From: Oscar Diaz-Ibarra Date: Mon, 18 Nov 2024 17:33:01 -0700 Subject: [PATCH 140/147] EAMxx: Modify microphysics interface to include sethet (washout rates) computations. --- ...mxx_mam_microphysics_process_interface.cpp | 32 ++++++++++++++++++- ...mxx_mam_microphysics_process_interface.hpp | 3 ++ .../mam/aero_microphys/input.yaml | 3 +- externals/mam4xx | 2 +- 4 files changed, 37 insertions(+), 3 deletions(-) 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 57eaf9275483..4a674fb094d3 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 @@ -146,6 +146,15 @@ void MAMMicrophysics::set_grids( // surface albedo shortwave, direct add_field("sfc_alb_dir_vis", scalar2d, nondim, grid_name); + //----------- Variables from microphysics scheme ------------- + + // Evaporation from stratiform rain [kg/kg/s] + add_field("nevapr", scalar3d_mid, kg / kg / s, grid_name); + + // Stratiform rain production rate [kg/kg/s] + add_field("precip_total_tend", scalar3d_mid, kg / kg / s, + grid_name); + // --------------------------------------------------------------------- // These variables are "updated" or inputs/outputs for the process // --------------------------------------------------------------------- @@ -512,6 +521,9 @@ void MAMMicrophysics::initialize_impl(const RunType run_type) { const int photo_table_len = get_photo_table_work_len(photo_table_); work_photo_table_ = view_2d("work_photo_table", ncol_, photo_table_len); + const int sethet_work_len = mam4::mo_sethet::get_total_work_len_sethet(); + work_set_het_ = view_2d("work_set_het_array", ncol_, sethet_work_len); + cmfdqr_ = view_1d("cmfdqr_", nlev_); // here's where we store per-column photolysis rates photo_rates_ = view_3d("photo_rates", ncol_, nlev_, mam4::mo_photo::phtcnt); @@ -565,6 +577,14 @@ void MAMMicrophysics::run_impl(const double dt) { Kokkos::parallel_for("preprocess", scan_policy, preprocess_); Kokkos::fence(); + //----------- Variables from microphysics scheme ------------- + + // Evaporation from stratiform rain [kg/kg/s] + const auto& nevapr = get_field_in("nevapr").get_view(); + + // Stratiform rain production rate [kg/kg/s] + const auto& prain = get_field_in("precip_total_tend").get_view(); + const auto wet_geometric_mean_diameter_i = get_field_in("dgnumwet").get_view(); const auto dry_geometric_mean_diameter_i = @@ -733,6 +753,8 @@ void MAMMicrophysics::run_impl(const double dt) { clsmap_4[i] = mam4::gas_chemistry::clsmap_4[i]; permute_4[i] = mam4::gas_chemistry::permute_4[i]; } + const auto& cmfdqr = cmfdqr_; + const auto& work_set_het =work_set_het_; // loop over atmosphere columns and compute aerosol microphyscs Kokkos::parallel_for( policy, KOKKOS_LAMBDA(const ThreadTeam &team) { @@ -798,6 +820,9 @@ void MAMMicrophysics::run_impl(const double dt) { ekat::subview(linoz_dPmL_dO3col, icol); const auto linoz_cariolle_pscs_icol = ekat::subview(linoz_cariolle_pscs, icol); + const auto nevapr_icol = ekat::subview(nevapr, icol); + const auto prain_icol = ekat::subview(prain, icol); + const auto work_set_het_icol = ekat::subview(work_set_het, icol); // Note: All variables are inputs, except for progs, which is an // input/output variable. mam4::microphysics::perform_atmospheric_chemistry_and_microphysics( @@ -811,7 +836,12 @@ void MAMMicrophysics::run_impl(const double dt) { linoz_cariolle_pscs_icol, eccf, adv_mass_kg_per_moles, clsmap_4, permute_4, offset_aerosol, config.linoz.o3_sfc, config.linoz.o3_tau, config.linoz.o3_lbl, - dry_diameter_icol, wet_diameter_icol, wetdens_icol); + dry_diameter_icol, wet_diameter_icol, wetdens_icol, + dry_atm.phis(icol), + cmfdqr, + prain_icol, + nevapr_icol, + work_set_het_icol); }); // parallel_for for the column loop Kokkos::fence(); diff --git a/components/eamxx/src/physics/mam/eamxx_mam_microphysics_process_interface.hpp b/components/eamxx/src/physics/mam/eamxx_mam_microphysics_process_interface.hpp index d555fe820242..6ff846d0d0c2 100644 --- a/components/eamxx/src/physics/mam/eamxx_mam_microphysics_process_interface.hpp +++ b/components/eamxx/src/physics/mam/eamxx_mam_microphysics_process_interface.hpp @@ -242,6 +242,9 @@ class MAMMicrophysics final : public scream::AtmosphereProcess { view_1d acos_cosine_zenith_; view_int_2d index_season_lai_; + // // dq/dt for convection [kg/kg/s] + view_1d cmfdqr_; + view_2d work_set_het_; }; // MAMMicrophysics diff --git a/components/eamxx/tests/single-process/mam/aero_microphys/input.yaml b/components/eamxx/tests/single-process/mam/aero_microphys/input.yaml index 9348a04a21d9..7dd28a87f478 100644 --- a/components/eamxx/tests/single-process/mam/aero_microphys/input.yaml +++ b/components/eamxx/tests/single-process/mam/aero_microphys/input.yaml @@ -58,7 +58,8 @@ initial_conditions: dgnum: [1.246662106183775E-007, 4.081134799487888E-008, 1.103139143795796E-006, 1.000000011686097E-007] dgnumwet: [2.367209731605067E-007, 6.780643470563889E-008, 3.028011448344027E-006, 1.000000096285154E-007] wetdens: [1038.67760516297, 1046.20002003441, 1031.74623165457, 1086.79731859184] - + nevapr: 0.0 + precip_total_tend: 0.0 # The parameters for I/O control Scorpio: output_yaml_files: ["output.yaml"] diff --git a/externals/mam4xx b/externals/mam4xx index e26b5b6faa5c..7d7a4a673a1f 160000 --- a/externals/mam4xx +++ b/externals/mam4xx @@ -1 +1 @@ -Subproject commit e26b5b6faa5cdf39a5421328165c49bdb728b038 +Subproject commit 7d7a4a673a1f2709986b62c6490c8414829c5212 From 00d55a053819a5ce3b2e13d534f004f9b07fb49a Mon Sep 17 00:00:00 2001 From: Oscar Diaz-Ibarra Date: Tue, 19 Nov 2024 11:07:44 -0700 Subject: [PATCH 141/147] EAMxx: Update mam4xx submodule to fix CUDA test. --- externals/mam4xx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/externals/mam4xx b/externals/mam4xx index 7d7a4a673a1f..fdbb0816c5c0 160000 --- a/externals/mam4xx +++ b/externals/mam4xx @@ -1 +1 @@ -Subproject commit 7d7a4a673a1f2709986b62c6490c8414829c5212 +Subproject commit fdbb0816c5c0c541265ec17f544908da935d8af6 From 2b50dbbed5730efe7819fa2845b35afd841ad464 Mon Sep 17 00:00:00 2001 From: Aaron Donahue Date: Fri, 8 Nov 2024 14:21:04 -0800 Subject: [PATCH 142/147] Add standard name metadata to most EAMxx output variables This commit brings EAMxx into CF-Compliance by adding `standard_name` metadata for a subset of the EAMxx output variables that have one. --- .../eamxx/src/share/io/scorpio_output.cpp | 8 +- .../eamxx/src/share/io/scorpio_output.hpp | 2 +- .../eamxx/src/share/io/scream_io_utils.hpp | 84 ++++++++++++++++++- 3 files changed, 91 insertions(+), 3 deletions(-) diff --git a/components/eamxx/src/share/io/scorpio_output.cpp b/components/eamxx/src/share/io/scorpio_output.cpp index 87fe9af7133e..e8f322b85f32 100644 --- a/components/eamxx/src/share/io/scorpio_output.cpp +++ b/components/eamxx/src/share/io/scorpio_output.cpp @@ -1044,9 +1044,15 @@ register_variables(const std::string& filename, // Gather longname (if not already in the io: string attributes) if (str_atts.count("long_name")==0) { - auto longname = m_longnames.get_longname(name); + auto longname = m_default_metadata.get_longname(name); scorpio::set_attribute(filename, name, "long_name", longname); } + + // Gather standard name, CF-Compliant (if not already in the io: string attributes) + if (str_atts.count("standard_name")==0) { + auto standardname = m_default_metadata.get_standardname(name); + scorpio::set_attribute(filename, name, "standard_name", standardname); + } } } // Now register the average count variables diff --git a/components/eamxx/src/share/io/scorpio_output.hpp b/components/eamxx/src/share/io/scorpio_output.hpp index 2cb45f28a322..696e08c99827 100644 --- a/components/eamxx/src/share/io/scorpio_output.hpp +++ b/components/eamxx/src/share/io/scorpio_output.hpp @@ -206,7 +206,7 @@ class AtmosphereOutput std::map> m_diagnostics; std::map> m_diag_depends_on_diags; std::map m_diag_computed; - LongNames m_longnames; + DefaultMetadata m_default_metadata; // Use float, so that if output fp_precision=float, this is a representable value. // Otherwise, you would get an error from Netcdf, like diff --git a/components/eamxx/src/share/io/scream_io_utils.hpp b/components/eamxx/src/share/io/scream_io_utils.hpp index d6c36ab37583..796ecd2a003b 100644 --- a/components/eamxx/src/share/io/scream_io_utils.hpp +++ b/components/eamxx/src/share/io/scream_io_utils.hpp @@ -72,7 +72,7 @@ std::string find_filename_in_rpointer ( const OutputAvgType avg_type = OutputAvgType::Instant, const IOControl& control = {}); -struct LongNames { +struct DefaultMetadata { std::string get_longname (const std::string& name) { if (name_2_longname.count(name)>0) { @@ -83,6 +83,15 @@ struct LongNames { } } + std::string get_standardname (const std::string& name) { + if (name_2_standardname.count(name)>0) { + return name_2_standardname.at(name); + } else { + // TODO: Do we want to print a Warning message? I'm not sure if its needed. + return name; + } + } + // Create map of longnames, can be added to as developers see fit. std::map name_2_longname = { {"lev","hybrid level at midpoints (1000*(A+B))"}, @@ -92,6 +101,79 @@ struct LongNames { {"hyam","hybrid A coefficient at layer midpoints"}, {"hybm","hybrid B coefficient at layer midpoints"} }; + + // Create map of longnames, can be added to as developers see fit. + std::map name_2_standardname = { + {"p_mid" , "air_pressure"}, + {"p_mid_at_cldtop" , "air_pressure_at_cloud_top"}, + {"T_2m" , "air_temperature"}, + {"T_mid" , "air_temperature"}, + {"T_mid_at_cldtop" , "air_temperature_at_cloud_top"}, + {"aero_g_sw" , "asymmetry_factor_of_ambient_aerosol_particles"}, + {"pbl_height" , "atmosphere_boundary_layer_thickness"}, + {"precip_liq_surf_mass" , "atmosphere_mass_content_of_liquid_precipitation"}, + {"cldlow" , "cloud_area_fraction"}, + {"cldmed" , "cloud_area_fraction"}, + {"cldhgh" , "cloud_area_fraction"}, + {"cldtot" , "cloud_area_fraction"}, + {"cldfrac_tot_at_cldtop" , "cloud_area_fraction"}, + {"cldfrac_tot" , "cloud_area_fraction_in_atmosphere_layer"}, + {"cldfrac_tot_for_analysis" , "cloud_area_fraction_in_atmosphere_layer"}, + {"cldfrac_rad" , "cloud_area_fraction_in_atmosphere_layer"}, + {"qi" , "cloud_ice_mixing_ratio"}, + {"qc" , "cloud_liquid_water_mixing_ratio"}, + {"U" , "eastward_wind"}, + {"eff_radius_qi" , "effective_radius_of_cloud_ice_particles"}, + {"eff_radius_qc" , "effective_radius_of_cloud_liquid_water_particles"}, + {"eff_radius_qc_at_cldtop" , "effective_radius_of_cloud_liquid_water_particles_at_liquid_water_cloud_top"}, + {"eff_radius_qr" , "effective_radius_of_cloud_rain_particles"}, + {"qv" , "humidity_mixing_ratio"}, + {"cldfrac_ice_at_cldtop" , "ice_cloud_area_fraction"}, + {"cldfrac_ice" , "ice_cloud_area_fraction_in_atmosphere_layer"}, + {"omega" , "lagrangian_tendency_of_air_pressure"}, + {"landfrac" , "land_area_fraction"}, + {"latitude" , "latitude"}, + {"cldfrac_liq_at_cldtop" , "liquid_water_cloud_area_fraction"}, + {"cldfrac_liq" , "liquid_water_cloud_area_fraction_in_atmosphere_layer"}, + {"longitude" , "longitude"}, + {"rainfrac" , "mass_fraction_of_liquid_precipitation_in_air"}, + {"V" , "northward_wind"}, + {"nc" , "number_concentration_of_cloud_liquid_water_particles_in_air"}, + {"cdnc_at_cldtop" , "number_concentration_of_cloud_liquid_water_particles_in_air_at_liquid_water_cloud_top"}, + {"ni" , "number_concentration_of_ice_crystals_in_air"}, + {"aero_tau_sw" , "optical_thickness_of_atmosphere_layer_due_to_ambient_aerosol_particles"}, + {"aero_tau_lw" , "optical_thickness_of_atmosphere_layer_due_to_ambient_aerosol_particles"}, + {"aero_ssa_sw" , "single_scattering_albedo_in_air_due_to_ambient_aerosol_particles"}, + {"sunlit" , "sunlit_binary_mask"}, + {"ps" , "surface_air_pressure"}, + {"LW_flux_dn_at_model_bot" , "surface_downwelling_longwave_flux_in_air"}, + {"SW_flux_dn_at_model_bot" , "surface_downwelling_shortwave_flux_in_air"}, + {"SW_clrsky_flux_dn_at_model_bot" , "surface_downwelling_shortwave_flux_in_air_assuming_clear_sky"}, + {"phis" , "surface_geopotential"}, + {"surf_radiative_T" , "surface_temperature"}, + {"surf_sens_flux" , "surface_upward_sensible_heat_flux"}, + {"SW_flux_dn_at_model_top" , "toa_incoming_shortwave_flux"}, + {"LW_flux_up_at_model_top" , "toa_outgoing_longwave_flux"}, + {"LW_clrsky_flux_up_at_model_top" , "toa_outgoing_longwave_flux_assuming_clear_sky"}, + {"surf_evap" , "water_evapotranspiration_flux"}, + {"AtmosphereDensity" , "air_density"}, + {"PotentialTemperature" , "air_potential_temperature"}, + {"SeaLevelPressure" , "air_pressure_at_mean_sea_level"}, + {"IceWaterPath" , "atmosphere_mass_content_of_cloud_ice"}, + {"LiqWaterPath" , "atmosphere_mass_content_of_cloud_liquid_water"}, + {"VapWaterPath" , "atmosphere_mass_content_of_water_vapor"}, + {"AerosolOpticalDepth550nm" , "atmosphere_optical_thickness_due_to_ambient_aerosol_particles"}, + {"Exner" , "dimensionless_exner_function"}, + {"z_mid" , "geopotential_height"}, + {"geopotential_mid" , "geopotential_height"}, + {"RelativeHumidity" , "relative_humidity"}, + {"surface_upward_latent_heat_flux" , "surface_upward_latent_heat_flux"}, + {"LongwaveCloudForcing" , "toa_longwave_cloud_radiative_effect"}, + {"ShortwaveCloudForcing" , "toa_shortwave_cloud_radiative_effect"}, + {"VirtualTemperature" , "virtual_temperature"}, + {"VaporFlux" , "water_evapotranspiration_flux"}, + {"wind_speed" , "wind_speed"} + }; }; From d44a616970c21cc26bc58b04b272d2c3cb19bb69 Mon Sep 17 00:00:00 2001 From: AaronDonahue Date: Mon, 11 Nov 2024 17:57:56 -0700 Subject: [PATCH 143/147] fix standard names for low/med/hgh cloud area fraction types --- components/eamxx/src/share/io/scream_io_utils.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/eamxx/src/share/io/scream_io_utils.hpp b/components/eamxx/src/share/io/scream_io_utils.hpp index 796ecd2a003b..9eda82e2bbd3 100644 --- a/components/eamxx/src/share/io/scream_io_utils.hpp +++ b/components/eamxx/src/share/io/scream_io_utils.hpp @@ -112,9 +112,9 @@ struct DefaultMetadata { {"aero_g_sw" , "asymmetry_factor_of_ambient_aerosol_particles"}, {"pbl_height" , "atmosphere_boundary_layer_thickness"}, {"precip_liq_surf_mass" , "atmosphere_mass_content_of_liquid_precipitation"}, - {"cldlow" , "cloud_area_fraction"}, - {"cldmed" , "cloud_area_fraction"}, - {"cldhgh" , "cloud_area_fraction"}, + {"cldlow" , "low_type_cloud_area_fraction"}, + {"cldmed" , "medium_type_cloud_area_fraction"}, + {"cldhgh" , "high_type_cloud_area_fraction"}, {"cldtot" , "cloud_area_fraction"}, {"cldfrac_tot_at_cldtop" , "cloud_area_fraction"}, {"cldfrac_tot" , "cloud_area_fraction_in_atmosphere_layer"}, From af3343b7e0681cc0e392d798b7be3ab261ca5467 Mon Sep 17 00:00:00 2001 From: Oscar Diaz-Ibarra Date: Tue, 19 Nov 2024 19:40:56 -0700 Subject: [PATCH 144/147] EAMxx: Add aerosols and gases outputs to ensure the microscopy baseline test is sensitive to changes in the interface. --- .../mam/aero_microphys/output.yaml | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/components/eamxx/tests/single-process/mam/aero_microphys/output.yaml b/components/eamxx/tests/single-process/mam/aero_microphys/output.yaml index 388781fb8f0b..5af90cac5479 100644 --- a/components/eamxx/tests/single-process/mam/aero_microphys/output.yaml +++ b/components/eamxx/tests/single-process/mam/aero_microphys/output.yaml @@ -6,6 +6,62 @@ Fields: Physics: Field Names: - T_mid + - O3 + - H2O2 + - H2SO4 + - SO2 + - DMS + - SOAG + - 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 # To save these fields make sure to turn on # OUTPUT_TRACER_FIELDS #- oxi_fields From 1df5b172c4e2cf671f17858eae701bdf60a8b277 Mon Sep 17 00:00:00 2001 From: Luca Bertagna Date: Wed, 20 Nov 2024 15:04:27 -0700 Subject: [PATCH 145/147] Mergify: dismiss reviews when new commits are pushed --- .mergify.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.mergify.yml b/.mergify.yml index 9c2b8fe13f1a..89fcc821e57a 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -31,6 +31,12 @@ merge_protections: - check-skipped=cpu-gcc pull_request_rules: + - name: dismiss stale reviews + conditions: + - base=master + actions: + dismiss_reviews: + when: synchronize # Dismiss reviews when synchronize event happens - name: Automatic merge when CI passes and approved conditions: - "label=CI: automerge" From 0d3b7da72c3694ec612ed80cf1e7cc398f6efb50 Mon Sep 17 00:00:00 2001 From: Luca Bertagna Date: Thu, 21 Nov 2024 17:02:50 -0700 Subject: [PATCH 146/147] Workflows: simplified and fixed eamxx workflow files * Remove pre_process_pr jobs, in favor of paths filters * Remove support for skip labels * Simplified setting of env vars (e.g., submit/generate) --- .github/workflows/eamxx-sa-testing.yml | 118 ++++------------------ .github/workflows/eamxx-scripts-tests.yml | 65 +----------- .github/workflows/eamxx-v1-testing.yml | 106 +++++-------------- 3 files changed, 48 insertions(+), 241 deletions(-) diff --git a/.github/workflows/eamxx-sa-testing.yml b/.github/workflows/eamxx-sa-testing.yml index a4397d4fdba3..e3657266cb64 100644 --- a/.github/workflows/eamxx-sa-testing.yml +++ b/.github/workflows/eamxx-sa-testing.yml @@ -5,6 +5,17 @@ on: pull_request: branches: [ master ] types: [opened, synchronize, ready_for_review, reopened] + paths: + # first, yes to these + - '.github/workflows/eamxx-sa-testing.yml' + - 'cime_config/machine/config_machines.xml' + - 'components/eamxx/**' + - 'components/homme/**' + - 'externals/ekat' + - 'externals/scorpio' + # second, no to these + - '!components/eamxx/docs/**' + - '!components/eamxx/mkdocs.yml' # Manual run is used to bless workflow_dispatch: @@ -40,83 +51,18 @@ concurrency: env: # Submit to cdash only for nightlies or if the user explicitly forced a submission via workflow dispatch submit: ${{ github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.submit) }} + generate: ${{ github.event_name == 'workflow_dispatch' && inputs.bless }} jobs: - pre_process_pr: - if: ${{ github.event_name == 'pull_request' }} - runs-on: ubuntu-latest # This job can run anywhere - outputs: - relevant_paths: ${{ steps.check_paths.outputs.value }} - labels: ${{ steps.get_labels.outputs.labels }} - steps: - - name: Check files modified by PR - id: check_paths - run: | - paths=( - components/eamxx - components/eam/src/physics/rrtmgp - components/eam/src/physics/p3/scream - components/eam/src/physics/cam - components/eam/src/physics/rrtmgp/external - externals/ekat - externals/scorpio - externals/haero - externals/YAKL - .github/workflows/eamxx-sa-testing.yml - ) - pattern=$(IFS=\|; echo "${paths[*]}") - - # Use the GitHub API to get the list of changed files - # There are page size limits, so do it in chunks - page=1 - while true; do - response=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ - "https://api.github.com/repos/E3SM-Project/scream/pulls/${{ github.event.number }}/files?per_page=100&page=$page") - - # Check if the response is empty, and break if it is - [ -z "$response" ] && break - - changed_files+=$(echo "$response" | grep -o '"filename": *"[^"]*"' | sed 's/"filename": *//; s/"//g')$'\n' - - # Check if there are more pages, and quite if there aren't - [[ $(echo "$response" | jq '. | length') -lt 100 ]] && break - - page=$((page + 1)) - done - - # Check for matches and echo the matching files (or "" if none) - matching_files=$(echo "$changed_files" | grep -E "^($pattern)" || echo "") - if [[ -n "$matching_files" ]]; then - echo "Found relevant files: $matching_files" - echo "value=true" >> $GITHUB_OUTPUT - else - echo "No relevant files touched by this PR." - echo "value=false" >> $GITHUB_OUTPUT - fi - - name: Retrieve PR labels - id: get_labels - run: | - labels="${{ join(github.event.pull_request.labels.*.name, ',') }}" - echo "labels=${labels}" >> $GITHUB_OUTPUT gcc-openmp: - needs: [pre_process_pr] if: | - !failure() && !cancelled() && - ( - github.event_name == 'schedule' || + ${{ + github.event_name != 'workflow_dispatch' || ( - github.event_name == 'pull_request' && - needs.pre_process_pr.outputs.relevant_paths=='true' && - !contains(needs.pre_process_pr.outputs.labels,'CI: skip gcc') && - !contains(needs.pre_process_pr.outputs.labels,'CI: skip openmp') && - !contains(needs.pre_process_pr.outputs.labels,'CI: skip eamxx-sa') && - !contains(needs.pre_process_pr.outputs.labels,'CI: skip eamxx-all') - ) || ( - github.event_name == 'workflow_dispatch' && github.event.inputs.job_to_run == 'gcc-openmp' || github.event.inputs.job_to_run == 'all' ) - ) + }} runs-on: [self-hosted, ghci-snl-cpu, gcc] strategy: fail-fast: false @@ -132,14 +78,6 @@ jobs: submodules: recursive - name: Show action trigger uses: ./.github/actions/show-workflow-trigger - - name: Set test-all inputs based on event specs - run: | - echo "generate=false" >> $GITHUB_ENV - if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then - if [ "${{ inputs.bless }}" == "true" ]; then - echo "generate=true" >> $GITHUB_ENV - fi - fi - name: Run tests uses: ./.github/actions/test-all-scream with: @@ -149,24 +87,14 @@ jobs: submit: ${{ env.submit }} cmake-configs: Kokkos_ENABLE_OPENMP=ON gcc-cuda: - needs: [pre_process_pr] if: | - !failure() && !cancelled() && - ( - github.event_name == 'schedule' || + ${{ + github.event_name != 'workflow_dispatch' || ( - github.event_name == 'pull_request' && - needs.pre_process_pr.outputs.relevant_paths=='true' && - !contains(needs.pre_process_pr.outputs.labels,'CI: skip gcc') && - !contains(needs.pre_process_pr.outputs.labels,'CI: skip cuda') && - !contains(needs.pre_process_pr.outputs.labels,'CI: skip eamxx-sa') && - !contains(needs.pre_process_pr.outputs.labels,'CI: skip eamxx-all') - ) || ( - github.event_name == 'workflow_dispatch' && - github.event.inputs.job_to_run == 'gcc-cuda' || + github.event.inputs.job_to_run == 'gcc-cuda' || github.event.inputs.job_to_run == 'all' ) - ) + }} runs-on: [self-hosted, ghci-snl-cuda, cuda, gcc] strategy: fail-fast: false @@ -182,14 +110,6 @@ jobs: submodules: recursive - name: Show action trigger uses: ./.github/actions/show-workflow-trigger - - name: Set test-all inputs based on event specs - run: | - echo "generate=false" >> $GITHUB_ENV - if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then - if [ "${{ inputs.bless }}" == "true" ]; then - echo "generate=true" >> $GITHUB_ENV - fi - fi - name: Get CUDA Arch run: | # Ensure nvidia-smi is available diff --git a/.github/workflows/eamxx-scripts-tests.yml b/.github/workflows/eamxx-scripts-tests.yml index a14cdc4f3505..2cdd6f8758f8 100644 --- a/.github/workflows/eamxx-scripts-tests.yml +++ b/.github/workflows/eamxx-scripts-tests.yml @@ -5,6 +5,10 @@ on: pull_request: branches: [ master ] types: [opened, synchronize, ready_for_review, reopened] + paths: + - 'components/eamxx/scripts/**' + - 'components/eamxx/cime_config/**' + - '.github/workflows/eamxx-scripts-tests.yml' # Manual run for debug purposes only workflow_dispatch: @@ -30,68 +34,7 @@ env: submit: ${{ github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.submit) }} jobs: - pre_process_pr: - if: ${{ github.event_name == 'pull_request' }} - runs-on: ubuntu-latest # This job can run anywhere - outputs: - relevant_paths: ${{ steps.check_paths.outputs.value}} - labels: ${{ steps.get_labels.outputs.labels }} - steps: - - name: Check files modified by PR - id: check_paths - run: | - paths=( - components/eamxx/scripts - components/eamxx/cime_config/eamxx - components/eamxx/cime_config/build - components/eamxx/cime_config/yaml_utils.py - .github/workflows/eamxx-scripts-tests.yml - ) - pattern=$(IFS=\|; echo "${paths[*]}") - - # Use the GitHub API to get the list of changed files - # There are page size limits, so do it in chunks - page=1 - while true; do - response=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ - "https://api.github.com/repos/E3SM-Project/scream/pulls/${{ github.event.number }}/files?per_page=100&page=$page") - - # Check if the response is empty, and break if it is - [ -z "$response" ] && break - - changed_files+=$(echo "$response" | grep -o '"filename": *"[^"]*"' | sed 's/"filename": *//; s/"//g')$'\n' - - # Check if there are more pages, and quite if there aren't - [[ $(echo "$response" | jq '. | length') -lt 100 ]] && break - - page=$((page + 1)) - done - - # Check for matches and echo the matching files (or "" if none) - matching_files=$(echo "$changed_files" | grep -E "^($pattern)" || echo "") - if [[ -n "$matching_files" ]]; then - echo "Found relevant files: $matching_files" - echo "value=true" >> $GITHUB_OUTPUT - else - echo "No relevant files touched by this PR." - echo "value=false" >> $GITHUB_OUTPUT - fi - - name: Retrieve PR labels - id: get_labels - run: | - labels="${{ join(github.event.pull_request.labels.*.name, ',') }}" - echo "labels=${labels}" >> $GITHUB_OUTPUT cpu-gcc: - needs: [pre_process_pr] - if: | - !failure() && !cancelled() && - ( - github.event_name != 'pull_request' || - ( - needs.pre_process_pr.outputs.relevant_paths == 'true' && - !contains(needs.pre_process_pr.outputs.labels, 'CI: skip eamxx-all') - ) - ) runs-on: [self-hosted, gcc, ghci-snl-cpu] steps: - name: Check out the repository diff --git a/.github/workflows/eamxx-v1-testing.yml b/.github/workflows/eamxx-v1-testing.yml index d55ed8252a50..9145961bdfee 100644 --- a/.github/workflows/eamxx-v1-testing.yml +++ b/.github/workflows/eamxx-v1-testing.yml @@ -5,6 +5,17 @@ on: pull_request: branches: [ master ] types: [opened, synchronize, ready_for_review, reopened] + paths: + # first, yes to these + - '.github/workflows/eamxx-v1-testing.yml' + - 'cime_config/machine/config_machines.xml' + - 'components/eamxx/**' + - 'components/homme/**' + - 'externals/ekat' + - 'externals/scorpio' + # second, no to these + - '!components/eamxx/docs/**' + - '!components/eamxx/mkdocs.yml' # Manual run is used to bless workflow_dispatch: @@ -28,81 +39,26 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true -jobs: - pre_process_pr: - if: ${{ github.event_name == 'pull_request' }} - runs-on: ubuntu-latest # This job can run anywhere - outputs: - relevant_paths: ${{ steps.check_paths.outputs.value }} - labels: ${{ steps.get_labels.outputs.labels }} - steps: - - name: Check files modified by PR - id: check_paths - run: | - paths=( - components/eamxx - components/eam/src/physics/rrtmgp - components/eam/src/physics/p3/scream - components/eam/src/physics/cam - components/eam/src/physics/rrtmgp/external - externals/ekat - externals/scorpio - externals/haero - externals/YAKL - .github/workflows/eamxx-v1-testing.yml - ) - pattern=$(IFS=\|; echo "${paths[*]}") - - # Use the GitHub API to get the list of changed files - # There are page size limits, so do it in chunks - page=1 - while true; do - response=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ - "https://api.github.com/repos/E3SM-Project/scream/pulls/${{ github.event.number }}/files?per_page=100&page=$page") - - # Check if the response is empty, and break if it is - [ -z "$response" ] && break - - changed_files+=$(echo "$response" | grep -o '"filename": *"[^"]*"' | sed 's/"filename": *//; s/"//g')$'\n' - - # Check if there are more pages, and quite if there aren't - [[ $(echo "$response" | jq '. | length') -lt 100 ]] && break +env: + # Submit to cdash only for nightlies or if the user explicitly forced a submission via workflow dispatch + submit: ${{ github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.submit) }} + # Generate only if user requested via workflow_dispatch + generate: ${{ github.event_name == 'workflow_dispatch' && inputs.bless }} + # Correct case folder suffix for generate/compare, used to find files to upload as artifacts + folder_suffix: ${{ github.event_name == 'workflow_dispatch' && inputs.bless && '.G' || '.C' }} + # Compare/generate flags for create_test + flags: ${{ github.event_name == 'workflow_dispatch' && inputs.bless && '-o -g -b master' || '-c -b master' }} - page=$((page + 1)) - done - - # Check for matches and echo the matching files (or "" if none) - matching_files=$(echo "$changed_files" | grep -E "^($pattern)" || echo "") - if [[ -n "$matching_files" ]]; then - echo "Found relevant files: $matching_files" - echo "value=true" >> $GITHUB_OUTPUT - else - echo "No relevant files touched by this PR." - echo "value=false" >> $GITHUB_OUTPUT - fi - - name: Retrieve PR labels - id: get_labels - run: | - labels="${{ join(github.event.pull_request.labels.*.name, ',') }}" - echo "labels=${labels}" >> $GITHUB_OUTPUT +jobs: cpu-gcc: - needs: [pre_process_pr] if: | - !failure() && !cancelled() && - ( - github.event_name == 'schedule' || + ${{ + github.event_name != 'workflow_dispatch' || ( - github.event_name == 'pull_request' && - needs.pre_process_pr.outputs.relevant_paths=='true' && - !contains(needs.pre_process_pr.outputs.labels,'CI: skip gcc') && - !contains(needs.pre_process_pr.outputs.labels,'CI: skip eamxx-v1') && - !contains(needs.pre_process_pr.outputs.labels,'CI: skip eamxx-all') - ) || ( - github.event_name == 'workflow_dispatch' && - github.event.inputs.job_to_run == 'cpu-gcc' || + github.event.inputs.job_to_run == 'cpu-gcc' || github.event.inputs.job_to_run == 'all' ) - ) + }} runs-on: [self-hosted, gcc, ghci-snl-cpu] strategy: matrix: @@ -142,18 +98,6 @@ jobs: echo "Unsupported Linux distribution" exit 1 fi - - name: Establish cmp/gen flag - run: | - dir_suffix=".C" - cmp_gen_flag="-c" - if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then - if [ ${{ inputs.bless }} ]; then - cmp_gen_flag="-o -g" - dir_suffix=".G" - fi - fi - echo "flags=$cmp_gen_flag -b master" >> $GITHUB_ENV - echo "folder_suffix=$dir_suffix" >> $GITHUB_ENV - name: Run test run: | ./cime/scripts/create_test ${{ matrix.test.full_name }} ${{ env.flags }} --wait From febfb90f207a05fd507749714a2ee04af63fc519 Mon Sep 17 00:00:00 2001 From: mahf708 Date: Fri, 22 Nov 2024 09:38:35 -0600 Subject: [PATCH 147/147] update pam to conform to new eamxx p3 --- components/eam/src/physics/crm/pam/external | 2 +- components/eam/src/physics/crm/pam/pam_driver.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/components/eam/src/physics/crm/pam/external b/components/eam/src/physics/crm/pam/external index 1c37054d1ff9..9b3e543d8bda 160000 --- a/components/eam/src/physics/crm/pam/external +++ b/components/eam/src/physics/crm/pam/external @@ -1 +1 @@ -Subproject commit 1c37054d1ff9b160290cc286dcbd3cdc6cd7e7f6 +Subproject commit 9b3e543d8bda43371a10cc1748397e69da9823ee diff --git a/components/eam/src/physics/crm/pam/pam_driver.cpp b/components/eam/src/physics/crm/pam/pam_driver.cpp index c7038343f08a..e3070cce240a 100644 --- a/components/eam/src/physics/crm/pam/pam_driver.cpp +++ b/components/eam/src/physics/crm/pam/pam_driver.cpp @@ -20,7 +20,6 @@ // Needed for p3_init #include "p3_functions.hpp" -#include "p3_f90.hpp" #include "pam_debug.h" bool constexpr enable_check_state = false; @@ -203,7 +202,8 @@ extern "C" void pam_driver() { #if defined(P3_CXX) if (is_first_step || is_restart) { auto am_i_root = coupler.get_option("am_i_root"); - scream::p3::p3_init(/*write_tables=*/false, am_i_root); + using P3F = scream::p3::Functions; + P3F::p3_init(/*write_tables=*/false, am_i_root); pam::p3_init_lookup_tables(); // Load P3 lookup table data - avoid re-loading every CRM call } #endif